diff options
author | Patrice Chotard <patrice.chotard@st.com> | 2016-04-29 10:25:43 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2016-05-10 07:48:26 -0400 |
commit | 3beed93c16170eacbfaa189dd4c1dc71866d3d3a (patch) | |
tree | 3f1a048959d05235c07610893ac5c5c1650bb026 /drivers/pinctrl | |
parent | caee57ec71e1a0cb50b6028c706cfe541dcb080a (diff) |
pinctrl: stm32: Implement .pin_config_dbg_show()
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r-- | drivers/pinctrl/stm32/pinctrl-stm32.c | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index 72b790450118..e51c1cf5270b 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c | |||
@@ -454,6 +454,29 @@ static void stm32_pmx_set_mode(struct stm32_gpio_bank *bank, | |||
454 | clk_disable(bank->clk); | 454 | clk_disable(bank->clk); |
455 | } | 455 | } |
456 | 456 | ||
457 | static void stm32_pmx_get_mode(struct stm32_gpio_bank *bank, | ||
458 | int pin, u32 *mode, u32 *alt) | ||
459 | { | ||
460 | u32 val; | ||
461 | int alt_shift = (pin % 8) * 4; | ||
462 | int alt_offset = STM32_GPIO_AFRL + (pin / 8) * 4; | ||
463 | unsigned long flags; | ||
464 | |||
465 | clk_enable(bank->clk); | ||
466 | spin_lock_irqsave(&bank->lock, flags); | ||
467 | |||
468 | val = readl_relaxed(bank->base + alt_offset); | ||
469 | val &= GENMASK(alt_shift + 3, alt_shift); | ||
470 | *alt = val >> alt_shift; | ||
471 | |||
472 | val = readl_relaxed(bank->base + STM32_GPIO_MODER); | ||
473 | val &= GENMASK(pin * 2 + 1, pin * 2); | ||
474 | *mode = val >> (pin * 2); | ||
475 | |||
476 | spin_unlock_irqrestore(&bank->lock, flags); | ||
477 | clk_disable(bank->clk); | ||
478 | } | ||
479 | |||
457 | static int stm32_pmx_set_mux(struct pinctrl_dev *pctldev, | 480 | static int stm32_pmx_set_mux(struct pinctrl_dev *pctldev, |
458 | unsigned function, | 481 | unsigned function, |
459 | unsigned group) | 482 | unsigned group) |
@@ -525,6 +548,24 @@ static void stm32_pconf_set_driving(struct stm32_gpio_bank *bank, | |||
525 | clk_disable(bank->clk); | 548 | clk_disable(bank->clk); |
526 | } | 549 | } |
527 | 550 | ||
551 | static u32 stm32_pconf_get_driving(struct stm32_gpio_bank *bank, | ||
552 | unsigned int offset) | ||
553 | { | ||
554 | unsigned long flags; | ||
555 | u32 val; | ||
556 | |||
557 | clk_enable(bank->clk); | ||
558 | spin_lock_irqsave(&bank->lock, flags); | ||
559 | |||
560 | val = readl_relaxed(bank->base + STM32_GPIO_TYPER); | ||
561 | val &= BIT(offset); | ||
562 | |||
563 | spin_unlock_irqrestore(&bank->lock, flags); | ||
564 | clk_disable(bank->clk); | ||
565 | |||
566 | return (val >> offset); | ||
567 | } | ||
568 | |||
528 | static void stm32_pconf_set_speed(struct stm32_gpio_bank *bank, | 569 | static void stm32_pconf_set_speed(struct stm32_gpio_bank *bank, |
529 | unsigned offset, u32 speed) | 570 | unsigned offset, u32 speed) |
530 | { | 571 | { |
@@ -543,6 +584,24 @@ static void stm32_pconf_set_speed(struct stm32_gpio_bank *bank, | |||
543 | clk_disable(bank->clk); | 584 | clk_disable(bank->clk); |
544 | } | 585 | } |
545 | 586 | ||
587 | static u32 stm32_pconf_get_speed(struct stm32_gpio_bank *bank, | ||
588 | unsigned int offset) | ||
589 | { | ||
590 | unsigned long flags; | ||
591 | u32 val; | ||
592 | |||
593 | clk_enable(bank->clk); | ||
594 | spin_lock_irqsave(&bank->lock, flags); | ||
595 | |||
596 | val = readl_relaxed(bank->base + STM32_GPIO_SPEEDR); | ||
597 | val &= GENMASK(offset * 2 + 1, offset * 2); | ||
598 | |||
599 | spin_unlock_irqrestore(&bank->lock, flags); | ||
600 | clk_disable(bank->clk); | ||
601 | |||
602 | return (val >> (offset * 2)); | ||
603 | } | ||
604 | |||
546 | static void stm32_pconf_set_bias(struct stm32_gpio_bank *bank, | 605 | static void stm32_pconf_set_bias(struct stm32_gpio_bank *bank, |
547 | unsigned offset, u32 bias) | 606 | unsigned offset, u32 bias) |
548 | { | 607 | { |
@@ -561,6 +620,57 @@ static void stm32_pconf_set_bias(struct stm32_gpio_bank *bank, | |||
561 | clk_disable(bank->clk); | 620 | clk_disable(bank->clk); |
562 | } | 621 | } |
563 | 622 | ||
623 | static u32 stm32_pconf_get_bias(struct stm32_gpio_bank *bank, | ||
624 | unsigned int offset) | ||
625 | { | ||
626 | unsigned long flags; | ||
627 | u32 val; | ||
628 | |||
629 | clk_enable(bank->clk); | ||
630 | spin_lock_irqsave(&bank->lock, flags); | ||
631 | |||
632 | val = readl_relaxed(bank->base + STM32_GPIO_PUPDR); | ||
633 | val &= GENMASK(offset * 2 + 1, offset * 2); | ||
634 | |||
635 | spin_unlock_irqrestore(&bank->lock, flags); | ||
636 | clk_disable(bank->clk); | ||
637 | |||
638 | return (val >> (offset * 2)); | ||
639 | } | ||
640 | |||
641 | static bool stm32_pconf_input_get(struct stm32_gpio_bank *bank, | ||
642 | unsigned int offset) | ||
643 | { | ||
644 | unsigned long flags; | ||
645 | u32 val; | ||
646 | |||
647 | clk_enable(bank->clk); | ||
648 | spin_lock_irqsave(&bank->lock, flags); | ||
649 | |||
650 | val = !!(readl_relaxed(bank->base + STM32_GPIO_IDR) & BIT(offset)); | ||
651 | |||
652 | spin_unlock_irqrestore(&bank->lock, flags); | ||
653 | clk_disable(bank->clk); | ||
654 | |||
655 | return val; | ||
656 | } | ||
657 | |||
658 | static bool stm32_pconf_output_get(struct stm32_gpio_bank *bank, | ||
659 | unsigned int offset) | ||
660 | { | ||
661 | unsigned long flags; | ||
662 | u32 val; | ||
663 | |||
664 | clk_enable(bank->clk); | ||
665 | spin_lock_irqsave(&bank->lock, flags); | ||
666 | val = !!(readl_relaxed(bank->base + STM32_GPIO_ODR) & BIT(offset)); | ||
667 | |||
668 | spin_unlock_irqrestore(&bank->lock, flags); | ||
669 | clk_disable(bank->clk); | ||
670 | |||
671 | return val; | ||
672 | } | ||
673 | |||
564 | static int stm32_pconf_parse_conf(struct pinctrl_dev *pctldev, | 674 | static int stm32_pconf_parse_conf(struct pinctrl_dev *pctldev, |
565 | unsigned int pin, enum pin_config_param param, | 675 | unsigned int pin, enum pin_config_param param, |
566 | enum pin_config_param arg) | 676 | enum pin_config_param arg) |
@@ -634,9 +744,73 @@ static int stm32_pconf_group_set(struct pinctrl_dev *pctldev, unsigned group, | |||
634 | return 0; | 744 | return 0; |
635 | } | 745 | } |
636 | 746 | ||
747 | static void stm32_pconf_dbg_show(struct pinctrl_dev *pctldev, | ||
748 | struct seq_file *s, | ||
749 | unsigned int pin) | ||
750 | { | ||
751 | struct pinctrl_gpio_range *range; | ||
752 | struct stm32_gpio_bank *bank; | ||
753 | int offset; | ||
754 | u32 mode, alt, drive, speed, bias; | ||
755 | static const char * const modes[] = { | ||
756 | "input", "output", "alternate", "analog" }; | ||
757 | static const char * const speeds[] = { | ||
758 | "low", "medium", "high", "very high" }; | ||
759 | static const char * const biasing[] = { | ||
760 | "floating", "pull up", "pull down", "" }; | ||
761 | bool val; | ||
762 | |||
763 | range = pinctrl_find_gpio_range_from_pin_nolock(pctldev, pin); | ||
764 | bank = gpio_range_to_bank(range); | ||
765 | offset = stm32_gpio_pin(pin); | ||
766 | |||
767 | stm32_pmx_get_mode(bank, offset, &mode, &alt); | ||
768 | bias = stm32_pconf_get_bias(bank, offset); | ||
769 | |||
770 | seq_printf(s, "%s ", modes[mode]); | ||
771 | |||
772 | switch (mode) { | ||
773 | /* input */ | ||
774 | case 0: | ||
775 | val = stm32_pconf_input_get(bank, offset); | ||
776 | seq_printf(s, "- %s - %s", | ||
777 | val ? "high" : "low", | ||
778 | biasing[bias]); | ||
779 | break; | ||
780 | |||
781 | /* output */ | ||
782 | case 1: | ||
783 | drive = stm32_pconf_get_driving(bank, offset); | ||
784 | speed = stm32_pconf_get_speed(bank, offset); | ||
785 | val = stm32_pconf_output_get(bank, offset); | ||
786 | seq_printf(s, "- %s - %s - %s - %s %s", | ||
787 | val ? "high" : "low", | ||
788 | drive ? "open drain" : "push pull", | ||
789 | biasing[bias], | ||
790 | speeds[speed], "speed"); | ||
791 | break; | ||
792 | |||
793 | /* alternate */ | ||
794 | case 2: | ||
795 | drive = stm32_pconf_get_driving(bank, offset); | ||
796 | speed = stm32_pconf_get_speed(bank, offset); | ||
797 | seq_printf(s, "%d - %s -%s", alt, | ||
798 | drive ? "open drain" : "push pull", | ||
799 | biasing[bias], | ||
800 | speeds[speed], "speed"); | ||
801 | break; | ||
802 | |||
803 | /* analog */ | ||
804 | case 3: | ||
805 | break; | ||
806 | } | ||
807 | } | ||
808 | |||
809 | |||
637 | static const struct pinconf_ops stm32_pconf_ops = { | 810 | static const struct pinconf_ops stm32_pconf_ops = { |
638 | .pin_config_group_get = stm32_pconf_group_get, | 811 | .pin_config_group_get = stm32_pconf_group_get, |
639 | .pin_config_group_set = stm32_pconf_group_set, | 812 | .pin_config_group_set = stm32_pconf_group_set, |
813 | .pin_config_dbg_show = stm32_pconf_dbg_show, | ||
640 | }; | 814 | }; |
641 | 815 | ||
642 | static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, | 816 | static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, |