xref: /linux/drivers/pinctrl/pinctrl-th1520.c (revision bed5cd6f8a988389e987bcf5c1762ab7c53be317)
1*bed5cd6fSEmil Renner Berthing // SPDX-License-Identifier: GPL-2.0
2*bed5cd6fSEmil Renner Berthing /*
3*bed5cd6fSEmil Renner Berthing  * Pinctrl driver for the T-Head TH1520 SoC
4*bed5cd6fSEmil Renner Berthing  *
5*bed5cd6fSEmil Renner Berthing  * Copyright (C) 2023 Emil Renner Berthing <emil.renner.berthing@canonical.com>
6*bed5cd6fSEmil Renner Berthing  */
7*bed5cd6fSEmil Renner Berthing 
8*bed5cd6fSEmil Renner Berthing #include <linux/array_size.h>
9*bed5cd6fSEmil Renner Berthing #include <linux/bits.h>
10*bed5cd6fSEmil Renner Berthing #include <linux/cleanup.h>
11*bed5cd6fSEmil Renner Berthing #include <linux/clk.h>
12*bed5cd6fSEmil Renner Berthing #include <linux/device.h>
13*bed5cd6fSEmil Renner Berthing #include <linux/io.h>
14*bed5cd6fSEmil Renner Berthing #include <linux/mod_devicetable.h>
15*bed5cd6fSEmil Renner Berthing #include <linux/module.h>
16*bed5cd6fSEmil Renner Berthing #include <linux/mutex.h>
17*bed5cd6fSEmil Renner Berthing #include <linux/of.h>
18*bed5cd6fSEmil Renner Berthing #include <linux/platform_device.h>
19*bed5cd6fSEmil Renner Berthing #include <linux/seq_file.h>
20*bed5cd6fSEmil Renner Berthing #include <linux/spinlock.h>
21*bed5cd6fSEmil Renner Berthing 
22*bed5cd6fSEmil Renner Berthing #include <linux/of_address.h>
23*bed5cd6fSEmil Renner Berthing #include <linux/of_device.h>
24*bed5cd6fSEmil Renner Berthing 
25*bed5cd6fSEmil Renner Berthing #include <linux/pinctrl/pinconf.h>
26*bed5cd6fSEmil Renner Berthing #include <linux/pinctrl/pinconf-generic.h>
27*bed5cd6fSEmil Renner Berthing #include <linux/pinctrl/pinctrl.h>
28*bed5cd6fSEmil Renner Berthing #include <linux/pinctrl/pinmux.h>
29*bed5cd6fSEmil Renner Berthing 
30*bed5cd6fSEmil Renner Berthing #include "core.h"
31*bed5cd6fSEmil Renner Berthing #include "pinmux.h"
32*bed5cd6fSEmil Renner Berthing #include "pinconf.h"
33*bed5cd6fSEmil Renner Berthing 
34*bed5cd6fSEmil Renner Berthing #define TH1520_PADCFG_IE	BIT(9)
35*bed5cd6fSEmil Renner Berthing #define TH1520_PADCFG_SL	BIT(8)
36*bed5cd6fSEmil Renner Berthing #define TH1520_PADCFG_ST	BIT(7)
37*bed5cd6fSEmil Renner Berthing #define TH1520_PADCFG_SPU	BIT(6)
38*bed5cd6fSEmil Renner Berthing #define TH1520_PADCFG_PS	BIT(5)
39*bed5cd6fSEmil Renner Berthing #define TH1520_PADCFG_PE	BIT(4)
40*bed5cd6fSEmil Renner Berthing #define TH1520_PADCFG_BIAS	(TH1520_PADCFG_SPU | TH1520_PADCFG_PS | TH1520_PADCFG_PE)
41*bed5cd6fSEmil Renner Berthing #define TH1520_PADCFG_DS	GENMASK(3, 0)
42*bed5cd6fSEmil Renner Berthing 
43*bed5cd6fSEmil Renner Berthing #define TH1520_PULL_DOWN_OHM	44000 /* typ. 44kOhm */
44*bed5cd6fSEmil Renner Berthing #define TH1520_PULL_UP_OHM	48000 /* typ. 48kOhm */
45*bed5cd6fSEmil Renner Berthing #define TH1520_PULL_STRONG_OHM	 2100 /* typ. 2.1kOhm */
46*bed5cd6fSEmil Renner Berthing 
47*bed5cd6fSEmil Renner Berthing #define TH1520_PAD_NO_PADCFG	BIT(30)
48*bed5cd6fSEmil Renner Berthing #define TH1520_PAD_MUXDATA	GENMASK(29, 0)
49*bed5cd6fSEmil Renner Berthing 
50*bed5cd6fSEmil Renner Berthing struct th1520_pad_group {
51*bed5cd6fSEmil Renner Berthing 	const char *name;
52*bed5cd6fSEmil Renner Berthing 	const struct pinctrl_pin_desc *pins;
53*bed5cd6fSEmil Renner Berthing 	unsigned int npins;
54*bed5cd6fSEmil Renner Berthing };
55*bed5cd6fSEmil Renner Berthing 
56*bed5cd6fSEmil Renner Berthing struct th1520_pinctrl {
57*bed5cd6fSEmil Renner Berthing 	struct pinctrl_desc desc;
58*bed5cd6fSEmil Renner Berthing 	struct mutex mutex;	/* serialize adding functions */
59*bed5cd6fSEmil Renner Berthing 	raw_spinlock_t lock;	/* serialize register access */
60*bed5cd6fSEmil Renner Berthing 	void __iomem *base;
61*bed5cd6fSEmil Renner Berthing 	struct pinctrl_dev *pctl;
62*bed5cd6fSEmil Renner Berthing };
63*bed5cd6fSEmil Renner Berthing 
64*bed5cd6fSEmil Renner Berthing static void __iomem *th1520_padcfg(struct th1520_pinctrl *thp,
65*bed5cd6fSEmil Renner Berthing 				   unsigned int pin)
66*bed5cd6fSEmil Renner Berthing {
67*bed5cd6fSEmil Renner Berthing 	return thp->base + 4 * (pin / 2);
68*bed5cd6fSEmil Renner Berthing }
69*bed5cd6fSEmil Renner Berthing 
70*bed5cd6fSEmil Renner Berthing static unsigned int th1520_padcfg_shift(unsigned int pin)
71*bed5cd6fSEmil Renner Berthing {
72*bed5cd6fSEmil Renner Berthing 	return 16 * (pin & BIT(0));
73*bed5cd6fSEmil Renner Berthing }
74*bed5cd6fSEmil Renner Berthing 
75*bed5cd6fSEmil Renner Berthing static void __iomem *th1520_muxcfg(struct th1520_pinctrl *thp,
76*bed5cd6fSEmil Renner Berthing 				   unsigned int pin)
77*bed5cd6fSEmil Renner Berthing {
78*bed5cd6fSEmil Renner Berthing 	return thp->base + 0x400 + 4 * (pin / 8);
79*bed5cd6fSEmil Renner Berthing }
80*bed5cd6fSEmil Renner Berthing 
81*bed5cd6fSEmil Renner Berthing static unsigned int th1520_muxcfg_shift(unsigned int pin)
82*bed5cd6fSEmil Renner Berthing {
83*bed5cd6fSEmil Renner Berthing 	return 4 * (pin & GENMASK(2, 0));
84*bed5cd6fSEmil Renner Berthing }
85*bed5cd6fSEmil Renner Berthing 
86*bed5cd6fSEmil Renner Berthing enum th1520_muxtype {
87*bed5cd6fSEmil Renner Berthing 	TH1520_MUX_____,
88*bed5cd6fSEmil Renner Berthing 	TH1520_MUX_GPIO,
89*bed5cd6fSEmil Renner Berthing 	TH1520_MUX_PWM,
90*bed5cd6fSEmil Renner Berthing 	TH1520_MUX_UART,
91*bed5cd6fSEmil Renner Berthing 	TH1520_MUX_IR,
92*bed5cd6fSEmil Renner Berthing 	TH1520_MUX_I2C,
93*bed5cd6fSEmil Renner Berthing 	TH1520_MUX_SPI,
94*bed5cd6fSEmil Renner Berthing 	TH1520_MUX_QSPI,
95*bed5cd6fSEmil Renner Berthing 	TH1520_MUX_SDIO,
96*bed5cd6fSEmil Renner Berthing 	TH1520_MUX_AUD,
97*bed5cd6fSEmil Renner Berthing 	TH1520_MUX_I2S,
98*bed5cd6fSEmil Renner Berthing 	TH1520_MUX_MAC0,
99*bed5cd6fSEmil Renner Berthing 	TH1520_MUX_MAC1,
100*bed5cd6fSEmil Renner Berthing 	TH1520_MUX_DPU0,
101*bed5cd6fSEmil Renner Berthing 	TH1520_MUX_DPU1,
102*bed5cd6fSEmil Renner Berthing 	TH1520_MUX_ISP,
103*bed5cd6fSEmil Renner Berthing 	TH1520_MUX_HDMI,
104*bed5cd6fSEmil Renner Berthing 	TH1520_MUX_BSEL,
105*bed5cd6fSEmil Renner Berthing 	TH1520_MUX_DBG,
106*bed5cd6fSEmil Renner Berthing 	TH1520_MUX_CLK,
107*bed5cd6fSEmil Renner Berthing 	TH1520_MUX_JTAG,
108*bed5cd6fSEmil Renner Berthing 	TH1520_MUX_ISO,
109*bed5cd6fSEmil Renner Berthing 	TH1520_MUX_FUSE,
110*bed5cd6fSEmil Renner Berthing 	TH1520_MUX_RST,
111*bed5cd6fSEmil Renner Berthing };
112*bed5cd6fSEmil Renner Berthing 
113*bed5cd6fSEmil Renner Berthing static const char *const th1520_muxtype_string[] = {
114*bed5cd6fSEmil Renner Berthing 	[TH1520_MUX_GPIO] = "gpio",
115*bed5cd6fSEmil Renner Berthing 	[TH1520_MUX_PWM]  = "pwm",
116*bed5cd6fSEmil Renner Berthing 	[TH1520_MUX_UART] = "uart",
117*bed5cd6fSEmil Renner Berthing 	[TH1520_MUX_IR]   = "ir",
118*bed5cd6fSEmil Renner Berthing 	[TH1520_MUX_I2C]  = "i2c",
119*bed5cd6fSEmil Renner Berthing 	[TH1520_MUX_SPI]  = "spi",
120*bed5cd6fSEmil Renner Berthing 	[TH1520_MUX_QSPI] = "qspi",
121*bed5cd6fSEmil Renner Berthing 	[TH1520_MUX_SDIO] = "sdio",
122*bed5cd6fSEmil Renner Berthing 	[TH1520_MUX_AUD]  = "audio",
123*bed5cd6fSEmil Renner Berthing 	[TH1520_MUX_I2S]  = "i2s",
124*bed5cd6fSEmil Renner Berthing 	[TH1520_MUX_MAC0] = "gmac0",
125*bed5cd6fSEmil Renner Berthing 	[TH1520_MUX_MAC1] = "gmac1",
126*bed5cd6fSEmil Renner Berthing 	[TH1520_MUX_DPU0] = "dpu0",
127*bed5cd6fSEmil Renner Berthing 	[TH1520_MUX_DPU1] = "dpu1",
128*bed5cd6fSEmil Renner Berthing 	[TH1520_MUX_ISP]  = "isp",
129*bed5cd6fSEmil Renner Berthing 	[TH1520_MUX_HDMI] = "hdmi",
130*bed5cd6fSEmil Renner Berthing 	[TH1520_MUX_BSEL] = "bootsel",
131*bed5cd6fSEmil Renner Berthing 	[TH1520_MUX_DBG]  = "debug",
132*bed5cd6fSEmil Renner Berthing 	[TH1520_MUX_CLK]  = "clock",
133*bed5cd6fSEmil Renner Berthing 	[TH1520_MUX_JTAG] = "jtag",
134*bed5cd6fSEmil Renner Berthing 	[TH1520_MUX_ISO]  = "iso7816",
135*bed5cd6fSEmil Renner Berthing 	[TH1520_MUX_FUSE] = "efuse",
136*bed5cd6fSEmil Renner Berthing 	[TH1520_MUX_RST]  = "reset",
137*bed5cd6fSEmil Renner Berthing };
138*bed5cd6fSEmil Renner Berthing 
139*bed5cd6fSEmil Renner Berthing static enum th1520_muxtype th1520_muxtype_get(const char *str)
140*bed5cd6fSEmil Renner Berthing {
141*bed5cd6fSEmil Renner Berthing 	enum th1520_muxtype mt;
142*bed5cd6fSEmil Renner Berthing 
143*bed5cd6fSEmil Renner Berthing 	for (mt = TH1520_MUX_GPIO; mt < ARRAY_SIZE(th1520_muxtype_string); mt++) {
144*bed5cd6fSEmil Renner Berthing 		if (!strcmp(str, th1520_muxtype_string[mt]))
145*bed5cd6fSEmil Renner Berthing 			return mt;
146*bed5cd6fSEmil Renner Berthing 	}
147*bed5cd6fSEmil Renner Berthing 	return TH1520_MUX_____;
148*bed5cd6fSEmil Renner Berthing }
149*bed5cd6fSEmil Renner Berthing 
150*bed5cd6fSEmil Renner Berthing #define TH1520_PAD(_nr, _name, m0, m1, m2, m3, m4, m5, _flags) \
151*bed5cd6fSEmil Renner Berthing 	{ .number = _nr, .name = #_name, .drv_data = (void *)((_flags) | \
152*bed5cd6fSEmil Renner Berthing 		(TH1520_MUX_##m0 <<  0) | (TH1520_MUX_##m1 <<  5) | (TH1520_MUX_##m2 << 10) | \
153*bed5cd6fSEmil Renner Berthing 		(TH1520_MUX_##m3 << 15) | (TH1520_MUX_##m4 << 20) | (TH1520_MUX_##m5 << 25)) }
154*bed5cd6fSEmil Renner Berthing 
155*bed5cd6fSEmil Renner Berthing static const struct pinctrl_pin_desc th1520_group1_pins[] = {
156*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(0,  OSC_CLK_IN,    ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG),
157*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(1,  OSC_CLK_OUT,   ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG),
158*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(2,  SYS_RST_N,     ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG),
159*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(3,  RTC_CLK_IN,    ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG),
160*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(4,  RTC_CLK_OUT,   ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG),
161*bed5cd6fSEmil Renner Berthing 	/* skip number 5 so we can calculate register offsets and shifts from the pin number */
162*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(6,  TEST_MODE,     ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG),
163*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(7,  DEBUG_MODE,    DBG,  ____, ____, GPIO, ____, ____, TH1520_PAD_NO_PADCFG),
164*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(8,  POR_SEL,       ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG),
165*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(9,  I2C_AON_SCL,   I2C,  ____, ____, GPIO, ____, ____, 0),
166*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(10, I2C_AON_SDA,   I2C,  ____, ____, GPIO, ____, ____, 0),
167*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(11, CPU_JTG_TCLK,  JTAG, ____, ____, GPIO, ____, ____, 0),
168*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(12, CPU_JTG_TMS,   JTAG, ____, ____, GPIO, ____, ____, 0),
169*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(13, CPU_JTG_TDI,   JTAG, ____, ____, GPIO, ____, ____, 0),
170*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(14, CPU_JTG_TDO,   JTAG, ____, ____, GPIO, ____, ____, 0),
171*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(15, CPU_JTG_TRST,  JTAG, ____, ____, GPIO, ____, ____, 0),
172*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(16, AOGPIO_7,      CLK,  AUD,  ____, GPIO, ____, ____, 0),
173*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(17, AOGPIO_8,      UART, AUD,  IR,   GPIO, ____, ____, 0),
174*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(18, AOGPIO_9,      UART, AUD,  IR,   GPIO, ____, ____, 0),
175*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(19, AOGPIO_10,     CLK,  AUD,  ____, GPIO, ____, ____, 0),
176*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(20, AOGPIO_11,     GPIO, AUD,  ____, ____, ____, ____, 0),
177*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(21, AOGPIO_12,     GPIO, AUD,  ____, ____, ____, ____, 0),
178*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(22, AOGPIO_13,     GPIO, AUD,  ____, ____, ____, ____, 0),
179*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(23, AOGPIO_14,     GPIO, AUD,  ____, ____, ____, ____, 0),
180*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(24, AOGPIO_15,     GPIO, AUD,  ____, ____, ____, ____, 0),
181*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(25, AUDIO_PA0,     AUD,  ____, ____, GPIO, ____, ____, 0),
182*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(26, AUDIO_PA1,     AUD,  ____, ____, GPIO, ____, ____, 0),
183*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(27, AUDIO_PA2,     AUD,  ____, ____, GPIO, ____, ____, 0),
184*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(28, AUDIO_PA3,     AUD,  ____, ____, GPIO, ____, ____, 0),
185*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(29, AUDIO_PA4,     AUD,  ____, ____, GPIO, ____, ____, 0),
186*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(30, AUDIO_PA5,     AUD,  ____, ____, GPIO, ____, ____, 0),
187*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(31, AUDIO_PA6,     AUD,  ____, ____, GPIO, ____, ____, 0),
188*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(32, AUDIO_PA7,     AUD,  ____, ____, GPIO, ____, ____, 0),
189*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(33, AUDIO_PA8,     AUD,  ____, ____, GPIO, ____, ____, 0),
190*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(34, AUDIO_PA9,     AUD,  ____, ____, GPIO, ____, ____, 0),
191*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(35, AUDIO_PA10,    AUD,  ____, ____, GPIO, ____, ____, 0),
192*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(36, AUDIO_PA11,    AUD,  ____, ____, GPIO, ____, ____, 0),
193*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(37, AUDIO_PA12,    AUD,  ____, ____, GPIO, ____, ____, 0),
194*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(38, AUDIO_PA13,    AUD,  ____, ____, GPIO, ____, ____, 0),
195*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(39, AUDIO_PA14,    AUD,  ____, ____, GPIO, ____, ____, 0),
196*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(40, AUDIO_PA15,    AUD,  ____, ____, GPIO, ____, ____, 0),
197*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(41, AUDIO_PA16,    AUD,  ____, ____, GPIO, ____, ____, 0),
198*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(42, AUDIO_PA17,    AUD,  ____, ____, GPIO, ____, ____, 0),
199*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(43, AUDIO_PA27,    AUD,  ____, ____, GPIO, ____, ____, 0),
200*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(44, AUDIO_PA28,    AUD,  ____, ____, GPIO, ____, ____, 0),
201*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(45, AUDIO_PA29,    AUD,  ____, ____, GPIO, ____, ____, 0),
202*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(46, AUDIO_PA30,    AUD,  RST,  ____, GPIO, ____, ____, 0),
203*bed5cd6fSEmil Renner Berthing };
204*bed5cd6fSEmil Renner Berthing 
205*bed5cd6fSEmil Renner Berthing static const struct pinctrl_pin_desc th1520_group2_pins[] = {
206*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(0,  QSPI1_SCLK,    QSPI, ISO,  ____, GPIO, FUSE, ____, 0),
207*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(1,  QSPI1_CSN0,    QSPI, ____, I2C,  GPIO, FUSE, ____, 0),
208*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(2,  QSPI1_D0_MOSI, QSPI, ISO,  I2C,  GPIO, FUSE, ____, 0),
209*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(3,  QSPI1_D1_MISO, QSPI, ISO,  ____, GPIO, FUSE, ____, 0),
210*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(4,  QSPI1_D2_WP,   QSPI, ISO,  UART, GPIO, FUSE, ____, 0),
211*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(5,  QSPI1_D3_HOLD, QSPI, ISO,  UART, GPIO, ____, ____, 0),
212*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(6,  I2C0_SCL,      I2C,  ____, ____, GPIO, ____, ____, 0),
213*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(7,  I2C0_SDA,      I2C,  ____, ____, GPIO, ____, ____, 0),
214*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(8,  I2C1_SCL,      I2C,  ____, ____, GPIO, ____, ____, 0),
215*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(9,  I2C1_SDA,      I2C,  ____, ____, GPIO, ____, ____, 0),
216*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(10, UART1_TXD,     UART, ____, ____, GPIO, ____, ____, 0),
217*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(11, UART1_RXD,     UART, ____, ____, GPIO, ____, ____, 0),
218*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(12, UART4_TXD,     UART, ____, ____, GPIO, ____, ____, 0),
219*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(13, UART4_RXD,     UART, ____, ____, GPIO, ____, ____, 0),
220*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(14, UART4_CTSN,    UART, ____, ____, GPIO, ____, ____, 0),
221*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(15, UART4_RTSN,    UART, ____, ____, GPIO, ____, ____, 0),
222*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(16, UART3_TXD,     DBG,  UART, ____, GPIO, ____, ____, 0),
223*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(17, UART3_RXD,     DBG,  UART, ____, GPIO, ____, ____, 0),
224*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(18, GPIO0_18,      GPIO, I2C,  ____, ____, ____, ____, 0),
225*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(19, GPIO0_19,      GPIO, I2C,  ____, ____, ____, ____, 0),
226*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(20, GPIO0_20,      GPIO, UART, IR,   ____, ____, ____, 0),
227*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(21, GPIO0_21,      GPIO, UART, IR,   ____, DPU0, DPU1, 0),
228*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(22, GPIO0_22,      GPIO, JTAG, I2C,  ____, DPU0, DPU1, 0),
229*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(23, GPIO0_23,      GPIO, JTAG, I2C,  ____, DPU0, DPU1, 0),
230*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(24, GPIO0_24,      GPIO, JTAG, QSPI, ____, DPU0, DPU1, 0),
231*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(25, GPIO0_25,      GPIO, JTAG, ____, ____, DPU0, DPU1, 0),
232*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(26, GPIO0_26,      GPIO, JTAG, ____, ____, DPU0, DPU1, 0),
233*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(27, GPIO0_27,      GPIO, ____, I2C,  ____, DPU0, DPU1, 0),
234*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(28, GPIO0_28,      GPIO, ____, I2C,  ____, DPU0, DPU1, 0),
235*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(29, GPIO0_29,      GPIO, ____, ____, ____, DPU0, DPU1, 0),
236*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(30, GPIO0_30,      GPIO, ____, ____, ____, DPU0, DPU1, 0),
237*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(31, GPIO0_31,      GPIO, ____, ____, ____, DPU0, DPU1, 0),
238*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(32, GPIO1_0,       GPIO, JTAG, ____, ____, DPU0, DPU1, 0),
239*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(33, GPIO1_1,       GPIO, JTAG, ____, ____, DPU0, DPU1, 0),
240*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(34, GPIO1_2,       GPIO, JTAG, ____, ____, DPU0, DPU1, 0),
241*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(35, GPIO1_3,       GPIO, JTAG, ____, ____, DPU0, DPU1, 0),
242*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(36, GPIO1_4,       GPIO, JTAG, ____, ____, DPU0, DPU1, 0),
243*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(37, GPIO1_5,       GPIO, ____, ____, ____, DPU0, DPU1, 0),
244*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(38, GPIO1_6,       GPIO, ____, ____, ____, DPU0, DPU1, 0),
245*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(39, GPIO1_7,       GPIO, QSPI, ____, ____, DPU0, DPU1, 0),
246*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(40, GPIO1_8,       GPIO, QSPI, ____, ____, DPU0, DPU1, 0),
247*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(41, GPIO1_9,       GPIO, QSPI, ____, ____, DPU0, DPU1, 0),
248*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(42, GPIO1_10,      GPIO, QSPI, ____, ____, DPU0, DPU1, 0),
249*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(43, GPIO1_11,      GPIO, QSPI, ____, ____, DPU0, DPU1, 0),
250*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(44, GPIO1_12,      GPIO, QSPI, ____, ____, DPU0, DPU1, 0),
251*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(45, GPIO1_13,      GPIO, UART, ____, ____, DPU0, DPU1, 0),
252*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(46, GPIO1_14,      GPIO, UART, ____, ____, DPU0, DPU1, 0),
253*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(47, GPIO1_15,      GPIO, UART, ____, ____, DPU0, DPU1, 0),
254*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(48, GPIO1_16,      GPIO, UART, ____, ____, DPU0, DPU1, 0),
255*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(49, CLK_OUT_0,     BSEL, CLK,  ____, GPIO, ____, ____, 0),
256*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(50, CLK_OUT_1,     BSEL, CLK,  ____, GPIO, ____, ____, 0),
257*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(51, CLK_OUT_2,     BSEL, CLK,  ____, GPIO, ____, ____, 0),
258*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(52, CLK_OUT_3,     BSEL, CLK,  ____, GPIO, ____, ____, 0),
259*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(53, GPIO1_21,      GPIO, ____, ISP,  ____, ____, ____, 0),
260*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(54, GPIO1_22,      GPIO, ____, ISP,  ____, ____, ____, 0),
261*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(55, GPIO1_23,      GPIO, ____, ISP,  ____, ____, ____, 0),
262*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(56, GPIO1_24,      GPIO, ____, ISP,  ____, ____, ____, 0),
263*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(57, GPIO1_25,      GPIO, ____, ISP,  ____, ____, ____, 0),
264*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(58, GPIO1_26,      GPIO, ____, ISP,  ____, ____, ____, 0),
265*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(59, GPIO1_27,      GPIO, ____, ISP,  ____, ____, ____, 0),
266*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(60, GPIO1_28,      GPIO, ____, ISP,  ____, ____, ____, 0),
267*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(61, GPIO1_29,      GPIO, ____, ISP,  ____, ____, ____, 0),
268*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(62, GPIO1_30,      GPIO, ____, ISP,  ____, ____, ____, 0),
269*bed5cd6fSEmil Renner Berthing };
270*bed5cd6fSEmil Renner Berthing 
271*bed5cd6fSEmil Renner Berthing static const struct pinctrl_pin_desc th1520_group3_pins[] = {
272*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(0,  UART0_TXD,     UART, ____, ____, GPIO, ____, ____, 0),
273*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(1,  UART0_RXD,     UART, ____, ____, GPIO, ____, ____, 0),
274*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(2,  QSPI0_SCLK,    QSPI, PWM,  I2S,  GPIO, ____, ____, 0),
275*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(3,  QSPI0_CSN0,    QSPI, PWM,  I2S,  GPIO, ____, ____, 0),
276*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(4,  QSPI0_CSN1,    QSPI, PWM,  I2S,  GPIO, ____, ____, 0),
277*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(5,  QSPI0_D0_MOSI, QSPI, PWM,  I2S,  GPIO, ____, ____, 0),
278*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(6,  QSPI0_D1_MISO, QSPI, PWM,  I2S,  GPIO, ____, ____, 0),
279*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(7,  QSPI0_D2_WP,   QSPI, PWM,  I2S,  GPIO, ____, ____, 0),
280*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(8,  QSPI1_D3_HOLD, QSPI, ____, I2S,  GPIO, ____, ____, 0),
281*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(9,  I2C2_SCL,      I2C,  UART, ____, GPIO, ____, ____, 0),
282*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(10, I2C2_SDA,      I2C,  UART, ____, GPIO, ____, ____, 0),
283*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(11, I2C3_SCL,      I2C,  ____, ____, GPIO, ____, ____, 0),
284*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(12, I2C3_SDA,      I2C,  ____, ____, GPIO, ____, ____, 0),
285*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(13, GPIO2_13,      GPIO, SPI,  ____, ____, ____, ____, 0),
286*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(14, SPI_SCLK,      SPI,  UART, IR,   GPIO, ____, ____, 0),
287*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(15, SPI_CSN,       SPI,  UART, IR,   GPIO, ____, ____, 0),
288*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(16, SPI_MOSI,      SPI,  ____, ____, GPIO, ____, ____, 0),
289*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(17, SPI_MISO,      SPI,  ____, ____, GPIO, ____, ____, 0),
290*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(18, GPIO2_18,      GPIO, MAC1, ____, ____, ____, ____, 0),
291*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(19, GPIO2_19,      GPIO, MAC1, ____, ____, ____, ____, 0),
292*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(20, GPIO2_20,      GPIO, MAC1, ____, ____, ____, ____, 0),
293*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(21, GPIO2_21,      GPIO, MAC1, ____, ____, ____, ____, 0),
294*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(22, GPIO2_22,      GPIO, MAC1, ____, ____, ____, ____, 0),
295*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(23, GPIO2_23,      GPIO, MAC1, ____, ____, ____, ____, 0),
296*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(24, GPIO2_24,      GPIO, MAC1, ____, ____, ____, ____, 0),
297*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(25, GPIO2_25,      GPIO, MAC1, ____, ____, ____, ____, 0),
298*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(26, SDIO0_WPRTN,   SDIO, ____, ____, GPIO, ____, ____, 0),
299*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(27, SDIO0_DETN,    SDIO, ____, ____, GPIO, ____, ____, 0),
300*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(28, SDIO1_WPRTN,   SDIO, ____, ____, GPIO, ____, ____, 0),
301*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(29, SDIO1_DETN,    SDIO, ____, ____, GPIO, ____, ____, 0),
302*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(30, GPIO2_30,      GPIO, MAC1, ____, ____, ____, ____, 0),
303*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(31, GPIO2_31,      GPIO, MAC1, ____, ____, ____, ____, 0),
304*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(32, GPIO3_0,       GPIO, MAC1, ____, ____, ____, ____, 0),
305*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(33, GPIO3_1,       GPIO, MAC1, ____, ____, ____, ____, 0),
306*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(34, GPIO3_2,       GPIO, PWM,  ____, ____, ____, ____, 0),
307*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(35, GPIO3_3,       GPIO, PWM,  ____, ____, ____, ____, 0),
308*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(36, HDMI_SCL,      HDMI, PWM,  ____, GPIO, ____, ____, 0),
309*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(37, HDMI_SDA,      HDMI, PWM,  ____, GPIO, ____, ____, 0),
310*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(38, HDMI_CEC,      HDMI, ____, ____, GPIO, ____, ____, 0),
311*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(39, GMAC0_TX_CLK,  MAC0, ____, ____, GPIO, ____, ____, 0),
312*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(40, GMAC0_RX_CLK,  MAC0, ____, ____, GPIO, ____, ____, 0),
313*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(41, GMAC0_TXEN,    MAC0, UART, ____, GPIO, ____, ____, 0),
314*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(42, GMAC0_TXD0,    MAC0, UART, ____, GPIO, ____, ____, 0),
315*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(43, GMAC0_TXD1,    MAC0, UART, ____, GPIO, ____, ____, 0),
316*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(44, GMAC0_TXD2,    MAC0, UART, ____, GPIO, ____, ____, 0),
317*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(45, GMAC0_TXD3,    MAC0, I2C,  ____, GPIO, ____, ____, 0),
318*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(46, GMAC0_RXDV,    MAC0, I2C,  ____, GPIO, ____, ____, 0),
319*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(47, GMAC0_RXD0,    MAC0, I2C,  ____, GPIO, ____, ____, 0),
320*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(48, GMAC0_RXD1,    MAC0, I2C,  ____, GPIO, ____, ____, 0),
321*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(49, GMAC0_RXD2,    MAC0, SPI,  ____, GPIO, ____, ____, 0),
322*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(50, GMAC0_RXD3,    MAC0, SPI,  ____, GPIO, ____, ____, 0),
323*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(51, GMAC0_MDC,     MAC0, SPI,  MAC1, GPIO, ____, ____, 0),
324*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(52, GMAC0_MDIO,    MAC0, SPI,  MAC1, GPIO, ____, ____, 0),
325*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(53, GMAC0_COL,     MAC0, PWM,  ____, GPIO, ____, ____, 0),
326*bed5cd6fSEmil Renner Berthing 	TH1520_PAD(54, GMAC0_CRS,     MAC0, PWM,  ____, GPIO, ____, ____, 0),
327*bed5cd6fSEmil Renner Berthing };
328*bed5cd6fSEmil Renner Berthing 
329*bed5cd6fSEmil Renner Berthing static const struct th1520_pad_group th1520_group1 = {
330*bed5cd6fSEmil Renner Berthing 	.name = "th1520-group1",
331*bed5cd6fSEmil Renner Berthing 	.pins = th1520_group1_pins,
332*bed5cd6fSEmil Renner Berthing 	.npins = ARRAY_SIZE(th1520_group1_pins),
333*bed5cd6fSEmil Renner Berthing };
334*bed5cd6fSEmil Renner Berthing 
335*bed5cd6fSEmil Renner Berthing static const struct th1520_pad_group th1520_group2 = {
336*bed5cd6fSEmil Renner Berthing 	.name = "th1520-group2",
337*bed5cd6fSEmil Renner Berthing 	.pins = th1520_group2_pins,
338*bed5cd6fSEmil Renner Berthing 	.npins = ARRAY_SIZE(th1520_group2_pins),
339*bed5cd6fSEmil Renner Berthing };
340*bed5cd6fSEmil Renner Berthing 
341*bed5cd6fSEmil Renner Berthing static const struct th1520_pad_group th1520_group3 = {
342*bed5cd6fSEmil Renner Berthing 	.name = "th1520-group3",
343*bed5cd6fSEmil Renner Berthing 	.pins = th1520_group3_pins,
344*bed5cd6fSEmil Renner Berthing 	.npins = ARRAY_SIZE(th1520_group3_pins),
345*bed5cd6fSEmil Renner Berthing };
346*bed5cd6fSEmil Renner Berthing 
347*bed5cd6fSEmil Renner Berthing static int th1520_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
348*bed5cd6fSEmil Renner Berthing {
349*bed5cd6fSEmil Renner Berthing 	struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev);
350*bed5cd6fSEmil Renner Berthing 
351*bed5cd6fSEmil Renner Berthing 	return thp->desc.npins;
352*bed5cd6fSEmil Renner Berthing }
353*bed5cd6fSEmil Renner Berthing 
354*bed5cd6fSEmil Renner Berthing static const char *th1520_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
355*bed5cd6fSEmil Renner Berthing 						 unsigned int gsel)
356*bed5cd6fSEmil Renner Berthing {
357*bed5cd6fSEmil Renner Berthing 	struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev);
358*bed5cd6fSEmil Renner Berthing 
359*bed5cd6fSEmil Renner Berthing 	return thp->desc.pins[gsel].name;
360*bed5cd6fSEmil Renner Berthing }
361*bed5cd6fSEmil Renner Berthing 
362*bed5cd6fSEmil Renner Berthing static int th1520_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
363*bed5cd6fSEmil Renner Berthing 					 unsigned int gsel,
364*bed5cd6fSEmil Renner Berthing 					 const unsigned int **pins,
365*bed5cd6fSEmil Renner Berthing 					 unsigned int *npins)
366*bed5cd6fSEmil Renner Berthing {
367*bed5cd6fSEmil Renner Berthing 	struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev);
368*bed5cd6fSEmil Renner Berthing 
369*bed5cd6fSEmil Renner Berthing 	*pins = &thp->desc.pins[gsel].number;
370*bed5cd6fSEmil Renner Berthing 	*npins = 1;
371*bed5cd6fSEmil Renner Berthing 	return 0;
372*bed5cd6fSEmil Renner Berthing }
373*bed5cd6fSEmil Renner Berthing 
374*bed5cd6fSEmil Renner Berthing #ifdef CONFIG_DEBUG_FS
375*bed5cd6fSEmil Renner Berthing static void th1520_pin_dbg_show(struct pinctrl_dev *pctldev,
376*bed5cd6fSEmil Renner Berthing 				struct seq_file *s, unsigned int pin)
377*bed5cd6fSEmil Renner Berthing {
378*bed5cd6fSEmil Renner Berthing 	struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev);
379*bed5cd6fSEmil Renner Berthing 	void __iomem *padcfg = th1520_padcfg(thp, pin);
380*bed5cd6fSEmil Renner Berthing 	void __iomem *muxcfg = th1520_muxcfg(thp, pin);
381*bed5cd6fSEmil Renner Berthing 	u32 pad;
382*bed5cd6fSEmil Renner Berthing 	u32 mux;
383*bed5cd6fSEmil Renner Berthing 
384*bed5cd6fSEmil Renner Berthing 	scoped_guard(raw_spinlock_irqsave, &thp->lock) {
385*bed5cd6fSEmil Renner Berthing 		pad = readl_relaxed(padcfg);
386*bed5cd6fSEmil Renner Berthing 		mux = readl_relaxed(muxcfg);
387*bed5cd6fSEmil Renner Berthing 	}
388*bed5cd6fSEmil Renner Berthing 
389*bed5cd6fSEmil Renner Berthing 	seq_printf(s, "[PADCFG_%03u:0x%x=0x%07x MUXCFG_%03u:0x%x=0x%08x]",
390*bed5cd6fSEmil Renner Berthing 		   1 + pin / 2, 0x000 + 4 * (pin / 2), pad,
391*bed5cd6fSEmil Renner Berthing 		   1 + pin / 8, 0x400 + 4 * (pin / 8), mux);
392*bed5cd6fSEmil Renner Berthing }
393*bed5cd6fSEmil Renner Berthing #else
394*bed5cd6fSEmil Renner Berthing #define th1520_pin_dbg_show NULL
395*bed5cd6fSEmil Renner Berthing #endif
396*bed5cd6fSEmil Renner Berthing 
397*bed5cd6fSEmil Renner Berthing static void th1520_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
398*bed5cd6fSEmil Renner Berthing 				       struct pinctrl_map *map, unsigned int nmaps)
399*bed5cd6fSEmil Renner Berthing {
400*bed5cd6fSEmil Renner Berthing 	unsigned long *seen = NULL;
401*bed5cd6fSEmil Renner Berthing 	unsigned int i;
402*bed5cd6fSEmil Renner Berthing 
403*bed5cd6fSEmil Renner Berthing 	for (i = 0; i < nmaps; i++) {
404*bed5cd6fSEmil Renner Berthing 		if (map[i].type == PIN_MAP_TYPE_CONFIGS_PIN &&
405*bed5cd6fSEmil Renner Berthing 		    map[i].data.configs.configs != seen) {
406*bed5cd6fSEmil Renner Berthing 			seen = map[i].data.configs.configs;
407*bed5cd6fSEmil Renner Berthing 			kfree(seen);
408*bed5cd6fSEmil Renner Berthing 		}
409*bed5cd6fSEmil Renner Berthing 	}
410*bed5cd6fSEmil Renner Berthing 
411*bed5cd6fSEmil Renner Berthing 	kfree(map);
412*bed5cd6fSEmil Renner Berthing }
413*bed5cd6fSEmil Renner Berthing 
414*bed5cd6fSEmil Renner Berthing static int th1520_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
415*bed5cd6fSEmil Renner Berthing 					 struct device_node *np,
416*bed5cd6fSEmil Renner Berthing 					 struct pinctrl_map **maps,
417*bed5cd6fSEmil Renner Berthing 					 unsigned int *num_maps)
418*bed5cd6fSEmil Renner Berthing {
419*bed5cd6fSEmil Renner Berthing 	struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev);
420*bed5cd6fSEmil Renner Berthing 	struct device_node *child;
421*bed5cd6fSEmil Renner Berthing 	struct pinctrl_map *map;
422*bed5cd6fSEmil Renner Berthing 	unsigned long *configs;
423*bed5cd6fSEmil Renner Berthing 	unsigned int nconfigs;
424*bed5cd6fSEmil Renner Berthing 	unsigned int nmaps;
425*bed5cd6fSEmil Renner Berthing 	int ret;
426*bed5cd6fSEmil Renner Berthing 
427*bed5cd6fSEmil Renner Berthing 	nmaps = 0;
428*bed5cd6fSEmil Renner Berthing 	for_each_available_child_of_node(np, child) {
429*bed5cd6fSEmil Renner Berthing 		int npins = of_property_count_strings(child, "pins");
430*bed5cd6fSEmil Renner Berthing 
431*bed5cd6fSEmil Renner Berthing 		if (npins <= 0) {
432*bed5cd6fSEmil Renner Berthing 			of_node_put(child);
433*bed5cd6fSEmil Renner Berthing 			dev_err(thp->pctl->dev, "no pins selected for %pOFn.%pOFn\n",
434*bed5cd6fSEmil Renner Berthing 				np, child);
435*bed5cd6fSEmil Renner Berthing 			return -EINVAL;
436*bed5cd6fSEmil Renner Berthing 		}
437*bed5cd6fSEmil Renner Berthing 		nmaps += npins;
438*bed5cd6fSEmil Renner Berthing 		if (of_property_present(child, "function"))
439*bed5cd6fSEmil Renner Berthing 			nmaps += npins;
440*bed5cd6fSEmil Renner Berthing 	}
441*bed5cd6fSEmil Renner Berthing 
442*bed5cd6fSEmil Renner Berthing 	map = kcalloc(nmaps, sizeof(*map), GFP_KERNEL);
443*bed5cd6fSEmil Renner Berthing 	if (!map)
444*bed5cd6fSEmil Renner Berthing 		return -ENOMEM;
445*bed5cd6fSEmil Renner Berthing 
446*bed5cd6fSEmil Renner Berthing 	nmaps = 0;
447*bed5cd6fSEmil Renner Berthing 	mutex_lock(&thp->mutex);
448*bed5cd6fSEmil Renner Berthing 	for_each_available_child_of_node(np, child) {
449*bed5cd6fSEmil Renner Berthing 		unsigned int rollback = nmaps;
450*bed5cd6fSEmil Renner Berthing 		enum th1520_muxtype muxtype;
451*bed5cd6fSEmil Renner Berthing 		struct property *prop;
452*bed5cd6fSEmil Renner Berthing 		const char *funcname;
453*bed5cd6fSEmil Renner Berthing 		const char **pgnames;
454*bed5cd6fSEmil Renner Berthing 		const char *pinname;
455*bed5cd6fSEmil Renner Berthing 		int npins;
456*bed5cd6fSEmil Renner Berthing 
457*bed5cd6fSEmil Renner Berthing 		ret = pinconf_generic_parse_dt_config(child, pctldev, &configs, &nconfigs);
458*bed5cd6fSEmil Renner Berthing 		if (ret) {
459*bed5cd6fSEmil Renner Berthing 			dev_err(thp->pctl->dev, "%pOFn.%pOFn: error parsing pin config\n",
460*bed5cd6fSEmil Renner Berthing 				np, child);
461*bed5cd6fSEmil Renner Berthing 			goto put_child;
462*bed5cd6fSEmil Renner Berthing 		}
463*bed5cd6fSEmil Renner Berthing 
464*bed5cd6fSEmil Renner Berthing 		if (!of_property_read_string(child, "function", &funcname)) {
465*bed5cd6fSEmil Renner Berthing 			muxtype = th1520_muxtype_get(funcname);
466*bed5cd6fSEmil Renner Berthing 			if (!muxtype) {
467*bed5cd6fSEmil Renner Berthing 				dev_err(thp->pctl->dev, "%pOFn.%pOFn: unknown function '%s'\n",
468*bed5cd6fSEmil Renner Berthing 					np, child, funcname);
469*bed5cd6fSEmil Renner Berthing 				ret = -EINVAL;
470*bed5cd6fSEmil Renner Berthing 				goto free_configs;
471*bed5cd6fSEmil Renner Berthing 			}
472*bed5cd6fSEmil Renner Berthing 
473*bed5cd6fSEmil Renner Berthing 			funcname = devm_kasprintf(thp->pctl->dev, GFP_KERNEL, "%pOFn.%pOFn",
474*bed5cd6fSEmil Renner Berthing 						  np, child);
475*bed5cd6fSEmil Renner Berthing 			if (!funcname) {
476*bed5cd6fSEmil Renner Berthing 				ret = -ENOMEM;
477*bed5cd6fSEmil Renner Berthing 				goto free_configs;
478*bed5cd6fSEmil Renner Berthing 			}
479*bed5cd6fSEmil Renner Berthing 
480*bed5cd6fSEmil Renner Berthing 			npins = of_property_count_strings(child, "pins");
481*bed5cd6fSEmil Renner Berthing 			pgnames = devm_kcalloc(thp->pctl->dev, npins, sizeof(*pgnames), GFP_KERNEL);
482*bed5cd6fSEmil Renner Berthing 			if (!pgnames) {
483*bed5cd6fSEmil Renner Berthing 				ret = -ENOMEM;
484*bed5cd6fSEmil Renner Berthing 				goto free_configs;
485*bed5cd6fSEmil Renner Berthing 			}
486*bed5cd6fSEmil Renner Berthing 		} else {
487*bed5cd6fSEmil Renner Berthing 			funcname = NULL;
488*bed5cd6fSEmil Renner Berthing 		}
489*bed5cd6fSEmil Renner Berthing 
490*bed5cd6fSEmil Renner Berthing 		npins = 0;
491*bed5cd6fSEmil Renner Berthing 		of_property_for_each_string(child, "pins", prop, pinname) {
492*bed5cd6fSEmil Renner Berthing 			unsigned int i;
493*bed5cd6fSEmil Renner Berthing 
494*bed5cd6fSEmil Renner Berthing 			for (i = 0; i < thp->desc.npins; i++) {
495*bed5cd6fSEmil Renner Berthing 				if (!strcmp(pinname, thp->desc.pins[i].name))
496*bed5cd6fSEmil Renner Berthing 					break;
497*bed5cd6fSEmil Renner Berthing 			}
498*bed5cd6fSEmil Renner Berthing 			if (i == thp->desc.npins) {
499*bed5cd6fSEmil Renner Berthing 				nmaps = rollback;
500*bed5cd6fSEmil Renner Berthing 				dev_err(thp->pctl->dev, "%pOFn.%pOFn: unknown pin '%s'\n",
501*bed5cd6fSEmil Renner Berthing 					np, child, pinname);
502*bed5cd6fSEmil Renner Berthing 				goto free_configs;
503*bed5cd6fSEmil Renner Berthing 			}
504*bed5cd6fSEmil Renner Berthing 
505*bed5cd6fSEmil Renner Berthing 			if (nconfigs) {
506*bed5cd6fSEmil Renner Berthing 				map[nmaps].type = PIN_MAP_TYPE_CONFIGS_PIN;
507*bed5cd6fSEmil Renner Berthing 				map[nmaps].data.configs.group_or_pin = thp->desc.pins[i].name;
508*bed5cd6fSEmil Renner Berthing 				map[nmaps].data.configs.configs = configs;
509*bed5cd6fSEmil Renner Berthing 				map[nmaps].data.configs.num_configs = nconfigs;
510*bed5cd6fSEmil Renner Berthing 				nmaps += 1;
511*bed5cd6fSEmil Renner Berthing 			}
512*bed5cd6fSEmil Renner Berthing 			if (funcname) {
513*bed5cd6fSEmil Renner Berthing 				pgnames[npins++] = thp->desc.pins[i].name;
514*bed5cd6fSEmil Renner Berthing 				map[nmaps].type = PIN_MAP_TYPE_MUX_GROUP;
515*bed5cd6fSEmil Renner Berthing 				map[nmaps].data.mux.function = funcname;
516*bed5cd6fSEmil Renner Berthing 				map[nmaps].data.mux.group = thp->desc.pins[i].name;
517*bed5cd6fSEmil Renner Berthing 				nmaps += 1;
518*bed5cd6fSEmil Renner Berthing 			}
519*bed5cd6fSEmil Renner Berthing 		}
520*bed5cd6fSEmil Renner Berthing 
521*bed5cd6fSEmil Renner Berthing 		if (funcname) {
522*bed5cd6fSEmil Renner Berthing 			ret = pinmux_generic_add_function(pctldev, funcname, pgnames,
523*bed5cd6fSEmil Renner Berthing 							  npins, (void *)muxtype);
524*bed5cd6fSEmil Renner Berthing 			if (ret < 0) {
525*bed5cd6fSEmil Renner Berthing 				dev_err(thp->pctl->dev, "error adding function %s\n", funcname);
526*bed5cd6fSEmil Renner Berthing 				goto put_child;
527*bed5cd6fSEmil Renner Berthing 			}
528*bed5cd6fSEmil Renner Berthing 		}
529*bed5cd6fSEmil Renner Berthing 	}
530*bed5cd6fSEmil Renner Berthing 
531*bed5cd6fSEmil Renner Berthing 	*maps = map;
532*bed5cd6fSEmil Renner Berthing 	*num_maps = nmaps;
533*bed5cd6fSEmil Renner Berthing 	mutex_unlock(&thp->mutex);
534*bed5cd6fSEmil Renner Berthing 	return 0;
535*bed5cd6fSEmil Renner Berthing 
536*bed5cd6fSEmil Renner Berthing free_configs:
537*bed5cd6fSEmil Renner Berthing 	kfree(configs);
538*bed5cd6fSEmil Renner Berthing put_child:
539*bed5cd6fSEmil Renner Berthing 	of_node_put(child);
540*bed5cd6fSEmil Renner Berthing 	th1520_pinctrl_dt_free_map(pctldev, map, nmaps);
541*bed5cd6fSEmil Renner Berthing 	mutex_unlock(&thp->mutex);
542*bed5cd6fSEmil Renner Berthing 	return ret;
543*bed5cd6fSEmil Renner Berthing }
544*bed5cd6fSEmil Renner Berthing 
545*bed5cd6fSEmil Renner Berthing static const struct pinctrl_ops th1520_pinctrl_ops = {
546*bed5cd6fSEmil Renner Berthing 	.get_groups_count = th1520_pinctrl_get_groups_count,
547*bed5cd6fSEmil Renner Berthing 	.get_group_name = th1520_pinctrl_get_group_name,
548*bed5cd6fSEmil Renner Berthing 	.get_group_pins = th1520_pinctrl_get_group_pins,
549*bed5cd6fSEmil Renner Berthing 	.pin_dbg_show = th1520_pin_dbg_show,
550*bed5cd6fSEmil Renner Berthing 	.dt_node_to_map = th1520_pinctrl_dt_node_to_map,
551*bed5cd6fSEmil Renner Berthing 	.dt_free_map = th1520_pinctrl_dt_free_map,
552*bed5cd6fSEmil Renner Berthing };
553*bed5cd6fSEmil Renner Berthing 
554*bed5cd6fSEmil Renner Berthing static const u8 th1520_drive_strength_in_ma[16] = {
555*bed5cd6fSEmil Renner Berthing 	1, 2, 3, 5, 7, 8, 10, 12, 13, 15, 16, 18, 20, 21, 23, 25,
556*bed5cd6fSEmil Renner Berthing };
557*bed5cd6fSEmil Renner Berthing 
558*bed5cd6fSEmil Renner Berthing static u16 th1520_drive_strength_from_ma(u32 arg)
559*bed5cd6fSEmil Renner Berthing {
560*bed5cd6fSEmil Renner Berthing 	u16 ds;
561*bed5cd6fSEmil Renner Berthing 
562*bed5cd6fSEmil Renner Berthing 	for (ds = 0; ds < TH1520_PADCFG_DS; ds++) {
563*bed5cd6fSEmil Renner Berthing 		if (arg <= th1520_drive_strength_in_ma[ds])
564*bed5cd6fSEmil Renner Berthing 			return ds;
565*bed5cd6fSEmil Renner Berthing 	}
566*bed5cd6fSEmil Renner Berthing 	return TH1520_PADCFG_DS;
567*bed5cd6fSEmil Renner Berthing }
568*bed5cd6fSEmil Renner Berthing 
569*bed5cd6fSEmil Renner Berthing static int th1520_padcfg_rmw(struct th1520_pinctrl *thp, unsigned int pin,
570*bed5cd6fSEmil Renner Berthing 			     u32 mask, u32 value)
571*bed5cd6fSEmil Renner Berthing {
572*bed5cd6fSEmil Renner Berthing 	void __iomem *padcfg = th1520_padcfg(thp, pin);
573*bed5cd6fSEmil Renner Berthing 	unsigned int shift = th1520_padcfg_shift(pin);
574*bed5cd6fSEmil Renner Berthing 	u32 tmp;
575*bed5cd6fSEmil Renner Berthing 
576*bed5cd6fSEmil Renner Berthing 	mask <<= shift;
577*bed5cd6fSEmil Renner Berthing 	value <<= shift;
578*bed5cd6fSEmil Renner Berthing 
579*bed5cd6fSEmil Renner Berthing 	scoped_guard(raw_spinlock_irqsave, &thp->lock) {
580*bed5cd6fSEmil Renner Berthing 		tmp = readl_relaxed(padcfg);
581*bed5cd6fSEmil Renner Berthing 		tmp = (tmp & ~mask) | value;
582*bed5cd6fSEmil Renner Berthing 		writel_relaxed(tmp, padcfg);
583*bed5cd6fSEmil Renner Berthing 	}
584*bed5cd6fSEmil Renner Berthing 	return 0;
585*bed5cd6fSEmil Renner Berthing }
586*bed5cd6fSEmil Renner Berthing 
587*bed5cd6fSEmil Renner Berthing static int th1520_pinconf_get(struct pinctrl_dev *pctldev,
588*bed5cd6fSEmil Renner Berthing 			      unsigned int pin, unsigned long *config)
589*bed5cd6fSEmil Renner Berthing {
590*bed5cd6fSEmil Renner Berthing 	struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev);
591*bed5cd6fSEmil Renner Berthing 	const struct pin_desc *desc = pin_desc_get(pctldev, pin);
592*bed5cd6fSEmil Renner Berthing 	bool enabled;
593*bed5cd6fSEmil Renner Berthing 	int param;
594*bed5cd6fSEmil Renner Berthing 	u32 value;
595*bed5cd6fSEmil Renner Berthing 	u32 arg;
596*bed5cd6fSEmil Renner Berthing 
597*bed5cd6fSEmil Renner Berthing 	if ((uintptr_t)desc->drv_data & TH1520_PAD_NO_PADCFG)
598*bed5cd6fSEmil Renner Berthing 		return -EOPNOTSUPP;
599*bed5cd6fSEmil Renner Berthing 
600*bed5cd6fSEmil Renner Berthing 	value = readl_relaxed(th1520_padcfg(thp, pin));
601*bed5cd6fSEmil Renner Berthing 	value = (value >> th1520_padcfg_shift(pin)) & GENMASK(9, 0);
602*bed5cd6fSEmil Renner Berthing 
603*bed5cd6fSEmil Renner Berthing 	param = pinconf_to_config_param(*config);
604*bed5cd6fSEmil Renner Berthing 	switch (param) {
605*bed5cd6fSEmil Renner Berthing 	case PIN_CONFIG_BIAS_DISABLE:
606*bed5cd6fSEmil Renner Berthing 		enabled = !(value & (TH1520_PADCFG_SPU | TH1520_PADCFG_PE));
607*bed5cd6fSEmil Renner Berthing 		arg = 0;
608*bed5cd6fSEmil Renner Berthing 		break;
609*bed5cd6fSEmil Renner Berthing 	case PIN_CONFIG_BIAS_PULL_DOWN:
610*bed5cd6fSEmil Renner Berthing 		enabled = (value & TH1520_PADCFG_BIAS) == TH1520_PADCFG_PE;
611*bed5cd6fSEmil Renner Berthing 		arg = enabled ? TH1520_PULL_DOWN_OHM : 0;
612*bed5cd6fSEmil Renner Berthing 		break;
613*bed5cd6fSEmil Renner Berthing 	case PIN_CONFIG_BIAS_PULL_UP:
614*bed5cd6fSEmil Renner Berthing 		if (value & TH1520_PADCFG_SPU) {
615*bed5cd6fSEmil Renner Berthing 			enabled = true;
616*bed5cd6fSEmil Renner Berthing 			arg = TH1520_PULL_STRONG_OHM;
617*bed5cd6fSEmil Renner Berthing 		} else if ((value & (TH1520_PADCFG_PE | TH1520_PADCFG_PS)) ==
618*bed5cd6fSEmil Renner Berthing 				    (TH1520_PADCFG_PE | TH1520_PADCFG_PS)) {
619*bed5cd6fSEmil Renner Berthing 			enabled = true;
620*bed5cd6fSEmil Renner Berthing 			arg = TH1520_PULL_UP_OHM;
621*bed5cd6fSEmil Renner Berthing 		} else {
622*bed5cd6fSEmil Renner Berthing 			enabled = false;
623*bed5cd6fSEmil Renner Berthing 			arg = 0;
624*bed5cd6fSEmil Renner Berthing 		}
625*bed5cd6fSEmil Renner Berthing 		break;
626*bed5cd6fSEmil Renner Berthing 	case PIN_CONFIG_DRIVE_STRENGTH:
627*bed5cd6fSEmil Renner Berthing 		enabled = true;
628*bed5cd6fSEmil Renner Berthing 		arg = th1520_drive_strength_in_ma[value & TH1520_PADCFG_DS];
629*bed5cd6fSEmil Renner Berthing 		break;
630*bed5cd6fSEmil Renner Berthing 	case PIN_CONFIG_INPUT_ENABLE:
631*bed5cd6fSEmil Renner Berthing 		enabled = value & TH1520_PADCFG_IE;
632*bed5cd6fSEmil Renner Berthing 		arg = enabled ? 1 : 0;
633*bed5cd6fSEmil Renner Berthing 		break;
634*bed5cd6fSEmil Renner Berthing 	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
635*bed5cd6fSEmil Renner Berthing 		enabled = value & TH1520_PADCFG_ST;
636*bed5cd6fSEmil Renner Berthing 		arg = enabled ? 1 : 0;
637*bed5cd6fSEmil Renner Berthing 		break;
638*bed5cd6fSEmil Renner Berthing 	case PIN_CONFIG_SLEW_RATE:
639*bed5cd6fSEmil Renner Berthing 		enabled = value & TH1520_PADCFG_SL;
640*bed5cd6fSEmil Renner Berthing 		arg = enabled ? 1 : 0;
641*bed5cd6fSEmil Renner Berthing 		break;
642*bed5cd6fSEmil Renner Berthing 	default:
643*bed5cd6fSEmil Renner Berthing 		return -EOPNOTSUPP;
644*bed5cd6fSEmil Renner Berthing 	}
645*bed5cd6fSEmil Renner Berthing 
646*bed5cd6fSEmil Renner Berthing 	*config = pinconf_to_config_packed(param, arg);
647*bed5cd6fSEmil Renner Berthing 	return enabled ? 0 : -EINVAL;
648*bed5cd6fSEmil Renner Berthing }
649*bed5cd6fSEmil Renner Berthing 
650*bed5cd6fSEmil Renner Berthing static int th1520_pinconf_group_get(struct pinctrl_dev *pctldev,
651*bed5cd6fSEmil Renner Berthing 				    unsigned int gsel, unsigned long *config)
652*bed5cd6fSEmil Renner Berthing {
653*bed5cd6fSEmil Renner Berthing 	struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev);
654*bed5cd6fSEmil Renner Berthing 	unsigned int pin = thp->desc.pins[gsel].number;
655*bed5cd6fSEmil Renner Berthing 
656*bed5cd6fSEmil Renner Berthing 	return th1520_pinconf_get(pctldev, pin, config);
657*bed5cd6fSEmil Renner Berthing }
658*bed5cd6fSEmil Renner Berthing 
659*bed5cd6fSEmil Renner Berthing static int th1520_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
660*bed5cd6fSEmil Renner Berthing 			      unsigned long *configs, unsigned int num_configs)
661*bed5cd6fSEmil Renner Berthing {
662*bed5cd6fSEmil Renner Berthing 	struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev);
663*bed5cd6fSEmil Renner Berthing 	const struct pin_desc *desc = pin_desc_get(pctldev, pin);
664*bed5cd6fSEmil Renner Berthing 	unsigned int i;
665*bed5cd6fSEmil Renner Berthing 	u16 mask, value;
666*bed5cd6fSEmil Renner Berthing 
667*bed5cd6fSEmil Renner Berthing 	if ((uintptr_t)desc->drv_data & TH1520_PAD_NO_PADCFG)
668*bed5cd6fSEmil Renner Berthing 		return -EOPNOTSUPP;
669*bed5cd6fSEmil Renner Berthing 
670*bed5cd6fSEmil Renner Berthing 	mask = 0;
671*bed5cd6fSEmil Renner Berthing 	value = 0;
672*bed5cd6fSEmil Renner Berthing 	for (i = 0; i < num_configs; i++) {
673*bed5cd6fSEmil Renner Berthing 		int param = pinconf_to_config_param(configs[i]);
674*bed5cd6fSEmil Renner Berthing 		u32 arg = pinconf_to_config_argument(configs[i]);
675*bed5cd6fSEmil Renner Berthing 
676*bed5cd6fSEmil Renner Berthing 		switch (param) {
677*bed5cd6fSEmil Renner Berthing 		case PIN_CONFIG_BIAS_DISABLE:
678*bed5cd6fSEmil Renner Berthing 			mask |= TH1520_PADCFG_BIAS;
679*bed5cd6fSEmil Renner Berthing 			value &= ~TH1520_PADCFG_BIAS;
680*bed5cd6fSEmil Renner Berthing 			break;
681*bed5cd6fSEmil Renner Berthing 		case PIN_CONFIG_BIAS_PULL_DOWN:
682*bed5cd6fSEmil Renner Berthing 			if (arg == 0)
683*bed5cd6fSEmil Renner Berthing 				return -EOPNOTSUPP;
684*bed5cd6fSEmil Renner Berthing 			mask |= TH1520_PADCFG_BIAS;
685*bed5cd6fSEmil Renner Berthing 			value &= ~TH1520_PADCFG_BIAS;
686*bed5cd6fSEmil Renner Berthing 			value |= TH1520_PADCFG_PE;
687*bed5cd6fSEmil Renner Berthing 			break;
688*bed5cd6fSEmil Renner Berthing 		case PIN_CONFIG_BIAS_PULL_UP:
689*bed5cd6fSEmil Renner Berthing 			if (arg == 0)
690*bed5cd6fSEmil Renner Berthing 				return -EOPNOTSUPP;
691*bed5cd6fSEmil Renner Berthing 			mask |= TH1520_PADCFG_BIAS;
692*bed5cd6fSEmil Renner Berthing 			value &= ~TH1520_PADCFG_BIAS;
693*bed5cd6fSEmil Renner Berthing 			if (arg == TH1520_PULL_STRONG_OHM)
694*bed5cd6fSEmil Renner Berthing 				value |= TH1520_PADCFG_SPU;
695*bed5cd6fSEmil Renner Berthing 			else
696*bed5cd6fSEmil Renner Berthing 				value |= TH1520_PADCFG_PE | TH1520_PADCFG_PS;
697*bed5cd6fSEmil Renner Berthing 			break;
698*bed5cd6fSEmil Renner Berthing 		case PIN_CONFIG_DRIVE_STRENGTH:
699*bed5cd6fSEmil Renner Berthing 			mask |= TH1520_PADCFG_DS;
700*bed5cd6fSEmil Renner Berthing 			value &= ~TH1520_PADCFG_DS;
701*bed5cd6fSEmil Renner Berthing 			value |= th1520_drive_strength_from_ma(arg);
702*bed5cd6fSEmil Renner Berthing 			break;
703*bed5cd6fSEmil Renner Berthing 		case PIN_CONFIG_INPUT_ENABLE:
704*bed5cd6fSEmil Renner Berthing 			mask |= TH1520_PADCFG_IE;
705*bed5cd6fSEmil Renner Berthing 			if (arg)
706*bed5cd6fSEmil Renner Berthing 				value |= TH1520_PADCFG_IE;
707*bed5cd6fSEmil Renner Berthing 			else
708*bed5cd6fSEmil Renner Berthing 				value &= ~TH1520_PADCFG_IE;
709*bed5cd6fSEmil Renner Berthing 			break;
710*bed5cd6fSEmil Renner Berthing 		case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
711*bed5cd6fSEmil Renner Berthing 			mask |= TH1520_PADCFG_ST;
712*bed5cd6fSEmil Renner Berthing 			if (arg)
713*bed5cd6fSEmil Renner Berthing 				value |= TH1520_PADCFG_ST;
714*bed5cd6fSEmil Renner Berthing 			else
715*bed5cd6fSEmil Renner Berthing 				value &= ~TH1520_PADCFG_ST;
716*bed5cd6fSEmil Renner Berthing 			break;
717*bed5cd6fSEmil Renner Berthing 		case PIN_CONFIG_SLEW_RATE:
718*bed5cd6fSEmil Renner Berthing 			mask |= TH1520_PADCFG_SL;
719*bed5cd6fSEmil Renner Berthing 			if (arg)
720*bed5cd6fSEmil Renner Berthing 				value |= TH1520_PADCFG_SL;
721*bed5cd6fSEmil Renner Berthing 			else
722*bed5cd6fSEmil Renner Berthing 				value &= ~TH1520_PADCFG_SL;
723*bed5cd6fSEmil Renner Berthing 			break;
724*bed5cd6fSEmil Renner Berthing 		default:
725*bed5cd6fSEmil Renner Berthing 			return -EOPNOTSUPP;
726*bed5cd6fSEmil Renner Berthing 		}
727*bed5cd6fSEmil Renner Berthing 	}
728*bed5cd6fSEmil Renner Berthing 
729*bed5cd6fSEmil Renner Berthing 	return th1520_padcfg_rmw(thp, pin, mask, value);
730*bed5cd6fSEmil Renner Berthing }
731*bed5cd6fSEmil Renner Berthing 
732*bed5cd6fSEmil Renner Berthing static int th1520_pinconf_group_set(struct pinctrl_dev *pctldev,
733*bed5cd6fSEmil Renner Berthing 				    unsigned int gsel,
734*bed5cd6fSEmil Renner Berthing 				    unsigned long *configs,
735*bed5cd6fSEmil Renner Berthing 				    unsigned int num_configs)
736*bed5cd6fSEmil Renner Berthing {
737*bed5cd6fSEmil Renner Berthing 	struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev);
738*bed5cd6fSEmil Renner Berthing 	unsigned int pin = thp->desc.pins[gsel].number;
739*bed5cd6fSEmil Renner Berthing 
740*bed5cd6fSEmil Renner Berthing 	return th1520_pinconf_set(pctldev, pin, configs, num_configs);
741*bed5cd6fSEmil Renner Berthing }
742*bed5cd6fSEmil Renner Berthing 
743*bed5cd6fSEmil Renner Berthing #ifdef CONFIG_DEBUG_FS
744*bed5cd6fSEmil Renner Berthing static void th1520_pinconf_dbg_show(struct pinctrl_dev *pctldev,
745*bed5cd6fSEmil Renner Berthing 				    struct seq_file *s, unsigned int pin)
746*bed5cd6fSEmil Renner Berthing {
747*bed5cd6fSEmil Renner Berthing 	struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev);
748*bed5cd6fSEmil Renner Berthing 	u32 value = readl_relaxed(th1520_padcfg(thp, pin));
749*bed5cd6fSEmil Renner Berthing 
750*bed5cd6fSEmil Renner Berthing 	value = (value >> th1520_padcfg_shift(pin)) & GENMASK(9, 0);
751*bed5cd6fSEmil Renner Berthing 
752*bed5cd6fSEmil Renner Berthing 	seq_printf(s, " [0x%03x]", value);
753*bed5cd6fSEmil Renner Berthing }
754*bed5cd6fSEmil Renner Berthing #else
755*bed5cd6fSEmil Renner Berthing #define th1520_pinconf_dbg_show NULL
756*bed5cd6fSEmil Renner Berthing #endif
757*bed5cd6fSEmil Renner Berthing 
758*bed5cd6fSEmil Renner Berthing static const struct pinconf_ops th1520_pinconf_ops = {
759*bed5cd6fSEmil Renner Berthing 	.pin_config_get = th1520_pinconf_get,
760*bed5cd6fSEmil Renner Berthing 	.pin_config_group_get = th1520_pinconf_group_get,
761*bed5cd6fSEmil Renner Berthing 	.pin_config_set = th1520_pinconf_set,
762*bed5cd6fSEmil Renner Berthing 	.pin_config_group_set = th1520_pinconf_group_set,
763*bed5cd6fSEmil Renner Berthing 	.pin_config_dbg_show = th1520_pinconf_dbg_show,
764*bed5cd6fSEmil Renner Berthing 	.is_generic = true,
765*bed5cd6fSEmil Renner Berthing };
766*bed5cd6fSEmil Renner Berthing 
767*bed5cd6fSEmil Renner Berthing static int th1520_pinmux_set(struct th1520_pinctrl *thp, unsigned int pin,
768*bed5cd6fSEmil Renner Berthing 			     unsigned long muxdata, enum th1520_muxtype muxtype)
769*bed5cd6fSEmil Renner Berthing {
770*bed5cd6fSEmil Renner Berthing 	void __iomem *muxcfg = th1520_muxcfg(thp, pin);
771*bed5cd6fSEmil Renner Berthing 	unsigned int shift = th1520_muxcfg_shift(pin);
772*bed5cd6fSEmil Renner Berthing 	u32 mask, value, tmp;
773*bed5cd6fSEmil Renner Berthing 
774*bed5cd6fSEmil Renner Berthing 	for (value = 0; muxdata; muxdata >>= 5, value++) {
775*bed5cd6fSEmil Renner Berthing 		if ((muxdata & GENMASK(4, 0)) == muxtype)
776*bed5cd6fSEmil Renner Berthing 			break;
777*bed5cd6fSEmil Renner Berthing 	}
778*bed5cd6fSEmil Renner Berthing 	if (!muxdata) {
779*bed5cd6fSEmil Renner Berthing 		dev_err(thp->pctl->dev, "invalid mux %s for pin %s\n",
780*bed5cd6fSEmil Renner Berthing 			th1520_muxtype_string[muxtype], pin_get_name(thp->pctl, pin));
781*bed5cd6fSEmil Renner Berthing 		return -EINVAL;
782*bed5cd6fSEmil Renner Berthing 	}
783*bed5cd6fSEmil Renner Berthing 
784*bed5cd6fSEmil Renner Berthing 	mask = GENMASK(3, 0) << shift;
785*bed5cd6fSEmil Renner Berthing 	value = value << shift;
786*bed5cd6fSEmil Renner Berthing 
787*bed5cd6fSEmil Renner Berthing 	scoped_guard(raw_spinlock_irqsave, &thp->lock) {
788*bed5cd6fSEmil Renner Berthing 		tmp = readl_relaxed(muxcfg);
789*bed5cd6fSEmil Renner Berthing 		tmp = (tmp & ~mask) | value;
790*bed5cd6fSEmil Renner Berthing 		writel_relaxed(tmp, muxcfg);
791*bed5cd6fSEmil Renner Berthing 	}
792*bed5cd6fSEmil Renner Berthing 	return 0;
793*bed5cd6fSEmil Renner Berthing }
794*bed5cd6fSEmil Renner Berthing 
795*bed5cd6fSEmil Renner Berthing static int th1520_pinmux_set_mux(struct pinctrl_dev *pctldev,
796*bed5cd6fSEmil Renner Berthing 				 unsigned int fsel, unsigned int gsel)
797*bed5cd6fSEmil Renner Berthing {
798*bed5cd6fSEmil Renner Berthing 	struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev);
799*bed5cd6fSEmil Renner Berthing 	const struct function_desc *func = pinmux_generic_get_function(pctldev, fsel);
800*bed5cd6fSEmil Renner Berthing 
801*bed5cd6fSEmil Renner Berthing 	return th1520_pinmux_set(thp, thp->desc.pins[gsel].number,
802*bed5cd6fSEmil Renner Berthing 				 (uintptr_t)thp->desc.pins[gsel].drv_data & TH1520_PAD_MUXDATA,
803*bed5cd6fSEmil Renner Berthing 				 (uintptr_t)func->data);
804*bed5cd6fSEmil Renner Berthing }
805*bed5cd6fSEmil Renner Berthing 
806*bed5cd6fSEmil Renner Berthing static int th1520_gpio_request_enable(struct pinctrl_dev *pctldev,
807*bed5cd6fSEmil Renner Berthing 				      struct pinctrl_gpio_range *range,
808*bed5cd6fSEmil Renner Berthing 				      unsigned int offset)
809*bed5cd6fSEmil Renner Berthing {
810*bed5cd6fSEmil Renner Berthing 	struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev);
811*bed5cd6fSEmil Renner Berthing 	const struct pin_desc *desc = pin_desc_get(pctldev, offset);
812*bed5cd6fSEmil Renner Berthing 
813*bed5cd6fSEmil Renner Berthing 	return th1520_pinmux_set(thp, offset,
814*bed5cd6fSEmil Renner Berthing 				 (uintptr_t)desc->drv_data & TH1520_PAD_MUXDATA,
815*bed5cd6fSEmil Renner Berthing 				 TH1520_MUX_GPIO);
816*bed5cd6fSEmil Renner Berthing }
817*bed5cd6fSEmil Renner Berthing 
818*bed5cd6fSEmil Renner Berthing static int th1520_gpio_set_direction(struct pinctrl_dev *pctldev,
819*bed5cd6fSEmil Renner Berthing 				     struct pinctrl_gpio_range *range,
820*bed5cd6fSEmil Renner Berthing 				     unsigned int offset, bool input)
821*bed5cd6fSEmil Renner Berthing {
822*bed5cd6fSEmil Renner Berthing 	struct th1520_pinctrl *thp = pinctrl_dev_get_drvdata(pctldev);
823*bed5cd6fSEmil Renner Berthing 
824*bed5cd6fSEmil Renner Berthing 	return th1520_padcfg_rmw(thp, offset, TH1520_PADCFG_IE,
825*bed5cd6fSEmil Renner Berthing 				 input ? TH1520_PADCFG_IE : 0);
826*bed5cd6fSEmil Renner Berthing }
827*bed5cd6fSEmil Renner Berthing 
828*bed5cd6fSEmil Renner Berthing static const struct pinmux_ops th1520_pinmux_ops = {
829*bed5cd6fSEmil Renner Berthing 	.get_functions_count = pinmux_generic_get_function_count,
830*bed5cd6fSEmil Renner Berthing 	.get_function_name = pinmux_generic_get_function_name,
831*bed5cd6fSEmil Renner Berthing 	.get_function_groups = pinmux_generic_get_function_groups,
832*bed5cd6fSEmil Renner Berthing 	.set_mux = th1520_pinmux_set_mux,
833*bed5cd6fSEmil Renner Berthing 	.gpio_request_enable = th1520_gpio_request_enable,
834*bed5cd6fSEmil Renner Berthing 	.gpio_set_direction = th1520_gpio_set_direction,
835*bed5cd6fSEmil Renner Berthing 	.strict = true,
836*bed5cd6fSEmil Renner Berthing };
837*bed5cd6fSEmil Renner Berthing 
838*bed5cd6fSEmil Renner Berthing static int th1520_pinctrl_probe(struct platform_device *pdev)
839*bed5cd6fSEmil Renner Berthing {
840*bed5cd6fSEmil Renner Berthing 	struct device *dev = &pdev->dev;
841*bed5cd6fSEmil Renner Berthing 	const struct th1520_pad_group *group;
842*bed5cd6fSEmil Renner Berthing 	struct device_node *np = dev->of_node;
843*bed5cd6fSEmil Renner Berthing 	struct th1520_pinctrl *thp;
844*bed5cd6fSEmil Renner Berthing 	struct clk *clk;
845*bed5cd6fSEmil Renner Berthing 	u32 pin_group;
846*bed5cd6fSEmil Renner Berthing 	int ret;
847*bed5cd6fSEmil Renner Berthing 
848*bed5cd6fSEmil Renner Berthing 	thp = devm_kzalloc(dev, sizeof(*thp), GFP_KERNEL);
849*bed5cd6fSEmil Renner Berthing 	if (!thp)
850*bed5cd6fSEmil Renner Berthing 		return -ENOMEM;
851*bed5cd6fSEmil Renner Berthing 
852*bed5cd6fSEmil Renner Berthing 	thp->base = devm_platform_ioremap_resource(pdev, 0);
853*bed5cd6fSEmil Renner Berthing 	if (IS_ERR(thp->base))
854*bed5cd6fSEmil Renner Berthing 		return PTR_ERR(thp->base);
855*bed5cd6fSEmil Renner Berthing 
856*bed5cd6fSEmil Renner Berthing 	clk = devm_clk_get_enabled(dev, NULL);
857*bed5cd6fSEmil Renner Berthing 	if (IS_ERR(clk))
858*bed5cd6fSEmil Renner Berthing 		return dev_err_probe(dev, PTR_ERR(clk), "error getting clock\n");
859*bed5cd6fSEmil Renner Berthing 
860*bed5cd6fSEmil Renner Berthing 	ret = of_property_read_u32(np, "thead,pad-group", &pin_group);
861*bed5cd6fSEmil Renner Berthing 	if (ret)
862*bed5cd6fSEmil Renner Berthing 		return dev_err_probe(dev, ret, "failed to read the thead,pad-group property\n");
863*bed5cd6fSEmil Renner Berthing 
864*bed5cd6fSEmil Renner Berthing 	if (pin_group == 1)
865*bed5cd6fSEmil Renner Berthing 		group = &th1520_group1;
866*bed5cd6fSEmil Renner Berthing 	else if (pin_group == 2)
867*bed5cd6fSEmil Renner Berthing 		group = &th1520_group2;
868*bed5cd6fSEmil Renner Berthing 	else if (pin_group == 3)
869*bed5cd6fSEmil Renner Berthing 		group = &th1520_group3;
870*bed5cd6fSEmil Renner Berthing 	else
871*bed5cd6fSEmil Renner Berthing 		return dev_err_probe(dev, -EINVAL, "unit address did not match any pad group\n");
872*bed5cd6fSEmil Renner Berthing 
873*bed5cd6fSEmil Renner Berthing 	thp->desc.name = group->name;
874*bed5cd6fSEmil Renner Berthing 	thp->desc.pins = group->pins;
875*bed5cd6fSEmil Renner Berthing 	thp->desc.npins = group->npins;
876*bed5cd6fSEmil Renner Berthing 	thp->desc.pctlops = &th1520_pinctrl_ops;
877*bed5cd6fSEmil Renner Berthing 	thp->desc.pmxops = &th1520_pinmux_ops;
878*bed5cd6fSEmil Renner Berthing 	thp->desc.confops = &th1520_pinconf_ops;
879*bed5cd6fSEmil Renner Berthing 	thp->desc.owner = THIS_MODULE;
880*bed5cd6fSEmil Renner Berthing 	mutex_init(&thp->mutex);
881*bed5cd6fSEmil Renner Berthing 	raw_spin_lock_init(&thp->lock);
882*bed5cd6fSEmil Renner Berthing 
883*bed5cd6fSEmil Renner Berthing 	ret = devm_pinctrl_register_and_init(dev, &thp->desc, thp, &thp->pctl);
884*bed5cd6fSEmil Renner Berthing 	if (ret)
885*bed5cd6fSEmil Renner Berthing 		return dev_err_probe(dev, ret, "could not register pinctrl driver\n");
886*bed5cd6fSEmil Renner Berthing 
887*bed5cd6fSEmil Renner Berthing 	return pinctrl_enable(thp->pctl);
888*bed5cd6fSEmil Renner Berthing }
889*bed5cd6fSEmil Renner Berthing 
890*bed5cd6fSEmil Renner Berthing static const struct of_device_id th1520_pinctrl_of_match[] = {
891*bed5cd6fSEmil Renner Berthing 	{ .compatible = "thead,th1520-pinctrl"},
892*bed5cd6fSEmil Renner Berthing 	{ /* sentinel */ }
893*bed5cd6fSEmil Renner Berthing };
894*bed5cd6fSEmil Renner Berthing MODULE_DEVICE_TABLE(of, th1520_pinctrl_of_match);
895*bed5cd6fSEmil Renner Berthing 
896*bed5cd6fSEmil Renner Berthing static struct platform_driver th1520_pinctrl_driver = {
897*bed5cd6fSEmil Renner Berthing 	.probe = th1520_pinctrl_probe,
898*bed5cd6fSEmil Renner Berthing 	.driver = {
899*bed5cd6fSEmil Renner Berthing 		.name = "pinctrl-th1520",
900*bed5cd6fSEmil Renner Berthing 		.of_match_table = th1520_pinctrl_of_match,
901*bed5cd6fSEmil Renner Berthing 	},
902*bed5cd6fSEmil Renner Berthing };
903*bed5cd6fSEmil Renner Berthing module_platform_driver(th1520_pinctrl_driver);
904*bed5cd6fSEmil Renner Berthing 
905*bed5cd6fSEmil Renner Berthing MODULE_DESCRIPTION("Pinctrl driver for the T-Head TH1520 SoC");
906*bed5cd6fSEmil Renner Berthing MODULE_AUTHOR("Emil Renner Berthing <emil.renner.berthing@canonical.com>");
907*bed5cd6fSEmil Renner Berthing MODULE_LICENSE("GPL");
908