1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
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> |
14 | #include <linux/pinctrl/pinconf-generic.h> |
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> |
20 | #include <asm/mach-ralink/mt7620.h> |
21 | |
22 | #include "pinctrl-mtmips.h" |
23 | #include "../core.h" |
24 | #include "../pinctrl-utils.h" |
25 | |
26 | #define SYSC_REG_GPIO_MODE 0x60 |
27 | #define SYSC_REG_GPIO_MODE2 0x64 |
28 | |
29 | struct mtmips_priv { |
30 | struct device *dev; |
31 | |
32 | struct pinctrl_pin_desc *pads; |
33 | struct pinctrl_desc *desc; |
34 | |
35 | struct mtmips_pmx_func **func; |
36 | int func_count; |
37 | |
38 | struct mtmips_pmx_group *groups; |
39 | const char **group_names; |
40 | int group_count; |
41 | |
42 | u8 *gpio; |
43 | int max_pins; |
44 | }; |
45 | |
46 | static int mtmips_get_group_count(struct pinctrl_dev *pctrldev) |
47 | { |
48 | struct mtmips_priv *p = pinctrl_dev_get_drvdata(pctldev: pctrldev); |
49 | |
50 | return p->group_count; |
51 | } |
52 | |
53 | static const char *mtmips_get_group_name(struct pinctrl_dev *pctrldev, |
54 | unsigned int group) |
55 | { |
56 | struct mtmips_priv *p = pinctrl_dev_get_drvdata(pctldev: pctrldev); |
57 | |
58 | return (group >= p->group_count) ? NULL : p->group_names[group]; |
59 | } |
60 | |
61 | static int mtmips_get_group_pins(struct pinctrl_dev *pctrldev, |
62 | unsigned int group, |
63 | const unsigned int **pins, |
64 | unsigned int *num_pins) |
65 | { |
66 | struct mtmips_priv *p = pinctrl_dev_get_drvdata(pctldev: pctrldev); |
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 | |
77 | static const struct pinctrl_ops mtmips_pctrl_ops = { |
78 | .get_groups_count = mtmips_get_group_count, |
79 | .get_group_name = mtmips_get_group_name, |
80 | .get_group_pins = mtmips_get_group_pins, |
81 | .dt_node_to_map = pinconf_generic_dt_node_to_map_all, |
82 | .dt_free_map = pinconf_generic_dt_free_map, |
83 | }; |
84 | |
85 | static int mtmips_pmx_func_count(struct pinctrl_dev *pctrldev) |
86 | { |
87 | struct mtmips_priv *p = pinctrl_dev_get_drvdata(pctldev: pctrldev); |
88 | |
89 | return p->func_count; |
90 | } |
91 | |
92 | static const char *mtmips_pmx_func_name(struct pinctrl_dev *pctrldev, |
93 | unsigned int func) |
94 | { |
95 | struct mtmips_priv *p = pinctrl_dev_get_drvdata(pctldev: pctrldev); |
96 | |
97 | return p->func[func]->name; |
98 | } |
99 | |
100 | static int mtmips_pmx_group_get_groups(struct pinctrl_dev *pctrldev, |
101 | unsigned int func, |
102 | const char * const **groups, |
103 | unsigned int * const num_groups) |
104 | { |
105 | struct mtmips_priv *p = pinctrl_dev_get_drvdata(pctldev: pctrldev); |
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 | |
117 | static int mtmips_pmx_group_enable(struct pinctrl_dev *pctrldev, |
118 | unsigned int func, unsigned int group) |
119 | { |
120 | struct mtmips_priv *p = pinctrl_dev_get_drvdata(pctldev: pctrldev); |
121 | u32 mode = 0; |
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) { |
128 | dev_err(p->dev, "%s is already enabled\n" , |
129 | p->groups[group].name); |
130 | return 0; |
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 | |
161 | static int mtmips_pmx_group_gpio_request_enable(struct pinctrl_dev *pctrldev, |
162 | struct pinctrl_gpio_range *range, |
163 | unsigned int pin) |
164 | { |
165 | struct mtmips_priv *p = pinctrl_dev_get_drvdata(pctldev: pctrldev); |
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 | |
175 | static const struct pinmux_ops mtmips_pmx_group_ops = { |
176 | .get_functions_count = mtmips_pmx_func_count, |
177 | .get_function_name = mtmips_pmx_func_name, |
178 | .get_function_groups = mtmips_pmx_group_get_groups, |
179 | .set_mux = mtmips_pmx_group_enable, |
180 | .gpio_request_enable = mtmips_pmx_group_gpio_request_enable, |
181 | }; |
182 | |
183 | static struct pinctrl_desc mtmips_pctrl_desc = { |
184 | .owner = THIS_MODULE, |
185 | .name = "mtmips-pinctrl" , |
186 | .pctlops = &mtmips_pctrl_ops, |
187 | .pmxops = &mtmips_pmx_group_ops, |
188 | }; |
189 | |
190 | static struct mtmips_pmx_func gpio_func = { |
191 | .name = "gpio" , |
192 | }; |
193 | |
194 | static int mtmips_pinctrl_index(struct mtmips_priv *p) |
195 | { |
196 | struct mtmips_pmx_group *mux = p->groups; |
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 */ |
206 | p->group_names = devm_kcalloc(dev: p->dev, n: p->group_count, |
207 | size: sizeof(char *), GFP_KERNEL); |
208 | if (!p->group_names) |
209 | return -ENOMEM; |
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 */ |
220 | p->func = devm_kcalloc(dev: p->dev, n: p->func_count, |
221 | size: sizeof(*p->func), GFP_KERNEL); |
222 | gpio_func.groups = devm_kcalloc(dev: p->dev, n: p->group_count, size: sizeof(int), |
223 | GFP_KERNEL); |
224 | if (!p->func || !gpio_func.groups) |
225 | return -ENOMEM; |
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 | |
232 | p->func[c] = &gpio_func; |
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++) { |
238 | p->func[c] = &p->groups[i].func[j]; |
239 | p->func[c]->groups = devm_kzalloc(dev: p->dev, size: sizeof(int), |
240 | GFP_KERNEL); |
241 | if (!p->func[c]->groups) |
242 | return -ENOMEM; |
243 | p->func[c]->groups[0] = i; |
244 | p->func[c]->group_count = 1; |
245 | c++; |
246 | } |
247 | } |
248 | return 0; |
249 | } |
250 | |
251 | static int mtmips_pinctrl_pins(struct mtmips_priv *p) |
252 | { |
253 | int i, j; |
254 | |
255 | /* |
256 | * loop over the functions and initialize the pins array. |
257 | * also work out the highest pin used. |
258 | */ |
259 | for (i = 0; i < p->func_count; i++) { |
260 | int pin; |
261 | |
262 | if (!p->func[i]->pin_count) |
263 | continue; |
264 | |
265 | p->func[i]->pins = devm_kcalloc(dev: p->dev, |
266 | n: p->func[i]->pin_count, |
267 | size: sizeof(int), |
268 | GFP_KERNEL); |
269 | if (!p->func[i]->pins) |
270 | return -ENOMEM; |
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 */ |
280 | p->gpio = devm_kcalloc(dev: p->dev, n: p->max_pins, size: sizeof(u8), GFP_KERNEL); |
281 | /* the pads needed to tell pinctrl about our pins */ |
282 | p->pads = devm_kcalloc(dev: p->dev, n: p->max_pins, |
283 | size: sizeof(struct pinctrl_pin_desc), GFP_KERNEL); |
284 | if (!p->pads || !p->gpio) |
285 | return -ENOMEM; |
286 | |
287 | memset(p->gpio, 1, sizeof(u8) * p->max_pins); |
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(dev: p->dev, size: 5, GFP_KERNEL); |
303 | |
304 | if (!name) |
305 | return -ENOMEM; |
306 | snprintf(buf: name, size: 5, fmt: "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 | |
316 | int mtmips_pinctrl_init(struct platform_device *pdev, |
317 | struct mtmips_pmx_group *data) |
318 | { |
319 | struct mtmips_priv *p; |
320 | struct pinctrl_dev *dev; |
321 | int err; |
322 | |
323 | if (!data) |
324 | return -ENOTSUPP; |
325 | |
326 | /* setup the private data */ |
327 | p = devm_kzalloc(dev: &pdev->dev, size: sizeof(struct mtmips_priv), GFP_KERNEL); |
328 | if (!p) |
329 | return -ENOMEM; |
330 | |
331 | p->dev = &pdev->dev; |
332 | p->desc = &mtmips_pctrl_desc; |
333 | p->groups = data; |
334 | platform_set_drvdata(pdev, data: p); |
335 | |
336 | /* init the device */ |
337 | err = mtmips_pinctrl_index(p); |
338 | if (err) { |
339 | dev_err(&pdev->dev, "failed to load index\n" ); |
340 | return err; |
341 | } |
342 | |
343 | err = mtmips_pinctrl_pins(p); |
344 | if (err) { |
345 | dev_err(&pdev->dev, "failed to load pins\n" ); |
346 | return err; |
347 | } |
348 | dev = pinctrl_register(pctldesc: p->desc, dev: &pdev->dev, driver_data: p); |
349 | |
350 | return PTR_ERR_OR_ZERO(ptr: dev); |
351 | } |
352 | |