OSDN Git Service

clk: Fix CLK_SET_RATE_GATE flag validation in clk_set_rate().
[uclinux-h8/linux.git] / drivers / pinctrl / pinctrl-pxa3xx.c
1 /*
2  *  linux/drivers/pinctrl/pinctrl-pxa3xx.c
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License version 2 as
6  *  publishhed by the Free Software Foundation.
7  *
8  *  Copyright (C) 2011, Marvell Technology Group Ltd.
9  *
10  *  Author: Haojian Zhuang <haojian.zhuang@marvell.com>
11  *
12  */
13
14 #include <linux/module.h>
15 #include <linux/device.h>
16 #include <linux/io.h>
17 #include <linux/platform_device.h>
18 #include <linux/slab.h>
19 #include "pinctrl-pxa3xx.h"
20
21 static struct pinctrl_gpio_range pxa3xx_pinctrl_gpio_range = {
22         .name           = "PXA3xx GPIO",
23         .id             = 0,
24         .base           = 0,
25         .pin_base       = 0,
26 };
27
28 static int pxa3xx_list_groups(struct pinctrl_dev *pctrldev, unsigned selector)
29 {
30         struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
31         if (selector >= info->num_grps)
32                 return -EINVAL;
33         return 0;
34 }
35
36 static const char *pxa3xx_get_group_name(struct pinctrl_dev *pctrldev,
37                                          unsigned selector)
38 {
39         struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
40         if (selector >= info->num_grps)
41                 return NULL;
42         return info->grps[selector].name;
43 }
44
45 static int pxa3xx_get_group_pins(struct pinctrl_dev *pctrldev,
46                                  unsigned selector,
47                                  const unsigned **pins,
48                                  unsigned *num_pins)
49 {
50         struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
51         if (selector >= info->num_grps)
52                 return -EINVAL;
53         *pins = info->grps[selector].pins;
54         *num_pins = info->grps[selector].npins;
55         return 0;
56 }
57
58 static struct pinctrl_ops pxa3xx_pctrl_ops = {
59         .list_groups    = pxa3xx_list_groups,
60         .get_group_name = pxa3xx_get_group_name,
61         .get_group_pins = pxa3xx_get_group_pins,
62 };
63
64 static int pxa3xx_pmx_list_func(struct pinctrl_dev *pctrldev, unsigned func)
65 {
66         struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
67         if (func >= info->num_funcs)
68                 return -EINVAL;
69         return 0;
70 }
71
72 static const char *pxa3xx_pmx_get_func_name(struct pinctrl_dev *pctrldev,
73                                             unsigned func)
74 {
75         struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
76         return info->funcs[func].name;
77 }
78
79 static int pxa3xx_pmx_get_groups(struct pinctrl_dev *pctrldev, unsigned func,
80                                  const char * const **groups,
81                                  unsigned * const num_groups)
82 {
83         struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
84         *groups = info->funcs[func].groups;
85         *num_groups = info->funcs[func].num_groups;
86         return 0;
87 }
88
89 /* Return function number. If failure, return negative value. */
90 static int match_mux(struct pxa3xx_mfp_pin *mfp, unsigned mux)
91 {
92         int i;
93         for (i = 0; i < PXA3xx_MAX_MUX; i++) {
94                 if (mfp->func[i] == mux)
95                         break;
96         }
97         if (i >= PXA3xx_MAX_MUX)
98                 return -EINVAL;
99         return i;
100 }
101
102 /* check whether current pin configuration is valid. Negative for failure */
103 static int match_group_mux(struct pxa3xx_pin_group *grp,
104                            struct pxa3xx_pinmux_info *info,
105                            unsigned mux)
106 {
107         int i, pin, ret = 0;
108         for (i = 0; i < grp->npins; i++) {
109                 pin = grp->pins[i];
110                 ret = match_mux(&info->mfp[pin], mux);
111                 if (ret < 0) {
112                         dev_err(info->dev, "Can't find mux %d on pin%d\n",
113                                 mux, pin);
114                         break;
115                 }
116         }
117         return ret;
118 }
119
120 static int pxa3xx_pmx_enable(struct pinctrl_dev *pctrldev, unsigned func,
121                              unsigned group)
122 {
123         struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
124         struct pxa3xx_pin_group *pin_grp = &info->grps[group];
125         unsigned int data;
126         int i, mfpr, pin, pin_func;
127
128         if (!pin_grp->npins ||
129                 (match_group_mux(pin_grp, info, pin_grp->mux) < 0)) {
130                 dev_err(info->dev, "Failed to set the pin group: %d\n", group);
131                 return -EINVAL;
132         }
133         for (i = 0; i < pin_grp->npins; i++) {
134                 pin = pin_grp->pins[i];
135                 pin_func = match_mux(&info->mfp[pin], pin_grp->mux);
136                 mfpr = info->mfp[pin].mfpr;
137                 data = readl_relaxed(info->virt_base + mfpr);
138                 data &= ~MFPR_FUNC_MASK;
139                 data |= pin_func;
140                 writel_relaxed(data, info->virt_base + mfpr);
141         }
142         return 0;
143 }
144
145 static void pxa3xx_pmx_disable(struct pinctrl_dev *pctrldev, unsigned func,
146                                unsigned group)
147 {
148 }
149
150 static int pxa3xx_pmx_request_gpio(struct pinctrl_dev *pctrldev,
151                                    struct pinctrl_gpio_range *range,
152                                    unsigned pin)
153 {
154         struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
155         unsigned int data;
156         int pin_func, mfpr;
157
158         pin_func = match_mux(&info->mfp[pin], PXA3xx_MUX_GPIO);
159         if (pin_func < 0) {
160                 dev_err(info->dev, "No GPIO function on pin%d (%s)\n",
161                         pin, info->pads[pin].name);
162                 return -EINVAL;
163         }
164         mfpr = info->mfp[pin].mfpr;
165         /* write gpio function into mfpr register */
166         data = readl_relaxed(info->virt_base + mfpr) & ~MFPR_FUNC_MASK;
167         data |= pin_func;
168         writel_relaxed(data, info->virt_base + mfpr);
169         return 0;
170 }
171
172 static struct pinmux_ops pxa3xx_pmx_ops = {
173         .list_functions         = pxa3xx_pmx_list_func,
174         .get_function_name      = pxa3xx_pmx_get_func_name,
175         .get_function_groups    = pxa3xx_pmx_get_groups,
176         .enable                 = pxa3xx_pmx_enable,
177         .disable                = pxa3xx_pmx_disable,
178         .gpio_request_enable    = pxa3xx_pmx_request_gpio,
179 };
180
181 int pxa3xx_pinctrl_register(struct platform_device *pdev,
182                             struct pxa3xx_pinmux_info *info)
183 {
184         struct pinctrl_desc *desc;
185         struct resource *res;
186         int ret = 0;
187
188         if (!info || !info->cputype)
189                 return -EINVAL;
190         desc = info->desc;
191         desc->pins = info->pads;
192         desc->npins = info->num_pads;
193         desc->pctlops = &pxa3xx_pctrl_ops;
194         desc->pmxops = &pxa3xx_pmx_ops;
195         info->dev = &pdev->dev;
196         pxa3xx_pinctrl_gpio_range.npins = info->num_gpio;
197
198         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
199         if (!res)
200                 return -ENOENT;
201         info->phy_base = res->start;
202         info->phy_size = resource_size(res);
203         info->virt_base = ioremap(info->phy_base, info->phy_size);
204         if (!info->virt_base)
205                 return -ENOMEM;
206         info->pctrl = pinctrl_register(desc, &pdev->dev, info);
207         if (!info->pctrl) {
208                 dev_err(&pdev->dev, "failed to register PXA pinmux driver\n");
209                 ret = -EINVAL;
210                 goto err;
211         }
212         pinctrl_add_gpio_range(info->pctrl, &pxa3xx_pinctrl_gpio_range);
213         platform_set_drvdata(pdev, info);
214         return 0;
215 err:
216         iounmap(info->virt_base);
217         return ret;
218 }
219
220 int pxa3xx_pinctrl_unregister(struct platform_device *pdev)
221 {
222         struct pxa3xx_pinmux_info *info = platform_get_drvdata(pdev);
223
224         pinctrl_unregister(info->pctrl);
225         iounmap(info->virt_base);
226         platform_set_drvdata(pdev, NULL);
227         return 0;
228 }
229
230 static int __init pxa3xx_pinctrl_init(void)
231 {
232         pr_info("pxa3xx-pinctrl: PXA3xx pinctrl driver initializing\n");
233         return 0;
234 }
235 core_initcall_sync(pxa3xx_pinctrl_init);
236
237 static void __exit pxa3xx_pinctrl_exit(void)
238 {
239 }
240 module_exit(pxa3xx_pinctrl_exit);
241
242 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
243 MODULE_DESCRIPTION("PXA3xx pin control driver");
244 MODULE_LICENSE("GPL v2");