aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinctrl-single.c
diff options
context:
space:
mode:
authorHaojian Zhuang <haojian.zhuang@gmail.com>2012-11-15 03:36:31 -0500
committerLinus Walleij <linus.walleij@linaro.org>2012-11-21 02:55:27 -0500
commit2e8b2eab94c35d83bb7da71c63b4695f32ddca88 (patch)
tree578f464443efaa00d53f1d698e1dbb82b9f2fe94 /drivers/pinctrl/pinctrl-single.c
parent2ccb0bcfb0dd2001b1a40048c1e407cd9a78bd3d (diff)
pinctrl: single: support gpio request and free
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. GPIO range is defined as a child node of pinmux in .dtsi file. If those pins are with the same gpio function configuration in the pinmux register, they could be defined in the same GPIO range. For this new child node, two properties are used. reg = <the start of pinmux register in range, size of range> pinctrl-single,gpio: <gpio base in range, the gpio function of the range in the pinmux register> Signed-off-by: Haojian Zhuang <haojian.zhuang@gmail.com> Acked-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/pinctrl-single.c')
-rw-r--r--drivers/pinctrl/pinctrl-single.c80
1 files changed, 78 insertions, 2 deletions
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index 145025f50086..e8dbb94494d3 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -30,6 +30,7 @@
30#define PCS_MUX_BITS_NAME "pinctrl-single,bits" 30#define PCS_MUX_BITS_NAME "pinctrl-single,bits"
31#define PCS_REG_NAME_LEN ((sizeof(unsigned long) * 2) + 1) 31#define PCS_REG_NAME_LEN ((sizeof(unsigned long) * 2) + 1)
32#define PCS_OFF_DISABLED ~0U 32#define PCS_OFF_DISABLED ~0U
33#define PCS_MAX_GPIO_VALUES 2
33 34
34/** 35/**
35 * struct pcs_pingroup - pingroups for a function 36 * struct pcs_pingroup - pingroups for a function
@@ -77,6 +78,16 @@ struct pcs_function {
77}; 78};
78 79
79/** 80/**
81 * struct pcs_gpio_range - pinctrl gpio range
82 * @range: subrange of the GPIO number space
83 * @gpio_func: gpio function value in the pinmux register
84 */
85struct pcs_gpio_range {
86 struct pinctrl_gpio_range range;
87 int gpio_func;
88};
89
90/**
80 * struct pcs_data - wrapper for data needed by pinctrl framework 91 * struct pcs_data - wrapper for data needed by pinctrl framework
81 * @pa: pindesc array 92 * @pa: pindesc array
82 * @cur: index to current element 93 * @cur: index to current element
@@ -403,9 +414,26 @@ static void pcs_disable(struct pinctrl_dev *pctldev, unsigned fselector,
403} 414}
404 415
405static int pcs_request_gpio(struct pinctrl_dev *pctldev, 416static int pcs_request_gpio(struct pinctrl_dev *pctldev,
406 struct pinctrl_gpio_range *range, unsigned offset) 417 struct pinctrl_gpio_range *range, unsigned pin)
407{ 418{
408 return -ENOTSUPP; 419 struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
420 struct pcs_gpio_range *gpio = NULL;
421 int end, mux_bytes;
422 unsigned data;
423
424 gpio = container_of(range, struct pcs_gpio_range, range);
425 end = range->pin_base + range->npins - 1;
426 if (pin < range->pin_base || pin > end) {
427 dev_err(pctldev->dev,
428 "pin %d isn't in the range of %d to %d\n",
429 pin, range->pin_base, end);
430 return -EINVAL;
431 }
432 mux_bytes = pcs->width / BITS_PER_BYTE;
433 data = pcs->read(pcs->base + pin * mux_bytes) & ~pcs->fmask;
434 data |= gpio->gpio_func;
435 pcs->write(data, pcs->base + pin * mux_bytes);
436 return 0;
409} 437}
410 438
411static struct pinmux_ops pcs_pinmux_ops = { 439static struct pinmux_ops pcs_pinmux_ops = {
@@ -879,6 +907,50 @@ static void pcs_free_resources(struct pcs_device *pcs)
879 907
880static struct of_device_id pcs_of_match[]; 908static struct of_device_id pcs_of_match[];
881 909
910static int __devinit pcs_add_gpio_range(struct device_node *node,
911 struct pcs_device *pcs)
912{
913 struct pcs_gpio_range *gpio;
914 struct device_node *child;
915 struct resource r;
916 const char name[] = "pinctrl-single";
917 u32 gpiores[PCS_MAX_GPIO_VALUES];
918 int ret, i = 0, mux_bytes = 0;
919
920 for_each_child_of_node(node, child) {
921 ret = of_address_to_resource(child, 0, &r);
922 if (ret < 0)
923 continue;
924 memset(gpiores, 0, sizeof(u32) * PCS_MAX_GPIO_VALUES);
925 ret = of_property_read_u32_array(child, "pinctrl-single,gpio",
926 gpiores, PCS_MAX_GPIO_VALUES);
927 if (ret < 0)
928 continue;
929 gpio = devm_kzalloc(pcs->dev, sizeof(*gpio), GFP_KERNEL);
930 if (!gpio) {
931 dev_err(pcs->dev, "failed to allocate pcs gpio\n");
932 return -ENOMEM;
933 }
934 gpio->range.name = devm_kzalloc(pcs->dev, sizeof(name),
935 GFP_KERNEL);
936 if (!gpio->range.name) {
937 dev_err(pcs->dev, "failed to allocate range name\n");
938 return -ENOMEM;
939 }
940 memcpy((char *)gpio->range.name, name, sizeof(name));
941
942 gpio->range.id = i++;
943 gpio->range.base = gpiores[0];
944 gpio->gpio_func = gpiores[1];
945 mux_bytes = pcs->width / BITS_PER_BYTE;
946 gpio->range.pin_base = (r.start - pcs->res->start) / mux_bytes;
947 gpio->range.npins = (r.end - r.start) / mux_bytes + 1;
948
949 pinctrl_add_gpio_range(pcs->pctl, &gpio->range);
950 }
951 return 0;
952}
953
882static int __devinit pcs_probe(struct platform_device *pdev) 954static int __devinit pcs_probe(struct platform_device *pdev)
883{ 955{
884 struct device_node *np = pdev->dev.of_node; 956 struct device_node *np = pdev->dev.of_node;
@@ -975,6 +1047,10 @@ static int __devinit pcs_probe(struct platform_device *pdev)
975 goto free; 1047 goto free;
976 } 1048 }
977 1049
1050 ret = pcs_add_gpio_range(np, pcs);
1051 if (ret < 0)
1052 goto free;
1053
978 dev_info(pcs->dev, "%i pins at pa %p size %u\n", 1054 dev_info(pcs->dev, "%i pins at pa %p size %u\n",
979 pcs->desc.npins, pcs->base, pcs->size); 1055 pcs->desc.npins, pcs->base, pcs->size);
980 1056