aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Jarzmik <robert.jarzmik@free.fr>2015-11-21 13:04:50 -0500
committerLinus Walleij <linus.walleij@linaro.org>2015-12-10 10:11:35 -0500
commitd530ef9b88e5162a1972050994264d66ca884f3f (patch)
tree3b6f36d479d9b8ec8788577ef72e58e206ad8134
parent73317712d9277407b726917de7c4e6d5a4b7df99 (diff)
pinctrl: pxa: pxa2xx: add pin muxing
The driver is inspired from the sunxi driver. The pxa architecture specificities leading to the driver are : - each pin has 8 possible alternate functions - 4 of these are output kind - 4 of these are input kind - there is always a "gpio input" and "gpio output" function - the function matrix is very scattered : - some functions can be found on 5 different pads - the number of functions is greater than the number of pins - there is no "topology" grouping of pins (such as all SPI in one corner of the die) Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/pinctrl/pxa/pinctrl-pxa2xx.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
index baded1a8745b..a4ba82459af8 100644
--- a/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
+++ b/drivers/pinctrl/pxa/pinctrl-pxa2xx.c
@@ -64,8 +64,129 @@ static const struct pinctrl_ops pxa2xx_pctl_ops = {
64 .get_group_pins = pxa2xx_pctrl_get_group_pins, 64 .get_group_pins = pxa2xx_pctrl_get_group_pins,
65}; 65};
66 66
67static struct pxa_desc_function *
68pxa_desc_by_func_group(struct pxa_pinctrl *pctl, const char *pin_name,
69 const char *func_name)
70{
71 int i;
72 struct pxa_desc_function *df;
73
74 for (i = 0; i < pctl->npins; i++) {
75 const struct pxa_desc_pin *pin = pctl->ppins + i;
76
77 if (!strcmp(pin->pin.name, pin_name))
78 for (df = pin->functions; df->name; df++)
79 if (!strcmp(df->name, func_name))
80 return df;
81 }
82
83 return NULL;
84}
85
86static int pxa2xx_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
87 struct pinctrl_gpio_range *range,
88 unsigned pin,
89 bool input)
90{
91 struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
92 unsigned long flags;
93 uint32_t val;
94 void __iomem *gpdr;
95
96 gpdr = pctl->base_gpdr[pin / 32];
97 dev_dbg(pctl->dev, "set_direction(pin=%d): dir=%d\n",
98 pin, !input);
99
100 spin_lock_irqsave(&pctl->lock, flags);
101
102 val = readl_relaxed(gpdr);
103 val = (val & ~BIT(pin % 32)) | (input ? 0 : BIT(pin % 32));
104 writel_relaxed(val, gpdr);
105
106 spin_unlock_irqrestore(&pctl->lock, flags);
107
108 return 0;
109}
110
111static const char *pxa2xx_pmx_get_func_name(struct pinctrl_dev *pctldev,
112 unsigned function)
113{
114 struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
115 struct pxa_pinctrl_function *pf = pctl->functions + function;
116
117 return pf->name;
118}
119
120static int pxa2xx_get_functions_count(struct pinctrl_dev *pctldev)
121{
122 struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
123
124 return pctl->nfuncs;
125}
126
127static int pxa2xx_pmx_get_func_groups(struct pinctrl_dev *pctldev,
128 unsigned function,
129 const char * const **groups,
130 unsigned * const num_groups)
131{
132 struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
133 struct pxa_pinctrl_function *pf = pctl->functions + function;
134
135 *groups = pf->groups;
136 *num_groups = pf->ngroups;
137
138 return 0;
139}
140
141static int pxa2xx_pmx_set_mux(struct pinctrl_dev *pctldev, unsigned function,
142 unsigned tgroup)
143{
144 struct pxa_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
145 struct pxa_pinctrl_group *group = pctl->groups + tgroup;
146 struct pxa_desc_function *df;
147 int pin, shift;
148 unsigned long flags;
149 void __iomem *gafr, *gpdr;
150 u32 val;
151
152
153 df = pxa_desc_by_func_group(pctl, group->name,
154 (pctl->functions + function)->name);
155 if (!df)
156 return -EINVAL;
157
158 pin = group->pin;
159 gafr = pctl->base_gafr[pin / 16];
160 gpdr = pctl->base_gpdr[pin / 32];
161 shift = (pin % 16) << 1;
162 dev_dbg(pctl->dev, "set_mux(pin=%d): af=%d dir=%d\n",
163 pin, df->muxval >> 1, df->muxval & 0x1);
164
165 spin_lock_irqsave(&pctl->lock, flags);
166
167 val = readl_relaxed(gafr);
168 val = (val & ~(0x3 << shift)) | ((df->muxval >> 1) << shift);
169 writel_relaxed(val, gafr);
170
171 val = readl_relaxed(gpdr);
172 val = (val & ~BIT(pin % 32)) | ((df->muxval & 1) ? BIT(pin % 32) : 0);
173 writel_relaxed(val, gpdr);
174
175 spin_unlock_irqrestore(&pctl->lock, flags);
176
177 return 0;
178}
179static const struct pinmux_ops pxa2xx_pinmux_ops = {
180 .get_functions_count = pxa2xx_get_functions_count,
181 .get_function_name = pxa2xx_pmx_get_func_name,
182 .get_function_groups = pxa2xx_pmx_get_func_groups,
183 .set_mux = pxa2xx_pmx_set_mux,
184 .gpio_set_direction = pxa2xx_pmx_gpio_set_direction,
185};
186
67static struct pinctrl_desc pxa2xx_pinctrl_desc = { 187static struct pinctrl_desc pxa2xx_pinctrl_desc = {
68 .pctlops = &pxa2xx_pctl_ops, 188 .pctlops = &pxa2xx_pctl_ops,
189 .pmxops = &pxa2xx_pinmux_ops,
69}; 190};
70 191
71static const struct pxa_pinctrl_function * 192static const struct pxa_pinctrl_function *