Commit | Line | Data |
---|---|---|
ce8dc094 AB |
1 | // SPDX-License-Identifier: (GPL-2.0 OR MIT) |
2 | /* | |
3 | * Microsemi SoCs pinctrl driver | |
4 | * | |
5 | * Author: <alexandre.belloni@free-electrons.com> | |
6 | * License: Dual MIT/GPL | |
7 | * Copyright (c) 2017 Microsemi Corporation | |
8 | */ | |
9 | ||
10 | #include <linux/gpio/driver.h> | |
11 | #include <linux/interrupt.h> | |
12 | #include <linux/io.h> | |
13 | #include <linux/of_device.h> | |
be36abb7 | 14 | #include <linux/of_irq.h> |
ce8dc094 AB |
15 | #include <linux/of_platform.h> |
16 | #include <linux/pinctrl/pinctrl.h> | |
17 | #include <linux/pinctrl/pinmux.h> | |
18 | #include <linux/pinctrl/pinconf.h> | |
19 | #include <linux/pinctrl/pinconf-generic.h> | |
20 | #include <linux/platform_device.h> | |
21 | #include <linux/regmap.h> | |
22 | #include <linux/slab.h> | |
23 | ||
24 | #include "core.h" | |
25 | #include "pinconf.h" | |
26 | #include "pinmux.h" | |
27 | ||
28 | #define OCELOT_GPIO_OUT_SET 0x0 | |
29 | #define OCELOT_GPIO_OUT_CLR 0x4 | |
30 | #define OCELOT_GPIO_OUT 0x8 | |
31 | #define OCELOT_GPIO_IN 0xc | |
32 | #define OCELOT_GPIO_OE 0x10 | |
33 | #define OCELOT_GPIO_INTR 0x14 | |
34 | #define OCELOT_GPIO_INTR_ENA 0x18 | |
35 | #define OCELOT_GPIO_INTR_IDENT 0x1c | |
36 | #define OCELOT_GPIO_ALT0 0x20 | |
37 | #define OCELOT_GPIO_ALT1 0x24 | |
38 | #define OCELOT_GPIO_SD_MAP 0x28 | |
39 | ||
ce8dc094 AB |
40 | #define OCELOT_FUNC_PER_PIN 4 |
41 | ||
42 | enum { | |
43 | FUNC_NONE, | |
44 | FUNC_GPIO, | |
45 | FUNC_IRQ0_IN, | |
46 | FUNC_IRQ0_OUT, | |
47 | FUNC_IRQ1_IN, | |
48 | FUNC_IRQ1_OUT, | |
49 | FUNC_MIIM1, | |
da801ab5 | 50 | FUNC_MIIM2, |
ce8dc094 AB |
51 | FUNC_PCI_WAKE, |
52 | FUNC_PTP0, | |
53 | FUNC_PTP1, | |
54 | FUNC_PTP2, | |
55 | FUNC_PTP3, | |
56 | FUNC_PWM, | |
57 | FUNC_RECO_CLK0, | |
58 | FUNC_RECO_CLK1, | |
59 | FUNC_SFP0, | |
60 | FUNC_SFP1, | |
61 | FUNC_SFP2, | |
62 | FUNC_SFP3, | |
63 | FUNC_SFP4, | |
64 | FUNC_SFP5, | |
da801ab5 AB |
65 | FUNC_SFP6, |
66 | FUNC_SFP7, | |
67 | FUNC_SFP8, | |
68 | FUNC_SFP9, | |
69 | FUNC_SFP10, | |
70 | FUNC_SFP11, | |
71 | FUNC_SFP12, | |
72 | FUNC_SFP13, | |
73 | FUNC_SFP14, | |
74 | FUNC_SFP15, | |
ce8dc094 | 75 | FUNC_SG0, |
da801ab5 AB |
76 | FUNC_SG1, |
77 | FUNC_SG2, | |
ce8dc094 AB |
78 | FUNC_SI, |
79 | FUNC_TACHO, | |
80 | FUNC_TWI, | |
da801ab5 | 81 | FUNC_TWI2, |
ce8dc094 AB |
82 | FUNC_TWI_SCL_M, |
83 | FUNC_UART, | |
84 | FUNC_UART2, | |
85 | FUNC_MAX | |
86 | }; | |
87 | ||
88 | static const char *const ocelot_function_names[] = { | |
89 | [FUNC_NONE] = "none", | |
90 | [FUNC_GPIO] = "gpio", | |
91 | [FUNC_IRQ0_IN] = "irq0_in", | |
92 | [FUNC_IRQ0_OUT] = "irq0_out", | |
93 | [FUNC_IRQ1_IN] = "irq1_in", | |
94 | [FUNC_IRQ1_OUT] = "irq1_out", | |
95 | [FUNC_MIIM1] = "miim1", | |
da801ab5 | 96 | [FUNC_MIIM2] = "miim2", |
ce8dc094 AB |
97 | [FUNC_PCI_WAKE] = "pci_wake", |
98 | [FUNC_PTP0] = "ptp0", | |
99 | [FUNC_PTP1] = "ptp1", | |
100 | [FUNC_PTP2] = "ptp2", | |
101 | [FUNC_PTP3] = "ptp3", | |
102 | [FUNC_PWM] = "pwm", | |
103 | [FUNC_RECO_CLK0] = "reco_clk0", | |
104 | [FUNC_RECO_CLK1] = "reco_clk1", | |
105 | [FUNC_SFP0] = "sfp0", | |
106 | [FUNC_SFP1] = "sfp1", | |
107 | [FUNC_SFP2] = "sfp2", | |
108 | [FUNC_SFP3] = "sfp3", | |
109 | [FUNC_SFP4] = "sfp4", | |
110 | [FUNC_SFP5] = "sfp5", | |
da801ab5 AB |
111 | [FUNC_SFP6] = "sfp6", |
112 | [FUNC_SFP7] = "sfp7", | |
113 | [FUNC_SFP8] = "sfp8", | |
114 | [FUNC_SFP9] = "sfp9", | |
115 | [FUNC_SFP10] = "sfp10", | |
116 | [FUNC_SFP11] = "sfp11", | |
117 | [FUNC_SFP12] = "sfp12", | |
118 | [FUNC_SFP13] = "sfp13", | |
119 | [FUNC_SFP14] = "sfp14", | |
120 | [FUNC_SFP15] = "sfp15", | |
ce8dc094 | 121 | [FUNC_SG0] = "sg0", |
da801ab5 AB |
122 | [FUNC_SG1] = "sg1", |
123 | [FUNC_SG2] = "sg2", | |
ce8dc094 AB |
124 | [FUNC_SI] = "si", |
125 | [FUNC_TACHO] = "tacho", | |
126 | [FUNC_TWI] = "twi", | |
da801ab5 | 127 | [FUNC_TWI2] = "twi2", |
ce8dc094 AB |
128 | [FUNC_TWI_SCL_M] = "twi_scl_m", |
129 | [FUNC_UART] = "uart", | |
130 | [FUNC_UART2] = "uart2", | |
131 | }; | |
132 | ||
133 | struct ocelot_pmx_func { | |
134 | const char **groups; | |
135 | unsigned int ngroups; | |
136 | }; | |
137 | ||
138 | struct ocelot_pin_caps { | |
139 | unsigned int pin; | |
140 | unsigned char functions[OCELOT_FUNC_PER_PIN]; | |
141 | }; | |
142 | ||
143 | struct ocelot_pinctrl { | |
144 | struct device *dev; | |
145 | struct pinctrl_dev *pctl; | |
146 | struct gpio_chip gpio_chip; | |
147 | struct regmap *map; | |
da801ab5 | 148 | struct pinctrl_desc *desc; |
ce8dc094 | 149 | struct ocelot_pmx_func func[FUNC_MAX]; |
da801ab5 | 150 | u8 stride; |
ce8dc094 AB |
151 | }; |
152 | ||
153 | #define OCELOT_P(p, f0, f1, f2) \ | |
154 | static struct ocelot_pin_caps ocelot_pin_##p = { \ | |
155 | .pin = p, \ | |
156 | .functions = { \ | |
157 | FUNC_GPIO, FUNC_##f0, FUNC_##f1, FUNC_##f2, \ | |
158 | }, \ | |
159 | } | |
160 | ||
161 | OCELOT_P(0, SG0, NONE, NONE); | |
162 | OCELOT_P(1, SG0, NONE, NONE); | |
163 | OCELOT_P(2, SG0, NONE, NONE); | |
164 | OCELOT_P(3, SG0, NONE, NONE); | |
17f79084 | 165 | OCELOT_P(4, IRQ0_IN, IRQ0_OUT, TWI_SCL_M); |
ce8dc094 AB |
166 | OCELOT_P(5, IRQ1_IN, IRQ1_OUT, PCI_WAKE); |
167 | OCELOT_P(6, UART, TWI_SCL_M, NONE); | |
168 | OCELOT_P(7, UART, TWI_SCL_M, NONE); | |
169 | OCELOT_P(8, SI, TWI_SCL_M, IRQ0_OUT); | |
170 | OCELOT_P(9, SI, TWI_SCL_M, IRQ1_OUT); | |
171 | OCELOT_P(10, PTP2, TWI_SCL_M, SFP0); | |
172 | OCELOT_P(11, PTP3, TWI_SCL_M, SFP1); | |
173 | OCELOT_P(12, UART2, TWI_SCL_M, SFP2); | |
174 | OCELOT_P(13, UART2, TWI_SCL_M, SFP3); | |
175 | OCELOT_P(14, MIIM1, TWI_SCL_M, SFP4); | |
176 | OCELOT_P(15, MIIM1, TWI_SCL_M, SFP5); | |
177 | OCELOT_P(16, TWI, NONE, SI); | |
178 | OCELOT_P(17, TWI, TWI_SCL_M, SI); | |
179 | OCELOT_P(18, PTP0, TWI_SCL_M, NONE); | |
180 | OCELOT_P(19, PTP1, TWI_SCL_M, NONE); | |
181 | OCELOT_P(20, RECO_CLK0, TACHO, NONE); | |
182 | OCELOT_P(21, RECO_CLK1, PWM, NONE); | |
183 | ||
184 | #define OCELOT_PIN(n) { \ | |
185 | .number = n, \ | |
186 | .name = "GPIO_"#n, \ | |
187 | .drv_data = &ocelot_pin_##n \ | |
188 | } | |
189 | ||
190 | static const struct pinctrl_pin_desc ocelot_pins[] = { | |
191 | OCELOT_PIN(0), | |
192 | OCELOT_PIN(1), | |
193 | OCELOT_PIN(2), | |
194 | OCELOT_PIN(3), | |
195 | OCELOT_PIN(4), | |
196 | OCELOT_PIN(5), | |
197 | OCELOT_PIN(6), | |
198 | OCELOT_PIN(7), | |
199 | OCELOT_PIN(8), | |
200 | OCELOT_PIN(9), | |
201 | OCELOT_PIN(10), | |
202 | OCELOT_PIN(11), | |
203 | OCELOT_PIN(12), | |
204 | OCELOT_PIN(13), | |
205 | OCELOT_PIN(14), | |
206 | OCELOT_PIN(15), | |
207 | OCELOT_PIN(16), | |
208 | OCELOT_PIN(17), | |
209 | OCELOT_PIN(18), | |
210 | OCELOT_PIN(19), | |
211 | OCELOT_PIN(20), | |
212 | OCELOT_PIN(21), | |
213 | }; | |
214 | ||
da801ab5 AB |
215 | #define JAGUAR2_P(p, f0, f1) \ |
216 | static struct ocelot_pin_caps jaguar2_pin_##p = { \ | |
217 | .pin = p, \ | |
218 | .functions = { \ | |
219 | FUNC_GPIO, FUNC_##f0, FUNC_##f1, FUNC_NONE \ | |
220 | }, \ | |
221 | } | |
222 | ||
223 | JAGUAR2_P(0, SG0, NONE); | |
224 | JAGUAR2_P(1, SG0, NONE); | |
225 | JAGUAR2_P(2, SG0, NONE); | |
226 | JAGUAR2_P(3, SG0, NONE); | |
227 | JAGUAR2_P(4, SG1, NONE); | |
228 | JAGUAR2_P(5, SG1, NONE); | |
229 | JAGUAR2_P(6, IRQ0_IN, IRQ0_OUT); | |
230 | JAGUAR2_P(7, IRQ1_IN, IRQ1_OUT); | |
231 | JAGUAR2_P(8, PTP0, NONE); | |
232 | JAGUAR2_P(9, PTP1, NONE); | |
233 | JAGUAR2_P(10, UART, NONE); | |
234 | JAGUAR2_P(11, UART, NONE); | |
235 | JAGUAR2_P(12, SG1, NONE); | |
236 | JAGUAR2_P(13, SG1, NONE); | |
237 | JAGUAR2_P(14, TWI, TWI_SCL_M); | |
238 | JAGUAR2_P(15, TWI, NONE); | |
239 | JAGUAR2_P(16, SI, TWI_SCL_M); | |
240 | JAGUAR2_P(17, SI, TWI_SCL_M); | |
241 | JAGUAR2_P(18, SI, TWI_SCL_M); | |
242 | JAGUAR2_P(19, PCI_WAKE, NONE); | |
243 | JAGUAR2_P(20, IRQ0_OUT, TWI_SCL_M); | |
244 | JAGUAR2_P(21, IRQ1_OUT, TWI_SCL_M); | |
245 | JAGUAR2_P(22, TACHO, NONE); | |
246 | JAGUAR2_P(23, PWM, NONE); | |
247 | JAGUAR2_P(24, UART2, NONE); | |
248 | JAGUAR2_P(25, UART2, SI); | |
249 | JAGUAR2_P(26, PTP2, SI); | |
250 | JAGUAR2_P(27, PTP3, SI); | |
251 | JAGUAR2_P(28, TWI2, SI); | |
252 | JAGUAR2_P(29, TWI2, SI); | |
253 | JAGUAR2_P(30, SG2, SI); | |
254 | JAGUAR2_P(31, SG2, SI); | |
255 | JAGUAR2_P(32, SG2, SI); | |
256 | JAGUAR2_P(33, SG2, SI); | |
257 | JAGUAR2_P(34, NONE, TWI_SCL_M); | |
258 | JAGUAR2_P(35, NONE, TWI_SCL_M); | |
259 | JAGUAR2_P(36, NONE, TWI_SCL_M); | |
260 | JAGUAR2_P(37, NONE, TWI_SCL_M); | |
261 | JAGUAR2_P(38, NONE, TWI_SCL_M); | |
262 | JAGUAR2_P(39, NONE, TWI_SCL_M); | |
263 | JAGUAR2_P(40, NONE, TWI_SCL_M); | |
264 | JAGUAR2_P(41, NONE, TWI_SCL_M); | |
265 | JAGUAR2_P(42, NONE, TWI_SCL_M); | |
266 | JAGUAR2_P(43, NONE, TWI_SCL_M); | |
267 | JAGUAR2_P(44, NONE, SFP8); | |
268 | JAGUAR2_P(45, NONE, SFP9); | |
269 | JAGUAR2_P(46, NONE, SFP10); | |
270 | JAGUAR2_P(47, NONE, SFP11); | |
271 | JAGUAR2_P(48, SFP0, NONE); | |
272 | JAGUAR2_P(49, SFP1, SI); | |
273 | JAGUAR2_P(50, SFP2, SI); | |
274 | JAGUAR2_P(51, SFP3, SI); | |
275 | JAGUAR2_P(52, SFP4, NONE); | |
276 | JAGUAR2_P(53, SFP5, NONE); | |
277 | JAGUAR2_P(54, SFP6, NONE); | |
278 | JAGUAR2_P(55, SFP7, NONE); | |
279 | JAGUAR2_P(56, MIIM1, SFP12); | |
280 | JAGUAR2_P(57, MIIM1, SFP13); | |
281 | JAGUAR2_P(58, MIIM2, SFP14); | |
282 | JAGUAR2_P(59, MIIM2, SFP15); | |
283 | JAGUAR2_P(60, NONE, NONE); | |
284 | JAGUAR2_P(61, NONE, NONE); | |
285 | JAGUAR2_P(62, NONE, NONE); | |
286 | JAGUAR2_P(63, NONE, NONE); | |
287 | ||
288 | #define JAGUAR2_PIN(n) { \ | |
289 | .number = n, \ | |
290 | .name = "GPIO_"#n, \ | |
291 | .drv_data = &jaguar2_pin_##n \ | |
292 | } | |
293 | ||
294 | static const struct pinctrl_pin_desc jaguar2_pins[] = { | |
295 | JAGUAR2_PIN(0), | |
296 | JAGUAR2_PIN(1), | |
297 | JAGUAR2_PIN(2), | |
298 | JAGUAR2_PIN(3), | |
299 | JAGUAR2_PIN(4), | |
300 | JAGUAR2_PIN(5), | |
301 | JAGUAR2_PIN(6), | |
302 | JAGUAR2_PIN(7), | |
303 | JAGUAR2_PIN(8), | |
304 | JAGUAR2_PIN(9), | |
305 | JAGUAR2_PIN(10), | |
306 | JAGUAR2_PIN(11), | |
307 | JAGUAR2_PIN(12), | |
308 | JAGUAR2_PIN(13), | |
309 | JAGUAR2_PIN(14), | |
310 | JAGUAR2_PIN(15), | |
311 | JAGUAR2_PIN(16), | |
312 | JAGUAR2_PIN(17), | |
313 | JAGUAR2_PIN(18), | |
314 | JAGUAR2_PIN(19), | |
315 | JAGUAR2_PIN(20), | |
316 | JAGUAR2_PIN(21), | |
317 | JAGUAR2_PIN(22), | |
318 | JAGUAR2_PIN(23), | |
319 | JAGUAR2_PIN(24), | |
320 | JAGUAR2_PIN(25), | |
321 | JAGUAR2_PIN(26), | |
322 | JAGUAR2_PIN(27), | |
323 | JAGUAR2_PIN(28), | |
324 | JAGUAR2_PIN(29), | |
325 | JAGUAR2_PIN(30), | |
326 | JAGUAR2_PIN(31), | |
327 | JAGUAR2_PIN(32), | |
328 | JAGUAR2_PIN(33), | |
329 | JAGUAR2_PIN(34), | |
330 | JAGUAR2_PIN(35), | |
331 | JAGUAR2_PIN(36), | |
332 | JAGUAR2_PIN(37), | |
333 | JAGUAR2_PIN(38), | |
334 | JAGUAR2_PIN(39), | |
335 | JAGUAR2_PIN(40), | |
336 | JAGUAR2_PIN(41), | |
337 | JAGUAR2_PIN(42), | |
338 | JAGUAR2_PIN(43), | |
339 | JAGUAR2_PIN(44), | |
340 | JAGUAR2_PIN(45), | |
341 | JAGUAR2_PIN(46), | |
342 | JAGUAR2_PIN(47), | |
343 | JAGUAR2_PIN(48), | |
344 | JAGUAR2_PIN(49), | |
345 | JAGUAR2_PIN(50), | |
346 | JAGUAR2_PIN(51), | |
347 | JAGUAR2_PIN(52), | |
348 | JAGUAR2_PIN(53), | |
349 | JAGUAR2_PIN(54), | |
350 | JAGUAR2_PIN(55), | |
351 | JAGUAR2_PIN(56), | |
352 | JAGUAR2_PIN(57), | |
353 | JAGUAR2_PIN(58), | |
354 | JAGUAR2_PIN(59), | |
355 | JAGUAR2_PIN(60), | |
356 | JAGUAR2_PIN(61), | |
357 | JAGUAR2_PIN(62), | |
358 | JAGUAR2_PIN(63), | |
359 | }; | |
360 | ||
ce8dc094 AB |
361 | static int ocelot_get_functions_count(struct pinctrl_dev *pctldev) |
362 | { | |
363 | return ARRAY_SIZE(ocelot_function_names); | |
364 | } | |
365 | ||
366 | static const char *ocelot_get_function_name(struct pinctrl_dev *pctldev, | |
367 | unsigned int function) | |
368 | { | |
369 | return ocelot_function_names[function]; | |
370 | } | |
371 | ||
372 | static int ocelot_get_function_groups(struct pinctrl_dev *pctldev, | |
373 | unsigned int function, | |
374 | const char *const **groups, | |
375 | unsigned *const num_groups) | |
376 | { | |
377 | struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | |
378 | ||
379 | *groups = info->func[function].groups; | |
380 | *num_groups = info->func[function].ngroups; | |
381 | ||
382 | return 0; | |
383 | } | |
384 | ||
da801ab5 AB |
385 | static int ocelot_pin_function_idx(struct ocelot_pinctrl *info, |
386 | unsigned int pin, unsigned int function) | |
ce8dc094 | 387 | { |
da801ab5 | 388 | struct ocelot_pin_caps *p = info->desc->pins[pin].drv_data; |
ce8dc094 AB |
389 | int i; |
390 | ||
391 | for (i = 0; i < OCELOT_FUNC_PER_PIN; i++) { | |
392 | if (function == p->functions[i]) | |
393 | return i; | |
394 | } | |
395 | ||
396 | return -1; | |
397 | } | |
398 | ||
da801ab5 AB |
399 | #define REG(r, info, p) ((r) * (info)->stride + (4 * ((p) / 32))) |
400 | ||
ce8dc094 AB |
401 | static int ocelot_pinmux_set_mux(struct pinctrl_dev *pctldev, |
402 | unsigned int selector, unsigned int group) | |
403 | { | |
404 | struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | |
da801ab5 AB |
405 | struct ocelot_pin_caps *pin = info->desc->pins[group].drv_data; |
406 | unsigned int p = pin->pin % 32; | |
ce8dc094 AB |
407 | int f; |
408 | ||
da801ab5 | 409 | f = ocelot_pin_function_idx(info, group, selector); |
ce8dc094 AB |
410 | if (f < 0) |
411 | return -EINVAL; | |
412 | ||
413 | /* | |
414 | * f is encoded on two bits. | |
415 | * bit 0 of f goes in BIT(pin) of ALT0, bit 1 of f goes in BIT(pin) of | |
416 | * ALT1 | |
417 | * This is racy because both registers can't be updated at the same time | |
418 | * but it doesn't matter much for now. | |
419 | */ | |
da801ab5 AB |
420 | regmap_update_bits(info->map, REG(OCELOT_GPIO_ALT0, info, pin->pin), |
421 | BIT(p), f << p); | |
422 | regmap_update_bits(info->map, REG(OCELOT_GPIO_ALT1, info, pin->pin), | |
423 | BIT(p), f << (p - 1)); | |
ce8dc094 AB |
424 | |
425 | return 0; | |
426 | } | |
427 | ||
428 | static int ocelot_gpio_set_direction(struct pinctrl_dev *pctldev, | |
429 | struct pinctrl_gpio_range *range, | |
430 | unsigned int pin, bool input) | |
431 | { | |
432 | struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | |
da801ab5 | 433 | unsigned int p = pin % 32; |
ce8dc094 | 434 | |
da801ab5 AB |
435 | regmap_update_bits(info->map, REG(OCELOT_GPIO_OE, info, p), BIT(p), |
436 | input ? 0 : BIT(p)); | |
ce8dc094 AB |
437 | |
438 | return 0; | |
439 | } | |
440 | ||
441 | static int ocelot_gpio_request_enable(struct pinctrl_dev *pctldev, | |
442 | struct pinctrl_gpio_range *range, | |
443 | unsigned int offset) | |
444 | { | |
445 | struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | |
da801ab5 | 446 | unsigned int p = offset % 32; |
ce8dc094 | 447 | |
da801ab5 AB |
448 | regmap_update_bits(info->map, REG(OCELOT_GPIO_ALT0, info, offset), |
449 | BIT(p), 0); | |
450 | regmap_update_bits(info->map, REG(OCELOT_GPIO_ALT1, info, offset), | |
451 | BIT(p), 0); | |
ce8dc094 AB |
452 | |
453 | return 0; | |
454 | } | |
455 | ||
456 | static const struct pinmux_ops ocelot_pmx_ops = { | |
457 | .get_functions_count = ocelot_get_functions_count, | |
458 | .get_function_name = ocelot_get_function_name, | |
459 | .get_function_groups = ocelot_get_function_groups, | |
460 | .set_mux = ocelot_pinmux_set_mux, | |
461 | .gpio_set_direction = ocelot_gpio_set_direction, | |
462 | .gpio_request_enable = ocelot_gpio_request_enable, | |
463 | }; | |
464 | ||
465 | static int ocelot_pctl_get_groups_count(struct pinctrl_dev *pctldev) | |
466 | { | |
da801ab5 AB |
467 | struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); |
468 | ||
469 | return info->desc->npins; | |
ce8dc094 AB |
470 | } |
471 | ||
472 | static const char *ocelot_pctl_get_group_name(struct pinctrl_dev *pctldev, | |
473 | unsigned int group) | |
474 | { | |
da801ab5 AB |
475 | struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); |
476 | ||
477 | return info->desc->pins[group].name; | |
ce8dc094 AB |
478 | } |
479 | ||
480 | static int ocelot_pctl_get_group_pins(struct pinctrl_dev *pctldev, | |
481 | unsigned int group, | |
482 | const unsigned int **pins, | |
483 | unsigned int *num_pins) | |
484 | { | |
da801ab5 AB |
485 | struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); |
486 | ||
487 | *pins = &info->desc->pins[group].number; | |
ce8dc094 AB |
488 | *num_pins = 1; |
489 | ||
490 | return 0; | |
491 | } | |
492 | ||
493 | static const struct pinctrl_ops ocelot_pctl_ops = { | |
494 | .get_groups_count = ocelot_pctl_get_groups_count, | |
495 | .get_group_name = ocelot_pctl_get_group_name, | |
496 | .get_group_pins = ocelot_pctl_get_group_pins, | |
497 | .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, | |
498 | .dt_free_map = pinconf_generic_dt_free_map, | |
499 | }; | |
500 | ||
501 | static struct pinctrl_desc ocelot_desc = { | |
502 | .name = "ocelot-pinctrl", | |
503 | .pins = ocelot_pins, | |
504 | .npins = ARRAY_SIZE(ocelot_pins), | |
505 | .pctlops = &ocelot_pctl_ops, | |
506 | .pmxops = &ocelot_pmx_ops, | |
507 | .owner = THIS_MODULE, | |
508 | }; | |
509 | ||
da801ab5 AB |
510 | static struct pinctrl_desc jaguar2_desc = { |
511 | .name = "jaguar2-pinctrl", | |
512 | .pins = jaguar2_pins, | |
513 | .npins = ARRAY_SIZE(jaguar2_pins), | |
514 | .pctlops = &ocelot_pctl_ops, | |
515 | .pmxops = &ocelot_pmx_ops, | |
516 | .owner = THIS_MODULE, | |
517 | }; | |
518 | ||
ce8dc094 AB |
519 | static int ocelot_create_group_func_map(struct device *dev, |
520 | struct ocelot_pinctrl *info) | |
521 | { | |
ce8dc094 | 522 | int f, npins, i; |
da801ab5 AB |
523 | u8 *pins = kcalloc(info->desc->npins, sizeof(u8), GFP_KERNEL); |
524 | ||
525 | if (!pins) | |
526 | return -ENOMEM; | |
ce8dc094 AB |
527 | |
528 | for (f = 0; f < FUNC_MAX; f++) { | |
da801ab5 AB |
529 | for (npins = 0, i = 0; i < info->desc->npins; i++) { |
530 | if (ocelot_pin_function_idx(info, i, f) >= 0) | |
ce8dc094 AB |
531 | pins[npins++] = i; |
532 | } | |
533 | ||
da801ab5 AB |
534 | if (!npins) |
535 | continue; | |
536 | ||
ce8dc094 | 537 | info->func[f].ngroups = npins; |
da801ab5 AB |
538 | info->func[f].groups = devm_kcalloc(dev, npins, sizeof(char *), |
539 | GFP_KERNEL); | |
540 | if (!info->func[f].groups) { | |
541 | kfree(pins); | |
ce8dc094 | 542 | return -ENOMEM; |
da801ab5 | 543 | } |
ce8dc094 AB |
544 | |
545 | for (i = 0; i < npins; i++) | |
da801ab5 | 546 | info->func[f].groups[i] = info->desc->pins[pins[i]].name; |
ce8dc094 AB |
547 | } |
548 | ||
da801ab5 AB |
549 | kfree(pins); |
550 | ||
ce8dc094 AB |
551 | return 0; |
552 | } | |
553 | ||
554 | static int ocelot_pinctrl_register(struct platform_device *pdev, | |
555 | struct ocelot_pinctrl *info) | |
556 | { | |
557 | int ret; | |
558 | ||
559 | ret = ocelot_create_group_func_map(&pdev->dev, info); | |
560 | if (ret) { | |
561 | dev_err(&pdev->dev, "Unable to create group func map.\n"); | |
562 | return ret; | |
563 | } | |
564 | ||
da801ab5 | 565 | info->pctl = devm_pinctrl_register(&pdev->dev, info->desc, info); |
ce8dc094 AB |
566 | if (IS_ERR(info->pctl)) { |
567 | dev_err(&pdev->dev, "Failed to register pinctrl\n"); | |
568 | return PTR_ERR(info->pctl); | |
569 | } | |
570 | ||
571 | return 0; | |
572 | } | |
573 | ||
574 | static int ocelot_gpio_get(struct gpio_chip *chip, unsigned int offset) | |
575 | { | |
576 | struct ocelot_pinctrl *info = gpiochip_get_data(chip); | |
577 | unsigned int val; | |
578 | ||
da801ab5 | 579 | regmap_read(info->map, REG(OCELOT_GPIO_IN, info, offset), &val); |
ce8dc094 | 580 | |
da801ab5 | 581 | return !!(val & BIT(offset % 32)); |
ce8dc094 AB |
582 | } |
583 | ||
584 | static void ocelot_gpio_set(struct gpio_chip *chip, unsigned int offset, | |
585 | int value) | |
586 | { | |
587 | struct ocelot_pinctrl *info = gpiochip_get_data(chip); | |
588 | ||
589 | if (value) | |
da801ab5 AB |
590 | regmap_write(info->map, REG(OCELOT_GPIO_OUT_SET, info, offset), |
591 | BIT(offset % 32)); | |
ce8dc094 | 592 | else |
da801ab5 AB |
593 | regmap_write(info->map, REG(OCELOT_GPIO_OUT_CLR, info, offset), |
594 | BIT(offset % 32)); | |
ce8dc094 AB |
595 | } |
596 | ||
597 | static int ocelot_gpio_get_direction(struct gpio_chip *chip, | |
598 | unsigned int offset) | |
599 | { | |
600 | struct ocelot_pinctrl *info = gpiochip_get_data(chip); | |
601 | unsigned int val; | |
602 | ||
da801ab5 | 603 | regmap_read(info->map, REG(OCELOT_GPIO_OE, info, offset), &val); |
ce8dc094 | 604 | |
da801ab5 | 605 | return !(val & BIT(offset % 32)); |
ce8dc094 AB |
606 | } |
607 | ||
608 | static int ocelot_gpio_direction_input(struct gpio_chip *chip, | |
609 | unsigned int offset) | |
610 | { | |
611 | return pinctrl_gpio_direction_input(chip->base + offset); | |
612 | } | |
613 | ||
614 | static int ocelot_gpio_direction_output(struct gpio_chip *chip, | |
615 | unsigned int offset, int value) | |
616 | { | |
617 | struct ocelot_pinctrl *info = gpiochip_get_data(chip); | |
da801ab5 | 618 | unsigned int pin = BIT(offset % 32); |
ce8dc094 AB |
619 | |
620 | if (value) | |
da801ab5 AB |
621 | regmap_write(info->map, REG(OCELOT_GPIO_OUT_SET, info, offset), |
622 | pin); | |
ce8dc094 | 623 | else |
da801ab5 AB |
624 | regmap_write(info->map, REG(OCELOT_GPIO_OUT_CLR, info, offset), |
625 | pin); | |
ce8dc094 AB |
626 | |
627 | return pinctrl_gpio_direction_output(chip->base + offset); | |
628 | } | |
629 | ||
630 | static const struct gpio_chip ocelot_gpiolib_chip = { | |
631 | .request = gpiochip_generic_request, | |
632 | .free = gpiochip_generic_free, | |
633 | .set = ocelot_gpio_set, | |
634 | .get = ocelot_gpio_get, | |
635 | .get_direction = ocelot_gpio_get_direction, | |
636 | .direction_input = ocelot_gpio_direction_input, | |
637 | .direction_output = ocelot_gpio_direction_output, | |
638 | .owner = THIS_MODULE, | |
639 | }; | |
640 | ||
be36abb7 QS |
641 | static void ocelot_irq_mask(struct irq_data *data) |
642 | { | |
643 | struct gpio_chip *chip = irq_data_get_irq_chip_data(data); | |
644 | struct ocelot_pinctrl *info = gpiochip_get_data(chip); | |
645 | unsigned int gpio = irqd_to_hwirq(data); | |
646 | ||
da801ab5 AB |
647 | regmap_update_bits(info->map, REG(OCELOT_GPIO_INTR_ENA, info, gpio), |
648 | BIT(gpio % 32), 0); | |
be36abb7 QS |
649 | } |
650 | ||
651 | static void ocelot_irq_unmask(struct irq_data *data) | |
652 | { | |
653 | struct gpio_chip *chip = irq_data_get_irq_chip_data(data); | |
654 | struct ocelot_pinctrl *info = gpiochip_get_data(chip); | |
655 | unsigned int gpio = irqd_to_hwirq(data); | |
656 | ||
da801ab5 AB |
657 | regmap_update_bits(info->map, REG(OCELOT_GPIO_INTR_ENA, info, gpio), |
658 | BIT(gpio % 32), BIT(gpio % 32)); | |
be36abb7 QS |
659 | } |
660 | ||
661 | static void ocelot_irq_ack(struct irq_data *data) | |
662 | { | |
663 | struct gpio_chip *chip = irq_data_get_irq_chip_data(data); | |
664 | struct ocelot_pinctrl *info = gpiochip_get_data(chip); | |
665 | unsigned int gpio = irqd_to_hwirq(data); | |
666 | ||
da801ab5 AB |
667 | regmap_write_bits(info->map, REG(OCELOT_GPIO_INTR, info, gpio), |
668 | BIT(gpio % 32), BIT(gpio % 32)); | |
be36abb7 QS |
669 | } |
670 | ||
671 | static int ocelot_irq_set_type(struct irq_data *data, unsigned int type); | |
672 | ||
673 | static struct irq_chip ocelot_eoi_irqchip = { | |
674 | .name = "gpio", | |
675 | .irq_mask = ocelot_irq_mask, | |
676 | .irq_eoi = ocelot_irq_ack, | |
677 | .irq_unmask = ocelot_irq_unmask, | |
678 | .flags = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED, | |
679 | .irq_set_type = ocelot_irq_set_type, | |
680 | }; | |
681 | ||
682 | static struct irq_chip ocelot_irqchip = { | |
683 | .name = "gpio", | |
684 | .irq_mask = ocelot_irq_mask, | |
685 | .irq_ack = ocelot_irq_ack, | |
686 | .irq_unmask = ocelot_irq_unmask, | |
687 | .irq_set_type = ocelot_irq_set_type, | |
688 | }; | |
689 | ||
690 | static int ocelot_irq_set_type(struct irq_data *data, unsigned int type) | |
691 | { | |
692 | type &= IRQ_TYPE_SENSE_MASK; | |
693 | ||
694 | if (!(type & (IRQ_TYPE_EDGE_BOTH | IRQ_TYPE_LEVEL_HIGH))) | |
695 | return -EINVAL; | |
696 | ||
697 | if (type & IRQ_TYPE_LEVEL_HIGH) | |
698 | irq_set_chip_handler_name_locked(data, &ocelot_eoi_irqchip, | |
699 | handle_fasteoi_irq, NULL); | |
700 | if (type & IRQ_TYPE_EDGE_BOTH) | |
701 | irq_set_chip_handler_name_locked(data, &ocelot_irqchip, | |
702 | handle_edge_irq, NULL); | |
703 | ||
704 | return 0; | |
705 | } | |
706 | ||
707 | static void ocelot_irq_handler(struct irq_desc *desc) | |
708 | { | |
709 | struct irq_chip *parent_chip = irq_desc_get_chip(desc); | |
710 | struct gpio_chip *chip = irq_desc_get_handler_data(desc); | |
711 | struct ocelot_pinctrl *info = gpiochip_get_data(chip); | |
da801ab5 | 712 | unsigned int reg = 0, irq, i; |
be36abb7 QS |
713 | unsigned long irqs; |
714 | ||
da801ab5 AB |
715 | for (i = 0; i < info->stride; i++) { |
716 | regmap_read(info->map, OCELOT_GPIO_INTR_IDENT + 4 * i, ®); | |
717 | if (!reg) | |
718 | continue; | |
be36abb7 | 719 | |
da801ab5 | 720 | chained_irq_enter(parent_chip, desc); |
be36abb7 | 721 | |
da801ab5 | 722 | irqs = reg; |
be36abb7 | 723 | |
da801ab5 AB |
724 | for_each_set_bit(irq, &irqs, |
725 | min(32U, info->desc->npins - 32 * i)) | |
726 | generic_handle_irq(irq_linear_revmap(chip->irq.domain, | |
727 | irq + 32 * i)); | |
be36abb7 | 728 | |
da801ab5 AB |
729 | chained_irq_exit(parent_chip, desc); |
730 | } | |
be36abb7 QS |
731 | } |
732 | ||
ce8dc094 AB |
733 | static int ocelot_gpiochip_register(struct platform_device *pdev, |
734 | struct ocelot_pinctrl *info) | |
735 | { | |
736 | struct gpio_chip *gc; | |
be36abb7 | 737 | int ret, irq; |
ce8dc094 AB |
738 | |
739 | info->gpio_chip = ocelot_gpiolib_chip; | |
740 | ||
741 | gc = &info->gpio_chip; | |
da801ab5 | 742 | gc->ngpio = info->desc->npins; |
ce8dc094 AB |
743 | gc->parent = &pdev->dev; |
744 | gc->base = 0; | |
745 | gc->of_node = info->dev->of_node; | |
746 | gc->label = "ocelot-gpio"; | |
747 | ||
748 | ret = devm_gpiochip_add_data(&pdev->dev, gc, info); | |
749 | if (ret) | |
750 | return ret; | |
751 | ||
be36abb7 QS |
752 | irq = irq_of_parse_and_map(pdev->dev.of_node, 0); |
753 | if (irq <= 0) | |
754 | return irq; | |
755 | ||
756 | ret = gpiochip_irqchip_add(gc, &ocelot_irqchip, 0, handle_edge_irq, | |
757 | IRQ_TYPE_NONE); | |
758 | if (ret) | |
759 | return ret; | |
760 | ||
761 | gpiochip_set_chained_irqchip(gc, &ocelot_irqchip, irq, | |
762 | ocelot_irq_handler); | |
ce8dc094 AB |
763 | |
764 | return 0; | |
765 | } | |
766 | ||
ce8dc094 | 767 | static const struct of_device_id ocelot_pinctrl_of_match[] = { |
da801ab5 AB |
768 | { .compatible = "mscc,ocelot-pinctrl", .data = &ocelot_desc }, |
769 | { .compatible = "mscc,jaguar2-pinctrl", .data = &jaguar2_desc }, | |
ce8dc094 AB |
770 | {}, |
771 | }; | |
772 | ||
ce3e7f0e | 773 | static int ocelot_pinctrl_probe(struct platform_device *pdev) |
ce8dc094 AB |
774 | { |
775 | struct device *dev = &pdev->dev; | |
776 | struct ocelot_pinctrl *info; | |
777 | void __iomem *base; | |
778 | int ret; | |
da801ab5 AB |
779 | struct regmap_config regmap_config = { |
780 | .reg_bits = 32, | |
781 | .val_bits = 32, | |
782 | .reg_stride = 4, | |
783 | }; | |
ce8dc094 AB |
784 | |
785 | info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); | |
786 | if (!info) | |
787 | return -ENOMEM; | |
788 | ||
da801ab5 AB |
789 | info->desc = (struct pinctrl_desc *)device_get_match_data(dev); |
790 | ||
ce8dc094 AB |
791 | base = devm_ioremap_resource(dev, |
792 | platform_get_resource(pdev, IORESOURCE_MEM, 0)); | |
793 | if (IS_ERR(base)) { | |
794 | dev_err(dev, "Failed to ioremap registers\n"); | |
795 | return PTR_ERR(base); | |
796 | } | |
797 | ||
da801ab5 AB |
798 | info->stride = 1 + (info->desc->npins - 1) / 32; |
799 | regmap_config.max_register = OCELOT_GPIO_SD_MAP * info->stride + 15 * 4; | |
800 | ||
801 | info->map = devm_regmap_init_mmio(dev, base, ®map_config); | |
ce8dc094 AB |
802 | if (IS_ERR(info->map)) { |
803 | dev_err(dev, "Failed to create regmap\n"); | |
804 | return PTR_ERR(info->map); | |
805 | } | |
806 | dev_set_drvdata(dev, info->map); | |
807 | info->dev = dev; | |
808 | ||
809 | ret = ocelot_pinctrl_register(pdev, info); | |
810 | if (ret) | |
811 | return ret; | |
812 | ||
813 | ret = ocelot_gpiochip_register(pdev, info); | |
814 | if (ret) | |
815 | return ret; | |
816 | ||
817 | return 0; | |
818 | } | |
819 | ||
820 | static struct platform_driver ocelot_pinctrl_driver = { | |
821 | .driver = { | |
822 | .name = "pinctrl-ocelot", | |
823 | .of_match_table = of_match_ptr(ocelot_pinctrl_of_match), | |
824 | .suppress_bind_attrs = true, | |
825 | }, | |
826 | .probe = ocelot_pinctrl_probe, | |
827 | }; | |
828 | builtin_platform_driver(ocelot_pinctrl_driver); |