All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/9]: pinctrl-single support DT
@ 2012-10-31 23:04 Haojian Zhuang
  2012-10-31 23:04 ` [PATCH v3 1/9] ARM: mmp: select pinctrl driver Haojian Zhuang
                   ` (8 more replies)
  0 siblings, 9 replies; 46+ messages in thread
From: Haojian Zhuang @ 2012-10-31 23:04 UTC (permalink / raw)
  To: linux-arm-kernel

Changelog:
v3:
1. Add more comments in document.
2. Replace pcs_readl() & pcs_writel() by pcs->read() & pcs->write().
3. Clean code.

v2:
1. Remove "pinctrl-single,gpio-mask". Since GPIO function is one of the
mux function in the pinmux register of both OMAP and PXA/MMP silicons.
Use "pinctrl-single,function-mask" instead.
2. Remove "pinctrl-single,gpio-enable" & "pinctrl-single,gpio-disable".
Use "pinctrl-single,gpio-func" instead. Because GPIO mode is only one
of the mux functions in the pinmux register. Defining "gpio-enable" &
"gpio-disable" are redundant.
3. Define register with __iomem, not u32 type.
4. Remove "pinctrl-single,input-schmit-shift",
"pinctrl-single,power-source-shift", "pinctrl-single,bias-shift". All
these properties could be calculated by mask fields.
5. Return -EPROBE_DEFER if pinmux could be got in device driver. And
the device driver would be probed again deferred.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v3 1/9] ARM: mmp: select pinctrl driver
  2012-10-31 23:04 [PATCH v3 0/9]: pinctrl-single support DT Haojian Zhuang
@ 2012-10-31 23:04 ` Haojian Zhuang
  2012-10-31 23:04 ` [PATCH v3 2/9] pinctrl: single: support gpio request and free Haojian Zhuang
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 46+ messages in thread
From: Haojian Zhuang @ 2012-10-31 23:04 UTC (permalink / raw)
  To: linux-arm-kernel

Pinctrl driver is necessary for MMP DT & MMP2 DT platforms.

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/mach-mmp/Kconfig |    4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig
index 178d4da..ebdda83 100644
--- a/arch/arm/mach-mmp/Kconfig
+++ b/arch/arm/mach-mmp/Kconfig
@@ -89,6 +89,8 @@ config MACH_MMP_DT
 	select CPU_PXA168
 	select CPU_PXA910
 	select USE_OF
+	select PINCTRL
+	select PINCTRL_SINGLE
 	help
 	  Include support for Marvell MMP2 based platforms using
 	  the device tree. Needn't select any other machine while
@@ -99,6 +101,8 @@ config MACH_MMP2_DT
 	depends on !CPU_MOHAWK
 	select CPU_MMP2
 	select USE_OF
+	select PINCTRL
+	select PINCTRL_SINGLE
 	help
 	  Include support for Marvell MMP2 based platforms using
 	  the device tree.
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 2/9] pinctrl: single: support gpio request and free
  2012-10-31 23:04 [PATCH v3 0/9]: pinctrl-single support DT Haojian Zhuang
  2012-10-31 23:04 ` [PATCH v3 1/9] ARM: mmp: select pinctrl driver Haojian Zhuang
@ 2012-10-31 23:04 ` Haojian Zhuang
  2012-10-31 23:04 ` [PATCH v3 3/9] pinctrl: single: support pinconf generic Haojian Zhuang
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 46+ messages in thread
From: Haojian Zhuang @ 2012-10-31 23:04 UTC (permalink / raw)
  To: linux-arm-kernel

Marvell's PXA/MMP silicon also match the behavior of pinctrl-single.
Each pin binds to one register. A lot of pins could be configured
as gpio.

Now add these properties in below.
<gpio range phandle>:
	include "pinctrl-single,gpio" & "pinctrl,gpio-func" properties.

	pinctrl-single,gpio: <gpio base, npins in range, register offset>

	pinctrl-single,gpio-func: <gpio function value in mux>

pinctrl-single,gpio-ranges: phandle list of gpio range array

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 drivers/pinctrl/pinctrl-single.c |  100 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 98 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index 726a729..a7c5fdd 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -30,6 +30,7 @@
 #define PCS_MUX_BITS_NAME		"pinctrl-single,bits"
 #define PCS_REG_NAME_LEN		((sizeof(unsigned long) * 2) + 1)
 #define PCS_OFF_DISABLED		~0U
+#define PCS_MAX_GPIO_VALUES		3
 
 /**
  * struct pcs_pingroup - pingroups for a function
@@ -77,6 +78,18 @@ struct pcs_function {
 };
 
 /**
+ * struct pcs_gpio_range - pinctrl gpio range
+ * @range:	subrange of the GPIO number space
+ * @gpio_func:	gpio function value in the pinmux register
+ * @func_en:	need to handle gpio function in the pinmux register
+ */
+struct pcs_gpio_range {
+	struct pinctrl_gpio_range range;
+	int gpio_func;
+	unsigned func_en:1;
+};
+
+/**
  * struct pcs_data - wrapper for data needed by pinctrl framework
  * @pa:		pindesc array
  * @cur:	index to current element
@@ -123,8 +136,10 @@ struct pcs_name {
  * @ftree:	function index radix tree
  * @pingroups:	list of pingroups
  * @functions:	list of functions
+ * @ranges:	list of gpio ranges
  * @ngroups:	number of pingroups
  * @nfuncs:	number of functions
+ * @nranges:	number of gpio ranges
  * @desc:	pin controller descriptor
  * @read:	register read function to use
  * @write:	register write function to use
@@ -148,8 +163,10 @@ struct pcs_device {
 	struct radix_tree_root ftree;
 	struct list_head pingroups;
 	struct list_head functions;
+	struct list_head ranges;
 	unsigned ngroups;
 	unsigned nfuncs;
+	unsigned nranges;
 	struct pinctrl_desc desc;
 	unsigned (*read)(void __iomem *reg);
 	void (*write)(unsigned val, void __iomem *reg);
@@ -403,9 +420,27 @@ static void pcs_disable(struct pinctrl_dev *pctldev, unsigned fselector,
 }
 
 static int pcs_request_gpio(struct pinctrl_dev *pctldev,
-			struct pinctrl_gpio_range *range, unsigned offset)
+			    struct pinctrl_gpio_range *range, unsigned pin)
 {
-	return -ENOTSUPP;
+	struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
+	struct pcs_gpio_range *gpio = NULL;
+	int end, mux_bytes;
+	unsigned data;
+
+	gpio = container_of(range, struct pcs_gpio_range, range);
+	if (!gpio->func_en)
+		return -ENOTSUPP;
+	end = range->pin_base + range->npins - 1;
+	if (pin < range->pin_base || pin > end) {
+		dev_err(pctldev->dev, "pin %d isn't in the range of "
+			"%d to %d\n", pin, range->pin_base, end);
+		return -EINVAL;
+	}
+	mux_bytes = pcs->width / BITS_PER_BYTE;
+	data = pcs->read(pcs->base + pin * mux_bytes) & ~pcs->fmask;
+	data |= gpio->gpio_func;
+	pcs->write(data, pcs->base + pin * mux_bytes);
+	return 0;
 }
 
 static struct pinmux_ops pcs_pinmux_ops = {
@@ -879,6 +914,62 @@ static void pcs_free_resources(struct pcs_device *pcs)
 
 static struct of_device_id pcs_of_match[];
 
+static int __devinit pcs_add_gpio_range(struct device_node *node,
+					struct pcs_device *pcs)
+{
+	struct pcs_gpio_range *gpio;
+	struct device_node *np;
+	const __be32 *list;
+	const char list_name[] = "pinctrl-single,gpio-ranges";
+	const char name[] = "pinctrl-single";
+	u32 gpiores[PCS_MAX_GPIO_VALUES];
+	int ret, size, i, mux_bytes = 0;
+
+	list = of_get_property(node, list_name, &size);
+	if (!list)
+		return 0;
+	size = size / sizeof(*list);
+	for (i = 0; i < size; i++) {
+		np = of_parse_phandle(node, list_name, i);
+		memset(gpiores, 0, sizeof(u32) * PCS_MAX_GPIO_VALUES);
+		ret = of_property_read_u32_array(np, "pinctrl-single,gpio",
+						 gpiores, PCS_MAX_GPIO_VALUES);
+		if (ret < 0)
+			return -ENOENT;
+		gpio = devm_kzalloc(pcs->dev, sizeof(*gpio), GFP_KERNEL);
+		if (!gpio) {
+			dev_err(pcs->dev, "failed to allocate pcs gpio\n");
+			return -ENOMEM;
+		}
+		gpio->range.id = i;
+		gpio->range.base = gpiores[0];
+		gpio->range.npins = gpiores[1];
+		gpio->range.name = devm_kzalloc(pcs->dev, sizeof(name),
+						GFP_KERNEL);
+		if (!gpio->range.name) {
+			dev_err(pcs->dev, "failed to allocate range name\n");
+			return -ENOMEM;
+		}
+		memcpy(&gpio->range.name, name, sizeof(name));
+		mux_bytes = pcs->width / BITS_PER_BYTE;
+		gpio->range.pin_base = gpiores[2] / mux_bytes;
+		memset(gpiores, 0, sizeof(u32) * PCS_MAX_GPIO_VALUES);
+		ret = of_property_read_u32(np, "pinctrl-single,gpio-func",
+					   &gpio->gpio_func);
+		if (ret < 0)
+			return -ENOENT;
+		gpio->func_en = 1;
+
+		mutex_lock(&pcs->mutex);
+		list_add_tail(&gpio->range.node, &pcs->ranges);
+		pcs->nranges++;
+		mutex_unlock(&pcs->mutex);
+
+		pinctrl_add_gpio_range(pcs->pctl, &gpio->range);
+	}
+	return 0;
+}
+
 static int __devinit pcs_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
@@ -900,6 +991,7 @@ static int __devinit pcs_probe(struct platform_device *pdev)
 	mutex_init(&pcs->mutex);
 	INIT_LIST_HEAD(&pcs->pingroups);
 	INIT_LIST_HEAD(&pcs->functions);
+	INIT_LIST_HEAD(&pcs->ranges);
 
 	PCS_GET_PROP_U32("pinctrl-single,register-width", &pcs->width,
 			 "register width not specified\n");
@@ -975,6 +1067,10 @@ static int __devinit pcs_probe(struct platform_device *pdev)
 		goto free;
 	}
 
+	ret = pcs_add_gpio_range(np, pcs);
+	if (ret < 0)
+		goto free;
+
 	dev_info(pcs->dev, "%i pins at pa %p size %u\n",
 		 pcs->desc.npins, pcs->base, pcs->size);
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 3/9] pinctrl: single: support pinconf generic
  2012-10-31 23:04 [PATCH v3 0/9]: pinctrl-single support DT Haojian Zhuang
  2012-10-31 23:04 ` [PATCH v3 1/9] ARM: mmp: select pinctrl driver Haojian Zhuang
  2012-10-31 23:04 ` [PATCH v3 2/9] pinctrl: single: support gpio request and free Haojian Zhuang
@ 2012-10-31 23:04 ` Haojian Zhuang
  2012-11-01  0:44   ` Tony Lindgren
  2012-10-31 23:04 ` [PATCH v3 4/9] ARM: dts: support pinctrl single in pxa910 Haojian Zhuang
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 46+ messages in thread
From: Haojian Zhuang @ 2012-10-31 23:04 UTC (permalink / raw)
  To: linux-arm-kernel

Add pinconf generic support with POWER SOURCE, BIAS PULL.

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 drivers/pinctrl/Kconfig          |    1 +
 drivers/pinctrl/pinctrl-single.c |  276 ++++++++++++++++++++++++++++++++++++--
 2 files changed, 266 insertions(+), 11 deletions(-)

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 7bf914d..e9f2d2d 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -139,6 +139,7 @@ config PINCTRL_SINGLE
 	depends on OF
 	select PINMUX
 	select PINCONF
+	select GENERIC_PINCONF
 	help
 	  This selects the device tree based generic pinctrl driver.
 
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index a7c5fdd..3b97b65 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -20,6 +20,7 @@
 #include <linux/of_device.h>
 #include <linux/of_address.h>
 
+#include <linux/pinctrl/pinconf-generic.h>
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/pinctrl/pinmux.h>
 
@@ -28,6 +29,9 @@
 #define DRIVER_NAME			"pinctrl-single"
 #define PCS_MUX_PINS_NAME		"pinctrl-single,pins"
 #define PCS_MUX_BITS_NAME		"pinctrl-single,bits"
+#define PCS_BIAS_NAME			"pinctrl-single,bias"
+#define PCS_POWER_SOURCE_NAME		"pinctrl-single,power-source"
+#define PCS_SCHMITT_NAME		"pinctrl-single,input-schmitt"
 #define PCS_REG_NAME_LEN		((sizeof(unsigned long) * 2) + 1)
 #define PCS_OFF_DISABLED		~0U
 #define PCS_MAX_GPIO_VALUES		3
@@ -130,6 +134,15 @@ struct pcs_name {
  * @fshift:	function register shift
  * @foff:	value to turn mux off
  * @fmax:	max number of functions in fmask
+ * @bmask:	bias mask in pinconf
+ * @bshift:	bias register shift
+ * @bdis:	bias disable value in pinconf
+ * @bpullup:	bias pull up value in pinconf
+ * @bpulldown:	bias pull down value in pinconf
+ * @ismask:	input schmitt mask in pinconf
+ * @isshift:	input schmitt register shift
+ * @psmask:	power source mask in pinconf
+ * @psshift:	power source register shift
  * @names:	array of register names for pins
  * @pins:	physical pins on the SoC
  * @pgtree:	pingroup index radix tree
@@ -156,6 +169,15 @@ struct pcs_device {
 	unsigned fshift;
 	unsigned foff;
 	unsigned fmax;
+	unsigned bmask;
+	unsigned bshift;
+	unsigned bdis;
+	unsigned bpullup;
+	unsigned bpulldown;
+	unsigned ismask;
+	unsigned isshift;
+	unsigned psmask;
+	unsigned psshift;
 	bool bits_per_mux;
 	struct pcs_name *names;
 	struct pcs_data pins;
@@ -452,28 +474,163 @@ static struct pinmux_ops pcs_pinmux_ops = {
 	.gpio_request_enable = pcs_request_gpio,
 };
 
+static void pcs_free_pingroups(struct pcs_device *pcs);
+
 static int pcs_pinconf_get(struct pinctrl_dev *pctldev,
 				unsigned pin, unsigned long *config)
 {
+	struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	unsigned data;
+	u32 offset;
+
+	offset = pin * (pcs->width / BITS_PER_BYTE);
+	data = pcs->read(pcs->base + offset);
+
+	switch (param) {
+	case PIN_CONFIG_POWER_SOURCE:
+		if (pcs->psmask == PCS_OFF_DISABLED
+			|| pcs->psshift == PCS_OFF_DISABLED)
+			return -ENOTSUPP;
+		data &= pcs->psmask;
+		data = data >> pcs->psshift;
+		*config = data;
+		return 0;
+		break;
+	case PIN_CONFIG_BIAS_DISABLE:
+		if (pcs->bmask == PCS_OFF_DISABLED
+			|| pcs->bshift == PCS_OFF_DISABLED
+			|| pcs->bdis == PCS_OFF_DISABLED)
+			return -ENOTSUPP;
+		data &= pcs->bmask;
+		*config = 0;
+		if (data == pcs->bdis)
+			return 0;
+		else
+			return -EINVAL;
+		break;
+	case PIN_CONFIG_BIAS_PULL_UP:
+		if (pcs->bmask == PCS_OFF_DISABLED
+			|| pcs->bshift == PCS_OFF_DISABLED
+			|| pcs->bpullup == PCS_OFF_DISABLED)
+			return -ENOTSUPP;
+		data &= pcs->bmask;
+		*config = 0;
+		if (data == pcs->bpullup)
+			return 0;
+		else
+			return -EINVAL;
+		break;
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		if (pcs->bmask == PCS_OFF_DISABLED
+			|| pcs->bshift == PCS_OFF_DISABLED
+			|| pcs->bpulldown == PCS_OFF_DISABLED)
+			return -ENOTSUPP;
+		data &= pcs->bmask;
+		*config = 0;
+		if (data == pcs->bpulldown)
+			return 0;
+		else
+			return -EINVAL;
+		break;
+	default:
+		break;
+	}
 	return -ENOTSUPP;
 }
 
 static int pcs_pinconf_set(struct pinctrl_dev *pctldev,
 				unsigned pin, unsigned long config)
 {
-	return -ENOTSUPP;
+	struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param config_param = pinconf_to_config_param(config);
+	unsigned ret, mask = ~0UL;
+	u32 offset, data;
+
+	switch (config_param) {
+	case PIN_CONFIG_POWER_SOURCE:
+		if (pcs->psmask == PCS_OFF_DISABLED
+			|| pcs->psshift == PCS_OFF_DISABLED)
+			return 0;
+		mask = pcs->psmask;
+		data = (pinconf_to_config_argument(config) << pcs->psshift)
+			& pcs->psmask;
+		break;
+	case PIN_CONFIG_BIAS_DISABLE:
+		if (pcs->bmask == PCS_OFF_DISABLED
+			|| pcs->bshift == PCS_OFF_DISABLED)
+			return 0;
+		mask = pcs->bmask;
+		data = (pinconf_to_config_argument(config) << pcs->bshift)
+			& pcs->bmask;
+		break;
+	default:
+		return 0;
+	}
+	offset = pin * (pcs->width / BITS_PER_BYTE);
+	ret = pcs->read(pcs->base + offset) & ~mask;
+	pcs->write(ret | data, pcs->base + offset);
+	return 0;
 }
 
 static int pcs_pinconf_group_get(struct pinctrl_dev *pctldev,
 				unsigned group, unsigned long *config)
 {
-	return -ENOTSUPP;
+	struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
+	struct pcs_pingroup *pins;
+
+	pins = radix_tree_lookup(&pcs->pgtree, group);
+	if (!pins) {
+		dev_err(pcs->dev, "%s could not find pingroup%i\n",
+			__func__, group);
+		return -EINVAL;
+	}
+	return pcs_pinconf_get(pctldev, pins->gpins[0], config);
 }
 
 static int pcs_pinconf_group_set(struct pinctrl_dev *pctldev,
 				unsigned group, unsigned long config)
 {
-	return -ENOTSUPP;
+	struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param config_param = pinconf_to_config_param(config);
+	struct pcs_pingroup *pins;
+	u32 offset, data;
+	unsigned ret, mask = ~0UL;
+	int i;
+
+	switch (config_param) {
+	case PIN_CONFIG_POWER_SOURCE:
+		if (pcs->psmask == PCS_OFF_DISABLED
+			|| pcs->psshift == PCS_OFF_DISABLED)
+			return 0;
+		mask = pcs->psmask;
+		data = (pinconf_to_config_argument(config) << pcs->psshift)
+			& pcs->psmask;
+		break;
+	case PIN_CONFIG_BIAS_DISABLE:
+		if (pcs->bmask == PCS_OFF_DISABLED
+			|| pcs->bshift == PCS_OFF_DISABLED)
+			return 0;
+		mask = pcs->bmask;
+		data = (pinconf_to_config_argument(config) << pcs->bshift)
+			& pcs->bmask;
+		break;
+	default:
+		return 0;
+	}
+
+	pins = radix_tree_lookup(&pcs->pgtree, group);
+	if (!pins) {
+		dev_err(pcs->dev, "%s could not find pingroup%i\n",
+			__func__, group);
+		return -EINVAL;
+	}
+	for (i = 0; i < pins->ngpins; i++) {
+		offset = pins->gpins[i] * (pcs->width / BITS_PER_BYTE);
+		ret = pcs->read(pcs->base + offset) & ~mask;
+		pcs->write(ret | data, pcs->base + offset);
+	}
+	return 0;
 }
 
 static void pcs_pinconf_dbg_show(struct pinctrl_dev *pctldev,
@@ -487,6 +644,7 @@ static void pcs_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
 }
 
 static struct pinconf_ops pcs_pinconf_ops = {
+	.is_generic = true,
 	.pin_config_get = pcs_pinconf_get,
 	.pin_config_set = pcs_pinconf_set,
 	.pin_config_group_get = pcs_pinconf_group_get,
@@ -688,6 +846,7 @@ static int pcs_get_pin_by_offset(struct pcs_device *pcs, unsigned offset)
  * @pcs: pinctrl driver instance
  * @np: device node of the mux entry
  * @map: map entry
+ * @num_configs: number of pin configurations
  * @pgnames: pingroup names
  *
  * Note that this binding currently supports only sets of one register + value.
@@ -704,12 +863,16 @@ static int pcs_get_pin_by_offset(struct pcs_device *pcs, unsigned offset)
 static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
 						struct device_node *np,
 						struct pinctrl_map **map,
+						unsigned num_configs,
 						const char **pgnames)
 {
 	struct pcs_func_vals *vals;
+	struct pinctrl_map *p = *map;
 	const __be32 *mux;
 	int size, params, rows, *pins, index = 0, found = 0, res = -ENOMEM;
 	struct pcs_function *function;
+	unsigned long *config;
+	u32 value;
 
 	if (pcs->bits_per_mux) {
 		params = 3;
@@ -772,12 +935,42 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
 	if (res < 0)
 		goto free_function;
 
-	(*map)->type = PIN_MAP_TYPE_MUX_GROUP;
-	(*map)->data.mux.group = np->name;
-	(*map)->data.mux.function = np->name;
+	p->type = PIN_MAP_TYPE_MUX_GROUP;
+	p->data.mux.group = np->name;
+	p->data.mux.function = np->name;
+
+	if (!num_configs)
+		return 0;
+	config = devm_kzalloc(pcs->dev, sizeof(*config) * num_configs,
+			      GFP_KERNEL);
+	if (!config) {
+		res = -ENOMEM;
+		goto free_pingroup;
+	}
+	index = 0;
+	if (!of_property_read_u32(np, PCS_SCHMITT_NAME, &value))
+		config[index++] =
+			pinconf_to_config_packed(PIN_CONFIG_INPUT_SCHMITT,
+						 value & 0xffff);
+	if (!of_property_read_u32(np, PCS_BIAS_NAME, &value))
+		config[index++] =
+			pinconf_to_config_packed(PIN_CONFIG_BIAS_DISABLE,
+						 value & 0xffff);
+	if (!of_property_read_u32(np, PCS_POWER_SOURCE_NAME, &value))
+		config[index++] =
+			pinconf_to_config_packed(PIN_CONFIG_POWER_SOURCE,
+						 value & 0xffff);
+	p++;
+	p->type = PIN_MAP_TYPE_CONFIGS_GROUP;
+	p->data.configs.group_or_pin = np->name;
+	p->data.configs.configs = config;
+	p->data.configs.num_configs = num_configs;
 
 	return 0;
 
+free_pingroup:
+	pcs_free_pingroups(pcs);
+
 free_function:
 	pcs_remove_function(pcs, function);
 
@@ -789,6 +982,30 @@ free_vals:
 
 	return res;
 }
+
+static int pcs_dt_check_maps(struct device_node *np, unsigned *num_maps,
+			     unsigned *num_configs)
+{
+	unsigned size;
+
+	*num_maps = 0;
+	*num_configs = 0;
+	if (of_get_property(np, PCS_MUX_PINS_NAME, &size)
+		|| of_get_property(np, PCS_MUX_BITS_NAME, &size))
+		(*num_maps)++;
+	if (of_get_property(np, PCS_SCHMITT_NAME, &size))
+		(*num_configs)++;
+	if (of_get_property(np, PCS_BIAS_NAME, &size))
+		(*num_configs)++;
+	if (of_get_property(np, PCS_POWER_SOURCE_NAME, &size))
+		(*num_configs)++;
+	if (*num_configs)
+		(*num_maps)++;
+	if (!(*num_maps))
+		return -EINVAL;
+	return 0;
+}
+
 /**
  * pcs_dt_node_to_map() - allocates and parses pinctrl maps
  * @pctldev: pinctrl instance
@@ -802,29 +1019,32 @@ static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev,
 {
 	struct pcs_device *pcs;
 	const char **pgnames;
+	unsigned num_configs;
 	int ret;
 
 	pcs = pinctrl_dev_get_drvdata(pctldev);
 
-	*map = devm_kzalloc(pcs->dev, sizeof(**map), GFP_KERNEL);
+	ret = pcs_dt_check_maps(np_config, num_maps, &num_configs);
+	if (ret)
+		return ret;
+
+	*map = devm_kzalloc(pcs->dev, sizeof(**map) * (*num_maps), GFP_KERNEL);
 	if (!map)
 		return -ENOMEM;
 
-	*num_maps = 0;
-
 	pgnames = devm_kzalloc(pcs->dev, sizeof(*pgnames), GFP_KERNEL);
 	if (!pgnames) {
 		ret = -ENOMEM;
 		goto free_map;
 	}
 
-	ret = pcs_parse_one_pinctrl_entry(pcs, np_config, map, pgnames);
+	ret = pcs_parse_one_pinctrl_entry(pcs, np_config, map,
+					  num_configs, pgnames);
 	if (ret < 0) {
 		dev_err(pcs->dev, "no pins entries for %s\n",
 			np_config->name);
 		goto free_pgnames;
 	}
-	*num_maps = 1;
 
 	return 0;
 
@@ -1009,6 +1229,40 @@ static int __devinit pcs_probe(struct platform_device *pdev)
 	pcs->bits_per_mux = of_property_read_bool(np,
 						  "pinctrl-single,bit-per-mux");
 
+	ret = of_property_read_u32(np, "pinctrl-single,power-source-mask",
+					&pcs->psmask);
+	if (ret) {
+		pcs->psmask = PCS_OFF_DISABLED;
+		pcs->psshift = PCS_OFF_DISABLED;
+	} else
+		pcs->psshift = ffs(pcs->psmask) - 1;
+	ret = of_property_read_u32(np, "pinctrl-single,bias-mask",
+					&pcs->bmask);
+	if (ret) {
+		pcs->bmask = PCS_OFF_DISABLED;
+		pcs->bshift = PCS_OFF_DISABLED;
+	} else
+		pcs->bshift = ffs(pcs->bmask) - 1;
+	ret = of_property_read_u32(np, "pinctrl-single,bias-disable",
+					&pcs->bdis);
+	if (ret)
+		pcs->bdis = PCS_OFF_DISABLED;
+	ret = of_property_read_u32(np, "pinctrl-single,bias-pull-up",
+					&pcs->bpullup);
+	if (ret)
+		pcs->bpullup = PCS_OFF_DISABLED;
+	ret = of_property_read_u32(np, "pinctrl-single,bias-pull-down",
+					&pcs->bpulldown);
+	if (ret)
+		pcs->bpulldown = PCS_OFF_DISABLED;
+	ret = of_property_read_u32(np, "pinctrl-single,input-schmitt-mask",
+					&pcs->ismask);
+	if (ret) {
+		pcs->ismask = PCS_OFF_DISABLED;
+		pcs->isshift = PCS_OFF_DISABLED;
+	} else
+		pcs->isshift = ffs(pcs->ismask) - 1;
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 		dev_err(pcs->dev, "could not get resource\n");
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 4/9] ARM: dts: support pinctrl single in pxa910
  2012-10-31 23:04 [PATCH v3 0/9]: pinctrl-single support DT Haojian Zhuang
                   ` (2 preceding siblings ...)
  2012-10-31 23:04 ` [PATCH v3 3/9] pinctrl: single: support pinconf generic Haojian Zhuang
@ 2012-10-31 23:04 ` Haojian Zhuang
  2012-10-31 23:04 ` [PATCH v3 5/9] document: devicetree: bind pinconf with pin-single Haojian Zhuang
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 46+ messages in thread
From: Haojian Zhuang @ 2012-10-31 23:04 UTC (permalink / raw)
  To: linux-arm-kernel

Add pinctrl-single support with device tree in pxa910 dkb platform.

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 arch/arm/boot/dts/pxa910-dkb.dts |  187 +++++++++++++++++++++++++++++++++++++-
 arch/arm/boot/dts/pxa910.dtsi    |   77 ++++++++++++++++
 2 files changed, 263 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/pxa910-dkb.dts b/arch/arm/boot/dts/pxa910-dkb.dts
index 595492a..394396a 100644
--- a/arch/arm/boot/dts/pxa910-dkb.dts
+++ b/arch/arm/boot/dts/pxa910-dkb.dts
@@ -24,10 +24,195 @@
 
 	soc {
 		apb at d4000000 {
-			uart1: uart at d4017000 {
+			pmx: pinmux at d401e000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&board_pins>;
+
+				board_pins: pinmux_board_pins {
+					/* pins not owned by device driver */
+				};
+				uart1_pins: pinmux_uart1_pins {
+					pinctrl-single,pins = <
+						0x198 0x6	/* GPIO47_UART1_RXD */
+						0x19c 0x6	/* GPIO48_UART1_TXD */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0x6>;
+				};
+				uart2_pins: pinmux_uart2_pins {
+					pinctrl-single,pins = <
+						0x150 0x4	/* GPIO29_UART2_CTS */
+						0x154 0x4	/* GPIO30_UART2_RTS */
+						0x158 0x4	/* GPIO31_UART2_TXD */
+						0x15c 0x4	/* GPIO32_UART2_RXD */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0>;
+				};
+				uart3_pins: pinmux_uart3_pins {
+					pinctrl-single,pins = <
+						0x188 0x7	/* GPIO43_UART3_RXD */
+						0x18c 0x7	/* GPIO44_UART3_TXD */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0>;
+				};
+				twsi1_pins: pinmux_twsi1_pins {
+					pinctrl-single,pins = <
+						0x1b0 0x2	/* GPIO53_TWSI_SCL */
+						0x1b4 0x2	/* GPIO54_TWSI_SDA */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0>;
+				};
+				nand_pins: pinmux_nand_pins {
+					pinctrl-single,pins = <
+						0x040 0x0	/* ND_IO0 */
+						0x03c 0x0	/* ND_IO1 */
+						0x038 0x0	/* ND_IO2 */
+						0x034 0x0	/* ND_IO3 */
+						0x030 0x0	/* ND_IO4 */
+						0x02c 0x0	/* ND_IO5 */
+						0x028 0x0	/* ND_IO6 */
+						0x024 0x0	/* ND_IO7 */
+						0x020 0x0	/* ND_IO8 */
+						0x01c 0x0	/* ND_IO9 */
+						0x018 0x0	/* ND_IO10 */
+						0x014 0x0	/* ND_IO11 */
+						0x010 0x0	/* ND_IO12 */
+						0x00c 0x0	/* ND_IO13 */
+						0x008 0x0	/* ND_IO14 */
+						0x004 0x0	/* ND_IO15 */
+						0x044 0x0	/* ND_nCS0 */
+						0x060 0x1	/* ND_ALE */
+						0x05c 0x0	/* ND_CLE */
+						0x054 0x1	/* ND_nWE */
+						0x058 0x1	/* ND_nRE */
+						0x068 0x0	/* ND_RDY0 */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0>;
+				};
+				mmc1_ldata_pins: pinmux_mmc1_ldata_pins {
+					pinctrl-single,pins = <
+						0x0a0 0x0	/* MMC1_DATA0 */
+						0x09c 0x0	/* MMC1_DATA1 */
+						0x098 0x0	/* MMC1_DATA2 */
+						0x094 0x0	/* MMC1_DATA3 */
+					>;
+					pinctrl-single,power-source = <0x3>;
+					pinctrl-single,bias = <0>;
+				};
+				mmc1_hdata_pins: pinmux_mmc1_hdata_pins {
+					pinctrl-single,pins = <
+						0x090 0x0	/* MMC1_DATA4 */
+						0x08c 0x0	/* MMC1_DATA5 */
+						0x088 0x0	/* MMC1_DATA6 */
+						0x084 0x0	/* MMC1_DATA7 */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0>;
+				};
+				mmc1_clk_pins: pinmux_mmc1_clk_pins {
+					pinctrl-single,pins = <
+						0x0a4 0x0	/* MMC1_CMD */
+						0x0a8 0x0	/* MMC1_CLK */
+					>;
+					pinctrl-single,power-source = <0x3>;
+					pinctrl-single,bias = <0>;
+				};
+				mmc1_cd_pins: pinmux_mmc1_cd_pins {
+					pinctrl-single,pins = <
+						0x0ac 0x0	/* MMC1_CD */
+						0x0b0 0x0	/* MMC1_WP */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0>;
+				};
+				mmc2_pins: pinmux_mmc2_pins {
+					pinctrl-single,pins = <
+						0x180 0x1	/* MMC2_CMD */
+						0x184 0x1	/* MMC2_CLK */
+						0x17c 0x1	/* MMC2_DATA0 */
+						0x178 0x1	/* MMC2_DATA1 */
+						0x174 0x1	/* MMC2_DATA2 */
+						0x170 0x1	/* MMC2_DATA3 */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0>;
+				};
+				w1_pins: pinmux_w1_pins {
+					pinctrl-single,pins = <
+						0x0cc 0x2	/* CLK_REQ_W1 */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0>;
+				};
+				ssp1_pins: pinmux_ssp1_pins {
+					pinctrl-single,pins = <
+						0x130 0x1	/* GPIO21_SSP1_SCLK */
+						0x134 0x1	/* GPIO22_SSP1_FRM */
+						0x138 0x1	/* GPIO23_SSP1_TXD */
+						0x13c 0x1	/* GPIO24_SSP1_RXD */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0>;
+				};
+				keypad_pins: pinmux_keypad_pins {
+					pinctrl-single,pins = <
+						0x0dc 0x1	/* GPIO0_MKIN0 */
+						0x0e0 0x1	/* GPIO1_MKOUT0 */
+						0x0e4 0x1	/* GPIO2_MKIN1 */
+						0x0e8 0x1	/* GPIO3_MKOUT1 */
+						0x0ec 0x1	/* GPIO4_MKIN2 */
+						0x0f0 0x1	/* GPIO5_MKOUT2 */
+						0x0f4 0x1	/* GPIO6_MKIN3 */
+						0x0f8 0x1	/* GPIO7_MKOUT3 */
+						0x0fc 0x1	/* GPIO8_MKIN4 */
+						0x100 0x1	/* GPIO9_MKOUT4 */
+						0x10c 0x1	/* GPIO12_MKIN6 */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0>;
+				};
+				nfc_pins: pinmux_nfc_pins {
+					pinctrl-single,pins = <
+						0x120 0x0	/* GPIO17 */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0>;
+				};
+				wlan_pins: pinmux_wlan_pins {
+					pinctrl-single,pins = <
+						0x114 0x0	/* GPIO14 */
+						0x12c 0x0	/* GPIO20 */
+						0x160 0x0	/* GPIO33 */
+						0x164 0x0	/* GPIO34 */
+						0x168 0x0	/* GPIO35 */
+						0x16c 0x0	/* GPIO36 */
+					>;
+					pinctrl-single,power-source = <0x2>;
+					pinctrl-single,bias = <0>;
+				};
+			};
+			uart1: uart at d4017000 {	/* FFUART */
+				pinctrl-names = "default";
+				pinctrl-0 = <&uart1_pins>;
+				status = "okay";
+			};
+			uart2: uart at d4018000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&uart2_pins>;
+				status = "okay";
+			};
+			uart3: uart at d4036000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&uart3_pins>;
 				status = "okay";
 			};
 			twsi1: i2c at d4011000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&twsi1_pins>;
 				status = "okay";
 
 				pmic: 88pm860x at 34 {
diff --git a/arch/arm/boot/dts/pxa910.dtsi b/arch/arm/boot/dts/pxa910.dtsi
index 825aaca..a11a582 100644
--- a/arch/arm/boot/dts/pxa910.dtsi
+++ b/arch/arm/boot/dts/pxa910.dtsi
@@ -54,6 +54,83 @@
 			reg = <0xd4000000 0x00200000>;
 			ranges;
 
+			pmx: pinmux at d401e000 {
+				compatible = "pinctrl-single";
+				reg = <0xd401e000 0x0330>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				pinctrl-single,register-width = <32>;
+				pinctrl-single,function-mask = <7>;
+				pinctrl-single,gpio-ranges = <&gpiorange0 &gpiorange1
+								&gpiorange2 &gpiorange3
+								&gpiorange4 &gpiorange5
+								&gpiorange6 &gpiorange7
+								&gpiorange8 &gpiorange9
+								&gpiorange10>;
+				pinctrl-single,power-source-mask = <0x1800>;
+				pinctrl-single,bias-mask = <0xe000>;
+				pinctrl-single,bias-disable = <0>;
+				pinctrl-single,bias-pull-down = <0xa000>;
+				pinctrl-single,bias-pull-up = <0xc000>;
+				pinctrl-single,input-schmitt-mask = <0x70>;
+
+				gpiorange0: gpiorange at d401e0dc {
+					/* GPIO0 ~ GPIO54 */
+					pinctrl-single,gpio = <0 55 0x0dc>;
+					pinctrl-single,gpio-func = <0>;
+				};
+				gpiorange1: gpiorange at d401e2f0 {
+					/* GPIO55 ~ GPIO59 */
+					pinctrl-single,gpio = <55 5 0x2f0>;
+					pinctrl-single,gpio-func = <1>;
+				};
+				gpiorange2: gpiorange at d401e304 {
+					/* GPIO60 ~ GPIO66 */
+					pinctrl-single,gpio = <60 7 0x304>;
+					pinctrl-single,gpio-func = <0>;
+				};
+				gpiorange3: gpiorange at d401e1b8 {
+					/* GPIO67 ~ GPIO109 */
+					pinctrl-single,gpio = <67 43 0x1b8>;
+					pinctrl-single,gpio-func = <0>;
+				};
+				gpiorange4: gpiorange at d401e298 {
+					/* GPIO110 ~ GPIO116 */
+					pinctrl-single,gpio = <110 7 0x298>;
+					pinctrl-single,gpio-func = <0>;
+				};
+				gpiorange5: gpiorange at d401e0b4 {
+					/* GPIO117 ~ GPIO120 */
+					pinctrl-single,gpio = <117 4 0x0b4>;
+					pinctrl-single,gpio-func = <1>;
+				};
+				gpiorange6: gpiorange at d401e32c {
+					/* GPIO121 */
+					pinctrl-single,gpio = <121 1 0x32c>;
+					pinctrl-single,gpio-func = <0>;
+				};
+				gpiorange7: gpiorange at d401e0c8 {
+					/* GPIO122 ~ GPIO123 */
+					pinctrl-single,gpio = <122 2 0x0c8>;
+					pinctrl-single,gpio-func = <1>;
+				};
+				gpiorange8: gpiorange at d401e0d0 {
+					/* GPIO124 */
+					pinctrl-single,gpio = <124 1 0x0d0>;
+					pinctrl-single,gpio-func = <0>;
+				};
+				gpiorange9: gpiorange at d401e0d4 {
+					/* GPIO125 */
+					pinctrl-single,gpio = <125 1 0x0d4>;
+					pinctrl-single,gpio-func = <1>;
+				};
+				gpiorange10: gpiorange at d401e06c {
+					/* GPIO126 ~ GPIO127 */
+					pinctrl-single,gpio = <126 2 0x06c>;
+					pinctrl-single,gpio-func = <0>;
+				};
+			};
+
 			timer0: timer at d4014000 {
 				compatible = "mrvl,mmp-timer";
 				reg = <0xd4014000 0x100>;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 5/9] document: devicetree: bind pinconf with pin-single
  2012-10-31 23:04 [PATCH v3 0/9]: pinctrl-single support DT Haojian Zhuang
                   ` (3 preceding siblings ...)
  2012-10-31 23:04 ` [PATCH v3 4/9] ARM: dts: support pinctrl single in pxa910 Haojian Zhuang
@ 2012-10-31 23:04 ` Haojian Zhuang
  2012-11-01 18:04   ` Stephen Warren
  2012-10-31 23:04 ` [PATCH v3 6/9] tty: pxa: configure pin Haojian Zhuang
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 46+ messages in thread
From: Haojian Zhuang @ 2012-10-31 23:04 UTC (permalink / raw)
  To: linux-arm-kernel

Add comments with pinconf & gpio range in the document of
pinctrl-single.

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 .../devicetree/bindings/pinctrl/pinctrl-single.txt |   66 ++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt
index 2c81e45..15f4dae 100644
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt
@@ -17,6 +17,41 @@ Optional properties:
 - pinctrl-single,bit-per-mux : boolean to indicate that one register controls
   more than one pin
 
+- pinctrl-single,gpio-ranges : gpio range list of phandles.
+  Must be present if gpio range phandle is specified.
+  This property should be existing in .dtsi files for those silicons.
+
+- pinctrl-single,gpio : array with gpio range start, size & register
+  offset. Must be present if gpio range phandle is specified.
+  This property should be existing in .dts files for those boards.
+
+- pinctrl-single,gpio-func : gpio function value in the pinmux register.
+  Must be present if gpio range phandle is specified.
+  This property should be existing in .dts files for those boards.
+
+- pinctrl-single,power-source-mask : mask of setting power source in
+  the pinmux register
+
+- pinctrl-single,power-source : value of setting power source field
+  in the pinmux register
+
+- pinctrl-single,bias-mask : mask of setting bias value in the pinmux
+  register
+
+- pinctrl-single,bias-disable : value of disabling bias in the pinmux
+  register
+
+- pinctrl-single,bias-pull-down : value of setting bias pull down in
+  the pinmux register
+
+- pinctrl-single,bias-pull-up : value of setting bias pull up in the
+  pinmux register
+
+- pinctrl-single,bias : value of setting bias in the pinmux register
+
+- pinctrl-single,input-schmitt-mask : mask of setting input schmitt
+  in the pinmux register
+
 This driver assumes that there is only one register for each pin (unless the
 pinctrl-single,bit-per-mux is set), and uses the common pinctrl bindings as
 specified in the pinctrl-bindings.txt document in this directory.
@@ -42,6 +77,15 @@ Where 0xdc is the offset from the pinctrl register base address for the
 device pinctrl register, 0x18 is the desired value, and 0xff is the sub mask to
 be used when applying this change to the register.
 
+In case pinctrl device supports gpio function, it needs to define gpio range.
+All the phandles of gpio range list should be set in below:
+
+	pinctrl-single,gpio-ranges = <[phandle of gpio range]>;
+
+	[phandle of gpio range]: {
+		pinctrl-single,gpio = <0 55 0x0dc>;
+		pinctrl-single,gpio-func = <0>;
+	};
 Example:
 
 /* SoC common file */
@@ -76,6 +120,28 @@ control_devconf0: pinmux at 48002274 {
 	pinctrl-single,function-mask = <0x5F>;
 };
 
+/* third controller instance for pins in gpio domain */
+pmx_gpio: pinmux at d401e000 {
+	compatible = "pinctrl-single";
+	reg = <0xd401e000 0x0330>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	pinctrl-single,register-width = <32>;
+	pinctrl-single,function-mask = <7>;
+	pinctrl-single,gpio-ranges = <&gpiorange0 &gpiorange1>;
+};
+
+gpiorange0: gpiorange at d401e0dc {
+	pinctrl-single,gpio = <0 55 0x0dc>;
+	pinctrl-single,gpio-func = <0>;
+};
+
+gpiorange1: gpiorange at d401e2f0 {
+	pinctrl-single,gpio = <55 5 0x2f0>;
+	pinctrl-single,gpio-func = <1>;
+};
+
+
 /* board specific .dts file */
 
 &pmx_core {
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 6/9] tty: pxa: configure pin
  2012-10-31 23:04 [PATCH v3 0/9]: pinctrl-single support DT Haojian Zhuang
                   ` (4 preceding siblings ...)
  2012-10-31 23:04 ` [PATCH v3 5/9] document: devicetree: bind pinconf with pin-single Haojian Zhuang
@ 2012-10-31 23:04 ` Haojian Zhuang
  2012-10-31 23:04 ` [PATCH v3 7/9] i2c: pxa: use devm_kzalloc Haojian Zhuang
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 46+ messages in thread
From: Haojian Zhuang @ 2012-10-31 23:04 UTC (permalink / raw)
  To: linux-arm-kernel

Configure pins by pinctrl driver.

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/tty/serial/pxa.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c
index 9033fc6..02dc771 100644
--- a/drivers/tty/serial/pxa.c
+++ b/drivers/tty/serial/pxa.c
@@ -37,6 +37,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/of.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
@@ -809,6 +810,7 @@ static int serial_pxa_probe_dt(struct platform_device *pdev,
 			       struct uart_pxa_port *sport)
 {
 	struct device_node *np = pdev->dev.of_node;
+	struct pinctrl *pinctrl;
 	int ret;
 
 	if (!np)
@@ -819,6 +821,10 @@ static int serial_pxa_probe_dt(struct platform_device *pdev,
 		dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret);
 		return ret;
 	}
+	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+	if (IS_ERR(pinctrl))
+		return -EPROBE_DEFER;
+
 	sport->port.line = ret;
 	return 0;
 }
@@ -857,7 +863,7 @@ static int serial_pxa_probe(struct platform_device *dev)
 	ret = serial_pxa_probe_dt(dev, sport);
 	if (ret > 0)
 		sport->port.line = dev->id;
-	else if (ret < 0)
+	if (ret < 0)
 		goto err_clk;
 	snprintf(sport->name, PXA_NAME_LEN - 1, "UART%d", sport->port.line + 1);
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 7/9] i2c: pxa: use devm_kzalloc
  2012-10-31 23:04 [PATCH v3 0/9]: pinctrl-single support DT Haojian Zhuang
                   ` (5 preceding siblings ...)
  2012-10-31 23:04 ` [PATCH v3 6/9] tty: pxa: configure pin Haojian Zhuang
@ 2012-10-31 23:04 ` Haojian Zhuang
  2012-10-31 23:04 ` [PATCH v3 8/9] i2c: pxa: configure pinmux Haojian Zhuang
  2012-10-31 23:04 ` [PATCH v3 9/9] pinctrl: single: dump pinmux register value Haojian Zhuang
  8 siblings, 0 replies; 46+ messages in thread
From: Haojian Zhuang @ 2012-10-31 23:04 UTC (permalink / raw)
  To: linux-arm-kernel

Use devm_kzalloc & add checking in probe() function.

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
Cc: Ben Dooks <ben-linux@fluff.org>
---
 drivers/i2c/busses/i2c-pxa.c |   26 ++++++++++----------------
 1 file changed, 10 insertions(+), 16 deletions(-)

diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 1034d93..7c8b5d0 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -1078,6 +1078,8 @@ static int i2c_pxa_probe_pdata(struct platform_device *pdev,
 	struct i2c_pxa_platform_data *plat = pdev->dev.platform_data;
 	const struct platform_device_id *id = platform_get_device_id(pdev);
 
+	if (!id)
+		return -EINVAL;
 	*i2c_types = id->driver_data;
 	if (plat) {
 		i2c->use_pio = plat->use_pio;
@@ -1094,29 +1096,23 @@ static int i2c_pxa_probe(struct platform_device *dev)
 	struct resource *res = NULL;
 	int ret, irq;
 
-	i2c = kzalloc(sizeof(struct pxa_i2c), GFP_KERNEL);
-	if (!i2c) {
-		ret = -ENOMEM;
-		goto emalloc;
-	}
+	i2c = devm_kzalloc(&dev->dev, sizeof(struct pxa_i2c), GFP_KERNEL);
+	if (!i2c)
+		return -ENOMEM;
 
 	ret = i2c_pxa_probe_dt(dev, i2c, &i2c_type);
 	if (ret > 0)
 		ret = i2c_pxa_probe_pdata(dev, i2c, &i2c_type);
 	if (ret < 0)
-		goto eclk;
+		return ret;
 
 	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
 	irq = platform_get_irq(dev, 0);
-	if (res == NULL || irq < 0) {
-		ret = -ENODEV;
-		goto eclk;
-	}
+	if (res == NULL || irq < 0)
+		return -ENODEV;
 
-	if (!request_mem_region(res->start, resource_size(res), res->name)) {
-		ret = -ENOMEM;
-		goto eclk;
-	}
+	if (!request_mem_region(res->start, resource_size(res), res->name))
+		return -ENOMEM;
 
 	i2c->adap.owner   = THIS_MODULE;
 	i2c->adap.retries = 5;
@@ -1209,8 +1205,6 @@ ereqirq:
 eremap:
 	clk_put(i2c->clk);
 eclk:
-	kfree(i2c);
-emalloc:
 	release_mem_region(res->start, resource_size(res));
 	return ret;
 }
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 8/9] i2c: pxa: configure pinmux
  2012-10-31 23:04 [PATCH v3 0/9]: pinctrl-single support DT Haojian Zhuang
                   ` (6 preceding siblings ...)
  2012-10-31 23:04 ` [PATCH v3 7/9] i2c: pxa: use devm_kzalloc Haojian Zhuang
@ 2012-10-31 23:04 ` Haojian Zhuang
  2012-10-31 23:04 ` [PATCH v3 9/9] pinctrl: single: dump pinmux register value Haojian Zhuang
  8 siblings, 0 replies; 46+ messages in thread
From: Haojian Zhuang @ 2012-10-31 23:04 UTC (permalink / raw)
  To: linux-arm-kernel

Configure pins by pinctrl driver.

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
Cc: Ben Dooks <ben-linux@fluff.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/i2c/busses/i2c-pxa.c |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 7c8b5d0..11e4a30 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -32,6 +32,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_i2c.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
 #include <linux/err.h>
 #include <linux/clk.h>
@@ -1051,6 +1052,7 @@ static int i2c_pxa_probe_dt(struct platform_device *pdev, struct pxa_i2c *i2c,
 			    enum pxa_i2c_types *i2c_types)
 {
 	struct device_node *np = pdev->dev.of_node;
+	struct pinctrl *pinctrl;
 	const struct of_device_id *of_id =
 			of_match_device(i2c_pxa_dt_ids, &pdev->dev);
 	int ret;
@@ -1063,6 +1065,9 @@ static int i2c_pxa_probe_dt(struct platform_device *pdev, struct pxa_i2c *i2c,
 		return ret;
 	}
 	pdev->id = ret;
+	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+	if (IS_ERR(pinctrl))
+		return -EPROBE_DEFER;
 	if (of_get_property(np, "mrvl,i2c-polling", NULL))
 		i2c->use_pio = 1;
 	if (of_get_property(np, "mrvl,i2c-fast-mode", NULL))
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 9/9] pinctrl: single: dump pinmux register value
  2012-10-31 23:04 [PATCH v3 0/9]: pinctrl-single support DT Haojian Zhuang
                   ` (7 preceding siblings ...)
  2012-10-31 23:04 ` [PATCH v3 8/9] i2c: pxa: configure pinmux Haojian Zhuang
@ 2012-10-31 23:04 ` Haojian Zhuang
  2012-11-01  0:47   ` Tony Lindgren
  8 siblings, 1 reply; 46+ messages in thread
From: Haojian Zhuang @ 2012-10-31 23:04 UTC (permalink / raw)
  To: linux-arm-kernel

Dump pinmux register value, not only function part in the pinmux
register.

Also fix the issue on caluclating pin offset. The last parameter
should be pin number, not register offset.

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 drivers/pinctrl/pinctrl-single.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index 3b97b65..72017e7 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -283,15 +283,15 @@ static int pcs_get_group_pins(struct pinctrl_dev *pctldev,
 
 static void pcs_pin_dbg_show(struct pinctrl_dev *pctldev,
 					struct seq_file *s,
-					unsigned offset)
+					unsigned pin)
 {
 	struct pcs_device *pcs;
-	unsigned val;
+	unsigned val, mux_bytes;
 
 	pcs = pinctrl_dev_get_drvdata(pctldev);
 
-	val = pcs->read(pcs->base + offset);
-	val &= pcs->fmask;
+	mux_bytes = pcs->width / BITS_PER_BYTE;
+	val = pcs->read(pcs->base + pin * mux_bytes);
 
 	seq_printf(s, "%08x %s " , val, DRIVER_NAME);
 }
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 3/9] pinctrl: single: support pinconf generic
  2012-10-31 23:04 ` [PATCH v3 3/9] pinctrl: single: support pinconf generic Haojian Zhuang
@ 2012-11-01  0:44   ` Tony Lindgren
  2012-11-07  7:27     ` [PATCH 08/10] " Haojian Zhuang
  0 siblings, 1 reply; 46+ messages in thread
From: Tony Lindgren @ 2012-11-01  0:44 UTC (permalink / raw)
  To: linux-arm-kernel

> --- a/drivers/pinctrl/pinctrl-single.c
> +++ b/drivers/pinctrl/pinctrl-single.c
> @@ -20,6 +20,7 @@
>  #include <linux/of_device.h>
>  #include <linux/of_address.h>
>  
> +#include <linux/pinctrl/pinconf-generic.h>
>  #include <linux/pinctrl/pinctrl.h>
>  #include <linux/pinctrl/pinmux.h>
>  
> @@ -28,6 +29,9 @@
>  #define DRIVER_NAME			"pinctrl-single"
>  #define PCS_MUX_PINS_NAME		"pinctrl-single,pins"
>  #define PCS_MUX_BITS_NAME		"pinctrl-single,bits"
> +#define PCS_BIAS_NAME			"pinctrl-single,bias"
> +#define PCS_POWER_SOURCE_NAME		"pinctrl-single,power-source"
> +#define PCS_SCHMITT_NAME		"pinctrl-single,input-schmitt"
>  #define PCS_REG_NAME_LEN		((sizeof(unsigned long) * 2) + 1)
>  #define PCS_OFF_DISABLED		~0U
>  #define PCS_MAX_GPIO_VALUES		3

Here too you can remove the new defines.

>  static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
>  						struct device_node *np,
>  						struct pinctrl_map **map,
> +						unsigned num_configs,
>  						const char **pgnames)
>  {
...

Then I suggest you add a generic pinconf-generic property to
indicate the controller supports pinconf. At least for omaps,
only some register ranges support pinconf. And by adding
pinconf-generic, you can parse it once during the probe of
pinctrl-single.c, and set pcs->pinconf flag.

Then you can use here and avoid calling of_property_read_u32
for about 600 times unnecessarily for omap4:

if (pcs->pinconf) {

> +	if (!num_configs)
> +		return 0;
> +	config = devm_kzalloc(pcs->dev, sizeof(*config) * num_configs,
> +			      GFP_KERNEL);
> +	if (!config) {
> +		res = -ENOMEM;
> +		goto free_pingroup;
> +	}
> +	index = 0;
> +
> +	if (!of_property_read_u32(np, PCS_SCHMITT_NAME, &value))
> +		config[index++] =
> +			pinconf_to_config_packed(PIN_CONFIG_INPUT_SCHMITT,
> +						 value & 0xffff);
> +	if (!of_property_read_u32(np, PCS_BIAS_NAME, &value))
> +		config[index++] =
> +			pinconf_to_config_packed(PIN_CONFIG_BIAS_DISABLE,
> +						 value & 0xffff);
> +	if (!of_property_read_u32(np, PCS_POWER_SOURCE_NAME, &value))
> +		config[index++] =
> +			pinconf_to_config_packed(PIN_CONFIG_POWER_SOURCE,
> +						 value & 0xffff);

}

> +static int pcs_dt_check_maps(struct device_node *np, unsigned *num_maps,
> +			     unsigned *num_configs)
> +{
> +	unsigned size;
> +
> +	*num_maps = 0;
> +	*num_configs = 0;
> +	if (of_get_property(np, PCS_MUX_PINS_NAME, &size)
> +		|| of_get_property(np, PCS_MUX_BITS_NAME, &size))
> +		(*num_maps)++;
> +	if (of_get_property(np, PCS_SCHMITT_NAME, &size))
> +		(*num_configs)++;
> +	if (of_get_property(np, PCS_BIAS_NAME, &size))
> +		(*num_configs)++;
> +	if (of_get_property(np, PCS_POWER_SOURCE_NAME, &size))
> +		(*num_configs)++;
> +	if (*num_configs)
> +		(*num_maps)++;
> +	if (!(*num_maps))
> +		return -EINVAL;
> +	return 0;
> +}
> +
>  /**
>   * pcs_dt_node_to_map() - allocates and parses pinctrl maps
>   * @pctldev: pinctrl instance
> @@ -802,29 +1019,32 @@ static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev,
>  {
>  	struct pcs_device *pcs;
>  	const char **pgnames;
> +	unsigned num_configs;
>  	int ret;
>  
>  	pcs = pinctrl_dev_get_drvdata(pctldev);

Here too:

if (pcs->pinconf) {
  
> -	*map = devm_kzalloc(pcs->dev, sizeof(**map), GFP_KERNEL);
> +	ret = pcs_dt_check_maps(np_config, num_maps, &num_configs);
> +	if (ret)
> +		return ret;
> +
> +	*map = devm_kzalloc(pcs->dev, sizeof(**map) * (*num_maps), GFP_KERNEL);
>  	if (!map)
>  		return -ENOMEM;

} else {
 
> -	*num_maps = 0;
> -

}

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v3 9/9] pinctrl: single: dump pinmux register value
  2012-10-31 23:04 ` [PATCH v3 9/9] pinctrl: single: dump pinmux register value Haojian Zhuang
@ 2012-11-01  0:47   ` Tony Lindgren
  2012-11-01  5:48     ` Haojian Zhuang
  0 siblings, 1 reply; 46+ messages in thread
From: Tony Lindgren @ 2012-11-01  0:47 UTC (permalink / raw)
  To: linux-arm-kernel

* Haojian Zhuang <haojian.zhuang@gmail.com> [121031 16:07]:
> Dump pinmux register value, not only function part in the pinmux
> register.
> 
> Also fix the issue on caluclating pin offset. The last parameter
> should be pin number, not register offset.

You have a minor typo   ^^^^^^^^^^^ should be calculating
instead.

Is there a bug that should be fixed for the -rc cycle
here? That's the impression I get from the description.
Or is it just a cosmetic fix to rename offset to pin?

Regards,

Tony
 
> Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
> ---
>  drivers/pinctrl/pinctrl-single.c |    8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
> index 3b97b65..72017e7 100644
> --- a/drivers/pinctrl/pinctrl-single.c
> +++ b/drivers/pinctrl/pinctrl-single.c
> @@ -283,15 +283,15 @@ static int pcs_get_group_pins(struct pinctrl_dev *pctldev,
>  
>  static void pcs_pin_dbg_show(struct pinctrl_dev *pctldev,
>  					struct seq_file *s,
> -					unsigned offset)
> +					unsigned pin)
>  {
>  	struct pcs_device *pcs;
> -	unsigned val;
> +	unsigned val, mux_bytes;
>  
>  	pcs = pinctrl_dev_get_drvdata(pctldev);
>  
> -	val = pcs->read(pcs->base + offset);
> -	val &= pcs->fmask;
> +	mux_bytes = pcs->width / BITS_PER_BYTE;
> +	val = pcs->read(pcs->base + pin * mux_bytes);
>  
>  	seq_printf(s, "%08x %s " , val, DRIVER_NAME);
>  }
> -- 
> 1.7.10.4
> 

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v3 9/9] pinctrl: single: dump pinmux register value
  2012-11-01  0:47   ` Tony Lindgren
@ 2012-11-01  5:48     ` Haojian Zhuang
  2012-11-06 14:39       ` Linus Walleij
  0 siblings, 1 reply; 46+ messages in thread
From: Haojian Zhuang @ 2012-11-01  5:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Nov 1, 2012 at 1:47 AM, Tony Lindgren <tony@atomide.com> wrote:
> * Haojian Zhuang <haojian.zhuang@gmail.com> [121031 16:07]:
>> Dump pinmux register value, not only function part in the pinmux
>> register.
>>
>> Also fix the issue on caluclating pin offset. The last parameter
>> should be pin number, not register offset.
>
> You have a minor typo   ^^^^^^^^^^^ should be calculating
> instead.
>
> Is there a bug that should be fixed for the -rc cycle
> here? That's the impression I get from the description.
> Or is it just a cosmetic fix to rename offset to pin?
>
> Regards,
>
> Tony
>
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
>> ---
>>  drivers/pinctrl/pinctrl-single.c |    8 ++++----
>>  1 file changed, 4 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
>> index 3b97b65..72017e7 100644
>> --- a/drivers/pinctrl/pinctrl-single.c
>> +++ b/drivers/pinctrl/pinctrl-single.c
>> @@ -283,15 +283,15 @@ static int pcs_get_group_pins(struct pinctrl_dev *pctldev,
>>
>>  static void pcs_pin_dbg_show(struct pinctrl_dev *pctldev,
>>                                       struct seq_file *s,
>> -                                     unsigned offset)
>> +                                     unsigned pin)
>>  {
>>       struct pcs_device *pcs;
>> -     unsigned val;
>> +     unsigned val, mux_bytes;
>>
>>       pcs = pinctrl_dev_get_drvdata(pctldev);
>>
>> -     val = pcs->read(pcs->base + offset);
>> -     val &= pcs->fmask;
>> +     mux_bytes = pcs->width / BITS_PER_BYTE;
>> +     val = pcs->read(pcs->base + pin * mux_bytes);
>>
>>       seq_printf(s, "%08x %s " , val, DRIVER_NAME);
>>  }
>> --
>> 1.7.10.4
>>

There's also include a bug fix. I'm OK that this patch could be
included in -rc cycle.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v3 5/9] document: devicetree: bind pinconf with pin-single
  2012-10-31 23:04 ` [PATCH v3 5/9] document: devicetree: bind pinconf with pin-single Haojian Zhuang
@ 2012-11-01 18:04   ` Stephen Warren
  2012-11-02 16:37     ` Tony Lindgren
  2012-11-07 15:04     ` Haojian Zhuang
  0 siblings, 2 replies; 46+ messages in thread
From: Stephen Warren @ 2012-11-01 18:04 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/31/2012 05:04 PM, Haojian Zhuang wrote:
> Add comments with pinconf & gpio range in the document of
> pinctrl-single.

I'd tend to suggest separating the series to add GPIO range support and
pinconf support, especially since didn't Tony suggest a separate driver
for pinconf? Perhaps that was just for non-generic properties.

> +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt

> +- pinctrl-single,gpio-ranges : gpio range list of phandles.
> +  Must be present if gpio range phandle is specified.
> +  This property should be existing in .dtsi files for those silicons.
> +
> +- pinctrl-single,gpio : array with gpio range start, size & register
> +  offset. Must be present if gpio range phandle is specified.
> +  This property should be existing in .dts files for those boards.
> +
> +- pinctrl-single,gpio-func : gpio function value in the pinmux register.
> +  Must be present if gpio range phandle is specified.
> +  This property should be existing in .dts files for those boards.

I don't see any reason why pinctrl-single,gpio or
pinctrl-single,gpio-func are board-specific rather than SoC-specific.
Surely it's the Soc HW construction that defines how the pinctrl and
GPIO modules relate to each-other? I would simply remove the last
sentence from each of the three descriptions above.

Also, isn't this list a list of properties for the main pinctrl-single
node itself? I think you should split the list up as follows:

1) A description of the main node
2) A list of required and optional properties for the main node
3) A description of what a GPIO range node is
4) A list of required and optional properties for a GPIO range node.

I think that would explain the whole structure a lot more clearly.

Oh, and why not just get rid of the pinctrl-single,gpio-ranges property
entirely, and simply make the GPIO range definitions be child nodes of
the pinctrl-single node? That would require them to either be named
according to some scheme or have some compatible property to
differentiate them from any other nodes, but I think that's workable.

> @@ -42,6 +77,15 @@ Where 0xdc is the offset from the pinctrl register base address for the
>  device pinctrl register, 0x18 is the desired value, and 0xff is the sub mask to
>  be used when applying this change to the register.
>  
> +In case pinctrl device supports gpio function, it needs to define gpio range.
> +All the phandles of gpio range list should be set in below:
> +
> +	pinctrl-single,gpio-ranges = <[phandle of gpio range]>;
> +
> +	[phandle of gpio range]: {

That's a label, not a phandle. The reference to the label gets compiled
to a phandle in the DTB. The node name is missing. you should probably
just use an example label and re-write the last 3 lines as:

	pinctrl-single,gpio-ranges = <&range0>;

	range0: range0 {

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v3 5/9] document: devicetree: bind pinconf with pin-single
  2012-11-01 18:04   ` Stephen Warren
@ 2012-11-02 16:37     ` Tony Lindgren
  2012-11-07 15:04     ` Haojian Zhuang
  1 sibling, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-11-02 16:37 UTC (permalink / raw)
  To: linux-arm-kernel

* Stephen Warren <swarren@wwwdotorg.org> [121101 11:06]:
> On 10/31/2012 05:04 PM, Haojian Zhuang wrote:
> > Add comments with pinconf & gpio range in the document of
> > pinctrl-single.
> 
> I'd tend to suggest separating the series to add GPIO range support and
> pinconf support, especially since didn't Tony suggest a separate driver
> for pinconf? Perhaps that was just for non-generic properties.

Well I was just thinking setting them up as separate driver
instances for the register ranges supporting pinconf and
not supporting pinconf. This combined with some pinconf
property parsed during pinctrl-single.c probe time allows
saving lots of unnecessary parsing of properties for
register ranges that don't support pinconf. At least for
omaps we have few hundred registers that don't support
pinconf, and then some separate random register that do.

Regards,

TOny 

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v3 9/9] pinctrl: single: dump pinmux register value
  2012-11-01  5:48     ` Haojian Zhuang
@ 2012-11-06 14:39       ` Linus Walleij
  0 siblings, 0 replies; 46+ messages in thread
From: Linus Walleij @ 2012-11-06 14:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Nov 1, 2012 at 6:48 AM, Haojian Zhuang <haojian.zhuang@gmail.com> wrote:
> On Thu, Nov 1, 2012 at 1:47 AM, Tony Lindgren <tony@atomide.com> wrote:

>>>  static void pcs_pin_dbg_show(struct pinctrl_dev *pctldev,
>>>                                       struct seq_file *s,
>>> -                                     unsigned offset)
>>> +                                     unsigned pin)
>>>  {
>>>       struct pcs_device *pcs;
>>> -     unsigned val;
>>> +     unsigned val, mux_bytes;
>>>
>>>       pcs = pinctrl_dev_get_drvdata(pctldev);
>>>
>>> -     val = pcs->read(pcs->base + offset);
>>> -     val &= pcs->fmask;
>>> +     mux_bytes = pcs->width / BITS_PER_BYTE;
>>> +     val = pcs->read(pcs->base + pin * mux_bytes);
>>>
>>>       seq_printf(s, "%08x %s " , val, DRIVER_NAME);
>>>  }
>>> --
>>> 1.7.10.4
>>>
>
> There's also include a bug fix. I'm OK that this patch could be
> included in -rc cycle.

A debug print can by definition not be a regression, it
should not have a specific use other than debugging.

And those debugging can use linux-next or separate
patches or whatever ... better keep this series together.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 08/10] pinctrl: single: support pinconf generic
  2012-11-01  0:44   ` Tony Lindgren
@ 2012-11-07  7:27     ` Haojian Zhuang
  0 siblings, 0 replies; 46+ messages in thread
From: Haojian Zhuang @ 2012-11-07  7:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday, November 1, 2012, Tony Lindgren wrote:
>
> > --- a/drivers/pinctrl/pinctrl-single.c
> > +++ b/drivers/pinctrl/pinctrl-single.c
> > @@ -20,6 +20,7 @@
> >  #include <linux/of_device.h>
> >  #include <linux/of_address.h>
> >
> > +#include <linux/pinctrl/pinconf-generic.h>
> >  #include <linux/pinctrl/pinctrl.h>
> >  #include <linux/pinctrl/pinmux.h>
> >
> > @@ -28,6 +29,9 @@
> >  #define DRIVER_NAME                  "pinctrl-single"
> >  #define PCS_MUX_PINS_NAME            "pinctrl-single,pins"
> >  #define PCS_MUX_BITS_NAME            "pinctrl-single,bits"
> > +#define PCS_BIAS_NAME                        "pinctrl-single,bias"
> > +#define PCS_POWER_SOURCE_NAME                "pinctrl-single,power-source"
> > +#define PCS_SCHMITT_NAME             "pinctrl-single,input-schmitt"
> >  #define PCS_REG_NAME_LEN             ((sizeof(unsigned long) * 2) + 1)
> >  #define PCS_OFF_DISABLED             ~0U
> >  #define PCS_MAX_GPIO_VALUES          3
>
> Here too you can remove the new defines.
>
> >  static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
> >                                               struct device_node *np,
> >                                               struct pinctrl_map **map,
> > +                                             unsigned num_configs,
> >                                               const char **pgnames)
> >  {
> ...
>
> Then I suggest you add a generic pinconf-generic property to
> indicate the controller supports pinconf. At least for omaps,
> only some register ranges support pinconf. And by adding
> pinconf-generic, you can parse it once during the probe of
> pinctrl-single.c, and set pcs->pinconf flag.
>
> Then you can use here and avoid calling of_property_read_u32
> for about 600 times unnecessarily for omap4:
>
I don't want to add new property for this. I think that we can use
compatible name instead.

"pinctrl-single" is only for pinmux & gpio range.
"pinconf-single" is for pinmux & gpio range & generic pinconf.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v3 5/9] document: devicetree: bind pinconf with pin-single
  2012-11-01 18:04   ` Stephen Warren
  2012-11-02 16:37     ` Tony Lindgren
@ 2012-11-07 15:04     ` Haojian Zhuang
  1 sibling, 0 replies; 46+ messages in thread
From: Haojian Zhuang @ 2012-11-07 15:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Nov 2, 2012 at 2:04 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 10/31/2012 05:04 PM, Haojian Zhuang wrote:
>> Add comments with pinconf & gpio range in the document of
>> pinctrl-single.
>
> I'd tend to suggest separating the series to add GPIO range support and
> pinconf support, especially since didn't Tony suggest a separate driver
> for pinconf? Perhaps that was just for non-generic properties.
>
>> +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt
>
>> +- pinctrl-single,gpio-ranges : gpio range list of phandles.
>> +  Must be present if gpio range phandle is specified.
>> +  This property should be existing in .dtsi files for those silicons.
>> +
>> +- pinctrl-single,gpio : array with gpio range start, size & register
>> +  offset. Must be present if gpio range phandle is specified.
>> +  This property should be existing in .dts files for those boards.
>> +
>> +- pinctrl-single,gpio-func : gpio function value in the pinmux register.
>> +  Must be present if gpio range phandle is specified.
>> +  This property should be existing in .dts files for those boards.
>
> I don't see any reason why pinctrl-single,gpio or
> pinctrl-single,gpio-func are board-specific rather than SoC-specific.

Oh, I wrote it with error. It should be SoC-specific.

> Surely it's the Soc HW construction that defines how the pinctrl and
> GPIO modules relate to each-other? I would simply remove the last
> sentence from each of the three descriptions above.
>
> Also, isn't this list a list of properties for the main pinctrl-single
> node itself? I think you should split the list up as follows:
>
> 1) A description of the main node
> 2) A list of required and optional properties for the main node
> 3) A description of what a GPIO range node is
> 4) A list of required and optional properties for a GPIO range node.
>
> I think that would explain the whole structure a lot more clearly.
>
> Oh, and why not just get rid of the pinctrl-single,gpio-ranges property
> entirely, and simply make the GPIO range definitions be child nodes of
> the pinctrl-single node? That would require them to either be named
> according to some scheme or have some compatible property to
> differentiate them from any other nodes, but I think that's workable.
>
Em. Removing pinctrl-single,gpio-ranges should be better. Now I define
range as sub node. There're two properties in this sub-node: reg &
pinctrl-single,gpio.

>> @@ -42,6 +77,15 @@ Where 0xdc is the offset from the pinctrl register base address for the
>>  device pinctrl register, 0x18 is the desired value, and 0xff is the sub mask to
>>  be used when applying this change to the register.
>>
>> +In case pinctrl device supports gpio function, it needs to define gpio range.
>> +All the phandles of gpio range list should be set in below:
>> +
>> +     pinctrl-single,gpio-ranges = <[phandle of gpio range]>;
>> +
>> +     [phandle of gpio range]: {
>
> That's a label, not a phandle. The reference to the label gets compiled
> to a phandle in the DTB. The node name is missing. you should probably
> just use an example label and re-write the last 3 lines as:
>
>         pinctrl-single,gpio-ranges = <&range0>;
>
>         range0: range0 {
>
Updated.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 08/10] pinctrl: single: support pinconf generic
  2012-10-25 23:43                     ` Tony Lindgren
@ 2012-10-31 22:37                         ` Haojian Zhuang
  -1 siblings, 0 replies; 46+ messages in thread
From: Haojian Zhuang @ 2012-10-31 22:37 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Fri, Oct 26, 2012 at 1:43 AM, Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> wrote:
> * Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> [121022 10:11]:
>> * Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> [121022 03:11]:
>> > On Sat, Oct 20, 2012 at 3:13 AM, Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> wrote:
>> > > * Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> [121018 02:08]:
>> > >> Add pinconf generic support with POWER SOURCE, BIAS PULL.
>> > > ...
>> > >
>> > >> +     case PIN_CONFIG_POWER_SOURCE:
>> > >> +             if (pcs->psmask == PCS_OFF_DISABLED
>> > >> +                     || pcs->psshift == PCS_OFF_DISABLED)
>> > >> +                     return -ENOTSUPP;
>> > >> +             data &= pcs->psmask;
>> > >> +             data = data >> pcs->psshift;
>> > >> +             *config = data;
>> > >> +             return 0;
>> > >> +             break;
>> > >
>> > > Hmm, only slightly related to this patch, mostly a generic
>> > > question to others: Do others have any mux registers with
>> > > status bits for things like PIN_CONFIG_POWER_SOURCE?
>> > >
>> > > I could use PIN_CONFIG_POWER_SOURCE for controlling the PBIAS
>> > > for omap MMC. But there's also a status bit that needs to be
>> > > checked for that. I think there was some other similar mux
>> > > register for USB PHY that has a status register.
>> > >
>> > > So I'm wondering should the checking for status bit be handled
>> > > in the pinctrl consume driver? Or should we have some bindings
>> > > for that?
>> > >
>> >
>> > Do you mean that the status register only exists in USB PHY controller or
>> > MMC controller?
>>
>> The status register is in the MMC PBIAS register that is mux
>> related otherwise. From OMAP4470_ES1.0_PUBLIC_TRM_vE.pdf,
>> Table 19-599. CONTROL_PBIASLITE:
>>
>> Bits
>> 26    MMC1_PWDNZ
>> 25    MMC1_PBIASLITE_HIZ_MODE
>> 24    MMC1_PBIASLITE_SUPPLY_HI_OUT
>> 23    MMC1_PBIASLITE_VMODE_ERROR      then this bit needs to clear..
>> 22    MMC1_PBIASLITE_PWRDNZ
>> 21    MMC1_PBIASLITE_VMODE            ..after VMODE bit is set to 3V
>>
>> > If so, could we use regulator framework in USB PHY or MMC driver?
>>
>> Yes we could use regulator framework for that that. Or just read the
>> status in the MMC driver for that bit if nobody else has mixed
>> mux-regulator needs like this.
>>
>> The sequence is MMC specific, so from that point of view it would
>> make sense to have the logic in the MMC driver.
>
> Well it turns out the VMODE_ERROR bit is not just for VMODE, it's a
> comparator that can also triggers for the other invalid states for
> CONTROL_PBIASLITE pinconf register. So hiding VMODE_ERROR into a
> regulator would be wrong. For now, VMODE best handled using
> PIN_CONFIG_POWER_SOURCE and let the MMC driver do the checking
> using the pinconf API.
>
I'm seeking whether there's more flexible way to support your case.
The fix won't
be contained in v3 round.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 08/10] pinctrl: single: support pinconf generic
@ 2012-10-31 22:37                         ` Haojian Zhuang
  0 siblings, 0 replies; 46+ messages in thread
From: Haojian Zhuang @ 2012-10-31 22:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Oct 26, 2012 at 1:43 AM, Tony Lindgren <tony@atomide.com> wrote:
> * Tony Lindgren <tony@atomide.com> [121022 10:11]:
>> * Haojian Zhuang <haojian.zhuang@gmail.com> [121022 03:11]:
>> > On Sat, Oct 20, 2012 at 3:13 AM, Tony Lindgren <tony@atomide.com> wrote:
>> > > * Haojian Zhuang <haojian.zhuang@gmail.com> [121018 02:08]:
>> > >> Add pinconf generic support with POWER SOURCE, BIAS PULL.
>> > > ...
>> > >
>> > >> +     case PIN_CONFIG_POWER_SOURCE:
>> > >> +             if (pcs->psmask == PCS_OFF_DISABLED
>> > >> +                     || pcs->psshift == PCS_OFF_DISABLED)
>> > >> +                     return -ENOTSUPP;
>> > >> +             data &= pcs->psmask;
>> > >> +             data = data >> pcs->psshift;
>> > >> +             *config = data;
>> > >> +             return 0;
>> > >> +             break;
>> > >
>> > > Hmm, only slightly related to this patch, mostly a generic
>> > > question to others: Do others have any mux registers with
>> > > status bits for things like PIN_CONFIG_POWER_SOURCE?
>> > >
>> > > I could use PIN_CONFIG_POWER_SOURCE for controlling the PBIAS
>> > > for omap MMC. But there's also a status bit that needs to be
>> > > checked for that. I think there was some other similar mux
>> > > register for USB PHY that has a status register.
>> > >
>> > > So I'm wondering should the checking for status bit be handled
>> > > in the pinctrl consume driver? Or should we have some bindings
>> > > for that?
>> > >
>> >
>> > Do you mean that the status register only exists in USB PHY controller or
>> > MMC controller?
>>
>> The status register is in the MMC PBIAS register that is mux
>> related otherwise. From OMAP4470_ES1.0_PUBLIC_TRM_vE.pdf,
>> Table 19-599. CONTROL_PBIASLITE:
>>
>> Bits
>> 26    MMC1_PWDNZ
>> 25    MMC1_PBIASLITE_HIZ_MODE
>> 24    MMC1_PBIASLITE_SUPPLY_HI_OUT
>> 23    MMC1_PBIASLITE_VMODE_ERROR      then this bit needs to clear..
>> 22    MMC1_PBIASLITE_PWRDNZ
>> 21    MMC1_PBIASLITE_VMODE            ..after VMODE bit is set to 3V
>>
>> > If so, could we use regulator framework in USB PHY or MMC driver?
>>
>> Yes we could use regulator framework for that that. Or just read the
>> status in the MMC driver for that bit if nobody else has mixed
>> mux-regulator needs like this.
>>
>> The sequence is MMC specific, so from that point of view it would
>> make sense to have the logic in the MMC driver.
>
> Well it turns out the VMODE_ERROR bit is not just for VMODE, it's a
> comparator that can also triggers for the other invalid states for
> CONTROL_PBIASLITE pinconf register. So hiding VMODE_ERROR into a
> regulator would be wrong. For now, VMODE best handled using
> PIN_CONFIG_POWER_SOURCE and let the MMC driver do the checking
> using the pinconf API.
>
I'm seeking whether there's more flexible way to support your case.
The fix won't
be contained in v3 round.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 08/10] pinctrl: single: support pinconf generic
  2012-10-26  1:47                         ` Haojian Zhuang
@ 2012-10-26 17:29                             ` Tony Lindgren
  -1 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-10-26 17:29 UTC (permalink / raw)
  To: Haojian Zhuang
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

* Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> [121025 18:49]:
> On Fri, Oct 26, 2012 at 7:43 AM, Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> wrote:
> > * Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> [121022 10:11]:
> >> * Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> [121022 03:11]:
> >> > On Sat, Oct 20, 2012 at 3:13 AM, Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> wrote:
> >> > > * Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> [121018 02:08]:
> >> > >> Add pinconf generic support with POWER SOURCE, BIAS PULL.
> >> > > ...
> >> > >
> >> > >> +     case PIN_CONFIG_POWER_SOURCE:
> >> > >> +             if (pcs->psmask == PCS_OFF_DISABLED
> >> > >> +                     || pcs->psshift == PCS_OFF_DISABLED)
> >> > >> +                     return -ENOTSUPP;
> >> > >> +             data &= pcs->psmask;
> >> > >> +             data = data >> pcs->psshift;
> >> > >> +             *config = data;
> >> > >> +             return 0;
> >> > >> +             break;
> >> > >
> >> > > Hmm, only slightly related to this patch, mostly a generic
> >> > > question to others: Do others have any mux registers with
> >> > > status bits for things like PIN_CONFIG_POWER_SOURCE?
> >> > >
> >> > > I could use PIN_CONFIG_POWER_SOURCE for controlling the PBIAS
> >> > > for omap MMC. But there's also a status bit that needs to be
> >> > > checked for that. I think there was some other similar mux
> >> > > register for USB PHY that has a status register.
> >> > >
> >> > > So I'm wondering should the checking for status bit be handled
> >> > > in the pinctrl consume driver? Or should we have some bindings
> >> > > for that?
> >> > >
> >> >
> >> > Do you mean that the status register only exists in USB PHY controller or
> >> > MMC controller?
> >>
> >> The status register is in the MMC PBIAS register that is mux
> >> related otherwise. From OMAP4470_ES1.0_PUBLIC_TRM_vE.pdf,
> >> Table 19-599. CONTROL_PBIASLITE:
> >>
> >> Bits
> >> 26    MMC1_PWDNZ
> >> 25    MMC1_PBIASLITE_HIZ_MODE
> >> 24    MMC1_PBIASLITE_SUPPLY_HI_OUT
> >> 23    MMC1_PBIASLITE_VMODE_ERROR      then this bit needs to clear..
> >> 22    MMC1_PBIASLITE_PWRDNZ
> >> 21    MMC1_PBIASLITE_VMODE            ..after VMODE bit is set to 3V
> >>
> >> > If so, could we use regulator framework in USB PHY or MMC driver?
> >>
> >> Yes we could use regulator framework for that that. Or just read the
> >> status in the MMC driver for that bit if nobody else has mixed
> >> mux-regulator needs like this.
> >>
> >> The sequence is MMC specific, so from that point of view it would
> >> make sense to have the logic in the MMC driver.
> >
> > Well it turns out the VMODE_ERROR bit is not just for VMODE, it's a
> > comparator that can also triggers for the other invalid states for
> > CONTROL_PBIASLITE pinconf register. So hiding VMODE_ERROR into a
> > regulator would be wrong. For now, VMODE best handled using
> > PIN_CONFIG_POWER_SOURCE and let the MMC driver do the checking
> > using the pinconf API.
> >
> > Regards,
> >
> > Tony
> 
> Could you share the link of downloading the spec?

Yes here's the omap4470 public TRM:

http://www.ti.com/litv/pdf/swpu270n

See CONTROL_PBIASLITE, and also "19.4.9.3 PBIAS Error Generation"
table on page 3520 for the combinations when the comparator can
generate errors.

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 08/10] pinctrl: single: support pinconf generic
@ 2012-10-26 17:29                             ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-10-26 17:29 UTC (permalink / raw)
  To: linux-arm-kernel

* Haojian Zhuang <haojian.zhuang@gmail.com> [121025 18:49]:
> On Fri, Oct 26, 2012 at 7:43 AM, Tony Lindgren <tony@atomide.com> wrote:
> > * Tony Lindgren <tony@atomide.com> [121022 10:11]:
> >> * Haojian Zhuang <haojian.zhuang@gmail.com> [121022 03:11]:
> >> > On Sat, Oct 20, 2012 at 3:13 AM, Tony Lindgren <tony@atomide.com> wrote:
> >> > > * Haojian Zhuang <haojian.zhuang@gmail.com> [121018 02:08]:
> >> > >> Add pinconf generic support with POWER SOURCE, BIAS PULL.
> >> > > ...
> >> > >
> >> > >> +     case PIN_CONFIG_POWER_SOURCE:
> >> > >> +             if (pcs->psmask == PCS_OFF_DISABLED
> >> > >> +                     || pcs->psshift == PCS_OFF_DISABLED)
> >> > >> +                     return -ENOTSUPP;
> >> > >> +             data &= pcs->psmask;
> >> > >> +             data = data >> pcs->psshift;
> >> > >> +             *config = data;
> >> > >> +             return 0;
> >> > >> +             break;
> >> > >
> >> > > Hmm, only slightly related to this patch, mostly a generic
> >> > > question to others: Do others have any mux registers with
> >> > > status bits for things like PIN_CONFIG_POWER_SOURCE?
> >> > >
> >> > > I could use PIN_CONFIG_POWER_SOURCE for controlling the PBIAS
> >> > > for omap MMC. But there's also a status bit that needs to be
> >> > > checked for that. I think there was some other similar mux
> >> > > register for USB PHY that has a status register.
> >> > >
> >> > > So I'm wondering should the checking for status bit be handled
> >> > > in the pinctrl consume driver? Or should we have some bindings
> >> > > for that?
> >> > >
> >> >
> >> > Do you mean that the status register only exists in USB PHY controller or
> >> > MMC controller?
> >>
> >> The status register is in the MMC PBIAS register that is mux
> >> related otherwise. From OMAP4470_ES1.0_PUBLIC_TRM_vE.pdf,
> >> Table 19-599. CONTROL_PBIASLITE:
> >>
> >> Bits
> >> 26    MMC1_PWDNZ
> >> 25    MMC1_PBIASLITE_HIZ_MODE
> >> 24    MMC1_PBIASLITE_SUPPLY_HI_OUT
> >> 23    MMC1_PBIASLITE_VMODE_ERROR      then this bit needs to clear..
> >> 22    MMC1_PBIASLITE_PWRDNZ
> >> 21    MMC1_PBIASLITE_VMODE            ..after VMODE bit is set to 3V
> >>
> >> > If so, could we use regulator framework in USB PHY or MMC driver?
> >>
> >> Yes we could use regulator framework for that that. Or just read the
> >> status in the MMC driver for that bit if nobody else has mixed
> >> mux-regulator needs like this.
> >>
> >> The sequence is MMC specific, so from that point of view it would
> >> make sense to have the logic in the MMC driver.
> >
> > Well it turns out the VMODE_ERROR bit is not just for VMODE, it's a
> > comparator that can also triggers for the other invalid states for
> > CONTROL_PBIASLITE pinconf register. So hiding VMODE_ERROR into a
> > regulator would be wrong. For now, VMODE best handled using
> > PIN_CONFIG_POWER_SOURCE and let the MMC driver do the checking
> > using the pinconf API.
> >
> > Regards,
> >
> > Tony
> 
> Could you share the link of downloading the spec?

Yes here's the omap4470 public TRM:

http://www.ti.com/litv/pdf/swpu270n

See CONTROL_PBIASLITE, and also "19.4.9.3 PBIAS Error Generation"
table on page 3520 for the combinations when the comparator can
generate errors.

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 08/10] pinctrl: single: support pinconf generic
  2012-10-25 23:43                     ` Tony Lindgren
@ 2012-10-26  1:47                         ` Haojian Zhuang
  -1 siblings, 0 replies; 46+ messages in thread
From: Haojian Zhuang @ 2012-10-26  1:47 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Fri, Oct 26, 2012 at 7:43 AM, Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> wrote:
> * Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> [121022 10:11]:
>> * Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> [121022 03:11]:
>> > On Sat, Oct 20, 2012 at 3:13 AM, Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> wrote:
>> > > * Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> [121018 02:08]:
>> > >> Add pinconf generic support with POWER SOURCE, BIAS PULL.
>> > > ...
>> > >
>> > >> +     case PIN_CONFIG_POWER_SOURCE:
>> > >> +             if (pcs->psmask == PCS_OFF_DISABLED
>> > >> +                     || pcs->psshift == PCS_OFF_DISABLED)
>> > >> +                     return -ENOTSUPP;
>> > >> +             data &= pcs->psmask;
>> > >> +             data = data >> pcs->psshift;
>> > >> +             *config = data;
>> > >> +             return 0;
>> > >> +             break;
>> > >
>> > > Hmm, only slightly related to this patch, mostly a generic
>> > > question to others: Do others have any mux registers with
>> > > status bits for things like PIN_CONFIG_POWER_SOURCE?
>> > >
>> > > I could use PIN_CONFIG_POWER_SOURCE for controlling the PBIAS
>> > > for omap MMC. But there's also a status bit that needs to be
>> > > checked for that. I think there was some other similar mux
>> > > register for USB PHY that has a status register.
>> > >
>> > > So I'm wondering should the checking for status bit be handled
>> > > in the pinctrl consume driver? Or should we have some bindings
>> > > for that?
>> > >
>> >
>> > Do you mean that the status register only exists in USB PHY controller or
>> > MMC controller?
>>
>> The status register is in the MMC PBIAS register that is mux
>> related otherwise. From OMAP4470_ES1.0_PUBLIC_TRM_vE.pdf,
>> Table 19-599. CONTROL_PBIASLITE:
>>
>> Bits
>> 26    MMC1_PWDNZ
>> 25    MMC1_PBIASLITE_HIZ_MODE
>> 24    MMC1_PBIASLITE_SUPPLY_HI_OUT
>> 23    MMC1_PBIASLITE_VMODE_ERROR      then this bit needs to clear..
>> 22    MMC1_PBIASLITE_PWRDNZ
>> 21    MMC1_PBIASLITE_VMODE            ..after VMODE bit is set to 3V
>>
>> > If so, could we use regulator framework in USB PHY or MMC driver?
>>
>> Yes we could use regulator framework for that that. Or just read the
>> status in the MMC driver for that bit if nobody else has mixed
>> mux-regulator needs like this.
>>
>> The sequence is MMC specific, so from that point of view it would
>> make sense to have the logic in the MMC driver.
>
> Well it turns out the VMODE_ERROR bit is not just for VMODE, it's a
> comparator that can also triggers for the other invalid states for
> CONTROL_PBIASLITE pinconf register. So hiding VMODE_ERROR into a
> regulator would be wrong. For now, VMODE best handled using
> PIN_CONFIG_POWER_SOURCE and let the MMC driver do the checking
> using the pinconf API.
>
> Regards,
>
> Tony

Could you share the link of downloading the spec?

Regards
Haojian

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 08/10] pinctrl: single: support pinconf generic
@ 2012-10-26  1:47                         ` Haojian Zhuang
  0 siblings, 0 replies; 46+ messages in thread
From: Haojian Zhuang @ 2012-10-26  1:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Oct 26, 2012 at 7:43 AM, Tony Lindgren <tony@atomide.com> wrote:
> * Tony Lindgren <tony@atomide.com> [121022 10:11]:
>> * Haojian Zhuang <haojian.zhuang@gmail.com> [121022 03:11]:
>> > On Sat, Oct 20, 2012 at 3:13 AM, Tony Lindgren <tony@atomide.com> wrote:
>> > > * Haojian Zhuang <haojian.zhuang@gmail.com> [121018 02:08]:
>> > >> Add pinconf generic support with POWER SOURCE, BIAS PULL.
>> > > ...
>> > >
>> > >> +     case PIN_CONFIG_POWER_SOURCE:
>> > >> +             if (pcs->psmask == PCS_OFF_DISABLED
>> > >> +                     || pcs->psshift == PCS_OFF_DISABLED)
>> > >> +                     return -ENOTSUPP;
>> > >> +             data &= pcs->psmask;
>> > >> +             data = data >> pcs->psshift;
>> > >> +             *config = data;
>> > >> +             return 0;
>> > >> +             break;
>> > >
>> > > Hmm, only slightly related to this patch, mostly a generic
>> > > question to others: Do others have any mux registers with
>> > > status bits for things like PIN_CONFIG_POWER_SOURCE?
>> > >
>> > > I could use PIN_CONFIG_POWER_SOURCE for controlling the PBIAS
>> > > for omap MMC. But there's also a status bit that needs to be
>> > > checked for that. I think there was some other similar mux
>> > > register for USB PHY that has a status register.
>> > >
>> > > So I'm wondering should the checking for status bit be handled
>> > > in the pinctrl consume driver? Or should we have some bindings
>> > > for that?
>> > >
>> >
>> > Do you mean that the status register only exists in USB PHY controller or
>> > MMC controller?
>>
>> The status register is in the MMC PBIAS register that is mux
>> related otherwise. From OMAP4470_ES1.0_PUBLIC_TRM_vE.pdf,
>> Table 19-599. CONTROL_PBIASLITE:
>>
>> Bits
>> 26    MMC1_PWDNZ
>> 25    MMC1_PBIASLITE_HIZ_MODE
>> 24    MMC1_PBIASLITE_SUPPLY_HI_OUT
>> 23    MMC1_PBIASLITE_VMODE_ERROR      then this bit needs to clear..
>> 22    MMC1_PBIASLITE_PWRDNZ
>> 21    MMC1_PBIASLITE_VMODE            ..after VMODE bit is set to 3V
>>
>> > If so, could we use regulator framework in USB PHY or MMC driver?
>>
>> Yes we could use regulator framework for that that. Or just read the
>> status in the MMC driver for that bit if nobody else has mixed
>> mux-regulator needs like this.
>>
>> The sequence is MMC specific, so from that point of view it would
>> make sense to have the logic in the MMC driver.
>
> Well it turns out the VMODE_ERROR bit is not just for VMODE, it's a
> comparator that can also triggers for the other invalid states for
> CONTROL_PBIASLITE pinconf register. So hiding VMODE_ERROR into a
> regulator would be wrong. For now, VMODE best handled using
> PIN_CONFIG_POWER_SOURCE and let the MMC driver do the checking
> using the pinconf API.
>
> Regards,
>
> Tony

Could you share the link of downloading the spec?

Regards
Haojian

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 08/10] pinctrl: single: support pinconf generic
  2012-10-22 17:09                 ` Tony Lindgren
@ 2012-10-25 23:43                     ` Tony Lindgren
  -1 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-10-25 23:43 UTC (permalink / raw)
  To: Haojian Zhuang
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

* Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> [121022 10:11]:
> * Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> [121022 03:11]:
> > On Sat, Oct 20, 2012 at 3:13 AM, Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> wrote:
> > > * Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> [121018 02:08]:
> > >> Add pinconf generic support with POWER SOURCE, BIAS PULL.
> > > ...
> > >
> > >> +     case PIN_CONFIG_POWER_SOURCE:
> > >> +             if (pcs->psmask == PCS_OFF_DISABLED
> > >> +                     || pcs->psshift == PCS_OFF_DISABLED)
> > >> +                     return -ENOTSUPP;
> > >> +             data &= pcs->psmask;
> > >> +             data = data >> pcs->psshift;
> > >> +             *config = data;
> > >> +             return 0;
> > >> +             break;
> > >
> > > Hmm, only slightly related to this patch, mostly a generic
> > > question to others: Do others have any mux registers with
> > > status bits for things like PIN_CONFIG_POWER_SOURCE?
> > >
> > > I could use PIN_CONFIG_POWER_SOURCE for controlling the PBIAS
> > > for omap MMC. But there's also a status bit that needs to be
> > > checked for that. I think there was some other similar mux
> > > register for USB PHY that has a status register.
> > >
> > > So I'm wondering should the checking for status bit be handled
> > > in the pinctrl consume driver? Or should we have some bindings
> > > for that?
> > >
> > 
> > Do you mean that the status register only exists in USB PHY controller or
> > MMC controller?
> 
> The status register is in the MMC PBIAS register that is mux
> related otherwise. From OMAP4470_ES1.0_PUBLIC_TRM_vE.pdf,
> Table 19-599. CONTROL_PBIASLITE:
> 
> Bits
> 26	MMC1_PWDNZ
> 25	MMC1_PBIASLITE_HIZ_MODE
> 24	MMC1_PBIASLITE_SUPPLY_HI_OUT
> 23	MMC1_PBIASLITE_VMODE_ERROR	then this bit needs to clear..
> 22	MMC1_PBIASLITE_PWRDNZ
> 21	MMC1_PBIASLITE_VMODE		..after VMODE bit is set to 3V
>  
> > If so, could we use regulator framework in USB PHY or MMC driver?
> 
> Yes we could use regulator framework for that that. Or just read the
> status in the MMC driver for that bit if nobody else has mixed
> mux-regulator needs like this.
> 
> The sequence is MMC specific, so from that point of view it would
> make sense to have the logic in the MMC driver.

Well it turns out the VMODE_ERROR bit is not just for VMODE, it's a
comparator that can also triggers for the other invalid states for
CONTROL_PBIASLITE pinconf register. So hiding VMODE_ERROR into a
regulator would be wrong. For now, VMODE best handled using
PIN_CONFIG_POWER_SOURCE and let the MMC driver do the checking
using the pinconf API.

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 08/10] pinctrl: single: support pinconf generic
@ 2012-10-25 23:43                     ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-10-25 23:43 UTC (permalink / raw)
  To: linux-arm-kernel

* Tony Lindgren <tony@atomide.com> [121022 10:11]:
> * Haojian Zhuang <haojian.zhuang@gmail.com> [121022 03:11]:
> > On Sat, Oct 20, 2012 at 3:13 AM, Tony Lindgren <tony@atomide.com> wrote:
> > > * Haojian Zhuang <haojian.zhuang@gmail.com> [121018 02:08]:
> > >> Add pinconf generic support with POWER SOURCE, BIAS PULL.
> > > ...
> > >
> > >> +     case PIN_CONFIG_POWER_SOURCE:
> > >> +             if (pcs->psmask == PCS_OFF_DISABLED
> > >> +                     || pcs->psshift == PCS_OFF_DISABLED)
> > >> +                     return -ENOTSUPP;
> > >> +             data &= pcs->psmask;
> > >> +             data = data >> pcs->psshift;
> > >> +             *config = data;
> > >> +             return 0;
> > >> +             break;
> > >
> > > Hmm, only slightly related to this patch, mostly a generic
> > > question to others: Do others have any mux registers with
> > > status bits for things like PIN_CONFIG_POWER_SOURCE?
> > >
> > > I could use PIN_CONFIG_POWER_SOURCE for controlling the PBIAS
> > > for omap MMC. But there's also a status bit that needs to be
> > > checked for that. I think there was some other similar mux
> > > register for USB PHY that has a status register.
> > >
> > > So I'm wondering should the checking for status bit be handled
> > > in the pinctrl consume driver? Or should we have some bindings
> > > for that?
> > >
> > 
> > Do you mean that the status register only exists in USB PHY controller or
> > MMC controller?
> 
> The status register is in the MMC PBIAS register that is mux
> related otherwise. From OMAP4470_ES1.0_PUBLIC_TRM_vE.pdf,
> Table 19-599. CONTROL_PBIASLITE:
> 
> Bits
> 26	MMC1_PWDNZ
> 25	MMC1_PBIASLITE_HIZ_MODE
> 24	MMC1_PBIASLITE_SUPPLY_HI_OUT
> 23	MMC1_PBIASLITE_VMODE_ERROR	then this bit needs to clear..
> 22	MMC1_PBIASLITE_PWRDNZ
> 21	MMC1_PBIASLITE_VMODE		..after VMODE bit is set to 3V
>  
> > If so, could we use regulator framework in USB PHY or MMC driver?
> 
> Yes we could use regulator framework for that that. Or just read the
> status in the MMC driver for that bit if nobody else has mixed
> mux-regulator needs like this.
> 
> The sequence is MMC specific, so from that point of view it would
> make sense to have the logic in the MMC driver.

Well it turns out the VMODE_ERROR bit is not just for VMODE, it's a
comparator that can also triggers for the other invalid states for
CONTROL_PBIASLITE pinconf register. So hiding VMODE_ERROR into a
regulator would be wrong. For now, VMODE best handled using
PIN_CONFIG_POWER_SOURCE and let the MMC driver do the checking
using the pinconf API.

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 08/10] pinctrl: single: support pinconf generic
  2012-10-22 10:09             ` Haojian Zhuang
@ 2012-10-22 17:09                 ` Tony Lindgren
  -1 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-10-22 17:09 UTC (permalink / raw)
  To: Haojian Zhuang
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

* Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> [121022 03:11]:
> On Sat, Oct 20, 2012 at 3:13 AM, Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> wrote:
> > * Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> [121018 02:08]:
> >> Add pinconf generic support with POWER SOURCE, BIAS PULL.
> > ...
> >
> >> +     case PIN_CONFIG_POWER_SOURCE:
> >> +             if (pcs->psmask == PCS_OFF_DISABLED
> >> +                     || pcs->psshift == PCS_OFF_DISABLED)
> >> +                     return -ENOTSUPP;
> >> +             data &= pcs->psmask;
> >> +             data = data >> pcs->psshift;
> >> +             *config = data;
> >> +             return 0;
> >> +             break;
> >
> > Hmm, only slightly related to this patch, mostly a generic
> > question to others: Do others have any mux registers with
> > status bits for things like PIN_CONFIG_POWER_SOURCE?
> >
> > I could use PIN_CONFIG_POWER_SOURCE for controlling the PBIAS
> > for omap MMC. But there's also a status bit that needs to be
> > checked for that. I think there was some other similar mux
> > register for USB PHY that has a status register.
> >
> > So I'm wondering should the checking for status bit be handled
> > in the pinctrl consume driver? Or should we have some bindings
> > for that?
> >
> 
> Do you mean that the status register only exists in USB PHY controller or
> MMC controller?

The status register is in the MMC PBIAS register that is mux
related otherwise. From OMAP4470_ES1.0_PUBLIC_TRM_vE.pdf,
Table 19-599. CONTROL_PBIASLITE:

Bits
26	MMC1_PWDNZ
25	MMC1_PBIASLITE_HIZ_MODE
24	MMC1_PBIASLITE_SUPPLY_HI_OUT
23	MMC1_PBIASLITE_VMODE_ERROR	then this bit needs to clear..
22	MMC1_PBIASLITE_PWRDNZ
21	MMC1_PBIASLITE_VMODE		..after VMODE bit is set to 3V
 
> If so, could we use regulator framework in USB PHY or MMC driver?

Yes we could use regulator framework for that that. Or just read the
status in the MMC driver for that bit if nobody else has mixed
mux-regulator needs like this.

The sequence is MMC specific, so from that point of view it would
make sense to have the logic in the MMC driver.

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 08/10] pinctrl: single: support pinconf generic
@ 2012-10-22 17:09                 ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-10-22 17:09 UTC (permalink / raw)
  To: linux-arm-kernel

* Haojian Zhuang <haojian.zhuang@gmail.com> [121022 03:11]:
> On Sat, Oct 20, 2012 at 3:13 AM, Tony Lindgren <tony@atomide.com> wrote:
> > * Haojian Zhuang <haojian.zhuang@gmail.com> [121018 02:08]:
> >> Add pinconf generic support with POWER SOURCE, BIAS PULL.
> > ...
> >
> >> +     case PIN_CONFIG_POWER_SOURCE:
> >> +             if (pcs->psmask == PCS_OFF_DISABLED
> >> +                     || pcs->psshift == PCS_OFF_DISABLED)
> >> +                     return -ENOTSUPP;
> >> +             data &= pcs->psmask;
> >> +             data = data >> pcs->psshift;
> >> +             *config = data;
> >> +             return 0;
> >> +             break;
> >
> > Hmm, only slightly related to this patch, mostly a generic
> > question to others: Do others have any mux registers with
> > status bits for things like PIN_CONFIG_POWER_SOURCE?
> >
> > I could use PIN_CONFIG_POWER_SOURCE for controlling the PBIAS
> > for omap MMC. But there's also a status bit that needs to be
> > checked for that. I think there was some other similar mux
> > register for USB PHY that has a status register.
> >
> > So I'm wondering should the checking for status bit be handled
> > in the pinctrl consume driver? Or should we have some bindings
> > for that?
> >
> 
> Do you mean that the status register only exists in USB PHY controller or
> MMC controller?

The status register is in the MMC PBIAS register that is mux
related otherwise. From OMAP4470_ES1.0_PUBLIC_TRM_vE.pdf,
Table 19-599. CONTROL_PBIASLITE:

Bits
26	MMC1_PWDNZ
25	MMC1_PBIASLITE_HIZ_MODE
24	MMC1_PBIASLITE_SUPPLY_HI_OUT
23	MMC1_PBIASLITE_VMODE_ERROR	then this bit needs to clear..
22	MMC1_PBIASLITE_PWRDNZ
21	MMC1_PBIASLITE_VMODE		..after VMODE bit is set to 3V
 
> If so, could we use regulator framework in USB PHY or MMC driver?

Yes we could use regulator framework for that that. Or just read the
status in the MMC driver for that bit if nobody else has mixed
mux-regulator needs like this.

The sequence is MMC specific, so from that point of view it would
make sense to have the logic in the MMC driver.

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 08/10] pinctrl: single: support pinconf generic
  2012-10-19 19:13         ` Tony Lindgren
@ 2012-10-22 10:09             ` Haojian Zhuang
  -1 siblings, 0 replies; 46+ messages in thread
From: Haojian Zhuang @ 2012-10-22 10:09 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Sat, Oct 20, 2012 at 3:13 AM, Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> wrote:
> * Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> [121018 02:08]:
>> Add pinconf generic support with POWER SOURCE, BIAS PULL.
> ...
>
>> +     case PIN_CONFIG_POWER_SOURCE:
>> +             if (pcs->psmask == PCS_OFF_DISABLED
>> +                     || pcs->psshift == PCS_OFF_DISABLED)
>> +                     return -ENOTSUPP;
>> +             data &= pcs->psmask;
>> +             data = data >> pcs->psshift;
>> +             *config = data;
>> +             return 0;
>> +             break;
>
> Hmm, only slightly related to this patch, mostly a generic
> question to others: Do others have any mux registers with
> status bits for things like PIN_CONFIG_POWER_SOURCE?
>
> I could use PIN_CONFIG_POWER_SOURCE for controlling the PBIAS
> for omap MMC. But there's also a status bit that needs to be
> checked for that. I think there was some other similar mux
> register for USB PHY that has a status register.
>
> So I'm wondering should the checking for status bit be handled
> in the pinctrl consume driver? Or should we have some bindings
> for that?
>

Do you mean that the status register only exists in USB PHY controller or
MMC controller?

If so, could we use regulator framework in USB PHY or MMC driver?

Regards
Haojian

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 08/10] pinctrl: single: support pinconf generic
@ 2012-10-22 10:09             ` Haojian Zhuang
  0 siblings, 0 replies; 46+ messages in thread
From: Haojian Zhuang @ 2012-10-22 10:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Oct 20, 2012 at 3:13 AM, Tony Lindgren <tony@atomide.com> wrote:
> * Haojian Zhuang <haojian.zhuang@gmail.com> [121018 02:08]:
>> Add pinconf generic support with POWER SOURCE, BIAS PULL.
> ...
>
>> +     case PIN_CONFIG_POWER_SOURCE:
>> +             if (pcs->psmask == PCS_OFF_DISABLED
>> +                     || pcs->psshift == PCS_OFF_DISABLED)
>> +                     return -ENOTSUPP;
>> +             data &= pcs->psmask;
>> +             data = data >> pcs->psshift;
>> +             *config = data;
>> +             return 0;
>> +             break;
>
> Hmm, only slightly related to this patch, mostly a generic
> question to others: Do others have any mux registers with
> status bits for things like PIN_CONFIG_POWER_SOURCE?
>
> I could use PIN_CONFIG_POWER_SOURCE for controlling the PBIAS
> for omap MMC. But there's also a status bit that needs to be
> checked for that. I think there was some other similar mux
> register for USB PHY that has a status register.
>
> So I'm wondering should the checking for status bit be handled
> in the pinctrl consume driver? Or should we have some bindings
> for that?
>

Do you mean that the status register only exists in USB PHY controller or
MMC controller?

If so, could we use regulator framework in USB PHY or MMC driver?

Regards
Haojian

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 08/10] pinctrl: single: support pinconf generic
  2012-10-18  9:07     ` Haojian Zhuang
@ 2012-10-19 19:13         ` Tony Lindgren
  -1 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-10-19 19:13 UTC (permalink / raw)
  To: Haojian Zhuang
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

* Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> [121018 02:08]:
> Add pinconf generic support with POWER SOURCE, BIAS PULL.
...

> +	case PIN_CONFIG_POWER_SOURCE:
> +		if (pcs->psmask == PCS_OFF_DISABLED
> +			|| pcs->psshift == PCS_OFF_DISABLED)
> +			return -ENOTSUPP;
> +		data &= pcs->psmask;
> +		data = data >> pcs->psshift;
> +		*config = data;
> +		return 0;
> +		break;

Hmm, only slightly related to this patch, mostly a generic
question to others: Do others have any mux registers with
status bits for things like PIN_CONFIG_POWER_SOURCE?

I could use PIN_CONFIG_POWER_SOURCE for controlling the PBIAS
for omap MMC. But there's also a status bit that needs to be
checked for that. I think there was some other similar mux
register for USB PHY that has a status register.

So I'm wondering should the checking for status bit be handled
in the pinctrl consume driver? Or should we have some bindings
for that?

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 08/10] pinctrl: single: support pinconf generic
@ 2012-10-19 19:13         ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-10-19 19:13 UTC (permalink / raw)
  To: linux-arm-kernel

* Haojian Zhuang <haojian.zhuang@gmail.com> [121018 02:08]:
> Add pinconf generic support with POWER SOURCE, BIAS PULL.
...

> +	case PIN_CONFIG_POWER_SOURCE:
> +		if (pcs->psmask == PCS_OFF_DISABLED
> +			|| pcs->psshift == PCS_OFF_DISABLED)
> +			return -ENOTSUPP;
> +		data &= pcs->psmask;
> +		data = data >> pcs->psshift;
> +		*config = data;
> +		return 0;
> +		break;

Hmm, only slightly related to this patch, mostly a generic
question to others: Do others have any mux registers with
status bits for things like PIN_CONFIG_POWER_SOURCE?

I could use PIN_CONFIG_POWER_SOURCE for controlling the PBIAS
for omap MMC. But there's also a status bit that needs to be
checked for that. I think there was some other similar mux
register for USB PHY that has a status register.

So I'm wondering should the checking for status bit be handled
in the pinctrl consume driver? Or should we have some bindings
for that?

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 08/10] pinctrl: single: support pinconf generic
  2012-10-19  2:23                 ` Haojian Zhuang
@ 2012-10-19 18:53                     ` Tony Lindgren
  -1 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-10-19 18:53 UTC (permalink / raw)
  To: Haojian Zhuang
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

* Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> [121018 19:25]:
> 
> I wonder whether gpio function in OMAP is also configured in the pinmux
> register. For example, the function is 3bit field in pinmux register
> of Marvell's
> PXA/MMP silicon. GPIO function is the one of function.

For omaps, the mux registers in padconf area just control
the routing of the signal, pulls and wake-up events. So
gpio mode is a number in the mode bits [2:0]. It's mode 3
for some omaps and mode 4 for some omaps. All the other GPIO
related registers are elsewhere.

Sounds like this is different from what you are describing,
but if you want to compare it, the register bits in the
legacy mach-omap2/mux.h are:

/* 34xx mux mode options for each pin. See TRM for options */
#define OMAP_MUX_MODE0      0
#define OMAP_MUX_MODE1      1
#define OMAP_MUX_MODE2      2
#define OMAP_MUX_MODE3      3
#define OMAP_MUX_MODE4      4
#define OMAP_MUX_MODE5      5
#define OMAP_MUX_MODE6      6
#define OMAP_MUX_MODE7      7
               
/* 24xx/34xx mux bit defines */
#define OMAP_PULL_ENA                   (1 << 3)
#define OMAP_PULL_UP                    (1 << 4)
#define OMAP_ALTELECTRICALSEL           (1 << 5)
               
/* 34xx specific mux bit defines */
#define OMAP_INPUT_EN                   (1 << 8)
#define OMAP_OFF_EN                     (1 << 9)
#define OMAP_OFFOUT_EN                  (1 << 10)
#define OMAP_OFFOUT_VAL                 (1 << 11)
#define OMAP_OFF_PULL_EN                (1 << 12)
#define OMAP_OFF_PULL_UP                (1 << 13)
#define OMAP_WAKEUP_EN                  (1 << 14)
       
/* 44xx specific mux bit defines */
#define OMAP_WAKEUP_EVENT               (1 << 15)

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 08/10] pinctrl: single: support pinconf generic
@ 2012-10-19 18:53                     ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-10-19 18:53 UTC (permalink / raw)
  To: linux-arm-kernel

* Haojian Zhuang <haojian.zhuang@gmail.com> [121018 19:25]:
> 
> I wonder whether gpio function in OMAP is also configured in the pinmux
> register. For example, the function is 3bit field in pinmux register
> of Marvell's
> PXA/MMP silicon. GPIO function is the one of function.

For omaps, the mux registers in padconf area just control
the routing of the signal, pulls and wake-up events. So
gpio mode is a number in the mode bits [2:0]. It's mode 3
for some omaps and mode 4 for some omaps. All the other GPIO
related registers are elsewhere.

Sounds like this is different from what you are describing,
but if you want to compare it, the register bits in the
legacy mach-omap2/mux.h are:

/* 34xx mux mode options for each pin. See TRM for options */
#define OMAP_MUX_MODE0      0
#define OMAP_MUX_MODE1      1
#define OMAP_MUX_MODE2      2
#define OMAP_MUX_MODE3      3
#define OMAP_MUX_MODE4      4
#define OMAP_MUX_MODE5      5
#define OMAP_MUX_MODE6      6
#define OMAP_MUX_MODE7      7
               
/* 24xx/34xx mux bit defines */
#define OMAP_PULL_ENA                   (1 << 3)
#define OMAP_PULL_UP                    (1 << 4)
#define OMAP_ALTELECTRICALSEL           (1 << 5)
               
/* 34xx specific mux bit defines */
#define OMAP_INPUT_EN                   (1 << 8)
#define OMAP_OFF_EN                     (1 << 9)
#define OMAP_OFFOUT_EN                  (1 << 10)
#define OMAP_OFFOUT_VAL                 (1 << 11)
#define OMAP_OFF_PULL_EN                (1 << 12)
#define OMAP_OFF_PULL_UP                (1 << 13)
#define OMAP_WAKEUP_EN                  (1 << 14)
       
/* 44xx specific mux bit defines */
#define OMAP_WAKEUP_EVENT               (1 << 15)

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 08/10] pinctrl: single: support pinconf generic
  2012-10-19  2:40                     ` Tony Lindgren
@ 2012-10-19 18:44                         ` Tony Lindgren
  -1 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-10-19 18:44 UTC (permalink / raw)
  To: Haojian Zhuang
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

* Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> [121018 19:41]:
> * Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> [121018 19:25]:
> > 
> > I wonder whether gpio function in OMAP is also configured in the pinmux
> > register. For example, the function is 3bit field in pinmux register
> > of Marvell's
> > PXA/MMP silicon. GPIO function is the one of function.
> > 
> > If the usage case is same in OMAP silicon, I can merge
> > "pinctrl-single,gpio-mask"
> > with "pinctrl-single,function-mask".
> > 
> > Do we need "pinctrl-single,gpio-disable" at here? I want to remove it,
> > but I don't
> > know whether it's necessary in OMAP case.
> 
> Maybe.. I'll take a look at at that tomorrow.

This one does not apply to v3.7-rc1 because of the pinctrl,bits
support merged from Peter Ujfalusi. Can you please update and
repost?

Thanks,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 08/10] pinctrl: single: support pinconf generic
@ 2012-10-19 18:44                         ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-10-19 18:44 UTC (permalink / raw)
  To: linux-arm-kernel

* Tony Lindgren <tony@atomide.com> [121018 19:41]:
> * Haojian Zhuang <haojian.zhuang@gmail.com> [121018 19:25]:
> > 
> > I wonder whether gpio function in OMAP is also configured in the pinmux
> > register. For example, the function is 3bit field in pinmux register
> > of Marvell's
> > PXA/MMP silicon. GPIO function is the one of function.
> > 
> > If the usage case is same in OMAP silicon, I can merge
> > "pinctrl-single,gpio-mask"
> > with "pinctrl-single,function-mask".
> > 
> > Do we need "pinctrl-single,gpio-disable" at here? I want to remove it,
> > but I don't
> > know whether it's necessary in OMAP case.
> 
> Maybe.. I'll take a look at at that tomorrow.

This one does not apply to v3.7-rc1 because of the pinctrl,bits
support merged from Peter Ujfalusi. Can you please update and
repost?

Thanks,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 08/10] pinctrl: single: support pinconf generic
  2012-10-19  2:23                 ` Haojian Zhuang
@ 2012-10-19  2:40                     ` Tony Lindgren
  -1 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-10-19  2:40 UTC (permalink / raw)
  To: Haojian Zhuang
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

* Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> [121018 19:25]:
> 
> I wonder whether gpio function in OMAP is also configured in the pinmux
> register. For example, the function is 3bit field in pinmux register
> of Marvell's
> PXA/MMP silicon. GPIO function is the one of function.
> 
> If the usage case is same in OMAP silicon, I can merge
> "pinctrl-single,gpio-mask"
> with "pinctrl-single,function-mask".
> 
> Do we need "pinctrl-single,gpio-disable" at here? I want to remove it,
> but I don't
> know whether it's necessary in OMAP case.

Maybe.. I'll take a look at at that tomorrow.

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 08/10] pinctrl: single: support pinconf generic
@ 2012-10-19  2:40                     ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-10-19  2:40 UTC (permalink / raw)
  To: linux-arm-kernel

* Haojian Zhuang <haojian.zhuang@gmail.com> [121018 19:25]:
> 
> I wonder whether gpio function in OMAP is also configured in the pinmux
> register. For example, the function is 3bit field in pinmux register
> of Marvell's
> PXA/MMP silicon. GPIO function is the one of function.
> 
> If the usage case is same in OMAP silicon, I can merge
> "pinctrl-single,gpio-mask"
> with "pinctrl-single,function-mask".
> 
> Do we need "pinctrl-single,gpio-disable" at here? I want to remove it,
> but I don't
> know whether it's necessary in OMAP case.

Maybe.. I'll take a look at at that tomorrow.

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 08/10] pinctrl: single: support pinconf generic
  2012-10-18 22:29             ` Tony Lindgren
@ 2012-10-19  2:23                 ` Haojian Zhuang
  -1 siblings, 0 replies; 46+ messages in thread
From: Haojian Zhuang @ 2012-10-19  2:23 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Fri, Oct 19, 2012 at 6:29 AM, Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org> wrote:
> * Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> [121018 11:32]:
>> On Thu, Oct 18, 2012 at 11:07 AM, Haojian Zhuang
>> <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>>
>> > Add pinconf generic support with POWER SOURCE, BIAS PULL.
>> >
>> > Signed-off-by: Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>>
>> I really like the looks of this, good job Haojian!
>>
>> Now we just need to hear what Tony says about it...
>
> Hey that's cool, maybe I'll find some use for those too :)
> I'll take a closer look tonigh or on Friday.
>
> Regards,
>
> Tony

I wonder whether gpio function in OMAP is also configured in the pinmux
register. For example, the function is 3bit field in pinmux register
of Marvell's
PXA/MMP silicon. GPIO function is the one of function.

If the usage case is same in OMAP silicon, I can merge
"pinctrl-single,gpio-mask"
with "pinctrl-single,function-mask".

Do we need "pinctrl-single,gpio-disable" at here? I want to remove it,
but I don't
know whether it's necessary in OMAP case.

Regards
Haojian

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 08/10] pinctrl: single: support pinconf generic
@ 2012-10-19  2:23                 ` Haojian Zhuang
  0 siblings, 0 replies; 46+ messages in thread
From: Haojian Zhuang @ 2012-10-19  2:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Oct 19, 2012 at 6:29 AM, Tony Lindgren <tony@atomide.com> wrote:
> * Linus Walleij <linus.walleij@linaro.org> [121018 11:32]:
>> On Thu, Oct 18, 2012 at 11:07 AM, Haojian Zhuang
>> <haojian.zhuang@gmail.com> wrote:
>>
>> > Add pinconf generic support with POWER SOURCE, BIAS PULL.
>> >
>> > Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
>>
>> I really like the looks of this, good job Haojian!
>>
>> Now we just need to hear what Tony says about it...
>
> Hey that's cool, maybe I'll find some use for those too :)
> I'll take a closer look tonigh or on Friday.
>
> Regards,
>
> Tony

I wonder whether gpio function in OMAP is also configured in the pinmux
register. For example, the function is 3bit field in pinmux register
of Marvell's
PXA/MMP silicon. GPIO function is the one of function.

If the usage case is same in OMAP silicon, I can merge
"pinctrl-single,gpio-mask"
with "pinctrl-single,function-mask".

Do we need "pinctrl-single,gpio-disable" at here? I want to remove it,
but I don't
know whether it's necessary in OMAP case.

Regards
Haojian

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 08/10] pinctrl: single: support pinconf generic
  2012-10-18 18:30         ` Linus Walleij
@ 2012-10-18 22:29             ` Tony Lindgren
  -1 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-10-18 22:29 UTC (permalink / raw)
  To: Linus Walleij
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

* Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> [121018 11:32]:
> On Thu, Oct 18, 2012 at 11:07 AM, Haojian Zhuang
> <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> 
> > Add pinconf generic support with POWER SOURCE, BIAS PULL.
> >
> > Signed-off-by: Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> 
> I really like the looks of this, good job Haojian!
> 
> Now we just need to hear what Tony says about it...

Hey that's cool, maybe I'll find some use for those too :)
I'll take a closer look tonigh or on Friday.

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 08/10] pinctrl: single: support pinconf generic
@ 2012-10-18 22:29             ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2012-10-18 22:29 UTC (permalink / raw)
  To: linux-arm-kernel

* Linus Walleij <linus.walleij@linaro.org> [121018 11:32]:
> On Thu, Oct 18, 2012 at 11:07 AM, Haojian Zhuang
> <haojian.zhuang@gmail.com> wrote:
> 
> > Add pinconf generic support with POWER SOURCE, BIAS PULL.
> >
> > Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
> 
> I really like the looks of this, good job Haojian!
> 
> Now we just need to hear what Tony says about it...

Hey that's cool, maybe I'll find some use for those too :)
I'll take a closer look tonigh or on Friday.

Regards,

Tony

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 08/10] pinctrl: single: support pinconf generic
  2012-10-18  9:07     ` Haojian Zhuang
@ 2012-10-18 18:30         ` Linus Walleij
  -1 siblings, 0 replies; 46+ messages in thread
From: Linus Walleij @ 2012-10-18 18:30 UTC (permalink / raw)
  To: Haojian Zhuang
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Thu, Oct 18, 2012 at 11:07 AM, Haojian Zhuang
<haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:

> Add pinconf generic support with POWER SOURCE, BIAS PULL.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

I really like the looks of this, good job Haojian!

Now we just need to hear what Tony says about it...

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 08/10] pinctrl: single: support pinconf generic
@ 2012-10-18 18:30         ` Linus Walleij
  0 siblings, 0 replies; 46+ messages in thread
From: Linus Walleij @ 2012-10-18 18:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Oct 18, 2012 at 11:07 AM, Haojian Zhuang
<haojian.zhuang@gmail.com> wrote:

> Add pinconf generic support with POWER SOURCE, BIAS PULL.
>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>

I really like the looks of this, good job Haojian!

Now we just need to hear what Tony says about it...

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 08/10] pinctrl: single: support pinconf generic
  2012-10-18  9:06 [PATCH 01/10] pinctrl: use postcore_initcall Haojian Zhuang
@ 2012-10-18  9:07     ` Haojian Zhuang
  0 siblings, 0 replies; 46+ messages in thread
From: Haojian Zhuang @ 2012-10-18  9:07 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	arnd-r2nGTMty4D4, linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
	tony-4v6yS6AI5VpBDgjK7y7TUQ,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

Add pinconf generic support with POWER SOURCE, BIAS PULL.

Signed-off-by: Haojian Zhuang <haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/pinctrl/Kconfig          |    2 +-
 drivers/pinctrl/pinctrl-single.c |  286 ++++++++++++++++++++++++++++++++++++--
 2 files changed, 274 insertions(+), 14 deletions(-)

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 54e3588..cc2ef20 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -106,7 +106,7 @@ config PINCTRL_SINGLE
 	tristate "One-register-per-pin type device tree based pinctrl driver"
 	depends on OF
 	select PINMUX
-	select PINCONF
+	select GENERIC_PINCONF
 	help
 	  This selects the device tree based generic pinctrl driver.
 
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index 02cd412..a396944 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -20,6 +20,7 @@
 #include <linux/of_device.h>
 #include <linux/of_address.h>
 
+#include <linux/pinctrl/pinconf-generic.h>
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/pinctrl/pinmux.h>
 
@@ -27,6 +28,9 @@
 
 #define DRIVER_NAME			"pinctrl-single"
 #define PCS_MUX_NAME			"pinctrl-single,pins"
+#define PCS_BIAS_NAME			"pinctrl-single,bias"
+#define PCS_POWER_SOURCE_NAME		"pinctrl-single,power-source"
+#define PCS_SCHMITT_NAME		"pinctrl-single,input-schmitt"
 #define PCS_REG_NAME_LEN		((sizeof(unsigned long) * 2) + 1)
 #define PCS_OFF_DISABLED		~0U
 #define PCS_MAX_GPIO_VALUES		3
@@ -137,6 +141,15 @@ struct pcs_name {
  * @foff:	value to turn mux off
  * @fmax:	max number of functions in fmask
  * @gmask:	gpio control mask
+ * @bmask:	mask of bias in pinconf
+ * @bshift:	offset of bias in pinconf
+ * @bdis:	bias disable value in pinconf
+ * @bpullup:	bias pull up value in pinconf
+ * @bpulldown:	bias pull down value in pinconf
+ * @ismask:	mask of input schmitt in pinconf
+ * @isshift:	offset of input schmitt in pinconf
+ * @psmask:	mask of power source in pinconf
+ * @psshift:	offset of power source in pinconf
  * @names:	array of register names for pins
  * @pins:	physical pins on the SoC
  * @pgtree:	pingroup index radix tree
@@ -164,6 +177,15 @@ struct pcs_device {
 	unsigned foff;
 	unsigned fmax;
 	unsigned gmask;
+	unsigned bmask;
+	unsigned bshift;
+	unsigned bdis;
+	unsigned bpullup;
+	unsigned bpulldown;
+	unsigned ismask;
+	unsigned isshift;
+	unsigned psmask;
+	unsigned psshift;
 	struct pcs_name *names;
 	struct pcs_data pins;
 	struct radix_tree_root pgtree;
@@ -268,9 +290,14 @@ static int pcs_get_group_pins(struct pinctrl_dev *pctldev,
 
 static void pcs_pin_dbg_show(struct pinctrl_dev *pctldev,
 					struct seq_file *s,
-					unsigned offset)
+					unsigned pin)
 {
-	seq_printf(s, " " DRIVER_NAME);
+	struct pcs_device *pcs;
+	unsigned offset;
+
+	pcs = pinctrl_dev_get_drvdata(pctldev);
+	offset = pin * (pcs->width / BITS_PER_BYTE);
+	seq_printf(s, " register value:0x%x", pcs_readl(pcs->base + offset));
 }
 
 static void pcs_dt_free_map(struct pinctrl_dev *pctldev,
@@ -468,28 +495,163 @@ static struct pinmux_ops pcs_pinmux_ops = {
 	.gpio_disable_free = pcs_disable_gpio,
 };
 
+static void pcs_free_pingroups(struct pcs_device *pcs);
+
 static int pcs_pinconf_get(struct pinctrl_dev *pctldev,
 				unsigned pin, unsigned long *config)
 {
+	struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	unsigned data;
+	u32 offset;
+
+	offset = pin * (pcs->width / BITS_PER_BYTE);
+	data = pcs_readl(pcs->base + offset);
+
+	switch (param) {
+	case PIN_CONFIG_POWER_SOURCE:
+		if (pcs->psmask == PCS_OFF_DISABLED
+			|| pcs->psshift == PCS_OFF_DISABLED)
+			return -ENOTSUPP;
+		data &= pcs->psmask;
+		data = data >> pcs->psshift;
+		*config = data;
+		return 0;
+		break;
+	case PIN_CONFIG_BIAS_DISABLE:
+		if (pcs->bmask == PCS_OFF_DISABLED
+			|| pcs->bshift == PCS_OFF_DISABLED
+			|| pcs->bdis == PCS_OFF_DISABLED)
+			return -ENOTSUPP;
+		data &= pcs->bmask;
+		*config = 0;
+		if (data == pcs->bdis)
+			return 0;
+		else
+			return -EINVAL;
+		break;
+	case PIN_CONFIG_BIAS_PULL_UP:
+		if (pcs->bmask == PCS_OFF_DISABLED
+			|| pcs->bshift == PCS_OFF_DISABLED
+			|| pcs->bpullup == PCS_OFF_DISABLED)
+			return -ENOTSUPP;
+		data &= pcs->bmask;
+		*config = 0;
+		if (data == pcs->bpullup)
+			return 0;
+		else
+			return -EINVAL;
+		break;
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		if (pcs->bmask == PCS_OFF_DISABLED
+			|| pcs->bshift == PCS_OFF_DISABLED
+			|| pcs->bpulldown == PCS_OFF_DISABLED)
+			return -ENOTSUPP;
+		data &= pcs->bmask;
+		*config = 0;
+		if (data == pcs->bpulldown)
+			return 0;
+		else
+			return -EINVAL;
+		break;
+	default:
+		break;
+	}
 	return -ENOTSUPP;
 }
 
 static int pcs_pinconf_set(struct pinctrl_dev *pctldev,
 				unsigned pin, unsigned long config)
 {
-	return -ENOTSUPP;
+	struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param config_param = pinconf_to_config_param(config);
+	unsigned ret, mask = ~0UL;
+	u32 offset, data;
+
+	switch (config_param) {
+	case PIN_CONFIG_POWER_SOURCE:
+		if (pcs->psmask == PCS_OFF_DISABLED
+			|| pcs->psshift == PCS_OFF_DISABLED)
+			return 0;
+		mask = pcs->psmask;
+		data = (pinconf_to_config_argument(config) << pcs->psshift)
+			& pcs->psmask;
+		break;
+	case PIN_CONFIG_BIAS_DISABLE:
+		if (pcs->bmask == PCS_OFF_DISABLED
+			|| pcs->bshift == PCS_OFF_DISABLED)
+			return 0;
+		mask = pcs->bmask;
+		data = (pinconf_to_config_argument(config) << pcs->bshift)
+			& pcs->bmask;
+		break;
+	default:
+		return 0;
+	}
+	offset = pin * (pcs->width / BITS_PER_BYTE);
+	ret = pcs_readl(pcs->base + offset) & ~mask;
+	pcs_writel(ret | data, pcs->base + offset);
+	return 0;
 }
 
 static int pcs_pinconf_group_get(struct pinctrl_dev *pctldev,
 				unsigned group, unsigned long *config)
 {
-	return -ENOTSUPP;
+	struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
+	struct pcs_pingroup *pins;
+
+	pins = radix_tree_lookup(&pcs->pgtree, group);
+	if (!pins) {
+		dev_err(pcs->dev, "%s could not find pingroup%i\n",
+			__func__, group);
+		return -EINVAL;
+	}
+	return pcs_pinconf_get(pctldev, pins->gpins[0], config);
 }
 
 static int pcs_pinconf_group_set(struct pinctrl_dev *pctldev,
 				unsigned group, unsigned long config)
 {
-	return -ENOTSUPP;
+	struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param config_param = pinconf_to_config_param(config);
+	struct pcs_pingroup *pins;
+	u32 offset, data;
+	unsigned ret, mask = ~0UL;
+	int i;
+
+	switch (config_param) {
+	case PIN_CONFIG_POWER_SOURCE:
+		if (pcs->psmask == PCS_OFF_DISABLED
+			|| pcs->psshift == PCS_OFF_DISABLED)
+			return 0;
+		mask = pcs->psmask;
+		data = (pinconf_to_config_argument(config) << pcs->psshift)
+			& pcs->psmask;
+		break;
+	case PIN_CONFIG_BIAS_DISABLE:
+		if (pcs->bmask == PCS_OFF_DISABLED
+			|| pcs->bshift == PCS_OFF_DISABLED)
+			return 0;
+		mask = pcs->bmask;
+		data = (pinconf_to_config_argument(config) << pcs->bshift)
+			& pcs->bmask;
+		break;
+	default:
+		return 0;
+	}
+
+	pins = radix_tree_lookup(&pcs->pgtree, group);
+	if (!pins) {
+		dev_err(pcs->dev, "%s could not find pingroup%i\n",
+			__func__, group);
+		return -EINVAL;
+	}
+	for (i = 0; i < pins->ngpins; i++) {
+		offset = pins->gpins[i] * (pcs->width / BITS_PER_BYTE);
+		ret = pcs_readl(pcs->base + offset) & ~mask;
+		pcs_writel(ret | data, pcs->base + offset);
+	}
+	return 0;
 }
 
 static void pcs_pinconf_dbg_show(struct pinctrl_dev *pctldev,
@@ -503,6 +665,7 @@ static void pcs_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
 }
 
 static struct pinconf_ops pcs_pinconf_ops = {
+	.is_generic = true,
 	.pin_config_get = pcs_pinconf_get,
 	.pin_config_set = pcs_pinconf_set,
 	.pin_config_group_get = pcs_pinconf_group_get,
@@ -720,12 +883,16 @@ static int pcs_get_pin_by_offset(struct pcs_device *pcs, unsigned offset)
 static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
 						struct device_node *np,
 						struct pinctrl_map **map,
+						unsigned num_configs,
 						const char **pgnames)
 {
 	struct pcs_func_vals *vals;
+	struct pinctrl_map *p = *map;
 	const __be32 *mux;
 	int size, rows, *pins, index = 0, found = 0, res = -ENOMEM;
 	struct pcs_function *function;
+	unsigned long *config;
+	u32 value;
 
 	mux = of_get_property(np, PCS_MUX_NAME, &size);
 	if ((!mux) || (size < sizeof(*mux) * 2)) {
@@ -773,12 +940,42 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
 	if (res < 0)
 		goto free_function;
 
-	(*map)->type = PIN_MAP_TYPE_MUX_GROUP;
-	(*map)->data.mux.group = np->name;
-	(*map)->data.mux.function = np->name;
+	p->type = PIN_MAP_TYPE_MUX_GROUP;
+	p->data.mux.group = np->name;
+	p->data.mux.function = np->name;
+
+	if (!num_configs)
+		return 0;
+	config = devm_kzalloc(pcs->dev, sizeof(*config) * num_configs,
+			      GFP_KERNEL);
+	if (!config) {
+		res = -ENOMEM;
+		goto free_pingroup;
+	}
+	index = 0;
+	if (!of_property_read_u32(np, PCS_SCHMITT_NAME, &value))
+		config[index++] =
+			pinconf_to_config_packed(PIN_CONFIG_INPUT_SCHMITT,
+						 value & 0xffff);
+	if (!of_property_read_u32(np, PCS_BIAS_NAME, &value))
+		config[index++] =
+			pinconf_to_config_packed(PIN_CONFIG_BIAS_DISABLE,
+						 value & 0xffff);
+	if (!of_property_read_u32(np, PCS_POWER_SOURCE_NAME, &value))
+		config[index++] =
+			pinconf_to_config_packed(PIN_CONFIG_POWER_SOURCE,
+						 value & 0xffff);
+	p++;
+	p->type = PIN_MAP_TYPE_CONFIGS_GROUP;
+	p->data.configs.group_or_pin = np->name;
+	p->data.configs.configs = config;
+	p->data.configs.num_configs = num_configs;
 
 	return 0;
 
+free_pingroup:
+	pcs_free_pingroups(pcs);
+
 free_function:
 	pcs_remove_function(pcs, function);
 
@@ -790,6 +987,29 @@ free_vals:
 
 	return res;
 }
+
+static int pcs_dt_check_maps(struct device_node *np, unsigned *num_maps,
+			     unsigned *num_configs)
+{
+	unsigned size;
+
+	*num_maps = 0;
+	*num_configs = 0;
+	if (of_get_property(np, PCS_MUX_NAME, &size))
+		(*num_maps)++;
+	if (of_get_property(np, PCS_SCHMITT_NAME, &size))
+		(*num_configs)++;
+	if (of_get_property(np, PCS_BIAS_NAME, &size))
+		(*num_configs)++;
+	if (of_get_property(np, PCS_POWER_SOURCE_NAME, &size))
+		(*num_configs)++;
+	if (*num_configs)
+		(*num_maps)++;
+	if (!(*num_maps))
+		return -EINVAL;
+	return 0;
+}
+
 /**
  * pcs_dt_node_to_map() - allocates and parses pinctrl maps
  * @pctldev: pinctrl instance
@@ -803,29 +1023,32 @@ static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev,
 {
 	struct pcs_device *pcs;
 	const char **pgnames;
+	unsigned num_configs;
 	int ret;
 
 	pcs = pinctrl_dev_get_drvdata(pctldev);
 
-	*map = devm_kzalloc(pcs->dev, sizeof(**map), GFP_KERNEL);
+	ret = pcs_dt_check_maps(np_config, num_maps, &num_configs);
+	if (ret)
+		return ret;
+
+	*map = devm_kzalloc(pcs->dev, sizeof(**map) * (*num_maps), GFP_KERNEL);
 	if (!map)
 		return -ENOMEM;
 
-	*num_maps = 0;
-
 	pgnames = devm_kzalloc(pcs->dev, sizeof(*pgnames), GFP_KERNEL);
 	if (!pgnames) {
 		ret = -ENOMEM;
 		goto free_map;
 	}
 
-	ret = pcs_parse_one_pinctrl_entry(pcs, np_config, map, pgnames);
+	ret = pcs_parse_one_pinctrl_entry(pcs, np_config, map,
+					  num_configs, pgnames);
 	if (ret < 0) {
 		dev_err(pcs->dev, "no pins entries for %s\n",
 			np_config->name);
 		goto free_pgnames;
 	}
-	*num_maps = 1;
 
 	return 0;
 
@@ -1015,6 +1238,43 @@ static int __devinit pcs_probe(struct platform_device *pdev)
 	if (ret)
 		pcs->foff = PCS_OFF_DISABLED;
 
+	ret = of_property_read_u32(np, "pinctrl-single,power-source-mask",
+					&pcs->psmask);
+	if (ret)
+		pcs->psmask = PCS_OFF_DISABLED;
+	ret = of_property_read_u32(np, "pinctrl-single,power-source-shift",
+					&pcs->psshift);
+	if (ret)
+		pcs->psshift = PCS_OFF_DISABLED;
+	ret = of_property_read_u32(np, "pinctrl-single,bias-mask",
+					&pcs->bmask);
+	if (ret)
+		pcs->bmask = PCS_OFF_DISABLED;
+	ret = of_property_read_u32(np, "pinctrl-single,bias-shift",
+					&pcs->bshift);
+	if (ret)
+		pcs->bshift = PCS_OFF_DISABLED;
+	ret = of_property_read_u32(np, "pinctrl-single,bias-disable",
+					&pcs->bdis);
+	if (ret)
+		pcs->bdis = PCS_OFF_DISABLED;
+	ret = of_property_read_u32(np, "pinctrl-single,bias-pull-up",
+					&pcs->bpullup);
+	if (ret)
+		pcs->bpullup = PCS_OFF_DISABLED;
+	ret = of_property_read_u32(np, "pinctrl-single,bias-pull-down",
+					&pcs->bpulldown);
+	if (ret)
+		pcs->bpulldown = PCS_OFF_DISABLED;
+	ret = of_property_read_u32(np, "pinctrl-single,input-schmitt-mask",
+					&pcs->ismask);
+	if (ret)
+		pcs->ismask = PCS_OFF_DISABLED;
+	ret = of_property_read_u32(np, "pinctrl-single,input-schmitt-shift",
+					&pcs->isshift);
+	if (ret)
+		pcs->isshift = PCS_OFF_DISABLED;
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 		dev_err(pcs->dev, "could not get resource\n");
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 08/10] pinctrl: single: support pinconf generic
@ 2012-10-18  9:07     ` Haojian Zhuang
  0 siblings, 0 replies; 46+ messages in thread
From: Haojian Zhuang @ 2012-10-18  9:07 UTC (permalink / raw)
  To: linux-arm-kernel

Add pinconf generic support with POWER SOURCE, BIAS PULL.

Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com>
---
 drivers/pinctrl/Kconfig          |    2 +-
 drivers/pinctrl/pinctrl-single.c |  286 ++++++++++++++++++++++++++++++++++++--
 2 files changed, 274 insertions(+), 14 deletions(-)

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 54e3588..cc2ef20 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -106,7 +106,7 @@ config PINCTRL_SINGLE
 	tristate "One-register-per-pin type device tree based pinctrl driver"
 	depends on OF
 	select PINMUX
-	select PINCONF
+	select GENERIC_PINCONF
 	help
 	  This selects the device tree based generic pinctrl driver.
 
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index 02cd412..a396944 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -20,6 +20,7 @@
 #include <linux/of_device.h>
 #include <linux/of_address.h>
 
+#include <linux/pinctrl/pinconf-generic.h>
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/pinctrl/pinmux.h>
 
@@ -27,6 +28,9 @@
 
 #define DRIVER_NAME			"pinctrl-single"
 #define PCS_MUX_NAME			"pinctrl-single,pins"
+#define PCS_BIAS_NAME			"pinctrl-single,bias"
+#define PCS_POWER_SOURCE_NAME		"pinctrl-single,power-source"
+#define PCS_SCHMITT_NAME		"pinctrl-single,input-schmitt"
 #define PCS_REG_NAME_LEN		((sizeof(unsigned long) * 2) + 1)
 #define PCS_OFF_DISABLED		~0U
 #define PCS_MAX_GPIO_VALUES		3
@@ -137,6 +141,15 @@ struct pcs_name {
  * @foff:	value to turn mux off
  * @fmax:	max number of functions in fmask
  * @gmask:	gpio control mask
+ * @bmask:	mask of bias in pinconf
+ * @bshift:	offset of bias in pinconf
+ * @bdis:	bias disable value in pinconf
+ * @bpullup:	bias pull up value in pinconf
+ * @bpulldown:	bias pull down value in pinconf
+ * @ismask:	mask of input schmitt in pinconf
+ * @isshift:	offset of input schmitt in pinconf
+ * @psmask:	mask of power source in pinconf
+ * @psshift:	offset of power source in pinconf
  * @names:	array of register names for pins
  * @pins:	physical pins on the SoC
  * @pgtree:	pingroup index radix tree
@@ -164,6 +177,15 @@ struct pcs_device {
 	unsigned foff;
 	unsigned fmax;
 	unsigned gmask;
+	unsigned bmask;
+	unsigned bshift;
+	unsigned bdis;
+	unsigned bpullup;
+	unsigned bpulldown;
+	unsigned ismask;
+	unsigned isshift;
+	unsigned psmask;
+	unsigned psshift;
 	struct pcs_name *names;
 	struct pcs_data pins;
 	struct radix_tree_root pgtree;
@@ -268,9 +290,14 @@ static int pcs_get_group_pins(struct pinctrl_dev *pctldev,
 
 static void pcs_pin_dbg_show(struct pinctrl_dev *pctldev,
 					struct seq_file *s,
-					unsigned offset)
+					unsigned pin)
 {
-	seq_printf(s, " " DRIVER_NAME);
+	struct pcs_device *pcs;
+	unsigned offset;
+
+	pcs = pinctrl_dev_get_drvdata(pctldev);
+	offset = pin * (pcs->width / BITS_PER_BYTE);
+	seq_printf(s, " register value:0x%x", pcs_readl(pcs->base + offset));
 }
 
 static void pcs_dt_free_map(struct pinctrl_dev *pctldev,
@@ -468,28 +495,163 @@ static struct pinmux_ops pcs_pinmux_ops = {
 	.gpio_disable_free = pcs_disable_gpio,
 };
 
+static void pcs_free_pingroups(struct pcs_device *pcs);
+
 static int pcs_pinconf_get(struct pinctrl_dev *pctldev,
 				unsigned pin, unsigned long *config)
 {
+	struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param param = pinconf_to_config_param(*config);
+	unsigned data;
+	u32 offset;
+
+	offset = pin * (pcs->width / BITS_PER_BYTE);
+	data = pcs_readl(pcs->base + offset);
+
+	switch (param) {
+	case PIN_CONFIG_POWER_SOURCE:
+		if (pcs->psmask == PCS_OFF_DISABLED
+			|| pcs->psshift == PCS_OFF_DISABLED)
+			return -ENOTSUPP;
+		data &= pcs->psmask;
+		data = data >> pcs->psshift;
+		*config = data;
+		return 0;
+		break;
+	case PIN_CONFIG_BIAS_DISABLE:
+		if (pcs->bmask == PCS_OFF_DISABLED
+			|| pcs->bshift == PCS_OFF_DISABLED
+			|| pcs->bdis == PCS_OFF_DISABLED)
+			return -ENOTSUPP;
+		data &= pcs->bmask;
+		*config = 0;
+		if (data == pcs->bdis)
+			return 0;
+		else
+			return -EINVAL;
+		break;
+	case PIN_CONFIG_BIAS_PULL_UP:
+		if (pcs->bmask == PCS_OFF_DISABLED
+			|| pcs->bshift == PCS_OFF_DISABLED
+			|| pcs->bpullup == PCS_OFF_DISABLED)
+			return -ENOTSUPP;
+		data &= pcs->bmask;
+		*config = 0;
+		if (data == pcs->bpullup)
+			return 0;
+		else
+			return -EINVAL;
+		break;
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		if (pcs->bmask == PCS_OFF_DISABLED
+			|| pcs->bshift == PCS_OFF_DISABLED
+			|| pcs->bpulldown == PCS_OFF_DISABLED)
+			return -ENOTSUPP;
+		data &= pcs->bmask;
+		*config = 0;
+		if (data == pcs->bpulldown)
+			return 0;
+		else
+			return -EINVAL;
+		break;
+	default:
+		break;
+	}
 	return -ENOTSUPP;
 }
 
 static int pcs_pinconf_set(struct pinctrl_dev *pctldev,
 				unsigned pin, unsigned long config)
 {
-	return -ENOTSUPP;
+	struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param config_param = pinconf_to_config_param(config);
+	unsigned ret, mask = ~0UL;
+	u32 offset, data;
+
+	switch (config_param) {
+	case PIN_CONFIG_POWER_SOURCE:
+		if (pcs->psmask == PCS_OFF_DISABLED
+			|| pcs->psshift == PCS_OFF_DISABLED)
+			return 0;
+		mask = pcs->psmask;
+		data = (pinconf_to_config_argument(config) << pcs->psshift)
+			& pcs->psmask;
+		break;
+	case PIN_CONFIG_BIAS_DISABLE:
+		if (pcs->bmask == PCS_OFF_DISABLED
+			|| pcs->bshift == PCS_OFF_DISABLED)
+			return 0;
+		mask = pcs->bmask;
+		data = (pinconf_to_config_argument(config) << pcs->bshift)
+			& pcs->bmask;
+		break;
+	default:
+		return 0;
+	}
+	offset = pin * (pcs->width / BITS_PER_BYTE);
+	ret = pcs_readl(pcs->base + offset) & ~mask;
+	pcs_writel(ret | data, pcs->base + offset);
+	return 0;
 }
 
 static int pcs_pinconf_group_get(struct pinctrl_dev *pctldev,
 				unsigned group, unsigned long *config)
 {
-	return -ENOTSUPP;
+	struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
+	struct pcs_pingroup *pins;
+
+	pins = radix_tree_lookup(&pcs->pgtree, group);
+	if (!pins) {
+		dev_err(pcs->dev, "%s could not find pingroup%i\n",
+			__func__, group);
+		return -EINVAL;
+	}
+	return pcs_pinconf_get(pctldev, pins->gpins[0], config);
 }
 
 static int pcs_pinconf_group_set(struct pinctrl_dev *pctldev,
 				unsigned group, unsigned long config)
 {
-	return -ENOTSUPP;
+	struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
+	enum pin_config_param config_param = pinconf_to_config_param(config);
+	struct pcs_pingroup *pins;
+	u32 offset, data;
+	unsigned ret, mask = ~0UL;
+	int i;
+
+	switch (config_param) {
+	case PIN_CONFIG_POWER_SOURCE:
+		if (pcs->psmask == PCS_OFF_DISABLED
+			|| pcs->psshift == PCS_OFF_DISABLED)
+			return 0;
+		mask = pcs->psmask;
+		data = (pinconf_to_config_argument(config) << pcs->psshift)
+			& pcs->psmask;
+		break;
+	case PIN_CONFIG_BIAS_DISABLE:
+		if (pcs->bmask == PCS_OFF_DISABLED
+			|| pcs->bshift == PCS_OFF_DISABLED)
+			return 0;
+		mask = pcs->bmask;
+		data = (pinconf_to_config_argument(config) << pcs->bshift)
+			& pcs->bmask;
+		break;
+	default:
+		return 0;
+	}
+
+	pins = radix_tree_lookup(&pcs->pgtree, group);
+	if (!pins) {
+		dev_err(pcs->dev, "%s could not find pingroup%i\n",
+			__func__, group);
+		return -EINVAL;
+	}
+	for (i = 0; i < pins->ngpins; i++) {
+		offset = pins->gpins[i] * (pcs->width / BITS_PER_BYTE);
+		ret = pcs_readl(pcs->base + offset) & ~mask;
+		pcs_writel(ret | data, pcs->base + offset);
+	}
+	return 0;
 }
 
 static void pcs_pinconf_dbg_show(struct pinctrl_dev *pctldev,
@@ -503,6 +665,7 @@ static void pcs_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
 }
 
 static struct pinconf_ops pcs_pinconf_ops = {
+	.is_generic = true,
 	.pin_config_get = pcs_pinconf_get,
 	.pin_config_set = pcs_pinconf_set,
 	.pin_config_group_get = pcs_pinconf_group_get,
@@ -720,12 +883,16 @@ static int pcs_get_pin_by_offset(struct pcs_device *pcs, unsigned offset)
 static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
 						struct device_node *np,
 						struct pinctrl_map **map,
+						unsigned num_configs,
 						const char **pgnames)
 {
 	struct pcs_func_vals *vals;
+	struct pinctrl_map *p = *map;
 	const __be32 *mux;
 	int size, rows, *pins, index = 0, found = 0, res = -ENOMEM;
 	struct pcs_function *function;
+	unsigned long *config;
+	u32 value;
 
 	mux = of_get_property(np, PCS_MUX_NAME, &size);
 	if ((!mux) || (size < sizeof(*mux) * 2)) {
@@ -773,12 +940,42 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
 	if (res < 0)
 		goto free_function;
 
-	(*map)->type = PIN_MAP_TYPE_MUX_GROUP;
-	(*map)->data.mux.group = np->name;
-	(*map)->data.mux.function = np->name;
+	p->type = PIN_MAP_TYPE_MUX_GROUP;
+	p->data.mux.group = np->name;
+	p->data.mux.function = np->name;
+
+	if (!num_configs)
+		return 0;
+	config = devm_kzalloc(pcs->dev, sizeof(*config) * num_configs,
+			      GFP_KERNEL);
+	if (!config) {
+		res = -ENOMEM;
+		goto free_pingroup;
+	}
+	index = 0;
+	if (!of_property_read_u32(np, PCS_SCHMITT_NAME, &value))
+		config[index++] =
+			pinconf_to_config_packed(PIN_CONFIG_INPUT_SCHMITT,
+						 value & 0xffff);
+	if (!of_property_read_u32(np, PCS_BIAS_NAME, &value))
+		config[index++] =
+			pinconf_to_config_packed(PIN_CONFIG_BIAS_DISABLE,
+						 value & 0xffff);
+	if (!of_property_read_u32(np, PCS_POWER_SOURCE_NAME, &value))
+		config[index++] =
+			pinconf_to_config_packed(PIN_CONFIG_POWER_SOURCE,
+						 value & 0xffff);
+	p++;
+	p->type = PIN_MAP_TYPE_CONFIGS_GROUP;
+	p->data.configs.group_or_pin = np->name;
+	p->data.configs.configs = config;
+	p->data.configs.num_configs = num_configs;
 
 	return 0;
 
+free_pingroup:
+	pcs_free_pingroups(pcs);
+
 free_function:
 	pcs_remove_function(pcs, function);
 
@@ -790,6 +987,29 @@ free_vals:
 
 	return res;
 }
+
+static int pcs_dt_check_maps(struct device_node *np, unsigned *num_maps,
+			     unsigned *num_configs)
+{
+	unsigned size;
+
+	*num_maps = 0;
+	*num_configs = 0;
+	if (of_get_property(np, PCS_MUX_NAME, &size))
+		(*num_maps)++;
+	if (of_get_property(np, PCS_SCHMITT_NAME, &size))
+		(*num_configs)++;
+	if (of_get_property(np, PCS_BIAS_NAME, &size))
+		(*num_configs)++;
+	if (of_get_property(np, PCS_POWER_SOURCE_NAME, &size))
+		(*num_configs)++;
+	if (*num_configs)
+		(*num_maps)++;
+	if (!(*num_maps))
+		return -EINVAL;
+	return 0;
+}
+
 /**
  * pcs_dt_node_to_map() - allocates and parses pinctrl maps
  * @pctldev: pinctrl instance
@@ -803,29 +1023,32 @@ static int pcs_dt_node_to_map(struct pinctrl_dev *pctldev,
 {
 	struct pcs_device *pcs;
 	const char **pgnames;
+	unsigned num_configs;
 	int ret;
 
 	pcs = pinctrl_dev_get_drvdata(pctldev);
 
-	*map = devm_kzalloc(pcs->dev, sizeof(**map), GFP_KERNEL);
+	ret = pcs_dt_check_maps(np_config, num_maps, &num_configs);
+	if (ret)
+		return ret;
+
+	*map = devm_kzalloc(pcs->dev, sizeof(**map) * (*num_maps), GFP_KERNEL);
 	if (!map)
 		return -ENOMEM;
 
-	*num_maps = 0;
-
 	pgnames = devm_kzalloc(pcs->dev, sizeof(*pgnames), GFP_KERNEL);
 	if (!pgnames) {
 		ret = -ENOMEM;
 		goto free_map;
 	}
 
-	ret = pcs_parse_one_pinctrl_entry(pcs, np_config, map, pgnames);
+	ret = pcs_parse_one_pinctrl_entry(pcs, np_config, map,
+					  num_configs, pgnames);
 	if (ret < 0) {
 		dev_err(pcs->dev, "no pins entries for %s\n",
 			np_config->name);
 		goto free_pgnames;
 	}
-	*num_maps = 1;
 
 	return 0;
 
@@ -1015,6 +1238,43 @@ static int __devinit pcs_probe(struct platform_device *pdev)
 	if (ret)
 		pcs->foff = PCS_OFF_DISABLED;
 
+	ret = of_property_read_u32(np, "pinctrl-single,power-source-mask",
+					&pcs->psmask);
+	if (ret)
+		pcs->psmask = PCS_OFF_DISABLED;
+	ret = of_property_read_u32(np, "pinctrl-single,power-source-shift",
+					&pcs->psshift);
+	if (ret)
+		pcs->psshift = PCS_OFF_DISABLED;
+	ret = of_property_read_u32(np, "pinctrl-single,bias-mask",
+					&pcs->bmask);
+	if (ret)
+		pcs->bmask = PCS_OFF_DISABLED;
+	ret = of_property_read_u32(np, "pinctrl-single,bias-shift",
+					&pcs->bshift);
+	if (ret)
+		pcs->bshift = PCS_OFF_DISABLED;
+	ret = of_property_read_u32(np, "pinctrl-single,bias-disable",
+					&pcs->bdis);
+	if (ret)
+		pcs->bdis = PCS_OFF_DISABLED;
+	ret = of_property_read_u32(np, "pinctrl-single,bias-pull-up",
+					&pcs->bpullup);
+	if (ret)
+		pcs->bpullup = PCS_OFF_DISABLED;
+	ret = of_property_read_u32(np, "pinctrl-single,bias-pull-down",
+					&pcs->bpulldown);
+	if (ret)
+		pcs->bpulldown = PCS_OFF_DISABLED;
+	ret = of_property_read_u32(np, "pinctrl-single,input-schmitt-mask",
+					&pcs->ismask);
+	if (ret)
+		pcs->ismask = PCS_OFF_DISABLED;
+	ret = of_property_read_u32(np, "pinctrl-single,input-schmitt-shift",
+					&pcs->isshift);
+	if (ret)
+		pcs->isshift = PCS_OFF_DISABLED;
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 		dev_err(pcs->dev, "could not get resource\n");
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

end of thread, other threads:[~2012-11-07 15:04 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-10-31 23:04 [PATCH v3 0/9]: pinctrl-single support DT Haojian Zhuang
2012-10-31 23:04 ` [PATCH v3 1/9] ARM: mmp: select pinctrl driver Haojian Zhuang
2012-10-31 23:04 ` [PATCH v3 2/9] pinctrl: single: support gpio request and free Haojian Zhuang
2012-10-31 23:04 ` [PATCH v3 3/9] pinctrl: single: support pinconf generic Haojian Zhuang
2012-11-01  0:44   ` Tony Lindgren
2012-11-07  7:27     ` [PATCH 08/10] " Haojian Zhuang
2012-10-31 23:04 ` [PATCH v3 4/9] ARM: dts: support pinctrl single in pxa910 Haojian Zhuang
2012-10-31 23:04 ` [PATCH v3 5/9] document: devicetree: bind pinconf with pin-single Haojian Zhuang
2012-11-01 18:04   ` Stephen Warren
2012-11-02 16:37     ` Tony Lindgren
2012-11-07 15:04     ` Haojian Zhuang
2012-10-31 23:04 ` [PATCH v3 6/9] tty: pxa: configure pin Haojian Zhuang
2012-10-31 23:04 ` [PATCH v3 7/9] i2c: pxa: use devm_kzalloc Haojian Zhuang
2012-10-31 23:04 ` [PATCH v3 8/9] i2c: pxa: configure pinmux Haojian Zhuang
2012-10-31 23:04 ` [PATCH v3 9/9] pinctrl: single: dump pinmux register value Haojian Zhuang
2012-11-01  0:47   ` Tony Lindgren
2012-11-01  5:48     ` Haojian Zhuang
2012-11-06 14:39       ` Linus Walleij
  -- strict thread matches above, loose matches on Subject: below --
2012-10-18  9:06 [PATCH 01/10] pinctrl: use postcore_initcall Haojian Zhuang
     [not found] ` <1350551224-12857-1-git-send-email-haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2012-10-18  9:07   ` [PATCH 08/10] pinctrl: single: support pinconf generic Haojian Zhuang
2012-10-18  9:07     ` Haojian Zhuang
     [not found]     ` <1350551224-12857-8-git-send-email-haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2012-10-18 18:30       ` Linus Walleij
2012-10-18 18:30         ` Linus Walleij
     [not found]         ` <CACRpkda0QLkdKns3CXNOijYBjaDtW1QyhNYjTqDvRH-in8pvZQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-10-18 22:29           ` Tony Lindgren
2012-10-18 22:29             ` Tony Lindgren
     [not found]             ` <20121018222907.GH30550-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
2012-10-19  2:23               ` Haojian Zhuang
2012-10-19  2:23                 ` Haojian Zhuang
     [not found]                 ` <CAN1soZzsruhWt7VFgf5Fi79npcjLiMSUEVwnE3hR5iWEh+9GRw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-10-19  2:40                   ` Tony Lindgren
2012-10-19  2:40                     ` Tony Lindgren
     [not found]                     ` <20121019024012.GP30550-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
2012-10-19 18:44                       ` Tony Lindgren
2012-10-19 18:44                         ` Tony Lindgren
2012-10-19 18:53                   ` Tony Lindgren
2012-10-19 18:53                     ` Tony Lindgren
2012-10-19 19:13       ` Tony Lindgren
2012-10-19 19:13         ` Tony Lindgren
     [not found]         ` <20121019191333.GT4730-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
2012-10-22 10:09           ` Haojian Zhuang
2012-10-22 10:09             ` Haojian Zhuang
     [not found]             ` <CAN1soZzE_tTkmPBechvUcdAbWKSScwcaqe_cb0TTmnRJi9gtRg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-10-22 17:09               ` Tony Lindgren
2012-10-22 17:09                 ` Tony Lindgren
     [not found]                 ` <20121022170917.GB4730-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
2012-10-25 23:43                   ` Tony Lindgren
2012-10-25 23:43                     ` Tony Lindgren
     [not found]                     ` <20121025234328.GF11928-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
2012-10-26  1:47                       ` Haojian Zhuang
2012-10-26  1:47                         ` Haojian Zhuang
     [not found]                         ` <CAN1soZyosQJYZAT61tUig6PGVrfXzwDeiC1R0hnKWoFLVP4Ayw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-10-26 17:29                           ` Tony Lindgren
2012-10-26 17:29                             ` Tony Lindgren
2012-10-31 22:37                       ` Haojian Zhuang
2012-10-31 22:37                         ` Haojian Zhuang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.