1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Combined GPIO and pin controller support for Renesas RZ/A2 (R7S9210) SoC |
4 | * |
5 | * Copyright (C) 2018 Chris Brandt |
6 | */ |
7 | |
8 | /* |
9 | * This pin controller/gpio combined driver supports Renesas devices of RZ/A2 |
10 | * family. |
11 | */ |
12 | |
13 | #include <linux/bitops.h> |
14 | #include <linux/gpio/driver.h> |
15 | #include <linux/io.h> |
16 | #include <linux/module.h> |
17 | #include <linux/mutex.h> |
18 | #include <linux/of.h> |
19 | #include <linux/pinctrl/pinmux.h> |
20 | #include <linux/platform_device.h> |
21 | |
22 | #include "../core.h" |
23 | #include "../pinmux.h" |
24 | |
25 | #define DRIVER_NAME "pinctrl-rza2" |
26 | |
27 | #define RZA2_PINS_PER_PORT 8 |
28 | #define RZA2_PIN_ID_TO_PORT(id) ((id) / RZA2_PINS_PER_PORT) |
29 | #define RZA2_PIN_ID_TO_PIN(id) ((id) % RZA2_PINS_PER_PORT) |
30 | |
31 | /* |
32 | * Use 16 lower bits [15:0] for pin identifier |
33 | * Use 16 higher bits [31:16] for pin mux function |
34 | */ |
35 | #define MUX_PIN_ID_MASK GENMASK(15, 0) |
36 | #define MUX_FUNC_MASK GENMASK(31, 16) |
37 | #define MUX_FUNC_OFFS 16 |
38 | #define MUX_FUNC(pinconf) ((pinconf & MUX_FUNC_MASK) >> MUX_FUNC_OFFS) |
39 | |
40 | static const char port_names[] = "0123456789ABCDEFGHJKLM" ; |
41 | |
42 | struct rza2_pinctrl_priv { |
43 | struct device *dev; |
44 | void __iomem *base; |
45 | |
46 | struct pinctrl_pin_desc *pins; |
47 | struct pinctrl_desc desc; |
48 | struct pinctrl_dev *pctl; |
49 | struct pinctrl_gpio_range gpio_range; |
50 | int npins; |
51 | struct mutex mutex; /* serialize adding groups and functions */ |
52 | }; |
53 | |
54 | #define RZA2_PDR(port) (0x0000 + (port) * 2) /* Direction 16-bit */ |
55 | #define RZA2_PODR(port) (0x0040 + (port)) /* Output Data 8-bit */ |
56 | #define RZA2_PIDR(port) (0x0060 + (port)) /* Input Data 8-bit */ |
57 | #define RZA2_PMR(port) (0x0080 + (port)) /* Mode 8-bit */ |
58 | #define RZA2_DSCR(port) (0x0140 + (port) * 2) /* Drive 16-bit */ |
59 | #define RZA2_PFS(port, pin) (0x0200 + ((port) * 8) + (pin)) /* Fnct 8-bit */ |
60 | |
61 | #define RZA2_PWPR 0x02ff /* Write Protect 8-bit */ |
62 | #define RZA2_PFENET 0x0820 /* Ethernet Pins 8-bit */ |
63 | #define RZA2_PPOC 0x0900 /* Dedicated Pins 32-bit */ |
64 | #define RZA2_PHMOMO 0x0980 /* Peripheral Pins 32-bit */ |
65 | #define RZA2_PCKIO 0x09d0 /* CKIO Drive 8-bit */ |
66 | |
67 | #define RZA2_PDR_INPUT 0x02 |
68 | #define RZA2_PDR_OUTPUT 0x03 |
69 | #define RZA2_PDR_MASK 0x03 |
70 | |
71 | #define PWPR_B0WI BIT(7) /* Bit Write Disable */ |
72 | #define PWPR_PFSWE BIT(6) /* PFS Register Write Enable */ |
73 | #define PFS_ISEL BIT(6) /* Interrupt Select */ |
74 | |
75 | static void rza2_set_pin_function(void __iomem *pfc_base, u8 port, u8 pin, |
76 | u8 func) |
77 | { |
78 | u16 mask16; |
79 | u16 reg16; |
80 | u8 reg8; |
81 | |
82 | /* Set pin to 'Non-use (Hi-z input protection)' */ |
83 | reg16 = readw(addr: pfc_base + RZA2_PDR(port)); |
84 | mask16 = RZA2_PDR_MASK << (pin * 2); |
85 | reg16 &= ~mask16; |
86 | writew(val: reg16, addr: pfc_base + RZA2_PDR(port)); |
87 | |
88 | /* Temporarily switch to GPIO */ |
89 | reg8 = readb(addr: pfc_base + RZA2_PMR(port)); |
90 | reg8 &= ~BIT(pin); |
91 | writeb(val: reg8, addr: pfc_base + RZA2_PMR(port)); |
92 | |
93 | /* PFS Register Write Protect : OFF */ |
94 | writeb(val: 0x00, addr: pfc_base + RZA2_PWPR); /* B0WI=0, PFSWE=0 */ |
95 | writeb(PWPR_PFSWE, addr: pfc_base + RZA2_PWPR); /* B0WI=0, PFSWE=1 */ |
96 | |
97 | /* Set Pin function (interrupt disabled, ISEL=0) */ |
98 | writeb(val: func, addr: pfc_base + RZA2_PFS(port, pin)); |
99 | |
100 | /* PFS Register Write Protect : ON */ |
101 | writeb(val: 0x00, addr: pfc_base + RZA2_PWPR); /* B0WI=0, PFSWE=0 */ |
102 | writeb(val: 0x80, addr: pfc_base + RZA2_PWPR); /* B0WI=1, PFSWE=0 */ |
103 | |
104 | /* Port Mode : Peripheral module pin functions */ |
105 | reg8 = readb(addr: pfc_base + RZA2_PMR(port)); |
106 | reg8 |= BIT(pin); |
107 | writeb(val: reg8, addr: pfc_base + RZA2_PMR(port)); |
108 | } |
109 | |
110 | static void rza2_pin_to_gpio(void __iomem *pfc_base, unsigned int offset, |
111 | u8 dir) |
112 | { |
113 | u8 port = RZA2_PIN_ID_TO_PORT(offset); |
114 | u8 pin = RZA2_PIN_ID_TO_PIN(offset); |
115 | u16 mask16; |
116 | u16 reg16; |
117 | |
118 | reg16 = readw(addr: pfc_base + RZA2_PDR(port)); |
119 | mask16 = RZA2_PDR_MASK << (pin * 2); |
120 | reg16 &= ~mask16; |
121 | |
122 | if (dir) |
123 | reg16 |= RZA2_PDR_INPUT << (pin * 2); /* pin as input */ |
124 | else |
125 | reg16 |= RZA2_PDR_OUTPUT << (pin * 2); /* pin as output */ |
126 | |
127 | writew(val: reg16, addr: pfc_base + RZA2_PDR(port)); |
128 | } |
129 | |
130 | static int rza2_chip_get_direction(struct gpio_chip *chip, unsigned int offset) |
131 | { |
132 | struct rza2_pinctrl_priv *priv = gpiochip_get_data(gc: chip); |
133 | u8 port = RZA2_PIN_ID_TO_PORT(offset); |
134 | u8 pin = RZA2_PIN_ID_TO_PIN(offset); |
135 | u16 reg16; |
136 | |
137 | reg16 = readw(addr: priv->base + RZA2_PDR(port)); |
138 | reg16 = (reg16 >> (pin * 2)) & RZA2_PDR_MASK; |
139 | |
140 | if (reg16 == RZA2_PDR_OUTPUT) |
141 | return GPIO_LINE_DIRECTION_OUT; |
142 | |
143 | if (reg16 == RZA2_PDR_INPUT) |
144 | return GPIO_LINE_DIRECTION_IN; |
145 | |
146 | /* |
147 | * This GPIO controller has a default Hi-Z state that is not input or |
148 | * output, so force the pin to input now. |
149 | */ |
150 | rza2_pin_to_gpio(pfc_base: priv->base, offset, dir: 1); |
151 | |
152 | return GPIO_LINE_DIRECTION_IN; |
153 | } |
154 | |
155 | static int rza2_chip_direction_input(struct gpio_chip *chip, |
156 | unsigned int offset) |
157 | { |
158 | struct rza2_pinctrl_priv *priv = gpiochip_get_data(gc: chip); |
159 | |
160 | rza2_pin_to_gpio(pfc_base: priv->base, offset, dir: 1); |
161 | |
162 | return 0; |
163 | } |
164 | |
165 | static int rza2_chip_get(struct gpio_chip *chip, unsigned int offset) |
166 | { |
167 | struct rza2_pinctrl_priv *priv = gpiochip_get_data(gc: chip); |
168 | u8 port = RZA2_PIN_ID_TO_PORT(offset); |
169 | u8 pin = RZA2_PIN_ID_TO_PIN(offset); |
170 | |
171 | return !!(readb(addr: priv->base + RZA2_PIDR(port)) & BIT(pin)); |
172 | } |
173 | |
174 | static void rza2_chip_set(struct gpio_chip *chip, unsigned int offset, |
175 | int value) |
176 | { |
177 | struct rza2_pinctrl_priv *priv = gpiochip_get_data(gc: chip); |
178 | u8 port = RZA2_PIN_ID_TO_PORT(offset); |
179 | u8 pin = RZA2_PIN_ID_TO_PIN(offset); |
180 | u8 new_value; |
181 | |
182 | new_value = readb(addr: priv->base + RZA2_PODR(port)); |
183 | |
184 | if (value) |
185 | new_value |= BIT(pin); |
186 | else |
187 | new_value &= ~BIT(pin); |
188 | |
189 | writeb(val: new_value, addr: priv->base + RZA2_PODR(port)); |
190 | } |
191 | |
192 | static int rza2_chip_direction_output(struct gpio_chip *chip, |
193 | unsigned int offset, int val) |
194 | { |
195 | struct rza2_pinctrl_priv *priv = gpiochip_get_data(gc: chip); |
196 | |
197 | rza2_chip_set(chip, offset, value: val); |
198 | rza2_pin_to_gpio(pfc_base: priv->base, offset, dir: 0); |
199 | |
200 | return 0; |
201 | } |
202 | |
203 | static const char * const rza2_gpio_names[] = { |
204 | "P0_0" , "P0_1" , "P0_2" , "P0_3" , "P0_4" , "P0_5" , "P0_6" , "P0_7" , |
205 | "P1_0" , "P1_1" , "P1_2" , "P1_3" , "P1_4" , "P1_5" , "P1_6" , "P1_7" , |
206 | "P2_0" , "P2_1" , "P2_2" , "P2_3" , "P2_4" , "P2_5" , "P2_6" , "P2_7" , |
207 | "P3_0" , "P3_1" , "P3_2" , "P3_3" , "P3_4" , "P3_5" , "P3_6" , "P3_7" , |
208 | "P4_0" , "P4_1" , "P4_2" , "P4_3" , "P4_4" , "P4_5" , "P4_6" , "P4_7" , |
209 | "P5_0" , "P5_1" , "P5_2" , "P5_3" , "P5_4" , "P5_5" , "P5_6" , "P5_7" , |
210 | "P6_0" , "P6_1" , "P6_2" , "P6_3" , "P6_4" , "P6_5" , "P6_6" , "P6_7" , |
211 | "P7_0" , "P7_1" , "P7_2" , "P7_3" , "P7_4" , "P7_5" , "P7_6" , "P7_7" , |
212 | "P8_0" , "P8_1" , "P8_2" , "P8_3" , "P8_4" , "P8_5" , "P8_6" , "P8_7" , |
213 | "P9_0" , "P9_1" , "P9_2" , "P9_3" , "P9_4" , "P9_5" , "P9_6" , "P9_7" , |
214 | "PA_0" , "PA_1" , "PA_2" , "PA_3" , "PA_4" , "PA_5" , "PA_6" , "PA_7" , |
215 | "PB_0" , "PB_1" , "PB_2" , "PB_3" , "PB_4" , "PB_5" , "PB_6" , "PB_7" , |
216 | "PC_0" , "PC_1" , "PC_2" , "PC_3" , "PC_4" , "PC_5" , "PC_6" , "PC_7" , |
217 | "PD_0" , "PD_1" , "PD_2" , "PD_3" , "PD_4" , "PD_5" , "PD_6" , "PD_7" , |
218 | "PE_0" , "PE_1" , "PE_2" , "PE_3" , "PE_4" , "PE_5" , "PE_6" , "PE_7" , |
219 | "PF_0" , "PF_1" , "PF_2" , "PF_3" , "PF_4" , "PF_5" , "PF_6" , "PF_7" , |
220 | "PG_0" , "PG_1" , "PG_2" , "PG_3" , "PG_4" , "PG_5" , "PG_6" , "PG_7" , |
221 | "PH_0" , "PH_1" , "PH_2" , "PH_3" , "PH_4" , "PH_5" , "PH_6" , "PH_7" , |
222 | /* port I does not exist */ |
223 | "PJ_0" , "PJ_1" , "PJ_2" , "PJ_3" , "PJ_4" , "PJ_5" , "PJ_6" , "PJ_7" , |
224 | "PK_0" , "PK_1" , "PK_2" , "PK_3" , "PK_4" , "PK_5" , "PK_6" , "PK_7" , |
225 | "PL_0" , "PL_1" , "PL_2" , "PL_3" , "PL_4" , "PL_5" , "PL_6" , "PL_7" , |
226 | "PM_0" , "PM_1" , "PM_2" , "PM_3" , "PM_4" , "PM_5" , "PM_6" , "PM_7" , |
227 | }; |
228 | |
229 | static struct gpio_chip chip = { |
230 | .names = rza2_gpio_names, |
231 | .base = -1, |
232 | .get_direction = rza2_chip_get_direction, |
233 | .direction_input = rza2_chip_direction_input, |
234 | .direction_output = rza2_chip_direction_output, |
235 | .get = rza2_chip_get, |
236 | .set = rza2_chip_set, |
237 | }; |
238 | |
239 | static int rza2_gpio_register(struct rza2_pinctrl_priv *priv) |
240 | { |
241 | struct device_node *np = priv->dev->of_node; |
242 | struct of_phandle_args of_args; |
243 | int ret; |
244 | |
245 | chip.label = devm_kasprintf(dev: priv->dev, GFP_KERNEL, fmt: "%pOFn" , np); |
246 | chip.parent = priv->dev; |
247 | chip.ngpio = priv->npins; |
248 | |
249 | ret = of_parse_phandle_with_fixed_args(np, list_name: "gpio-ranges" , cell_count: 3, index: 0, |
250 | out_args: &of_args); |
251 | if (ret) { |
252 | dev_err(priv->dev, "Unable to parse gpio-ranges\n" ); |
253 | return ret; |
254 | } |
255 | |
256 | if ((of_args.args[0] != 0) || |
257 | (of_args.args[1] != 0) || |
258 | (of_args.args[2] != priv->npins)) { |
259 | dev_err(priv->dev, "gpio-ranges does not match selected SOC\n" ); |
260 | return -EINVAL; |
261 | } |
262 | priv->gpio_range.id = 0; |
263 | priv->gpio_range.pin_base = priv->gpio_range.base = 0; |
264 | priv->gpio_range.npins = priv->npins; |
265 | priv->gpio_range.name = chip.label; |
266 | priv->gpio_range.gc = &chip; |
267 | |
268 | /* Register our gpio chip with gpiolib */ |
269 | ret = devm_gpiochip_add_data(priv->dev, &chip, priv); |
270 | if (ret) |
271 | return ret; |
272 | |
273 | /* Register pin range with pinctrl core */ |
274 | pinctrl_add_gpio_range(pctldev: priv->pctl, range: &priv->gpio_range); |
275 | |
276 | dev_dbg(priv->dev, "Registered gpio controller\n" ); |
277 | |
278 | return 0; |
279 | } |
280 | |
281 | static int rza2_pinctrl_register(struct rza2_pinctrl_priv *priv) |
282 | { |
283 | struct pinctrl_pin_desc *pins; |
284 | unsigned int i; |
285 | int ret; |
286 | |
287 | pins = devm_kcalloc(dev: priv->dev, n: priv->npins, size: sizeof(*pins), GFP_KERNEL); |
288 | if (!pins) |
289 | return -ENOMEM; |
290 | |
291 | priv->pins = pins; |
292 | priv->desc.pins = pins; |
293 | priv->desc.npins = priv->npins; |
294 | |
295 | for (i = 0; i < priv->npins; i++) { |
296 | pins[i].number = i; |
297 | pins[i].name = rza2_gpio_names[i]; |
298 | } |
299 | |
300 | ret = devm_pinctrl_register_and_init(dev: priv->dev, pctldesc: &priv->desc, driver_data: priv, |
301 | pctldev: &priv->pctl); |
302 | if (ret) { |
303 | dev_err(priv->dev, "pinctrl registration failed\n" ); |
304 | return ret; |
305 | } |
306 | |
307 | ret = pinctrl_enable(pctldev: priv->pctl); |
308 | if (ret) { |
309 | dev_err(priv->dev, "pinctrl enable failed\n" ); |
310 | return ret; |
311 | } |
312 | |
313 | ret = rza2_gpio_register(priv); |
314 | if (ret) { |
315 | dev_err(priv->dev, "GPIO registration failed\n" ); |
316 | return ret; |
317 | } |
318 | |
319 | return 0; |
320 | } |
321 | |
322 | /* |
323 | * For each DT node, create a single pin mapping. That pin mapping will only |
324 | * contain a single group of pins, and that group of pins will only have a |
325 | * single function that can be selected. |
326 | */ |
327 | static int rza2_dt_node_to_map(struct pinctrl_dev *pctldev, |
328 | struct device_node *np, |
329 | struct pinctrl_map **map, |
330 | unsigned int *num_maps) |
331 | { |
332 | struct rza2_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev); |
333 | unsigned int *pins, *psel_val; |
334 | int i, ret, npins, gsel, fsel; |
335 | struct property *of_pins; |
336 | const char **pin_fn; |
337 | |
338 | /* Find out how many pins to map */ |
339 | of_pins = of_find_property(np, name: "pinmux" , NULL); |
340 | if (!of_pins) { |
341 | dev_info(priv->dev, "Missing pinmux property\n" ); |
342 | return -ENOENT; |
343 | } |
344 | npins = of_pins->length / sizeof(u32); |
345 | |
346 | pins = devm_kcalloc(dev: priv->dev, n: npins, size: sizeof(*pins), GFP_KERNEL); |
347 | psel_val = devm_kcalloc(dev: priv->dev, n: npins, size: sizeof(*psel_val), |
348 | GFP_KERNEL); |
349 | pin_fn = devm_kzalloc(dev: priv->dev, size: sizeof(*pin_fn), GFP_KERNEL); |
350 | if (!pins || !psel_val || !pin_fn) |
351 | return -ENOMEM; |
352 | |
353 | /* Collect pin locations and mux settings from DT properties */ |
354 | for (i = 0; i < npins; ++i) { |
355 | u32 value; |
356 | |
357 | ret = of_property_read_u32_index(np, propname: "pinmux" , index: i, out_value: &value); |
358 | if (ret) |
359 | return ret; |
360 | pins[i] = value & MUX_PIN_ID_MASK; |
361 | psel_val[i] = MUX_FUNC(value); |
362 | } |
363 | |
364 | mutex_lock(&priv->mutex); |
365 | |
366 | /* Register a single pin group listing all the pins we read from DT */ |
367 | gsel = pinctrl_generic_add_group(pctldev, name: np->name, pins, num_pins: npins, NULL); |
368 | if (gsel < 0) { |
369 | ret = gsel; |
370 | goto unlock; |
371 | } |
372 | |
373 | /* |
374 | * Register a single group function where the 'data' is an array PSEL |
375 | * register values read from DT. |
376 | */ |
377 | pin_fn[0] = np->name; |
378 | fsel = pinmux_generic_add_function(pctldev, name: np->name, groups: pin_fn, num_groups: 1, |
379 | data: psel_val); |
380 | if (fsel < 0) { |
381 | ret = fsel; |
382 | goto remove_group; |
383 | } |
384 | |
385 | dev_dbg(priv->dev, "Parsed %pOF with %d pins\n" , np, npins); |
386 | |
387 | /* Create map where to retrieve function and mux settings from */ |
388 | *num_maps = 0; |
389 | *map = kzalloc(size: sizeof(**map), GFP_KERNEL); |
390 | if (!*map) { |
391 | ret = -ENOMEM; |
392 | goto remove_function; |
393 | } |
394 | |
395 | (*map)->type = PIN_MAP_TYPE_MUX_GROUP; |
396 | (*map)->data.mux.group = np->name; |
397 | (*map)->data.mux.function = np->name; |
398 | *num_maps = 1; |
399 | |
400 | mutex_unlock(lock: &priv->mutex); |
401 | |
402 | return 0; |
403 | |
404 | remove_function: |
405 | pinmux_generic_remove_function(pctldev, selector: fsel); |
406 | |
407 | remove_group: |
408 | pinctrl_generic_remove_group(pctldev, group_selector: gsel); |
409 | |
410 | unlock: |
411 | mutex_unlock(lock: &priv->mutex); |
412 | |
413 | dev_err(priv->dev, "Unable to parse DT node %s\n" , np->name); |
414 | |
415 | return ret; |
416 | } |
417 | |
418 | static void rza2_dt_free_map(struct pinctrl_dev *pctldev, |
419 | struct pinctrl_map *map, unsigned int num_maps) |
420 | { |
421 | kfree(objp: map); |
422 | } |
423 | |
424 | static const struct pinctrl_ops rza2_pinctrl_ops = { |
425 | .get_groups_count = pinctrl_generic_get_group_count, |
426 | .get_group_name = pinctrl_generic_get_group_name, |
427 | .get_group_pins = pinctrl_generic_get_group_pins, |
428 | .dt_node_to_map = rza2_dt_node_to_map, |
429 | .dt_free_map = rza2_dt_free_map, |
430 | }; |
431 | |
432 | static int rza2_set_mux(struct pinctrl_dev *pctldev, unsigned int selector, |
433 | unsigned int group) |
434 | { |
435 | struct rza2_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev); |
436 | struct function_desc *func; |
437 | unsigned int i, *psel_val; |
438 | struct group_desc *grp; |
439 | |
440 | grp = pinctrl_generic_get_group(pctldev, group_selector: group); |
441 | if (!grp) |
442 | return -EINVAL; |
443 | |
444 | func = pinmux_generic_get_function(pctldev, selector); |
445 | if (!func) |
446 | return -EINVAL; |
447 | |
448 | psel_val = func->data; |
449 | |
450 | for (i = 0; i < grp->grp.npins; ++i) { |
451 | dev_dbg(priv->dev, "Setting P%c_%d to PSEL=%d\n" , |
452 | port_names[RZA2_PIN_ID_TO_PORT(grp->grp.pins[i])], |
453 | RZA2_PIN_ID_TO_PIN(grp->grp.pins[i]), |
454 | psel_val[i]); |
455 | rza2_set_pin_function( |
456 | pfc_base: priv->base, |
457 | RZA2_PIN_ID_TO_PORT(grp->grp.pins[i]), |
458 | RZA2_PIN_ID_TO_PIN(grp->grp.pins[i]), |
459 | func: psel_val[i]); |
460 | } |
461 | |
462 | return 0; |
463 | } |
464 | |
465 | static const struct pinmux_ops rza2_pinmux_ops = { |
466 | .get_functions_count = pinmux_generic_get_function_count, |
467 | .get_function_name = pinmux_generic_get_function_name, |
468 | .get_function_groups = pinmux_generic_get_function_groups, |
469 | .set_mux = rza2_set_mux, |
470 | .strict = true, |
471 | }; |
472 | |
473 | static int rza2_pinctrl_probe(struct platform_device *pdev) |
474 | { |
475 | struct rza2_pinctrl_priv *priv; |
476 | int ret; |
477 | |
478 | priv = devm_kzalloc(dev: &pdev->dev, size: sizeof(*priv), GFP_KERNEL); |
479 | if (!priv) |
480 | return -ENOMEM; |
481 | |
482 | priv->dev = &pdev->dev; |
483 | |
484 | priv->base = devm_platform_ioremap_resource(pdev, index: 0); |
485 | if (IS_ERR(ptr: priv->base)) |
486 | return PTR_ERR(ptr: priv->base); |
487 | |
488 | mutex_init(&priv->mutex); |
489 | |
490 | platform_set_drvdata(pdev, data: priv); |
491 | |
492 | priv->npins = (int)(uintptr_t)of_device_get_match_data(dev: &pdev->dev) * |
493 | RZA2_PINS_PER_PORT; |
494 | |
495 | priv->desc.name = DRIVER_NAME; |
496 | priv->desc.pctlops = &rza2_pinctrl_ops; |
497 | priv->desc.pmxops = &rza2_pinmux_ops; |
498 | priv->desc.owner = THIS_MODULE; |
499 | |
500 | ret = rza2_pinctrl_register(priv); |
501 | if (ret) |
502 | return ret; |
503 | |
504 | dev_info(&pdev->dev, "Registered ports P0 - P%c\n" , |
505 | port_names[priv->desc.npins / RZA2_PINS_PER_PORT - 1]); |
506 | |
507 | return 0; |
508 | } |
509 | |
510 | static const struct of_device_id rza2_pinctrl_of_match[] = { |
511 | { .compatible = "renesas,r7s9210-pinctrl" , .data = (void *)22, }, |
512 | { /* sentinel */ } |
513 | }; |
514 | |
515 | static struct platform_driver rza2_pinctrl_driver = { |
516 | .driver = { |
517 | .name = DRIVER_NAME, |
518 | .of_match_table = rza2_pinctrl_of_match, |
519 | }, |
520 | .probe = rza2_pinctrl_probe, |
521 | }; |
522 | |
523 | static int __init rza2_pinctrl_init(void) |
524 | { |
525 | return platform_driver_register(&rza2_pinctrl_driver); |
526 | } |
527 | core_initcall(rza2_pinctrl_init); |
528 | |
529 | MODULE_AUTHOR("Chris Brandt <chris.brandt@renesas.com>" ); |
530 | MODULE_DESCRIPTION("Pin and gpio controller driver for RZ/A2 SoC" ); |
531 | |