Commit | Line | Data |
---|---|---|
3b20b003 | 1 | // SPDX-License-Identifier: GPL-2.0 |
0317d60d | 2 | /* |
0317d60d JC |
3 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> |
4 | */ | |
5 | ||
6 | #include <linux/module.h> | |
7 | #include <linux/device.h> | |
8 | #include <linux/io.h> | |
9 | #include <linux/platform_device.h> | |
10 | #include <linux/slab.h> | |
11 | #include <linux/of.h> | |
12 | #include <linux/pinctrl/pinctrl.h> | |
13 | #include <linux/pinctrl/pinconf.h> | |
0ca1f908 | 14 | #include <linux/pinctrl/pinconf-generic.h> |
0317d60d JC |
15 | #include <linux/pinctrl/pinmux.h> |
16 | #include <linux/pinctrl/consumer.h> | |
17 | #include <linux/pinctrl/machine.h> | |
18 | ||
19 | #include <asm/mach-ralink/ralink_regs.h> | |
0317d60d JC |
20 | #include <asm/mach-ralink/mt7620.h> |
21 | ||
6b3dd85b | 22 | #include "pinctrl-ralink.h" |
518b466a SP |
23 | #include "../core.h" |
24 | #include "../pinctrl-utils.h" | |
0317d60d JC |
25 | |
26 | #define SYSC_REG_GPIO_MODE 0x60 | |
27 | #define SYSC_REG_GPIO_MODE2 0x64 | |
28 | ||
6b3dd85b | 29 | struct ralink_priv { |
0317d60d JC |
30 | struct device *dev; |
31 | ||
32 | struct pinctrl_pin_desc *pads; | |
33 | struct pinctrl_desc *desc; | |
34 | ||
6b3dd85b | 35 | struct ralink_pmx_func **func; |
0317d60d JC |
36 | int func_count; |
37 | ||
6b3dd85b | 38 | struct ralink_pmx_group *groups; |
0317d60d JC |
39 | const char **group_names; |
40 | int group_count; | |
41 | ||
4a1cf86b | 42 | u8 *gpio; |
0317d60d JC |
43 | int max_pins; |
44 | }; | |
45 | ||
6b3dd85b | 46 | static int ralink_get_group_count(struct pinctrl_dev *pctrldev) |
0317d60d | 47 | { |
6b3dd85b | 48 | struct ralink_priv *p = pinctrl_dev_get_drvdata(pctrldev); |
0317d60d JC |
49 | |
50 | return p->group_count; | |
51 | } | |
52 | ||
6b3dd85b | 53 | static const char *ralink_get_group_name(struct pinctrl_dev *pctrldev, |
c3de9923 | 54 | unsigned int group) |
0317d60d | 55 | { |
6b3dd85b | 56 | struct ralink_priv *p = pinctrl_dev_get_drvdata(pctrldev); |
0317d60d | 57 | |
74ee97cc | 58 | return (group >= p->group_count) ? NULL : p->group_names[group]; |
0317d60d JC |
59 | } |
60 | ||
6b3dd85b | 61 | static int ralink_get_group_pins(struct pinctrl_dev *pctrldev, |
c3de9923 SP |
62 | unsigned int group, |
63 | const unsigned int **pins, | |
64 | unsigned int *num_pins) | |
0317d60d | 65 | { |
6b3dd85b | 66 | struct ralink_priv *p = pinctrl_dev_get_drvdata(pctrldev); |
0317d60d JC |
67 | |
68 | if (group >= p->group_count) | |
69 | return -EINVAL; | |
70 | ||
71 | *pins = p->groups[group].func[0].pins; | |
72 | *num_pins = p->groups[group].func[0].pin_count; | |
73 | ||
74 | return 0; | |
75 | } | |
76 | ||
6b3dd85b AÜ |
77 | static const struct pinctrl_ops ralink_pctrl_ops = { |
78 | .get_groups_count = ralink_get_group_count, | |
79 | .get_group_name = ralink_get_group_name, | |
80 | .get_group_pins = ralink_get_group_pins, | |
0ca1f908 SP |
81 | .dt_node_to_map = pinconf_generic_dt_node_to_map_all, |
82 | .dt_free_map = pinconf_generic_dt_free_map, | |
0317d60d JC |
83 | }; |
84 | ||
6b3dd85b | 85 | static int ralink_pmx_func_count(struct pinctrl_dev *pctrldev) |
0317d60d | 86 | { |
6b3dd85b | 87 | struct ralink_priv *p = pinctrl_dev_get_drvdata(pctrldev); |
0317d60d JC |
88 | |
89 | return p->func_count; | |
90 | } | |
91 | ||
6b3dd85b | 92 | static const char *ralink_pmx_func_name(struct pinctrl_dev *pctrldev, |
d756d387 | 93 | unsigned int func) |
0317d60d | 94 | { |
6b3dd85b | 95 | struct ralink_priv *p = pinctrl_dev_get_drvdata(pctrldev); |
0317d60d JC |
96 | |
97 | return p->func[func]->name; | |
98 | } | |
99 | ||
6b3dd85b | 100 | static int ralink_pmx_group_get_groups(struct pinctrl_dev *pctrldev, |
d756d387 SP |
101 | unsigned int func, |
102 | const char * const **groups, | |
103 | unsigned int * const num_groups) | |
0317d60d | 104 | { |
6b3dd85b | 105 | struct ralink_priv *p = pinctrl_dev_get_drvdata(pctrldev); |
0317d60d JC |
106 | |
107 | if (p->func[func]->group_count == 1) | |
108 | *groups = &p->group_names[p->func[func]->groups[0]]; | |
109 | else | |
110 | *groups = p->group_names; | |
111 | ||
112 | *num_groups = p->func[func]->group_count; | |
113 | ||
114 | return 0; | |
115 | } | |
116 | ||
6b3dd85b | 117 | static int ralink_pmx_group_enable(struct pinctrl_dev *pctrldev, |
d756d387 | 118 | unsigned int func, unsigned int group) |
0317d60d | 119 | { |
6b3dd85b | 120 | struct ralink_priv *p = pinctrl_dev_get_drvdata(pctrldev); |
a2a678b6 | 121 | u32 mode = 0; |
0317d60d JC |
122 | u32 reg = SYSC_REG_GPIO_MODE; |
123 | int i; | |
124 | int shift; | |
125 | ||
126 | /* dont allow double use */ | |
127 | if (p->groups[group].enabled) { | |
c60cf7e0 SP |
128 | dev_err(p->dev, "%s is already enabled\n", |
129 | p->groups[group].name); | |
eb367d87 | 130 | return 0; |
0317d60d JC |
131 | } |
132 | ||
133 | p->groups[group].enabled = 1; | |
134 | p->func[func]->enabled = 1; | |
135 | ||
136 | shift = p->groups[group].shift; | |
137 | if (shift >= 32) { | |
138 | shift -= 32; | |
139 | reg = SYSC_REG_GPIO_MODE2; | |
140 | } | |
141 | mode = rt_sysc_r32(reg); | |
142 | mode &= ~(p->groups[group].mask << shift); | |
143 | ||
144 | /* mark the pins as gpio */ | |
145 | for (i = 0; i < p->groups[group].func[0].pin_count; i++) | |
146 | p->gpio[p->groups[group].func[0].pins[i]] = 1; | |
147 | ||
148 | /* function 0 is gpio and needs special handling */ | |
149 | if (func == 0) { | |
150 | mode |= p->groups[group].gpio << shift; | |
151 | } else { | |
152 | for (i = 0; i < p->func[func]->pin_count; i++) | |
153 | p->gpio[p->func[func]->pins[i]] = 0; | |
154 | mode |= p->func[func]->value << shift; | |
155 | } | |
156 | rt_sysc_w32(mode, reg); | |
157 | ||
158 | return 0; | |
159 | } | |
160 | ||
6b3dd85b | 161 | static int ralink_pmx_group_gpio_request_enable(struct pinctrl_dev *pctrldev, |
d756d387 SP |
162 | struct pinctrl_gpio_range *range, |
163 | unsigned int pin) | |
0317d60d | 164 | { |
6b3dd85b | 165 | struct ralink_priv *p = pinctrl_dev_get_drvdata(pctrldev); |
0317d60d JC |
166 | |
167 | if (!p->gpio[pin]) { | |
168 | dev_err(p->dev, "pin %d is not set to gpio mux\n", pin); | |
169 | return -EINVAL; | |
170 | } | |
171 | ||
172 | return 0; | |
173 | } | |
174 | ||
6b3dd85b AÜ |
175 | static const struct pinmux_ops ralink_pmx_group_ops = { |
176 | .get_functions_count = ralink_pmx_func_count, | |
177 | .get_function_name = ralink_pmx_func_name, | |
178 | .get_function_groups = ralink_pmx_group_get_groups, | |
179 | .set_mux = ralink_pmx_group_enable, | |
180 | .gpio_request_enable = ralink_pmx_group_gpio_request_enable, | |
0317d60d JC |
181 | }; |
182 | ||
6b3dd85b | 183 | static struct pinctrl_desc ralink_pctrl_desc = { |
0317d60d | 184 | .owner = THIS_MODULE, |
bc25a975 | 185 | .name = "ralink-pinctrl", |
6b3dd85b AÜ |
186 | .pctlops = &ralink_pctrl_ops, |
187 | .pmxops = &ralink_pmx_group_ops, | |
0317d60d JC |
188 | }; |
189 | ||
6b3dd85b | 190 | static struct ralink_pmx_func gpio_func = { |
0317d60d JC |
191 | .name = "gpio", |
192 | }; | |
193 | ||
bc25a975 | 194 | static int ralink_pinctrl_index(struct ralink_priv *p) |
0317d60d | 195 | { |
6b3dd85b | 196 | struct ralink_pmx_group *mux = p->groups; |
0317d60d JC |
197 | int i, j, c = 0; |
198 | ||
199 | /* count the mux functions */ | |
200 | while (mux->name) { | |
201 | p->group_count++; | |
202 | mux++; | |
203 | } | |
204 | ||
205 | /* allocate the group names array needed by the gpio function */ | |
c60cf7e0 SP |
206 | p->group_names = devm_kcalloc(p->dev, p->group_count, |
207 | sizeof(char *), GFP_KERNEL); | |
0317d60d | 208 | if (!p->group_names) |
7391031b | 209 | return -ENOMEM; |
0317d60d JC |
210 | |
211 | for (i = 0; i < p->group_count; i++) { | |
212 | p->group_names[i] = p->groups[i].name; | |
213 | p->func_count += p->groups[i].func_count; | |
214 | } | |
215 | ||
216 | /* we have a dummy function[0] for gpio */ | |
217 | p->func_count++; | |
218 | ||
219 | /* allocate our function and group mapping index buffers */ | |
53abfe67 SP |
220 | p->func = devm_kcalloc(p->dev, p->func_count, |
221 | sizeof(*p->func), GFP_KERNEL); | |
a86854d0 KC |
222 | gpio_func.groups = devm_kcalloc(p->dev, p->group_count, sizeof(int), |
223 | GFP_KERNEL); | |
53abfe67 SP |
224 | if (!p->func || !gpio_func.groups) |
225 | return -ENOMEM; | |
0317d60d JC |
226 | |
227 | /* add a backpointer to the function so it knows its group */ | |
228 | gpio_func.group_count = p->group_count; | |
229 | for (i = 0; i < gpio_func.group_count; i++) | |
230 | gpio_func.groups[i] = i; | |
231 | ||
53abfe67 | 232 | p->func[c] = &gpio_func; |
0317d60d JC |
233 | c++; |
234 | ||
235 | /* add remaining functions */ | |
236 | for (i = 0; i < p->group_count; i++) { | |
237 | for (j = 0; j < p->groups[i].func_count; j++) { | |
53abfe67 SP |
238 | p->func[c] = &p->groups[i].func[j]; |
239 | p->func[c]->groups = devm_kzalloc(p->dev, sizeof(int), | |
c60cf7e0 | 240 | GFP_KERNEL); |
09f8101d SP |
241 | if (!p->func[c]->groups) |
242 | return -ENOMEM; | |
53abfe67 SP |
243 | p->func[c]->groups[0] = i; |
244 | p->func[c]->group_count = 1; | |
0317d60d JC |
245 | c++; |
246 | } | |
247 | } | |
248 | return 0; | |
249 | } | |
250 | ||
bc25a975 | 251 | static int ralink_pinctrl_pins(struct ralink_priv *p) |
0317d60d JC |
252 | { |
253 | int i, j; | |
254 | ||
c60cf7e0 SP |
255 | /* |
256 | * loop over the functions and initialize the pins array. | |
257 | * also work out the highest pin used. | |
258 | */ | |
0317d60d JC |
259 | for (i = 0; i < p->func_count; i++) { |
260 | int pin; | |
261 | ||
262 | if (!p->func[i]->pin_count) | |
263 | continue; | |
264 | ||
a86854d0 KC |
265 | p->func[i]->pins = devm_kcalloc(p->dev, |
266 | p->func[i]->pin_count, | |
267 | sizeof(int), | |
268 | GFP_KERNEL); | |
c3b821e8 WD |
269 | if (!p->func[i]->pins) |
270 | return -ENOMEM; | |
0317d60d JC |
271 | for (j = 0; j < p->func[i]->pin_count; j++) |
272 | p->func[i]->pins[j] = p->func[i]->pin_first + j; | |
273 | ||
274 | pin = p->func[i]->pin_first + p->func[i]->pin_count; | |
275 | if (pin > p->max_pins) | |
276 | p->max_pins = pin; | |
277 | } | |
278 | ||
279 | /* the buffer that tells us which pins are gpio */ | |
4a1cf86b | 280 | p->gpio = devm_kcalloc(p->dev, p->max_pins, sizeof(u8), GFP_KERNEL); |
0317d60d | 281 | /* the pads needed to tell pinctrl about our pins */ |
c60cf7e0 SP |
282 | p->pads = devm_kcalloc(p->dev, p->max_pins, |
283 | sizeof(struct pinctrl_pin_desc), GFP_KERNEL); | |
420cf17d | 284 | if (!p->pads || !p->gpio) |
0317d60d | 285 | return -ENOMEM; |
0317d60d | 286 | |
4a1cf86b | 287 | memset(p->gpio, 1, sizeof(u8) * p->max_pins); |
0317d60d JC |
288 | for (i = 0; i < p->func_count; i++) { |
289 | if (!p->func[i]->pin_count) | |
290 | continue; | |
291 | ||
292 | for (j = 0; j < p->func[i]->pin_count; j++) | |
293 | p->gpio[p->func[i]->pins[j]] = 0; | |
294 | } | |
295 | ||
296 | /* pin 0 is always a gpio */ | |
297 | p->gpio[0] = 1; | |
298 | ||
299 | /* set the pads */ | |
300 | for (i = 0; i < p->max_pins; i++) { | |
301 | /* strlen("ioXY") + 1 = 5 */ | |
302 | char *name = devm_kzalloc(p->dev, 5, GFP_KERNEL); | |
303 | ||
63e57b95 | 304 | if (!name) |
0317d60d | 305 | return -ENOMEM; |
0317d60d JC |
306 | snprintf(name, 5, "io%d", i); |
307 | p->pads[i].number = i; | |
308 | p->pads[i].name = name; | |
309 | } | |
310 | p->desc->pins = p->pads; | |
311 | p->desc->npins = p->max_pins; | |
312 | ||
313 | return 0; | |
314 | } | |
315 | ||
bc25a975 AÜ |
316 | int ralink_pinctrl_init(struct platform_device *pdev, |
317 | struct ralink_pmx_group *data) | |
0317d60d | 318 | { |
6b3dd85b | 319 | struct ralink_priv *p; |
0317d60d | 320 | struct pinctrl_dev *dev; |
8a55d64c | 321 | int err; |
0317d60d | 322 | |
276e552e | 323 | if (!data) |
32c6dcff | 324 | return -ENOTSUPP; |
0317d60d JC |
325 | |
326 | /* setup the private data */ | |
6b3dd85b | 327 | p = devm_kzalloc(&pdev->dev, sizeof(struct ralink_priv), GFP_KERNEL); |
0317d60d JC |
328 | if (!p) |
329 | return -ENOMEM; | |
330 | ||
331 | p->dev = &pdev->dev; | |
6b3dd85b | 332 | p->desc = &ralink_pctrl_desc; |
276e552e | 333 | p->groups = data; |
0317d60d JC |
334 | platform_set_drvdata(pdev, p); |
335 | ||
336 | /* init the device */ | |
bc25a975 | 337 | err = ralink_pinctrl_index(p); |
8a55d64c | 338 | if (err) { |
0317d60d | 339 | dev_err(&pdev->dev, "failed to load index\n"); |
8a55d64c | 340 | return err; |
0317d60d | 341 | } |
8a55d64c | 342 | |
bc25a975 | 343 | err = ralink_pinctrl_pins(p); |
8a55d64c | 344 | if (err) { |
0317d60d | 345 | dev_err(&pdev->dev, "failed to load pins\n"); |
8a55d64c | 346 | return err; |
0317d60d JC |
347 | } |
348 | dev = pinctrl_register(p->desc, &pdev->dev, p); | |
0317d60d | 349 | |
50a71087 | 350 | return PTR_ERR_OR_ZERO(dev); |
0317d60d | 351 | } |