aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinctrl-single.c
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@ti.com>2012-09-11 04:54:24 -0400
committerLinus Walleij <linus.walleij@linaro.org>2012-09-13 03:00:10 -0400
commit9e605cb68a21d5704839a192a46ebcf387773704 (patch)
tree11768cb28e03ee2600d4728f0b993fda4b53a168 /drivers/pinctrl/pinctrl-single.c
parent2830c3686be31f74cc788250eb54dc2d7a7e48d8 (diff)
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@ti.com> Acked-by: Tony Lindgren <tony@atomide.com> [Removed a misplaced comment] Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/pinctrl-single.c')
-rw-r--r--drivers/pinctrl/pinctrl-single.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index 35086310b81..aabecfa507b 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -26,7 +26,8 @@
26#include "core.h" 26#include "core.h"
27 27
28#define DRIVER_NAME "pinctrl-single" 28#define DRIVER_NAME "pinctrl-single"
29#define PCS_MUX_NAME "pinctrl-single,pins" 29#define PCS_MUX_PINS_NAME "pinctrl-single,pins"
30#define PCS_MUX_BITS_NAME "pinctrl-single,bits"
30#define PCS_REG_NAME_LEN ((sizeof(unsigned long) * 2) + 1) 31#define PCS_REG_NAME_LEN ((sizeof(unsigned long) * 2) + 1)
31#define PCS_OFF_DISABLED ~0U 32#define PCS_OFF_DISABLED ~0U
32 33
@@ -54,6 +55,7 @@ struct pcs_pingroup {
54struct pcs_func_vals { 55struct pcs_func_vals {
55 void __iomem *reg; 56 void __iomem *reg;
56 unsigned val; 57 unsigned val;
58 unsigned mask;
57}; 59};
58 60
59/** 61/**
@@ -139,6 +141,7 @@ struct pcs_device {
139 unsigned fshift; 141 unsigned fshift;
140 unsigned foff; 142 unsigned foff;
141 unsigned fmax; 143 unsigned fmax;
144 bool bits_per_mux;
142 struct pcs_name *names; 145 struct pcs_name *names;
143 struct pcs_data pins; 146 struct pcs_data pins;
144 struct radix_tree_root pgtree; 147 struct radix_tree_root pgtree;
@@ -332,12 +335,17 @@ static int pcs_enable(struct pinctrl_dev *pctldev, unsigned fselector,
332 335
333 for (i = 0; i < func->nvals; i++) { 336 for (i = 0; i < func->nvals; i++) {
334 struct pcs_func_vals *vals; 337 struct pcs_func_vals *vals;
335 unsigned val; 338 unsigned val, mask;
336 339
337 vals = &func->vals[i]; 340 vals = &func->vals[i];
338 val = pcs->read(vals->reg); 341 val = pcs->read(vals->reg);
339 val &= ~pcs->fmask; 342 if (!vals->mask)
340 val |= (vals->val & pcs->fmask); 343 mask = pcs->fmask;
344 else
345 mask = pcs->fmask & vals->mask;
346
347 val &= ~mask;
348 val |= (vals->val & mask);
341 pcs->write(val, vals->reg); 349 pcs->write(val, vals->reg);
342 } 350 }
343 351
@@ -657,18 +665,29 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
657{ 665{
658 struct pcs_func_vals *vals; 666 struct pcs_func_vals *vals;
659 const __be32 *mux; 667 const __be32 *mux;
660 int size, rows, *pins, index = 0, found = 0, res = -ENOMEM; 668 int size, params, rows, *pins, index = 0, found = 0, res = -ENOMEM;
661 struct pcs_function *function; 669 struct pcs_function *function;
662 670
663 mux = of_get_property(np, PCS_MUX_NAME, &size); 671 if (pcs->bits_per_mux) {
664 if ((!mux) || (size < sizeof(*mux) * 2)) { 672 params = 3;
665 dev_err(pcs->dev, "bad data for mux %s\n", 673 mux = of_get_property(np, PCS_MUX_BITS_NAME, &size);
666 np->name); 674 } else {
675 params = 2;
676 mux = of_get_property(np, PCS_MUX_PINS_NAME, &size);
677 }
678
679 if (!mux) {
680 dev_err(pcs->dev, "no valid property for %s\n", np->name);
681 return -EINVAL;
682 }
683
684 if (size < (sizeof(*mux) * params)) {
685 dev_err(pcs->dev, "bad data for %s\n", np->name);
667 return -EINVAL; 686 return -EINVAL;
668 } 687 }
669 688
670 size /= sizeof(*mux); /* Number of elements in array */ 689 size /= sizeof(*mux); /* Number of elements in array */
671 rows = size / 2; /* Each row is a key value pair */ 690 rows = size / params;
672 691
673 vals = devm_kzalloc(pcs->dev, sizeof(*vals) * rows, GFP_KERNEL); 692 vals = devm_kzalloc(pcs->dev, sizeof(*vals) * rows, GFP_KERNEL);
674 if (!vals) 693 if (!vals)
@@ -686,6 +705,10 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
686 val = be32_to_cpup(mux + index++); 705 val = be32_to_cpup(mux + index++);
687 vals[found].reg = pcs->base + offset; 706 vals[found].reg = pcs->base + offset;
688 vals[found].val = val; 707 vals[found].val = val;
708 if (params == 3) {
709 val = be32_to_cpup(mux + index++);
710 vals[found].mask = val;
711 }
689 712
690 pin = pcs_get_pin_by_offset(pcs, offset); 713 pin = pcs_get_pin_by_offset(pcs, offset);
691 if (pin < 0) { 714 if (pin < 0) {
@@ -883,6 +906,9 @@ static int __devinit pcs_probe(struct platform_device *pdev)
883 if (ret) 906 if (ret)
884 pcs->foff = PCS_OFF_DISABLED; 907 pcs->foff = PCS_OFF_DISABLED;
885 908
909 pcs->bits_per_mux = of_property_read_bool(np,
910 "pinctrl-single,bit-per-mux");
911
886 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 912 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
887 if (!res) { 913 if (!res) {
888 dev_err(pcs->dev, "could not get resource\n"); 914 dev_err(pcs->dev, "could not get resource\n");