[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1346835718-21325-3-git-send-email-peter.ujfalusi@ti.com>
Date: Wed, 5 Sep 2012 12:01:58 +0300
From: Peter Ujfalusi <peter.ujfalusi@...com>
To: Linus Walleij <linus.walleij@...aro.org>,
Tony Lindgren <tony@...mide.com>
Cc: linux-kernel@...r.kernel.org, linux-omap@...r.kernel.org
Subject: [PATCH 2/2] pinctrl: pinctrl-single: Add pinctrl-single,bits type of mux
With pinctrl-single,bits it is possible to update just part of the register
within the pinctrl-single,function-mask area.
This is useful when one register configures mmore than one pin's mux.
pinctrl-single,bits takes three parameters:
<reg offset, value, sub-mask>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@...com>
---
.../devicetree/bindings/pinctrl/pinctrl-single.txt | 9 +++++
drivers/pinctrl/pinctrl-single.c | 42 ++++++++++++++++------
2 files changed, 41 insertions(+), 10 deletions(-)
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt
index 5187f0d..287801d 100644
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.txt
@@ -31,6 +31,15 @@ device pinctrl register, and 0x118 contains the desired value of the
pinctrl register. See the device example and static board pins example
below for more information.
+In case when one register changes more than one pin's mux the
+pinctrl-single,bits can be used which takes three parameters:
+
+ pinctrl-single,bits = <0xdc 0x18, 0xff>;
+
+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.
+
Example:
/* SoC common file */
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index 3508631..aec338e 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -26,7 +26,8 @@
#include "core.h"
#define DRIVER_NAME "pinctrl-single"
-#define PCS_MUX_NAME "pinctrl-single,pins"
+#define PCS_MUX_PINS_NAME "pinctrl-single,pins"
+#define PCS_MUX_BITS_NAME "pinctrl-single,bits"
#define PCS_REG_NAME_LEN ((sizeof(unsigned long) * 2) + 1)
#define PCS_OFF_DISABLED ~0U
@@ -54,6 +55,7 @@ struct pcs_pingroup {
struct pcs_func_vals {
void __iomem *reg;
unsigned val;
+ unsigned mask;
};
/**
@@ -332,12 +334,17 @@ static int pcs_enable(struct pinctrl_dev *pctldev, unsigned fselector,
for (i = 0; i < func->nvals; i++) {
struct pcs_func_vals *vals;
- unsigned val;
+ unsigned val, mask;
vals = &func->vals[i];
val = pcs->read(vals->reg);
- val &= ~pcs->fmask;
- val |= (vals->val & pcs->fmask);
+ if (!vals->mask)
+ mask = pcs->fmask;
+ else
+ mask = pcs->fmask & vals->mask;
+
+ val &= ~mask;
+ val |= (vals->val & mask);
pcs->write(val, vals->reg);
}
@@ -657,18 +664,29 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
{
struct pcs_func_vals *vals;
const __be32 *mux;
- int size, rows, *pins, index = 0, found = 0, res = -ENOMEM;
+ int size, params, rows, *pins, index = 0, found = 0, res = -ENOMEM;
struct pcs_function *function;
- mux = of_get_property(np, PCS_MUX_NAME, &size);
- if ((!mux) || (size < sizeof(*mux) * 2)) {
- dev_err(pcs->dev, "bad data for mux %s\n",
- np->name);
+ mux = of_get_property(np, PCS_MUX_PINS_NAME, &size);
+ if (mux) {
+ params = 2;
+ } else {
+ mux = of_get_property(np, PCS_MUX_BITS_NAME, &size);
+ if (!mux) {
+ dev_err(pcs->dev, "no valid property for %s\n",
+ np->name);
+ return -EINVAL;
+ }
+ params = 3;
+ }
+
+ if (size < (sizeof(*mux) * params)) {
+ dev_err(pcs->dev, "bad data for %s\n", np->name);
return -EINVAL;
}
size /= sizeof(*mux); /* Number of elements in array */
- rows = size / 2; /* Each row is a key value pair */
+ rows = size / params; /* Each row is a key value pair */
vals = devm_kzalloc(pcs->dev, sizeof(*vals) * rows, GFP_KERNEL);
if (!vals)
@@ -686,6 +704,10 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
val = be32_to_cpup(mux + index++);
vals[found].reg = pcs->base + offset;
vals[found].val = val;
+ if (params == 3) {
+ val = be32_to_cpup(mux + index++);
+ vals[found].mask = val;
+ }
pin = pcs_get_pin_by_offset(pcs, offset);
if (pin < 0) {
--
1.7.12
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists