1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * SP7021 Pin Controller Driver. |
4 | * Copyright (C) Sunplus Tech / Tibbo Tech. |
5 | */ |
6 | |
7 | #include <linux/cleanup.h> |
8 | #include <linux/bitfield.h> |
9 | #include <linux/device.h> |
10 | #include <linux/err.h> |
11 | #include <linux/gpio/driver.h> |
12 | #include <linux/init.h> |
13 | #include <linux/module.h> |
14 | #include <linux/of.h> |
15 | #include <linux/overflow.h> |
16 | #include <linux/platform_device.h> |
17 | #include <linux/seq_file.h> |
18 | #include <linux/slab.h> |
19 | |
20 | #include <linux/pinctrl/pinconf.h> |
21 | #include <linux/pinctrl/pinconf-generic.h> |
22 | #include <linux/pinctrl/pinmux.h> |
23 | |
24 | #include <dt-bindings/pinctrl/sppctl-sp7021.h> |
25 | |
26 | #include "../core.h" |
27 | #include "../pinctrl-utils.h" |
28 | |
29 | #include "sppctl.h" |
30 | |
31 | struct sppctl_gpio_chip { |
32 | void __iomem *gpioxt_base; /* MASTER, OE, OUT, IN, I_INV, O_INV, OD */ |
33 | void __iomem *first_base; /* GPIO_FIRST */ |
34 | |
35 | struct gpio_chip chip; |
36 | spinlock_t lock; /* lock for accessing OE register */ |
37 | }; |
38 | |
39 | static inline u32 sppctl_first_readl(struct sppctl_gpio_chip *spp_gchip, u32 off) |
40 | { |
41 | return readl(addr: spp_gchip->first_base + SPPCTL_GPIO_OFF_FIRST + off); |
42 | } |
43 | |
44 | static inline void sppctl_first_writel(struct sppctl_gpio_chip *spp_gchip, u32 val, u32 off) |
45 | { |
46 | writel(val, addr: spp_gchip->first_base + SPPCTL_GPIO_OFF_FIRST + off); |
47 | } |
48 | |
49 | static inline u32 sppctl_gpio_master_readl(struct sppctl_gpio_chip *spp_gchip, u32 off) |
50 | { |
51 | return readl(addr: spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_MASTER + off); |
52 | } |
53 | |
54 | static inline void sppctl_gpio_master_writel(struct sppctl_gpio_chip *spp_gchip, u32 val, |
55 | u32 off) |
56 | { |
57 | writel(val, addr: spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_MASTER + off); |
58 | } |
59 | |
60 | static inline u32 sppctl_gpio_oe_readl(struct sppctl_gpio_chip *spp_gchip, u32 off) |
61 | { |
62 | return readl(addr: spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OE + off); |
63 | } |
64 | |
65 | static inline void sppctl_gpio_oe_writel(struct sppctl_gpio_chip *spp_gchip, u32 val, u32 off) |
66 | { |
67 | writel(val, addr: spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OE + off); |
68 | } |
69 | |
70 | static inline void sppctl_gpio_out_writel(struct sppctl_gpio_chip *spp_gchip, u32 val, u32 off) |
71 | { |
72 | writel(val, addr: spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OUT + off); |
73 | } |
74 | |
75 | static inline u32 sppctl_gpio_in_readl(struct sppctl_gpio_chip *spp_gchip, u32 off) |
76 | { |
77 | return readl(addr: spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_IN + off); |
78 | } |
79 | |
80 | static inline u32 sppctl_gpio_iinv_readl(struct sppctl_gpio_chip *spp_gchip, u32 off) |
81 | { |
82 | return readl(addr: spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_IINV + off); |
83 | } |
84 | |
85 | static inline void sppctl_gpio_iinv_writel(struct sppctl_gpio_chip *spp_gchip, u32 val, |
86 | u32 off) |
87 | { |
88 | writel(val, addr: spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_IINV + off); |
89 | } |
90 | |
91 | static inline u32 sppctl_gpio_oinv_readl(struct sppctl_gpio_chip *spp_gchip, u32 off) |
92 | { |
93 | return readl(addr: spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OINV + off); |
94 | } |
95 | |
96 | static inline void sppctl_gpio_oinv_writel(struct sppctl_gpio_chip *spp_gchip, u32 val, |
97 | u32 off) |
98 | { |
99 | writel(val, addr: spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OINV + off); |
100 | } |
101 | |
102 | static inline u32 sppctl_gpio_od_readl(struct sppctl_gpio_chip *spp_gchip, u32 off) |
103 | { |
104 | return readl(addr: spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OD + off); |
105 | } |
106 | |
107 | static inline void sppctl_gpio_od_writel(struct sppctl_gpio_chip *spp_gchip, u32 val, u32 off) |
108 | { |
109 | writel(val, addr: spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OD + off); |
110 | } |
111 | |
112 | static inline u32 sppctl_get_reg_and_bit_offset(unsigned int offset, u32 *reg_off) |
113 | { |
114 | u32 bit_off; |
115 | |
116 | /* Each register has 32 bits. */ |
117 | *reg_off = (offset / 32) * 4; |
118 | bit_off = offset % 32; |
119 | |
120 | return bit_off; |
121 | } |
122 | |
123 | static inline u32 sppctl_get_moon_reg_and_bit_offset(unsigned int offset, u32 *reg_off) |
124 | { |
125 | u32 bit_off; |
126 | |
127 | /* |
128 | * Each MOON register has 32 bits. Upper 16-bit word are mask-fields. |
129 | * The lower 16-bit word are the control-fields. The corresponding |
130 | * bits in mask-field should be set then you can write something to |
131 | * control-field. |
132 | */ |
133 | *reg_off = (offset / 16) * 4; |
134 | bit_off = offset % 16; |
135 | |
136 | return bit_off; |
137 | } |
138 | |
139 | static inline u32 sppctl_prep_moon_reg_and_offset(unsigned int offset, u32 *reg_off, int val) |
140 | { |
141 | u32 bit_off; |
142 | |
143 | bit_off = sppctl_get_moon_reg_and_bit_offset(offset, reg_off); |
144 | if (val) |
145 | return SPPCTL_SET_MOON_REG_BIT(bit_off); |
146 | else |
147 | return SPPCTL_CLR_MOON_REG_BIT(bit_off); |
148 | } |
149 | |
150 | /** |
151 | * sppctl_func_set() - Set pin of fully-pinmux function. |
152 | * |
153 | * Mask-fields and control-fields of fully-pinmux function of SP7021 are |
154 | * arranged as shown below: |
155 | * |
156 | * func# | register | mask-field | control-field |
157 | * -------+----------+--------------+--------------- |
158 | * 0 | base[0] | (22 : 16) | ( 6 : 0) |
159 | * 1 | base[0] | (30 : 24) | (14 : 8) |
160 | * 2 | base[1] | (22 : 16) | ( 6 : 0) |
161 | * 3 | baeg[1] | (30 : 24) | (14 : 8) |
162 | * : | : | : | : |
163 | * |
164 | * where mask-fields are used to protect control-fields from write-in |
165 | * accidentally. Set the corresponding bits in the mask-field before |
166 | * you write a value into a control-field. |
167 | * |
168 | * Control-fields are used to set where the function pin is going to |
169 | * be routed to. |
170 | * |
171 | * Note that mask-fields and control-fields of even number of 'func' |
172 | * are located at bits (22:16) and (6:0), while odd number of 'func's |
173 | * are located at bits (30:24) and (14:8). |
174 | */ |
175 | static void sppctl_func_set(struct sppctl_pdata *pctl, u8 func, u8 val) |
176 | { |
177 | u32 reg, offset; |
178 | |
179 | /* |
180 | * Note that upper 16-bit word are mask-fields and lower 16-bit |
181 | * word are the control-fields. Set corresponding bits in mask- |
182 | * field before write to a control-field. |
183 | */ |
184 | reg = SPPCTL_FULLY_PINMUX_MASK_MASK | val; |
185 | |
186 | /* |
187 | * MUXF_L2SW_CLK_OUT is the first fully-pinmux pin |
188 | * and its register offset is 0. |
189 | */ |
190 | func -= MUXF_L2SW_CLK_OUT; |
191 | |
192 | /* |
193 | * Check if 'func' is an odd number or not. Mask and control- |
194 | * fields of odd number 'func' is located at upper portion of |
195 | * a register. Extra shift is needed. |
196 | */ |
197 | if (func & BIT(0)) |
198 | reg <<= SPPCTL_FULLY_PINMUX_UPPER_SHIFT; |
199 | |
200 | /* Convert func# to register offset w.r.t. base register. */ |
201 | offset = func * 2; |
202 | offset &= GENMASK(31, 2); |
203 | |
204 | writel(val: reg, addr: pctl->moon2_base + offset); |
205 | } |
206 | |
207 | /** |
208 | * sppctl_gmx_set() - Set pin of group-pinmux. |
209 | * |
210 | * Mask-fields and control-fields of group-pinmux function of SP7021 are |
211 | * arranged as shown below: |
212 | * |
213 | * register | mask-fields | control-fields |
214 | * ----------+--------------+---------------- |
215 | * base[0] | (31 : 16) | (15 : 0) |
216 | * base[1] | (31 : 24) | (15 : 0) |
217 | * base[2] | (31 : 24) | (15 : 0) |
218 | * : | : | : |
219 | * |
220 | * where mask-fields are used to protect control-fields from write-in |
221 | * accidentally. Set the corresponding bits in the mask-field before |
222 | * you write a value into a control-field. |
223 | * |
224 | * Control-fields are used to set where the function pin is going to |
225 | * be routed to. A control-field consists of one or more bits. |
226 | */ |
227 | static void sppctl_gmx_set(struct sppctl_pdata *pctl, u8 reg_off, u8 bit_off, u8 bit_sz, |
228 | u8 val) |
229 | { |
230 | u32 mask, reg; |
231 | |
232 | /* |
233 | * Note that upper 16-bit word are mask-fields and lower 16-bit |
234 | * word are the control-fields. Set corresponding bits in mask- |
235 | * field before write to a control-field. |
236 | */ |
237 | mask = GENMASK(bit_sz - 1, 0) << SPPCTL_MOON_REG_MASK_SHIFT; |
238 | reg = (mask | val) << bit_off; |
239 | |
240 | writel(val: reg, addr: pctl->moon1_base + reg_off * 4); |
241 | } |
242 | |
243 | /** |
244 | * sppctl_first_get() - get bit of FIRST register. |
245 | * |
246 | * There are 4 FIRST registers. Each has 32 control-bits. |
247 | * Totally, there are 4 * 32 = 128 control-bits. |
248 | * Control-bits are arranged as shown below: |
249 | * |
250 | * registers | control-bits |
251 | * -----------+-------------- |
252 | * first[0] | (31 : 0) |
253 | * first[1] | (63 : 32) |
254 | * first[2] | (95 : 64) |
255 | * first[3] | (127 : 96) |
256 | * |
257 | * Each control-bit sets type of a GPIO pin. |
258 | * 0: a fully-pinmux pin |
259 | * 1: a GPIO or IOP pin |
260 | */ |
261 | static int sppctl_first_get(struct gpio_chip *chip, unsigned int offset) |
262 | { |
263 | struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(gc: chip); |
264 | u32 reg_off, bit_off, reg; |
265 | |
266 | bit_off = sppctl_get_reg_and_bit_offset(offset, reg_off: ®_off); |
267 | reg = sppctl_first_readl(spp_gchip, off: reg_off); |
268 | |
269 | return (reg & BIT(bit_off)) ? 1 : 0; |
270 | } |
271 | |
272 | /** |
273 | * sppctl_master_get() - get bit of MASTER register. |
274 | * |
275 | * There are 8 MASTER registers. Each has 16 mask-bits and 16 control-bits. |
276 | * Upper 16-bit of MASTER registers are mask-bits while lower 16-bit are |
277 | * control-bits. Totally, there are 128 mask-bits and 128 control-bits. |
278 | * They are arranged as shown below: |
279 | * |
280 | * register | mask-bits | control-bits |
281 | * -----------+-------------+-------------- |
282 | * master[0] | (15 : 0) | (15 : 0) |
283 | * master[1] | (31 : 16) | (31 : 16) |
284 | * master[2] | (47 : 32) | (47 : 32) |
285 | * : | : | : |
286 | * master[7] | (127 : 112) | (127 : 112) |
287 | * |
288 | * where mask-bits are used to protect control-bits from write-in |
289 | * accidentally. Set the corresponding mask-bit before you write |
290 | * a value into a control-bit. |
291 | * |
292 | * Each control-bit sets type of a GPIO pin when FIRST bit is 1. |
293 | * 0: a IOP pin |
294 | * 1: a GPIO pin |
295 | */ |
296 | static int sppctl_master_get(struct gpio_chip *chip, unsigned int offset) |
297 | { |
298 | struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(gc: chip); |
299 | u32 reg_off, bit_off, reg; |
300 | |
301 | bit_off = sppctl_get_moon_reg_and_bit_offset(offset, reg_off: ®_off); |
302 | reg = sppctl_gpio_master_readl(spp_gchip, off: reg_off); |
303 | return (reg & BIT(bit_off)) ? 1 : 0; |
304 | } |
305 | |
306 | static void sppctl_first_master_set(struct gpio_chip *chip, unsigned int offset, |
307 | enum mux_first_reg first, enum mux_master_reg master) |
308 | { |
309 | struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(gc: chip); |
310 | u32 reg_off, bit_off, reg; |
311 | enum mux_first_reg val; |
312 | |
313 | /* FIRST register */ |
314 | if (first != mux_f_keep) { |
315 | bit_off = sppctl_get_reg_and_bit_offset(offset, reg_off: ®_off); |
316 | reg = sppctl_first_readl(spp_gchip, off: reg_off); |
317 | val = (reg & BIT(bit_off)) ? mux_f_gpio : mux_f_mux; |
318 | |
319 | if (first != val) |
320 | switch (first) { |
321 | case mux_f_gpio: |
322 | reg |= BIT(bit_off); |
323 | sppctl_first_writel(spp_gchip, val: reg, off: reg_off); |
324 | break; |
325 | |
326 | case mux_f_mux: |
327 | reg &= ~BIT(bit_off); |
328 | sppctl_first_writel(spp_gchip, val: reg, off: reg_off); |
329 | break; |
330 | |
331 | case mux_f_keep: |
332 | break; |
333 | } |
334 | } |
335 | |
336 | /* MASTER register */ |
337 | if (master != mux_m_keep) { |
338 | reg = sppctl_prep_moon_reg_and_offset(offset, reg_off: ®_off, val: (master == mux_m_gpio)); |
339 | sppctl_gpio_master_writel(spp_gchip, val: reg, off: reg_off); |
340 | } |
341 | } |
342 | |
343 | static void sppctl_gpio_input_inv_set(struct gpio_chip *chip, unsigned int offset) |
344 | { |
345 | struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(gc: chip); |
346 | u32 reg_off, reg; |
347 | |
348 | reg = sppctl_prep_moon_reg_and_offset(offset, reg_off: ®_off, val: 1); |
349 | sppctl_gpio_iinv_writel(spp_gchip, val: reg, off: reg_off); |
350 | } |
351 | |
352 | static void sppctl_gpio_output_inv_set(struct gpio_chip *chip, unsigned int offset) |
353 | { |
354 | struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(gc: chip); |
355 | u32 reg_off, reg; |
356 | |
357 | reg = sppctl_prep_moon_reg_and_offset(offset, reg_off: ®_off, val: 1); |
358 | sppctl_gpio_oinv_writel(spp_gchip, val: reg, off: reg_off); |
359 | } |
360 | |
361 | static int sppctl_gpio_output_od_get(struct gpio_chip *chip, unsigned int offset) |
362 | { |
363 | struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(gc: chip); |
364 | u32 reg_off, bit_off, reg; |
365 | |
366 | bit_off = sppctl_get_moon_reg_and_bit_offset(offset, reg_off: ®_off); |
367 | reg = sppctl_gpio_od_readl(spp_gchip, off: reg_off); |
368 | |
369 | return (reg & BIT(bit_off)) ? 1 : 0; |
370 | } |
371 | |
372 | static void sppctl_gpio_output_od_set(struct gpio_chip *chip, unsigned int offset, |
373 | unsigned int val) |
374 | { |
375 | struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(gc: chip); |
376 | u32 reg_off, reg; |
377 | |
378 | reg = sppctl_prep_moon_reg_and_offset(offset, reg_off: ®_off, val); |
379 | sppctl_gpio_od_writel(spp_gchip, val: reg, off: reg_off); |
380 | } |
381 | |
382 | static int sppctl_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) |
383 | { |
384 | struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(gc: chip); |
385 | u32 reg_off, bit_off, reg; |
386 | |
387 | bit_off = sppctl_get_moon_reg_and_bit_offset(offset, reg_off: ®_off); |
388 | reg = sppctl_gpio_oe_readl(spp_gchip, off: reg_off); |
389 | |
390 | return (reg & BIT(bit_off)) ? 0 : 1; |
391 | } |
392 | |
393 | static int sppctl_gpio_inv_get(struct gpio_chip *chip, unsigned int offset) |
394 | { |
395 | struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(gc: chip); |
396 | u32 reg_off, bit_off, reg; |
397 | unsigned long flags; |
398 | |
399 | bit_off = sppctl_get_moon_reg_and_bit_offset(offset, reg_off: ®_off); |
400 | |
401 | spin_lock_irqsave(&spp_gchip->lock, flags); |
402 | |
403 | if (sppctl_gpio_get_direction(chip, offset)) |
404 | reg = sppctl_gpio_iinv_readl(spp_gchip, off: reg_off); |
405 | else |
406 | reg = sppctl_gpio_oinv_readl(spp_gchip, off: reg_off); |
407 | |
408 | spin_unlock_irqrestore(lock: &spp_gchip->lock, flags); |
409 | |
410 | return (reg & BIT(bit_off)) ? 1 : 0; |
411 | } |
412 | |
413 | static int sppctl_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) |
414 | { |
415 | struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(gc: chip); |
416 | unsigned long flags; |
417 | u32 reg_off, reg; |
418 | |
419 | reg = sppctl_prep_moon_reg_and_offset(offset, reg_off: ®_off, val: 0); |
420 | |
421 | spin_lock_irqsave(&spp_gchip->lock, flags); |
422 | |
423 | sppctl_gpio_oe_writel(spp_gchip, val: reg, off: reg_off); |
424 | |
425 | spin_unlock_irqrestore(lock: &spp_gchip->lock, flags); |
426 | return 0; |
427 | } |
428 | |
429 | static int sppctl_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int val) |
430 | { |
431 | struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(gc: chip); |
432 | unsigned long flags; |
433 | u32 reg_off, reg; |
434 | |
435 | reg = sppctl_prep_moon_reg_and_offset(offset, reg_off: ®_off, val: 1); |
436 | |
437 | spin_lock_irqsave(&spp_gchip->lock, flags); |
438 | |
439 | sppctl_gpio_oe_writel(spp_gchip, val: reg, off: reg_off); |
440 | |
441 | if (val < 0) { |
442 | spin_unlock_irqrestore(lock: &spp_gchip->lock, flags); |
443 | return 0; |
444 | } |
445 | |
446 | reg = sppctl_prep_moon_reg_and_offset(offset, reg_off: ®_off, val); |
447 | sppctl_gpio_out_writel(spp_gchip, val: reg, off: reg_off); |
448 | |
449 | spin_unlock_irqrestore(lock: &spp_gchip->lock, flags); |
450 | return 0; |
451 | } |
452 | |
453 | static int sppctl_gpio_get(struct gpio_chip *chip, unsigned int offset) |
454 | { |
455 | struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(gc: chip); |
456 | u32 reg_off, bit_off, reg; |
457 | |
458 | bit_off = sppctl_get_reg_and_bit_offset(offset, reg_off: ®_off); |
459 | reg = sppctl_gpio_in_readl(spp_gchip, off: reg_off); |
460 | |
461 | return (reg & BIT(bit_off)) ? 1 : 0; |
462 | } |
463 | |
464 | static void sppctl_gpio_set(struct gpio_chip *chip, unsigned int offset, int val) |
465 | { |
466 | struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(gc: chip); |
467 | u32 reg_off, reg; |
468 | |
469 | reg = sppctl_prep_moon_reg_and_offset(offset, reg_off: ®_off, val); |
470 | sppctl_gpio_out_writel(spp_gchip, val: reg, off: reg_off); |
471 | } |
472 | |
473 | static int sppctl_gpio_set_config(struct gpio_chip *chip, unsigned int offset, |
474 | unsigned long config) |
475 | { |
476 | enum pin_config_param param = pinconf_to_config_param(config); |
477 | struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(gc: chip); |
478 | u32 reg_off, reg; |
479 | |
480 | switch (param) { |
481 | case PIN_CONFIG_DRIVE_OPEN_DRAIN: |
482 | reg = sppctl_prep_moon_reg_and_offset(offset, reg_off: ®_off, val: 1); |
483 | sppctl_gpio_od_writel(spp_gchip, val: reg, off: reg_off); |
484 | break; |
485 | |
486 | case PIN_CONFIG_INPUT_ENABLE: |
487 | break; |
488 | |
489 | case PIN_CONFIG_OUTPUT: |
490 | return sppctl_gpio_direction_output(chip, offset, val: 0); |
491 | |
492 | case PIN_CONFIG_PERSIST_STATE: |
493 | return -ENOTSUPP; |
494 | |
495 | default: |
496 | return -EINVAL; |
497 | } |
498 | |
499 | return 0; |
500 | } |
501 | |
502 | static void sppctl_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) |
503 | { |
504 | int i; |
505 | |
506 | for (i = 0; i < chip->ngpio; i++) { |
507 | char *label __free(kfree) = gpiochip_dup_line_label(gc: chip, offset: i); |
508 | if (IS_ERR(ptr: label)) |
509 | continue; |
510 | |
511 | seq_printf(m: s, fmt: " gpio-%03d (%-16.16s | %-16.16s)" , i + chip->base, |
512 | chip->names[i], label ?: "" ); |
513 | seq_printf(m: s, fmt: " %c" , sppctl_gpio_get_direction(chip, offset: i) ? 'I' : 'O'); |
514 | seq_printf(m: s, fmt: ":%d" , sppctl_gpio_get(chip, offset: i)); |
515 | seq_printf(m: s, fmt: " %s" , sppctl_first_get(chip, offset: i) ? "gpi" : "mux" ); |
516 | seq_printf(m: s, fmt: " %s" , sppctl_master_get(chip, offset: i) ? "gpi" : "iop" ); |
517 | seq_printf(m: s, fmt: " %s" , sppctl_gpio_inv_get(chip, offset: i) ? "inv" : " " ); |
518 | seq_printf(m: s, fmt: " %s" , sppctl_gpio_output_od_get(chip, offset: i) ? "oDr" : "" ); |
519 | seq_puts(m: s, s: "\n" ); |
520 | } |
521 | } |
522 | |
523 | static int sppctl_gpio_new(struct platform_device *pdev, struct sppctl_pdata *pctl) |
524 | { |
525 | struct sppctl_gpio_chip *spp_gchip; |
526 | struct gpio_chip *gchip; |
527 | int err; |
528 | |
529 | spp_gchip = devm_kzalloc(dev: &pdev->dev, size: sizeof(*spp_gchip), GFP_KERNEL); |
530 | if (!spp_gchip) |
531 | return -ENOMEM; |
532 | pctl->spp_gchip = spp_gchip; |
533 | |
534 | spp_gchip->gpioxt_base = pctl->gpioxt_base; |
535 | spp_gchip->first_base = pctl->first_base; |
536 | spin_lock_init(&spp_gchip->lock); |
537 | |
538 | gchip = &spp_gchip->chip; |
539 | gchip->label = SPPCTL_MODULE_NAME; |
540 | gchip->parent = &pdev->dev; |
541 | gchip->owner = THIS_MODULE; |
542 | gchip->request = gpiochip_generic_request; |
543 | gchip->free = gpiochip_generic_free; |
544 | gchip->get_direction = sppctl_gpio_get_direction; |
545 | gchip->direction_input = sppctl_gpio_direction_input; |
546 | gchip->direction_output = sppctl_gpio_direction_output; |
547 | gchip->get = sppctl_gpio_get; |
548 | gchip->set = sppctl_gpio_set; |
549 | gchip->set_config = sppctl_gpio_set_config; |
550 | gchip->dbg_show = IS_ENABLED(CONFIG_DEBUG_FS) ? |
551 | sppctl_gpio_dbg_show : NULL; |
552 | gchip->base = -1; |
553 | gchip->ngpio = sppctl_gpio_list_sz; |
554 | gchip->names = sppctl_gpio_list_s; |
555 | |
556 | pctl->pctl_grange.npins = gchip->ngpio; |
557 | pctl->pctl_grange.name = gchip->label; |
558 | pctl->pctl_grange.gc = gchip; |
559 | |
560 | err = devm_gpiochip_add_data(&pdev->dev, gchip, spp_gchip); |
561 | if (err) |
562 | return dev_err_probe(dev: &pdev->dev, err, fmt: "Failed to add gpiochip!\n" ); |
563 | |
564 | return 0; |
565 | } |
566 | |
567 | static int sppctl_pin_config_get(struct pinctrl_dev *pctldev, unsigned int pin, |
568 | unsigned long *config) |
569 | { |
570 | struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev); |
571 | unsigned int param = pinconf_to_config_param(config: *config); |
572 | unsigned int arg; |
573 | |
574 | switch (param) { |
575 | case PIN_CONFIG_DRIVE_OPEN_DRAIN: |
576 | if (!sppctl_gpio_output_od_get(chip: &pctl->spp_gchip->chip, offset: pin)) |
577 | return -EINVAL; |
578 | arg = 0; |
579 | break; |
580 | |
581 | case PIN_CONFIG_OUTPUT: |
582 | if (!sppctl_first_get(chip: &pctl->spp_gchip->chip, offset: pin)) |
583 | return -EINVAL; |
584 | if (!sppctl_master_get(chip: &pctl->spp_gchip->chip, offset: pin)) |
585 | return -EINVAL; |
586 | if (sppctl_gpio_get_direction(chip: &pctl->spp_gchip->chip, offset: pin)) |
587 | return -EINVAL; |
588 | arg = sppctl_gpio_get(chip: &pctl->spp_gchip->chip, offset: pin); |
589 | break; |
590 | |
591 | default: |
592 | return -EOPNOTSUPP; |
593 | } |
594 | *config = pinconf_to_config_packed(param, argument: arg); |
595 | |
596 | return 0; |
597 | } |
598 | |
599 | static int sppctl_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin, |
600 | unsigned long *configs, unsigned int num_configs) |
601 | { |
602 | struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev); |
603 | int i; |
604 | |
605 | /* Special handling for IOP pins */ |
606 | if (configs[0] == SPPCTL_IOP_CONFIGS) { |
607 | sppctl_first_master_set(chip: &pctl->spp_gchip->chip, offset: pin, first: mux_f_gpio, master: mux_m_iop); |
608 | return 0; |
609 | } |
610 | |
611 | for (i = 0; i < num_configs; i++) { |
612 | if (configs[i] & SPPCTL_PCTL_L_OUT) |
613 | sppctl_gpio_direction_output(chip: &pctl->spp_gchip->chip, offset: pin, val: 0); |
614 | if (configs[i] & SPPCTL_PCTL_L_OU1) |
615 | sppctl_gpio_direction_output(chip: &pctl->spp_gchip->chip, offset: pin, val: 1); |
616 | if (configs[i] & SPPCTL_PCTL_L_INV) |
617 | sppctl_gpio_input_inv_set(chip: &pctl->spp_gchip->chip, offset: pin); |
618 | if (configs[i] & SPPCTL_PCTL_L_ONV) |
619 | sppctl_gpio_output_inv_set(chip: &pctl->spp_gchip->chip, offset: pin); |
620 | if (configs[i] & SPPCTL_PCTL_L_ODR) |
621 | sppctl_gpio_output_od_set(chip: &pctl->spp_gchip->chip, offset: pin, val: 1); |
622 | } |
623 | |
624 | return 0; |
625 | } |
626 | |
627 | static const struct pinconf_ops sppctl_pconf_ops = { |
628 | .is_generic = true, |
629 | .pin_config_get = sppctl_pin_config_get, |
630 | .pin_config_set = sppctl_pin_config_set, |
631 | }; |
632 | |
633 | static int sppctl_get_functions_count(struct pinctrl_dev *pctldev) |
634 | { |
635 | return sppctl_list_funcs_sz; |
636 | } |
637 | |
638 | static const char *sppctl_get_function_name(struct pinctrl_dev *pctldev, |
639 | unsigned int selector) |
640 | { |
641 | return sppctl_list_funcs[selector].name; |
642 | } |
643 | |
644 | static int sppctl_get_function_groups(struct pinctrl_dev *pctldev, unsigned int selector, |
645 | const char * const **groups, unsigned int *num_groups) |
646 | { |
647 | struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev); |
648 | const struct sppctl_func *f = &sppctl_list_funcs[selector]; |
649 | int i; |
650 | |
651 | *num_groups = 0; |
652 | switch (f->type) { |
653 | case pinmux_type_fpmx: |
654 | *num_groups = sppctl_pmux_list_sz; |
655 | *groups = sppctl_pmux_list_s; |
656 | break; |
657 | |
658 | case pinmux_type_grp: |
659 | if (!f->grps) |
660 | break; |
661 | |
662 | *num_groups = f->gnum; |
663 | for (i = 0; i < pctl->unq_grps_sz; i++) |
664 | if (pctl->g2fp_maps[i].f_idx == selector) |
665 | break; |
666 | *groups = &pctl->unq_grps[i]; |
667 | break; |
668 | |
669 | default: |
670 | dev_err(pctldev->dev, "Unknown pinmux (selector: %d, type: %d)\n" , |
671 | selector, f->type); |
672 | break; |
673 | } |
674 | |
675 | return 0; |
676 | } |
677 | |
678 | /** |
679 | * sppctl_fully_pinmux_conv - Convert GPIO# to fully-pinmux control-field setting |
680 | * |
681 | * Each fully-pinmux function can be mapped to any of GPIO 8 ~ 71 by |
682 | * settings its control-field. Refer to following table: |
683 | * |
684 | * control-field | GPIO |
685 | * --------------+-------- |
686 | * 0 | No map |
687 | * 1 | 8 |
688 | * 2 | 9 |
689 | * 3 | 10 |
690 | * : | : |
691 | * 65 | 71 |
692 | */ |
693 | static inline int sppctl_fully_pinmux_conv(unsigned int offset) |
694 | { |
695 | return (offset < 8) ? 0 : offset - 7; |
696 | } |
697 | |
698 | static int sppctl_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector, |
699 | unsigned int group_selector) |
700 | { |
701 | const struct sppctl_func *f = &sppctl_list_funcs[func_selector]; |
702 | struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev); |
703 | struct grp2fp_map g2fpm = pctl->g2fp_maps[group_selector]; |
704 | int i; |
705 | |
706 | switch (f->type) { |
707 | case pinmux_type_fpmx: |
708 | sppctl_first_master_set(chip: &pctl->spp_gchip->chip, offset: group_selector, |
709 | first: mux_f_mux, master: mux_m_keep); |
710 | sppctl_func_set(pctl, func: func_selector, val: sppctl_fully_pinmux_conv(offset: group_selector)); |
711 | break; |
712 | |
713 | case pinmux_type_grp: |
714 | for (i = 0; i < f->grps[g2fpm.g_idx].pnum; i++) |
715 | sppctl_first_master_set(chip: &pctl->spp_gchip->chip, |
716 | offset: f->grps[g2fpm.g_idx].pins[i], |
717 | first: mux_f_mux, master: mux_m_keep); |
718 | sppctl_gmx_set(pctl, reg_off: f->roff, bit_off: f->boff, bit_sz: f->blen, val: f->grps[g2fpm.g_idx].gval); |
719 | break; |
720 | |
721 | default: |
722 | dev_err(pctldev->dev, "Unknown pinmux type (func_selector: %d, type: %d)\n" , |
723 | func_selector, f->type); |
724 | break; |
725 | } |
726 | |
727 | return 0; |
728 | } |
729 | |
730 | static int sppctl_gpio_request_enable(struct pinctrl_dev *pctldev, |
731 | struct pinctrl_gpio_range *range, unsigned int offset) |
732 | { |
733 | struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev); |
734 | int g_f, g_m; |
735 | |
736 | g_f = sppctl_first_get(chip: &pctl->spp_gchip->chip, offset); |
737 | g_m = sppctl_master_get(chip: &pctl->spp_gchip->chip, offset); |
738 | if (g_f == mux_f_gpio && g_m == mux_m_gpio) |
739 | return 0; |
740 | |
741 | sppctl_first_master_set(chip: &pctl->spp_gchip->chip, offset, first: mux_f_gpio, master: mux_m_gpio); |
742 | return 0; |
743 | } |
744 | |
745 | static const struct pinmux_ops sppctl_pinmux_ops = { |
746 | .get_functions_count = sppctl_get_functions_count, |
747 | .get_function_name = sppctl_get_function_name, |
748 | .get_function_groups = sppctl_get_function_groups, |
749 | .set_mux = sppctl_set_mux, |
750 | .gpio_request_enable = sppctl_gpio_request_enable, |
751 | .strict = true, |
752 | }; |
753 | |
754 | static int sppctl_get_groups_count(struct pinctrl_dev *pctldev) |
755 | { |
756 | struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev); |
757 | |
758 | return pctl->unq_grps_sz; |
759 | } |
760 | |
761 | static const char *sppctl_get_group_name(struct pinctrl_dev *pctldev, unsigned int selector) |
762 | { |
763 | struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev); |
764 | |
765 | return pctl->unq_grps[selector]; |
766 | } |
767 | |
768 | static int sppctl_get_group_pins(struct pinctrl_dev *pctldev, unsigned int selector, |
769 | const unsigned int **pins, unsigned int *num_pins) |
770 | { |
771 | struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev); |
772 | struct grp2fp_map g2fpm = pctl->g2fp_maps[selector]; |
773 | const struct sppctl_func *f; |
774 | |
775 | f = &sppctl_list_funcs[g2fpm.f_idx]; |
776 | *num_pins = 0; |
777 | |
778 | /* Except group-pinmux, each group has 1 pin. */ |
779 | if (f->type != pinmux_type_grp) { |
780 | *num_pins = 1; |
781 | *pins = &sppctl_pins_gpio[selector]; |
782 | return 0; |
783 | } |
784 | |
785 | /* Group-pinmux may have more than one pin. */ |
786 | if (!f->grps) |
787 | return 0; |
788 | |
789 | if (f->gnum < 1) |
790 | return 0; |
791 | |
792 | *num_pins = f->grps[g2fpm.g_idx].pnum; |
793 | *pins = f->grps[g2fpm.g_idx].pins; |
794 | |
795 | return 0; |
796 | } |
797 | |
798 | #ifdef CONFIG_DEBUG_FS |
799 | static void sppctl_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, |
800 | unsigned int offset) |
801 | { |
802 | struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev); |
803 | const char *pin_type; |
804 | u8 first, master; |
805 | |
806 | first = sppctl_first_get(chip: &pctl->spp_gchip->chip, offset); |
807 | master = sppctl_master_get(chip: &pctl->spp_gchip->chip, offset); |
808 | if (first) |
809 | if (master) |
810 | pin_type = "GPIO" ; |
811 | else |
812 | pin_type = " IOP" ; |
813 | else |
814 | pin_type = " MUX" ; |
815 | seq_printf(m: s, fmt: " %s" , pin_type); |
816 | } |
817 | #endif |
818 | |
819 | static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node *np_config, |
820 | struct pinctrl_map **map, unsigned int *num_maps) |
821 | { |
822 | struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev); |
823 | int nmG = of_property_count_strings(np: np_config, propname: "groups" ); |
824 | const struct sppctl_func *f = NULL; |
825 | u8 pin_num, pin_type, pin_func; |
826 | struct device_node *parent; |
827 | unsigned long *configs; |
828 | struct property *prop; |
829 | const char *s_f, *s_g; |
830 | |
831 | const __be32 *list; |
832 | u32 dt_pin, dt_fun; |
833 | int i, size = 0; |
834 | |
835 | list = of_get_property(node: np_config, name: "sunplus,pins" , lenp: &size); |
836 | *num_maps = size / sizeof(*list); |
837 | |
838 | /* |
839 | * Process property: |
840 | * sunplus,pins = < u32 u32 u32 ... >; |
841 | * |
842 | * Each 32-bit integer defines a individual pin in which: |
843 | * |
844 | * Bit 32~24: defines GPIO pin number. Its range is 0 ~ 98. |
845 | * Bit 23~16: defines types: (1) fully-pinmux pins |
846 | * (2) IO processor pins |
847 | * (3) digital GPIO pins |
848 | * Bit 15~8: defines pins of peripherals (which are defined in |
849 | * 'include/dt-binging/pinctrl/sppctl.h'). |
850 | * Bit 7~0: defines types or initial-state of digital GPIO pins. |
851 | */ |
852 | for (i = 0; i < (*num_maps); i++) { |
853 | dt_pin = be32_to_cpu(list[i]); |
854 | pin_num = FIELD_GET(GENMASK(31, 24), dt_pin); |
855 | |
856 | if (pin_num >= sppctl_pins_all_sz) { |
857 | dev_err(pctldev->dev, "Invalid pin property at index %d (0x%08x)\n" , |
858 | i, dt_pin); |
859 | return -EINVAL; |
860 | } |
861 | } |
862 | |
863 | if (nmG <= 0) |
864 | nmG = 0; |
865 | |
866 | *map = kcalloc(n: *num_maps + nmG, size: sizeof(**map), GFP_KERNEL); |
867 | if (!(*map)) |
868 | return -ENOMEM; |
869 | |
870 | parent = of_get_parent(node: np_config); |
871 | for (i = 0; i < (*num_maps); i++) { |
872 | dt_pin = be32_to_cpu(list[i]); |
873 | pin_num = FIELD_GET(GENMASK(31, 24), dt_pin); |
874 | pin_type = FIELD_GET(GENMASK(23, 16), dt_pin); |
875 | pin_func = FIELD_GET(GENMASK(15, 8), dt_pin); |
876 | (*map)[i].name = parent->name; |
877 | |
878 | if (pin_type == SPPCTL_PCTL_G_GPIO) { |
879 | /* A digital GPIO pin */ |
880 | (*map)[i].type = PIN_MAP_TYPE_CONFIGS_PIN; |
881 | (*map)[i].data.configs.num_configs = 1; |
882 | (*map)[i].data.configs.group_or_pin = pin_get_name(pctldev, pin: pin_num); |
883 | configs = kmalloc(size: sizeof(*configs), GFP_KERNEL); |
884 | if (!configs) |
885 | goto sppctl_map_err; |
886 | *configs = FIELD_GET(GENMASK(7, 0), dt_pin); |
887 | (*map)[i].data.configs.configs = configs; |
888 | |
889 | dev_dbg(pctldev->dev, "%s: GPIO (%s)\n" , |
890 | (*map)[i].data.configs.group_or_pin, |
891 | (*configs & (SPPCTL_PCTL_L_OUT | SPPCTL_PCTL_L_OU1)) ? |
892 | "OUT" : "IN" ); |
893 | } else if (pin_type == SPPCTL_PCTL_G_IOPP) { |
894 | /* A IO Processor (IOP) pin */ |
895 | (*map)[i].type = PIN_MAP_TYPE_CONFIGS_PIN; |
896 | (*map)[i].data.configs.num_configs = 1; |
897 | (*map)[i].data.configs.group_or_pin = pin_get_name(pctldev, pin: pin_num); |
898 | configs = kmalloc(size: sizeof(*configs), GFP_KERNEL); |
899 | if (!configs) |
900 | goto sppctl_map_err; |
901 | *configs = SPPCTL_IOP_CONFIGS; |
902 | (*map)[i].data.configs.configs = configs; |
903 | |
904 | dev_dbg(pctldev->dev, "%s: IOP\n" , |
905 | (*map)[i].data.configs.group_or_pin); |
906 | } else { |
907 | /* A fully-pinmux pin */ |
908 | (*map)[i].type = PIN_MAP_TYPE_MUX_GROUP; |
909 | (*map)[i].data.mux.function = sppctl_list_funcs[pin_func].name; |
910 | (*map)[i].data.mux.group = pin_get_name(pctldev, pin: pin_num); |
911 | |
912 | dev_dbg(pctldev->dev, "%s: %s\n" , (*map)[i].data.mux.group, |
913 | (*map)[i].data.mux.function); |
914 | } |
915 | } |
916 | |
917 | /* |
918 | * Process properties: |
919 | * function = "xxx"; |
920 | * groups = "yyy"; |
921 | */ |
922 | if (nmG > 0 && of_property_read_string(np: np_config, propname: "function" , out_string: &s_f) == 0) { |
923 | of_property_for_each_string(np_config, "groups" , prop, s_g) { |
924 | (*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP; |
925 | (*map)[*num_maps].data.mux.function = s_f; |
926 | (*map)[*num_maps].data.mux.group = s_g; |
927 | (*num_maps)++; |
928 | |
929 | dev_dbg(pctldev->dev, "%s: %s\n" , s_f, s_g); |
930 | } |
931 | } |
932 | |
933 | /* |
934 | * Process property: |
935 | * sunplus,zerofunc = < u32 u32 u32 ...> |
936 | */ |
937 | list = of_get_property(node: np_config, name: "sunplus,zerofunc" , lenp: &size); |
938 | if (list) { |
939 | for (i = 0; i < (size / sizeof(*list)); i++) { |
940 | dt_fun = be32_to_cpu(list[i]); |
941 | if (dt_fun >= sppctl_list_funcs_sz) { |
942 | dev_err(pctldev->dev, "Zero-func %d out of range!\n" , |
943 | dt_fun); |
944 | continue; |
945 | } |
946 | |
947 | f = &sppctl_list_funcs[dt_fun]; |
948 | switch (f->type) { |
949 | case pinmux_type_fpmx: |
950 | sppctl_func_set(pctl, func: dt_fun, val: 0); |
951 | dev_dbg(pctldev->dev, "%s: No map\n" , f->name); |
952 | break; |
953 | |
954 | case pinmux_type_grp: |
955 | sppctl_gmx_set(pctl, reg_off: f->roff, bit_off: f->boff, bit_sz: f->blen, val: 0); |
956 | dev_dbg(pctldev->dev, "%s: No map\n" , f->name); |
957 | break; |
958 | |
959 | default: |
960 | dev_err(pctldev->dev, "Wrong zero-group: %d (%s)\n" , |
961 | dt_fun, f->name); |
962 | break; |
963 | } |
964 | } |
965 | } |
966 | |
967 | of_node_put(node: parent); |
968 | dev_dbg(pctldev->dev, "%d pins mapped\n" , *num_maps); |
969 | return 0; |
970 | |
971 | sppctl_map_err: |
972 | for (i = 0; i < (*num_maps); i++) |
973 | if ((*map)[i].type == PIN_MAP_TYPE_CONFIGS_PIN) |
974 | kfree(objp: (*map)[i].data.configs.configs); |
975 | kfree(objp: *map); |
976 | of_node_put(node: parent); |
977 | return -ENOMEM; |
978 | } |
979 | |
980 | static const struct pinctrl_ops sppctl_pctl_ops = { |
981 | .get_groups_count = sppctl_get_groups_count, |
982 | .get_group_name = sppctl_get_group_name, |
983 | .get_group_pins = sppctl_get_group_pins, |
984 | #ifdef CONFIG_DEBUG_FS |
985 | .pin_dbg_show = sppctl_pin_dbg_show, |
986 | #endif |
987 | .dt_node_to_map = sppctl_dt_node_to_map, |
988 | .dt_free_map = pinctrl_utils_free_map, |
989 | }; |
990 | |
991 | static int sppctl_group_groups(struct platform_device *pdev) |
992 | { |
993 | struct sppctl_pdata *sppctl = platform_get_drvdata(pdev); |
994 | int i, k, j; |
995 | |
996 | /* Calculate number of total group (GPIO + group-pinmux group). */ |
997 | sppctl->unq_grps_sz = sppctl_gpio_list_sz; |
998 | for (i = 0; i < sppctl_list_funcs_sz; i++) |
999 | if (sppctl_list_funcs[i].type == pinmux_type_grp) |
1000 | sppctl->unq_grps_sz += sppctl_list_funcs[i].gnum; |
1001 | |
1002 | sppctl->unq_grps = devm_kcalloc(dev: &pdev->dev, n: sppctl->unq_grps_sz + 1, |
1003 | size: sizeof(*sppctl->unq_grps), GFP_KERNEL); |
1004 | if (!sppctl->unq_grps) |
1005 | return -ENOMEM; |
1006 | |
1007 | sppctl->g2fp_maps = devm_kcalloc(dev: &pdev->dev, n: sppctl->unq_grps_sz + 1, |
1008 | size: sizeof(*sppctl->g2fp_maps), GFP_KERNEL); |
1009 | if (!sppctl->g2fp_maps) |
1010 | return -ENOMEM; |
1011 | |
1012 | /* Add GPIO pins. */ |
1013 | for (i = 0; i < sppctl_gpio_list_sz; i++) { |
1014 | sppctl->unq_grps[i] = sppctl_gpio_list_s[i]; |
1015 | sppctl->g2fp_maps[i].f_idx = 0; |
1016 | sppctl->g2fp_maps[i].g_idx = i; |
1017 | } |
1018 | |
1019 | /* Add group-pinmux to end of GPIO pins. */ |
1020 | j = sppctl_gpio_list_sz; |
1021 | for (i = 0; i < sppctl_list_funcs_sz; i++) { |
1022 | if (sppctl_list_funcs[i].type != pinmux_type_grp) |
1023 | continue; |
1024 | |
1025 | for (k = 0; k < sppctl_list_funcs[i].gnum; k++) { |
1026 | sppctl->unq_grps[j] = sppctl_list_funcs[i].grps[k].name; |
1027 | sppctl->g2fp_maps[j].f_idx = i; |
1028 | sppctl->g2fp_maps[j].g_idx = k; |
1029 | j++; |
1030 | } |
1031 | } |
1032 | |
1033 | return 0; |
1034 | } |
1035 | |
1036 | static int sppctl_pinctrl_init(struct platform_device *pdev) |
1037 | { |
1038 | struct sppctl_pdata *sppctl = platform_get_drvdata(pdev); |
1039 | int err; |
1040 | |
1041 | sppctl->pctl_desc.owner = THIS_MODULE; |
1042 | sppctl->pctl_desc.name = dev_name(dev: &pdev->dev); |
1043 | sppctl->pctl_desc.pins = sppctl_pins_all; |
1044 | sppctl->pctl_desc.npins = sppctl_pins_all_sz; |
1045 | sppctl->pctl_desc.pctlops = &sppctl_pctl_ops; |
1046 | sppctl->pctl_desc.confops = &sppctl_pconf_ops; |
1047 | sppctl->pctl_desc.pmxops = &sppctl_pinmux_ops; |
1048 | |
1049 | err = sppctl_group_groups(pdev); |
1050 | if (err) |
1051 | return err; |
1052 | |
1053 | err = devm_pinctrl_register_and_init(dev: &pdev->dev, pctldesc: &sppctl->pctl_desc, |
1054 | driver_data: sppctl, pctldev: &sppctl->pctl_dev); |
1055 | if (err) |
1056 | return dev_err_probe(dev: &pdev->dev, err, fmt: "Failed to register pinctrl!\n" ); |
1057 | |
1058 | pinctrl_enable(pctldev: sppctl->pctl_dev); |
1059 | return 0; |
1060 | } |
1061 | |
1062 | static int sppctl_resource_map(struct platform_device *pdev, struct sppctl_pdata *sppctl) |
1063 | { |
1064 | sppctl->moon2_base = devm_platform_ioremap_resource_byname(pdev, name: "moon2" ); |
1065 | if (IS_ERR(ptr: sppctl->moon2_base)) |
1066 | return PTR_ERR(ptr: sppctl->moon2_base); |
1067 | |
1068 | sppctl->gpioxt_base = devm_platform_ioremap_resource_byname(pdev, name: "gpioxt" ); |
1069 | if (IS_ERR(ptr: sppctl->gpioxt_base)) |
1070 | return PTR_ERR(ptr: sppctl->gpioxt_base); |
1071 | |
1072 | sppctl->first_base = devm_platform_ioremap_resource_byname(pdev, name: "first" ); |
1073 | if (IS_ERR(ptr: sppctl->first_base)) |
1074 | return PTR_ERR(ptr: sppctl->first_base); |
1075 | |
1076 | sppctl->moon1_base = devm_platform_ioremap_resource_byname(pdev, name: "moon1" ); |
1077 | if (IS_ERR(ptr: sppctl->moon1_base)) |
1078 | return PTR_ERR(ptr: sppctl->moon1_base); |
1079 | |
1080 | return 0; |
1081 | } |
1082 | |
1083 | static int sppctl_probe(struct platform_device *pdev) |
1084 | { |
1085 | struct sppctl_pdata *sppctl; |
1086 | int ret; |
1087 | |
1088 | sppctl = devm_kzalloc(dev: &pdev->dev, size: sizeof(*sppctl), GFP_KERNEL); |
1089 | if (!sppctl) |
1090 | return -ENOMEM; |
1091 | platform_set_drvdata(pdev, data: sppctl); |
1092 | |
1093 | ret = sppctl_resource_map(pdev, sppctl); |
1094 | if (ret) |
1095 | return ret; |
1096 | |
1097 | ret = sppctl_gpio_new(pdev, pctl: sppctl); |
1098 | if (ret) |
1099 | return ret; |
1100 | |
1101 | ret = sppctl_pinctrl_init(pdev); |
1102 | if (ret) |
1103 | return ret; |
1104 | |
1105 | pinctrl_add_gpio_range(pctldev: sppctl->pctl_dev, range: &sppctl->pctl_grange); |
1106 | |
1107 | return 0; |
1108 | } |
1109 | |
1110 | static const struct of_device_id sppctl_match_table[] = { |
1111 | { .compatible = "sunplus,sp7021-pctl" }, |
1112 | { /* sentinel */ } |
1113 | }; |
1114 | |
1115 | static struct platform_driver sppctl_pinctrl_driver = { |
1116 | .driver = { |
1117 | .name = SPPCTL_MODULE_NAME, |
1118 | .of_match_table = sppctl_match_table, |
1119 | }, |
1120 | .probe = sppctl_probe, |
1121 | }; |
1122 | builtin_platform_driver(sppctl_pinctrl_driver) |
1123 | |
1124 | MODULE_AUTHOR("Dvorkin Dmitry <dvorkin@tibbo.com>" ); |
1125 | MODULE_AUTHOR("Wells Lu <wellslutw@gmail.com>" ); |
1126 | MODULE_DESCRIPTION("Sunplus SP7021 Pin Control and GPIO driver" ); |
1127 | MODULE_LICENSE("GPL v2" ); |
1128 | |