File Index
Files and directories
Sign in
FILE

pinctrl-th1520.c

File preview with syntax highlighting.

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