xref: /openbmc/linux/drivers/pinctrl/pinctrl-k210.c (revision 060f35a317ef09101b128f399dce7ed13d019461)
1d4c34d09SDamien Le Moal // SPDX-License-Identifier: GPL-2.0-or-later
2d4c34d09SDamien Le Moal /*
3d4c34d09SDamien Le Moal  * Copyright (C) 2020 Sean Anderson <seanga2@gmail.com>
4d4c34d09SDamien Le Moal  * Copyright (c) 2020 Western Digital Corporation or its affiliates.
5d4c34d09SDamien Le Moal  */
6d4c34d09SDamien Le Moal #include <linux/bitfield.h>
793c9dc90SAndy Shevchenko #include <linux/clk.h>
893c9dc90SAndy Shevchenko #include <linux/io.h>
993c9dc90SAndy Shevchenko #include <linux/mfd/syscon.h>
10060f03e9SRob Herring #include <linux/of.h>
1193c9dc90SAndy Shevchenko #include <linux/platform_device.h>
12d4c34d09SDamien Le Moal #include <linux/regmap.h>
1393c9dc90SAndy Shevchenko #include <linux/seq_file.h>
14d4c34d09SDamien Le Moal #include <linux/slab.h>
1593c9dc90SAndy Shevchenko 
1693c9dc90SAndy Shevchenko #include <linux/pinctrl/pinconf-generic.h>
1793c9dc90SAndy Shevchenko #include <linux/pinctrl/pinconf.h>
18d4c34d09SDamien Le Moal #include <linux/pinctrl/pinctrl.h>
19d4c34d09SDamien Le Moal #include <linux/pinctrl/pinmux.h>
20d4c34d09SDamien Le Moal 
21d4c34d09SDamien Le Moal #include <dt-bindings/pinctrl/k210-fpioa.h>
22d4c34d09SDamien Le Moal 
23d4c34d09SDamien Le Moal #include "core.h"
24d4c34d09SDamien Le Moal #include "pinconf.h"
25d4c34d09SDamien Le Moal #include "pinctrl-utils.h"
26d4c34d09SDamien Le Moal 
27d4c34d09SDamien Le Moal /*
28d4c34d09SDamien Le Moal  * The K210 only implements 8 drive levels, even though
29d4c34d09SDamien Le Moal  * there is register space for 16
30d4c34d09SDamien Le Moal  */
31d4c34d09SDamien Le Moal #define K210_PC_DRIVE_MASK	GENMASK(11, 8)
32d4c34d09SDamien Le Moal #define K210_PC_DRIVE_SHIFT	8
33d4c34d09SDamien Le Moal #define K210_PC_DRIVE_0		(0 << K210_PC_DRIVE_SHIFT)
34d4c34d09SDamien Le Moal #define K210_PC_DRIVE_1		(1 << K210_PC_DRIVE_SHIFT)
35d4c34d09SDamien Le Moal #define K210_PC_DRIVE_2		(2 << K210_PC_DRIVE_SHIFT)
36d4c34d09SDamien Le Moal #define K210_PC_DRIVE_3		(3 << K210_PC_DRIVE_SHIFT)
37d4c34d09SDamien Le Moal #define K210_PC_DRIVE_4		(4 << K210_PC_DRIVE_SHIFT)
38d4c34d09SDamien Le Moal #define K210_PC_DRIVE_5		(5 << K210_PC_DRIVE_SHIFT)
39d4c34d09SDamien Le Moal #define K210_PC_DRIVE_6		(6 << K210_PC_DRIVE_SHIFT)
40d4c34d09SDamien Le Moal #define K210_PC_DRIVE_7		(7 << K210_PC_DRIVE_SHIFT)
41d4c34d09SDamien Le Moal #define K210_PC_DRIVE_MAX	7
42d4c34d09SDamien Le Moal #define K210_PC_MODE_MASK	GENMASK(23, 12)
43d4c34d09SDamien Le Moal 
44d4c34d09SDamien Le Moal /*
45d4c34d09SDamien Le Moal  * output enabled == PC_OE & (PC_OE_INV ^ FUNCTION_OE)
46d4c34d09SDamien Le Moal  * where FUNCTION_OE is a physical signal from the function.
47d4c34d09SDamien Le Moal  */
48d4c34d09SDamien Le Moal #define K210_PC_OE		BIT(12) /* Output Enable */
49d4c34d09SDamien Le Moal #define K210_PC_OE_INV		BIT(13) /* INVert Output Enable */
50d4c34d09SDamien Le Moal #define K210_PC_DO_OE		BIT(14) /* set Data Out to Output Enable sig */
51d4c34d09SDamien Le Moal #define K210_PC_DO_INV		BIT(15) /* INVert final Data Output */
52d4c34d09SDamien Le Moal #define K210_PC_PU		BIT(16) /* Pull Up */
53d4c34d09SDamien Le Moal #define K210_PC_PD		BIT(17) /* Pull Down */
54d4c34d09SDamien Le Moal /* Strong pull up not implemented on K210 */
55d4c34d09SDamien Le Moal #define K210_PC_SL		BIT(19) /* reduce SLew rate */
56d4c34d09SDamien Le Moal /* Same semantics as OE above */
57d4c34d09SDamien Le Moal #define K210_PC_IE		BIT(20) /* Input Enable */
58d4c34d09SDamien Le Moal #define K210_PC_IE_INV		BIT(21) /* INVert Input Enable */
59d4c34d09SDamien Le Moal #define K210_PC_DI_INV		BIT(22) /* INVert Data Input */
60d4c34d09SDamien Le Moal #define K210_PC_ST		BIT(23) /* Schmitt Trigger */
61d4c34d09SDamien Le Moal #define K210_PC_DI		BIT(31) /* raw Data Input */
62d4c34d09SDamien Le Moal 
63d4c34d09SDamien Le Moal #define K210_PC_BIAS_MASK	(K210_PC_PU & K210_PC_PD)
64d4c34d09SDamien Le Moal 
65d4c34d09SDamien Le Moal #define K210_PC_MODE_IN		(K210_PC_IE | K210_PC_ST)
66d4c34d09SDamien Le Moal #define K210_PC_MODE_OUT	(K210_PC_DRIVE_7 | K210_PC_OE)
67d4c34d09SDamien Le Moal #define K210_PC_MODE_I2C	(K210_PC_MODE_IN | K210_PC_SL | \
68d4c34d09SDamien Le Moal 				 K210_PC_OE | K210_PC_PU)
69d4c34d09SDamien Le Moal #define K210_PC_MODE_SCCB	(K210_PC_MODE_I2C | \
70d4c34d09SDamien Le Moal 				 K210_PC_OE_INV | K210_PC_IE_INV)
71d4c34d09SDamien Le Moal #define K210_PC_MODE_SPI	(K210_PC_MODE_IN | K210_PC_IE_INV | \
72d4c34d09SDamien Le Moal 				 K210_PC_MODE_OUT | K210_PC_OE_INV)
73d4c34d09SDamien Le Moal #define K210_PC_MODE_GPIO	(K210_PC_MODE_IN | K210_PC_MODE_OUT)
74d4c34d09SDamien Le Moal 
75d4c34d09SDamien Le Moal #define K210_PG_FUNC		GENMASK(7, 0)
76d4c34d09SDamien Le Moal #define K210_PG_DO		BIT(8)
77d4c34d09SDamien Le Moal #define K210_PG_PIN		GENMASK(22, 16)
78d4c34d09SDamien Le Moal 
79d4c34d09SDamien Le Moal /*
80d4c34d09SDamien Le Moal  * struct k210_fpioa: Kendryte K210 FPIOA memory mapped registers
81d4c34d09SDamien Le Moal  * @pins: 48 32-bits IO pin registers
82d4c34d09SDamien Le Moal  * @tie_en: 256 (one per function) input tie enable bits
83d4c34d09SDamien Le Moal  * @tie_val: 256 (one per function) input tie value bits
84d4c34d09SDamien Le Moal  */
85d4c34d09SDamien Le Moal struct k210_fpioa {
86d4c34d09SDamien Le Moal 	u32 pins[48];
87d4c34d09SDamien Le Moal 	u32 tie_en[8];
88d4c34d09SDamien Le Moal 	u32 tie_val[8];
89d4c34d09SDamien Le Moal };
90d4c34d09SDamien Le Moal 
91d4c34d09SDamien Le Moal struct k210_fpioa_data {
92d4c34d09SDamien Le Moal 
93d4c34d09SDamien Le Moal 	struct device *dev;
94d4c34d09SDamien Le Moal 	struct pinctrl_dev *pctl;
95d4c34d09SDamien Le Moal 
96d4c34d09SDamien Le Moal 	struct k210_fpioa __iomem *fpioa;
97d4c34d09SDamien Le Moal 	struct regmap *sysctl_map;
98d4c34d09SDamien Le Moal 	u32 power_offset;
99d4c34d09SDamien Le Moal 	struct clk *clk;
100d4c34d09SDamien Le Moal 	struct clk *pclk;
101d4c34d09SDamien Le Moal };
102d4c34d09SDamien Le Moal 
103d4c34d09SDamien Le Moal #define K210_PIN_NAME(i)	("IO_" #i)
104d4c34d09SDamien Le Moal #define K210_PIN(i)		[(i)] = PINCTRL_PIN((i), K210_PIN_NAME(i))
105d4c34d09SDamien Le Moal 
106d4c34d09SDamien Le Moal static const struct pinctrl_pin_desc k210_pins[] = {
107d4c34d09SDamien Le Moal 	K210_PIN(0),  K210_PIN(1),  K210_PIN(2),
108d4c34d09SDamien Le Moal 	K210_PIN(3),  K210_PIN(4),  K210_PIN(5),
109d4c34d09SDamien Le Moal 	K210_PIN(6),  K210_PIN(7),  K210_PIN(8),
110d4c34d09SDamien Le Moal 	K210_PIN(9),  K210_PIN(10), K210_PIN(11),
111d4c34d09SDamien Le Moal 	K210_PIN(12), K210_PIN(13), K210_PIN(14),
112d4c34d09SDamien Le Moal 	K210_PIN(15), K210_PIN(16), K210_PIN(17),
113d4c34d09SDamien Le Moal 	K210_PIN(18), K210_PIN(19), K210_PIN(20),
114d4c34d09SDamien Le Moal 	K210_PIN(21), K210_PIN(22), K210_PIN(23),
115d4c34d09SDamien Le Moal 	K210_PIN(24), K210_PIN(25), K210_PIN(26),
116d4c34d09SDamien Le Moal 	K210_PIN(27), K210_PIN(28), K210_PIN(29),
117d4c34d09SDamien Le Moal 	K210_PIN(30), K210_PIN(31), K210_PIN(32),
118d4c34d09SDamien Le Moal 	K210_PIN(33), K210_PIN(34), K210_PIN(35),
119d4c34d09SDamien Le Moal 	K210_PIN(36), K210_PIN(37), K210_PIN(38),
120d4c34d09SDamien Le Moal 	K210_PIN(39), K210_PIN(40), K210_PIN(41),
121d4c34d09SDamien Le Moal 	K210_PIN(42), K210_PIN(43), K210_PIN(44),
122d4c34d09SDamien Le Moal 	K210_PIN(45), K210_PIN(46), K210_PIN(47)
123d4c34d09SDamien Le Moal };
124d4c34d09SDamien Le Moal 
125d4c34d09SDamien Le Moal #define K210_NPINS ARRAY_SIZE(k210_pins)
126d4c34d09SDamien Le Moal 
127d4c34d09SDamien Le Moal /*
128d4c34d09SDamien Le Moal  * Pin groups: each of the 48 programmable pins is a group.
129d4c34d09SDamien Le Moal  * To this are added 8 power domain groups, which for the purposes of
130d4c34d09SDamien Le Moal  * the pin subsystem, contain no pins. The power domain groups only exist
131d4c34d09SDamien Le Moal  * to set the power level. The id should never be used (since there are
132d4c34d09SDamien Le Moal  * no pins 48-55).
133d4c34d09SDamien Le Moal  */
134d4c34d09SDamien Le Moal static const char *const k210_group_names[] = {
135d4c34d09SDamien Le Moal 	/* The first 48 groups are for pins, one each */
136d4c34d09SDamien Le Moal 	K210_PIN_NAME(0),  K210_PIN_NAME(1),  K210_PIN_NAME(2),
137d4c34d09SDamien Le Moal 	K210_PIN_NAME(3),  K210_PIN_NAME(4),  K210_PIN_NAME(5),
138d4c34d09SDamien Le Moal 	K210_PIN_NAME(6),  K210_PIN_NAME(7),  K210_PIN_NAME(8),
139d4c34d09SDamien Le Moal 	K210_PIN_NAME(9),  K210_PIN_NAME(10), K210_PIN_NAME(11),
140d4c34d09SDamien Le Moal 	K210_PIN_NAME(12), K210_PIN_NAME(13), K210_PIN_NAME(14),
141d4c34d09SDamien Le Moal 	K210_PIN_NAME(15), K210_PIN_NAME(16), K210_PIN_NAME(17),
142d4c34d09SDamien Le Moal 	K210_PIN_NAME(18), K210_PIN_NAME(19), K210_PIN_NAME(20),
143d4c34d09SDamien Le Moal 	K210_PIN_NAME(21), K210_PIN_NAME(22), K210_PIN_NAME(23),
144d4c34d09SDamien Le Moal 	K210_PIN_NAME(24), K210_PIN_NAME(25), K210_PIN_NAME(26),
145d4c34d09SDamien Le Moal 	K210_PIN_NAME(27), K210_PIN_NAME(28), K210_PIN_NAME(29),
146d4c34d09SDamien Le Moal 	K210_PIN_NAME(30), K210_PIN_NAME(31), K210_PIN_NAME(32),
147d4c34d09SDamien Le Moal 	K210_PIN_NAME(33), K210_PIN_NAME(34), K210_PIN_NAME(35),
148d4c34d09SDamien Le Moal 	K210_PIN_NAME(36), K210_PIN_NAME(37), K210_PIN_NAME(38),
149d4c34d09SDamien Le Moal 	K210_PIN_NAME(39), K210_PIN_NAME(40), K210_PIN_NAME(41),
150d4c34d09SDamien Le Moal 	K210_PIN_NAME(42), K210_PIN_NAME(43), K210_PIN_NAME(44),
151d4c34d09SDamien Le Moal 	K210_PIN_NAME(45), K210_PIN_NAME(46), K210_PIN_NAME(47),
152d4c34d09SDamien Le Moal 	[48] = "A0", [49] = "A1", [50] = "A2",
153d4c34d09SDamien Le Moal 	[51] = "B3", [52] = "B4", [53] = "B5",
154d4c34d09SDamien Le Moal 	[54] = "C6", [55] = "C7"
155d4c34d09SDamien Le Moal };
156d4c34d09SDamien Le Moal 
157d4c34d09SDamien Le Moal #define K210_NGROUPS	ARRAY_SIZE(k210_group_names)
158d4c34d09SDamien Le Moal 
159d4c34d09SDamien Le Moal enum k210_pinctrl_mode_id {
160d4c34d09SDamien Le Moal 	K210_PC_DEFAULT_DISABLED,
161d4c34d09SDamien Le Moal 	K210_PC_DEFAULT_IN,
162d4c34d09SDamien Le Moal 	K210_PC_DEFAULT_IN_TIE,
163d4c34d09SDamien Le Moal 	K210_PC_DEFAULT_OUT,
164d4c34d09SDamien Le Moal 	K210_PC_DEFAULT_I2C,
165d4c34d09SDamien Le Moal 	K210_PC_DEFAULT_SCCB,
166d4c34d09SDamien Le Moal 	K210_PC_DEFAULT_SPI,
167d4c34d09SDamien Le Moal 	K210_PC_DEFAULT_GPIO,
168d4c34d09SDamien Le Moal 	K210_PC_DEFAULT_INT13,
169d4c34d09SDamien Le Moal };
170d4c34d09SDamien Le Moal 
171d4c34d09SDamien Le Moal #define K210_PC_DEFAULT(mode) \
172d4c34d09SDamien Le Moal 	[K210_PC_DEFAULT_##mode] = K210_PC_MODE_##mode
173d4c34d09SDamien Le Moal 
174d4c34d09SDamien Le Moal static const u32 k210_pinconf_mode_id_to_mode[] = {
175d4c34d09SDamien Le Moal 	[K210_PC_DEFAULT_DISABLED] = 0,
176d4c34d09SDamien Le Moal 	K210_PC_DEFAULT(IN),
177d4c34d09SDamien Le Moal 	[K210_PC_DEFAULT_IN_TIE] = K210_PC_MODE_IN,
178d4c34d09SDamien Le Moal 	K210_PC_DEFAULT(OUT),
179d4c34d09SDamien Le Moal 	K210_PC_DEFAULT(I2C),
180d4c34d09SDamien Le Moal 	K210_PC_DEFAULT(SCCB),
181d4c34d09SDamien Le Moal 	K210_PC_DEFAULT(SPI),
182d4c34d09SDamien Le Moal 	K210_PC_DEFAULT(GPIO),
183d4c34d09SDamien Le Moal 	[K210_PC_DEFAULT_INT13] = K210_PC_MODE_IN | K210_PC_PU,
184d4c34d09SDamien Le Moal };
185d4c34d09SDamien Le Moal 
186f65f4ad8Szhang jiao #undef K210_PC_DEFAULT
187d4c34d09SDamien Le Moal 
188d4c34d09SDamien Le Moal /*
189d4c34d09SDamien Le Moal  * Pin functions configuration information.
190d4c34d09SDamien Le Moal  */
191d4c34d09SDamien Le Moal struct k210_pcf_info {
192d4c34d09SDamien Le Moal 	char name[15];
193d4c34d09SDamien Le Moal 	u8 mode_id;
194d4c34d09SDamien Le Moal };
195d4c34d09SDamien Le Moal 
196d4c34d09SDamien Le Moal #define K210_FUNC(id, mode)				\
197d4c34d09SDamien Le Moal 	[K210_PCF_##id] = {				\
198d4c34d09SDamien Le Moal 		.name = #id,				\
199d4c34d09SDamien Le Moal 		.mode_id = K210_PC_DEFAULT_##mode	\
200d4c34d09SDamien Le Moal 	}
201d4c34d09SDamien Le Moal 
202d4c34d09SDamien Le Moal static const struct k210_pcf_info k210_pcf_infos[] = {
203d4c34d09SDamien Le Moal 	K210_FUNC(JTAG_TCLK,		IN),
204d4c34d09SDamien Le Moal 	K210_FUNC(JTAG_TDI,		IN),
205d4c34d09SDamien Le Moal 	K210_FUNC(JTAG_TMS,		IN),
206d4c34d09SDamien Le Moal 	K210_FUNC(JTAG_TDO,		OUT),
207d4c34d09SDamien Le Moal 	K210_FUNC(SPI0_D0,		SPI),
208d4c34d09SDamien Le Moal 	K210_FUNC(SPI0_D1,		SPI),
209d4c34d09SDamien Le Moal 	K210_FUNC(SPI0_D2,		SPI),
210d4c34d09SDamien Le Moal 	K210_FUNC(SPI0_D3,		SPI),
211d4c34d09SDamien Le Moal 	K210_FUNC(SPI0_D4,		SPI),
212d4c34d09SDamien Le Moal 	K210_FUNC(SPI0_D5,		SPI),
213d4c34d09SDamien Le Moal 	K210_FUNC(SPI0_D6,		SPI),
214d4c34d09SDamien Le Moal 	K210_FUNC(SPI0_D7,		SPI),
215d4c34d09SDamien Le Moal 	K210_FUNC(SPI0_SS0,		OUT),
216d4c34d09SDamien Le Moal 	K210_FUNC(SPI0_SS1,		OUT),
217d4c34d09SDamien Le Moal 	K210_FUNC(SPI0_SS2,		OUT),
218d4c34d09SDamien Le Moal 	K210_FUNC(SPI0_SS3,		OUT),
219d4c34d09SDamien Le Moal 	K210_FUNC(SPI0_ARB,		IN_TIE),
220d4c34d09SDamien Le Moal 	K210_FUNC(SPI0_SCLK,		OUT),
221d4c34d09SDamien Le Moal 	K210_FUNC(UARTHS_RX,		IN),
222d4c34d09SDamien Le Moal 	K210_FUNC(UARTHS_TX,		OUT),
223d4c34d09SDamien Le Moal 	K210_FUNC(RESV6,		IN),
224d4c34d09SDamien Le Moal 	K210_FUNC(RESV7,		IN),
225d4c34d09SDamien Le Moal 	K210_FUNC(CLK_SPI1,		OUT),
226d4c34d09SDamien Le Moal 	K210_FUNC(CLK_I2C1,		OUT),
227d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS0,		GPIO),
228d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS1,		GPIO),
229d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS2,		GPIO),
230d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS3,		GPIO),
231d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS4,		GPIO),
232d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS5,		GPIO),
233d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS6,		GPIO),
234d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS7,		GPIO),
235d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS8,		GPIO),
236d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS9,		GPIO),
237d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS10,		GPIO),
238d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS11,		GPIO),
239d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS12,		GPIO),
240d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS13,		GPIO),
241d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS14,		GPIO),
242d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS15,		GPIO),
243d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS16,		GPIO),
244d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS17,		GPIO),
245d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS18,		GPIO),
246d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS19,		GPIO),
247d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS20,		GPIO),
248d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS21,		GPIO),
249d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS22,		GPIO),
250d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS23,		GPIO),
251d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS24,		GPIO),
252d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS25,		GPIO),
253d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS26,		GPIO),
254d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS27,		GPIO),
255d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS28,		GPIO),
256d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS29,		GPIO),
257d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS30,		GPIO),
258d4c34d09SDamien Le Moal 	K210_FUNC(GPIOHS31,		GPIO),
259d4c34d09SDamien Le Moal 	K210_FUNC(GPIO0,		GPIO),
260d4c34d09SDamien Le Moal 	K210_FUNC(GPIO1,		GPIO),
261d4c34d09SDamien Le Moal 	K210_FUNC(GPIO2,		GPIO),
262d4c34d09SDamien Le Moal 	K210_FUNC(GPIO3,		GPIO),
263d4c34d09SDamien Le Moal 	K210_FUNC(GPIO4,		GPIO),
264d4c34d09SDamien Le Moal 	K210_FUNC(GPIO5,		GPIO),
265d4c34d09SDamien Le Moal 	K210_FUNC(GPIO6,		GPIO),
266d4c34d09SDamien Le Moal 	K210_FUNC(GPIO7,		GPIO),
267d4c34d09SDamien Le Moal 	K210_FUNC(UART1_RX,		IN),
268d4c34d09SDamien Le Moal 	K210_FUNC(UART1_TX,		OUT),
269d4c34d09SDamien Le Moal 	K210_FUNC(UART2_RX,		IN),
270d4c34d09SDamien Le Moal 	K210_FUNC(UART2_TX,		OUT),
271d4c34d09SDamien Le Moal 	K210_FUNC(UART3_RX,		IN),
272d4c34d09SDamien Le Moal 	K210_FUNC(UART3_TX,		OUT),
273d4c34d09SDamien Le Moal 	K210_FUNC(SPI1_D0,		SPI),
274d4c34d09SDamien Le Moal 	K210_FUNC(SPI1_D1,		SPI),
275d4c34d09SDamien Le Moal 	K210_FUNC(SPI1_D2,		SPI),
276d4c34d09SDamien Le Moal 	K210_FUNC(SPI1_D3,		SPI),
277d4c34d09SDamien Le Moal 	K210_FUNC(SPI1_D4,		SPI),
278d4c34d09SDamien Le Moal 	K210_FUNC(SPI1_D5,		SPI),
279d4c34d09SDamien Le Moal 	K210_FUNC(SPI1_D6,		SPI),
280d4c34d09SDamien Le Moal 	K210_FUNC(SPI1_D7,		SPI),
281d4c34d09SDamien Le Moal 	K210_FUNC(SPI1_SS0,		OUT),
282d4c34d09SDamien Le Moal 	K210_FUNC(SPI1_SS1,		OUT),
283d4c34d09SDamien Le Moal 	K210_FUNC(SPI1_SS2,		OUT),
284d4c34d09SDamien Le Moal 	K210_FUNC(SPI1_SS3,		OUT),
285d4c34d09SDamien Le Moal 	K210_FUNC(SPI1_ARB,		IN_TIE),
286d4c34d09SDamien Le Moal 	K210_FUNC(SPI1_SCLK,		OUT),
287d4c34d09SDamien Le Moal 	K210_FUNC(SPI2_D0,		SPI),
288d4c34d09SDamien Le Moal 	K210_FUNC(SPI2_SS,		IN),
289d4c34d09SDamien Le Moal 	K210_FUNC(SPI2_SCLK,		IN),
290d4c34d09SDamien Le Moal 	K210_FUNC(I2S0_MCLK,		OUT),
291d4c34d09SDamien Le Moal 	K210_FUNC(I2S0_SCLK,		OUT),
292d4c34d09SDamien Le Moal 	K210_FUNC(I2S0_WS,		OUT),
293d4c34d09SDamien Le Moal 	K210_FUNC(I2S0_IN_D0,		IN),
294d4c34d09SDamien Le Moal 	K210_FUNC(I2S0_IN_D1,		IN),
295d4c34d09SDamien Le Moal 	K210_FUNC(I2S0_IN_D2,		IN),
296d4c34d09SDamien Le Moal 	K210_FUNC(I2S0_IN_D3,		IN),
297d4c34d09SDamien Le Moal 	K210_FUNC(I2S0_OUT_D0,		OUT),
298d4c34d09SDamien Le Moal 	K210_FUNC(I2S0_OUT_D1,		OUT),
299d4c34d09SDamien Le Moal 	K210_FUNC(I2S0_OUT_D2,		OUT),
300d4c34d09SDamien Le Moal 	K210_FUNC(I2S0_OUT_D3,		OUT),
301d4c34d09SDamien Le Moal 	K210_FUNC(I2S1_MCLK,		OUT),
302d4c34d09SDamien Le Moal 	K210_FUNC(I2S1_SCLK,		OUT),
303d4c34d09SDamien Le Moal 	K210_FUNC(I2S1_WS,		OUT),
304d4c34d09SDamien Le Moal 	K210_FUNC(I2S1_IN_D0,		IN),
305d4c34d09SDamien Le Moal 	K210_FUNC(I2S1_IN_D1,		IN),
306d4c34d09SDamien Le Moal 	K210_FUNC(I2S1_IN_D2,		IN),
307d4c34d09SDamien Le Moal 	K210_FUNC(I2S1_IN_D3,		IN),
308d4c34d09SDamien Le Moal 	K210_FUNC(I2S1_OUT_D0,		OUT),
309d4c34d09SDamien Le Moal 	K210_FUNC(I2S1_OUT_D1,		OUT),
310d4c34d09SDamien Le Moal 	K210_FUNC(I2S1_OUT_D2,		OUT),
311d4c34d09SDamien Le Moal 	K210_FUNC(I2S1_OUT_D3,		OUT),
312d4c34d09SDamien Le Moal 	K210_FUNC(I2S2_MCLK,		OUT),
313d4c34d09SDamien Le Moal 	K210_FUNC(I2S2_SCLK,		OUT),
314d4c34d09SDamien Le Moal 	K210_FUNC(I2S2_WS,		OUT),
315d4c34d09SDamien Le Moal 	K210_FUNC(I2S2_IN_D0,		IN),
316d4c34d09SDamien Le Moal 	K210_FUNC(I2S2_IN_D1,		IN),
317d4c34d09SDamien Le Moal 	K210_FUNC(I2S2_IN_D2,		IN),
318d4c34d09SDamien Le Moal 	K210_FUNC(I2S2_IN_D3,		IN),
319d4c34d09SDamien Le Moal 	K210_FUNC(I2S2_OUT_D0,		OUT),
320d4c34d09SDamien Le Moal 	K210_FUNC(I2S2_OUT_D1,		OUT),
321d4c34d09SDamien Le Moal 	K210_FUNC(I2S2_OUT_D2,		OUT),
322d4c34d09SDamien Le Moal 	K210_FUNC(I2S2_OUT_D3,		OUT),
323d4c34d09SDamien Le Moal 	K210_FUNC(RESV0,		DISABLED),
324d4c34d09SDamien Le Moal 	K210_FUNC(RESV1,		DISABLED),
325d4c34d09SDamien Le Moal 	K210_FUNC(RESV2,		DISABLED),
326d4c34d09SDamien Le Moal 	K210_FUNC(RESV3,		DISABLED),
327d4c34d09SDamien Le Moal 	K210_FUNC(RESV4,		DISABLED),
328d4c34d09SDamien Le Moal 	K210_FUNC(RESV5,		DISABLED),
329d4c34d09SDamien Le Moal 	K210_FUNC(I2C0_SCLK,		I2C),
330d4c34d09SDamien Le Moal 	K210_FUNC(I2C0_SDA,		I2C),
331d4c34d09SDamien Le Moal 	K210_FUNC(I2C1_SCLK,		I2C),
332d4c34d09SDamien Le Moal 	K210_FUNC(I2C1_SDA,		I2C),
333d4c34d09SDamien Le Moal 	K210_FUNC(I2C2_SCLK,		I2C),
334d4c34d09SDamien Le Moal 	K210_FUNC(I2C2_SDA,		I2C),
335d4c34d09SDamien Le Moal 	K210_FUNC(DVP_XCLK,		OUT),
336d4c34d09SDamien Le Moal 	K210_FUNC(DVP_RST,		OUT),
337d4c34d09SDamien Le Moal 	K210_FUNC(DVP_PWDN,		OUT),
338d4c34d09SDamien Le Moal 	K210_FUNC(DVP_VSYNC,		IN),
339d4c34d09SDamien Le Moal 	K210_FUNC(DVP_HSYNC,		IN),
340d4c34d09SDamien Le Moal 	K210_FUNC(DVP_PCLK,		IN),
341d4c34d09SDamien Le Moal 	K210_FUNC(DVP_D0,		IN),
342d4c34d09SDamien Le Moal 	K210_FUNC(DVP_D1,		IN),
343d4c34d09SDamien Le Moal 	K210_FUNC(DVP_D2,		IN),
344d4c34d09SDamien Le Moal 	K210_FUNC(DVP_D3,		IN),
345d4c34d09SDamien Le Moal 	K210_FUNC(DVP_D4,		IN),
346d4c34d09SDamien Le Moal 	K210_FUNC(DVP_D5,		IN),
347d4c34d09SDamien Le Moal 	K210_FUNC(DVP_D6,		IN),
348d4c34d09SDamien Le Moal 	K210_FUNC(DVP_D7,		IN),
349d4c34d09SDamien Le Moal 	K210_FUNC(SCCB_SCLK,		SCCB),
350d4c34d09SDamien Le Moal 	K210_FUNC(SCCB_SDA,		SCCB),
351d4c34d09SDamien Le Moal 	K210_FUNC(UART1_CTS,		IN),
352d4c34d09SDamien Le Moal 	K210_FUNC(UART1_DSR,		IN),
353d4c34d09SDamien Le Moal 	K210_FUNC(UART1_DCD,		IN),
354d4c34d09SDamien Le Moal 	K210_FUNC(UART1_RI,		IN),
355d4c34d09SDamien Le Moal 	K210_FUNC(UART1_SIR_IN,		IN),
356d4c34d09SDamien Le Moal 	K210_FUNC(UART1_DTR,		OUT),
357d4c34d09SDamien Le Moal 	K210_FUNC(UART1_RTS,		OUT),
358d4c34d09SDamien Le Moal 	K210_FUNC(UART1_OUT2,		OUT),
359d4c34d09SDamien Le Moal 	K210_FUNC(UART1_OUT1,		OUT),
360d4c34d09SDamien Le Moal 	K210_FUNC(UART1_SIR_OUT,	OUT),
361d4c34d09SDamien Le Moal 	K210_FUNC(UART1_BAUD,		OUT),
362d4c34d09SDamien Le Moal 	K210_FUNC(UART1_RE,		OUT),
363d4c34d09SDamien Le Moal 	K210_FUNC(UART1_DE,		OUT),
364d4c34d09SDamien Le Moal 	K210_FUNC(UART1_RS485_EN,	OUT),
365d4c34d09SDamien Le Moal 	K210_FUNC(UART2_CTS,		IN),
366d4c34d09SDamien Le Moal 	K210_FUNC(UART2_DSR,		IN),
367d4c34d09SDamien Le Moal 	K210_FUNC(UART2_DCD,		IN),
368d4c34d09SDamien Le Moal 	K210_FUNC(UART2_RI,		IN),
369d4c34d09SDamien Le Moal 	K210_FUNC(UART2_SIR_IN,		IN),
370d4c34d09SDamien Le Moal 	K210_FUNC(UART2_DTR,		OUT),
371d4c34d09SDamien Le Moal 	K210_FUNC(UART2_RTS,		OUT),
372d4c34d09SDamien Le Moal 	K210_FUNC(UART2_OUT2,		OUT),
373d4c34d09SDamien Le Moal 	K210_FUNC(UART2_OUT1,		OUT),
374d4c34d09SDamien Le Moal 	K210_FUNC(UART2_SIR_OUT,	OUT),
375d4c34d09SDamien Le Moal 	K210_FUNC(UART2_BAUD,		OUT),
376d4c34d09SDamien Le Moal 	K210_FUNC(UART2_RE,		OUT),
377d4c34d09SDamien Le Moal 	K210_FUNC(UART2_DE,		OUT),
378d4c34d09SDamien Le Moal 	K210_FUNC(UART2_RS485_EN,	OUT),
379d4c34d09SDamien Le Moal 	K210_FUNC(UART3_CTS,		IN),
380d4c34d09SDamien Le Moal 	K210_FUNC(UART3_DSR,		IN),
381d4c34d09SDamien Le Moal 	K210_FUNC(UART3_DCD,		IN),
382d4c34d09SDamien Le Moal 	K210_FUNC(UART3_RI,		IN),
383d4c34d09SDamien Le Moal 	K210_FUNC(UART3_SIR_IN,		IN),
384d4c34d09SDamien Le Moal 	K210_FUNC(UART3_DTR,		OUT),
385d4c34d09SDamien Le Moal 	K210_FUNC(UART3_RTS,		OUT),
386d4c34d09SDamien Le Moal 	K210_FUNC(UART3_OUT2,		OUT),
387d4c34d09SDamien Le Moal 	K210_FUNC(UART3_OUT1,		OUT),
388d4c34d09SDamien Le Moal 	K210_FUNC(UART3_SIR_OUT,	OUT),
389d4c34d09SDamien Le Moal 	K210_FUNC(UART3_BAUD,		OUT),
390d4c34d09SDamien Le Moal 	K210_FUNC(UART3_RE,		OUT),
391d4c34d09SDamien Le Moal 	K210_FUNC(UART3_DE,		OUT),
392d4c34d09SDamien Le Moal 	K210_FUNC(UART3_RS485_EN,	OUT),
393d4c34d09SDamien Le Moal 	K210_FUNC(TIMER0_TOGGLE1,	OUT),
394d4c34d09SDamien Le Moal 	K210_FUNC(TIMER0_TOGGLE2,	OUT),
395d4c34d09SDamien Le Moal 	K210_FUNC(TIMER0_TOGGLE3,	OUT),
396d4c34d09SDamien Le Moal 	K210_FUNC(TIMER0_TOGGLE4,	OUT),
397d4c34d09SDamien Le Moal 	K210_FUNC(TIMER1_TOGGLE1,	OUT),
398d4c34d09SDamien Le Moal 	K210_FUNC(TIMER1_TOGGLE2,	OUT),
399d4c34d09SDamien Le Moal 	K210_FUNC(TIMER1_TOGGLE3,	OUT),
400d4c34d09SDamien Le Moal 	K210_FUNC(TIMER1_TOGGLE4,	OUT),
401d4c34d09SDamien Le Moal 	K210_FUNC(TIMER2_TOGGLE1,	OUT),
402d4c34d09SDamien Le Moal 	K210_FUNC(TIMER2_TOGGLE2,	OUT),
403d4c34d09SDamien Le Moal 	K210_FUNC(TIMER2_TOGGLE3,	OUT),
404d4c34d09SDamien Le Moal 	K210_FUNC(TIMER2_TOGGLE4,	OUT),
405d4c34d09SDamien Le Moal 	K210_FUNC(CLK_SPI2,		OUT),
406d4c34d09SDamien Le Moal 	K210_FUNC(CLK_I2C2,		OUT),
407d4c34d09SDamien Le Moal 	K210_FUNC(INTERNAL0,		OUT),
408d4c34d09SDamien Le Moal 	K210_FUNC(INTERNAL1,		OUT),
409d4c34d09SDamien Le Moal 	K210_FUNC(INTERNAL2,		OUT),
410d4c34d09SDamien Le Moal 	K210_FUNC(INTERNAL3,		OUT),
411d4c34d09SDamien Le Moal 	K210_FUNC(INTERNAL4,		OUT),
412d4c34d09SDamien Le Moal 	K210_FUNC(INTERNAL5,		OUT),
413d4c34d09SDamien Le Moal 	K210_FUNC(INTERNAL6,		OUT),
414d4c34d09SDamien Le Moal 	K210_FUNC(INTERNAL7,		OUT),
415d4c34d09SDamien Le Moal 	K210_FUNC(INTERNAL8,		OUT),
416d4c34d09SDamien Le Moal 	K210_FUNC(INTERNAL9,		IN),
417d4c34d09SDamien Le Moal 	K210_FUNC(INTERNAL10,		IN),
418d4c34d09SDamien Le Moal 	K210_FUNC(INTERNAL11,		IN),
419d4c34d09SDamien Le Moal 	K210_FUNC(INTERNAL12,		IN),
420d4c34d09SDamien Le Moal 	K210_FUNC(INTERNAL13,		INT13),
421d4c34d09SDamien Le Moal 	K210_FUNC(INTERNAL14,		I2C),
422d4c34d09SDamien Le Moal 	K210_FUNC(INTERNAL15,		IN),
423d4c34d09SDamien Le Moal 	K210_FUNC(INTERNAL16,		IN),
424d4c34d09SDamien Le Moal 	K210_FUNC(INTERNAL17,		IN),
425d4c34d09SDamien Le Moal 	K210_FUNC(CONSTANT,		DISABLED),
426d4c34d09SDamien Le Moal 	K210_FUNC(INTERNAL18,		IN),
427d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG0,		OUT),
428d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG1,		OUT),
429d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG2,		OUT),
430d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG3,		OUT),
431d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG4,		OUT),
432d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG5,		OUT),
433d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG6,		OUT),
434d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG7,		OUT),
435d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG8,		OUT),
436d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG9,		OUT),
437d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG10,		OUT),
438d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG11,		OUT),
439d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG12,		OUT),
440d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG13,		OUT),
441d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG14,		OUT),
442d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG15,		OUT),
443d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG16,		OUT),
444d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG17,		OUT),
445d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG18,		OUT),
446d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG19,		OUT),
447d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG20,		OUT),
448d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG21,		OUT),
449d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG22,		OUT),
450d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG23,		OUT),
451d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG24,		OUT),
452d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG25,		OUT),
453d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG26,		OUT),
454d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG27,		OUT),
455d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG28,		OUT),
456d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG29,		OUT),
457d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG30,		OUT),
458d4c34d09SDamien Le Moal 	K210_FUNC(DEBUG31,		OUT),
459d4c34d09SDamien Le Moal };
460d4c34d09SDamien Le Moal 
461d4c34d09SDamien Le Moal #define PIN_CONFIG_OUTPUT_INVERT	(PIN_CONFIG_END + 1)
462d4c34d09SDamien Le Moal #define PIN_CONFIG_INPUT_INVERT		(PIN_CONFIG_END + 2)
463d4c34d09SDamien Le Moal 
464d4c34d09SDamien Le Moal static const struct pinconf_generic_params k210_pinconf_custom_params[] = {
465d4c34d09SDamien Le Moal 	{ "output-polarity-invert", PIN_CONFIG_OUTPUT_INVERT, 1 },
466d4c34d09SDamien Le Moal 	{ "input-polarity-invert",  PIN_CONFIG_INPUT_INVERT, 1 },
467d4c34d09SDamien Le Moal };
468d4c34d09SDamien Le Moal 
469d4c34d09SDamien Le Moal /*
470d4c34d09SDamien Le Moal  * Max drive strength in uA.
471d4c34d09SDamien Le Moal  */
472d4c34d09SDamien Le Moal static const int k210_pinconf_drive_strength[] = {
473d4c34d09SDamien Le Moal 	[0] = 11200,
474d4c34d09SDamien Le Moal 	[1] = 16800,
475d4c34d09SDamien Le Moal 	[2] = 22300,
476d4c34d09SDamien Le Moal 	[3] = 27800,
477d4c34d09SDamien Le Moal 	[4] = 33300,
478d4c34d09SDamien Le Moal 	[5] = 38700,
479d4c34d09SDamien Le Moal 	[6] = 44100,
480d4c34d09SDamien Le Moal 	[7] = 49500,
481d4c34d09SDamien Le Moal };
482d4c34d09SDamien Le Moal 
k210_pinconf_get_drive(unsigned int max_strength_ua)483d4c34d09SDamien Le Moal static int k210_pinconf_get_drive(unsigned int max_strength_ua)
484d4c34d09SDamien Le Moal {
485d4c34d09SDamien Le Moal 	int i;
486d4c34d09SDamien Le Moal 
487ba2ab859SDan Carpenter 	for (i = K210_PC_DRIVE_MAX; i >= 0; i--) {
488d4c34d09SDamien Le Moal 		if (k210_pinconf_drive_strength[i] <= max_strength_ua)
489d4c34d09SDamien Le Moal 			return i;
490d4c34d09SDamien Le Moal 	}
491d4c34d09SDamien Le Moal 
492d4c34d09SDamien Le Moal 	return -EINVAL;
493d4c34d09SDamien Le Moal }
494d4c34d09SDamien Le Moal 
k210_pinmux_set_pin_function(struct pinctrl_dev * pctldev,u32 pin,u32 func)495d4c34d09SDamien Le Moal static void k210_pinmux_set_pin_function(struct pinctrl_dev *pctldev,
496d4c34d09SDamien Le Moal 					 u32 pin, u32 func)
497d4c34d09SDamien Le Moal {
498d4c34d09SDamien Le Moal 	struct k210_fpioa_data *pdata = pinctrl_dev_get_drvdata(pctldev);
499d4c34d09SDamien Le Moal 	const struct k210_pcf_info *info = &k210_pcf_infos[func];
500d4c34d09SDamien Le Moal 	u32 mode = k210_pinconf_mode_id_to_mode[info->mode_id];
501d4c34d09SDamien Le Moal 	u32 val = func | mode;
502d4c34d09SDamien Le Moal 
503d4c34d09SDamien Le Moal 	dev_dbg(pdata->dev, "set pin %u function %s (%u) -> 0x%08x\n",
504d4c34d09SDamien Le Moal 		pin, info->name, func, val);
505d4c34d09SDamien Le Moal 
506d4c34d09SDamien Le Moal 	writel(val, &pdata->fpioa->pins[pin]);
507d4c34d09SDamien Le Moal }
508d4c34d09SDamien Le Moal 
k210_pinconf_set_param(struct pinctrl_dev * pctldev,unsigned int pin,unsigned int param,unsigned int arg)509d4c34d09SDamien Le Moal static int k210_pinconf_set_param(struct pinctrl_dev *pctldev,
510d4c34d09SDamien Le Moal 				  unsigned int pin,
511d4c34d09SDamien Le Moal 				  unsigned int param, unsigned int arg)
512d4c34d09SDamien Le Moal {
513d4c34d09SDamien Le Moal 	struct k210_fpioa_data *pdata = pinctrl_dev_get_drvdata(pctldev);
514d4c34d09SDamien Le Moal 	u32 val = readl(&pdata->fpioa->pins[pin]);
515d4c34d09SDamien Le Moal 	int drive;
516d4c34d09SDamien Le Moal 
517d4c34d09SDamien Le Moal 	dev_dbg(pdata->dev, "set pin %u param %u, arg 0x%x\n",
518d4c34d09SDamien Le Moal 		pin, param, arg);
519d4c34d09SDamien Le Moal 
520d4c34d09SDamien Le Moal 	switch (param) {
521d4c34d09SDamien Le Moal 	case PIN_CONFIG_BIAS_DISABLE:
522d4c34d09SDamien Le Moal 		val &= ~K210_PC_BIAS_MASK;
523d4c34d09SDamien Le Moal 		break;
524d4c34d09SDamien Le Moal 	case PIN_CONFIG_BIAS_PULL_DOWN:
525d4c34d09SDamien Le Moal 		if (!arg)
526d4c34d09SDamien Le Moal 			return -EINVAL;
527d4c34d09SDamien Le Moal 		val |= K210_PC_PD;
528d4c34d09SDamien Le Moal 		break;
529d4c34d09SDamien Le Moal 	case PIN_CONFIG_BIAS_PULL_UP:
530d4c34d09SDamien Le Moal 		if (!arg)
531d4c34d09SDamien Le Moal 			return -EINVAL;
532e9f7b922SSean Anderson 		val |= K210_PC_PU;
533d4c34d09SDamien Le Moal 		break;
534d4c34d09SDamien Le Moal 	case PIN_CONFIG_DRIVE_STRENGTH:
535d4c34d09SDamien Le Moal 		arg *= 1000;
536d4c34d09SDamien Le Moal 		fallthrough;
537d4c34d09SDamien Le Moal 	case PIN_CONFIG_DRIVE_STRENGTH_UA:
538d4c34d09SDamien Le Moal 		drive = k210_pinconf_get_drive(arg);
539d4c34d09SDamien Le Moal 		if (drive < 0)
540d4c34d09SDamien Le Moal 			return drive;
541d4c34d09SDamien Le Moal 		val &= ~K210_PC_DRIVE_MASK;
542d4c34d09SDamien Le Moal 		val |= FIELD_PREP(K210_PC_DRIVE_MASK, drive);
543d4c34d09SDamien Le Moal 		break;
544d4c34d09SDamien Le Moal 	case PIN_CONFIG_INPUT_ENABLE:
545d4c34d09SDamien Le Moal 		if (arg)
546d4c34d09SDamien Le Moal 			val |= K210_PC_IE;
547d4c34d09SDamien Le Moal 		else
548d4c34d09SDamien Le Moal 			val &= ~K210_PC_IE;
549d4c34d09SDamien Le Moal 		break;
550d4c34d09SDamien Le Moal 	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
551d4c34d09SDamien Le Moal 		if (arg)
552d4c34d09SDamien Le Moal 			val |= K210_PC_ST;
553d4c34d09SDamien Le Moal 		else
554d4c34d09SDamien Le Moal 			val &= ~K210_PC_ST;
555d4c34d09SDamien Le Moal 		break;
556d4c34d09SDamien Le Moal 	case PIN_CONFIG_OUTPUT:
557d4c34d09SDamien Le Moal 		k210_pinmux_set_pin_function(pctldev, pin, K210_PCF_CONSTANT);
558d4c34d09SDamien Le Moal 		val = readl(&pdata->fpioa->pins[pin]);
559d4c34d09SDamien Le Moal 		val |= K210_PC_MODE_OUT;
560d4c34d09SDamien Le Moal 		if (!arg)
561d4c34d09SDamien Le Moal 			val |= K210_PC_DO_INV;
562d4c34d09SDamien Le Moal 		break;
563d4c34d09SDamien Le Moal 	case PIN_CONFIG_OUTPUT_ENABLE:
564d4c34d09SDamien Le Moal 		if (arg)
565d4c34d09SDamien Le Moal 			val |= K210_PC_OE;
566d4c34d09SDamien Le Moal 		else
567d4c34d09SDamien Le Moal 			val &= ~K210_PC_OE;
568d4c34d09SDamien Le Moal 		break;
569d4c34d09SDamien Le Moal 	case PIN_CONFIG_SLEW_RATE:
570d4c34d09SDamien Le Moal 		if (arg)
571d4c34d09SDamien Le Moal 			val |= K210_PC_SL;
572d4c34d09SDamien Le Moal 		else
573d4c34d09SDamien Le Moal 			val &= ~K210_PC_SL;
574d4c34d09SDamien Le Moal 		break;
575d4c34d09SDamien Le Moal 	case PIN_CONFIG_OUTPUT_INVERT:
576d4c34d09SDamien Le Moal 		if (arg)
577d4c34d09SDamien Le Moal 			val |= K210_PC_DO_INV;
578d4c34d09SDamien Le Moal 		else
579d4c34d09SDamien Le Moal 			val &= ~K210_PC_DO_INV;
580d4c34d09SDamien Le Moal 		break;
581d4c34d09SDamien Le Moal 	case PIN_CONFIG_INPUT_INVERT:
582d4c34d09SDamien Le Moal 		if (arg)
583d4c34d09SDamien Le Moal 			val |= K210_PC_DI_INV;
584d4c34d09SDamien Le Moal 		else
585d4c34d09SDamien Le Moal 			val &= ~K210_PC_DI_INV;
586d4c34d09SDamien Le Moal 		break;
587d4c34d09SDamien Le Moal 	default:
588d4c34d09SDamien Le Moal 		return -EINVAL;
589d4c34d09SDamien Le Moal 	}
590d4c34d09SDamien Le Moal 
591d4c34d09SDamien Le Moal 	writel(val, &pdata->fpioa->pins[pin]);
592d4c34d09SDamien Le Moal 
593d4c34d09SDamien Le Moal 	return 0;
594d4c34d09SDamien Le Moal }
595d4c34d09SDamien Le Moal 
k210_pinconf_set(struct pinctrl_dev * pctldev,unsigned int pin,unsigned long * configs,unsigned int num_configs)596d4c34d09SDamien Le Moal static int k210_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
597d4c34d09SDamien Le Moal 			    unsigned long *configs, unsigned int num_configs)
598d4c34d09SDamien Le Moal {
599d4c34d09SDamien Le Moal 	unsigned int param, arg;
600d4c34d09SDamien Le Moal 	int i, ret;
601d4c34d09SDamien Le Moal 
602d4c34d09SDamien Le Moal 	if (WARN_ON(pin >= K210_NPINS))
603d4c34d09SDamien Le Moal 		return -EINVAL;
604d4c34d09SDamien Le Moal 
605d4c34d09SDamien Le Moal 	for (i = 0; i < num_configs; i++) {
606d4c34d09SDamien Le Moal 		param = pinconf_to_config_param(configs[i]);
607d4c34d09SDamien Le Moal 		arg = pinconf_to_config_argument(configs[i]);
608d4c34d09SDamien Le Moal 		ret = k210_pinconf_set_param(pctldev, pin, param, arg);
609d4c34d09SDamien Le Moal 		if (ret)
610d4c34d09SDamien Le Moal 			return ret;
611d4c34d09SDamien Le Moal 	}
612d4c34d09SDamien Le Moal 
613d4c34d09SDamien Le Moal 	return 0;
614d4c34d09SDamien Le Moal }
615d4c34d09SDamien Le Moal 
k210_pinconf_dbg_show(struct pinctrl_dev * pctldev,struct seq_file * s,unsigned int pin)616d4c34d09SDamien Le Moal static void k210_pinconf_dbg_show(struct pinctrl_dev *pctldev,
617d4c34d09SDamien Le Moal 				  struct seq_file *s, unsigned int pin)
618d4c34d09SDamien Le Moal {
619d4c34d09SDamien Le Moal 	struct k210_fpioa_data *pdata = pinctrl_dev_get_drvdata(pctldev);
620d4c34d09SDamien Le Moal 
621d4c34d09SDamien Le Moal 	seq_printf(s, "%#x", readl(&pdata->fpioa->pins[pin]));
622d4c34d09SDamien Le Moal }
623d4c34d09SDamien Le Moal 
k210_pinconf_group_set(struct pinctrl_dev * pctldev,unsigned int selector,unsigned long * configs,unsigned int num_configs)624d4c34d09SDamien Le Moal static int k210_pinconf_group_set(struct pinctrl_dev *pctldev,
625d4c34d09SDamien Le Moal 				  unsigned int selector, unsigned long *configs,
626d4c34d09SDamien Le Moal 				  unsigned int num_configs)
627d4c34d09SDamien Le Moal {
628d4c34d09SDamien Le Moal 	struct k210_fpioa_data *pdata = pinctrl_dev_get_drvdata(pctldev);
629d4c34d09SDamien Le Moal 	unsigned int param, arg;
630d4c34d09SDamien Le Moal 	u32 bit;
631d4c34d09SDamien Le Moal 	int i;
632d4c34d09SDamien Le Moal 
633d4c34d09SDamien Le Moal 	/* Pins should be configured with pinmux, not groups*/
634d4c34d09SDamien Le Moal 	if (selector < K210_NPINS)
635d4c34d09SDamien Le Moal 		return -EINVAL;
636d4c34d09SDamien Le Moal 
637d4c34d09SDamien Le Moal 	/* Otherwise it's a power domain */
638d4c34d09SDamien Le Moal 	for (i = 0; i < num_configs; i++) {
639d4c34d09SDamien Le Moal 		param = pinconf_to_config_param(configs[i]);
640d4c34d09SDamien Le Moal 		if (param != PIN_CONFIG_POWER_SOURCE)
641d4c34d09SDamien Le Moal 			return -EINVAL;
642d4c34d09SDamien Le Moal 
643d4c34d09SDamien Le Moal 		arg = pinconf_to_config_argument(configs[i]);
644d4c34d09SDamien Le Moal 		bit = BIT(selector - K210_NPINS);
645d4c34d09SDamien Le Moal 		regmap_update_bits(pdata->sysctl_map,
646d4c34d09SDamien Le Moal 				   pdata->power_offset,
647d4c34d09SDamien Le Moal 				   bit, arg ? bit : 0);
648d4c34d09SDamien Le Moal 	}
649d4c34d09SDamien Le Moal 
650d4c34d09SDamien Le Moal 	return 0;
651d4c34d09SDamien Le Moal }
652d4c34d09SDamien Le Moal 
k210_pinconf_group_dbg_show(struct pinctrl_dev * pctldev,struct seq_file * s,unsigned int selector)653d4c34d09SDamien Le Moal static void k210_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
654d4c34d09SDamien Le Moal 					struct seq_file *s,
655d4c34d09SDamien Le Moal 					unsigned int selector)
656d4c34d09SDamien Le Moal {
657d4c34d09SDamien Le Moal 	struct k210_fpioa_data *pdata = pinctrl_dev_get_drvdata(pctldev);
658d4c34d09SDamien Le Moal 	int ret;
659d4c34d09SDamien Le Moal 	u32 val;
660d4c34d09SDamien Le Moal 
661d4c34d09SDamien Le Moal 	if (selector < K210_NPINS)
662d4c34d09SDamien Le Moal 		return k210_pinconf_dbg_show(pctldev, s, selector);
663d4c34d09SDamien Le Moal 
664d4c34d09SDamien Le Moal 	ret = regmap_read(pdata->sysctl_map, pdata->power_offset, &val);
665d4c34d09SDamien Le Moal 	if (ret) {
666d4c34d09SDamien Le Moal 		dev_err(pdata->dev, "Failed to read power reg\n");
667d4c34d09SDamien Le Moal 		return;
668d4c34d09SDamien Le Moal 	}
669d4c34d09SDamien Le Moal 
670d4c34d09SDamien Le Moal 	seq_printf(s, "%s: %s V", k210_group_names[selector],
671d4c34d09SDamien Le Moal 		   val & BIT(selector - K210_NPINS) ? "1.8" : "3.3");
672d4c34d09SDamien Le Moal }
673d4c34d09SDamien Le Moal 
674d4c34d09SDamien Le Moal static const struct pinconf_ops k210_pinconf_ops = {
675d4c34d09SDamien Le Moal 	.is_generic = true,
676d4c34d09SDamien Le Moal 	.pin_config_set = k210_pinconf_set,
677d4c34d09SDamien Le Moal 	.pin_config_group_set = k210_pinconf_group_set,
678d4c34d09SDamien Le Moal 	.pin_config_dbg_show = k210_pinconf_dbg_show,
679d4c34d09SDamien Le Moal 	.pin_config_group_dbg_show = k210_pinconf_group_dbg_show,
680d4c34d09SDamien Le Moal };
681d4c34d09SDamien Le Moal 
k210_pinmux_get_function_count(struct pinctrl_dev * pctldev)682d4c34d09SDamien Le Moal static int k210_pinmux_get_function_count(struct pinctrl_dev *pctldev)
683d4c34d09SDamien Le Moal {
684d4c34d09SDamien Le Moal 	return ARRAY_SIZE(k210_pcf_infos);
685d4c34d09SDamien Le Moal }
686d4c34d09SDamien Le Moal 
k210_pinmux_get_function_name(struct pinctrl_dev * pctldev,unsigned int selector)687d4c34d09SDamien Le Moal static const char *k210_pinmux_get_function_name(struct pinctrl_dev *pctldev,
688d4c34d09SDamien Le Moal 						 unsigned int selector)
689d4c34d09SDamien Le Moal {
690d4c34d09SDamien Le Moal 	return k210_pcf_infos[selector].name;
691d4c34d09SDamien Le Moal }
692d4c34d09SDamien Le Moal 
k210_pinmux_get_function_groups(struct pinctrl_dev * pctldev,unsigned int selector,const char * const ** groups,unsigned int * const num_groups)693d4c34d09SDamien Le Moal static int k210_pinmux_get_function_groups(struct pinctrl_dev *pctldev,
694d4c34d09SDamien Le Moal 					   unsigned int selector,
695d4c34d09SDamien Le Moal 					   const char * const **groups,
696d4c34d09SDamien Le Moal 					   unsigned int * const num_groups)
697d4c34d09SDamien Le Moal {
698d4c34d09SDamien Le Moal 	/* Any function can be mapped to any pin */
699d4c34d09SDamien Le Moal 	*groups = k210_group_names;
700d4c34d09SDamien Le Moal 	*num_groups = K210_NPINS;
701d4c34d09SDamien Le Moal 
702d4c34d09SDamien Le Moal 	return 0;
703d4c34d09SDamien Le Moal }
704d4c34d09SDamien Le Moal 
k210_pinmux_set_mux(struct pinctrl_dev * pctldev,unsigned int function,unsigned int group)705d4c34d09SDamien Le Moal static int k210_pinmux_set_mux(struct pinctrl_dev *pctldev,
706d4c34d09SDamien Le Moal 			       unsigned int function,
707d4c34d09SDamien Le Moal 			       unsigned int group)
708d4c34d09SDamien Le Moal {
709d4c34d09SDamien Le Moal 	/* Can't mux power domains */
710d4c34d09SDamien Le Moal 	if (group >= K210_NPINS)
711d4c34d09SDamien Le Moal 		return -EINVAL;
712d4c34d09SDamien Le Moal 
713d4c34d09SDamien Le Moal 	k210_pinmux_set_pin_function(pctldev, group, function);
714d4c34d09SDamien Le Moal 
715d4c34d09SDamien Le Moal 	return 0;
716d4c34d09SDamien Le Moal }
717d4c34d09SDamien Le Moal 
718d4c34d09SDamien Le Moal static const struct pinmux_ops k210_pinmux_ops = {
719d4c34d09SDamien Le Moal 	.get_functions_count = k210_pinmux_get_function_count,
720d4c34d09SDamien Le Moal 	.get_function_name = k210_pinmux_get_function_name,
721d4c34d09SDamien Le Moal 	.get_function_groups = k210_pinmux_get_function_groups,
722d4c34d09SDamien Le Moal 	.set_mux = k210_pinmux_set_mux,
723d4c34d09SDamien Le Moal 	.strict = true,
724d4c34d09SDamien Le Moal };
725d4c34d09SDamien Le Moal 
k210_pinctrl_get_groups_count(struct pinctrl_dev * pctldev)726d4c34d09SDamien Le Moal static int k210_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
727d4c34d09SDamien Le Moal {
728d4c34d09SDamien Le Moal 	return K210_NGROUPS;
729d4c34d09SDamien Le Moal }
730d4c34d09SDamien Le Moal 
k210_pinctrl_get_group_name(struct pinctrl_dev * pctldev,unsigned int group)731d4c34d09SDamien Le Moal static const char *k210_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
732d4c34d09SDamien Le Moal 					       unsigned int group)
733d4c34d09SDamien Le Moal {
734d4c34d09SDamien Le Moal 	return k210_group_names[group];
735d4c34d09SDamien Le Moal }
736d4c34d09SDamien Le Moal 
k210_pinctrl_get_group_pins(struct pinctrl_dev * pctldev,unsigned int group,const unsigned int ** pins,unsigned int * npins)737d4c34d09SDamien Le Moal static int k210_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
738d4c34d09SDamien Le Moal 				       unsigned int group,
739d4c34d09SDamien Le Moal 				       const unsigned int **pins,
740d4c34d09SDamien Le Moal 				       unsigned int *npins)
741d4c34d09SDamien Le Moal {
742d4c34d09SDamien Le Moal 	if (group >= K210_NPINS) {
743d4c34d09SDamien Le Moal 		*pins = NULL;
744d4c34d09SDamien Le Moal 		*npins = 0;
745d4c34d09SDamien Le Moal 		return 0;
746d4c34d09SDamien Le Moal 	}
747d4c34d09SDamien Le Moal 
748d4c34d09SDamien Le Moal 	*pins = &k210_pins[group].number;
749d4c34d09SDamien Le Moal 	*npins = 1;
750d4c34d09SDamien Le Moal 
751d4c34d09SDamien Le Moal 	return 0;
752d4c34d09SDamien Le Moal }
753d4c34d09SDamien Le Moal 
k210_pinctrl_pin_dbg_show(struct pinctrl_dev * pctldev,struct seq_file * s,unsigned int offset)754d4c34d09SDamien Le Moal static void k210_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
755d4c34d09SDamien Le Moal 				      struct seq_file *s, unsigned int offset)
756d4c34d09SDamien Le Moal {
757d4c34d09SDamien Le Moal 	seq_printf(s, "%s", dev_name(pctldev->dev));
758d4c34d09SDamien Le Moal }
759d4c34d09SDamien Le Moal 
k210_pinctrl_dt_subnode_to_map(struct pinctrl_dev * pctldev,struct device_node * np,struct pinctrl_map ** map,unsigned int * reserved_maps,unsigned int * num_maps)760d4c34d09SDamien Le Moal static int k210_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
761d4c34d09SDamien Le Moal 					  struct device_node *np,
762d4c34d09SDamien Le Moal 					  struct pinctrl_map **map,
763d4c34d09SDamien Le Moal 					  unsigned int *reserved_maps,
764d4c34d09SDamien Le Moal 					  unsigned int *num_maps)
765d4c34d09SDamien Le Moal {
766d4c34d09SDamien Le Moal 	int ret, pinmux_groups;
767d4c34d09SDamien Le Moal 	u32 pinmux_group;
768d4c34d09SDamien Le Moal 	unsigned long *configs = NULL;
769d4c34d09SDamien Le Moal 	unsigned int num_configs = 0;
770d4c34d09SDamien Le Moal 	unsigned int reserve = 0;
771d4c34d09SDamien Le Moal 
772d4c34d09SDamien Le Moal 	ret = of_property_count_strings(np, "groups");
773d4c34d09SDamien Le Moal 	if (!ret)
774d4c34d09SDamien Le Moal 		return pinconf_generic_dt_subnode_to_map(pctldev, np, map,
775d4c34d09SDamien Le Moal 						reserved_maps, num_maps,
776d4c34d09SDamien Le Moal 						PIN_MAP_TYPE_CONFIGS_GROUP);
777d4c34d09SDamien Le Moal 
778d4c34d09SDamien Le Moal 	pinmux_groups = of_property_count_u32_elems(np, "pinmux");
779d4c34d09SDamien Le Moal 	if (pinmux_groups <= 0) {
780d4c34d09SDamien Le Moal 		/* Ignore this node */
781d4c34d09SDamien Le Moal 		return 0;
782d4c34d09SDamien Le Moal 	}
783d4c34d09SDamien Le Moal 
784d4c34d09SDamien Le Moal 	ret = pinconf_generic_parse_dt_config(np, pctldev, &configs,
785d4c34d09SDamien Le Moal 					      &num_configs);
786d4c34d09SDamien Le Moal 	if (ret < 0) {
787d4c34d09SDamien Le Moal 		dev_err(pctldev->dev, "%pOF: could not parse node property\n",
788d4c34d09SDamien Le Moal 			np);
789d4c34d09SDamien Le Moal 		return ret;
790d4c34d09SDamien Le Moal 	}
791d4c34d09SDamien Le Moal 
792d4c34d09SDamien Le Moal 	reserve = pinmux_groups * (1 + num_configs);
793d4c34d09SDamien Le Moal 	ret = pinctrl_utils_reserve_map(pctldev, map, reserved_maps, num_maps,
794d4c34d09SDamien Le Moal 					reserve);
795d4c34d09SDamien Le Moal 	if (ret < 0)
796d4c34d09SDamien Le Moal 		goto exit;
797d4c34d09SDamien Le Moal 
798*914ef7d1SLuca Ceresoli 	of_property_for_each_u32(np, "pinmux", pinmux_group) {
799d4c34d09SDamien Le Moal 		const char *group_name, *func_name;
800d4c34d09SDamien Le Moal 		u32 pin = FIELD_GET(K210_PG_PIN, pinmux_group);
801d4c34d09SDamien Le Moal 		u32 func = FIELD_GET(K210_PG_FUNC, pinmux_group);
802d4c34d09SDamien Le Moal 
803d4c34d09SDamien Le Moal 		if (pin >= K210_NPINS) {
804d4c34d09SDamien Le Moal 			ret = -EINVAL;
805d4c34d09SDamien Le Moal 			goto exit;
806d4c34d09SDamien Le Moal 		}
807d4c34d09SDamien Le Moal 
808d4c34d09SDamien Le Moal 		group_name = k210_group_names[pin];
809d4c34d09SDamien Le Moal 		func_name = k210_pcf_infos[func].name;
810d4c34d09SDamien Le Moal 
811d4c34d09SDamien Le Moal 		dev_dbg(pctldev->dev, "Pinmux %s: pin %u func %s\n",
812d4c34d09SDamien Le Moal 			np->name, pin, func_name);
813d4c34d09SDamien Le Moal 
814d4c34d09SDamien Le Moal 		ret = pinctrl_utils_add_map_mux(pctldev, map, reserved_maps,
815d4c34d09SDamien Le Moal 						num_maps, group_name,
816d4c34d09SDamien Le Moal 						func_name);
817d4c34d09SDamien Le Moal 		if (ret < 0) {
818d4c34d09SDamien Le Moal 			dev_err(pctldev->dev, "%pOF add mux map failed %d\n",
819d4c34d09SDamien Le Moal 				np, ret);
820d4c34d09SDamien Le Moal 			goto exit;
821d4c34d09SDamien Le Moal 		}
822d4c34d09SDamien Le Moal 
823d4c34d09SDamien Le Moal 		if (num_configs) {
824d4c34d09SDamien Le Moal 			ret = pinctrl_utils_add_map_configs(pctldev, map,
825d4c34d09SDamien Le Moal 					reserved_maps, num_maps, group_name,
826d4c34d09SDamien Le Moal 					configs, num_configs,
827d4c34d09SDamien Le Moal 					PIN_MAP_TYPE_CONFIGS_PIN);
828d4c34d09SDamien Le Moal 			if (ret < 0) {
829d4c34d09SDamien Le Moal 				dev_err(pctldev->dev,
830d4c34d09SDamien Le Moal 					"%pOF add configs map failed %d\n",
831d4c34d09SDamien Le Moal 					np, ret);
832d4c34d09SDamien Le Moal 				goto exit;
833d4c34d09SDamien Le Moal 			}
834d4c34d09SDamien Le Moal 		}
835d4c34d09SDamien Le Moal 	}
836d4c34d09SDamien Le Moal 
837d4c34d09SDamien Le Moal 	ret = 0;
838d4c34d09SDamien Le Moal 
839d4c34d09SDamien Le Moal exit:
840d4c34d09SDamien Le Moal 	kfree(configs);
841d4c34d09SDamien Le Moal 	return ret;
842d4c34d09SDamien Le Moal }
843d4c34d09SDamien Le Moal 
k210_pinctrl_dt_node_to_map(struct pinctrl_dev * pctldev,struct device_node * np_config,struct pinctrl_map ** map,unsigned int * num_maps)844d4c34d09SDamien Le Moal static int k210_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
845d4c34d09SDamien Le Moal 				       struct device_node *np_config,
846d4c34d09SDamien Le Moal 				       struct pinctrl_map **map,
847d4c34d09SDamien Le Moal 				       unsigned int *num_maps)
848d4c34d09SDamien Le Moal {
849d4c34d09SDamien Le Moal 	unsigned int reserved_maps;
850d4c34d09SDamien Le Moal 	struct device_node *np;
851d4c34d09SDamien Le Moal 	int ret;
852d4c34d09SDamien Le Moal 
853d4c34d09SDamien Le Moal 	reserved_maps = 0;
854d4c34d09SDamien Le Moal 	*map = NULL;
855d4c34d09SDamien Le Moal 	*num_maps = 0;
856d4c34d09SDamien Le Moal 
857d4c34d09SDamien Le Moal 	ret = k210_pinctrl_dt_subnode_to_map(pctldev, np_config, map,
858d4c34d09SDamien Le Moal 					     &reserved_maps, num_maps);
859d4c34d09SDamien Le Moal 	if (ret < 0)
860d4c34d09SDamien Le Moal 		goto err;
861d4c34d09SDamien Le Moal 
862d4c34d09SDamien Le Moal 	for_each_available_child_of_node(np_config, np) {
863d4c34d09SDamien Le Moal 		ret = k210_pinctrl_dt_subnode_to_map(pctldev, np, map,
864d4c34d09SDamien Le Moal 						     &reserved_maps, num_maps);
865a8acc116SZhangPeng 		if (ret < 0) {
866a8acc116SZhangPeng 			of_node_put(np);
867d4c34d09SDamien Le Moal 			goto err;
868d4c34d09SDamien Le Moal 		}
869a8acc116SZhangPeng 	}
870d4c34d09SDamien Le Moal 	return 0;
871d4c34d09SDamien Le Moal 
872d4c34d09SDamien Le Moal err:
873d4c34d09SDamien Le Moal 	pinctrl_utils_free_map(pctldev, *map, *num_maps);
874d4c34d09SDamien Le Moal 	return ret;
875d4c34d09SDamien Le Moal }
876d4c34d09SDamien Le Moal 
877d4c34d09SDamien Le Moal 
878d4c34d09SDamien Le Moal static const struct pinctrl_ops k210_pinctrl_ops = {
879d4c34d09SDamien Le Moal 	.get_groups_count = k210_pinctrl_get_groups_count,
880d4c34d09SDamien Le Moal 	.get_group_name = k210_pinctrl_get_group_name,
881d4c34d09SDamien Le Moal 	.get_group_pins = k210_pinctrl_get_group_pins,
882d4c34d09SDamien Le Moal 	.pin_dbg_show = k210_pinctrl_pin_dbg_show,
883d4c34d09SDamien Le Moal 	.dt_node_to_map = k210_pinctrl_dt_node_to_map,
884d4c34d09SDamien Le Moal 	.dt_free_map = pinconf_generic_dt_free_map,
885d4c34d09SDamien Le Moal };
886d4c34d09SDamien Le Moal 
887d4c34d09SDamien Le Moal static struct pinctrl_desc k210_pinctrl_desc = {
888d4c34d09SDamien Le Moal 	.name = "k210-pinctrl",
889d4c34d09SDamien Le Moal 	.pins = k210_pins,
890d4c34d09SDamien Le Moal 	.npins = K210_NPINS,
891d4c34d09SDamien Le Moal 	.pctlops = &k210_pinctrl_ops,
892d4c34d09SDamien Le Moal 	.pmxops = &k210_pinmux_ops,
893d4c34d09SDamien Le Moal 	.confops = &k210_pinconf_ops,
894d4c34d09SDamien Le Moal 	.custom_params = k210_pinconf_custom_params,
895d4c34d09SDamien Le Moal 	.num_custom_params = ARRAY_SIZE(k210_pinconf_custom_params),
896d4c34d09SDamien Le Moal };
897d4c34d09SDamien Le Moal 
k210_fpioa_init_ties(struct k210_fpioa_data * pdata)898d4c34d09SDamien Le Moal static void k210_fpioa_init_ties(struct k210_fpioa_data *pdata)
899d4c34d09SDamien Le Moal {
900d4c34d09SDamien Le Moal 	struct k210_fpioa __iomem *fpioa = pdata->fpioa;
901d4c34d09SDamien Le Moal 	u32 val;
902d4c34d09SDamien Le Moal 	int i, j;
903d4c34d09SDamien Le Moal 
904d4c34d09SDamien Le Moal 	dev_dbg(pdata->dev, "Init pin ties\n");
905d4c34d09SDamien Le Moal 
906d4c34d09SDamien Le Moal 	/* Init pin functions input ties */
907d4c34d09SDamien Le Moal 	for (i = 0; i < ARRAY_SIZE(fpioa->tie_en); i++) {
908d4c34d09SDamien Le Moal 		val = 0;
909d4c34d09SDamien Le Moal 		for (j = 0; j < 32; j++) {
910d4c34d09SDamien Le Moal 			if (k210_pcf_infos[i * 32 + j].mode_id ==
911d4c34d09SDamien Le Moal 			    K210_PC_DEFAULT_IN_TIE) {
912d4c34d09SDamien Le Moal 				dev_dbg(pdata->dev,
913d4c34d09SDamien Le Moal 					"tie_en function %d (%s)\n",
914d4c34d09SDamien Le Moal 					i * 32 + j,
915d4c34d09SDamien Le Moal 					k210_pcf_infos[i * 32 + j].name);
916d4c34d09SDamien Le Moal 				val |= BIT(j);
917d4c34d09SDamien Le Moal 			}
918d4c34d09SDamien Le Moal 		}
919d4c34d09SDamien Le Moal 
920d4c34d09SDamien Le Moal 		/* Set value before enable */
921d4c34d09SDamien Le Moal 		writel(val, &fpioa->tie_val[i]);
922d4c34d09SDamien Le Moal 		writel(val, &fpioa->tie_en[i]);
923d4c34d09SDamien Le Moal 	}
924d4c34d09SDamien Le Moal }
925d4c34d09SDamien Le Moal 
k210_fpioa_probe(struct platform_device * pdev)926d4c34d09SDamien Le Moal static int k210_fpioa_probe(struct platform_device *pdev)
927d4c34d09SDamien Le Moal {
928d4c34d09SDamien Le Moal 	struct device *dev = &pdev->dev;
929d4c34d09SDamien Le Moal 	struct device_node *np = dev->of_node;
930d4c34d09SDamien Le Moal 	struct k210_fpioa_data *pdata;
931d4c34d09SDamien Le Moal 	int ret;
932d4c34d09SDamien Le Moal 
933d4c34d09SDamien Le Moal 	dev_info(dev, "K210 FPIOA pin controller\n");
934d4c34d09SDamien Le Moal 
935d4c34d09SDamien Le Moal 	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
936d4c34d09SDamien Le Moal 	if (!pdata)
937d4c34d09SDamien Le Moal 		return -ENOMEM;
938d4c34d09SDamien Le Moal 
939d4c34d09SDamien Le Moal 	pdata->dev = dev;
940d4c34d09SDamien Le Moal 	platform_set_drvdata(pdev, pdata);
941d4c34d09SDamien Le Moal 
942d4c34d09SDamien Le Moal 	pdata->fpioa = devm_platform_ioremap_resource(pdev, 0);
943d4c34d09SDamien Le Moal 	if (IS_ERR(pdata->fpioa))
944d4c34d09SDamien Le Moal 		return PTR_ERR(pdata->fpioa);
945d4c34d09SDamien Le Moal 
946d4c34d09SDamien Le Moal 	pdata->clk = devm_clk_get(dev, "ref");
947d4c34d09SDamien Le Moal 	if (IS_ERR(pdata->clk))
948d4c34d09SDamien Le Moal 		return PTR_ERR(pdata->clk);
949d4c34d09SDamien Le Moal 
950d4c34d09SDamien Le Moal 	ret = clk_prepare_enable(pdata->clk);
951d4c34d09SDamien Le Moal 	if (ret)
952d4c34d09SDamien Le Moal 		return ret;
953d4c34d09SDamien Le Moal 
954d4c34d09SDamien Le Moal 	pdata->pclk = devm_clk_get_optional(dev, "pclk");
95531697ef7SDamien Le Moal 	if (!IS_ERR(pdata->pclk)) {
95631697ef7SDamien Le Moal 		ret = clk_prepare_enable(pdata->pclk);
95731697ef7SDamien Le Moal 		if (ret)
95831697ef7SDamien Le Moal 			goto disable_clk;
95931697ef7SDamien Le Moal 	}
960d4c34d09SDamien Le Moal 
961d4c34d09SDamien Le Moal 	pdata->sysctl_map =
962d4c34d09SDamien Le Moal 		syscon_regmap_lookup_by_phandle_args(np,
963d4c34d09SDamien Le Moal 						"canaan,k210-sysctl-power",
964d4c34d09SDamien Le Moal 						1, &pdata->power_offset);
96531697ef7SDamien Le Moal 	if (IS_ERR(pdata->sysctl_map)) {
96631697ef7SDamien Le Moal 		ret = PTR_ERR(pdata->sysctl_map);
96731697ef7SDamien Le Moal 		goto disable_pclk;
96831697ef7SDamien Le Moal 	}
969d4c34d09SDamien Le Moal 
970d4c34d09SDamien Le Moal 	k210_fpioa_init_ties(pdata);
971d4c34d09SDamien Le Moal 
972d4c34d09SDamien Le Moal 	pdata->pctl = pinctrl_register(&k210_pinctrl_desc, dev, (void *)pdata);
97331697ef7SDamien Le Moal 	if (IS_ERR(pdata->pctl)) {
97431697ef7SDamien Le Moal 		ret = PTR_ERR(pdata->pctl);
97531697ef7SDamien Le Moal 		goto disable_pclk;
97631697ef7SDamien Le Moal 	}
977d4c34d09SDamien Le Moal 
978d4c34d09SDamien Le Moal 	return 0;
97931697ef7SDamien Le Moal 
98031697ef7SDamien Le Moal disable_pclk:
98131697ef7SDamien Le Moal 	clk_disable_unprepare(pdata->pclk);
98231697ef7SDamien Le Moal disable_clk:
98331697ef7SDamien Le Moal 	clk_disable_unprepare(pdata->clk);
98431697ef7SDamien Le Moal 
98531697ef7SDamien Le Moal 	return ret;
986d4c34d09SDamien Le Moal }
987d4c34d09SDamien Le Moal 
988d4c34d09SDamien Le Moal static const struct of_device_id k210_fpioa_dt_ids[] = {
989d4c34d09SDamien Le Moal 	{ .compatible = "canaan,k210-fpioa" },
990d4c34d09SDamien Le Moal 	{ /* sentinel */ },
991d4c34d09SDamien Le Moal };
992d4c34d09SDamien Le Moal 
993d4c34d09SDamien Le Moal static struct platform_driver k210_fpioa_driver = {
994d4c34d09SDamien Le Moal 	.probe	= k210_fpioa_probe,
995d4c34d09SDamien Le Moal 	.driver = {
996d4c34d09SDamien Le Moal 		.name		= "k210-fpioa",
997d4c34d09SDamien Le Moal 		.of_match_table	= k210_fpioa_dt_ids,
998d4c34d09SDamien Le Moal 	},
999d4c34d09SDamien Le Moal };
1000d4c34d09SDamien Le Moal builtin_platform_driver(k210_fpioa_driver);
1001