1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Renesas RZ/V2M Pin Control and GPIO driver core |
4 | * |
5 | * Based on: |
6 | * Renesas RZ/G2L Pin Control and GPIO driver core |
7 | * |
8 | * Copyright (C) 2022 Renesas Electronics Corporation. |
9 | */ |
10 | |
11 | #include <linux/bitfield.h> |
12 | #include <linux/bitops.h> |
13 | #include <linux/clk.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/platform_device.h> |
20 | #include <linux/spinlock.h> |
21 | |
22 | #include <linux/pinctrl/consumer.h> |
23 | #include <linux/pinctrl/pinconf-generic.h> |
24 | #include <linux/pinctrl/pinconf.h> |
25 | #include <linux/pinctrl/pinctrl.h> |
26 | #include <linux/pinctrl/pinmux.h> |
27 | |
28 | #include <dt-bindings/pinctrl/rzv2m-pinctrl.h> |
29 | |
30 | #include "../core.h" |
31 | #include "../pinconf.h" |
32 | #include "../pinmux.h" |
33 | |
34 | #define DRV_NAME "pinctrl-rzv2m" |
35 | |
36 | /* |
37 | * Use 16 lower bits [15:0] for pin identifier |
38 | * Use 16 higher bits [31:16] for pin mux function |
39 | */ |
40 | #define MUX_PIN_ID_MASK GENMASK(15, 0) |
41 | #define MUX_FUNC_MASK GENMASK(31, 16) |
42 | #define MUX_FUNC(pinconf) FIELD_GET(MUX_FUNC_MASK, (pinconf)) |
43 | |
44 | /* PIN capabilities */ |
45 | #define PIN_CFG_GRP_1_8V_2 1 |
46 | #define PIN_CFG_GRP_1_8V_3 2 |
47 | #define PIN_CFG_GRP_SWIO_1 3 |
48 | #define PIN_CFG_GRP_SWIO_2 4 |
49 | #define PIN_CFG_GRP_3_3V 5 |
50 | #define PIN_CFG_GRP_MASK GENMASK(2, 0) |
51 | #define PIN_CFG_BIAS BIT(3) |
52 | #define PIN_CFG_DRV BIT(4) |
53 | #define PIN_CFG_SLEW BIT(5) |
54 | |
55 | #define RZV2M_MPXED_PIN_FUNCS (PIN_CFG_BIAS | \ |
56 | PIN_CFG_DRV | \ |
57 | PIN_CFG_SLEW) |
58 | |
59 | /* |
60 | * n indicates number of pins in the port, a is the register index |
61 | * and f is pin configuration capabilities supported. |
62 | */ |
63 | #define RZV2M_GPIO_PORT_PACK(n, a, f) (((n) << 24) | ((a) << 16) | (f)) |
64 | #define RZV2M_GPIO_PORT_GET_PINCNT(x) FIELD_GET(GENMASK(31, 24), (x)) |
65 | #define RZV2M_GPIO_PORT_GET_INDEX(x) FIELD_GET(GENMASK(23, 16), (x)) |
66 | #define RZV2M_GPIO_PORT_GET_CFGS(x) FIELD_GET(GENMASK(15, 0), (x)) |
67 | |
68 | #define RZV2M_DEDICATED_PORT_IDX 22 |
69 | |
70 | /* |
71 | * BIT(31) indicates dedicated pin, b is the register bits (b * 16) |
72 | * and f is the pin configuration capabilities supported. |
73 | */ |
74 | #define RZV2M_SINGLE_PIN BIT(31) |
75 | #define RZV2M_SINGLE_PIN_PACK(b, f) (RZV2M_SINGLE_PIN | \ |
76 | ((RZV2M_DEDICATED_PORT_IDX) << 24) | \ |
77 | ((b) << 16) | (f)) |
78 | #define RZV2M_SINGLE_PIN_GET_PORT(x) FIELD_GET(GENMASK(30, 24), (x)) |
79 | #define RZV2M_SINGLE_PIN_GET_BIT(x) FIELD_GET(GENMASK(23, 16), (x)) |
80 | #define RZV2M_SINGLE_PIN_GET_CFGS(x) FIELD_GET(GENMASK(15, 0), (x)) |
81 | |
82 | #define RZV2M_PIN_ID_TO_PORT(id) ((id) / RZV2M_PINS_PER_PORT) |
83 | #define RZV2M_PIN_ID_TO_PIN(id) ((id) % RZV2M_PINS_PER_PORT) |
84 | |
85 | #define DO(n) (0x00 + (n) * 0x40) |
86 | #define OE(n) (0x04 + (n) * 0x40) |
87 | #define IE(n) (0x08 + (n) * 0x40) |
88 | #define PFSEL(n) (0x10 + (n) * 0x40) |
89 | #define DI(n) (0x20 + (n) * 0x40) |
90 | #define PUPD(n) (0x24 + (n) * 0x40) |
91 | #define DRV(n) ((n) < RZV2M_DEDICATED_PORT_IDX ? (0x28 + (n) * 0x40) \ |
92 | : 0x590) |
93 | #define SR(n) ((n) < RZV2M_DEDICATED_PORT_IDX ? (0x2c + (n) * 0x40) \ |
94 | : 0x594) |
95 | #define DI_MSK(n) (0x30 + (n) * 0x40) |
96 | #define EN_MSK(n) (0x34 + (n) * 0x40) |
97 | |
98 | #define PFC_MASK 0x07 |
99 | #define PUPD_MASK 0x03 |
100 | #define DRV_MASK 0x03 |
101 | |
102 | struct rzv2m_dedicated_configs { |
103 | const char *name; |
104 | u32 config; |
105 | }; |
106 | |
107 | struct rzv2m_pinctrl_data { |
108 | const char * const *port_pins; |
109 | const u32 *port_pin_configs; |
110 | const struct rzv2m_dedicated_configs *dedicated_pins; |
111 | unsigned int n_port_pins; |
112 | unsigned int n_dedicated_pins; |
113 | }; |
114 | |
115 | struct rzv2m_pinctrl { |
116 | struct pinctrl_dev *pctl; |
117 | struct pinctrl_desc desc; |
118 | struct pinctrl_pin_desc *pins; |
119 | |
120 | const struct rzv2m_pinctrl_data *data; |
121 | void __iomem *base; |
122 | struct device *dev; |
123 | |
124 | struct gpio_chip gpio_chip; |
125 | struct pinctrl_gpio_range gpio_range; |
126 | |
127 | spinlock_t lock; /* lock read/write registers */ |
128 | struct mutex mutex; /* serialize adding groups and functions */ |
129 | }; |
130 | |
131 | static const unsigned int drv_1_8V_group2_uA[] = { 1800, 3800, 7800, 11000 }; |
132 | static const unsigned int drv_1_8V_group3_uA[] = { 1600, 3200, 6400, 9600 }; |
133 | static const unsigned int drv_SWIO_group2_3_3V_uA[] = { 9000, 11000, 13000, 18000 }; |
134 | static const unsigned int drv_3_3V_group_uA[] = { 2000, 4000, 8000, 12000 }; |
135 | |
136 | /* Helper for registers that have a write enable bit in the upper word */ |
137 | static void rzv2m_writel_we(void __iomem *addr, u8 shift, u8 value) |
138 | { |
139 | writel(val: (BIT(16) | value) << shift, addr); |
140 | } |
141 | |
142 | static void rzv2m_pinctrl_set_pfc_mode(struct rzv2m_pinctrl *pctrl, |
143 | u8 port, u8 pin, u8 func) |
144 | { |
145 | void __iomem *addr; |
146 | |
147 | /* Mask input/output */ |
148 | rzv2m_writel_we(addr: pctrl->base + DI_MSK(port), shift: pin, value: 1); |
149 | rzv2m_writel_we(addr: pctrl->base + EN_MSK(port), shift: pin, value: 1); |
150 | |
151 | /* Select the function and set the write enable bits */ |
152 | addr = pctrl->base + PFSEL(port) + (pin / 4) * 4; |
153 | writel(val: ((PFC_MASK << 16) | func) << ((pin % 4) * 4), addr); |
154 | |
155 | /* Unmask input/output */ |
156 | rzv2m_writel_we(addr: pctrl->base + EN_MSK(port), shift: pin, value: 0); |
157 | rzv2m_writel_we(addr: pctrl->base + DI_MSK(port), shift: pin, value: 0); |
158 | }; |
159 | |
160 | static int rzv2m_pinctrl_set_mux(struct pinctrl_dev *pctldev, |
161 | unsigned int func_selector, |
162 | unsigned int group_selector) |
163 | { |
164 | struct rzv2m_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); |
165 | struct function_desc *func; |
166 | unsigned int i, *psel_val; |
167 | struct group_desc *group; |
168 | const unsigned int *pins; |
169 | |
170 | func = pinmux_generic_get_function(pctldev, selector: func_selector); |
171 | if (!func) |
172 | return -EINVAL; |
173 | group = pinctrl_generic_get_group(pctldev, group_selector); |
174 | if (!group) |
175 | return -EINVAL; |
176 | |
177 | psel_val = func->data; |
178 | pins = group->grp.pins; |
179 | |
180 | for (i = 0; i < group->grp.npins; i++) { |
181 | dev_dbg(pctrl->dev, "port:%u pin: %u PSEL:%u\n" , |
182 | RZV2M_PIN_ID_TO_PORT(pins[i]), RZV2M_PIN_ID_TO_PIN(pins[i]), |
183 | psel_val[i]); |
184 | rzv2m_pinctrl_set_pfc_mode(pctrl, RZV2M_PIN_ID_TO_PORT(pins[i]), |
185 | RZV2M_PIN_ID_TO_PIN(pins[i]), func: psel_val[i]); |
186 | } |
187 | |
188 | return 0; |
189 | }; |
190 | |
191 | static int rzv2m_map_add_config(struct pinctrl_map *map, |
192 | const char *group_or_pin, |
193 | enum pinctrl_map_type type, |
194 | unsigned long *configs, |
195 | unsigned int num_configs) |
196 | { |
197 | unsigned long *cfgs; |
198 | |
199 | cfgs = kmemdup(p: configs, size: num_configs * sizeof(*cfgs), |
200 | GFP_KERNEL); |
201 | if (!cfgs) |
202 | return -ENOMEM; |
203 | |
204 | map->type = type; |
205 | map->data.configs.group_or_pin = group_or_pin; |
206 | map->data.configs.configs = cfgs; |
207 | map->data.configs.num_configs = num_configs; |
208 | |
209 | return 0; |
210 | } |
211 | |
212 | static int rzv2m_dt_subnode_to_map(struct pinctrl_dev *pctldev, |
213 | struct device_node *np, |
214 | struct device_node *parent, |
215 | struct pinctrl_map **map, |
216 | unsigned int *num_maps, |
217 | unsigned int *index) |
218 | { |
219 | struct rzv2m_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); |
220 | struct pinctrl_map *maps = *map; |
221 | unsigned int nmaps = *num_maps; |
222 | unsigned long *configs = NULL; |
223 | unsigned int *pins, *psel_val; |
224 | unsigned int num_pinmux = 0; |
225 | unsigned int idx = *index; |
226 | unsigned int num_pins, i; |
227 | unsigned int num_configs; |
228 | struct property *pinmux; |
229 | struct property *prop; |
230 | int ret, gsel, fsel; |
231 | const char **pin_fn; |
232 | const char *name; |
233 | const char *pin; |
234 | |
235 | pinmux = of_find_property(np, name: "pinmux" , NULL); |
236 | if (pinmux) |
237 | num_pinmux = pinmux->length / sizeof(u32); |
238 | |
239 | ret = of_property_count_strings(np, propname: "pins" ); |
240 | if (ret == -EINVAL) { |
241 | num_pins = 0; |
242 | } else if (ret < 0) { |
243 | dev_err(pctrl->dev, "Invalid pins list in DT\n" ); |
244 | return ret; |
245 | } else { |
246 | num_pins = ret; |
247 | } |
248 | |
249 | if (!num_pinmux && !num_pins) |
250 | return 0; |
251 | |
252 | if (num_pinmux && num_pins) { |
253 | dev_err(pctrl->dev, |
254 | "DT node must contain either a pinmux or pins and not both\n" ); |
255 | return -EINVAL; |
256 | } |
257 | |
258 | ret = pinconf_generic_parse_dt_config(np, NULL, configs: &configs, nconfigs: &num_configs); |
259 | if (ret < 0) |
260 | return ret; |
261 | |
262 | if (num_pins && !num_configs) { |
263 | dev_err(pctrl->dev, "DT node must contain a config\n" ); |
264 | ret = -ENODEV; |
265 | goto done; |
266 | } |
267 | |
268 | if (num_pinmux) |
269 | nmaps += 1; |
270 | |
271 | if (num_pins) |
272 | nmaps += num_pins; |
273 | |
274 | maps = krealloc_array(p: maps, new_n: nmaps, new_size: sizeof(*maps), GFP_KERNEL); |
275 | if (!maps) { |
276 | ret = -ENOMEM; |
277 | goto done; |
278 | } |
279 | |
280 | *map = maps; |
281 | *num_maps = nmaps; |
282 | if (num_pins) { |
283 | of_property_for_each_string(np, "pins" , prop, pin) { |
284 | ret = rzv2m_map_add_config(map: &maps[idx], group_or_pin: pin, |
285 | type: PIN_MAP_TYPE_CONFIGS_PIN, |
286 | configs, num_configs); |
287 | if (ret < 0) |
288 | goto done; |
289 | |
290 | idx++; |
291 | } |
292 | ret = 0; |
293 | goto done; |
294 | } |
295 | |
296 | pins = devm_kcalloc(dev: pctrl->dev, n: num_pinmux, size: sizeof(*pins), GFP_KERNEL); |
297 | psel_val = devm_kcalloc(dev: pctrl->dev, n: num_pinmux, size: sizeof(*psel_val), |
298 | GFP_KERNEL); |
299 | pin_fn = devm_kzalloc(dev: pctrl->dev, size: sizeof(*pin_fn), GFP_KERNEL); |
300 | if (!pins || !psel_val || !pin_fn) { |
301 | ret = -ENOMEM; |
302 | goto done; |
303 | } |
304 | |
305 | /* Collect pin locations and mux settings from DT properties */ |
306 | for (i = 0; i < num_pinmux; ++i) { |
307 | u32 value; |
308 | |
309 | ret = of_property_read_u32_index(np, propname: "pinmux" , index: i, out_value: &value); |
310 | if (ret) |
311 | goto done; |
312 | pins[i] = value & MUX_PIN_ID_MASK; |
313 | psel_val[i] = MUX_FUNC(value); |
314 | } |
315 | |
316 | if (parent) { |
317 | name = devm_kasprintf(dev: pctrl->dev, GFP_KERNEL, fmt: "%pOFn.%pOFn" , |
318 | parent, np); |
319 | if (!name) { |
320 | ret = -ENOMEM; |
321 | goto done; |
322 | } |
323 | } else { |
324 | name = np->name; |
325 | } |
326 | |
327 | mutex_lock(&pctrl->mutex); |
328 | |
329 | /* Register a single pin group listing all the pins we read from DT */ |
330 | gsel = pinctrl_generic_add_group(pctldev, name, pins, num_pins: num_pinmux, NULL); |
331 | if (gsel < 0) { |
332 | ret = gsel; |
333 | goto unlock; |
334 | } |
335 | |
336 | /* |
337 | * Register a single group function where the 'data' is an array PSEL |
338 | * register values read from DT. |
339 | */ |
340 | pin_fn[0] = name; |
341 | fsel = pinmux_generic_add_function(pctldev, name, groups: pin_fn, num_groups: 1, data: psel_val); |
342 | if (fsel < 0) { |
343 | ret = fsel; |
344 | goto remove_group; |
345 | } |
346 | |
347 | mutex_unlock(lock: &pctrl->mutex); |
348 | |
349 | maps[idx].type = PIN_MAP_TYPE_MUX_GROUP; |
350 | maps[idx].data.mux.group = name; |
351 | maps[idx].data.mux.function = name; |
352 | idx++; |
353 | |
354 | dev_dbg(pctrl->dev, "Parsed %pOF with %d pins\n" , np, num_pinmux); |
355 | ret = 0; |
356 | goto done; |
357 | |
358 | remove_group: |
359 | pinctrl_generic_remove_group(pctldev, group_selector: gsel); |
360 | unlock: |
361 | mutex_unlock(lock: &pctrl->mutex); |
362 | done: |
363 | *index = idx; |
364 | kfree(objp: configs); |
365 | return ret; |
366 | } |
367 | |
368 | static void rzv2m_dt_free_map(struct pinctrl_dev *pctldev, |
369 | struct pinctrl_map *map, |
370 | unsigned int num_maps) |
371 | { |
372 | unsigned int i; |
373 | |
374 | if (!map) |
375 | return; |
376 | |
377 | for (i = 0; i < num_maps; ++i) { |
378 | if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP || |
379 | map[i].type == PIN_MAP_TYPE_CONFIGS_PIN) |
380 | kfree(objp: map[i].data.configs.configs); |
381 | } |
382 | kfree(objp: map); |
383 | } |
384 | |
385 | static int rzv2m_dt_node_to_map(struct pinctrl_dev *pctldev, |
386 | struct device_node *np, |
387 | struct pinctrl_map **map, |
388 | unsigned int *num_maps) |
389 | { |
390 | struct rzv2m_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); |
391 | struct device_node *child; |
392 | unsigned int index; |
393 | int ret; |
394 | |
395 | *map = NULL; |
396 | *num_maps = 0; |
397 | index = 0; |
398 | |
399 | for_each_child_of_node(np, child) { |
400 | ret = rzv2m_dt_subnode_to_map(pctldev, np: child, parent: np, map, |
401 | num_maps, index: &index); |
402 | if (ret < 0) { |
403 | of_node_put(node: child); |
404 | goto done; |
405 | } |
406 | } |
407 | |
408 | if (*num_maps == 0) { |
409 | ret = rzv2m_dt_subnode_to_map(pctldev, np, NULL, map, |
410 | num_maps, index: &index); |
411 | if (ret < 0) |
412 | goto done; |
413 | } |
414 | |
415 | if (*num_maps) |
416 | return 0; |
417 | |
418 | dev_err(pctrl->dev, "no mapping found in node %pOF\n" , np); |
419 | ret = -EINVAL; |
420 | |
421 | done: |
422 | rzv2m_dt_free_map(pctldev, map: *map, num_maps: *num_maps); |
423 | |
424 | return ret; |
425 | } |
426 | |
427 | static int rzv2m_validate_gpio_pin(struct rzv2m_pinctrl *pctrl, |
428 | u32 cfg, u32 port, u8 bit) |
429 | { |
430 | u8 pincount = RZV2M_GPIO_PORT_GET_PINCNT(cfg); |
431 | u32 port_index = RZV2M_GPIO_PORT_GET_INDEX(cfg); |
432 | u32 data; |
433 | |
434 | if (bit >= pincount || port >= pctrl->data->n_port_pins) |
435 | return -EINVAL; |
436 | |
437 | data = pctrl->data->port_pin_configs[port]; |
438 | if (port_index != RZV2M_GPIO_PORT_GET_INDEX(data)) |
439 | return -EINVAL; |
440 | |
441 | return 0; |
442 | } |
443 | |
444 | static void rzv2m_rmw_pin_config(struct rzv2m_pinctrl *pctrl, u32 offset, |
445 | u8 shift, u32 mask, u32 val) |
446 | { |
447 | void __iomem *addr = pctrl->base + offset; |
448 | unsigned long flags; |
449 | u32 reg; |
450 | |
451 | spin_lock_irqsave(&pctrl->lock, flags); |
452 | reg = readl(addr) & ~(mask << shift); |
453 | writel(val: reg | (val << shift), addr); |
454 | spin_unlock_irqrestore(lock: &pctrl->lock, flags); |
455 | } |
456 | |
457 | static int rzv2m_pinctrl_pinconf_get(struct pinctrl_dev *pctldev, |
458 | unsigned int _pin, |
459 | unsigned long *config) |
460 | { |
461 | struct rzv2m_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); |
462 | enum pin_config_param param = pinconf_to_config_param(config: *config); |
463 | const struct pinctrl_pin_desc *pin = &pctrl->desc.pins[_pin]; |
464 | unsigned int *pin_data = pin->drv_data; |
465 | unsigned int arg = 0; |
466 | u32 port; |
467 | u32 cfg; |
468 | u8 bit; |
469 | u32 val; |
470 | |
471 | if (!pin_data) |
472 | return -EINVAL; |
473 | |
474 | if (*pin_data & RZV2M_SINGLE_PIN) { |
475 | port = RZV2M_SINGLE_PIN_GET_PORT(*pin_data); |
476 | cfg = RZV2M_SINGLE_PIN_GET_CFGS(*pin_data); |
477 | bit = RZV2M_SINGLE_PIN_GET_BIT(*pin_data); |
478 | } else { |
479 | cfg = RZV2M_GPIO_PORT_GET_CFGS(*pin_data); |
480 | port = RZV2M_PIN_ID_TO_PORT(_pin); |
481 | bit = RZV2M_PIN_ID_TO_PIN(_pin); |
482 | |
483 | if (rzv2m_validate_gpio_pin(pctrl, cfg: *pin_data, RZV2M_PIN_ID_TO_PORT(_pin), bit)) |
484 | return -EINVAL; |
485 | } |
486 | |
487 | switch (param) { |
488 | case PIN_CONFIG_BIAS_DISABLE: |
489 | case PIN_CONFIG_BIAS_PULL_UP: |
490 | case PIN_CONFIG_BIAS_PULL_DOWN: { |
491 | enum pin_config_param bias; |
492 | |
493 | if (!(cfg & PIN_CFG_BIAS)) |
494 | return -EINVAL; |
495 | |
496 | /* PUPD uses 2-bits per pin */ |
497 | bit *= 2; |
498 | |
499 | switch ((readl(addr: pctrl->base + PUPD(port)) >> bit) & PUPD_MASK) { |
500 | case 0: |
501 | bias = PIN_CONFIG_BIAS_PULL_DOWN; |
502 | break; |
503 | case 2: |
504 | bias = PIN_CONFIG_BIAS_PULL_UP; |
505 | break; |
506 | default: |
507 | bias = PIN_CONFIG_BIAS_DISABLE; |
508 | } |
509 | |
510 | if (bias != param) |
511 | return -EINVAL; |
512 | break; |
513 | } |
514 | |
515 | case PIN_CONFIG_DRIVE_STRENGTH_UA: |
516 | if (!(cfg & PIN_CFG_DRV)) |
517 | return -EINVAL; |
518 | |
519 | /* DRV uses 2-bits per pin */ |
520 | bit *= 2; |
521 | |
522 | val = (readl(addr: pctrl->base + DRV(port)) >> bit) & DRV_MASK; |
523 | |
524 | switch (cfg & PIN_CFG_GRP_MASK) { |
525 | case PIN_CFG_GRP_1_8V_2: |
526 | arg = drv_1_8V_group2_uA[val]; |
527 | break; |
528 | case PIN_CFG_GRP_1_8V_3: |
529 | arg = drv_1_8V_group3_uA[val]; |
530 | break; |
531 | case PIN_CFG_GRP_SWIO_2: |
532 | arg = drv_SWIO_group2_3_3V_uA[val]; |
533 | break; |
534 | case PIN_CFG_GRP_SWIO_1: |
535 | case PIN_CFG_GRP_3_3V: |
536 | arg = drv_3_3V_group_uA[val]; |
537 | break; |
538 | default: |
539 | return -EINVAL; |
540 | } |
541 | |
542 | break; |
543 | |
544 | case PIN_CONFIG_SLEW_RATE: |
545 | if (!(cfg & PIN_CFG_SLEW)) |
546 | return -EINVAL; |
547 | |
548 | arg = readl(addr: pctrl->base + SR(port)) & BIT(bit); |
549 | break; |
550 | |
551 | default: |
552 | return -ENOTSUPP; |
553 | } |
554 | |
555 | *config = pinconf_to_config_packed(param, argument: arg); |
556 | |
557 | return 0; |
558 | }; |
559 | |
560 | static int rzv2m_pinctrl_pinconf_set(struct pinctrl_dev *pctldev, |
561 | unsigned int _pin, |
562 | unsigned long *_configs, |
563 | unsigned int num_configs) |
564 | { |
565 | struct rzv2m_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); |
566 | const struct pinctrl_pin_desc *pin = &pctrl->desc.pins[_pin]; |
567 | unsigned int *pin_data = pin->drv_data; |
568 | enum pin_config_param param; |
569 | u32 port; |
570 | unsigned int i; |
571 | u32 cfg; |
572 | u8 bit; |
573 | u32 val; |
574 | |
575 | if (!pin_data) |
576 | return -EINVAL; |
577 | |
578 | if (*pin_data & RZV2M_SINGLE_PIN) { |
579 | port = RZV2M_SINGLE_PIN_GET_PORT(*pin_data); |
580 | cfg = RZV2M_SINGLE_PIN_GET_CFGS(*pin_data); |
581 | bit = RZV2M_SINGLE_PIN_GET_BIT(*pin_data); |
582 | } else { |
583 | cfg = RZV2M_GPIO_PORT_GET_CFGS(*pin_data); |
584 | port = RZV2M_PIN_ID_TO_PORT(_pin); |
585 | bit = RZV2M_PIN_ID_TO_PIN(_pin); |
586 | |
587 | if (rzv2m_validate_gpio_pin(pctrl, cfg: *pin_data, RZV2M_PIN_ID_TO_PORT(_pin), bit)) |
588 | return -EINVAL; |
589 | } |
590 | |
591 | for (i = 0; i < num_configs; i++) { |
592 | param = pinconf_to_config_param(config: _configs[i]); |
593 | switch (param) { |
594 | case PIN_CONFIG_BIAS_DISABLE: |
595 | case PIN_CONFIG_BIAS_PULL_UP: |
596 | case PIN_CONFIG_BIAS_PULL_DOWN: |
597 | if (!(cfg & PIN_CFG_BIAS)) |
598 | return -EINVAL; |
599 | |
600 | /* PUPD uses 2-bits per pin */ |
601 | bit *= 2; |
602 | |
603 | switch (param) { |
604 | case PIN_CONFIG_BIAS_PULL_DOWN: |
605 | val = 0; |
606 | break; |
607 | case PIN_CONFIG_BIAS_PULL_UP: |
608 | val = 2; |
609 | break; |
610 | default: |
611 | val = 1; |
612 | } |
613 | |
614 | rzv2m_rmw_pin_config(pctrl, PUPD(port), shift: bit, PUPD_MASK, val); |
615 | break; |
616 | |
617 | case PIN_CONFIG_DRIVE_STRENGTH_UA: { |
618 | unsigned int arg = pinconf_to_config_argument(config: _configs[i]); |
619 | const unsigned int *drv_strengths; |
620 | unsigned int index; |
621 | |
622 | if (!(cfg & PIN_CFG_DRV)) |
623 | return -EINVAL; |
624 | |
625 | switch (cfg & PIN_CFG_GRP_MASK) { |
626 | case PIN_CFG_GRP_1_8V_2: |
627 | drv_strengths = drv_1_8V_group2_uA; |
628 | break; |
629 | case PIN_CFG_GRP_1_8V_3: |
630 | drv_strengths = drv_1_8V_group3_uA; |
631 | break; |
632 | case PIN_CFG_GRP_SWIO_2: |
633 | drv_strengths = drv_SWIO_group2_3_3V_uA; |
634 | break; |
635 | case PIN_CFG_GRP_SWIO_1: |
636 | case PIN_CFG_GRP_3_3V: |
637 | drv_strengths = drv_3_3V_group_uA; |
638 | break; |
639 | default: |
640 | return -EINVAL; |
641 | } |
642 | |
643 | for (index = 0; index < 4; index++) { |
644 | if (arg == drv_strengths[index]) |
645 | break; |
646 | } |
647 | if (index >= 4) |
648 | return -EINVAL; |
649 | |
650 | /* DRV uses 2-bits per pin */ |
651 | bit *= 2; |
652 | |
653 | rzv2m_rmw_pin_config(pctrl, DRV(port), shift: bit, DRV_MASK, val: index); |
654 | break; |
655 | } |
656 | |
657 | case PIN_CONFIG_SLEW_RATE: { |
658 | unsigned int arg = pinconf_to_config_argument(config: _configs[i]); |
659 | |
660 | if (!(cfg & PIN_CFG_SLEW)) |
661 | return -EINVAL; |
662 | |
663 | rzv2m_writel_we(addr: pctrl->base + SR(port), shift: bit, value: !arg); |
664 | break; |
665 | } |
666 | |
667 | default: |
668 | return -EOPNOTSUPP; |
669 | } |
670 | } |
671 | |
672 | return 0; |
673 | } |
674 | |
675 | static int rzv2m_pinctrl_pinconf_group_set(struct pinctrl_dev *pctldev, |
676 | unsigned int group, |
677 | unsigned long *configs, |
678 | unsigned int num_configs) |
679 | { |
680 | const unsigned int *pins; |
681 | unsigned int i, npins; |
682 | int ret; |
683 | |
684 | ret = pinctrl_generic_get_group_pins(pctldev, group_selector: group, pins: &pins, npins: &npins); |
685 | if (ret) |
686 | return ret; |
687 | |
688 | for (i = 0; i < npins; i++) { |
689 | ret = rzv2m_pinctrl_pinconf_set(pctldev, pin: pins[i], configs: configs, |
690 | num_configs); |
691 | if (ret) |
692 | return ret; |
693 | } |
694 | |
695 | return 0; |
696 | }; |
697 | |
698 | static int rzv2m_pinctrl_pinconf_group_get(struct pinctrl_dev *pctldev, |
699 | unsigned int group, |
700 | unsigned long *config) |
701 | { |
702 | const unsigned int *pins; |
703 | unsigned int i, npins, prev_config = 0; |
704 | int ret; |
705 | |
706 | ret = pinctrl_generic_get_group_pins(pctldev, group_selector: group, pins: &pins, npins: &npins); |
707 | if (ret) |
708 | return ret; |
709 | |
710 | for (i = 0; i < npins; i++) { |
711 | ret = rzv2m_pinctrl_pinconf_get(pctldev, pin: pins[i], config); |
712 | if (ret) |
713 | return ret; |
714 | |
715 | /* Check config matches previous pins */ |
716 | if (i && prev_config != *config) |
717 | return -EOPNOTSUPP; |
718 | |
719 | prev_config = *config; |
720 | } |
721 | |
722 | return 0; |
723 | }; |
724 | |
725 | static const struct pinctrl_ops rzv2m_pinctrl_pctlops = { |
726 | .get_groups_count = pinctrl_generic_get_group_count, |
727 | .get_group_name = pinctrl_generic_get_group_name, |
728 | .get_group_pins = pinctrl_generic_get_group_pins, |
729 | .dt_node_to_map = rzv2m_dt_node_to_map, |
730 | .dt_free_map = rzv2m_dt_free_map, |
731 | }; |
732 | |
733 | static const struct pinmux_ops rzv2m_pinctrl_pmxops = { |
734 | .get_functions_count = pinmux_generic_get_function_count, |
735 | .get_function_name = pinmux_generic_get_function_name, |
736 | .get_function_groups = pinmux_generic_get_function_groups, |
737 | .set_mux = rzv2m_pinctrl_set_mux, |
738 | .strict = true, |
739 | }; |
740 | |
741 | static const struct pinconf_ops rzv2m_pinctrl_confops = { |
742 | .is_generic = true, |
743 | .pin_config_get = rzv2m_pinctrl_pinconf_get, |
744 | .pin_config_set = rzv2m_pinctrl_pinconf_set, |
745 | .pin_config_group_set = rzv2m_pinctrl_pinconf_group_set, |
746 | .pin_config_group_get = rzv2m_pinctrl_pinconf_group_get, |
747 | .pin_config_config_dbg_show = pinconf_generic_dump_config, |
748 | }; |
749 | |
750 | static int rzv2m_gpio_request(struct gpio_chip *chip, unsigned int offset) |
751 | { |
752 | struct rzv2m_pinctrl *pctrl = gpiochip_get_data(gc: chip); |
753 | u32 port = RZV2M_PIN_ID_TO_PORT(offset); |
754 | u8 bit = RZV2M_PIN_ID_TO_PIN(offset); |
755 | int ret; |
756 | |
757 | ret = pinctrl_gpio_request(gc: chip, offset); |
758 | if (ret) |
759 | return ret; |
760 | |
761 | rzv2m_pinctrl_set_pfc_mode(pctrl, port, pin: bit, func: 0); |
762 | |
763 | return 0; |
764 | } |
765 | |
766 | static void rzv2m_gpio_set_direction(struct rzv2m_pinctrl *pctrl, u32 port, |
767 | u8 bit, bool output) |
768 | { |
769 | rzv2m_writel_we(addr: pctrl->base + OE(port), shift: bit, value: output); |
770 | rzv2m_writel_we(addr: pctrl->base + IE(port), shift: bit, value: !output); |
771 | } |
772 | |
773 | static int rzv2m_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) |
774 | { |
775 | struct rzv2m_pinctrl *pctrl = gpiochip_get_data(gc: chip); |
776 | u32 port = RZV2M_PIN_ID_TO_PORT(offset); |
777 | u8 bit = RZV2M_PIN_ID_TO_PIN(offset); |
778 | |
779 | if (!(readl(addr: pctrl->base + IE(port)) & BIT(bit))) |
780 | return GPIO_LINE_DIRECTION_OUT; |
781 | |
782 | return GPIO_LINE_DIRECTION_IN; |
783 | } |
784 | |
785 | static int rzv2m_gpio_direction_input(struct gpio_chip *chip, |
786 | unsigned int offset) |
787 | { |
788 | struct rzv2m_pinctrl *pctrl = gpiochip_get_data(gc: chip); |
789 | u32 port = RZV2M_PIN_ID_TO_PORT(offset); |
790 | u8 bit = RZV2M_PIN_ID_TO_PIN(offset); |
791 | |
792 | rzv2m_gpio_set_direction(pctrl, port, bit, output: false); |
793 | |
794 | return 0; |
795 | } |
796 | |
797 | static void rzv2m_gpio_set(struct gpio_chip *chip, unsigned int offset, |
798 | int value) |
799 | { |
800 | struct rzv2m_pinctrl *pctrl = gpiochip_get_data(gc: chip); |
801 | u32 port = RZV2M_PIN_ID_TO_PORT(offset); |
802 | u8 bit = RZV2M_PIN_ID_TO_PIN(offset); |
803 | |
804 | rzv2m_writel_we(addr: pctrl->base + DO(port), shift: bit, value: !!value); |
805 | } |
806 | |
807 | static int rzv2m_gpio_direction_output(struct gpio_chip *chip, |
808 | unsigned int offset, int value) |
809 | { |
810 | struct rzv2m_pinctrl *pctrl = gpiochip_get_data(gc: chip); |
811 | u32 port = RZV2M_PIN_ID_TO_PORT(offset); |
812 | u8 bit = RZV2M_PIN_ID_TO_PIN(offset); |
813 | |
814 | rzv2m_gpio_set(chip, offset, value); |
815 | rzv2m_gpio_set_direction(pctrl, port, bit, output: true); |
816 | |
817 | return 0; |
818 | } |
819 | |
820 | static int rzv2m_gpio_get(struct gpio_chip *chip, unsigned int offset) |
821 | { |
822 | struct rzv2m_pinctrl *pctrl = gpiochip_get_data(gc: chip); |
823 | u32 port = RZV2M_PIN_ID_TO_PORT(offset); |
824 | u8 bit = RZV2M_PIN_ID_TO_PIN(offset); |
825 | int direction = rzv2m_gpio_get_direction(chip, offset); |
826 | |
827 | if (direction == GPIO_LINE_DIRECTION_IN) |
828 | return !!(readl(addr: pctrl->base + DI(port)) & BIT(bit)); |
829 | else |
830 | return !!(readl(addr: pctrl->base + DO(port)) & BIT(bit)); |
831 | } |
832 | |
833 | static void rzv2m_gpio_free(struct gpio_chip *chip, unsigned int offset) |
834 | { |
835 | pinctrl_gpio_free(gc: chip, offset); |
836 | |
837 | /* |
838 | * Set the GPIO as an input to ensure that the next GPIO request won't |
839 | * drive the GPIO pin as an output. |
840 | */ |
841 | rzv2m_gpio_direction_input(chip, offset); |
842 | } |
843 | |
844 | static const char * const rzv2m_gpio_names[] = { |
845 | "P0_0" , "P0_1" , "P0_2" , "P0_3" , "P0_4" , "P0_5" , "P0_6" , "P0_7" , |
846 | "P0_8" , "P0_9" , "P0_10" , "P0_11" , "P0_12" , "P0_13" , "P0_14" , "P0_15" , |
847 | "P1_0" , "P1_1" , "P1_2" , "P1_3" , "P1_4" , "P1_5" , "P1_6" , "P1_7" , |
848 | "P1_8" , "P1_9" , "P1_10" , "P1_11" , "P1_12" , "P1_13" , "P1_14" , "P1_15" , |
849 | "P2_0" , "P2_1" , "P2_2" , "P2_3" , "P2_4" , "P2_5" , "P2_6" , "P2_7" , |
850 | "P2_8" , "P2_9" , "P2_10" , "P2_11" , "P2_12" , "P2_13" , "P2_14" , "P2_15" , |
851 | "P3_0" , "P3_1" , "P3_2" , "P3_3" , "P3_4" , "P3_5" , "P3_6" , "P3_7" , |
852 | "P3_8" , "P3_9" , "P3_10" , "P3_11" , "P3_12" , "P3_13" , "P3_14" , "P3_15" , |
853 | "P4_0" , "P4_1" , "P4_2" , "P4_3" , "P4_4" , "P4_5" , "P4_6" , "P4_7" , |
854 | "P4_8" , "P4_9" , "P4_10" , "P4_11" , "P4_12" , "P4_13" , "P4_14" , "P4_15" , |
855 | "P5_0" , "P5_1" , "P5_2" , "P5_3" , "P5_4" , "P5_5" , "P5_6" , "P5_7" , |
856 | "P5_8" , "P5_9" , "P5_10" , "P5_11" , "P5_12" , "P5_13" , "P5_14" , "P5_15" , |
857 | "P6_0" , "P6_1" , "P6_2" , "P6_3" , "P6_4" , "P6_5" , "P6_6" , "P6_7" , |
858 | "P6_8" , "P6_9" , "P6_10" , "P6_11" , "P6_12" , "P6_13" , "P6_14" , "P6_15" , |
859 | "P7_0" , "P7_1" , "P7_2" , "P7_3" , "P7_4" , "P7_5" , "P7_6" , "P7_7" , |
860 | "P7_8" , "P7_9" , "P7_10" , "P7_11" , "P7_12" , "P7_13" , "P7_14" , "P7_15" , |
861 | "P8_0" , "P8_1" , "P8_2" , "P8_3" , "P8_4" , "P8_5" , "P8_6" , "P8_7" , |
862 | "P8_8" , "P8_9" , "P8_10" , "P8_11" , "P8_12" , "P8_13" , "P8_14" , "P8_15" , |
863 | "P9_0" , "P9_1" , "P9_2" , "P9_3" , "P9_4" , "P9_5" , "P9_6" , "P9_7" , |
864 | "P9_8" , "P9_9" , "P9_10" , "P9_11" , "P9_12" , "P9_13" , "P9_14" , "P9_15" , |
865 | "P10_0" , "P10_1" , "P10_2" , "P10_3" , "P10_4" , "P10_5" , "P10_6" , "P10_7" , |
866 | "P10_8" , "P10_9" , "P10_10" , "P10_11" , "P10_12" , "P10_13" , "P10_14" , "P10_15" , |
867 | "P11_0" , "P11_1" , "P11_2" , "P11_3" , "P11_4" , "P11_5" , "P11_6" , "P11_7" , |
868 | "P11_8" , "P11_9" , "P11_10" , "P11_11" , "P11_12" , "P11_13" , "P11_14" , "P11_15" , |
869 | "P12_0" , "P12_1" , "P12_2" , "P12_3" , "P12_4" , "P12_5" , "P12_6" , "P12_7" , |
870 | "P12_8" , "P12_9" , "P12_10" , "P12_11" , "P12_12" , "P12_13" , "P12_14" , "P12_15" , |
871 | "P13_0" , "P13_1" , "P13_2" , "P13_3" , "P13_4" , "P13_5" , "P13_6" , "P13_7" , |
872 | "P13_8" , "P13_9" , "P13_10" , "P13_11" , "P13_12" , "P13_13" , "P13_14" , "P13_15" , |
873 | "P14_0" , "P14_1" , "P14_2" , "P14_3" , "P14_4" , "P14_5" , "P14_6" , "P14_7" , |
874 | "P14_8" , "P14_9" , "P14_10" , "P14_11" , "P14_12" , "P14_13" , "P14_14" , "P14_15" , |
875 | "P15_0" , "P15_1" , "P15_2" , "P15_3" , "P15_4" , "P15_5" , "P15_6" , "P15_7" , |
876 | "P15_8" , "P15_9" , "P15_10" , "P15_11" , "P15_12" , "P15_13" , "P15_14" , "P15_15" , |
877 | "P16_0" , "P16_1" , "P16_2" , "P16_3" , "P16_4" , "P16_5" , "P16_6" , "P16_7" , |
878 | "P16_8" , "P16_9" , "P16_10" , "P16_11" , "P16_12" , "P16_13" , "P16_14" , "P16_15" , |
879 | "P17_0" , "P17_1" , "P17_2" , "P17_3" , "P17_4" , "P17_5" , "P17_6" , "P17_7" , |
880 | "P17_8" , "P17_9" , "P17_10" , "P17_11" , "P17_12" , "P17_13" , "P17_14" , "P17_15" , |
881 | "P18_0" , "P18_1" , "P18_2" , "P18_3" , "P18_4" , "P18_5" , "P18_6" , "P18_7" , |
882 | "P18_8" , "P18_9" , "P18_10" , "P18_11" , "P18_12" , "P18_13" , "P18_14" , "P18_15" , |
883 | "P19_0" , "P19_1" , "P19_2" , "P19_3" , "P19_4" , "P19_5" , "P19_6" , "P19_7" , |
884 | "P19_8" , "P19_9" , "P19_10" , "P19_11" , "P19_12" , "P19_13" , "P19_14" , "P19_15" , |
885 | "P20_0" , "P20_1" , "P20_2" , "P20_3" , "P20_4" , "P20_5" , "P20_6" , "P20_7" , |
886 | "P20_8" , "P20_9" , "P20_10" , "P20_11" , "P20_12" , "P20_13" , "P20_14" , "P20_15" , |
887 | "P21_0" , "P21_1" , "P21_2" , "P21_3" , "P21_4" , "P21_5" , "P21_6" , "P21_7" , |
888 | "P21_8" , "P21_9" , "P21_10" , "P21_11" , "P21_12" , "P21_13" , "P21_14" , "P21_15" , |
889 | }; |
890 | |
891 | static const u32 rzv2m_gpio_configs[] = { |
892 | RZV2M_GPIO_PORT_PACK(14, 0, PIN_CFG_GRP_SWIO_2 | RZV2M_MPXED_PIN_FUNCS), |
893 | RZV2M_GPIO_PORT_PACK(16, 1, PIN_CFG_GRP_SWIO_1 | RZV2M_MPXED_PIN_FUNCS), |
894 | RZV2M_GPIO_PORT_PACK(8, 2, PIN_CFG_GRP_1_8V_3 | RZV2M_MPXED_PIN_FUNCS), |
895 | RZV2M_GPIO_PORT_PACK(16, 3, PIN_CFG_GRP_SWIO_1 | RZV2M_MPXED_PIN_FUNCS), |
896 | RZV2M_GPIO_PORT_PACK(8, 4, PIN_CFG_GRP_SWIO_1 | RZV2M_MPXED_PIN_FUNCS), |
897 | RZV2M_GPIO_PORT_PACK(4, 5, PIN_CFG_GRP_1_8V_3 | RZV2M_MPXED_PIN_FUNCS), |
898 | RZV2M_GPIO_PORT_PACK(12, 6, PIN_CFG_GRP_SWIO_1 | RZV2M_MPXED_PIN_FUNCS), |
899 | RZV2M_GPIO_PORT_PACK(6, 7, PIN_CFG_GRP_SWIO_1 | RZV2M_MPXED_PIN_FUNCS), |
900 | RZV2M_GPIO_PORT_PACK(8, 8, PIN_CFG_GRP_SWIO_2 | RZV2M_MPXED_PIN_FUNCS), |
901 | RZV2M_GPIO_PORT_PACK(8, 9, PIN_CFG_GRP_SWIO_2 | RZV2M_MPXED_PIN_FUNCS), |
902 | RZV2M_GPIO_PORT_PACK(9, 10, PIN_CFG_GRP_SWIO_1 | RZV2M_MPXED_PIN_FUNCS), |
903 | RZV2M_GPIO_PORT_PACK(9, 11, PIN_CFG_GRP_SWIO_1 | RZV2M_MPXED_PIN_FUNCS), |
904 | RZV2M_GPIO_PORT_PACK(4, 12, PIN_CFG_GRP_3_3V | RZV2M_MPXED_PIN_FUNCS), |
905 | RZV2M_GPIO_PORT_PACK(12, 13, PIN_CFG_GRP_3_3V | RZV2M_MPXED_PIN_FUNCS), |
906 | RZV2M_GPIO_PORT_PACK(8, 14, PIN_CFG_GRP_3_3V | RZV2M_MPXED_PIN_FUNCS), |
907 | RZV2M_GPIO_PORT_PACK(16, 15, PIN_CFG_GRP_SWIO_2 | RZV2M_MPXED_PIN_FUNCS), |
908 | RZV2M_GPIO_PORT_PACK(14, 16, PIN_CFG_GRP_SWIO_2 | RZV2M_MPXED_PIN_FUNCS), |
909 | RZV2M_GPIO_PORT_PACK(1, 17, PIN_CFG_GRP_SWIO_2 | RZV2M_MPXED_PIN_FUNCS), |
910 | RZV2M_GPIO_PORT_PACK(0, 18, 0), |
911 | RZV2M_GPIO_PORT_PACK(0, 19, 0), |
912 | RZV2M_GPIO_PORT_PACK(3, 20, PIN_CFG_GRP_1_8V_2 | PIN_CFG_DRV), |
913 | RZV2M_GPIO_PORT_PACK(1, 21, PIN_CFG_GRP_SWIO_1 | PIN_CFG_DRV | PIN_CFG_SLEW), |
914 | }; |
915 | |
916 | static const struct rzv2m_dedicated_configs rzv2m_dedicated_pins[] = { |
917 | { "NAWPN" , RZV2M_SINGLE_PIN_PACK(0, |
918 | (PIN_CFG_GRP_SWIO_2 | PIN_CFG_DRV | PIN_CFG_SLEW)) }, |
919 | { "IM0CLK" , RZV2M_SINGLE_PIN_PACK(1, |
920 | (PIN_CFG_GRP_SWIO_1 | PIN_CFG_DRV | PIN_CFG_SLEW)) }, |
921 | { "IM1CLK" , RZV2M_SINGLE_PIN_PACK(2, |
922 | (PIN_CFG_GRP_SWIO_1 | PIN_CFG_DRV | PIN_CFG_SLEW)) }, |
923 | { "DETDO" , RZV2M_SINGLE_PIN_PACK(5, |
924 | (PIN_CFG_GRP_1_8V_3 | PIN_CFG_DRV | PIN_CFG_SLEW)) }, |
925 | { "DETMS" , RZV2M_SINGLE_PIN_PACK(6, |
926 | (PIN_CFG_GRP_1_8V_3 | PIN_CFG_DRV | PIN_CFG_SLEW)) }, |
927 | { "PCRSTOUTB" , RZV2M_SINGLE_PIN_PACK(12, |
928 | (PIN_CFG_GRP_3_3V | PIN_CFG_DRV | PIN_CFG_SLEW)) }, |
929 | { "USPWEN" , RZV2M_SINGLE_PIN_PACK(14, |
930 | (PIN_CFG_GRP_3_3V | PIN_CFG_DRV | PIN_CFG_SLEW)) }, |
931 | }; |
932 | |
933 | static int rzv2m_gpio_register(struct rzv2m_pinctrl *pctrl) |
934 | { |
935 | struct device_node *np = pctrl->dev->of_node; |
936 | struct gpio_chip *chip = &pctrl->gpio_chip; |
937 | const char *name = dev_name(dev: pctrl->dev); |
938 | struct of_phandle_args of_args; |
939 | int ret; |
940 | |
941 | ret = of_parse_phandle_with_fixed_args(np, list_name: "gpio-ranges" , cell_count: 3, index: 0, out_args: &of_args); |
942 | if (ret) { |
943 | dev_err(pctrl->dev, "Unable to parse gpio-ranges\n" ); |
944 | return ret; |
945 | } |
946 | |
947 | if (of_args.args[0] != 0 || of_args.args[1] != 0 || |
948 | of_args.args[2] != pctrl->data->n_port_pins) { |
949 | dev_err(pctrl->dev, "gpio-ranges does not match selected SOC\n" ); |
950 | return -EINVAL; |
951 | } |
952 | |
953 | chip->names = pctrl->data->port_pins; |
954 | chip->request = rzv2m_gpio_request; |
955 | chip->free = rzv2m_gpio_free; |
956 | chip->get_direction = rzv2m_gpio_get_direction; |
957 | chip->direction_input = rzv2m_gpio_direction_input; |
958 | chip->direction_output = rzv2m_gpio_direction_output; |
959 | chip->get = rzv2m_gpio_get; |
960 | chip->set = rzv2m_gpio_set; |
961 | chip->label = name; |
962 | chip->parent = pctrl->dev; |
963 | chip->owner = THIS_MODULE; |
964 | chip->base = -1; |
965 | chip->ngpio = of_args.args[2]; |
966 | |
967 | pctrl->gpio_range.id = 0; |
968 | pctrl->gpio_range.pin_base = 0; |
969 | pctrl->gpio_range.base = 0; |
970 | pctrl->gpio_range.npins = chip->ngpio; |
971 | pctrl->gpio_range.name = chip->label; |
972 | pctrl->gpio_range.gc = chip; |
973 | ret = devm_gpiochip_add_data(pctrl->dev, chip, pctrl); |
974 | if (ret) { |
975 | dev_err(pctrl->dev, "failed to add GPIO controller\n" ); |
976 | return ret; |
977 | } |
978 | |
979 | dev_dbg(pctrl->dev, "Registered gpio controller\n" ); |
980 | |
981 | return 0; |
982 | } |
983 | |
984 | static int rzv2m_pinctrl_register(struct rzv2m_pinctrl *pctrl) |
985 | { |
986 | struct pinctrl_pin_desc *pins; |
987 | unsigned int i, j; |
988 | u32 *pin_data; |
989 | int ret; |
990 | |
991 | pctrl->desc.name = DRV_NAME; |
992 | pctrl->desc.npins = pctrl->data->n_port_pins + pctrl->data->n_dedicated_pins; |
993 | pctrl->desc.pctlops = &rzv2m_pinctrl_pctlops; |
994 | pctrl->desc.pmxops = &rzv2m_pinctrl_pmxops; |
995 | pctrl->desc.confops = &rzv2m_pinctrl_confops; |
996 | pctrl->desc.owner = THIS_MODULE; |
997 | |
998 | pins = devm_kcalloc(dev: pctrl->dev, n: pctrl->desc.npins, size: sizeof(*pins), GFP_KERNEL); |
999 | if (!pins) |
1000 | return -ENOMEM; |
1001 | |
1002 | pin_data = devm_kcalloc(dev: pctrl->dev, n: pctrl->desc.npins, |
1003 | size: sizeof(*pin_data), GFP_KERNEL); |
1004 | if (!pin_data) |
1005 | return -ENOMEM; |
1006 | |
1007 | pctrl->pins = pins; |
1008 | pctrl->desc.pins = pins; |
1009 | |
1010 | for (i = 0, j = 0; i < pctrl->data->n_port_pins; i++) { |
1011 | pins[i].number = i; |
1012 | pins[i].name = pctrl->data->port_pins[i]; |
1013 | if (i && !(i % RZV2M_PINS_PER_PORT)) |
1014 | j++; |
1015 | pin_data[i] = pctrl->data->port_pin_configs[j]; |
1016 | pins[i].drv_data = &pin_data[i]; |
1017 | } |
1018 | |
1019 | for (i = 0; i < pctrl->data->n_dedicated_pins; i++) { |
1020 | unsigned int index = pctrl->data->n_port_pins + i; |
1021 | |
1022 | pins[index].number = index; |
1023 | pins[index].name = pctrl->data->dedicated_pins[i].name; |
1024 | pin_data[index] = pctrl->data->dedicated_pins[i].config; |
1025 | pins[index].drv_data = &pin_data[index]; |
1026 | } |
1027 | |
1028 | ret = devm_pinctrl_register_and_init(dev: pctrl->dev, pctldesc: &pctrl->desc, driver_data: pctrl, |
1029 | pctldev: &pctrl->pctl); |
1030 | if (ret) { |
1031 | dev_err(pctrl->dev, "pinctrl registration failed\n" ); |
1032 | return ret; |
1033 | } |
1034 | |
1035 | ret = pinctrl_enable(pctldev: pctrl->pctl); |
1036 | if (ret) { |
1037 | dev_err(pctrl->dev, "pinctrl enable failed\n" ); |
1038 | return ret; |
1039 | } |
1040 | |
1041 | ret = rzv2m_gpio_register(pctrl); |
1042 | if (ret) { |
1043 | dev_err(pctrl->dev, "failed to add GPIO chip: %i\n" , ret); |
1044 | return ret; |
1045 | } |
1046 | |
1047 | return 0; |
1048 | } |
1049 | |
1050 | static int rzv2m_pinctrl_probe(struct platform_device *pdev) |
1051 | { |
1052 | struct rzv2m_pinctrl *pctrl; |
1053 | struct clk *clk; |
1054 | int ret; |
1055 | |
1056 | pctrl = devm_kzalloc(dev: &pdev->dev, size: sizeof(*pctrl), GFP_KERNEL); |
1057 | if (!pctrl) |
1058 | return -ENOMEM; |
1059 | |
1060 | pctrl->dev = &pdev->dev; |
1061 | |
1062 | pctrl->data = of_device_get_match_data(dev: &pdev->dev); |
1063 | if (!pctrl->data) |
1064 | return -EINVAL; |
1065 | |
1066 | pctrl->base = devm_platform_ioremap_resource(pdev, index: 0); |
1067 | if (IS_ERR(ptr: pctrl->base)) |
1068 | return PTR_ERR(ptr: pctrl->base); |
1069 | |
1070 | clk = devm_clk_get_enabled(dev: pctrl->dev, NULL); |
1071 | if (IS_ERR(ptr: clk)) |
1072 | return dev_err_probe(dev: pctrl->dev, err: PTR_ERR(ptr: clk), |
1073 | fmt: "failed to enable GPIO clk\n" ); |
1074 | |
1075 | spin_lock_init(&pctrl->lock); |
1076 | mutex_init(&pctrl->mutex); |
1077 | |
1078 | platform_set_drvdata(pdev, data: pctrl); |
1079 | |
1080 | ret = rzv2m_pinctrl_register(pctrl); |
1081 | if (ret) |
1082 | return ret; |
1083 | |
1084 | dev_info(pctrl->dev, "%s support registered\n" , DRV_NAME); |
1085 | return 0; |
1086 | } |
1087 | |
1088 | static struct rzv2m_pinctrl_data r9a09g011_data = { |
1089 | .port_pins = rzv2m_gpio_names, |
1090 | .port_pin_configs = rzv2m_gpio_configs, |
1091 | .dedicated_pins = rzv2m_dedicated_pins, |
1092 | .n_port_pins = ARRAY_SIZE(rzv2m_gpio_configs) * RZV2M_PINS_PER_PORT, |
1093 | .n_dedicated_pins = ARRAY_SIZE(rzv2m_dedicated_pins), |
1094 | }; |
1095 | |
1096 | static const struct of_device_id rzv2m_pinctrl_of_table[] = { |
1097 | { |
1098 | .compatible = "renesas,r9a09g011-pinctrl" , |
1099 | .data = &r9a09g011_data, |
1100 | }, |
1101 | { /* sentinel */ } |
1102 | }; |
1103 | |
1104 | static struct platform_driver rzv2m_pinctrl_driver = { |
1105 | .driver = { |
1106 | .name = DRV_NAME, |
1107 | .of_match_table = of_match_ptr(rzv2m_pinctrl_of_table), |
1108 | }, |
1109 | .probe = rzv2m_pinctrl_probe, |
1110 | }; |
1111 | |
1112 | static int __init rzv2m_pinctrl_init(void) |
1113 | { |
1114 | return platform_driver_register(&rzv2m_pinctrl_driver); |
1115 | } |
1116 | core_initcall(rzv2m_pinctrl_init); |
1117 | |
1118 | MODULE_AUTHOR("Phil Edworthy <phil.edworthy@renesas.com>" ); |
1119 | MODULE_DESCRIPTION("Pin and gpio controller driver for RZ/V2M" ); |
1120 | |