1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Realtek DHC pin controller driver
4 *
5 * Copyright (c) 2023 Realtek Semiconductor Corp.
6 */
7
8#include <linux/bitops.h>
9#include <linux/io.h>
10#include <linux/module.h>
11#include <linux/of.h>
12#include <linux/of_address.h>
13#include <linux/pinctrl/machine.h>
14#include <linux/pinctrl/pinconf.h>
15#include <linux/pinctrl/pinconf-generic.h>
16#include <linux/pinctrl/pinctrl.h>
17#include <linux/pinctrl/pinmux.h>
18#include <linux/platform_device.h>
19#include <linux/seq_file.h>
20#include <linux/regmap.h>
21#include <linux/slab.h>
22#include "../core.h"
23#include "../pinctrl-utils.h"
24#include "pinctrl-rtd.h"
25
26struct rtd_pinctrl {
27 struct device *dev;
28 struct pinctrl_dev *pcdev;
29 void __iomem *base;
30 struct pinctrl_desc desc;
31 const struct rtd_pinctrl_desc *info;
32 struct regmap *regmap_pinctrl;
33};
34
35/* custom pinconf parameters */
36#define RTD_DRIVE_STRENGH_P (PIN_CONFIG_END + 1)
37#define RTD_DRIVE_STRENGH_N (PIN_CONFIG_END + 2)
38#define RTD_DUTY_CYCLE (PIN_CONFIG_END + 3)
39
40static const struct pinconf_generic_params rtd_custom_bindings[] = {
41 {"realtek,drive-strength-p", RTD_DRIVE_STRENGH_P, 0},
42 {"realtek,drive-strength-n", RTD_DRIVE_STRENGH_N, 0},
43 {"realtek,duty-cycle", RTD_DUTY_CYCLE, 0},
44};
45
46static int rtd_pinctrl_get_groups_count(struct pinctrl_dev *pcdev)
47{
48 struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pctldev: pcdev);
49
50 return data->info->num_groups;
51}
52
53static const char *rtd_pinctrl_get_group_name(struct pinctrl_dev *pcdev,
54 unsigned int selector)
55{
56 struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pctldev: pcdev);
57
58 return data->info->groups[selector].name;
59}
60
61static int rtd_pinctrl_get_group_pins(struct pinctrl_dev *pcdev,
62 unsigned int selector,
63 const unsigned int **pins,
64 unsigned int *num_pins)
65{
66 struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pctldev: pcdev);
67
68 *pins = data->info->groups[selector].pins;
69 *num_pins = data->info->groups[selector].num_pins;
70
71 return 0;
72}
73
74static void rtd_pinctrl_dbg_show(struct pinctrl_dev *pcdev,
75 struct seq_file *s,
76 unsigned int offset)
77{
78 struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pctldev: pcdev);
79 const struct rtd_pin_desc *mux = &data->info->muxes[offset];
80 const struct rtd_pin_mux_desc *func;
81 u32 val;
82 u32 mask;
83 u32 pin_val;
84 int is_map;
85
86 if (!mux->name) {
87 seq_puts(m: s, s: "[not defined]");
88 return;
89 }
90 val = readl_relaxed(data->base + mux->mux_offset);
91 mask = mux->mux_mask;
92 pin_val = val & mask;
93
94 is_map = 0;
95 func = &mux->functions[0];
96 seq_puts(m: s, s: "function: ");
97 while (func->name) {
98 if (func->mux_value == pin_val) {
99 is_map = 1;
100 seq_printf(m: s, fmt: "[%s] ", func->name);
101 } else {
102 seq_printf(m: s, fmt: "%s ", func->name);
103 }
104 func++;
105 }
106 if (!is_map)
107 seq_puts(m: s, s: "[not defined]");
108}
109
110static const struct pinctrl_ops rtd_pinctrl_ops = {
111 .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
112 .dt_free_map = pinctrl_utils_free_map,
113 .get_groups_count = rtd_pinctrl_get_groups_count,
114 .get_group_name = rtd_pinctrl_get_group_name,
115 .get_group_pins = rtd_pinctrl_get_group_pins,
116 .pin_dbg_show = rtd_pinctrl_dbg_show,
117};
118
119static int rtd_pinctrl_get_functions_count(struct pinctrl_dev *pcdev)
120{
121 struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pctldev: pcdev);
122
123 return data->info->num_functions;
124}
125
126static const char *rtd_pinctrl_get_function_name(struct pinctrl_dev *pcdev,
127 unsigned int selector)
128{
129 struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pctldev: pcdev);
130
131 return data->info->functions[selector].name;
132}
133
134static int rtd_pinctrl_get_function_groups(struct pinctrl_dev *pcdev,
135 unsigned int selector,
136 const char * const **groups,
137 unsigned int * const num_groups)
138{
139 struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pctldev: pcdev);
140
141 *groups = data->info->functions[selector].groups;
142 *num_groups = data->info->functions[selector].num_groups;
143
144 return 0;
145}
146
147static const struct rtd_pin_desc *rtd_pinctrl_find_mux(struct rtd_pinctrl *data, unsigned int pin)
148{
149 if (data->info->muxes[pin].name)
150 return &data->info->muxes[pin];
151
152 return NULL;
153}
154
155static int rtd_pinctrl_set_one_mux(struct pinctrl_dev *pcdev,
156 unsigned int pin, const char *func_name)
157{
158 struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pctldev: pcdev);
159 const struct rtd_pin_desc *mux;
160 int ret = 0;
161 int i;
162
163 mux = rtd_pinctrl_find_mux(data, pin);
164 if (!mux)
165 return 0;
166
167 if (!mux->functions) {
168 if (!mux->name)
169 dev_err(pcdev->dev, "NULL pin has no functions\n");
170 else
171 dev_err(pcdev->dev, "No functions available for pin %s\n", mux->name);
172 return -ENOTSUPP;
173 }
174
175 for (i = 0; mux->functions[i].name; i++) {
176 if (strcmp(mux->functions[i].name, func_name) != 0)
177 continue;
178 ret = regmap_update_bits(map: data->regmap_pinctrl, reg: mux->mux_offset, mask: mux->mux_mask,
179 val: mux->functions[i].mux_value);
180 return ret;
181 }
182
183 if (!mux->name) {
184 dev_err(pcdev->dev, "NULL pin provided for function %s\n", func_name);
185 return -EINVAL;
186 }
187
188 dev_err(pcdev->dev, "No function %s available for pin %s\n", func_name, mux->name);
189
190 return -EINVAL;
191}
192
193static int rtd_pinctrl_set_mux(struct pinctrl_dev *pcdev,
194 unsigned int function, unsigned int group)
195{
196 struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pctldev: pcdev);
197 const unsigned int *pins;
198 unsigned int num_pins;
199 const char *func_name;
200 const char *group_name;
201 int i, ret;
202
203 func_name = data->info->functions[function].name;
204 group_name = data->info->groups[group].name;
205
206 ret = rtd_pinctrl_get_group_pins(pcdev, selector: group, pins: &pins, num_pins: &num_pins);
207 if (ret) {
208 dev_err(pcdev->dev, "Getting pins for group %s failed\n", group_name);
209 return ret;
210 }
211
212 for (i = 0; i < num_pins; i++) {
213 ret = rtd_pinctrl_set_one_mux(pcdev, pin: pins[i], func_name);
214 if (ret)
215 return ret;
216 }
217
218 return 0;
219}
220
221static int rtd_pinctrl_gpio_request_enable(struct pinctrl_dev *pcdev,
222 struct pinctrl_gpio_range *range,
223 unsigned int offset)
224{
225 return rtd_pinctrl_set_one_mux(pcdev, pin: offset, func_name: "gpio");
226}
227
228static const struct pinmux_ops rtd_pinmux_ops = {
229 .get_functions_count = rtd_pinctrl_get_functions_count,
230 .get_function_name = rtd_pinctrl_get_function_name,
231 .get_function_groups = rtd_pinctrl_get_function_groups,
232 .set_mux = rtd_pinctrl_set_mux,
233 .gpio_request_enable = rtd_pinctrl_gpio_request_enable,
234};
235
236static const struct pinctrl_pin_desc
237 *rtd_pinctrl_get_pin_by_number(struct rtd_pinctrl *data, int number)
238{
239 int i;
240
241 for (i = 0; i < data->info->num_pins; i++) {
242 if (data->info->pins[i].number == number)
243 return &data->info->pins[i];
244 }
245
246 return NULL;
247}
248
249static const struct rtd_pin_config_desc
250 *rtd_pinctrl_find_config(struct rtd_pinctrl *data, unsigned int pin)
251{
252 if (data->info->configs[pin].name)
253 return &data->info->configs[pin];
254
255 return NULL;
256}
257
258static const struct rtd_pin_sconfig_desc *rtd_pinctrl_find_sconfig(struct rtd_pinctrl *data,
259 unsigned int pin)
260{
261 int i;
262 const struct pinctrl_pin_desc *pin_desc;
263 const char *pin_name;
264
265 pin_desc = rtd_pinctrl_get_pin_by_number(data, number: pin);
266 if (!pin_desc)
267 return NULL;
268
269 pin_name = pin_desc->name;
270
271 for (i = 0; i < data->info->num_sconfigs; i++) {
272 if (strcmp(data->info->sconfigs[i].name, pin_name) == 0)
273 return &data->info->sconfigs[i];
274 }
275
276 return NULL;
277}
278
279static int rtd_pconf_parse_conf(struct rtd_pinctrl *data,
280 unsigned int pinnr,
281 enum pin_config_param param,
282 enum pin_config_param arg)
283{
284 const struct rtd_pin_config_desc *config_desc;
285 const struct rtd_pin_sconfig_desc *sconfig_desc;
286 u8 set_val = 0;
287 u16 strength;
288 u32 val;
289 u32 mask;
290 u32 pulsel_off, pulen_off, smt_off, curr_off, pow_off, reg_off, p_off, n_off;
291 const char *name = data->info->pins[pinnr].name;
292 int ret = 0;
293
294 config_desc = rtd_pinctrl_find_config(data, pin: pinnr);
295 if (!config_desc) {
296 dev_err(data->dev, "Not support pin config for pin: %s\n", name);
297 return -ENOTSUPP;
298 }
299 switch ((u32)param) {
300 case PIN_CONFIG_INPUT_SCHMITT:
301 case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
302 if (config_desc->smt_offset == NA) {
303 dev_err(data->dev, "Not support input schmitt for pin: %s\n", name);
304 return -ENOTSUPP;
305 }
306 smt_off = config_desc->base_bit + config_desc->smt_offset;
307 reg_off = config_desc->reg_offset;
308 set_val = arg;
309
310 mask = BIT(smt_off);
311 val = set_val ? BIT(smt_off) : 0;
312 break;
313
314 case PIN_CONFIG_DRIVE_PUSH_PULL:
315 if (config_desc->pud_en_offset == NA) {
316 dev_err(data->dev, "Not support push pull for pin: %s\n", name);
317 return -ENOTSUPP;
318 }
319 pulen_off = config_desc->base_bit + config_desc->pud_en_offset;
320 reg_off = config_desc->reg_offset;
321
322 mask = BIT(pulen_off);
323 val = 0;
324 break;
325
326 case PIN_CONFIG_BIAS_DISABLE:
327 if (config_desc->pud_en_offset == NA) {
328 dev_err(data->dev, "Not support bias disable for pin: %s\n", name);
329 return -ENOTSUPP;
330 }
331 pulen_off = config_desc->base_bit + config_desc->pud_en_offset;
332 reg_off = config_desc->reg_offset;
333
334 mask = BIT(pulen_off);
335 val = 0;
336 break;
337
338 case PIN_CONFIG_BIAS_PULL_UP:
339 if (config_desc->pud_en_offset == NA) {
340 dev_err(data->dev, "Not support bias pull up for pin:%s\n", name);
341 return -ENOTSUPP;
342 }
343 pulen_off = config_desc->base_bit + config_desc->pud_en_offset;
344 pulsel_off = config_desc->base_bit + config_desc->pud_sel_offset;
345 reg_off = config_desc->reg_offset;
346
347 mask = BIT(pulen_off) | BIT(pulsel_off);
348 val = mask;
349 break;
350
351 case PIN_CONFIG_BIAS_PULL_DOWN:
352 if (config_desc->pud_en_offset == NA) {
353 dev_err(data->dev, "Not support bias pull down for pin: %s\n", name);
354 return -ENOTSUPP;
355 }
356 pulen_off = config_desc->base_bit + config_desc->pud_en_offset;
357 pulsel_off = config_desc->base_bit + config_desc->pud_sel_offset;
358 reg_off = config_desc->reg_offset;
359
360 mask = BIT(pulen_off) | BIT(pulsel_off);
361 val = BIT(pulen_off);
362 break;
363
364 case PIN_CONFIG_DRIVE_STRENGTH:
365 curr_off = config_desc->base_bit + config_desc->curr_offset;
366 reg_off = config_desc->reg_offset;
367 strength = arg;
368 val = 0;
369 switch (config_desc->curr_type) {
370 case PADDRI_4_8:
371 if (strength == 4)
372 val = 0;
373 else if (strength == 8)
374 val = BIT(curr_off);
375 else
376 return -EINVAL;
377 break;
378 case PADDRI_2_4:
379 if (strength == 2)
380 val = 0;
381 else if (strength == 4)
382 val = BIT(curr_off);
383 else
384 return -EINVAL;
385 break;
386 case NA:
387 dev_err(data->dev, "Not support drive strength for pin: %s\n", name);
388 return -ENOTSUPP;
389 default:
390 return -EINVAL;
391 }
392 mask = BIT(curr_off);
393 break;
394
395 case PIN_CONFIG_POWER_SOURCE:
396 if (config_desc->power_offset == NA) {
397 dev_err(data->dev, "Not support power source for pin: %s\n", name);
398 return -ENOTSUPP;
399 }
400 reg_off = config_desc->reg_offset;
401 pow_off = config_desc->base_bit + config_desc->power_offset;
402 if (pow_off >= 32) {
403 reg_off += 0x4;
404 pow_off -= 32;
405 }
406 set_val = arg;
407 mask = BIT(pow_off);
408 val = set_val ? mask : 0;
409 break;
410
411 case RTD_DRIVE_STRENGH_P:
412 sconfig_desc = rtd_pinctrl_find_sconfig(data, pin: pinnr);
413 if (!sconfig_desc) {
414 dev_err(data->dev, "Not support P driving for pin: %s\n", name);
415 return -ENOTSUPP;
416 }
417 set_val = arg;
418 reg_off = sconfig_desc->reg_offset;
419 p_off = sconfig_desc->pdrive_offset;
420 if (p_off >= 32) {
421 reg_off += 0x4;
422 p_off -= 32;
423 }
424 mask = GENMASK(p_off + sconfig_desc->pdrive_maskbits - 1, p_off);
425 val = set_val << p_off;
426 break;
427
428 case RTD_DRIVE_STRENGH_N:
429 sconfig_desc = rtd_pinctrl_find_sconfig(data, pin: pinnr);
430 if (!sconfig_desc) {
431 dev_err(data->dev, "Not support N driving for pin: %s\n", name);
432 return -ENOTSUPP;
433 }
434 set_val = arg;
435 reg_off = sconfig_desc->reg_offset;
436 n_off = sconfig_desc->ndrive_offset;
437 if (n_off >= 32) {
438 reg_off += 0x4;
439 n_off -= 32;
440 }
441 mask = GENMASK(n_off + sconfig_desc->ndrive_maskbits - 1, n_off);
442 val = set_val << n_off;
443 break;
444
445 case RTD_DUTY_CYCLE:
446 sconfig_desc = rtd_pinctrl_find_sconfig(data, pin: pinnr);
447 if (!sconfig_desc || sconfig_desc->dcycle_offset == NA) {
448 dev_err(data->dev, "Not support duty cycle for pin: %s\n", name);
449 return -ENOTSUPP;
450 }
451 set_val = arg;
452 reg_off = config_desc->reg_offset;
453 mask = GENMASK(sconfig_desc->dcycle_offset +
454 sconfig_desc->dcycle_maskbits - 1, sconfig_desc->dcycle_offset);
455 val = set_val << sconfig_desc->dcycle_offset;
456 break;
457
458 default:
459 dev_err(data->dev, "unsupported pinconf: %d\n", (u32)param);
460 return -EINVAL;
461 }
462
463 ret = regmap_update_bits(map: data->regmap_pinctrl, reg: reg_off, mask, val);
464 if (ret)
465 dev_err(data->dev, "could not update pinconf(%d) for pin(%s)\n", (u32)param, name);
466
467 return ret;
468}
469
470static int rtd_pin_config_get(struct pinctrl_dev *pcdev, unsigned int pinnr,
471 unsigned long *config)
472{
473 unsigned int param = pinconf_to_config_param(config: *config);
474 unsigned int arg = 0;
475
476 switch (param) {
477 default:
478 return -ENOTSUPP;
479 }
480
481 *config = pinconf_to_config_packed(param, argument: arg);
482 return 0;
483}
484
485static int rtd_pin_config_set(struct pinctrl_dev *pcdev, unsigned int pinnr,
486 unsigned long *configs, unsigned int num_configs)
487{
488 struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pctldev: pcdev);
489 int i;
490 int ret = 0;
491
492 for (i = 0; i < num_configs; i++) {
493 ret = rtd_pconf_parse_conf(data, pinnr,
494 param: pinconf_to_config_param(config: configs[i]),
495 arg: pinconf_to_config_argument(config: configs[i]));
496 if (ret < 0)
497 return ret;
498 }
499
500 return 0;
501}
502
503static int rtd_pin_config_group_set(struct pinctrl_dev *pcdev, unsigned int group,
504 unsigned long *configs, unsigned int num_configs)
505{
506 struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pctldev: pcdev);
507 const unsigned int *pins;
508 unsigned int num_pins;
509 const char *group_name;
510 int i, ret;
511
512 group_name = data->info->groups[group].name;
513
514 ret = rtd_pinctrl_get_group_pins(pcdev, selector: group, pins: &pins, num_pins: &num_pins);
515 if (ret) {
516 dev_err(pcdev->dev, "Getting pins for group %s failed\n", group_name);
517 return ret;
518 }
519
520 for (i = 0; i < num_pins; i++) {
521 ret = rtd_pin_config_set(pcdev, pinnr: pins[i], configs, num_configs);
522 if (ret)
523 return ret;
524 }
525
526 return 0;
527}
528
529static const struct pinconf_ops rtd_pinconf_ops = {
530 .is_generic = true,
531 .pin_config_get = rtd_pin_config_get,
532 .pin_config_set = rtd_pin_config_set,
533 .pin_config_group_set = rtd_pin_config_group_set,
534};
535
536static struct regmap_config rtd_pinctrl_regmap_config = {
537 .reg_bits = 32,
538 .val_bits = 32,
539 .reg_stride = 4,
540 .use_relaxed_mmio = true,
541};
542
543int rtd_pinctrl_probe(struct platform_device *pdev, const struct rtd_pinctrl_desc *desc)
544{
545 struct rtd_pinctrl *data;
546 int ret;
547
548 data = devm_kzalloc(dev: &pdev->dev, size: sizeof(*data), GFP_KERNEL);
549 if (!data)
550 return -ENOMEM;
551
552 data->base = of_iomap(node: pdev->dev.of_node, index: 0);
553 if (!data->base)
554 return -ENOMEM;
555
556 data->dev = &pdev->dev;
557 data->info = desc;
558 data->desc.name = dev_name(dev: &pdev->dev);
559 data->desc.pins = data->info->pins;
560 data->desc.npins = data->info->num_pins;
561 data->desc.pctlops = &rtd_pinctrl_ops;
562 data->desc.pmxops = &rtd_pinmux_ops;
563 data->desc.confops = &rtd_pinconf_ops;
564 data->desc.custom_params = rtd_custom_bindings;
565 data->desc.num_custom_params = ARRAY_SIZE(rtd_custom_bindings);
566 data->desc.owner = THIS_MODULE;
567 data->regmap_pinctrl = devm_regmap_init_mmio(data->dev, data->base,
568 &rtd_pinctrl_regmap_config);
569
570 if (IS_ERR(ptr: data->regmap_pinctrl)) {
571 dev_err(data->dev, "failed to init regmap: %ld\n",
572 PTR_ERR(data->regmap_pinctrl));
573 ret = PTR_ERR(ptr: data->regmap_pinctrl);
574 goto unmap;
575 }
576
577 data->pcdev = pinctrl_register(pctldesc: &data->desc, dev: &pdev->dev, driver_data: data);
578 if (IS_ERR(ptr: data->pcdev)) {
579 ret = PTR_ERR(ptr: data->pcdev);
580 goto unmap;
581 }
582
583 platform_set_drvdata(pdev, data);
584
585 dev_dbg(&pdev->dev, "probed\n");
586
587 return 0;
588
589unmap:
590 iounmap(addr: data->base);
591 return ret;
592}
593EXPORT_SYMBOL(rtd_pinctrl_probe);
594
595MODULE_DESCRIPTION("Realtek DHC SoC pinctrl driver");
596MODULE_LICENSE("GPL v2");
597

source code of linux/drivers/pinctrl/realtek/pinctrl-rtd.c