1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Driver for the Atmel PIO4 controller |
4 | * |
5 | * Copyright (C) 2015 Atmel, |
6 | * 2015 Ludovic Desroches <ludovic.desroches@atmel.com> |
7 | */ |
8 | |
9 | #include <dt-bindings/pinctrl/at91.h> |
10 | |
11 | #include <linux/clk.h> |
12 | #include <linux/gpio/driver.h> |
13 | #include <linux/init.h> |
14 | #include <linux/interrupt.h> |
15 | #include <linux/io.h> |
16 | #include <linux/of.h> |
17 | #include <linux/platform_device.h> |
18 | #include <linux/seq_file.h> |
19 | #include <linux/slab.h> |
20 | |
21 | #include <linux/pinctrl/pinconf-generic.h> |
22 | #include <linux/pinctrl/pinconf.h> |
23 | #include <linux/pinctrl/pinctrl.h> |
24 | #include <linux/pinctrl/pinmux.h> |
25 | |
26 | #include "core.h" |
27 | #include "pinconf.h" |
28 | #include "pinctrl-utils.h" |
29 | |
30 | /* |
31 | * Warning: |
32 | * In order to not introduce confusion between Atmel PIO groups and pinctrl |
33 | * framework groups, Atmel PIO groups will be called banks, line is kept to |
34 | * designed the pin id into this bank. |
35 | */ |
36 | |
37 | #define ATMEL_PIO_MSKR 0x0000 |
38 | #define ATMEL_PIO_CFGR 0x0004 |
39 | #define ATMEL_PIO_CFGR_FUNC_MASK GENMASK(2, 0) |
40 | #define ATMEL_PIO_DIR_MASK BIT(8) |
41 | #define ATMEL_PIO_PUEN_MASK BIT(9) |
42 | #define ATMEL_PIO_PDEN_MASK BIT(10) |
43 | #define ATMEL_PIO_SR_MASK BIT(11) |
44 | #define ATMEL_PIO_IFEN_MASK BIT(12) |
45 | #define ATMEL_PIO_IFSCEN_MASK BIT(13) |
46 | #define ATMEL_PIO_OPD_MASK BIT(14) |
47 | #define ATMEL_PIO_SCHMITT_MASK BIT(15) |
48 | #define ATMEL_PIO_DRVSTR_MASK GENMASK(17, 16) |
49 | #define ATMEL_PIO_DRVSTR_OFFSET 16 |
50 | #define ATMEL_PIO_CFGR_EVTSEL_MASK GENMASK(26, 24) |
51 | #define ATMEL_PIO_CFGR_EVTSEL_FALLING (0 << 24) |
52 | #define ATMEL_PIO_CFGR_EVTSEL_RISING (1 << 24) |
53 | #define ATMEL_PIO_CFGR_EVTSEL_BOTH (2 << 24) |
54 | #define ATMEL_PIO_CFGR_EVTSEL_LOW (3 << 24) |
55 | #define ATMEL_PIO_CFGR_EVTSEL_HIGH (4 << 24) |
56 | #define ATMEL_PIO_PDSR 0x0008 |
57 | #define ATMEL_PIO_LOCKSR 0x000C |
58 | #define ATMEL_PIO_SODR 0x0010 |
59 | #define ATMEL_PIO_CODR 0x0014 |
60 | #define ATMEL_PIO_ODSR 0x0018 |
61 | #define ATMEL_PIO_IER 0x0020 |
62 | #define ATMEL_PIO_IDR 0x0024 |
63 | #define ATMEL_PIO_IMR 0x0028 |
64 | #define ATMEL_PIO_ISR 0x002C |
65 | #define ATMEL_PIO_IOFR 0x003C |
66 | |
67 | #define ATMEL_PIO_NPINS_PER_BANK 32 |
68 | #define ATMEL_PIO_BANK(pin_id) (pin_id / ATMEL_PIO_NPINS_PER_BANK) |
69 | #define ATMEL_PIO_LINE(pin_id) (pin_id % ATMEL_PIO_NPINS_PER_BANK) |
70 | #define ATMEL_PIO_BANK_OFFSET 0x40 |
71 | |
72 | #define ATMEL_GET_PIN_NO(pinfunc) ((pinfunc) & 0xff) |
73 | #define ATMEL_GET_PIN_FUNC(pinfunc) ((pinfunc >> 16) & 0xf) |
74 | #define ATMEL_GET_PIN_IOSET(pinfunc) ((pinfunc >> 20) & 0xf) |
75 | |
76 | /* Custom pinconf parameters */ |
77 | #define ATMEL_PIN_CONFIG_DRIVE_STRENGTH (PIN_CONFIG_END + 1) |
78 | |
79 | /** |
80 | * struct atmel_pioctrl_data - Atmel PIO controller (pinmux + gpio) data struct |
81 | * @nbanks: number of PIO banks |
82 | * @last_bank_count: number of lines in the last bank (can be less than |
83 | * the rest of the banks). |
84 | * @slew_rate_support: slew rate support |
85 | */ |
86 | struct atmel_pioctrl_data { |
87 | unsigned int nbanks; |
88 | unsigned int last_bank_count; |
89 | unsigned int slew_rate_support; |
90 | }; |
91 | |
92 | struct atmel_group { |
93 | const char *name; |
94 | u32 pin; |
95 | }; |
96 | |
97 | struct atmel_pin { |
98 | unsigned int pin_id; |
99 | unsigned int mux; |
100 | unsigned int ioset; |
101 | unsigned int bank; |
102 | unsigned int line; |
103 | const char *device; |
104 | }; |
105 | |
106 | /** |
107 | * struct atmel_pioctrl - Atmel PIO controller (pinmux + gpio) |
108 | * @reg_base: base address of the controller. |
109 | * @clk: clock of the controller. |
110 | * @nbanks: number of PIO groups, it can vary depending on the SoC. |
111 | * @pinctrl_dev: pinctrl device registered. |
112 | * @groups: groups table to provide group name and pin in the group to pinctrl. |
113 | * @group_names: group names table to provide all the group/pin names to |
114 | * pinctrl or gpio. |
115 | * @pins: pins table used for both pinctrl and gpio. pin_id, bank and line |
116 | * fields are set at probe time. Other ones are set when parsing dt |
117 | * pinctrl. |
118 | * @npins: number of pins. |
119 | * @gpio_chip: gpio chip registered. |
120 | * @irq_domain: irq domain for the gpio controller. |
121 | * @irqs: table containing the hw irq number of the bank. The index of the |
122 | * table is the bank id. |
123 | * @pm_wakeup_sources: bitmap of wakeup sources (lines) |
124 | * @pm_suspend_backup: backup/restore register values on suspend/resume |
125 | * @dev: device entry for the Atmel PIO controller. |
126 | * @node: node of the Atmel PIO controller. |
127 | * @slew_rate_support: slew rate support |
128 | */ |
129 | struct atmel_pioctrl { |
130 | void __iomem *reg_base; |
131 | struct clk *clk; |
132 | unsigned int nbanks; |
133 | struct pinctrl_dev *pinctrl_dev; |
134 | struct atmel_group *groups; |
135 | const char * const *group_names; |
136 | struct atmel_pin **pins; |
137 | unsigned int npins; |
138 | struct gpio_chip *gpio_chip; |
139 | struct irq_domain *irq_domain; |
140 | int *irqs; |
141 | unsigned int *pm_wakeup_sources; |
142 | struct { |
143 | u32 imr; |
144 | u32 odsr; |
145 | u32 cfgr[ATMEL_PIO_NPINS_PER_BANK]; |
146 | } *pm_suspend_backup; |
147 | struct device *dev; |
148 | struct device_node *node; |
149 | unsigned int slew_rate_support; |
150 | }; |
151 | |
152 | static const char * const atmel_functions[] = { |
153 | "GPIO" , "A" , "B" , "C" , "D" , "E" , "F" , "G" |
154 | }; |
155 | |
156 | static const struct pinconf_generic_params atmel_custom_bindings[] = { |
157 | {"atmel,drive-strength" , ATMEL_PIN_CONFIG_DRIVE_STRENGTH, 0}, |
158 | }; |
159 | |
160 | /* --- GPIO --- */ |
161 | static unsigned int atmel_gpio_read(struct atmel_pioctrl *atmel_pioctrl, |
162 | unsigned int bank, unsigned int reg) |
163 | { |
164 | return readl_relaxed(atmel_pioctrl->reg_base |
165 | + ATMEL_PIO_BANK_OFFSET * bank + reg); |
166 | } |
167 | |
168 | static void atmel_gpio_write(struct atmel_pioctrl *atmel_pioctrl, |
169 | unsigned int bank, unsigned int reg, |
170 | unsigned int val) |
171 | { |
172 | writel_relaxed(val, atmel_pioctrl->reg_base |
173 | + ATMEL_PIO_BANK_OFFSET * bank + reg); |
174 | } |
175 | |
176 | static void atmel_gpio_irq_ack(struct irq_data *d) |
177 | { |
178 | /* |
179 | * Nothing to do, interrupt is cleared when reading the status |
180 | * register. |
181 | */ |
182 | } |
183 | |
184 | static int atmel_gpio_irq_set_type(struct irq_data *d, unsigned int type) |
185 | { |
186 | struct atmel_pioctrl *atmel_pioctrl = irq_data_get_irq_chip_data(d); |
187 | struct atmel_pin *pin = atmel_pioctrl->pins[d->hwirq]; |
188 | unsigned int reg; |
189 | |
190 | atmel_gpio_write(atmel_pioctrl, bank: pin->bank, ATMEL_PIO_MSKR, |
191 | BIT(pin->line)); |
192 | reg = atmel_gpio_read(atmel_pioctrl, bank: pin->bank, ATMEL_PIO_CFGR); |
193 | reg &= (~ATMEL_PIO_CFGR_EVTSEL_MASK); |
194 | |
195 | switch (type) { |
196 | case IRQ_TYPE_EDGE_RISING: |
197 | irq_set_handler_locked(data: d, handler: handle_edge_irq); |
198 | reg |= ATMEL_PIO_CFGR_EVTSEL_RISING; |
199 | break; |
200 | case IRQ_TYPE_EDGE_FALLING: |
201 | irq_set_handler_locked(data: d, handler: handle_edge_irq); |
202 | reg |= ATMEL_PIO_CFGR_EVTSEL_FALLING; |
203 | break; |
204 | case IRQ_TYPE_EDGE_BOTH: |
205 | irq_set_handler_locked(data: d, handler: handle_edge_irq); |
206 | reg |= ATMEL_PIO_CFGR_EVTSEL_BOTH; |
207 | break; |
208 | case IRQ_TYPE_LEVEL_LOW: |
209 | irq_set_handler_locked(data: d, handler: handle_level_irq); |
210 | reg |= ATMEL_PIO_CFGR_EVTSEL_LOW; |
211 | break; |
212 | case IRQ_TYPE_LEVEL_HIGH: |
213 | irq_set_handler_locked(data: d, handler: handle_level_irq); |
214 | reg |= ATMEL_PIO_CFGR_EVTSEL_HIGH; |
215 | break; |
216 | case IRQ_TYPE_NONE: |
217 | default: |
218 | return -EINVAL; |
219 | } |
220 | |
221 | atmel_gpio_write(atmel_pioctrl, bank: pin->bank, ATMEL_PIO_CFGR, val: reg); |
222 | |
223 | return 0; |
224 | } |
225 | |
226 | static void atmel_gpio_irq_mask(struct irq_data *d) |
227 | { |
228 | struct atmel_pioctrl *atmel_pioctrl = irq_data_get_irq_chip_data(d); |
229 | struct atmel_pin *pin = atmel_pioctrl->pins[d->hwirq]; |
230 | |
231 | atmel_gpio_write(atmel_pioctrl, bank: pin->bank, ATMEL_PIO_IDR, |
232 | BIT(pin->line)); |
233 | } |
234 | |
235 | static void atmel_gpio_irq_unmask(struct irq_data *d) |
236 | { |
237 | struct atmel_pioctrl *atmel_pioctrl = irq_data_get_irq_chip_data(d); |
238 | struct atmel_pin *pin = atmel_pioctrl->pins[d->hwirq]; |
239 | |
240 | atmel_gpio_write(atmel_pioctrl, bank: pin->bank, ATMEL_PIO_IER, |
241 | BIT(pin->line)); |
242 | } |
243 | |
244 | static int atmel_gpio_irq_set_wake(struct irq_data *d, unsigned int on) |
245 | { |
246 | struct atmel_pioctrl *atmel_pioctrl = irq_data_get_irq_chip_data(d); |
247 | int bank = ATMEL_PIO_BANK(d->hwirq); |
248 | int line = ATMEL_PIO_LINE(d->hwirq); |
249 | |
250 | /* The gpio controller has one interrupt line per bank. */ |
251 | irq_set_irq_wake(irq: atmel_pioctrl->irqs[bank], on); |
252 | |
253 | if (on) |
254 | atmel_pioctrl->pm_wakeup_sources[bank] |= BIT(line); |
255 | else |
256 | atmel_pioctrl->pm_wakeup_sources[bank] &= ~(BIT(line)); |
257 | |
258 | return 0; |
259 | } |
260 | |
261 | static struct irq_chip atmel_gpio_irq_chip = { |
262 | .name = "GPIO" , |
263 | .irq_ack = atmel_gpio_irq_ack, |
264 | .irq_mask = atmel_gpio_irq_mask, |
265 | .irq_unmask = atmel_gpio_irq_unmask, |
266 | .irq_set_type = atmel_gpio_irq_set_type, |
267 | .irq_set_wake = pm_sleep_ptr(atmel_gpio_irq_set_wake), |
268 | }; |
269 | |
270 | static int atmel_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) |
271 | { |
272 | struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(gc: chip); |
273 | |
274 | return irq_find_mapping(domain: atmel_pioctrl->irq_domain, hwirq: offset); |
275 | } |
276 | |
277 | static void atmel_gpio_irq_handler(struct irq_desc *desc) |
278 | { |
279 | unsigned int irq = irq_desc_get_irq(desc); |
280 | struct atmel_pioctrl *atmel_pioctrl = irq_desc_get_handler_data(desc); |
281 | struct irq_chip *chip = irq_desc_get_chip(desc); |
282 | unsigned long isr; |
283 | int n, bank = -1; |
284 | |
285 | /* Find from which bank is the irq received. */ |
286 | for (n = 0; n < atmel_pioctrl->nbanks; n++) { |
287 | if (atmel_pioctrl->irqs[n] == irq) { |
288 | bank = n; |
289 | break; |
290 | } |
291 | } |
292 | |
293 | if (bank < 0) { |
294 | dev_err(atmel_pioctrl->dev, |
295 | "no bank associated to irq %u\n" , irq); |
296 | return; |
297 | } |
298 | |
299 | chained_irq_enter(chip, desc); |
300 | |
301 | for (;;) { |
302 | isr = (unsigned long)atmel_gpio_read(atmel_pioctrl, bank, |
303 | ATMEL_PIO_ISR); |
304 | isr &= (unsigned long)atmel_gpio_read(atmel_pioctrl, bank, |
305 | ATMEL_PIO_IMR); |
306 | if (!isr) |
307 | break; |
308 | |
309 | for_each_set_bit(n, &isr, BITS_PER_LONG) |
310 | generic_handle_irq(irq: atmel_gpio_to_irq( |
311 | chip: atmel_pioctrl->gpio_chip, |
312 | offset: bank * ATMEL_PIO_NPINS_PER_BANK + n)); |
313 | } |
314 | |
315 | chained_irq_exit(chip, desc); |
316 | } |
317 | |
318 | static int atmel_gpio_direction_input(struct gpio_chip *chip, |
319 | unsigned int offset) |
320 | { |
321 | struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(gc: chip); |
322 | struct atmel_pin *pin = atmel_pioctrl->pins[offset]; |
323 | unsigned int reg; |
324 | |
325 | atmel_gpio_write(atmel_pioctrl, bank: pin->bank, ATMEL_PIO_MSKR, |
326 | BIT(pin->line)); |
327 | reg = atmel_gpio_read(atmel_pioctrl, bank: pin->bank, ATMEL_PIO_CFGR); |
328 | reg &= ~ATMEL_PIO_DIR_MASK; |
329 | atmel_gpio_write(atmel_pioctrl, bank: pin->bank, ATMEL_PIO_CFGR, val: reg); |
330 | |
331 | return 0; |
332 | } |
333 | |
334 | static int atmel_gpio_get(struct gpio_chip *chip, unsigned int offset) |
335 | { |
336 | struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(gc: chip); |
337 | struct atmel_pin *pin = atmel_pioctrl->pins[offset]; |
338 | unsigned int reg; |
339 | |
340 | reg = atmel_gpio_read(atmel_pioctrl, bank: pin->bank, ATMEL_PIO_PDSR); |
341 | |
342 | return !!(reg & BIT(pin->line)); |
343 | } |
344 | |
345 | static int atmel_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask, |
346 | unsigned long *bits) |
347 | { |
348 | struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(gc: chip); |
349 | unsigned int bank; |
350 | |
351 | bitmap_zero(dst: bits, nbits: atmel_pioctrl->npins); |
352 | |
353 | for (bank = 0; bank < atmel_pioctrl->nbanks; bank++) { |
354 | unsigned int word = bank; |
355 | unsigned int offset = 0; |
356 | unsigned int reg; |
357 | |
358 | #if ATMEL_PIO_NPINS_PER_BANK != BITS_PER_LONG |
359 | word = BIT_WORD(bank * ATMEL_PIO_NPINS_PER_BANK); |
360 | offset = bank * ATMEL_PIO_NPINS_PER_BANK % BITS_PER_LONG; |
361 | #endif |
362 | if (!mask[word]) |
363 | continue; |
364 | |
365 | reg = atmel_gpio_read(atmel_pioctrl, bank, ATMEL_PIO_PDSR); |
366 | bits[word] |= mask[word] & (reg << offset); |
367 | } |
368 | |
369 | return 0; |
370 | } |
371 | |
372 | static int atmel_gpio_direction_output(struct gpio_chip *chip, |
373 | unsigned int offset, |
374 | int value) |
375 | { |
376 | struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(gc: chip); |
377 | struct atmel_pin *pin = atmel_pioctrl->pins[offset]; |
378 | unsigned int reg; |
379 | |
380 | atmel_gpio_write(atmel_pioctrl, bank: pin->bank, |
381 | reg: value ? ATMEL_PIO_SODR : ATMEL_PIO_CODR, |
382 | BIT(pin->line)); |
383 | |
384 | atmel_gpio_write(atmel_pioctrl, bank: pin->bank, ATMEL_PIO_MSKR, |
385 | BIT(pin->line)); |
386 | reg = atmel_gpio_read(atmel_pioctrl, bank: pin->bank, ATMEL_PIO_CFGR); |
387 | reg |= ATMEL_PIO_DIR_MASK; |
388 | atmel_gpio_write(atmel_pioctrl, bank: pin->bank, ATMEL_PIO_CFGR, val: reg); |
389 | |
390 | return 0; |
391 | } |
392 | |
393 | static void atmel_gpio_set(struct gpio_chip *chip, unsigned int offset, int val) |
394 | { |
395 | struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(gc: chip); |
396 | struct atmel_pin *pin = atmel_pioctrl->pins[offset]; |
397 | |
398 | atmel_gpio_write(atmel_pioctrl, bank: pin->bank, |
399 | reg: val ? ATMEL_PIO_SODR : ATMEL_PIO_CODR, |
400 | BIT(pin->line)); |
401 | } |
402 | |
403 | static void atmel_gpio_set_multiple(struct gpio_chip *chip, unsigned long *mask, |
404 | unsigned long *bits) |
405 | { |
406 | struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(gc: chip); |
407 | unsigned int bank; |
408 | |
409 | for (bank = 0; bank < atmel_pioctrl->nbanks; bank++) { |
410 | unsigned int bitmask; |
411 | unsigned int word = bank; |
412 | |
413 | /* |
414 | * On a 64-bit platform, BITS_PER_LONG is 64 so it is necessary to iterate over |
415 | * two 32bit words to handle the whole bitmask |
416 | */ |
417 | #if ATMEL_PIO_NPINS_PER_BANK != BITS_PER_LONG |
418 | word = BIT_WORD(bank * ATMEL_PIO_NPINS_PER_BANK); |
419 | #endif |
420 | if (!mask[word]) |
421 | continue; |
422 | |
423 | bitmask = mask[word] & bits[word]; |
424 | atmel_gpio_write(atmel_pioctrl, bank, ATMEL_PIO_SODR, val: bitmask); |
425 | |
426 | bitmask = mask[word] & ~bits[word]; |
427 | atmel_gpio_write(atmel_pioctrl, bank, ATMEL_PIO_CODR, val: bitmask); |
428 | |
429 | #if ATMEL_PIO_NPINS_PER_BANK != BITS_PER_LONG |
430 | mask[word] >>= ATMEL_PIO_NPINS_PER_BANK; |
431 | bits[word] >>= ATMEL_PIO_NPINS_PER_BANK; |
432 | #endif |
433 | } |
434 | } |
435 | |
436 | static struct gpio_chip atmel_gpio_chip = { |
437 | .direction_input = atmel_gpio_direction_input, |
438 | .get = atmel_gpio_get, |
439 | .get_multiple = atmel_gpio_get_multiple, |
440 | .direction_output = atmel_gpio_direction_output, |
441 | .set = atmel_gpio_set, |
442 | .set_multiple = atmel_gpio_set_multiple, |
443 | .to_irq = atmel_gpio_to_irq, |
444 | .base = 0, |
445 | }; |
446 | |
447 | /* --- PINCTRL --- */ |
448 | static unsigned int atmel_pin_config_read(struct pinctrl_dev *pctldev, |
449 | unsigned int pin_id) |
450 | { |
451 | struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); |
452 | unsigned int bank = atmel_pioctrl->pins[pin_id]->bank; |
453 | unsigned int line = atmel_pioctrl->pins[pin_id]->line; |
454 | void __iomem *addr = atmel_pioctrl->reg_base |
455 | + bank * ATMEL_PIO_BANK_OFFSET; |
456 | |
457 | writel_relaxed(BIT(line), addr + ATMEL_PIO_MSKR); |
458 | /* Have to set MSKR first, to access the right pin CFGR. */ |
459 | wmb(); |
460 | |
461 | return readl_relaxed(addr + ATMEL_PIO_CFGR); |
462 | } |
463 | |
464 | static void atmel_pin_config_write(struct pinctrl_dev *pctldev, |
465 | unsigned int pin_id, u32 conf) |
466 | { |
467 | struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); |
468 | unsigned int bank = atmel_pioctrl->pins[pin_id]->bank; |
469 | unsigned int line = atmel_pioctrl->pins[pin_id]->line; |
470 | void __iomem *addr = atmel_pioctrl->reg_base |
471 | + bank * ATMEL_PIO_BANK_OFFSET; |
472 | |
473 | writel_relaxed(BIT(line), addr + ATMEL_PIO_MSKR); |
474 | /* Have to set MSKR first, to access the right pin CFGR. */ |
475 | wmb(); |
476 | writel_relaxed(conf, addr + ATMEL_PIO_CFGR); |
477 | } |
478 | |
479 | static int atmel_pctl_get_groups_count(struct pinctrl_dev *pctldev) |
480 | { |
481 | struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); |
482 | |
483 | return atmel_pioctrl->npins; |
484 | } |
485 | |
486 | static const char *atmel_pctl_get_group_name(struct pinctrl_dev *pctldev, |
487 | unsigned int selector) |
488 | { |
489 | struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); |
490 | |
491 | return atmel_pioctrl->groups[selector].name; |
492 | } |
493 | |
494 | static int atmel_pctl_get_group_pins(struct pinctrl_dev *pctldev, |
495 | unsigned int selector, |
496 | const unsigned int **pins, |
497 | unsigned int *num_pins) |
498 | { |
499 | struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); |
500 | |
501 | *pins = (unsigned int *)&atmel_pioctrl->groups[selector].pin; |
502 | *num_pins = 1; |
503 | |
504 | return 0; |
505 | } |
506 | |
507 | static struct atmel_group * |
508 | atmel_pctl_find_group_by_pin(struct pinctrl_dev *pctldev, unsigned int pin) |
509 | { |
510 | struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); |
511 | int i; |
512 | |
513 | for (i = 0; i < atmel_pioctrl->npins; i++) { |
514 | struct atmel_group *grp = atmel_pioctrl->groups + i; |
515 | |
516 | if (grp->pin == pin) |
517 | return grp; |
518 | } |
519 | |
520 | return NULL; |
521 | } |
522 | |
523 | static int atmel_pctl_xlate_pinfunc(struct pinctrl_dev *pctldev, |
524 | struct device_node *np, |
525 | u32 pinfunc, const char **grp_name, |
526 | const char **func_name) |
527 | { |
528 | struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); |
529 | unsigned int pin_id, func_id; |
530 | struct atmel_group *grp; |
531 | |
532 | pin_id = ATMEL_GET_PIN_NO(pinfunc); |
533 | func_id = ATMEL_GET_PIN_FUNC(pinfunc); |
534 | |
535 | if (func_id >= ARRAY_SIZE(atmel_functions)) |
536 | return -EINVAL; |
537 | |
538 | *func_name = atmel_functions[func_id]; |
539 | |
540 | grp = atmel_pctl_find_group_by_pin(pctldev, pin: pin_id); |
541 | if (!grp) |
542 | return -EINVAL; |
543 | *grp_name = grp->name; |
544 | |
545 | atmel_pioctrl->pins[pin_id]->mux = func_id; |
546 | atmel_pioctrl->pins[pin_id]->ioset = ATMEL_GET_PIN_IOSET(pinfunc); |
547 | /* Want the device name not the group one. */ |
548 | if (np->parent == atmel_pioctrl->node) |
549 | atmel_pioctrl->pins[pin_id]->device = np->name; |
550 | else |
551 | atmel_pioctrl->pins[pin_id]->device = np->parent->name; |
552 | |
553 | return 0; |
554 | } |
555 | |
556 | static int atmel_pctl_dt_subnode_to_map(struct pinctrl_dev *pctldev, |
557 | struct device_node *np, |
558 | struct pinctrl_map **map, |
559 | unsigned int *reserved_maps, |
560 | unsigned int *num_maps) |
561 | { |
562 | unsigned int num_pins, num_configs, reserve; |
563 | unsigned long *configs; |
564 | struct property *pins; |
565 | u32 pinfunc; |
566 | int ret, i; |
567 | |
568 | pins = of_find_property(np, name: "pinmux" , NULL); |
569 | if (!pins) |
570 | return -EINVAL; |
571 | |
572 | ret = pinconf_generic_parse_dt_config(np, pctldev, configs: &configs, |
573 | nconfigs: &num_configs); |
574 | if (ret < 0) { |
575 | dev_err(pctldev->dev, "%pOF: could not parse node property\n" , |
576 | np); |
577 | return ret; |
578 | } |
579 | |
580 | num_pins = pins->length / sizeof(u32); |
581 | if (!num_pins) { |
582 | dev_err(pctldev->dev, "no pins found in node %pOF\n" , np); |
583 | ret = -EINVAL; |
584 | goto exit; |
585 | } |
586 | |
587 | /* |
588 | * Reserve maps, at least there is a mux map and an optional conf |
589 | * map for each pin. |
590 | */ |
591 | reserve = 1; |
592 | if (num_configs) |
593 | reserve++; |
594 | reserve *= num_pins; |
595 | ret = pinctrl_utils_reserve_map(pctldev, map, reserved_maps, num_maps, |
596 | reserve); |
597 | if (ret < 0) |
598 | goto exit; |
599 | |
600 | for (i = 0; i < num_pins; i++) { |
601 | const char *group, *func; |
602 | |
603 | ret = of_property_read_u32_index(np, propname: "pinmux" , index: i, out_value: &pinfunc); |
604 | if (ret) |
605 | goto exit; |
606 | |
607 | ret = atmel_pctl_xlate_pinfunc(pctldev, np, pinfunc, grp_name: &group, |
608 | func_name: &func); |
609 | if (ret) |
610 | goto exit; |
611 | |
612 | pinctrl_utils_add_map_mux(pctldev, map, reserved_maps, num_maps, |
613 | group, function: func); |
614 | |
615 | if (num_configs) { |
616 | ret = pinctrl_utils_add_map_configs(pctldev, map, |
617 | reserved_maps, num_maps, group, |
618 | configs, num_configs, |
619 | type: PIN_MAP_TYPE_CONFIGS_GROUP); |
620 | if (ret < 0) |
621 | goto exit; |
622 | } |
623 | } |
624 | |
625 | exit: |
626 | kfree(objp: configs); |
627 | return ret; |
628 | } |
629 | |
630 | static int atmel_pctl_dt_node_to_map(struct pinctrl_dev *pctldev, |
631 | struct device_node *np_config, |
632 | struct pinctrl_map **map, |
633 | unsigned int *num_maps) |
634 | { |
635 | struct device_node *np; |
636 | unsigned int reserved_maps; |
637 | int ret; |
638 | |
639 | *map = NULL; |
640 | *num_maps = 0; |
641 | reserved_maps = 0; |
642 | |
643 | /* |
644 | * If all the pins of a device have the same configuration (or no one), |
645 | * it is useless to add a subnode, so directly parse node referenced by |
646 | * phandle. |
647 | */ |
648 | ret = atmel_pctl_dt_subnode_to_map(pctldev, np: np_config, map, |
649 | reserved_maps: &reserved_maps, num_maps); |
650 | if (ret) { |
651 | for_each_child_of_node(np_config, np) { |
652 | ret = atmel_pctl_dt_subnode_to_map(pctldev, np, map, |
653 | reserved_maps: &reserved_maps, num_maps); |
654 | if (ret < 0) { |
655 | of_node_put(node: np); |
656 | break; |
657 | } |
658 | } |
659 | } |
660 | |
661 | if (ret < 0) { |
662 | pinctrl_utils_free_map(pctldev, map: *map, num_maps: *num_maps); |
663 | dev_err(pctldev->dev, "can't create maps for node %pOF\n" , |
664 | np_config); |
665 | } |
666 | |
667 | return ret; |
668 | } |
669 | |
670 | static const struct pinctrl_ops atmel_pctlops = { |
671 | .get_groups_count = atmel_pctl_get_groups_count, |
672 | .get_group_name = atmel_pctl_get_group_name, |
673 | .get_group_pins = atmel_pctl_get_group_pins, |
674 | .dt_node_to_map = atmel_pctl_dt_node_to_map, |
675 | .dt_free_map = pinctrl_utils_free_map, |
676 | }; |
677 | |
678 | static int atmel_pmx_get_functions_count(struct pinctrl_dev *pctldev) |
679 | { |
680 | return ARRAY_SIZE(atmel_functions); |
681 | } |
682 | |
683 | static const char *atmel_pmx_get_function_name(struct pinctrl_dev *pctldev, |
684 | unsigned int selector) |
685 | { |
686 | return atmel_functions[selector]; |
687 | } |
688 | |
689 | static int atmel_pmx_get_function_groups(struct pinctrl_dev *pctldev, |
690 | unsigned int selector, |
691 | const char * const **groups, |
692 | unsigned * const num_groups) |
693 | { |
694 | struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); |
695 | |
696 | *groups = atmel_pioctrl->group_names; |
697 | *num_groups = atmel_pioctrl->npins; |
698 | |
699 | return 0; |
700 | } |
701 | |
702 | static int atmel_pmx_set_mux(struct pinctrl_dev *pctldev, |
703 | unsigned int function, |
704 | unsigned int group) |
705 | { |
706 | struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); |
707 | unsigned int pin; |
708 | u32 conf; |
709 | |
710 | dev_dbg(pctldev->dev, "enable function %s group %s\n" , |
711 | atmel_functions[function], atmel_pioctrl->groups[group].name); |
712 | |
713 | pin = atmel_pioctrl->groups[group].pin; |
714 | conf = atmel_pin_config_read(pctldev, pin_id: pin); |
715 | conf &= (~ATMEL_PIO_CFGR_FUNC_MASK); |
716 | conf |= (function & ATMEL_PIO_CFGR_FUNC_MASK); |
717 | dev_dbg(pctldev->dev, "pin: %u, conf: 0x%08x\n" , pin, conf); |
718 | atmel_pin_config_write(pctldev, pin_id: pin, conf); |
719 | |
720 | return 0; |
721 | } |
722 | |
723 | static const struct pinmux_ops atmel_pmxops = { |
724 | .get_functions_count = atmel_pmx_get_functions_count, |
725 | .get_function_name = atmel_pmx_get_function_name, |
726 | .get_function_groups = atmel_pmx_get_function_groups, |
727 | .set_mux = atmel_pmx_set_mux, |
728 | }; |
729 | |
730 | static int atmel_conf_pin_config_group_get(struct pinctrl_dev *pctldev, |
731 | unsigned int group, |
732 | unsigned long *config) |
733 | { |
734 | struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); |
735 | unsigned int param = pinconf_to_config_param(config: *config), arg = 0; |
736 | struct atmel_group *grp = atmel_pioctrl->groups + group; |
737 | unsigned int pin_id = grp->pin; |
738 | u32 res; |
739 | |
740 | res = atmel_pin_config_read(pctldev, pin_id); |
741 | |
742 | switch (param) { |
743 | case PIN_CONFIG_BIAS_PULL_UP: |
744 | if (!(res & ATMEL_PIO_PUEN_MASK)) |
745 | return -EINVAL; |
746 | arg = 1; |
747 | break; |
748 | case PIN_CONFIG_BIAS_PULL_DOWN: |
749 | if ((res & ATMEL_PIO_PUEN_MASK) || |
750 | (!(res & ATMEL_PIO_PDEN_MASK))) |
751 | return -EINVAL; |
752 | arg = 1; |
753 | break; |
754 | case PIN_CONFIG_BIAS_DISABLE: |
755 | if ((res & ATMEL_PIO_PUEN_MASK) || |
756 | ((res & ATMEL_PIO_PDEN_MASK))) |
757 | return -EINVAL; |
758 | arg = 1; |
759 | break; |
760 | case PIN_CONFIG_DRIVE_OPEN_DRAIN: |
761 | if (!(res & ATMEL_PIO_OPD_MASK)) |
762 | return -EINVAL; |
763 | arg = 1; |
764 | break; |
765 | case PIN_CONFIG_DRIVE_PUSH_PULL: |
766 | if (res & ATMEL_PIO_OPD_MASK) |
767 | return -EINVAL; |
768 | arg = 1; |
769 | break; |
770 | case PIN_CONFIG_INPUT_SCHMITT_ENABLE: |
771 | if (!(res & ATMEL_PIO_SCHMITT_MASK)) |
772 | return -EINVAL; |
773 | arg = 1; |
774 | break; |
775 | case PIN_CONFIG_SLEW_RATE: |
776 | if (!atmel_pioctrl->slew_rate_support) |
777 | return -EOPNOTSUPP; |
778 | if (!(res & ATMEL_PIO_SR_MASK)) |
779 | return -EINVAL; |
780 | arg = 1; |
781 | break; |
782 | case ATMEL_PIN_CONFIG_DRIVE_STRENGTH: |
783 | if (!(res & ATMEL_PIO_DRVSTR_MASK)) |
784 | return -EINVAL; |
785 | arg = (res & ATMEL_PIO_DRVSTR_MASK) >> ATMEL_PIO_DRVSTR_OFFSET; |
786 | break; |
787 | case PIN_CONFIG_PERSIST_STATE: |
788 | return -ENOTSUPP; |
789 | default: |
790 | return -ENOTSUPP; |
791 | } |
792 | |
793 | *config = pinconf_to_config_packed(param, argument: arg); |
794 | return 0; |
795 | } |
796 | |
797 | static int atmel_conf_pin_config_group_set(struct pinctrl_dev *pctldev, |
798 | unsigned int group, |
799 | unsigned long *configs, |
800 | unsigned int num_configs) |
801 | { |
802 | struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); |
803 | struct atmel_group *grp = atmel_pioctrl->groups + group; |
804 | unsigned int bank, pin, pin_id = grp->pin; |
805 | u32 mask, conf = 0; |
806 | int i; |
807 | |
808 | conf = atmel_pin_config_read(pctldev, pin_id); |
809 | |
810 | /* Keep slew rate enabled by default. */ |
811 | if (atmel_pioctrl->slew_rate_support) |
812 | conf |= ATMEL_PIO_SR_MASK; |
813 | |
814 | for (i = 0; i < num_configs; i++) { |
815 | unsigned int param = pinconf_to_config_param(config: configs[i]); |
816 | unsigned int arg = pinconf_to_config_argument(config: configs[i]); |
817 | |
818 | dev_dbg(pctldev->dev, "%s: pin=%u, config=0x%lx\n" , |
819 | __func__, pin_id, configs[i]); |
820 | |
821 | switch (param) { |
822 | case PIN_CONFIG_BIAS_DISABLE: |
823 | conf &= (~ATMEL_PIO_PUEN_MASK); |
824 | conf &= (~ATMEL_PIO_PDEN_MASK); |
825 | break; |
826 | case PIN_CONFIG_BIAS_PULL_UP: |
827 | conf |= ATMEL_PIO_PUEN_MASK; |
828 | conf &= (~ATMEL_PIO_PDEN_MASK); |
829 | break; |
830 | case PIN_CONFIG_BIAS_PULL_DOWN: |
831 | conf |= ATMEL_PIO_PDEN_MASK; |
832 | conf &= (~ATMEL_PIO_PUEN_MASK); |
833 | break; |
834 | case PIN_CONFIG_DRIVE_OPEN_DRAIN: |
835 | conf |= ATMEL_PIO_OPD_MASK; |
836 | break; |
837 | case PIN_CONFIG_DRIVE_PUSH_PULL: |
838 | conf &= ~ATMEL_PIO_OPD_MASK; |
839 | break; |
840 | case PIN_CONFIG_INPUT_SCHMITT_ENABLE: |
841 | if (arg == 0) |
842 | conf |= ATMEL_PIO_SCHMITT_MASK; |
843 | else |
844 | conf &= (~ATMEL_PIO_SCHMITT_MASK); |
845 | break; |
846 | case PIN_CONFIG_INPUT_DEBOUNCE: |
847 | if (arg == 0) { |
848 | conf &= (~ATMEL_PIO_IFEN_MASK); |
849 | conf &= (~ATMEL_PIO_IFSCEN_MASK); |
850 | } else { |
851 | /* |
852 | * We don't care about the debounce value for several reasons: |
853 | * - can't have different debounce periods inside a same group, |
854 | * - the register to configure this period is a secure register. |
855 | * The debouncing filter can filter a pulse with a duration of less |
856 | * than 1/2 slow clock period. |
857 | */ |
858 | conf |= ATMEL_PIO_IFEN_MASK; |
859 | conf |= ATMEL_PIO_IFSCEN_MASK; |
860 | } |
861 | break; |
862 | case PIN_CONFIG_OUTPUT: |
863 | conf |= ATMEL_PIO_DIR_MASK; |
864 | bank = ATMEL_PIO_BANK(pin_id); |
865 | pin = ATMEL_PIO_LINE(pin_id); |
866 | mask = 1 << pin; |
867 | |
868 | if (arg == 0) { |
869 | writel_relaxed(mask, atmel_pioctrl->reg_base + |
870 | bank * ATMEL_PIO_BANK_OFFSET + |
871 | ATMEL_PIO_CODR); |
872 | } else { |
873 | writel_relaxed(mask, atmel_pioctrl->reg_base + |
874 | bank * ATMEL_PIO_BANK_OFFSET + |
875 | ATMEL_PIO_SODR); |
876 | } |
877 | break; |
878 | case PIN_CONFIG_SLEW_RATE: |
879 | if (!atmel_pioctrl->slew_rate_support) |
880 | break; |
881 | /* And remove it if explicitly requested. */ |
882 | if (arg == 0) |
883 | conf &= ~ATMEL_PIO_SR_MASK; |
884 | break; |
885 | case ATMEL_PIN_CONFIG_DRIVE_STRENGTH: |
886 | switch (arg) { |
887 | case ATMEL_PIO_DRVSTR_LO: |
888 | case ATMEL_PIO_DRVSTR_ME: |
889 | case ATMEL_PIO_DRVSTR_HI: |
890 | conf &= (~ATMEL_PIO_DRVSTR_MASK); |
891 | conf |= arg << ATMEL_PIO_DRVSTR_OFFSET; |
892 | break; |
893 | default: |
894 | dev_warn(pctldev->dev, "drive strength not updated (incorrect value)\n" ); |
895 | } |
896 | break; |
897 | case PIN_CONFIG_PERSIST_STATE: |
898 | return -ENOTSUPP; |
899 | default: |
900 | dev_warn(pctldev->dev, |
901 | "unsupported configuration parameter: %u\n" , |
902 | param); |
903 | continue; |
904 | } |
905 | } |
906 | |
907 | dev_dbg(pctldev->dev, "%s: reg=0x%08x\n" , __func__, conf); |
908 | atmel_pin_config_write(pctldev, pin_id, conf); |
909 | |
910 | return 0; |
911 | } |
912 | |
913 | static int atmel_conf_pin_config_set(struct pinctrl_dev *pctldev, |
914 | unsigned pin, |
915 | unsigned long *configs, |
916 | unsigned num_configs) |
917 | { |
918 | struct atmel_group *grp = atmel_pctl_find_group_by_pin(pctldev, pin); |
919 | |
920 | return atmel_conf_pin_config_group_set(pctldev, group: grp->pin, configs, num_configs); |
921 | } |
922 | |
923 | static int atmel_conf_pin_config_get(struct pinctrl_dev *pctldev, |
924 | unsigned pin, |
925 | unsigned long *configs) |
926 | { |
927 | struct atmel_group *grp = atmel_pctl_find_group_by_pin(pctldev, pin); |
928 | |
929 | return atmel_conf_pin_config_group_get(pctldev, group: grp->pin, config: configs); |
930 | } |
931 | |
932 | static void atmel_conf_pin_config_dbg_show(struct pinctrl_dev *pctldev, |
933 | struct seq_file *s, |
934 | unsigned int pin_id) |
935 | { |
936 | struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); |
937 | u32 conf; |
938 | |
939 | if (!atmel_pioctrl->pins[pin_id]->device) |
940 | return; |
941 | |
942 | seq_printf(m: s, fmt: " (%s, ioset %u) " , |
943 | atmel_pioctrl->pins[pin_id]->device, |
944 | atmel_pioctrl->pins[pin_id]->ioset); |
945 | |
946 | conf = atmel_pin_config_read(pctldev, pin_id); |
947 | if (conf & ATMEL_PIO_PUEN_MASK) |
948 | seq_printf(m: s, fmt: "%s " , "pull-up" ); |
949 | if (conf & ATMEL_PIO_PDEN_MASK) |
950 | seq_printf(m: s, fmt: "%s " , "pull-down" ); |
951 | if (conf & ATMEL_PIO_IFEN_MASK) |
952 | seq_printf(m: s, fmt: "%s " , "debounce" ); |
953 | if (conf & ATMEL_PIO_OPD_MASK) |
954 | seq_printf(m: s, fmt: "%s " , "open-drain" ); |
955 | else |
956 | seq_printf(m: s, fmt: "%s " , "push-pull" ); |
957 | if (conf & ATMEL_PIO_SCHMITT_MASK) |
958 | seq_printf(m: s, fmt: "%s " , "schmitt" ); |
959 | if (atmel_pioctrl->slew_rate_support && (conf & ATMEL_PIO_SR_MASK)) |
960 | seq_printf(m: s, fmt: "%s " , "slew-rate" ); |
961 | if (conf & ATMEL_PIO_DRVSTR_MASK) { |
962 | switch ((conf & ATMEL_PIO_DRVSTR_MASK) >> ATMEL_PIO_DRVSTR_OFFSET) { |
963 | case ATMEL_PIO_DRVSTR_ME: |
964 | seq_printf(m: s, fmt: "%s " , "medium-drive" ); |
965 | break; |
966 | case ATMEL_PIO_DRVSTR_HI: |
967 | seq_printf(m: s, fmt: "%s " , "high-drive" ); |
968 | break; |
969 | /* ATMEL_PIO_DRVSTR_LO and 0 which is the default value at reset */ |
970 | default: |
971 | seq_printf(m: s, fmt: "%s " , "low-drive" ); |
972 | } |
973 | } |
974 | } |
975 | |
976 | static const struct pinconf_ops atmel_confops = { |
977 | .pin_config_group_get = atmel_conf_pin_config_group_get, |
978 | .pin_config_group_set = atmel_conf_pin_config_group_set, |
979 | .pin_config_dbg_show = atmel_conf_pin_config_dbg_show, |
980 | .pin_config_set = atmel_conf_pin_config_set, |
981 | .pin_config_get = atmel_conf_pin_config_get, |
982 | }; |
983 | |
984 | static struct pinctrl_desc atmel_pinctrl_desc = { |
985 | .name = "atmel_pinctrl" , |
986 | .confops = &atmel_confops, |
987 | .pctlops = &atmel_pctlops, |
988 | .pmxops = &atmel_pmxops, |
989 | }; |
990 | |
991 | static int __maybe_unused atmel_pctrl_suspend(struct device *dev) |
992 | { |
993 | struct atmel_pioctrl *atmel_pioctrl = dev_get_drvdata(dev); |
994 | int i, j; |
995 | |
996 | /* |
997 | * For each bank, save IMR to restore it later and disable all GPIO |
998 | * interrupts excepting the ones marked as wakeup sources. |
999 | */ |
1000 | for (i = 0; i < atmel_pioctrl->nbanks; i++) { |
1001 | atmel_pioctrl->pm_suspend_backup[i].imr = |
1002 | atmel_gpio_read(atmel_pioctrl, bank: i, ATMEL_PIO_IMR); |
1003 | atmel_gpio_write(atmel_pioctrl, bank: i, ATMEL_PIO_IDR, |
1004 | val: ~atmel_pioctrl->pm_wakeup_sources[i]); |
1005 | atmel_pioctrl->pm_suspend_backup[i].odsr = |
1006 | atmel_gpio_read(atmel_pioctrl, bank: i, ATMEL_PIO_ODSR); |
1007 | for (j = 0; j < ATMEL_PIO_NPINS_PER_BANK; j++) { |
1008 | atmel_gpio_write(atmel_pioctrl, bank: i, |
1009 | ATMEL_PIO_MSKR, BIT(j)); |
1010 | atmel_pioctrl->pm_suspend_backup[i].cfgr[j] = |
1011 | atmel_gpio_read(atmel_pioctrl, bank: i, |
1012 | ATMEL_PIO_CFGR); |
1013 | } |
1014 | } |
1015 | |
1016 | return 0; |
1017 | } |
1018 | |
1019 | static int __maybe_unused atmel_pctrl_resume(struct device *dev) |
1020 | { |
1021 | struct atmel_pioctrl *atmel_pioctrl = dev_get_drvdata(dev); |
1022 | int i, j; |
1023 | |
1024 | for (i = 0; i < atmel_pioctrl->nbanks; i++) { |
1025 | atmel_gpio_write(atmel_pioctrl, bank: i, ATMEL_PIO_IER, |
1026 | val: atmel_pioctrl->pm_suspend_backup[i].imr); |
1027 | atmel_gpio_write(atmel_pioctrl, bank: i, ATMEL_PIO_SODR, |
1028 | val: atmel_pioctrl->pm_suspend_backup[i].odsr); |
1029 | for (j = 0; j < ATMEL_PIO_NPINS_PER_BANK; j++) { |
1030 | atmel_gpio_write(atmel_pioctrl, bank: i, |
1031 | ATMEL_PIO_MSKR, BIT(j)); |
1032 | atmel_gpio_write(atmel_pioctrl, bank: i, ATMEL_PIO_CFGR, |
1033 | val: atmel_pioctrl->pm_suspend_backup[i].cfgr[j]); |
1034 | } |
1035 | } |
1036 | |
1037 | return 0; |
1038 | } |
1039 | |
1040 | static const struct dev_pm_ops atmel_pctrl_pm_ops = { |
1041 | SET_SYSTEM_SLEEP_PM_OPS(atmel_pctrl_suspend, atmel_pctrl_resume) |
1042 | }; |
1043 | |
1044 | /* |
1045 | * The number of banks can be different from a SoC to another one. |
1046 | * We can have up to 16 banks. |
1047 | */ |
1048 | static const struct atmel_pioctrl_data atmel_sama5d2_pioctrl_data = { |
1049 | .nbanks = 4, |
1050 | .last_bank_count = ATMEL_PIO_NPINS_PER_BANK, |
1051 | }; |
1052 | |
1053 | static const struct atmel_pioctrl_data microchip_sama7g5_pioctrl_data = { |
1054 | .nbanks = 5, |
1055 | .last_bank_count = 8, /* sama7g5 has only PE0 to PE7 */ |
1056 | .slew_rate_support = 1, |
1057 | }; |
1058 | |
1059 | static const struct of_device_id atmel_pctrl_of_match[] = { |
1060 | { |
1061 | .compatible = "atmel,sama5d2-pinctrl" , |
1062 | .data = &atmel_sama5d2_pioctrl_data, |
1063 | }, { |
1064 | .compatible = "microchip,sama7g5-pinctrl" , |
1065 | .data = µchip_sama7g5_pioctrl_data, |
1066 | }, { |
1067 | /* sentinel */ |
1068 | } |
1069 | }; |
1070 | |
1071 | static int atmel_pinctrl_probe(struct platform_device *pdev) |
1072 | { |
1073 | struct device *dev = &pdev->dev; |
1074 | struct pinctrl_pin_desc *pin_desc; |
1075 | const char **group_names; |
1076 | int i, ret; |
1077 | struct atmel_pioctrl *atmel_pioctrl; |
1078 | const struct atmel_pioctrl_data *atmel_pioctrl_data; |
1079 | |
1080 | atmel_pioctrl = devm_kzalloc(dev, size: sizeof(*atmel_pioctrl), GFP_KERNEL); |
1081 | if (!atmel_pioctrl) |
1082 | return -ENOMEM; |
1083 | atmel_pioctrl->dev = dev; |
1084 | atmel_pioctrl->node = dev->of_node; |
1085 | platform_set_drvdata(pdev, data: atmel_pioctrl); |
1086 | |
1087 | atmel_pioctrl_data = device_get_match_data(dev); |
1088 | if (!atmel_pioctrl_data) |
1089 | return dev_err_probe(dev, err: -ENODEV, fmt: "Invalid device data\n" ); |
1090 | |
1091 | atmel_pioctrl->nbanks = atmel_pioctrl_data->nbanks; |
1092 | atmel_pioctrl->npins = atmel_pioctrl->nbanks * ATMEL_PIO_NPINS_PER_BANK; |
1093 | /* if last bank has limited number of pins, adjust accordingly */ |
1094 | if (atmel_pioctrl_data->last_bank_count != ATMEL_PIO_NPINS_PER_BANK) { |
1095 | atmel_pioctrl->npins -= ATMEL_PIO_NPINS_PER_BANK; |
1096 | atmel_pioctrl->npins += atmel_pioctrl_data->last_bank_count; |
1097 | } |
1098 | atmel_pioctrl->slew_rate_support = atmel_pioctrl_data->slew_rate_support; |
1099 | |
1100 | atmel_pioctrl->reg_base = devm_platform_ioremap_resource(pdev, index: 0); |
1101 | if (IS_ERR(ptr: atmel_pioctrl->reg_base)) |
1102 | return PTR_ERR(ptr: atmel_pioctrl->reg_base); |
1103 | |
1104 | atmel_pioctrl->clk = devm_clk_get_enabled(dev, NULL); |
1105 | if (IS_ERR(ptr: atmel_pioctrl->clk)) |
1106 | return dev_err_probe(dev, err: PTR_ERR(ptr: atmel_pioctrl->clk), fmt: "failed to get clock\n" ); |
1107 | |
1108 | atmel_pioctrl->pins = devm_kcalloc(dev, |
1109 | n: atmel_pioctrl->npins, |
1110 | size: sizeof(*atmel_pioctrl->pins), |
1111 | GFP_KERNEL); |
1112 | if (!atmel_pioctrl->pins) |
1113 | return -ENOMEM; |
1114 | |
1115 | pin_desc = devm_kcalloc(dev, n: atmel_pioctrl->npins, size: sizeof(*pin_desc), |
1116 | GFP_KERNEL); |
1117 | if (!pin_desc) |
1118 | return -ENOMEM; |
1119 | atmel_pinctrl_desc.pins = pin_desc; |
1120 | atmel_pinctrl_desc.npins = atmel_pioctrl->npins; |
1121 | atmel_pinctrl_desc.num_custom_params = ARRAY_SIZE(atmel_custom_bindings); |
1122 | atmel_pinctrl_desc.custom_params = atmel_custom_bindings; |
1123 | |
1124 | /* One pin is one group since a pin can achieve all functions. */ |
1125 | group_names = devm_kcalloc(dev, |
1126 | n: atmel_pioctrl->npins, size: sizeof(*group_names), |
1127 | GFP_KERNEL); |
1128 | if (!group_names) |
1129 | return -ENOMEM; |
1130 | atmel_pioctrl->group_names = group_names; |
1131 | |
1132 | atmel_pioctrl->groups = devm_kcalloc(dev: &pdev->dev, |
1133 | n: atmel_pioctrl->npins, size: sizeof(*atmel_pioctrl->groups), |
1134 | GFP_KERNEL); |
1135 | if (!atmel_pioctrl->groups) |
1136 | return -ENOMEM; |
1137 | for (i = 0 ; i < atmel_pioctrl->npins; i++) { |
1138 | struct atmel_group *group = atmel_pioctrl->groups + i; |
1139 | unsigned int bank = ATMEL_PIO_BANK(i); |
1140 | unsigned int line = ATMEL_PIO_LINE(i); |
1141 | |
1142 | atmel_pioctrl->pins[i] = devm_kzalloc(dev, |
1143 | size: sizeof(**atmel_pioctrl->pins), GFP_KERNEL); |
1144 | if (!atmel_pioctrl->pins[i]) |
1145 | return -ENOMEM; |
1146 | |
1147 | atmel_pioctrl->pins[i]->pin_id = i; |
1148 | atmel_pioctrl->pins[i]->bank = bank; |
1149 | atmel_pioctrl->pins[i]->line = line; |
1150 | |
1151 | pin_desc[i].number = i; |
1152 | /* Pin naming convention: P(bank_name)(bank_pin_number). */ |
1153 | pin_desc[i].name = devm_kasprintf(dev: &pdev->dev, GFP_KERNEL, fmt: "P%c%u" , |
1154 | bank + 'A', line); |
1155 | if (!pin_desc[i].name) |
1156 | return -ENOMEM; |
1157 | |
1158 | group->name = group_names[i] = pin_desc[i].name; |
1159 | group->pin = pin_desc[i].number; |
1160 | |
1161 | dev_dbg(dev, "pin_id=%u, bank=%u, line=%u" , i, bank, line); |
1162 | } |
1163 | |
1164 | atmel_pioctrl->gpio_chip = &atmel_gpio_chip; |
1165 | atmel_pioctrl->gpio_chip->ngpio = atmel_pioctrl->npins; |
1166 | atmel_pioctrl->gpio_chip->label = dev_name(dev); |
1167 | atmel_pioctrl->gpio_chip->parent = dev; |
1168 | atmel_pioctrl->gpio_chip->names = atmel_pioctrl->group_names; |
1169 | atmel_pioctrl->gpio_chip->set_config = gpiochip_generic_config; |
1170 | |
1171 | atmel_pioctrl->pm_wakeup_sources = devm_kcalloc(dev, |
1172 | n: atmel_pioctrl->nbanks, |
1173 | size: sizeof(*atmel_pioctrl->pm_wakeup_sources), |
1174 | GFP_KERNEL); |
1175 | if (!atmel_pioctrl->pm_wakeup_sources) |
1176 | return -ENOMEM; |
1177 | |
1178 | atmel_pioctrl->pm_suspend_backup = devm_kcalloc(dev, |
1179 | n: atmel_pioctrl->nbanks, |
1180 | size: sizeof(*atmel_pioctrl->pm_suspend_backup), |
1181 | GFP_KERNEL); |
1182 | if (!atmel_pioctrl->pm_suspend_backup) |
1183 | return -ENOMEM; |
1184 | |
1185 | atmel_pioctrl->irqs = devm_kcalloc(dev, |
1186 | n: atmel_pioctrl->nbanks, |
1187 | size: sizeof(*atmel_pioctrl->irqs), |
1188 | GFP_KERNEL); |
1189 | if (!atmel_pioctrl->irqs) |
1190 | return -ENOMEM; |
1191 | |
1192 | /* There is one controller but each bank has its own irq line. */ |
1193 | for (i = 0; i < atmel_pioctrl->nbanks; i++) { |
1194 | ret = platform_get_irq(pdev, i); |
1195 | if (ret < 0) { |
1196 | dev_dbg(dev, "missing irq resource for group %c\n" , |
1197 | 'A' + i); |
1198 | return ret; |
1199 | } |
1200 | atmel_pioctrl->irqs[i] = ret; |
1201 | irq_set_chained_handler_and_data(irq: ret, handle: atmel_gpio_irq_handler, data: atmel_pioctrl); |
1202 | dev_dbg(dev, "bank %i: irq=%d\n" , i, ret); |
1203 | } |
1204 | |
1205 | atmel_pioctrl->irq_domain = irq_domain_add_linear(of_node: dev->of_node, |
1206 | size: atmel_pioctrl->gpio_chip->ngpio, |
1207 | ops: &irq_domain_simple_ops, NULL); |
1208 | if (!atmel_pioctrl->irq_domain) |
1209 | return dev_err_probe(dev, err: -ENODEV, fmt: "can't add the irq domain\n" ); |
1210 | |
1211 | for (i = 0; i < atmel_pioctrl->npins; i++) { |
1212 | int irq = irq_create_mapping(host: atmel_pioctrl->irq_domain, hwirq: i); |
1213 | |
1214 | irq_set_chip_and_handler(irq, chip: &atmel_gpio_irq_chip, |
1215 | handle: handle_simple_irq); |
1216 | irq_set_chip_data(irq, data: atmel_pioctrl); |
1217 | dev_dbg(dev, |
1218 | "atmel gpio irq domain: hwirq: %d, linux irq: %d\n" , |
1219 | i, irq); |
1220 | } |
1221 | |
1222 | atmel_pioctrl->pinctrl_dev = devm_pinctrl_register(dev: &pdev->dev, |
1223 | pctldesc: &atmel_pinctrl_desc, |
1224 | driver_data: atmel_pioctrl); |
1225 | if (IS_ERR(ptr: atmel_pioctrl->pinctrl_dev)) { |
1226 | ret = PTR_ERR(ptr: atmel_pioctrl->pinctrl_dev); |
1227 | dev_err(dev, "pinctrl registration failed\n" ); |
1228 | goto irq_domain_remove_error; |
1229 | } |
1230 | |
1231 | ret = gpiochip_add_data(atmel_pioctrl->gpio_chip, atmel_pioctrl); |
1232 | if (ret) { |
1233 | dev_err(dev, "failed to add gpiochip\n" ); |
1234 | goto irq_domain_remove_error; |
1235 | } |
1236 | |
1237 | ret = gpiochip_add_pin_range(gc: atmel_pioctrl->gpio_chip, pinctl_name: dev_name(dev), |
1238 | gpio_offset: 0, pin_offset: 0, npins: atmel_pioctrl->gpio_chip->ngpio); |
1239 | if (ret) { |
1240 | dev_err(dev, "failed to add gpio pin range\n" ); |
1241 | goto gpiochip_add_pin_range_error; |
1242 | } |
1243 | |
1244 | dev_info(&pdev->dev, "atmel pinctrl initialized\n" ); |
1245 | |
1246 | return 0; |
1247 | |
1248 | gpiochip_add_pin_range_error: |
1249 | gpiochip_remove(gc: atmel_pioctrl->gpio_chip); |
1250 | |
1251 | irq_domain_remove_error: |
1252 | irq_domain_remove(host: atmel_pioctrl->irq_domain); |
1253 | |
1254 | return ret; |
1255 | } |
1256 | |
1257 | static struct platform_driver atmel_pinctrl_driver = { |
1258 | .driver = { |
1259 | .name = "pinctrl-at91-pio4" , |
1260 | .of_match_table = atmel_pctrl_of_match, |
1261 | .pm = &atmel_pctrl_pm_ops, |
1262 | .suppress_bind_attrs = true, |
1263 | }, |
1264 | .probe = atmel_pinctrl_probe, |
1265 | }; |
1266 | builtin_platform_driver(atmel_pinctrl_driver); |
1267 | |