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 | ||
4b36082e | 399 | #define REG_ALT(msb, info, p) (OCELOT_GPIO_ALT0 * (info)->stride + 4 * ((msb) + ((info)->stride * ((p) / 32)))) |
da801ab5 | 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. | |
4b36082e AB |
415 | * bit 0 of f goes in BIT(pin) of ALT[0], bit 1 of f goes in BIT(pin) of |
416 | * ALT[1] | |
ce8dc094 AB |
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 | */ | |
4b36082e | 420 | regmap_update_bits(info->map, REG_ALT(0, info, pin->pin), |
da801ab5 | 421 | BIT(p), f << p); |
4b36082e | 422 | regmap_update_bits(info->map, REG_ALT(1, info, pin->pin), |
da801ab5 | 423 | BIT(p), f << (p - 1)); |
ce8dc094 AB |
424 | |
425 | return 0; | |
426 | } | |
427 | ||
4b36082e AB |
428 | #define REG(r, info, p) ((r) * (info)->stride + (4 * ((p) / 32))) |
429 | ||
ce8dc094 AB |
430 | static int ocelot_gpio_set_direction(struct pinctrl_dev *pctldev, |
431 | struct pinctrl_gpio_range *range, | |
432 | unsigned int pin, bool input) | |
433 | { | |
434 | struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | |
da801ab5 | 435 | unsigned int p = pin % 32; |
ce8dc094 | 436 | |
f2818ba3 | 437 | regmap_update_bits(info->map, REG(OCELOT_GPIO_OE, info, pin), BIT(p), |
da801ab5 | 438 | input ? 0 : BIT(p)); |
ce8dc094 AB |
439 | |
440 | return 0; | |
441 | } | |
442 | ||
443 | static int ocelot_gpio_request_enable(struct pinctrl_dev *pctldev, | |
444 | struct pinctrl_gpio_range *range, | |
445 | unsigned int offset) | |
446 | { | |
447 | struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); | |
da801ab5 | 448 | unsigned int p = offset % 32; |
ce8dc094 | 449 | |
4b36082e | 450 | regmap_update_bits(info->map, REG_ALT(0, info, offset), |
da801ab5 | 451 | BIT(p), 0); |
4b36082e | 452 | regmap_update_bits(info->map, REG_ALT(1, info, offset), |
da801ab5 | 453 | BIT(p), 0); |
ce8dc094 AB |
454 | |
455 | return 0; | |
456 | } | |
457 | ||
458 | static const struct pinmux_ops ocelot_pmx_ops = { | |
459 | .get_functions_count = ocelot_get_functions_count, | |
460 | .get_function_name = ocelot_get_function_name, | |
461 | .get_function_groups = ocelot_get_function_groups, | |
462 | .set_mux = ocelot_pinmux_set_mux, | |
463 | .gpio_set_direction = ocelot_gpio_set_direction, | |
464 | .gpio_request_enable = ocelot_gpio_request_enable, | |
465 | }; | |
466 | ||
467 | static int ocelot_pctl_get_groups_count(struct pinctrl_dev *pctldev) | |
468 | { | |
da801ab5 AB |
469 | struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); |
470 | ||
471 | return info->desc->npins; | |
ce8dc094 AB |
472 | } |
473 | ||
474 | static const char *ocelot_pctl_get_group_name(struct pinctrl_dev *pctldev, | |
475 | unsigned int group) | |
476 | { | |
da801ab5 AB |
477 | struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); |
478 | ||
479 | return info->desc->pins[group].name; | |
ce8dc094 AB |
480 | } |
481 | ||
482 | static int ocelot_pctl_get_group_pins(struct pinctrl_dev *pctldev, | |
483 | unsigned int group, | |
484 | const unsigned int **pins, | |
485 | unsigned int *num_pins) | |
486 | { | |
da801ab5 AB |
487 | struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); |
488 | ||
489 | *pins = &info->desc->pins[group].number; | |
ce8dc094 AB |
490 | *num_pins = 1; |
491 | ||
492 | return 0; | |
493 | } | |
494 | ||
495 | static const struct pinctrl_ops ocelot_pctl_ops = { | |
496 | .get_groups_count = ocelot_pctl_get_groups_count, | |
497 | .get_group_name = ocelot_pctl_get_group_name, | |
498 | .get_group_pins = ocelot_pctl_get_group_pins, | |
499 | .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, | |
500 | .dt_free_map = pinconf_generic_dt_free_map, | |
501 | }; | |
502 | ||
503 | static struct pinctrl_desc ocelot_desc = { | |
504 | .name = "ocelot-pinctrl", | |
505 | .pins = ocelot_pins, | |
506 | .npins = ARRAY_SIZE(ocelot_pins), | |
507 | .pctlops = &ocelot_pctl_ops, | |
508 | .pmxops = &ocelot_pmx_ops, | |
509 | .owner = THIS_MODULE, | |
510 | }; | |
511 | ||
da801ab5 AB |
512 | static struct pinctrl_desc jaguar2_desc = { |
513 | .name = "jaguar2-pinctrl", | |
514 | .pins = jaguar2_pins, | |
515 | .npins = ARRAY_SIZE(jaguar2_pins), | |
516 | .pctlops = &ocelot_pctl_ops, | |
517 | .pmxops = &ocelot_pmx_ops, | |
518 | .owner = THIS_MODULE, | |
519 | }; | |
520 | ||
ce8dc094 AB |
521 | static int ocelot_create_group_func_map(struct device *dev, |
522 | struct ocelot_pinctrl *info) | |
523 | { | |
ce8dc094 | 524 | int f, npins, i; |
da801ab5 AB |
525 | u8 *pins = kcalloc(info->desc->npins, sizeof(u8), GFP_KERNEL); |
526 | ||
527 | if (!pins) | |
528 | return -ENOMEM; | |
ce8dc094 AB |
529 | |
530 | for (f = 0; f < FUNC_MAX; f++) { | |
da801ab5 AB |
531 | for (npins = 0, i = 0; i < info->desc->npins; i++) { |
532 | if (ocelot_pin_function_idx(info, i, f) >= 0) | |
ce8dc094 AB |
533 | pins[npins++] = i; |
534 | } | |
535 | ||
da801ab5 AB |
536 | if (!npins) |
537 | continue; | |
538 | ||
ce8dc094 | 539 | info->func[f].ngroups = npins; |
da801ab5 AB |
540 | info->func[f].groups = devm_kcalloc(dev, npins, sizeof(char *), |
541 | GFP_KERNEL); | |
542 | if (!info->func[f].groups) { | |
543 | kfree(pins); | |
ce8dc094 | 544 | return -ENOMEM; |
da801ab5 | 545 | } |
ce8dc094 AB |
546 | |
547 | for (i = 0; i < npins; i++) | |
da801ab5 | 548 | info->func[f].groups[i] = info->desc->pins[pins[i]].name; |
ce8dc094 AB |
549 | } |
550 | ||
da801ab5 AB |
551 | kfree(pins); |
552 | ||
ce8dc094 AB |
553 | return 0; |
554 | } | |
555 | ||
556 | static int ocelot_pinctrl_register(struct platform_device *pdev, | |
557 | struct ocelot_pinctrl *info) | |
558 | { | |
559 | int ret; | |
560 | ||
561 | ret = ocelot_create_group_func_map(&pdev->dev, info); | |
562 | if (ret) { | |
563 | dev_err(&pdev->dev, "Unable to create group func map.\n"); | |
564 | return ret; | |
565 | } | |
566 | ||
da801ab5 | 567 | info->pctl = devm_pinctrl_register(&pdev->dev, info->desc, info); |
ce8dc094 AB |
568 | if (IS_ERR(info->pctl)) { |
569 | dev_err(&pdev->dev, "Failed to register pinctrl\n"); | |
570 | return PTR_ERR(info->pctl); | |
571 | } | |
572 | ||
573 | return 0; | |
574 | } | |
575 | ||
576 | static int ocelot_gpio_get(struct gpio_chip *chip, unsigned int offset) | |
577 | { | |
578 | struct ocelot_pinctrl *info = gpiochip_get_data(chip); | |
579 | unsigned int val; | |
580 | ||
da801ab5 | 581 | regmap_read(info->map, REG(OCELOT_GPIO_IN, info, offset), &val); |
ce8dc094 | 582 | |
da801ab5 | 583 | return !!(val & BIT(offset % 32)); |
ce8dc094 AB |
584 | } |
585 | ||
586 | static void ocelot_gpio_set(struct gpio_chip *chip, unsigned int offset, | |
587 | int value) | |
588 | { | |
589 | struct ocelot_pinctrl *info = gpiochip_get_data(chip); | |
590 | ||
591 | if (value) | |
da801ab5 AB |
592 | regmap_write(info->map, REG(OCELOT_GPIO_OUT_SET, info, offset), |
593 | BIT(offset % 32)); | |
ce8dc094 | 594 | else |
da801ab5 AB |
595 | regmap_write(info->map, REG(OCELOT_GPIO_OUT_CLR, info, offset), |
596 | BIT(offset % 32)); | |
ce8dc094 AB |
597 | } |
598 | ||
599 | static int ocelot_gpio_get_direction(struct gpio_chip *chip, | |
600 | unsigned int offset) | |
601 | { | |
602 | struct ocelot_pinctrl *info = gpiochip_get_data(chip); | |
603 | unsigned int val; | |
604 | ||
da801ab5 | 605 | regmap_read(info->map, REG(OCELOT_GPIO_OE, info, offset), &val); |
ce8dc094 | 606 | |
da801ab5 | 607 | return !(val & BIT(offset % 32)); |
ce8dc094 AB |
608 | } |
609 | ||
610 | static int ocelot_gpio_direction_input(struct gpio_chip *chip, | |
611 | unsigned int offset) | |
612 | { | |
613 | return pinctrl_gpio_direction_input(chip->base + offset); | |
614 | } | |
615 | ||
616 | static int ocelot_gpio_direction_output(struct gpio_chip *chip, | |
617 | unsigned int offset, int value) | |
618 | { | |
619 | struct ocelot_pinctrl *info = gpiochip_get_data(chip); | |
da801ab5 | 620 | unsigned int pin = BIT(offset % 32); |
ce8dc094 AB |
621 | |
622 | if (value) | |
da801ab5 AB |
623 | regmap_write(info->map, REG(OCELOT_GPIO_OUT_SET, info, offset), |
624 | pin); | |
ce8dc094 | 625 | else |
da801ab5 AB |
626 | regmap_write(info->map, REG(OCELOT_GPIO_OUT_CLR, info, offset), |
627 | pin); | |
ce8dc094 AB |
628 | |
629 | return pinctrl_gpio_direction_output(chip->base + offset); | |
630 | } | |
631 | ||
632 | static const struct gpio_chip ocelot_gpiolib_chip = { | |
633 | .request = gpiochip_generic_request, | |
634 | .free = gpiochip_generic_free, | |
635 | .set = ocelot_gpio_set, | |
636 | .get = ocelot_gpio_get, | |
637 | .get_direction = ocelot_gpio_get_direction, | |
638 | .direction_input = ocelot_gpio_direction_input, | |
639 | .direction_output = ocelot_gpio_direction_output, | |
640 | .owner = THIS_MODULE, | |
641 | }; | |
642 | ||
be36abb7 QS |
643 | static void ocelot_irq_mask(struct irq_data *data) |
644 | { | |
645 | struct gpio_chip *chip = irq_data_get_irq_chip_data(data); | |
646 | struct ocelot_pinctrl *info = gpiochip_get_data(chip); | |
647 | unsigned int gpio = irqd_to_hwirq(data); | |
648 | ||
da801ab5 AB |
649 | regmap_update_bits(info->map, REG(OCELOT_GPIO_INTR_ENA, info, gpio), |
650 | BIT(gpio % 32), 0); | |
be36abb7 QS |
651 | } |
652 | ||
653 | static void ocelot_irq_unmask(struct irq_data *data) | |
654 | { | |
655 | struct gpio_chip *chip = irq_data_get_irq_chip_data(data); | |
656 | struct ocelot_pinctrl *info = gpiochip_get_data(chip); | |
657 | unsigned int gpio = irqd_to_hwirq(data); | |
658 | ||
da801ab5 AB |
659 | regmap_update_bits(info->map, REG(OCELOT_GPIO_INTR_ENA, info, gpio), |
660 | BIT(gpio % 32), BIT(gpio % 32)); | |
be36abb7 QS |
661 | } |
662 | ||
663 | static void ocelot_irq_ack(struct irq_data *data) | |
664 | { | |
665 | struct gpio_chip *chip = irq_data_get_irq_chip_data(data); | |
666 | struct ocelot_pinctrl *info = gpiochip_get_data(chip); | |
667 | unsigned int gpio = irqd_to_hwirq(data); | |
668 | ||
da801ab5 AB |
669 | regmap_write_bits(info->map, REG(OCELOT_GPIO_INTR, info, gpio), |
670 | BIT(gpio % 32), BIT(gpio % 32)); | |
be36abb7 QS |
671 | } |
672 | ||
673 | static int ocelot_irq_set_type(struct irq_data *data, unsigned int type); | |
674 | ||
675 | static struct irq_chip ocelot_eoi_irqchip = { | |
676 | .name = "gpio", | |
677 | .irq_mask = ocelot_irq_mask, | |
678 | .irq_eoi = ocelot_irq_ack, | |
679 | .irq_unmask = ocelot_irq_unmask, | |
680 | .flags = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED, | |
681 | .irq_set_type = ocelot_irq_set_type, | |
682 | }; | |
683 | ||
684 | static struct irq_chip ocelot_irqchip = { | |
685 | .name = "gpio", | |
686 | .irq_mask = ocelot_irq_mask, | |
687 | .irq_ack = ocelot_irq_ack, | |
688 | .irq_unmask = ocelot_irq_unmask, | |
689 | .irq_set_type = ocelot_irq_set_type, | |
690 | }; | |
691 | ||
692 | static int ocelot_irq_set_type(struct irq_data *data, unsigned int type) | |
693 | { | |
694 | type &= IRQ_TYPE_SENSE_MASK; | |
695 | ||
696 | if (!(type & (IRQ_TYPE_EDGE_BOTH | IRQ_TYPE_LEVEL_HIGH))) | |
697 | return -EINVAL; | |
698 | ||
699 | if (type & IRQ_TYPE_LEVEL_HIGH) | |
700 | irq_set_chip_handler_name_locked(data, &ocelot_eoi_irqchip, | |
701 | handle_fasteoi_irq, NULL); | |
702 | if (type & IRQ_TYPE_EDGE_BOTH) | |
703 | irq_set_chip_handler_name_locked(data, &ocelot_irqchip, | |
704 | handle_edge_irq, NULL); | |
705 | ||
706 | return 0; | |
707 | } | |
708 | ||
709 | static void ocelot_irq_handler(struct irq_desc *desc) | |
710 | { | |
711 | struct irq_chip *parent_chip = irq_desc_get_chip(desc); | |
712 | struct gpio_chip *chip = irq_desc_get_handler_data(desc); | |
713 | struct ocelot_pinctrl *info = gpiochip_get_data(chip); | |
da801ab5 | 714 | unsigned int reg = 0, irq, i; |
be36abb7 QS |
715 | unsigned long irqs; |
716 | ||
da801ab5 AB |
717 | for (i = 0; i < info->stride; i++) { |
718 | regmap_read(info->map, OCELOT_GPIO_INTR_IDENT + 4 * i, ®); | |
719 | if (!reg) | |
720 | continue; | |
be36abb7 | 721 | |
da801ab5 | 722 | chained_irq_enter(parent_chip, desc); |
be36abb7 | 723 | |
da801ab5 | 724 | irqs = reg; |
be36abb7 | 725 | |
da801ab5 AB |
726 | for_each_set_bit(irq, &irqs, |
727 | min(32U, info->desc->npins - 32 * i)) | |
728 | generic_handle_irq(irq_linear_revmap(chip->irq.domain, | |
729 | irq + 32 * i)); | |
be36abb7 | 730 | |
da801ab5 AB |
731 | chained_irq_exit(parent_chip, desc); |
732 | } | |
be36abb7 QS |
733 | } |
734 | ||
ce8dc094 AB |
735 | static int ocelot_gpiochip_register(struct platform_device *pdev, |
736 | struct ocelot_pinctrl *info) | |
737 | { | |
738 | struct gpio_chip *gc; | |
be36abb7 | 739 | int ret, irq; |
ce8dc094 AB |
740 | |
741 | info->gpio_chip = ocelot_gpiolib_chip; | |
742 | ||
743 | gc = &info->gpio_chip; | |
da801ab5 | 744 | gc->ngpio = info->desc->npins; |
ce8dc094 AB |
745 | gc->parent = &pdev->dev; |
746 | gc->base = 0; | |
747 | gc->of_node = info->dev->of_node; | |
748 | gc->label = "ocelot-gpio"; | |
749 | ||
750 | ret = devm_gpiochip_add_data(&pdev->dev, gc, info); | |
751 | if (ret) | |
752 | return ret; | |
753 | ||
be36abb7 QS |
754 | irq = irq_of_parse_and_map(pdev->dev.of_node, 0); |
755 | if (irq <= 0) | |
756 | return irq; | |
757 | ||
758 | ret = gpiochip_irqchip_add(gc, &ocelot_irqchip, 0, handle_edge_irq, | |
759 | IRQ_TYPE_NONE); | |
760 | if (ret) | |
761 | return ret; | |
762 | ||
763 | gpiochip_set_chained_irqchip(gc, &ocelot_irqchip, irq, | |
764 | ocelot_irq_handler); | |
ce8dc094 AB |
765 | |
766 | return 0; | |
767 | } | |
768 | ||
ce8dc094 | 769 | static const struct of_device_id ocelot_pinctrl_of_match[] = { |
da801ab5 AB |
770 | { .compatible = "mscc,ocelot-pinctrl", .data = &ocelot_desc }, |
771 | { .compatible = "mscc,jaguar2-pinctrl", .data = &jaguar2_desc }, | |
ce8dc094 AB |
772 | {}, |
773 | }; | |
774 | ||
ce3e7f0e | 775 | static int ocelot_pinctrl_probe(struct platform_device *pdev) |
ce8dc094 AB |
776 | { |
777 | struct device *dev = &pdev->dev; | |
778 | struct ocelot_pinctrl *info; | |
779 | void __iomem *base; | |
780 | int ret; | |
da801ab5 AB |
781 | struct regmap_config regmap_config = { |
782 | .reg_bits = 32, | |
783 | .val_bits = 32, | |
784 | .reg_stride = 4, | |
785 | }; | |
ce8dc094 AB |
786 | |
787 | info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); | |
788 | if (!info) | |
789 | return -ENOMEM; | |
790 | ||
da801ab5 AB |
791 | info->desc = (struct pinctrl_desc *)device_get_match_data(dev); |
792 | ||
ce8dc094 AB |
793 | base = devm_ioremap_resource(dev, |
794 | platform_get_resource(pdev, IORESOURCE_MEM, 0)); | |
795 | if (IS_ERR(base)) { | |
796 | dev_err(dev, "Failed to ioremap registers\n"); | |
797 | return PTR_ERR(base); | |
798 | } | |
799 | ||
da801ab5 AB |
800 | info->stride = 1 + (info->desc->npins - 1) / 32; |
801 | regmap_config.max_register = OCELOT_GPIO_SD_MAP * info->stride + 15 * 4; | |
802 | ||
803 | info->map = devm_regmap_init_mmio(dev, base, ®map_config); | |
ce8dc094 AB |
804 | if (IS_ERR(info->map)) { |
805 | dev_err(dev, "Failed to create regmap\n"); | |
806 | return PTR_ERR(info->map); | |
807 | } | |
808 | dev_set_drvdata(dev, info->map); | |
809 | info->dev = dev; | |
810 | ||
811 | ret = ocelot_pinctrl_register(pdev, info); | |
812 | if (ret) | |
813 | return ret; | |
814 | ||
815 | ret = ocelot_gpiochip_register(pdev, info); | |
816 | if (ret) | |
817 | return ret; | |
818 | ||
819 | return 0; | |
820 | } | |
821 | ||
822 | static struct platform_driver ocelot_pinctrl_driver = { | |
823 | .driver = { | |
824 | .name = "pinctrl-ocelot", | |
825 | .of_match_table = of_match_ptr(ocelot_pinctrl_of_match), | |
826 | .suppress_bind_attrs = true, | |
827 | }, | |
828 | .probe = ocelot_pinctrl_probe, | |
829 | }; | |
830 | builtin_platform_driver(ocelot_pinctrl_driver); |