1 // SPDX-License-Identifier: GPL-2.0+
2 //
3 // Author: Jerry Zhu <Jerry.Zhu@cixtech.com>
4 // Author: Gary Yang <gary.yang@cixtech.com>
5
6 #include <linux/device.h>
7 #include <linux/err.h>
8 #include <linux/init.h>
9 #include <linux/io.h>
10 #include <linux/module.h>
11 #include <linux/of.h>
12 #include <linux/of_device.h>
13 #include <linux/of_address.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/slab.h>
21
22 #include "../core.h"
23 #include "../pinconf.h"
24 #include "../pinctrl-utils.h"
25 #include "../pinmux.h"
26 #include "pinctrl-sky1.h"
27
28 #define SKY1_PIN_SIZE (4)
29 #define SKY1_MUX_MASK GENMASK(8, 7)
30 #define SKY1_MUX_SHIFT (7)
31 #define SKY1_PULLCONF_MASK GENMASK(6, 5)
32 #define SKY1_PULLUP_BIT (6)
33 #define SKY1_PULLDN_BIT (5)
34 #define SKY1_DS_MASK GENMASK(3, 0)
35
36 #define CIX_PIN_NO_SHIFT (8)
37 #define CIX_PIN_FUN_MASK GENMASK(1, 0)
38 #define CIX_GET_PIN_NO(x) ((x) >> CIX_PIN_NO_SHIFT)
39 #define CIX_GET_PIN_FUNC(x) ((x) & CIX_PIN_FUN_MASK)
40 #define SKY1_DEFAULT_DS_VAL (4)
41
42 static const char * const sky1_gpio_functions[] = {
43 "func0", "func1", "func2", "func3",
44 };
45
46 static unsigned char sky1_ds_table[] = {
47 2, 3, 5, 6, 8, 9, 11, 12, 13, 14, 17, 18, 20, 21, 23, 24,
48 };
49
sky1_pctrl_is_function_valid(struct sky1_pinctrl * spctl,u32 pin_num,u32 fnum)50 static bool sky1_pctrl_is_function_valid(struct sky1_pinctrl *spctl,
51 u32 pin_num, u32 fnum)
52 {
53 int i;
54
55 for (i = 0; i < spctl->info->npins; i++) {
56 const struct sky1_pin_desc *pin = spctl->info->pins + i;
57
58 if (pin->pin.number == pin_num) {
59 if (fnum < pin->nfunc)
60 return true;
61
62 break;
63 }
64 }
65
66 return false;
67 }
68
sky1_pctrl_dt_node_to_map_func(struct sky1_pinctrl * spctl,u32 pin,u32 fnum,struct sky1_pinctrl_group * grp,struct pinctrl_map ** map,unsigned int * reserved_maps,unsigned int * num_maps)69 static int sky1_pctrl_dt_node_to_map_func(struct sky1_pinctrl *spctl,
70 u32 pin, u32 fnum, struct sky1_pinctrl_group *grp,
71 struct pinctrl_map **map, unsigned int *reserved_maps,
72 unsigned int *num_maps)
73 {
74 bool ret;
75
76 if (*num_maps == *reserved_maps)
77 return -ENOSPC;
78
79 (*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP;
80 (*map)[*num_maps].data.mux.group = grp->name;
81
82 ret = sky1_pctrl_is_function_valid(spctl, pin, fnum);
83 if (!ret) {
84 dev_err(spctl->dev, "invalid function %d on pin %d .\n",
85 fnum, pin);
86 return -EINVAL;
87 }
88
89 (*map)[*num_maps].data.mux.function = sky1_gpio_functions[fnum];
90 (*num_maps)++;
91
92 return 0;
93 }
94
95 static struct sky1_pinctrl_group *
sky1_pctrl_find_group_by_pin(struct sky1_pinctrl * spctl,u32 pin)96 sky1_pctrl_find_group_by_pin(struct sky1_pinctrl *spctl, u32 pin)
97 {
98 int i;
99
100 for (i = 0; i < spctl->info->npins; i++) {
101 struct sky1_pinctrl_group *grp =
102 (struct sky1_pinctrl_group *)spctl->groups + i;
103
104 if (grp->pin == pin)
105 return grp;
106 }
107
108 return NULL;
109 }
110
sky1_pctrl_dt_subnode_to_map(struct pinctrl_dev * pctldev,struct device_node * node,struct pinctrl_map ** map,unsigned int * reserved_maps,unsigned int * num_maps)111 static int sky1_pctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
112 struct device_node *node,
113 struct pinctrl_map **map,
114 unsigned int *reserved_maps,
115 unsigned int *num_maps)
116 {
117 struct property *pins;
118 u32 pinfunc, pin, func;
119 int num_pins, num_funcs, maps_per_pin;
120 unsigned long *configs;
121 unsigned int num_configs;
122 bool has_config = false;
123 int i, err;
124 unsigned int reserve = 0;
125 struct sky1_pinctrl_group *grp;
126 struct sky1_pinctrl *spctl = pinctrl_dev_get_drvdata(pctldev);
127
128 pins = of_find_property(node, "pinmux", NULL);
129 if (!pins) {
130 dev_err(spctl->dev, "missing pins property in node %pOFn .\n",
131 node);
132 return -EINVAL;
133 }
134
135 err = pinconf_generic_parse_dt_config(node, pctldev, &configs,
136 &num_configs);
137 if (err)
138 return err;
139
140 if (num_configs)
141 has_config = true;
142
143 num_pins = pins->length / sizeof(u32);
144 num_funcs = num_pins;
145 maps_per_pin = 0;
146 if (num_funcs)
147 maps_per_pin++;
148 if (has_config && num_pins >= 1)
149 maps_per_pin++;
150
151 if (!num_pins || !maps_per_pin) {
152 err = -EINVAL;
153 goto exit;
154 }
155
156 reserve = num_pins * maps_per_pin;
157
158 err = pinctrl_utils_reserve_map(pctldev, map,
159 reserved_maps, num_maps, reserve);
160 if (err < 0)
161 goto exit;
162
163 for (i = 0; i < num_pins; i++) {
164 err = of_property_read_u32_index(node, "pinmux",
165 i, &pinfunc);
166 if (err)
167 goto exit;
168
169 pin = CIX_GET_PIN_NO(pinfunc);
170 func = CIX_GET_PIN_FUNC(pinfunc);
171 pctldev->num_functions = ARRAY_SIZE(sky1_gpio_functions);
172
173 if (pin >= pctldev->desc->npins ||
174 func >= pctldev->num_functions) {
175 dev_err(spctl->dev, "invalid pins value.\n");
176 err = -EINVAL;
177 goto exit;
178 }
179
180 grp = sky1_pctrl_find_group_by_pin(spctl, pin);
181 if (!grp) {
182 dev_err(spctl->dev, "unable to match pin %d to group\n",
183 pin);
184 err = -EINVAL;
185 goto exit;
186 }
187
188 err = sky1_pctrl_dt_node_to_map_func(spctl, pin, func, grp,
189 map, reserved_maps, num_maps);
190 if (err < 0)
191 goto exit;
192
193 if (has_config) {
194 err = pinctrl_utils_add_map_configs(pctldev, map,
195 reserved_maps, num_maps, grp->name,
196 configs, num_configs,
197 PIN_MAP_TYPE_CONFIGS_GROUP);
198 if (err < 0)
199 goto exit;
200 }
201 }
202
203 err = 0;
204
205 exit:
206 kfree(configs);
207 return err;
208 }
209
sky1_pctrl_dt_node_to_map(struct pinctrl_dev * pctldev,struct device_node * np_config,struct pinctrl_map ** map,unsigned int * num_maps)210 static int sky1_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
211 struct device_node *np_config,
212 struct pinctrl_map **map, unsigned int *num_maps)
213 {
214 unsigned int reserved_maps;
215 int ret;
216
217 *map = NULL;
218 *num_maps = 0;
219 reserved_maps = 0;
220
221 for_each_child_of_node_scoped(np_config, np) {
222 ret = sky1_pctrl_dt_subnode_to_map(pctldev, np, map,
223 &reserved_maps, num_maps);
224 if (ret < 0) {
225 pinctrl_utils_free_map(pctldev, *map, *num_maps);
226 return ret;
227 }
228 }
229
230 return 0;
231 }
232
sky1_dt_free_map(struct pinctrl_dev * pctldev,struct pinctrl_map * map,unsigned int num_maps)233 static void sky1_dt_free_map(struct pinctrl_dev *pctldev,
234 struct pinctrl_map *map,
235 unsigned int num_maps)
236 {
237 kfree(map);
238 }
239
sky1_pctrl_get_groups_count(struct pinctrl_dev * pctldev)240 static int sky1_pctrl_get_groups_count(struct pinctrl_dev *pctldev)
241 {
242 struct sky1_pinctrl *spctl = pinctrl_dev_get_drvdata(pctldev);
243
244 return spctl->info->npins;
245 }
246
sky1_pctrl_get_group_name(struct pinctrl_dev * pctldev,unsigned int group)247 static const char *sky1_pctrl_get_group_name(struct pinctrl_dev *pctldev,
248 unsigned int group)
249 {
250 struct sky1_pinctrl *spctl = pinctrl_dev_get_drvdata(pctldev);
251
252 return spctl->groups[group].name;
253 }
254
sky1_pctrl_get_group_pins(struct pinctrl_dev * pctldev,unsigned int group,const unsigned int ** pins,unsigned int * num_pins)255 static int sky1_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
256 unsigned int group,
257 const unsigned int **pins,
258 unsigned int *num_pins)
259 {
260 struct sky1_pinctrl *spctl = pinctrl_dev_get_drvdata(pctldev);
261
262 *pins = (unsigned int *)&spctl->groups[group].pin;
263 *num_pins = 1;
264
265 return 0;
266 }
267
sky1_pin_dbg_show(struct pinctrl_dev * pctldev,struct seq_file * s,unsigned int offset)268 static void sky1_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
269 unsigned int offset)
270 {
271 seq_printf(s, "%s", dev_name(pctldev->dev));
272 }
273
274 static const struct pinctrl_ops sky1_pctrl_ops = {
275 .dt_node_to_map = sky1_pctrl_dt_node_to_map,
276 .dt_free_map = sky1_dt_free_map,
277 .get_groups_count = sky1_pctrl_get_groups_count,
278 .get_group_name = sky1_pctrl_get_group_name,
279 .get_group_pins = sky1_pctrl_get_group_pins,
280 .pin_dbg_show = sky1_pin_dbg_show,
281 };
282
sky1_pmx_set_one_pin(struct sky1_pinctrl * spctl,unsigned int pin,unsigned char muxval)283 static int sky1_pmx_set_one_pin(struct sky1_pinctrl *spctl,
284 unsigned int pin, unsigned char muxval)
285 {
286 u32 reg_val;
287 void __iomem *pin_reg;
288
289 pin_reg = spctl->base + pin * SKY1_PIN_SIZE;
290 reg_val = readl(pin_reg);
291 reg_val &= ~SKY1_MUX_MASK;
292 reg_val |= muxval << SKY1_MUX_SHIFT;
293 writel(reg_val, pin_reg);
294
295 dev_dbg(spctl->dev, "write: offset 0x%x val 0x%x\n",
296 pin * SKY1_PIN_SIZE, reg_val);
297 return 0;
298 }
299
sky1_pmx_set_mux(struct pinctrl_dev * pctldev,unsigned int function,unsigned int group)300 static int sky1_pmx_set_mux(struct pinctrl_dev *pctldev,
301 unsigned int function,
302 unsigned int group)
303 {
304 bool ret;
305 struct sky1_pinctrl *spctl = pinctrl_dev_get_drvdata(pctldev);
306 struct sky1_pinctrl_group *g =
307 (struct sky1_pinctrl_group *)spctl->groups + group;
308
309 ret = sky1_pctrl_is_function_valid(spctl, g->pin, function);
310 if (!ret) {
311 dev_err(spctl->dev, "invalid function %d on group %d .\n",
312 function, group);
313 return -EINVAL;
314 }
315
316 sky1_pmx_set_one_pin(spctl, g->pin, function);
317 return 0;
318 }
319
sky1_pmx_get_funcs_cnt(struct pinctrl_dev * pctldev)320 static int sky1_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
321 {
322 return ARRAY_SIZE(sky1_gpio_functions);
323 }
324
sky1_pmx_get_func_name(struct pinctrl_dev * pctldev,unsigned int selector)325 static const char *sky1_pmx_get_func_name(struct pinctrl_dev *pctldev,
326 unsigned int selector)
327 {
328 return sky1_gpio_functions[selector];
329 }
330
sky1_pmx_get_func_groups(struct pinctrl_dev * pctldev,unsigned int function,const char * const ** groups,unsigned int * const num_groups)331 static int sky1_pmx_get_func_groups(struct pinctrl_dev *pctldev,
332 unsigned int function,
333 const char * const **groups,
334 unsigned int * const num_groups)
335 {
336 struct sky1_pinctrl *spctl = pinctrl_dev_get_drvdata(pctldev);
337 const struct sky1_pinctrl_soc_info *info = spctl->info;
338
339 *groups = spctl->grp_names;
340 *num_groups = info->npins;
341
342 return 0;
343 }
344
345 static const struct pinmux_ops sky1_pmx_ops = {
346 .get_functions_count = sky1_pmx_get_funcs_cnt,
347 .get_function_groups = sky1_pmx_get_func_groups,
348 .get_function_name = sky1_pmx_get_func_name,
349 .set_mux = sky1_pmx_set_mux,
350 };
351
sky1_pconf_set_pull_select(struct sky1_pinctrl * spctl,unsigned int pin,bool enable,bool isup)352 static int sky1_pconf_set_pull_select(struct sky1_pinctrl *spctl,
353 unsigned int pin, bool enable, bool isup)
354 {
355 u32 reg_val, reg_pullsel = 0;
356 void __iomem *pin_reg;
357
358 pin_reg = spctl->base + pin * SKY1_PIN_SIZE;
359 reg_val = readl(pin_reg);
360 reg_val &= ~SKY1_PULLCONF_MASK;
361
362 if (!enable)
363 goto update;
364
365 if (isup)
366 reg_pullsel = BIT(SKY1_PULLUP_BIT);
367 else
368 reg_pullsel = BIT(SKY1_PULLDN_BIT);
369
370 update:
371 reg_val |= reg_pullsel;
372 writel(reg_val, pin_reg);
373
374 dev_dbg(spctl->dev, "write: offset 0x%x val 0x%x\n",
375 pin * SKY1_PIN_SIZE, reg_val);
376 return 0;
377 }
378
sky1_ds_to_index(unsigned char driving)379 static int sky1_ds_to_index(unsigned char driving)
380 {
381 int i;
382
383 for (i = 0; i < sizeof(sky1_ds_table); i++)
384 if (driving == sky1_ds_table[i])
385 return i;
386 return SKY1_DEFAULT_DS_VAL;
387 }
388
sky1_pconf_set_driving(struct sky1_pinctrl * spctl,unsigned int pin,unsigned char driving)389 static int sky1_pconf_set_driving(struct sky1_pinctrl *spctl,
390 unsigned int pin, unsigned char driving)
391 {
392 unsigned int reg_val, val;
393 void __iomem *pin_reg;
394
395 if (pin >= spctl->info->npins)
396 return -EINVAL;
397
398 pin_reg = spctl->base + pin * SKY1_PIN_SIZE;
399 reg_val = readl(pin_reg);
400 reg_val &= ~SKY1_DS_MASK;
401 val = sky1_ds_to_index(driving);
402 reg_val |= (val & SKY1_DS_MASK);
403 writel(reg_val, pin_reg);
404
405 dev_dbg(spctl->dev, "write: offset 0x%x val 0x%x\n",
406 pin * SKY1_PIN_SIZE, reg_val);
407
408 return 0;
409 }
410
sky1_pconf_parse_conf(struct pinctrl_dev * pctldev,unsigned int pin,enum pin_config_param param,enum pin_config_param arg)411 static int sky1_pconf_parse_conf(struct pinctrl_dev *pctldev,
412 unsigned int pin, enum pin_config_param param,
413 enum pin_config_param arg)
414 {
415 int ret = 0;
416 struct sky1_pinctrl *spctl = pinctrl_dev_get_drvdata(pctldev);
417
418 switch (param) {
419 case PIN_CONFIG_BIAS_DISABLE:
420 ret = sky1_pconf_set_pull_select(spctl, pin, false, false);
421 break;
422 case PIN_CONFIG_BIAS_PULL_UP:
423 ret = sky1_pconf_set_pull_select(spctl, pin, true, true);
424 break;
425 case PIN_CONFIG_BIAS_PULL_DOWN:
426 ret = sky1_pconf_set_pull_select(spctl, pin, true, false);
427 break;
428 case PIN_CONFIG_DRIVE_STRENGTH:
429 ret = sky1_pconf_set_driving(spctl, pin, arg);
430 break;
431 default:
432 ret = -EINVAL;
433 }
434
435 return ret;
436 }
437
sky1_pconf_group_get(struct pinctrl_dev * pctldev,unsigned int group,unsigned long * config)438 static int sky1_pconf_group_get(struct pinctrl_dev *pctldev,
439 unsigned int group,
440 unsigned long *config)
441 {
442 struct sky1_pinctrl *spctl = pinctrl_dev_get_drvdata(pctldev);
443 struct sky1_pinctrl_group *g = &spctl->groups[group];
444
445 *config = g->config;
446
447 return 0;
448 }
449
sky1_pconf_group_set(struct pinctrl_dev * pctldev,unsigned int group,unsigned long * configs,unsigned int num_configs)450 static int sky1_pconf_group_set(struct pinctrl_dev *pctldev, unsigned int group,
451 unsigned long *configs, unsigned int num_configs)
452 {
453 struct sky1_pinctrl *spctl = pinctrl_dev_get_drvdata(pctldev);
454 struct sky1_pinctrl_group *g = &spctl->groups[group];
455 int i, ret;
456
457 for (i = 0; i < num_configs; i++) {
458 ret = sky1_pconf_parse_conf(pctldev, g->pin,
459 pinconf_to_config_param(configs[i]),
460 pinconf_to_config_argument(configs[i]));
461 if (ret < 0)
462 return ret;
463
464 g->config = configs[i];
465 }
466
467 return 0;
468 }
469
470 static const struct pinconf_ops sky1_pinconf_ops = {
471 .pin_config_group_get = sky1_pconf_group_get,
472 .pin_config_group_set = sky1_pconf_group_set,
473 };
474
sky1_pctrl_build_state(struct platform_device * pdev)475 static int sky1_pctrl_build_state(struct platform_device *pdev)
476 {
477 struct sky1_pinctrl *spctl = platform_get_drvdata(pdev);
478 const struct sky1_pinctrl_soc_info *info = spctl->info;
479 int i;
480
481 /* Allocate groups */
482 spctl->groups = devm_kcalloc(&pdev->dev, info->npins,
483 sizeof(*spctl->groups), GFP_KERNEL);
484 if (!spctl->groups)
485 return -ENOMEM;
486
487 /* We assume that one pin is one group, use pin name as group name. */
488 spctl->grp_names = devm_kcalloc(&pdev->dev, info->npins,
489 sizeof(*spctl->grp_names), GFP_KERNEL);
490 if (!spctl->grp_names)
491 return -ENOMEM;
492
493 for (i = 0; i < info->npins; i++) {
494 const struct sky1_pin_desc *pin = spctl->info->pins + i;
495 struct sky1_pinctrl_group *group =
496 (struct sky1_pinctrl_group *)spctl->groups + i;
497
498 group->name = pin->pin.name;
499 group->pin = pin->pin.number;
500 spctl->grp_names[i] = pin->pin.name;
501 }
502
503 return 0;
504 }
505
sky1_base_pinctrl_probe(struct platform_device * pdev,const struct sky1_pinctrl_soc_info * info)506 int sky1_base_pinctrl_probe(struct platform_device *pdev,
507 const struct sky1_pinctrl_soc_info *info)
508 {
509 struct pinctrl_desc *sky1_pinctrl_desc;
510 struct sky1_pinctrl *spctl;
511 struct pinctrl_pin_desc *pins;
512 int ret, i;
513
514 if (!info || !info->pins || !info->npins) {
515 dev_err(&pdev->dev, "wrong pinctrl info\n");
516 return -EINVAL;
517 }
518
519 /* Create state holders etc for this driver */
520 spctl = devm_kzalloc(&pdev->dev, sizeof(*spctl), GFP_KERNEL);
521 if (!spctl)
522 return -ENOMEM;
523
524 spctl->info = info;
525 platform_set_drvdata(pdev, spctl);
526
527 spctl->base = devm_platform_ioremap_resource(pdev, 0);
528 if (IS_ERR(spctl->base))
529 return PTR_ERR(spctl->base);
530
531 sky1_pinctrl_desc = devm_kzalloc(&pdev->dev, sizeof(*sky1_pinctrl_desc),
532 GFP_KERNEL);
533 if (!sky1_pinctrl_desc)
534 return -ENOMEM;
535
536 pins = devm_kcalloc(&pdev->dev, info->npins, sizeof(*pins),
537 GFP_KERNEL);
538 if (!pins)
539 return -ENOMEM;
540 for (i = 0; i < info->npins; i++)
541 pins[i] = info->pins[i].pin;
542
543 ret = sky1_pctrl_build_state(pdev);
544 if (ret)
545 return ret;
546
547 sky1_pinctrl_desc->name = dev_name(&pdev->dev);
548 sky1_pinctrl_desc->pins = pins;
549 sky1_pinctrl_desc->npins = info->npins;
550 sky1_pinctrl_desc->pctlops = &sky1_pctrl_ops;
551 sky1_pinctrl_desc->pmxops = &sky1_pmx_ops;
552 sky1_pinctrl_desc->confops = &sky1_pinconf_ops;
553 sky1_pinctrl_desc->owner = THIS_MODULE;
554 spctl->dev = &pdev->dev;
555 ret = devm_pinctrl_register_and_init(&pdev->dev,
556 sky1_pinctrl_desc, spctl,
557 &spctl->pctl);
558 if (ret) {
559 dev_err(&pdev->dev, "could not register SKY1 pinctrl driver\n");
560 return ret;
561 }
562
563 /*
564 * The SKY1 SoC has two pin controllers: one for normal working state
565 * and one for sleep state. Since one controller only has working
566 * states and the other only sleep states, it will seem to the
567 * controller is always in the first configured state, so no
568 * transitions between default->sleep->default are detected and no
569 * new pin states are applied when we go in and out of sleep state.
570 *
571 * To counter this, provide dummies, so that the sleep-only pin
572 * controller still get some default states, and the working state pin
573 * controller get some sleep states, so that state transitions occur
574 * and we re-configure pins for default and sleep states.
575 */
576 pinctrl_provide_dummies();
577
578 dev_dbg(&pdev->dev, "initialized SKY1 pinctrl driver\n");
579
580 return pinctrl_enable(spctl->pctl);
581 }
582 EXPORT_SYMBOL_GPL(sky1_base_pinctrl_probe);
583
584
585 MODULE_AUTHOR("Jerry Zhu <Jerry.Zhu@cixtech.com>");
586 MODULE_DESCRIPTION("Cix SKy1 pinctrl base driver");
587 MODULE_LICENSE("GPL");
588