1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Marvell Armada ap806 pinctrl driver based on mvebu pinctrl core |
4 | * |
5 | * Copyright (C) 2017 Marvell |
6 | * |
7 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> |
8 | * Hanna Hawa <hannah@marvell.com> |
9 | */ |
10 | |
11 | #include <linux/err.h> |
12 | #include <linux/init.h> |
13 | #include <linux/io.h> |
14 | #include <linux/platform_device.h> |
15 | #include <linux/of.h> |
16 | #include <linux/pinctrl/pinctrl.h> |
17 | |
18 | #include "pinctrl-mvebu.h" |
19 | |
20 | static struct mvebu_mpp_mode armada_ap806_mpp_modes[] = { |
21 | MPP_MODE(0, |
22 | MPP_FUNCTION(0, "gpio" , NULL), |
23 | MPP_FUNCTION(1, "sdio" , "clk" ), |
24 | MPP_FUNCTION(3, "spi0" , "clk" )), |
25 | MPP_MODE(1, |
26 | MPP_FUNCTION(0, "gpio" , NULL), |
27 | MPP_FUNCTION(1, "sdio" , "cmd" ), |
28 | MPP_FUNCTION(3, "spi0" , "miso" )), |
29 | MPP_MODE(2, |
30 | MPP_FUNCTION(0, "gpio" , NULL), |
31 | MPP_FUNCTION(1, "sdio" , "d0" ), |
32 | MPP_FUNCTION(3, "spi0" , "mosi" )), |
33 | MPP_MODE(3, |
34 | MPP_FUNCTION(0, "gpio" , NULL), |
35 | MPP_FUNCTION(1, "sdio" , "d1" ), |
36 | MPP_FUNCTION(3, "spi0" , "cs0n" )), |
37 | MPP_MODE(4, |
38 | MPP_FUNCTION(0, "gpio" , NULL), |
39 | MPP_FUNCTION(1, "sdio" , "d2" ), |
40 | MPP_FUNCTION(3, "i2c0" , "sda" )), |
41 | MPP_MODE(5, |
42 | MPP_FUNCTION(0, "gpio" , NULL), |
43 | MPP_FUNCTION(1, "sdio" , "d3" ), |
44 | MPP_FUNCTION(3, "i2c0" , "sdk" )), |
45 | MPP_MODE(6, |
46 | MPP_FUNCTION(0, "gpio" , NULL), |
47 | MPP_FUNCTION(1, "sdio" , "ds" )), |
48 | MPP_MODE(7, |
49 | MPP_FUNCTION(0, "gpio" , NULL), |
50 | MPP_FUNCTION(1, "sdio" , "d4" ), |
51 | MPP_FUNCTION(3, "uart1" , "rxd" )), |
52 | MPP_MODE(8, |
53 | MPP_FUNCTION(0, "gpio" , NULL), |
54 | MPP_FUNCTION(1, "sdio" , "d5" ), |
55 | MPP_FUNCTION(3, "uart1" , "txd" )), |
56 | MPP_MODE(9, |
57 | MPP_FUNCTION(0, "gpio" , NULL), |
58 | MPP_FUNCTION(1, "sdio" , "d6" ), |
59 | MPP_FUNCTION(3, "spi0" , "cs1n" )), |
60 | MPP_MODE(10, |
61 | MPP_FUNCTION(0, "gpio" , NULL), |
62 | MPP_FUNCTION(1, "sdio" , "d7" )), |
63 | MPP_MODE(11, |
64 | MPP_FUNCTION(0, "gpio" , NULL), |
65 | MPP_FUNCTION(3, "uart0" , "txd" )), |
66 | MPP_MODE(12, |
67 | MPP_FUNCTION(0, "gpio" , NULL), |
68 | MPP_FUNCTION(1, "sdio" , "pw_off" ), |
69 | MPP_FUNCTION(2, "sdio" , "hw_rst" )), |
70 | MPP_MODE(13, |
71 | MPP_FUNCTION(0, "gpio" , NULL)), |
72 | MPP_MODE(14, |
73 | MPP_FUNCTION(0, "gpio" , NULL)), |
74 | MPP_MODE(15, |
75 | MPP_FUNCTION(0, "gpio" , NULL)), |
76 | MPP_MODE(16, |
77 | MPP_FUNCTION(0, "gpio" , NULL)), |
78 | MPP_MODE(17, |
79 | MPP_FUNCTION(0, "gpio" , NULL)), |
80 | MPP_MODE(18, |
81 | MPP_FUNCTION(0, "gpio" , NULL)), |
82 | MPP_MODE(19, |
83 | MPP_FUNCTION(0, "gpio" , NULL), |
84 | MPP_FUNCTION(3, "uart0" , "rxd" ), |
85 | MPP_FUNCTION(4, "sdio" , "pw_off" )), |
86 | }; |
87 | |
88 | static struct mvebu_pinctrl_soc_info armada_ap806_pinctrl_info; |
89 | |
90 | static const struct of_device_id armada_ap806_pinctrl_of_match[] = { |
91 | { |
92 | .compatible = "marvell,ap806-pinctrl" , |
93 | }, |
94 | { }, |
95 | }; |
96 | |
97 | static const struct mvebu_mpp_ctrl armada_ap806_mpp_controls[] = { |
98 | MPP_FUNC_CTRL(0, 19, NULL, mvebu_regmap_mpp_ctrl), |
99 | }; |
100 | |
101 | static struct pinctrl_gpio_range armada_ap806_mpp_gpio_ranges[] = { |
102 | MPP_GPIO_RANGE(0, 0, 0, 20), |
103 | }; |
104 | |
105 | static int armada_ap806_pinctrl_probe(struct platform_device *pdev) |
106 | { |
107 | struct mvebu_pinctrl_soc_info *soc = &armada_ap806_pinctrl_info; |
108 | |
109 | if (!pdev->dev.parent) |
110 | return -ENODEV; |
111 | |
112 | soc->variant = 0; /* no variants for Armada AP806 */ |
113 | soc->controls = armada_ap806_mpp_controls; |
114 | soc->ncontrols = ARRAY_SIZE(armada_ap806_mpp_controls); |
115 | soc->gpioranges = armada_ap806_mpp_gpio_ranges; |
116 | soc->ngpioranges = ARRAY_SIZE(armada_ap806_mpp_gpio_ranges); |
117 | soc->modes = armada_ap806_mpp_modes; |
118 | soc->nmodes = armada_ap806_mpp_controls[0].npins; |
119 | |
120 | pdev->dev.platform_data = soc; |
121 | |
122 | return mvebu_pinctrl_simple_regmap_probe(pdev, syscon_dev: pdev->dev.parent, offset: 0); |
123 | } |
124 | |
125 | static struct platform_driver armada_ap806_pinctrl_driver = { |
126 | .driver = { |
127 | .name = "armada-ap806-pinctrl" , |
128 | .of_match_table = of_match_ptr(armada_ap806_pinctrl_of_match), |
129 | }, |
130 | .probe = armada_ap806_pinctrl_probe, |
131 | }; |
132 | |
133 | builtin_platform_driver(armada_ap806_pinctrl_driver); |
134 | |