blob: 7d9a44bd0047f3d4dd394141c8e28a352471839f [file] [log] [blame]
Baolin Wang41d32cf2017-08-17 14:50:38 +08001/*
2 * Spreadtrum pin controller driver
3 * Copyright (C) 2017 Spreadtrum - http://www.spreadtrum.com
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 */
14
15#include <linux/debugfs.h>
16#include <linux/err.h>
17#include <linux/init.h>
18#include <linux/io.h>
19#include <linux/kernel.h>
20#include <linux/module.h>
21#include <linux/of.h>
22#include <linux/of_device.h>
23#include <linux/platform_device.h>
24#include <linux/pinctrl/machine.h>
25#include <linux/pinctrl/pinconf.h>
26#include <linux/pinctrl/pinconf-generic.h>
27#include <linux/pinctrl/pinctrl.h>
28#include <linux/pinctrl/pinmux.h>
29#include <linux/slab.h>
30
31#include "../core.h"
32#include "../pinmux.h"
33#include "../pinconf.h"
34#include "../pinctrl-utils.h"
35#include "pinctrl-sprd.h"
36
37#define PINCTRL_BIT_MASK(width) (~(~0UL << (width)))
38#define PINCTRL_REG_OFFSET 0x20
39#define PINCTRL_REG_MISC_OFFSET 0x4020
40#define PINCTRL_REG_LEN 0x4
41
42#define PIN_FUNC_MASK (BIT(4) | BIT(5))
43#define PIN_FUNC_SEL_1 ~PIN_FUNC_MASK
44#define PIN_FUNC_SEL_2 BIT(4)
45#define PIN_FUNC_SEL_3 BIT(5)
46#define PIN_FUNC_SEL_4 PIN_FUNC_MASK
47
48#define AP_SLEEP_MODE BIT(13)
49#define PUBCP_SLEEP_MODE BIT(14)
50#define TGLDSP_SLEEP_MODE BIT(15)
51#define AGDSP_SLEEP_MODE BIT(16)
52#define SLEEP_MODE_MASK GENMASK(3, 0)
53#define SLEEP_MODE_SHIFT 13
54
55#define SLEEP_INPUT BIT(1)
56#define SLEEP_INPUT_MASK 0x1
57#define SLEEP_INPUT_SHIFT 1
58
59#define SLEEP_OUTPUT BIT(0)
60#define SLEEP_OUTPUT_MASK 0x1
61#define SLEEP_OUTPUT_SHIFT 0
62
63#define DRIVE_STRENGTH_MASK GENMASK(3, 0)
64#define DRIVE_STRENGTH_SHIFT 19
65
66#define SLEEP_PULL_DOWN BIT(2)
67#define SLEEP_PULL_DOWN_MASK 0x1
68#define SLEEP_PULL_DOWN_SHIFT 2
69
70#define PULL_DOWN BIT(6)
71#define PULL_DOWN_MASK 0x1
72#define PULL_DOWN_SHIFT 6
73
74#define SLEEP_PULL_UP BIT(3)
75#define SLEEP_PULL_UP_MASK 0x1
76#define SLEEP_PULL_UP_SHIFT 3
77
78#define PULL_UP_20K (BIT(12) | BIT(7))
79#define PULL_UP_4_7K BIT(12)
80#define PULL_UP_MASK 0x21
81#define PULL_UP_SHIFT 7
82
83#define INPUT_SCHMITT BIT(11)
84#define INPUT_SCHMITT_MASK 0x1
85#define INPUT_SCHMITT_SHIFT 11
86
87enum pin_sleep_mode {
88 AP_SLEEP = BIT(0),
89 PUBCP_SLEEP = BIT(1),
90 TGLDSP_SLEEP = BIT(2),
91 AGDSP_SLEEP = BIT(3),
92};
93
94enum pin_func_sel {
95 PIN_FUNC_1,
96 PIN_FUNC_2,
97 PIN_FUNC_3,
98 PIN_FUNC_4,
99 PIN_FUNC_MAX,
100};
101
102/**
103 * struct sprd_pin: represent one pin's description
104 * @name: pin name
105 * @number: pin number
106 * @type: pin type, can be GLOBAL_CTRL_PIN/COMMON_PIN/MISC_PIN
107 * @reg: pin register address
108 * @bit_offset: bit offset in pin register
109 * @bit_width: bit width in pin register
110 */
111struct sprd_pin {
112 const char *name;
113 unsigned int number;
114 enum pin_type type;
115 unsigned long reg;
116 unsigned long bit_offset;
117 unsigned long bit_width;
118};
119
120/**
121 * struct sprd_pin_group: represent one group's description
122 * @name: group name
123 * @npins: pin numbers of this group
124 * @pins: pointer to pins array
125 */
126struct sprd_pin_group {
127 const char *name;
128 unsigned int npins;
129 unsigned int *pins;
130};
131
132/**
133 * struct sprd_pinctrl_soc_info: represent the SoC's pins description
134 * @groups: pointer to groups of pins
135 * @ngroups: group numbers of the whole SoC
136 * @pins: pointer to pins description
137 * @npins: pin numbers of the whole SoC
138 * @grp_names: pointer to group names array
139 */
140struct sprd_pinctrl_soc_info {
141 struct sprd_pin_group *groups;
142 unsigned int ngroups;
143 struct sprd_pin *pins;
144 unsigned int npins;
145 const char **grp_names;
146};
147
148/**
149 * struct sprd_pinctrl: represent the pin controller device
150 * @dev: pointer to the device structure
151 * @pctl: pointer to the pinctrl handle
152 * @base: base address of the controller
153 * @info: pointer to SoC's pins description information
154 */
155struct sprd_pinctrl {
156 struct device *dev;
157 struct pinctrl_dev *pctl;
158 void __iomem *base;
159 struct sprd_pinctrl_soc_info *info;
160};
161
Nathan Chancellor957063c2018-10-31 17:44:10 -0700162#define SPRD_PIN_CONFIG_CONTROL (PIN_CONFIG_END + 1)
163#define SPRD_PIN_CONFIG_SLEEP_MODE (PIN_CONFIG_END + 2)
Baolin Wang41d32cf2017-08-17 14:50:38 +0800164
165static int sprd_pinctrl_get_id_by_name(struct sprd_pinctrl *sprd_pctl,
166 const char *name)
167{
168 struct sprd_pinctrl_soc_info *info = sprd_pctl->info;
169 int i;
170
171 for (i = 0; i < info->npins; i++) {
172 if (!strcmp(info->pins[i].name, name))
173 return info->pins[i].number;
174 }
175
176 return -ENODEV;
177}
178
179static struct sprd_pin *
180sprd_pinctrl_get_pin_by_id(struct sprd_pinctrl *sprd_pctl, unsigned int id)
181{
182 struct sprd_pinctrl_soc_info *info = sprd_pctl->info;
183 struct sprd_pin *pin = NULL;
184 int i;
185
186 for (i = 0; i < info->npins; i++) {
187 if (info->pins[i].number == id) {
188 pin = &info->pins[i];
189 break;
190 }
191 }
192
193 return pin;
194}
195
196static const struct sprd_pin_group *
197sprd_pinctrl_find_group_by_name(struct sprd_pinctrl *sprd_pctl,
198 const char *name)
199{
200 struct sprd_pinctrl_soc_info *info = sprd_pctl->info;
201 const struct sprd_pin_group *grp = NULL;
202 int i;
203
204 for (i = 0; i < info->ngroups; i++) {
205 if (!strcmp(info->groups[i].name, name)) {
206 grp = &info->groups[i];
207 break;
208 }
209 }
210
211 return grp;
212}
213
214static int sprd_pctrl_group_count(struct pinctrl_dev *pctldev)
215{
216 struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
217 struct sprd_pinctrl_soc_info *info = pctl->info;
218
219 return info->ngroups;
220}
221
222static const char *sprd_pctrl_group_name(struct pinctrl_dev *pctldev,
223 unsigned int selector)
224{
225 struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
226 struct sprd_pinctrl_soc_info *info = pctl->info;
227
228 return info->groups[selector].name;
229}
230
231static int sprd_pctrl_group_pins(struct pinctrl_dev *pctldev,
232 unsigned int selector,
233 const unsigned int **pins,
234 unsigned int *npins)
235{
236 struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
237 struct sprd_pinctrl_soc_info *info = pctl->info;
238
239 if (selector >= info->ngroups)
240 return -EINVAL;
241
242 *pins = info->groups[selector].pins;
243 *npins = info->groups[selector].npins;
244
245 return 0;
246}
247
248static int sprd_dt_node_to_map(struct pinctrl_dev *pctldev,
249 struct device_node *np,
250 struct pinctrl_map **map,
251 unsigned int *num_maps)
252{
253 struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
254 const struct sprd_pin_group *grp;
255 unsigned long *configs = NULL;
256 unsigned int num_configs = 0;
257 unsigned int reserved_maps = 0;
258 unsigned int reserve = 0;
259 const char *function;
260 enum pinctrl_map_type type;
261 int ret;
262
263 grp = sprd_pinctrl_find_group_by_name(pctl, np->name);
264 if (!grp) {
265 dev_err(pctl->dev, "unable to find group for node %s\n",
266 of_node_full_name(np));
267 return -EINVAL;
268 }
269
270 ret = of_property_count_strings(np, "pins");
271 if (ret < 0)
272 return ret;
273
274 if (ret == 1)
275 type = PIN_MAP_TYPE_CONFIGS_PIN;
276 else
277 type = PIN_MAP_TYPE_CONFIGS_GROUP;
278
279 ret = of_property_read_string(np, "function", &function);
280 if (ret < 0) {
281 if (ret != -EINVAL)
282 dev_err(pctl->dev,
283 "%s: could not parse property function\n",
284 of_node_full_name(np));
285 function = NULL;
286 }
287
288 ret = pinconf_generic_parse_dt_config(np, pctldev, &configs,
289 &num_configs);
290 if (ret < 0) {
291 dev_err(pctl->dev, "%s: could not parse node property\n",
292 of_node_full_name(np));
293 return ret;
294 }
295
296 *map = NULL;
297 *num_maps = 0;
298
299 if (function != NULL)
300 reserve++;
301 if (num_configs)
302 reserve++;
303
304 ret = pinctrl_utils_reserve_map(pctldev, map, &reserved_maps,
305 num_maps, reserve);
306 if (ret < 0)
307 goto out;
308
309 if (function) {
310 ret = pinctrl_utils_add_map_mux(pctldev, map,
311 &reserved_maps, num_maps,
312 grp->name, function);
313 if (ret < 0)
314 goto out;
315 }
316
317 if (num_configs) {
318 const char *group_or_pin;
319 unsigned int pin_id;
320
321 if (type == PIN_MAP_TYPE_CONFIGS_PIN) {
322 pin_id = grp->pins[0];
323 group_or_pin = pin_get_name(pctldev, pin_id);
324 } else {
325 group_or_pin = grp->name;
326 }
327
328 ret = pinctrl_utils_add_map_configs(pctldev, map,
329 &reserved_maps, num_maps,
330 group_or_pin, configs,
331 num_configs, type);
332 }
333
334out:
335 kfree(configs);
336 return ret;
337}
338
339static void sprd_pctrl_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
340 unsigned int offset)
341{
342 seq_printf(s, "%s", dev_name(pctldev->dev));
343}
344
345static const struct pinctrl_ops sprd_pctrl_ops = {
346 .get_groups_count = sprd_pctrl_group_count,
347 .get_group_name = sprd_pctrl_group_name,
348 .get_group_pins = sprd_pctrl_group_pins,
349 .pin_dbg_show = sprd_pctrl_dbg_show,
350 .dt_node_to_map = sprd_dt_node_to_map,
351 .dt_free_map = pinctrl_utils_free_map,
352};
353
Colin Ian King045b5792017-09-04 11:53:22 +0100354static int sprd_pmx_get_function_count(struct pinctrl_dev *pctldev)
Baolin Wang41d32cf2017-08-17 14:50:38 +0800355{
356 return PIN_FUNC_MAX;
357}
358
Colin Ian King045b5792017-09-04 11:53:22 +0100359static const char *sprd_pmx_get_function_name(struct pinctrl_dev *pctldev,
360 unsigned int selector)
Baolin Wang41d32cf2017-08-17 14:50:38 +0800361{
362 switch (selector) {
363 case PIN_FUNC_1:
364 return "func1";
365 case PIN_FUNC_2:
366 return "func2";
367 case PIN_FUNC_3:
368 return "func3";
369 case PIN_FUNC_4:
370 return "func4";
371 default:
372 return "null";
373 }
374}
375
Colin Ian King045b5792017-09-04 11:53:22 +0100376static int sprd_pmx_get_function_groups(struct pinctrl_dev *pctldev,
377 unsigned int selector,
378 const char * const **groups,
379 unsigned int * const num_groups)
Baolin Wang41d32cf2017-08-17 14:50:38 +0800380{
381 struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
382 struct sprd_pinctrl_soc_info *info = pctl->info;
383
384 *groups = info->grp_names;
385 *num_groups = info->ngroups;
386
387 return 0;
388}
389
390static int sprd_pmx_set_mux(struct pinctrl_dev *pctldev,
391 unsigned int func_selector,
392 unsigned int group_selector)
393{
394 struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
395 struct sprd_pinctrl_soc_info *info = pctl->info;
396 struct sprd_pin_group *grp = &info->groups[group_selector];
397 unsigned int i, grp_pins = grp->npins;
398 unsigned long reg;
399 unsigned int val = 0;
400
Dan Carpenter4ce504c2017-09-07 14:12:05 +0300401 if (group_selector >= info->ngroups)
Baolin Wang41d32cf2017-08-17 14:50:38 +0800402 return -EINVAL;
403
404 switch (func_selector) {
405 case PIN_FUNC_1:
406 val &= PIN_FUNC_SEL_1;
407 break;
408 case PIN_FUNC_2:
409 val |= PIN_FUNC_SEL_2;
410 break;
411 case PIN_FUNC_3:
412 val |= PIN_FUNC_SEL_3;
413 break;
414 case PIN_FUNC_4:
415 val |= PIN_FUNC_SEL_4;
416 break;
417 default:
418 break;
419 }
420
421 for (i = 0; i < grp_pins; i++) {
422 unsigned int pin_id = grp->pins[i];
423 struct sprd_pin *pin = sprd_pinctrl_get_pin_by_id(pctl, pin_id);
424
425 if (!pin || pin->type != COMMON_PIN)
426 continue;
427
428 reg = readl((void __iomem *)pin->reg);
429 reg &= ~PIN_FUNC_MASK;
430 reg |= val;
431 writel(reg, (void __iomem *)pin->reg);
432 }
433
434 return 0;
435}
436
437static const struct pinmux_ops sprd_pmx_ops = {
438 .get_functions_count = sprd_pmx_get_function_count,
439 .get_function_name = sprd_pmx_get_function_name,
440 .get_function_groups = sprd_pmx_get_function_groups,
441 .set_mux = sprd_pmx_set_mux,
442};
443
444static int sprd_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin_id,
445 unsigned long *config)
446{
447 struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
448 struct sprd_pin *pin = sprd_pinctrl_get_pin_by_id(pctl, pin_id);
449 unsigned int param = pinconf_to_config_param(*config);
450 unsigned int reg, arg;
451
452 if (!pin)
453 return -EINVAL;
454
455 if (pin->type == GLOBAL_CTRL_PIN) {
456 reg = (readl((void __iomem *)pin->reg) >>
457 pin->bit_offset) & PINCTRL_BIT_MASK(pin->bit_width);
458 } else {
459 reg = readl((void __iomem *)pin->reg);
460 }
461
462 if (pin->type == GLOBAL_CTRL_PIN &&
463 param == SPRD_PIN_CONFIG_CONTROL) {
464 arg = reg;
465 } else if (pin->type == COMMON_PIN) {
466 switch (param) {
467 case SPRD_PIN_CONFIG_SLEEP_MODE:
468 arg = (reg >> SLEEP_MODE_SHIFT) & SLEEP_MODE_MASK;
469 break;
470 case PIN_CONFIG_INPUT_ENABLE:
471 arg = (reg >> SLEEP_INPUT_SHIFT) & SLEEP_INPUT_MASK;
472 break;
473 case PIN_CONFIG_OUTPUT:
474 arg = reg & SLEEP_OUTPUT_MASK;
475 break;
476 case PIN_CONFIG_SLEEP_HARDWARE_STATE:
477 arg = 0;
478 break;
479 default:
480 return -ENOTSUPP;
481 }
482 } else if (pin->type == MISC_PIN) {
483 switch (param) {
484 case PIN_CONFIG_DRIVE_STRENGTH:
485 arg = (reg >> DRIVE_STRENGTH_SHIFT) &
486 DRIVE_STRENGTH_MASK;
487 break;
488 case PIN_CONFIG_BIAS_PULL_DOWN:
489 /* combine sleep pull down and pull down config */
490 arg = ((reg >> SLEEP_PULL_DOWN_SHIFT) &
491 SLEEP_PULL_DOWN_MASK) << 16;
492 arg |= (reg >> PULL_DOWN_SHIFT) & PULL_DOWN_MASK;
493 break;
494 case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
495 arg = (reg >> INPUT_SCHMITT_SHIFT) & INPUT_SCHMITT_MASK;
496 break;
497 case PIN_CONFIG_BIAS_PULL_UP:
498 /* combine sleep pull up and pull up config */
499 arg = ((reg >> SLEEP_PULL_UP_SHIFT) &
500 SLEEP_PULL_UP_MASK) << 16;
501 arg |= (reg >> PULL_UP_SHIFT) & PULL_UP_MASK;
502 break;
503 case PIN_CONFIG_SLEEP_HARDWARE_STATE:
504 arg = 0;
505 break;
506 default:
507 return -ENOTSUPP;
508 }
509 } else {
510 return -ENOTSUPP;
511 }
512
513 *config = pinconf_to_config_packed(param, arg);
514 return 0;
515}
516
517static unsigned int sprd_pinconf_drive(unsigned int mA)
518{
519 unsigned int val = 0;
520
521 switch (mA) {
522 case 2:
523 break;
524 case 4:
525 val |= BIT(19);
526 break;
527 case 6:
528 val |= BIT(20);
529 break;
530 case 8:
531 val |= BIT(19) | BIT(20);
532 break;
533 case 10:
534 val |= BIT(21);
535 break;
536 case 12:
537 val |= BIT(21) | BIT(19);
538 break;
539 case 14:
540 val |= BIT(21) | BIT(20);
541 break;
542 case 16:
543 val |= BIT(19) | BIT(20) | BIT(21);
544 break;
545 case 20:
546 val |= BIT(22);
547 break;
548 case 21:
549 val |= BIT(22) | BIT(19);
550 break;
551 case 24:
552 val |= BIT(22) | BIT(20);
553 break;
554 case 25:
555 val |= BIT(22) | BIT(20) | BIT(19);
556 break;
557 case 27:
558 val |= BIT(22) | BIT(21);
559 break;
560 case 29:
561 val |= BIT(22) | BIT(21) | BIT(19);
562 break;
563 case 31:
564 val |= BIT(22) | BIT(21) | BIT(20);
565 break;
566 case 33:
567 val |= BIT(22) | BIT(21) | BIT(20) | BIT(19);
568 break;
569 default:
570 break;
571 }
572
573 return val;
574}
575
576static bool sprd_pinctrl_check_sleep_config(unsigned long *configs,
577 unsigned int num_configs)
578{
579 unsigned int param;
580 int i;
581
582 for (i = 0; i < num_configs; i++) {
583 param = pinconf_to_config_param(configs[i]);
584 if (param == PIN_CONFIG_SLEEP_HARDWARE_STATE)
585 return true;
586 }
587
588 return false;
589}
590
591static int sprd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin_id,
592 unsigned long *configs, unsigned int num_configs)
593{
594 struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
595 struct sprd_pin *pin = sprd_pinctrl_get_pin_by_id(pctl, pin_id);
596 bool is_sleep_config;
597 unsigned long reg;
598 int i;
599
600 if (!pin)
601 return -EINVAL;
602
603 is_sleep_config = sprd_pinctrl_check_sleep_config(configs, num_configs);
604
605 for (i = 0; i < num_configs; i++) {
606 unsigned int param, arg, shift, mask, val;
607
608 param = pinconf_to_config_param(configs[i]);
609 arg = pinconf_to_config_argument(configs[i]);
610
611 val = 0;
612 shift = 0;
613 mask = 0;
614 if (pin->type == GLOBAL_CTRL_PIN &&
615 param == SPRD_PIN_CONFIG_CONTROL) {
616 val = arg;
617 } else if (pin->type == COMMON_PIN) {
618 switch (param) {
619 case SPRD_PIN_CONFIG_SLEEP_MODE:
620 if (arg & AP_SLEEP)
621 val |= AP_SLEEP_MODE;
622 if (arg & PUBCP_SLEEP)
623 val |= PUBCP_SLEEP_MODE;
624 if (arg & TGLDSP_SLEEP)
625 val |= TGLDSP_SLEEP_MODE;
626 if (arg & AGDSP_SLEEP)
627 val |= AGDSP_SLEEP_MODE;
628
629 mask = SLEEP_MODE_MASK;
630 shift = SLEEP_MODE_SHIFT;
631 break;
632 case PIN_CONFIG_INPUT_ENABLE:
633 if (is_sleep_config == true) {
634 if (arg > 0)
635 val |= SLEEP_INPUT;
636 else
637 val &= ~SLEEP_INPUT;
638
639 mask = SLEEP_INPUT_MASK;
640 shift = SLEEP_INPUT_SHIFT;
641 }
642 break;
643 case PIN_CONFIG_OUTPUT:
644 if (is_sleep_config == true) {
645 val |= SLEEP_OUTPUT;
646 mask = SLEEP_OUTPUT_MASK;
647 shift = SLEEP_OUTPUT_SHIFT;
648 }
649 break;
650 case PIN_CONFIG_SLEEP_HARDWARE_STATE:
651 continue;
652 default:
653 return -ENOTSUPP;
654 }
655 } else if (pin->type == MISC_PIN) {
656 switch (param) {
657 case PIN_CONFIG_DRIVE_STRENGTH:
658 if (arg < 2 || arg > 60)
659 return -EINVAL;
660
661 val = sprd_pinconf_drive(arg);
662 mask = DRIVE_STRENGTH_MASK;
663 shift = DRIVE_STRENGTH_SHIFT;
664 break;
665 case PIN_CONFIG_BIAS_PULL_DOWN:
666 if (is_sleep_config == true) {
667 val |= SLEEP_PULL_DOWN;
668 mask = SLEEP_PULL_DOWN_MASK;
669 shift = SLEEP_PULL_DOWN_SHIFT;
670 } else {
671 val |= PULL_DOWN;
672 mask = PULL_DOWN_MASK;
673 shift = PULL_DOWN_SHIFT;
674 }
675 break;
676 case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
677 if (arg > 0)
678 val |= INPUT_SCHMITT;
679 else
680 val &= ~INPUT_SCHMITT;
681
682 mask = INPUT_SCHMITT_MASK;
683 shift = INPUT_SCHMITT_SHIFT;
684 break;
685 case PIN_CONFIG_BIAS_PULL_UP:
686 if (is_sleep_config == true) {
687 val |= SLEEP_PULL_UP;
688 mask = SLEEP_PULL_UP_MASK;
689 shift = SLEEP_PULL_UP_SHIFT;
690 } else {
691 if (arg == 20000)
692 val |= PULL_UP_20K;
693 else if (arg == 4700)
694 val |= PULL_UP_4_7K;
695
696 mask = PULL_UP_MASK;
697 shift = PULL_UP_SHIFT;
698 }
699 break;
700 case PIN_CONFIG_SLEEP_HARDWARE_STATE:
701 continue;
702 default:
703 return -ENOTSUPP;
704 }
705 } else {
706 return -ENOTSUPP;
707 }
708
709 if (pin->type == GLOBAL_CTRL_PIN) {
710 reg = readl((void __iomem *)pin->reg);
711 reg &= ~(PINCTRL_BIT_MASK(pin->bit_width)
712 << pin->bit_offset);
713 reg |= (val & PINCTRL_BIT_MASK(pin->bit_width))
714 << pin->bit_offset;
715 writel(reg, (void __iomem *)pin->reg);
716 } else {
717 reg = readl((void __iomem *)pin->reg);
718 reg &= ~(mask << shift);
719 reg |= val;
720 writel(reg, (void __iomem *)pin->reg);
721 }
722 }
723
724 return 0;
725}
726
727static int sprd_pinconf_group_get(struct pinctrl_dev *pctldev,
728 unsigned int selector, unsigned long *config)
729{
730 struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
731 struct sprd_pinctrl_soc_info *info = pctl->info;
732 struct sprd_pin_group *grp;
733 unsigned int pin_id;
734
Dan Carpenter4ce504c2017-09-07 14:12:05 +0300735 if (selector >= info->ngroups)
Baolin Wang41d32cf2017-08-17 14:50:38 +0800736 return -EINVAL;
737
738 grp = &info->groups[selector];
739 pin_id = grp->pins[0];
740
741 return sprd_pinconf_get(pctldev, pin_id, config);
742}
743
744static int sprd_pinconf_group_set(struct pinctrl_dev *pctldev,
745 unsigned int selector,
746 unsigned long *configs,
747 unsigned int num_configs)
748{
749 struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
750 struct sprd_pinctrl_soc_info *info = pctl->info;
751 struct sprd_pin_group *grp;
752 int ret, i;
753
Dan Carpenter4ce504c2017-09-07 14:12:05 +0300754 if (selector >= info->ngroups)
Baolin Wang41d32cf2017-08-17 14:50:38 +0800755 return -EINVAL;
756
757 grp = &info->groups[selector];
758
759 for (i = 0; i < grp->npins; i++) {
760 unsigned int pin_id = grp->pins[i];
761
762 ret = sprd_pinconf_set(pctldev, pin_id, configs, num_configs);
763 if (ret)
764 return ret;
765 }
766
767 return 0;
768}
769
770static int sprd_pinconf_get_config(struct pinctrl_dev *pctldev,
771 unsigned int pin_id,
772 unsigned long *config)
773{
774 struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
775 struct sprd_pin *pin = sprd_pinctrl_get_pin_by_id(pctl, pin_id);
776
777 if (!pin)
778 return -EINVAL;
779
780 if (pin->type == GLOBAL_CTRL_PIN) {
781 *config = (readl((void __iomem *)pin->reg) >>
782 pin->bit_offset) & PINCTRL_BIT_MASK(pin->bit_width);
783 } else {
784 *config = readl((void __iomem *)pin->reg);
785 }
786
787 return 0;
788}
789
790static void sprd_pinconf_dbg_show(struct pinctrl_dev *pctldev,
791 struct seq_file *s, unsigned int pin_id)
792{
793 unsigned long config;
794 int ret;
795
796 ret = sprd_pinconf_get_config(pctldev, pin_id, &config);
797 if (ret)
798 return;
799
800 seq_printf(s, "0x%lx", config);
801}
802
803static void sprd_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
804 struct seq_file *s,
805 unsigned int selector)
806{
807 struct sprd_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
808 struct sprd_pinctrl_soc_info *info = pctl->info;
809 struct sprd_pin_group *grp;
810 unsigned long config;
811 const char *name;
812 int i, ret;
813
Dan Carpenter4ce504c2017-09-07 14:12:05 +0300814 if (selector >= info->ngroups)
Baolin Wang41d32cf2017-08-17 14:50:38 +0800815 return;
816
817 grp = &info->groups[selector];
818
Markus Elfring9d2fc7c2018-01-13 12:42:14 +0100819 seq_putc(s, '\n');
Baolin Wang41d32cf2017-08-17 14:50:38 +0800820 for (i = 0; i < grp->npins; i++, config++) {
821 unsigned int pin_id = grp->pins[i];
822
823 name = pin_get_name(pctldev, pin_id);
824 ret = sprd_pinconf_get_config(pctldev, pin_id, &config);
825 if (ret)
826 return;
827
828 seq_printf(s, "%s: 0x%lx ", name, config);
829 }
830}
831
832static const struct pinconf_ops sprd_pinconf_ops = {
833 .is_generic = true,
834 .pin_config_get = sprd_pinconf_get,
835 .pin_config_set = sprd_pinconf_set,
836 .pin_config_group_get = sprd_pinconf_group_get,
837 .pin_config_group_set = sprd_pinconf_group_set,
838 .pin_config_dbg_show = sprd_pinconf_dbg_show,
839 .pin_config_group_dbg_show = sprd_pinconf_group_dbg_show,
840};
841
842static const struct pinconf_generic_params sprd_dt_params[] = {
843 {"sprd,control", SPRD_PIN_CONFIG_CONTROL, 0},
844 {"sprd,sleep-mode", SPRD_PIN_CONFIG_SLEEP_MODE, 0},
845};
846
847#ifdef CONFIG_DEBUG_FS
848static const struct pin_config_item sprd_conf_items[] = {
849 PCONFDUMP(SPRD_PIN_CONFIG_CONTROL, "global control", NULL, true),
850 PCONFDUMP(SPRD_PIN_CONFIG_SLEEP_MODE, "sleep mode", NULL, true),
851};
852#endif
853
854static struct pinctrl_desc sprd_pinctrl_desc = {
855 .pctlops = &sprd_pctrl_ops,
856 .pmxops = &sprd_pmx_ops,
857 .confops = &sprd_pinconf_ops,
858 .num_custom_params = ARRAY_SIZE(sprd_dt_params),
859 .custom_params = sprd_dt_params,
860#ifdef CONFIG_DEBUG_FS
861 .custom_conf_items = sprd_conf_items,
862#endif
863 .owner = THIS_MODULE,
864};
865
866static int sprd_pinctrl_parse_groups(struct device_node *np,
867 struct sprd_pinctrl *sprd_pctl,
868 struct sprd_pin_group *grp)
869{
870 struct property *prop;
871 const char *pin_name;
872 int ret, i = 0;
873
874 ret = of_property_count_strings(np, "pins");
875 if (ret < 0)
876 return ret;
877
878 grp->name = np->name;
879 grp->npins = ret;
Kees Cooka86854d2018-06-12 14:07:58 -0700880 grp->pins = devm_kcalloc(sprd_pctl->dev,
881 grp->npins, sizeof(unsigned int),
882 GFP_KERNEL);
Baolin Wang41d32cf2017-08-17 14:50:38 +0800883 if (!grp->pins)
884 return -ENOMEM;
885
886 of_property_for_each_string(np, "pins", prop, pin_name) {
887 ret = sprd_pinctrl_get_id_by_name(sprd_pctl, pin_name);
888 if (ret >= 0)
889 grp->pins[i++] = ret;
890 }
891
892 for (i = 0; i < grp->npins; i++) {
893 dev_dbg(sprd_pctl->dev,
894 "Group[%s] contains [%d] pins: id = %d\n",
895 grp->name, grp->npins, grp->pins[i]);
896 }
897
898 return 0;
899}
900
901static unsigned int sprd_pinctrl_get_groups(struct device_node *np)
902{
903 struct device_node *child;
904 unsigned int group_cnt, cnt;
905
906 group_cnt = of_get_child_count(np);
907
908 for_each_child_of_node(np, child) {
909 cnt = of_get_child_count(child);
910 if (cnt > 0)
911 group_cnt += cnt;
912 }
913
914 return group_cnt;
915}
916
917static int sprd_pinctrl_parse_dt(struct sprd_pinctrl *sprd_pctl)
918{
919 struct sprd_pinctrl_soc_info *info = sprd_pctl->info;
920 struct device_node *np = sprd_pctl->dev->of_node;
921 struct device_node *child, *sub_child;
922 struct sprd_pin_group *grp;
923 const char **temp;
924 int ret;
925
926 if (!np)
927 return -ENODEV;
928
929 info->ngroups = sprd_pinctrl_get_groups(np);
930 if (!info->ngroups)
931 return 0;
932
Kees Cooka86854d2018-06-12 14:07:58 -0700933 info->groups = devm_kcalloc(sprd_pctl->dev,
934 info->ngroups,
Baolin Wang41d32cf2017-08-17 14:50:38 +0800935 sizeof(struct sprd_pin_group),
936 GFP_KERNEL);
937 if (!info->groups)
938 return -ENOMEM;
939
Kees Cooka86854d2018-06-12 14:07:58 -0700940 info->grp_names = devm_kcalloc(sprd_pctl->dev,
941 info->ngroups, sizeof(char *),
Baolin Wang41d32cf2017-08-17 14:50:38 +0800942 GFP_KERNEL);
943 if (!info->grp_names)
944 return -ENOMEM;
945
946 temp = info->grp_names;
947 grp = info->groups;
948
949 for_each_child_of_node(np, child) {
950 ret = sprd_pinctrl_parse_groups(child, sprd_pctl, grp);
951 if (ret)
952 return ret;
953
954 *temp++ = grp->name;
955 grp++;
956
957 if (of_get_child_count(child) > 0) {
958 for_each_child_of_node(child, sub_child) {
959 ret = sprd_pinctrl_parse_groups(sub_child,
960 sprd_pctl, grp);
961 if (ret)
962 return ret;
963
964 *temp++ = grp->name;
965 grp++;
966 }
967 }
968 }
969
970 return 0;
971}
972
973static int sprd_pinctrl_add_pins(struct sprd_pinctrl *sprd_pctl,
974 struct sprd_pins_info *sprd_soc_pin_info,
975 int pins_cnt)
976{
977 struct sprd_pinctrl_soc_info *info = sprd_pctl->info;
978 unsigned int ctrl_pin = 0, com_pin = 0;
979 struct sprd_pin *pin;
980 int i;
981
982 info->npins = pins_cnt;
Kees Cooka86854d2018-06-12 14:07:58 -0700983 info->pins = devm_kcalloc(sprd_pctl->dev,
984 info->npins, sizeof(struct sprd_pin),
Baolin Wang41d32cf2017-08-17 14:50:38 +0800985 GFP_KERNEL);
986 if (!info->pins)
987 return -ENOMEM;
988
989 for (i = 0, pin = info->pins; i < info->npins; i++, pin++) {
990 unsigned int reg;
991
992 pin->name = sprd_soc_pin_info[i].name;
993 pin->type = sprd_soc_pin_info[i].type;
994 pin->number = sprd_soc_pin_info[i].num;
995 reg = sprd_soc_pin_info[i].reg;
996 if (pin->type == GLOBAL_CTRL_PIN) {
997 pin->reg = (unsigned long)sprd_pctl->base +
998 PINCTRL_REG_LEN * reg;
999 pin->bit_offset = sprd_soc_pin_info[i].bit_offset;
1000 pin->bit_width = sprd_soc_pin_info[i].bit_width;
1001 ctrl_pin++;
1002 } else if (pin->type == COMMON_PIN) {
1003 pin->reg = (unsigned long)sprd_pctl->base +
1004 PINCTRL_REG_OFFSET + PINCTRL_REG_LEN *
1005 (i - ctrl_pin);
1006 com_pin++;
1007 } else if (pin->type == MISC_PIN) {
1008 pin->reg = (unsigned long)sprd_pctl->base +
1009 PINCTRL_REG_MISC_OFFSET + PINCTRL_REG_LEN *
1010 (i - ctrl_pin - com_pin);
1011 }
1012 }
1013
1014 for (i = 0, pin = info->pins; i < info->npins; pin++, i++) {
1015 dev_dbg(sprd_pctl->dev, "pin name[%s-%d], type = %d, "
1016 "bit offset = %ld, bit width = %ld, reg = 0x%lx\n",
1017 pin->name, pin->number, pin->type,
1018 pin->bit_offset, pin->bit_width, pin->reg);
1019 }
1020
1021 return 0;
1022}
1023
1024int sprd_pinctrl_core_probe(struct platform_device *pdev,
1025 struct sprd_pins_info *sprd_soc_pin_info,
1026 int pins_cnt)
1027{
1028 struct sprd_pinctrl *sprd_pctl;
1029 struct sprd_pinctrl_soc_info *pinctrl_info;
1030 struct pinctrl_pin_desc *pin_desc;
1031 struct resource *res;
1032 int ret, i;
1033
1034 sprd_pctl = devm_kzalloc(&pdev->dev, sizeof(struct sprd_pinctrl),
1035 GFP_KERNEL);
1036 if (!sprd_pctl)
1037 return -ENOMEM;
1038
1039 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1040 sprd_pctl->base = devm_ioremap_resource(&pdev->dev, res);
1041 if (IS_ERR(sprd_pctl->base))
1042 return PTR_ERR(sprd_pctl->base);
1043
1044 pinctrl_info = devm_kzalloc(&pdev->dev,
1045 sizeof(struct sprd_pinctrl_soc_info),
1046 GFP_KERNEL);
1047 if (!pinctrl_info)
1048 return -ENOMEM;
1049
1050 sprd_pctl->info = pinctrl_info;
1051 sprd_pctl->dev = &pdev->dev;
1052 platform_set_drvdata(pdev, sprd_pctl);
1053
1054 ret = sprd_pinctrl_add_pins(sprd_pctl, sprd_soc_pin_info, pins_cnt);
1055 if (ret) {
1056 dev_err(&pdev->dev, "fail to add pins information\n");
1057 return ret;
1058 }
1059
Baolin Wang63e037b2018-09-27 17:15:08 +08001060 ret = sprd_pinctrl_parse_dt(sprd_pctl);
1061 if (ret) {
1062 dev_err(&pdev->dev, "fail to parse dt properties\n");
1063 return ret;
1064 }
1065
Kees Cooka86854d2018-06-12 14:07:58 -07001066 pin_desc = devm_kcalloc(&pdev->dev,
1067 pinctrl_info->npins,
Baolin Wang41d32cf2017-08-17 14:50:38 +08001068 sizeof(struct pinctrl_pin_desc),
1069 GFP_KERNEL);
1070 if (!pin_desc)
1071 return -ENOMEM;
1072
1073 for (i = 0; i < pinctrl_info->npins; i++) {
1074 pin_desc[i].number = pinctrl_info->pins[i].number;
1075 pin_desc[i].name = pinctrl_info->pins[i].name;
1076 pin_desc[i].drv_data = pinctrl_info;
1077 }
1078
1079 sprd_pinctrl_desc.pins = pin_desc;
1080 sprd_pinctrl_desc.name = dev_name(&pdev->dev);
1081 sprd_pinctrl_desc.npins = pinctrl_info->npins;
1082
1083 sprd_pctl->pctl = pinctrl_register(&sprd_pinctrl_desc,
1084 &pdev->dev, (void *)sprd_pctl);
1085 if (IS_ERR(sprd_pctl->pctl)) {
1086 dev_err(&pdev->dev, "could not register pinctrl driver\n");
1087 return PTR_ERR(sprd_pctl->pctl);
1088 }
1089
Baolin Wang41d32cf2017-08-17 14:50:38 +08001090 return 0;
1091}
1092
1093int sprd_pinctrl_remove(struct platform_device *pdev)
1094{
1095 struct sprd_pinctrl *sprd_pctl = platform_get_drvdata(pdev);
1096
1097 pinctrl_unregister(sprd_pctl->pctl);
1098 return 0;
1099}
1100
1101void sprd_pinctrl_shutdown(struct platform_device *pdev)
1102{
Dan Carpenter41470c32017-09-07 10:29:26 +03001103 struct pinctrl *pinctl;
Baolin Wang41d32cf2017-08-17 14:50:38 +08001104 struct pinctrl_state *state;
1105
Dan Carpenter41470c32017-09-07 10:29:26 +03001106 pinctl = devm_pinctrl_get(&pdev->dev);
1107 if (IS_ERR(pinctl))
1108 return;
Baolin Wang41d32cf2017-08-17 14:50:38 +08001109 state = pinctrl_lookup_state(pinctl, "shutdown");
Dan Carpenter41470c32017-09-07 10:29:26 +03001110 if (IS_ERR(state))
1111 return;
1112 pinctrl_select_state(pinctl, state);
Baolin Wang41d32cf2017-08-17 14:50:38 +08001113}
1114
1115MODULE_DESCRIPTION("SPREADTRUM Pin Controller Driver");
1116MODULE_AUTHOR("Baolin Wang <baolin.wang@spreadtrum.com>");
1117MODULE_LICENSE("GPL v2");