xref: /linux/drivers/pinctrl/pinctrl-rockchip.c (revision 42b16d3ac371a2fac9b6f08fd75f23f34ba3955a)
11802d0beSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2d3e51161SHeiko Stübner /*
3d3e51161SHeiko Stübner  * Pinctrl driver for Rockchip SoCs
4d3e51161SHeiko Stübner  *
5d3e51161SHeiko Stübner  * Copyright (c) 2013 MundoReader S.L.
6d3e51161SHeiko Stübner  * Author: Heiko Stuebner <heiko@sntech.de>
7d3e51161SHeiko Stübner  *
8d3e51161SHeiko Stübner  * With some ideas taken from pinctrl-samsung:
9d3e51161SHeiko Stübner  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
10d3e51161SHeiko Stübner  *		http://www.samsung.com
11d3e51161SHeiko Stübner  * Copyright (c) 2012 Linaro Ltd
123e3f742bSAlexander A. Klimov  *		https://www.linaro.org
13d3e51161SHeiko Stübner  *
14d3e51161SHeiko Stübner  * and pinctrl-at91:
15d3e51161SHeiko Stübner  * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
16d3e51161SHeiko Stübner  */
17d3e51161SHeiko Stübner 
182f436204SPaul Gortmaker #include <linux/init.h>
19be786ac5SJianqun Xu #include <linux/module.h>
20d3e51161SHeiko Stübner #include <linux/platform_device.h>
21d3e51161SHeiko Stübner #include <linux/io.h>
22d3e51161SHeiko Stübner #include <linux/bitops.h>
231c5fb66aSLinus Walleij #include <linux/gpio/driver.h>
24060f03e9SRob Herring #include <linux/of.h>
25060f03e9SRob Herring #include <linux/of_platform.h>
26d3e51161SHeiko Stübner #include <linux/pinctrl/machine.h>
27d3e51161SHeiko Stübner #include <linux/pinctrl/pinconf.h>
28d3e51161SHeiko Stübner #include <linux/pinctrl/pinctrl.h>
29d3e51161SHeiko Stübner #include <linux/pinctrl/pinmux.h>
30d3e51161SHeiko Stübner #include <linux/pinctrl/pinconf-generic.h>
31d3e51161SHeiko Stübner #include <linux/irqchip/chained_irq.h>
327e865abbSHeiko Stübner #include <linux/clk.h>
33751a99abSHeiko Stübner #include <linux/regmap.h>
3414dee867SHeiko Stübner #include <linux/mfd/syscon.h>
35069d7796SAndy Shevchenko #include <linux/string_helpers.h>
36069d7796SAndy Shevchenko 
37d3e51161SHeiko Stübner #include <dt-bindings/pinctrl/rockchip.h>
38d3e51161SHeiko Stübner 
39d3e51161SHeiko Stübner #include "core.h"
40d3e51161SHeiko Stübner #include "pinconf.h"
41e1450694SJianqun Xu #include "pinctrl-rockchip.h"
42d3e51161SHeiko Stübner 
435a83227bSAndy Shevchenko /*
44c0dadc0eSJianqun Xu  * Generate a bitmask for setting a value (v) with a write mask bit in hiword
45c0dadc0eSJianqun Xu  * register 31:16 area.
46c0dadc0eSJianqun Xu  */
47c0dadc0eSJianqun Xu #define WRITE_MASK_VAL(h, l, v) \
48c0dadc0eSJianqun Xu 	(GENMASK(((h) + 16), ((l) + 16)) | (((v) << (l)) & GENMASK((h), (l))))
49c0dadc0eSJianqun Xu 
50e1524ea8SLee Jones /*
51fc72c923SHeiko Stübner  * Encode variants of iomux registers into a type variable
52fc72c923SHeiko Stübner  */
53fc72c923SHeiko Stübner #define IOMUX_GPIO_ONLY		BIT(0)
5403716e1dSHeiko Stübner #define IOMUX_WIDTH_4BIT	BIT(1)
5595ec8ae4SHeiko Stübner #define IOMUX_SOURCE_PMU	BIT(2)
5662f49226SHeiko Stübner #define IOMUX_UNROUTED		BIT(3)
578b6c6f93Sdavid.wu #define IOMUX_WIDTH_3BIT	BIT(4)
587825aeb7SJianqun Xu #define IOMUX_WIDTH_2BIT	BIT(5)
59fd4ea486SJagan Teki #define IOMUX_L_SOURCE_PMU	BIT(6)
60fc72c923SHeiko Stübner 
61d3e51161SHeiko Stübner #define PIN_BANK(id, pins, label)			\
62d3e51161SHeiko Stübner 	{						\
63d3e51161SHeiko Stübner 		.bank_num	= id,			\
64d3e51161SHeiko Stübner 		.nr_pins	= pins,			\
65d3e51161SHeiko Stübner 		.name		= label,		\
666bc0d121SHeiko Stübner 		.iomux		= {			\
676bc0d121SHeiko Stübner 			{ .offset = -1 },		\
686bc0d121SHeiko Stübner 			{ .offset = -1 },		\
696bc0d121SHeiko Stübner 			{ .offset = -1 },		\
706bc0d121SHeiko Stübner 			{ .offset = -1 },		\
716bc0d121SHeiko Stübner 		},					\
72d3e51161SHeiko Stübner 	}
73d3e51161SHeiko Stübner 
74fc72c923SHeiko Stübner #define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3)	\
75fc72c923SHeiko Stübner 	{								\
76fc72c923SHeiko Stübner 		.bank_num	= id,					\
77fc72c923SHeiko Stübner 		.nr_pins	= pins,					\
78fc72c923SHeiko Stübner 		.name		= label,				\
79fc72c923SHeiko Stübner 		.iomux		= {					\
806bc0d121SHeiko Stübner 			{ .type = iom0, .offset = -1 },			\
816bc0d121SHeiko Stübner 			{ .type = iom1, .offset = -1 },			\
826bc0d121SHeiko Stübner 			{ .type = iom2, .offset = -1 },			\
836bc0d121SHeiko Stübner 			{ .type = iom3, .offset = -1 },			\
84fc72c923SHeiko Stübner 		},							\
85fc72c923SHeiko Stübner 	}
86fc72c923SHeiko Stübner 
87b6c23275SDavid Wu #define PIN_BANK_IOMUX_FLAGS_OFFSET_PULL_FLAGS(id, pins, label, iom0,	\
88b6c23275SDavid Wu 					       iom1, iom2, iom3,	\
89b6c23275SDavid Wu 					       offset0, offset1,	\
90b6c23275SDavid Wu 					       offset2, offset3, pull0,	\
91b6c23275SDavid Wu 					       pull1, pull2, pull3)	\
92b6c23275SDavid Wu 	{								\
93b6c23275SDavid Wu 		.bank_num	= id,					\
94b6c23275SDavid Wu 		.nr_pins	= pins,					\
95b6c23275SDavid Wu 		.name		= label,				\
96b6c23275SDavid Wu 		.iomux		= {					\
97b6c23275SDavid Wu 			{ .type = iom0, .offset = offset0 },		\
98b6c23275SDavid Wu 			{ .type = iom1, .offset = offset1 },		\
99b6c23275SDavid Wu 			{ .type = iom2, .offset = offset2 },		\
100b6c23275SDavid Wu 			{ .type = iom3, .offset = offset3 },		\
101b6c23275SDavid Wu 		},							\
102b6c23275SDavid Wu 		.pull_type[0] = pull0,					\
103b6c23275SDavid Wu 		.pull_type[1] = pull1,					\
104b6c23275SDavid Wu 		.pull_type[2] = pull2,					\
105b6c23275SDavid Wu 		.pull_type[3] = pull3,					\
106fdc33ebaSJianqun Xu 	}
107fdc33ebaSJianqun Xu 
108fdc33ebaSJianqun Xu #define PIN_BANK_DRV_FLAGS(id, pins, label, type0, type1, type2, type3) \
109fdc33ebaSJianqun Xu 	{								\
110fdc33ebaSJianqun Xu 		.bank_num	= id,					\
111fdc33ebaSJianqun Xu 		.nr_pins	= pins,					\
112fdc33ebaSJianqun Xu 		.name		= label,				\
113fdc33ebaSJianqun Xu 		.iomux		= {					\
114fdc33ebaSJianqun Xu 			{ .offset = -1 },				\
115fdc33ebaSJianqun Xu 			{ .offset = -1 },				\
116fdc33ebaSJianqun Xu 			{ .offset = -1 },				\
117fdc33ebaSJianqun Xu 			{ .offset = -1 },				\
118fdc33ebaSJianqun Xu 		},							\
119fdc33ebaSJianqun Xu 		.drv		= {					\
120fdc33ebaSJianqun Xu 			{ .drv_type = type0, .offset = -1 },		\
121fdc33ebaSJianqun Xu 			{ .drv_type = type1, .offset = -1 },		\
122fdc33ebaSJianqun Xu 			{ .drv_type = type2, .offset = -1 },		\
123fdc33ebaSJianqun Xu 			{ .drv_type = type3, .offset = -1 },		\
124fdc33ebaSJianqun Xu 		},							\
1253ba6767aSDavid Wu 	}
1263ba6767aSDavid Wu 
1273ba6767aSDavid Wu #define PIN_BANK_IOMUX_FLAGS_PULL_FLAGS(id, pins, label, iom0, iom1,	\
1283ba6767aSDavid Wu 					iom2, iom3, pull0, pull1,	\
1293ba6767aSDavid Wu 					pull2, pull3)			\
1303ba6767aSDavid Wu 	{								\
1313ba6767aSDavid Wu 		.bank_num	= id,					\
1323ba6767aSDavid Wu 		.nr_pins	= pins,					\
1333ba6767aSDavid Wu 		.name		= label,				\
1343ba6767aSDavid Wu 		.iomux		= {					\
1353ba6767aSDavid Wu 			{ .type = iom0, .offset = -1 },			\
1363ba6767aSDavid Wu 			{ .type = iom1, .offset = -1 },			\
1373ba6767aSDavid Wu 			{ .type = iom2, .offset = -1 },			\
1383ba6767aSDavid Wu 			{ .type = iom3, .offset = -1 },			\
1393ba6767aSDavid Wu 		},							\
1403ba6767aSDavid Wu 		.pull_type[0] = pull0,					\
1413ba6767aSDavid Wu 		.pull_type[1] = pull1,					\
1423ba6767aSDavid Wu 		.pull_type[2] = pull2,					\
1433ba6767aSDavid Wu 		.pull_type[3] = pull3,					\
1443ba6767aSDavid Wu 	}
1453ba6767aSDavid Wu 
1463ba6767aSDavid Wu #define PIN_BANK_DRV_FLAGS_PULL_FLAGS(id, pins, label, drv0, drv1,	\
1473ba6767aSDavid Wu 				      drv2, drv3, pull0, pull1,		\
1483ba6767aSDavid Wu 				      pull2, pull3)			\
1493ba6767aSDavid Wu 	{								\
150fd4ea486SJagan Teki 		.bank_num	= id,					\
151fd4ea486SJagan Teki 		.nr_pins	= pins,					\
152fd4ea486SJagan Teki 		.name		= label,				\
153fd4ea486SJagan Teki 		.iomux		= {					\
154fd4ea486SJagan Teki 			{ .offset = -1 },				\
155fd4ea486SJagan Teki 			{ .offset = -1 },				\
156fd4ea486SJagan Teki 			{ .offset = -1 },				\
157fd4ea486SJagan Teki 			{ .offset = -1 },				\
158fd4ea486SJagan Teki 		},							\
159fd4ea486SJagan Teki 		.drv		= {					\
160fd4ea486SJagan Teki 			{ .drv_type = drv0, .offset = -1 },		\
161fd4ea486SJagan Teki 			{ .drv_type = drv1, .offset = -1 },		\
162fd4ea486SJagan Teki 			{ .drv_type = drv2, .offset = -1 },		\
163fd4ea486SJagan Teki 			{ .drv_type = drv3, .offset = -1 },		\
164fd4ea486SJagan Teki 		},							\
165b6c23275SDavid Wu 		.pull_type[0] = pull0,					\
166b6c23275SDavid Wu 		.pull_type[1] = pull1,					\
167b6c23275SDavid Wu 		.pull_type[2] = pull2,					\
168b6c23275SDavid Wu 		.pull_type[3] = pull3,					\
169b6c23275SDavid Wu 	}
170b6c23275SDavid Wu 
171b6c23275SDavid Wu #define PIN_BANK_IOMUX_FLAGS_OFFSET(id, pins, label, iom0, iom1, iom2,	\
172b6c23275SDavid Wu 				    iom3, offset0, offset1, offset2,	\
173b6c23275SDavid Wu 				    offset3)				\
174b6c23275SDavid Wu 	{								\
175b6c23275SDavid Wu 		.bank_num	= id,					\
176b6c23275SDavid Wu 		.nr_pins	= pins,					\
177b6c23275SDavid Wu 		.name		= label,				\
178b6c23275SDavid Wu 		.iomux		= {					\
179b6c23275SDavid Wu 			{ .type = iom0, .offset = offset0 },		\
180b6c23275SDavid Wu 			{ .type = iom1, .offset = offset1 },		\
181b6c23275SDavid Wu 			{ .type = iom2, .offset = offset2 },		\
182b6c23275SDavid Wu 			{ .type = iom3, .offset = offset3 },		\
183b6c23275SDavid Wu 		},							\
184b6c23275SDavid Wu 	}
185b6c23275SDavid Wu 
186b6c23275SDavid Wu #define PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(id, pins, label, iom0, iom1,	\
1873ba6767aSDavid Wu 					iom2, iom3, drv0, drv1, drv2,	\
1883ba6767aSDavid Wu 					drv3, offset0, offset1,		\
1893ba6767aSDavid Wu 					offset2, offset3)		\
1903ba6767aSDavid Wu 	{								\
1913ba6767aSDavid Wu 		.bank_num	= id,					\
1923ba6767aSDavid Wu 		.nr_pins	= pins,					\
1933ba6767aSDavid Wu 		.name		= label,				\
1943ba6767aSDavid Wu 		.iomux		= {					\
1953ba6767aSDavid Wu 			{ .type = iom0, .offset = -1 },			\
1963ba6767aSDavid Wu 			{ .type = iom1, .offset = -1 },			\
1973ba6767aSDavid Wu 			{ .type = iom2, .offset = -1 },			\
1983ba6767aSDavid Wu 			{ .type = iom3, .offset = -1 },			\
1993ba6767aSDavid Wu 		},							\
2003ba6767aSDavid Wu 		.drv		= {					\
2013ba6767aSDavid Wu 			{ .drv_type = drv0, .offset = offset0 },	\
2023ba6767aSDavid Wu 			{ .drv_type = drv1, .offset = offset1 },	\
2033ba6767aSDavid Wu 			{ .drv_type = drv2, .offset = offset2 },	\
2043ba6767aSDavid Wu 			{ .drv_type = drv3, .offset = offset3 },	\
2053ba6767aSDavid Wu 		},							\
2063ba6767aSDavid Wu 	}
2073ba6767aSDavid Wu 
2083ba6767aSDavid Wu #define PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(id, pins,	\
2093ba6767aSDavid Wu 					      label, iom0, iom1, iom2,  \
2103ba6767aSDavid Wu 					      iom3, drv0, drv1, drv2,   \
2113ba6767aSDavid Wu 					      drv3, offset0, offset1,   \
2123ba6767aSDavid Wu 					      offset2, offset3, pull0,  \
2133ba6767aSDavid Wu 					      pull1, pull2, pull3)	\
2143ba6767aSDavid Wu 	{								\
215c0dadc0eSJianqun Xu 		.bank_num	= id,					\
216c0dadc0eSJianqun Xu 		.nr_pins	= pins,					\
217c0dadc0eSJianqun Xu 		.name		= label,				\
218c0dadc0eSJianqun Xu 		.iomux		= {					\
219c0dadc0eSJianqun Xu 			{ .type = iom0, .offset = -1 },			\
220c0dadc0eSJianqun Xu 			{ .type = iom1, .offset = -1 },			\
221c0dadc0eSJianqun Xu 			{ .type = iom2, .offset = -1 },			\
222c0dadc0eSJianqun Xu 			{ .type = iom3, .offset = -1 },			\
223c0dadc0eSJianqun Xu 		},							\
224c0dadc0eSJianqun Xu 		.drv		= {					\
225c0dadc0eSJianqun Xu 			{ .drv_type = drv0, .offset = offset0 },	\
226c0dadc0eSJianqun Xu 			{ .drv_type = drv1, .offset = offset1 },	\
227c0dadc0eSJianqun Xu 			{ .drv_type = drv2, .offset = offset2 },	\
228c0dadc0eSJianqun Xu 			{ .drv_type = drv3, .offset = offset3 },	\
229c0dadc0eSJianqun Xu 		},							\
230c0dadc0eSJianqun Xu 		.pull_type[0] = pull0,					\
231c0dadc0eSJianqun Xu 		.pull_type[1] = pull1,					\
232c0dadc0eSJianqun Xu 		.pull_type[2] = pull2,					\
233c0dadc0eSJianqun Xu 		.pull_type[3] = pull3,					\
234fdc33ebaSJianqun Xu 	}
235fdc33ebaSJianqun Xu 
236fdc33ebaSJianqun Xu #define PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, FLAG)		\
237751a99abSHeiko Stübner 	{								\
238751a99abSHeiko Stübner 		.bank_num	= ID,					\
239751a99abSHeiko Stübner 		.pin		= PIN,					\
240751a99abSHeiko Stübner 		.func		= FUNC,					\
241751a99abSHeiko Stübner 		.route_offset	= REG,					\
242751a99abSHeiko Stübner 		.route_val	= VAL,					\
24356411f3cSArnd Bergmann 		.route_location	= FLAG,					\
244d3e51161SHeiko Stübner 	}
245d3e51161SHeiko Stübner 
246d3e51161SHeiko Stübner #define RK_MUXROUTE_SAME(ID, PIN, FUNC, REG, VAL)	\
247d3e51161SHeiko Stübner 	PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_SAME)
248d3e51161SHeiko Stübner 
249d3e51161SHeiko Stübner #define RK_MUXROUTE_GRF(ID, PIN, FUNC, REG, VAL)	\
2501cb95395SAxel Lin 	PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_GRF)
2511cb95395SAxel Lin 
252d3e51161SHeiko Stübner #define RK_MUXROUTE_PMU(ID, PIN, FUNC, REG, VAL)	\
253d3e51161SHeiko Stübner 	PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_PMU)
2541cb95395SAxel Lin 
255d3e51161SHeiko Stübner #define RK3588_PIN_BANK_FLAGS(ID, PIN, LABEL, M, P)			\
256d3e51161SHeiko Stübner 	PIN_BANK_IOMUX_FLAGS_PULL_FLAGS(ID, PIN, LABEL, M, M, M, M, P, P, P, P)
257d3e51161SHeiko Stübner 
258d3e51161SHeiko Stübner static struct regmap_config rockchip_regmap_config = {
259d3e51161SHeiko Stübner 	.reg_bits = 32,
260d3e51161SHeiko Stübner 	.val_bits = 32,
261d3e51161SHeiko Stübner 	.reg_stride = 4,
262d3e51161SHeiko Stübner };
263d3e51161SHeiko Stübner 
pinctrl_name_to_group(const struct rockchip_pinctrl * info,const char * name)264d3e51161SHeiko Stübner static inline const struct rockchip_pin_group *pinctrl_name_to_group(
265d3e51161SHeiko Stübner 					const struct rockchip_pinctrl *info,
26651578b9bSAxel Lin 					const char *name)
267d3e51161SHeiko Stübner {
268d3e51161SHeiko Stübner 	int i;
269d3e51161SHeiko Stübner 
270d3e51161SHeiko Stübner 	for (i = 0; i < info->ngroups; i++) {
271d3e51161SHeiko Stübner 		if (!strcmp(info->groups[i].name, name))
272d3e51161SHeiko Stübner 			return &info->groups[i];
273d3e51161SHeiko Stübner 	}
274d3e51161SHeiko Stübner 
275d3e51161SHeiko Stübner 	return NULL;
276d3e51161SHeiko Stübner }
277d3e51161SHeiko Stübner 
278d3e51161SHeiko Stübner /*
2791cb95395SAxel Lin  * given a pin number that is local to a pin controller, find out the pin bank
280d3e51161SHeiko Stübner  * and the register base of the pin bank.
2811cb95395SAxel Lin  */
pin_to_bank(struct rockchip_pinctrl * info,unsigned pin)282d3e51161SHeiko Stübner static struct rockchip_pin_bank *pin_to_bank(struct rockchip_pinctrl *info,
283d3e51161SHeiko Stübner 								unsigned pin)
284d3e51161SHeiko Stübner {
285d3e51161SHeiko Stübner 	struct rockchip_pin_bank *b = info->ctrl->pin_banks;
286d3e51161SHeiko Stübner 
287d3e51161SHeiko Stübner 	while (pin >= (b->pin_base + b->nr_pins))
288d3e51161SHeiko Stübner 		b++;
289d3e51161SHeiko Stübner 
290d3e51161SHeiko Stübner 	return b;
291d3e51161SHeiko Stübner }
292d3e51161SHeiko Stübner 
bank_num_to_bank(struct rockchip_pinctrl * info,unsigned num)293d3e51161SHeiko Stübner static struct rockchip_pin_bank *bank_num_to_bank(
294d3e51161SHeiko Stübner 					struct rockchip_pinctrl *info,
295d3e51161SHeiko Stübner 					unsigned num)
296d3e51161SHeiko Stübner {
297d3e51161SHeiko Stübner 	struct rockchip_pin_bank *b = info->ctrl->pin_banks;
298d3e51161SHeiko Stübner 	int i;
299d3e51161SHeiko Stübner 
300d3e51161SHeiko Stübner 	for (i = 0; i < info->ctrl->nr_banks; i++, b++) {
301d3e51161SHeiko Stübner 		if (b->bank_num == num)
302d3e51161SHeiko Stübner 			return b;
303d3e51161SHeiko Stübner 	}
304d3e51161SHeiko Stübner 
305d3e51161SHeiko Stübner 	return ERR_PTR(-EINVAL);
306d3e51161SHeiko Stübner }
307d3e51161SHeiko Stübner 
308d3e51161SHeiko Stübner /*
309d3e51161SHeiko Stübner  * Pinctrl_ops handling
310d3e51161SHeiko Stübner  */
311d3e51161SHeiko Stübner 
rockchip_get_groups_count(struct pinctrl_dev * pctldev)312d3e51161SHeiko Stübner static int rockchip_get_groups_count(struct pinctrl_dev *pctldev)
313d3e51161SHeiko Stübner {
314d3e51161SHeiko Stübner 	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
315d3e51161SHeiko Stübner 
316d3e51161SHeiko Stübner 	return info->ngroups;
317d3e51161SHeiko Stübner }
318d3e51161SHeiko Stübner 
rockchip_get_group_name(struct pinctrl_dev * pctldev,unsigned selector)319d3e51161SHeiko Stübner static const char *rockchip_get_group_name(struct pinctrl_dev *pctldev,
320d3e51161SHeiko Stübner 							unsigned selector)
321d3e51161SHeiko Stübner {
322d3e51161SHeiko Stübner 	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
323d3e51161SHeiko Stübner 
324d3e51161SHeiko Stübner 	return info->groups[selector].name;
325d3e51161SHeiko Stübner }
326d3e51161SHeiko Stübner 
rockchip_get_group_pins(struct pinctrl_dev * pctldev,unsigned selector,const unsigned ** pins,unsigned * npins)327e4dd7fd5SAndy Shevchenko static int rockchip_get_group_pins(struct pinctrl_dev *pctldev,
328d3e51161SHeiko Stübner 				      unsigned selector, const unsigned **pins,
329d3e51161SHeiko Stübner 				      unsigned *npins)
330d3e51161SHeiko Stübner {
331d3e51161SHeiko Stübner 	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
332d3e51161SHeiko Stübner 
333d3e51161SHeiko Stübner 	if (selector >= info->ngroups)
334d3e51161SHeiko Stübner 		return -EINVAL;
335d3e51161SHeiko Stübner 
336d3e51161SHeiko Stübner 	*pins = info->groups[selector].pins;
337d3e51161SHeiko Stübner 	*npins = info->groups[selector].npins;
338d3e51161SHeiko Stübner 
339e4dd7fd5SAndy Shevchenko 	return 0;
340d3e51161SHeiko Stübner }
341d3e51161SHeiko Stübner 
rockchip_dt_node_to_map(struct pinctrl_dev * pctldev,struct device_node * np,struct pinctrl_map ** map,unsigned * num_maps)342d3e51161SHeiko Stübner static int rockchip_dt_node_to_map(struct pinctrl_dev *pctldev,
343d3e51161SHeiko Stübner 				 struct device_node *np,
344d7faa8ffSDafna Hirschfeld 				 struct pinctrl_map **map, unsigned *num_maps)
345d7faa8ffSDafna Hirschfeld {
346d3e51161SHeiko Stübner 	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
347d3e51161SHeiko Stübner 	const struct rockchip_pin_group *grp;
348d3e51161SHeiko Stübner 	struct device *dev = info->dev;
349d3e51161SHeiko Stübner 	struct pinctrl_map *new_map;
350d3e51161SHeiko Stübner 	struct device_node *parent;
351d3e51161SHeiko Stübner 	int map_num = 1;
352d3e51161SHeiko Stübner 	int i;
353d3e51161SHeiko Stübner 
354d3e51161SHeiko Stübner 	/*
355d7faa8ffSDafna Hirschfeld 	 * first find the group of this node and check if we need to create
356d3e51161SHeiko Stübner 	 * config maps for pins
357d3e51161SHeiko Stübner 	 */
358d3e51161SHeiko Stübner 	grp = pinctrl_name_to_group(info, np->name);
359d3e51161SHeiko Stübner 	if (!grp) {
360d3e51161SHeiko Stübner 		dev_err(dev, "unable to find group for node %pOFn\n", np);
361d3e51161SHeiko Stübner 		return -EINVAL;
362d3e51161SHeiko Stübner 	}
363d3e51161SHeiko Stübner 
364d3e51161SHeiko Stübner 	map_num += grp->npins;
365d3e51161SHeiko Stübner 
366d3e51161SHeiko Stübner 	new_map = kcalloc(map_num, sizeof(*new_map), GFP_KERNEL);
367d3e51161SHeiko Stübner 	if (!new_map)
368d3e51161SHeiko Stübner 		return -ENOMEM;
369d3e51161SHeiko Stübner 
370d3e51161SHeiko Stübner 	*map = new_map;
371d3e51161SHeiko Stübner 	*num_maps = map_num;
372d3e51161SHeiko Stübner 
373e4dd7fd5SAndy Shevchenko 	/* create mux map */
374d3e51161SHeiko Stübner 	parent = of_get_parent(np);
375d3e51161SHeiko Stübner 	if (!parent) {
376d3e51161SHeiko Stübner 		kfree(new_map);
377d3e51161SHeiko Stübner 		return -EINVAL;
378d3e51161SHeiko Stübner 	}
379d3e51161SHeiko Stübner 	new_map[0].type = PIN_MAP_TYPE_MUX_GROUP;
380d3e51161SHeiko Stübner 	new_map[0].data.mux.function = parent->name;
381d3e51161SHeiko Stübner 	new_map[0].data.mux.group = np->name;
382d7faa8ffSDafna Hirschfeld 	of_node_put(parent);
383d3e51161SHeiko Stübner 
384d3e51161SHeiko Stübner 	/* create config map */
385d3e51161SHeiko Stübner 	new_map++;
386d3e51161SHeiko Stübner 	for (i = 0; i < grp->npins; i++) {
387d3e51161SHeiko Stübner 		new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN;
388d3e51161SHeiko Stübner 		new_map[i].data.configs.group_or_pin =
389d3e51161SHeiko Stübner 				pin_get_name(pctldev, grp->pins[i]);
390d3e51161SHeiko Stübner 		new_map[i].data.configs.configs = grp->data[i].configs;
391d3e51161SHeiko Stübner 		new_map[i].data.configs.num_configs = grp->data[i].nconfigs;
392d3e51161SHeiko Stübner 	}
393d3e51161SHeiko Stübner 
394d3e51161SHeiko Stübner 	dev_dbg(dev, "maps: function %s group %s num %d\n",
395d3e51161SHeiko Stübner 		(*map)->data.mux.function, (*map)->data.mux.group, map_num);
396d3e51161SHeiko Stübner 
39712b8f018SDavid Wu 	return 0;
39812b8f018SDavid Wu }
39912b8f018SDavid Wu 
rockchip_dt_free_map(struct pinctrl_dev * pctldev,struct pinctrl_map * map,unsigned num_maps)40012b8f018SDavid Wu static void rockchip_dt_free_map(struct pinctrl_dev *pctldev,
40112b8f018SDavid Wu 				    struct pinctrl_map *map, unsigned num_maps)
40212b8f018SDavid Wu {
40312b8f018SDavid Wu 	kfree(map);
40412b8f018SDavid Wu }
40512b8f018SDavid Wu 
40612b8f018SDavid Wu static const struct pinctrl_ops rockchip_pctrl_ops = {
40712b8f018SDavid Wu 	.get_groups_count	= rockchip_get_groups_count,
40812b8f018SDavid Wu 	.get_group_name		= rockchip_get_group_name,
40912b8f018SDavid Wu 	.get_group_pins		= rockchip_get_group_pins,
41012b8f018SDavid Wu 	.dt_node_to_map		= rockchip_dt_node_to_map,
41112b8f018SDavid Wu 	.dt_free_map		= rockchip_dt_free_map,
41212b8f018SDavid Wu };
41312b8f018SDavid Wu 
41412b8f018SDavid Wu /*
41512b8f018SDavid Wu  * Hardware access
41612b8f018SDavid Wu  */
41712b8f018SDavid Wu 
41812b8f018SDavid Wu static struct rockchip_mux_recalced_data rv1108_mux_recalced_data[] = {
41912b8f018SDavid Wu 	{
42012b8f018SDavid Wu 		.num = 1,
42112b8f018SDavid Wu 		.pin = 0,
42212b8f018SDavid Wu 		.reg = 0x418,
42312b8f018SDavid Wu 		.bit = 0,
42412b8f018SDavid Wu 		.mask = 0x3
42512b8f018SDavid Wu 	}, {
42612b8f018SDavid Wu 		.num = 1,
42712b8f018SDavid Wu 		.pin = 1,
42812b8f018SDavid Wu 		.reg = 0x418,
42912b8f018SDavid Wu 		.bit = 2,
43012b8f018SDavid Wu 		.mask = 0x3
43112b8f018SDavid Wu 	}, {
43212b8f018SDavid Wu 		.num = 1,
43312b8f018SDavid Wu 		.pin = 2,
43412b8f018SDavid Wu 		.reg = 0x418,
43512b8f018SDavid Wu 		.bit = 4,
43612b8f018SDavid Wu 		.mask = 0x3
43712b8f018SDavid Wu 	}, {
43812b8f018SDavid Wu 		.num = 1,
43912b8f018SDavid Wu 		.pin = 3,
44012b8f018SDavid Wu 		.reg = 0x418,
44112b8f018SDavid Wu 		.bit = 6,
44212b8f018SDavid Wu 		.mask = 0x3
44312b8f018SDavid Wu 	}, {
44412b8f018SDavid Wu 		.num = 1,
44512b8f018SDavid Wu 		.pin = 4,
44612b8f018SDavid Wu 		.reg = 0x418,
44712b8f018SDavid Wu 		.bit = 8,
44812b8f018SDavid Wu 		.mask = 0x3
44912b8f018SDavid Wu 	}, {
45012b8f018SDavid Wu 		.num = 1,
45112b8f018SDavid Wu 		.pin = 5,
45212b8f018SDavid Wu 		.reg = 0x418,
45312b8f018SDavid Wu 		.bit = 10,
45412b8f018SDavid Wu 		.mask = 0x3
45512b8f018SDavid Wu 	}, {
45612b8f018SDavid Wu 		.num = 1,
45712b8f018SDavid Wu 		.pin = 6,
45812b8f018SDavid Wu 		.reg = 0x418,
45912b8f018SDavid Wu 		.bit = 12,
46012b8f018SDavid Wu 		.mask = 0x3
461fd4ea486SJagan Teki 	}, {
462fd4ea486SJagan Teki 		.num = 1,
463fd4ea486SJagan Teki 		.pin = 7,
464fd4ea486SJagan Teki 		.reg = 0x418,
465fd4ea486SJagan Teki 		.bit = 14,
466fd4ea486SJagan Teki 		.mask = 0x3
467fd4ea486SJagan Teki 	}, {
468fd4ea486SJagan Teki 		.num = 1,
469fd4ea486SJagan Teki 		.pin = 8,
470fd4ea486SJagan Teki 		.reg = 0x41c,
471fd4ea486SJagan Teki 		.bit = 0,
472fd4ea486SJagan Teki 		.mask = 0x3
473fd4ea486SJagan Teki 	}, {
474fd4ea486SJagan Teki 		.num = 1,
475fd4ea486SJagan Teki 		.pin = 9,
476fd4ea486SJagan Teki 		.reg = 0x41c,
477fd4ea486SJagan Teki 		.bit = 2,
478fd4ea486SJagan Teki 		.mask = 0x3
479fd4ea486SJagan Teki 	},
480fd4ea486SJagan Teki };
481fd4ea486SJagan Teki 
482fd4ea486SJagan Teki static struct rockchip_mux_recalced_data rv1126_mux_recalced_data[] = {
483fd4ea486SJagan Teki 	{
484fd4ea486SJagan Teki 		.num = 0,
485fd4ea486SJagan Teki 		.pin = 20,
486fd4ea486SJagan Teki 		.reg = 0x10000,
487fd4ea486SJagan Teki 		.bit = 0,
488fd4ea486SJagan Teki 		.mask = 0xf
489fd4ea486SJagan Teki 	},
490fd4ea486SJagan Teki 	{
491fd4ea486SJagan Teki 		.num = 0,
492d23c66dfSDavid Wu 		.pin = 21,
493d23c66dfSDavid Wu 		.reg = 0x10000,
494d23c66dfSDavid Wu 		.bit = 4,
495d23c66dfSDavid Wu 		.mask = 0xf
496d23c66dfSDavid Wu 	},
497d23c66dfSDavid Wu 	{
498d23c66dfSDavid Wu 		.num = 0,
499d23c66dfSDavid Wu 		.pin = 22,
500d23c66dfSDavid Wu 		.reg = 0x10000,
501d23c66dfSDavid Wu 		.bit = 8,
502d23c66dfSDavid Wu 		.mask = 0xf
503d23c66dfSDavid Wu 	},
504d23c66dfSDavid Wu 	{
505d23c66dfSDavid Wu 		.num = 0,
506d23c66dfSDavid Wu 		.pin = 23,
507d23c66dfSDavid Wu 		.reg = 0x10000,
508d23c66dfSDavid Wu 		.bit = 12,
509d23c66dfSDavid Wu 		.mask = 0xf
510d23c66dfSDavid Wu 	},
511d23c66dfSDavid Wu };
512d23c66dfSDavid Wu 
513d23c66dfSDavid Wu static  struct rockchip_mux_recalced_data rk3128_mux_recalced_data[] = {
514d23c66dfSDavid Wu 	{
515d23c66dfSDavid Wu 		.num = 2,
516d23c66dfSDavid Wu 		.pin = 20,
517d23c66dfSDavid Wu 		.reg = 0xe8,
518d23c66dfSDavid Wu 		.bit = 0,
519d23c66dfSDavid Wu 		.mask = 0x7
520d23c66dfSDavid Wu 	}, {
521d23c66dfSDavid Wu 		.num = 2,
522d23c66dfSDavid Wu 		.pin = 21,
523d23c66dfSDavid Wu 		.reg = 0xe8,
524d23c66dfSDavid Wu 		.bit = 4,
525d23c66dfSDavid Wu 		.mask = 0x7
5267825aeb7SJianqun Xu 	}, {
5277825aeb7SJianqun Xu 		.num = 2,
5281f3e25a0SLuca Ceresoli 		.pin = 22,
5297825aeb7SJianqun Xu 		.reg = 0xe8,
5307825aeb7SJianqun Xu 		.bit = 8,
5317825aeb7SJianqun Xu 		.mask = 0x7
5327825aeb7SJianqun Xu 	}, {
5337825aeb7SJianqun Xu 		.num = 2,
5347825aeb7SJianqun Xu 		.pin = 23,
5351f3e25a0SLuca Ceresoli 		.reg = 0xe8,
5367825aeb7SJianqun Xu 		.bit = 12,
5377825aeb7SJianqun Xu 		.mask = 0x7
5387825aeb7SJianqun Xu 	}, {
5397825aeb7SJianqun Xu 		.num = 2,
5407825aeb7SJianqun Xu 		.pin = 24,
5417825aeb7SJianqun Xu 		.reg = 0xd4,
5421f3e25a0SLuca Ceresoli 		.bit = 12,
5437825aeb7SJianqun Xu 		.mask = 0x7
5447825aeb7SJianqun Xu 	},
5457825aeb7SJianqun Xu };
5467825aeb7SJianqun Xu 
5477825aeb7SJianqun Xu static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = {
5487825aeb7SJianqun Xu 	{
5491f3e25a0SLuca Ceresoli 		/* gpio1b6_sel */
5507825aeb7SJianqun Xu 		.num = 1,
5517825aeb7SJianqun Xu 		.pin = 14,
5527825aeb7SJianqun Xu 		.reg = 0x28,
5537825aeb7SJianqun Xu 		.bit = 12,
5547825aeb7SJianqun Xu 		.mask = 0xf
5557825aeb7SJianqun Xu 	}, {
5561f3e25a0SLuca Ceresoli 		/* gpio1b7_sel */
5577825aeb7SJianqun Xu 		.num = 1,
5587825aeb7SJianqun Xu 		.pin = 15,
5597825aeb7SJianqun Xu 		.reg = 0x2c,
5607825aeb7SJianqun Xu 		.bit = 0,
5617825aeb7SJianqun Xu 		.mask = 0x3
5627825aeb7SJianqun Xu 	}, {
5631f3e25a0SLuca Ceresoli 		/* gpio1c2_sel */
5647825aeb7SJianqun Xu 		.num = 1,
5657825aeb7SJianqun Xu 		.pin = 18,
5667825aeb7SJianqun Xu 		.reg = 0x30,
5677825aeb7SJianqun Xu 		.bit = 4,
5687825aeb7SJianqun Xu 		.mask = 0xf
5697825aeb7SJianqun Xu 	}, {
5701f3e25a0SLuca Ceresoli 		/* gpio1c3_sel */
5717825aeb7SJianqun Xu 		.num = 1,
5727825aeb7SJianqun Xu 		.pin = 19,
5737825aeb7SJianqun Xu 		.reg = 0x30,
5747825aeb7SJianqun Xu 		.bit = 8,
5757825aeb7SJianqun Xu 		.mask = 0xf
5767825aeb7SJianqun Xu 	}, {
5771f3e25a0SLuca Ceresoli 		/* gpio1c4_sel */
5787825aeb7SJianqun Xu 		.num = 1,
5797825aeb7SJianqun Xu 		.pin = 20,
5807825aeb7SJianqun Xu 		.reg = 0x30,
5817825aeb7SJianqun Xu 		.bit = 12,
5827825aeb7SJianqun Xu 		.mask = 0xf
5837825aeb7SJianqun Xu 	}, {
5841f3e25a0SLuca Ceresoli 		/* gpio1c5_sel */
5857825aeb7SJianqun Xu 		.num = 1,
5867825aeb7SJianqun Xu 		.pin = 21,
5871f3e25a0SLuca Ceresoli 		.reg = 0x34,
5881f3e25a0SLuca Ceresoli 		.bit = 0,
5891f3e25a0SLuca Ceresoli 		.mask = 0xf
5907825aeb7SJianqun Xu 	}, {
5911f3e25a0SLuca Ceresoli 		/* gpio1c6_sel */
5927825aeb7SJianqun Xu 		.num = 1,
5937825aeb7SJianqun Xu 		.pin = 22,
5941f3e25a0SLuca Ceresoli 		.reg = 0x34,
5951f3e25a0SLuca Ceresoli 		.bit = 4,
5961f3e25a0SLuca Ceresoli 		.mask = 0xf
5977825aeb7SJianqun Xu 	}, {
5981f3e25a0SLuca Ceresoli 		/* gpio1c7_sel */
5997825aeb7SJianqun Xu 		.num = 1,
6007825aeb7SJianqun Xu 		.pin = 23,
6011f3e25a0SLuca Ceresoli 		.reg = 0x34,
6021f3e25a0SLuca Ceresoli 		.bit = 8,
6031f3e25a0SLuca Ceresoli 		.mask = 0xf
6047825aeb7SJianqun Xu 	}, {
6051f3e25a0SLuca Ceresoli 		/* gpio2a2_sel */
6067825aeb7SJianqun Xu 		.num = 2,
6077825aeb7SJianqun Xu 		.pin = 2,
6081f3e25a0SLuca Ceresoli 		.reg = 0x40,
6091f3e25a0SLuca Ceresoli 		.bit = 4,
6101f3e25a0SLuca Ceresoli 		.mask = 0x3
6117825aeb7SJianqun Xu 	}, {
6121f3e25a0SLuca Ceresoli 		/* gpio2a3_sel */
6137825aeb7SJianqun Xu 		.num = 2,
6147825aeb7SJianqun Xu 		.pin = 3,
6151f3e25a0SLuca Ceresoli 		.reg = 0x40,
6161f3e25a0SLuca Ceresoli 		.bit = 6,
6171f3e25a0SLuca Ceresoli 		.mask = 0x3
6187c4cffc5SLuca Ceresoli 	}, {
6197c4cffc5SLuca Ceresoli 		/* gpio2c0_sel */
6207825aeb7SJianqun Xu 		.num = 2,
6217825aeb7SJianqun Xu 		.pin = 16,
6227825aeb7SJianqun Xu 		.reg = 0x50,
6237825aeb7SJianqun Xu 		.bit = 0,
6247825aeb7SJianqun Xu 		.mask = 0x3
6257825aeb7SJianqun Xu 	}, {
6267c4cffc5SLuca Ceresoli 		/* gpio3b2_sel */
6277825aeb7SJianqun Xu 		.num = 3,
6287825aeb7SJianqun Xu 		.pin = 10,
6297825aeb7SJianqun Xu 		.reg = 0x68,
6307825aeb7SJianqun Xu 		.bit = 4,
6317825aeb7SJianqun Xu 		.mask = 0x3
6327825aeb7SJianqun Xu 	}, {
6337825aeb7SJianqun Xu 		/* gpio3b3_sel */
6347825aeb7SJianqun Xu 		.num = 3,
635c04c3fa6SDavid Wu 		.pin = 11,
6363818e4a7Sdavid.wu 		.reg = 0x68,
6375ef6914eSHuang-Huang Bao 		.bit = 6,
6383818e4a7Sdavid.wu 		.mask = 0x3
6393818e4a7Sdavid.wu 	}, {
6403818e4a7Sdavid.wu 		/* gpio3b4_sel */
6413818e4a7Sdavid.wu 		.num = 3,
6423818e4a7Sdavid.wu 		.pin = 12,
6433818e4a7Sdavid.wu 		.reg = 0x68,
6445ef6914eSHuang-Huang Bao 		.bit = 8,
6453818e4a7Sdavid.wu 		.mask = 0xf
6463818e4a7Sdavid.wu 	}, {
6473818e4a7Sdavid.wu 		/* gpio3b5_sel */
6483818e4a7Sdavid.wu 		.num = 3,
6493818e4a7Sdavid.wu 		.pin = 13,
6505ef6914eSHuang-Huang Bao 		.reg = 0x68,
6515ef6914eSHuang-Huang Bao 		.bit = 12,
6525ef6914eSHuang-Huang Bao 		.mask = 0xf
6535ef6914eSHuang-Huang Bao 	},
6545ef6914eSHuang-Huang Bao };
6555ef6914eSHuang-Huang Bao 
6565ef6914eSHuang-Huang Bao static struct rockchip_mux_recalced_data rk3328_mux_recalced_data[] = {
6575ef6914eSHuang-Huang Bao 	{
6585ef6914eSHuang-Huang Bao 		/* gpio2_b7_sel */
6595ef6914eSHuang-Huang Bao 		.num = 2,
6605ef6914eSHuang-Huang Bao 		.pin = 15,
6615ef6914eSHuang-Huang Bao 		.reg = 0x28,
6625ef6914eSHuang-Huang Bao 		.bit = 0,
6635ef6914eSHuang-Huang Bao 		.mask = 0x7
6645ef6914eSHuang-Huang Bao 	}, {
6655ef6914eSHuang-Huang Bao 		/* gpio2_c7_sel */
6665ef6914eSHuang-Huang Bao 		.num = 2,
6675ef6914eSHuang-Huang Bao 		.pin = 23,
6685ef6914eSHuang-Huang Bao 		.reg = 0x30,
6695ef6914eSHuang-Huang Bao 		.bit = 14,
6705ef6914eSHuang-Huang Bao 		.mask = 0x3
6715ef6914eSHuang-Huang Bao 	}, {
6725ef6914eSHuang-Huang Bao 		/* gpio3_b1_sel */
6735ef6914eSHuang-Huang Bao 		.num = 3,
6745ef6914eSHuang-Huang Bao 		.pin = 9,
6755ef6914eSHuang-Huang Bao 		.reg = 0x44,
6765ef6914eSHuang-Huang Bao 		.bit = 2,
6775ef6914eSHuang-Huang Bao 		.mask = 0x3
6785ef6914eSHuang-Huang Bao 	}, {
6795ef6914eSHuang-Huang Bao 		/* gpio3_b2_sel */
6805ef6914eSHuang-Huang Bao 		.num = 3,
6815ef6914eSHuang-Huang Bao 		.pin = 10,
6825ef6914eSHuang-Huang Bao 		.reg = 0x44,
6835ef6914eSHuang-Huang Bao 		.bit = 4,
6845ef6914eSHuang-Huang Bao 		.mask = 0x3
6855ef6914eSHuang-Huang Bao 	}, {
6865ef6914eSHuang-Huang Bao 		/* gpio3_b3_sel */
6875ef6914eSHuang-Huang Bao 		.num = 3,
6885ef6914eSHuang-Huang Bao 		.pin = 11,
6895ef6914eSHuang-Huang Bao 		.reg = 0x44,
6905ef6914eSHuang-Huang Bao 		.bit = 6,
6915ef6914eSHuang-Huang Bao 		.mask = 0x3
6925ef6914eSHuang-Huang Bao 	}, {
6935ef6914eSHuang-Huang Bao 		/* gpio3_b4_sel */
6945ef6914eSHuang-Huang Bao 		.num = 3,
6955ef6914eSHuang-Huang Bao 		.pin = 12,
6965ef6914eSHuang-Huang Bao 		.reg = 0x44,
6975ef6914eSHuang-Huang Bao 		.bit = 8,
6985ef6914eSHuang-Huang Bao 		.mask = 0x3
6993818e4a7Sdavid.wu 	}, {
7003818e4a7Sdavid.wu 		/* gpio3_b5_sel */
7013818e4a7Sdavid.wu 		.num = 3,
702c04c3fa6SDavid Wu 		.pin = 13,
703c04c3fa6SDavid Wu 		.reg = 0x44,
7043818e4a7Sdavid.wu 		.bit = 10,
705c04c3fa6SDavid Wu 		.mask = 0x3
706c04c3fa6SDavid Wu 	}, {
707c04c3fa6SDavid Wu 		/* gpio3_b6_sel */
7083818e4a7Sdavid.wu 		.num = 3,
7093818e4a7Sdavid.wu 		.pin = 14,
710c04c3fa6SDavid Wu 		.reg = 0x44,
711c04c3fa6SDavid Wu 		.bit = 12,
712c04c3fa6SDavid Wu 		.mask = 0x3
713c04c3fa6SDavid Wu 	}, {
7143818e4a7Sdavid.wu 		/* gpio3_b7_sel */
7153818e4a7Sdavid.wu 		.num = 3,
7163818e4a7Sdavid.wu 		.pin = 15,
717c04c3fa6SDavid Wu 		.reg = 0x44,
7183818e4a7Sdavid.wu 		.bit = 14,
7193818e4a7Sdavid.wu 		.mask = 0x3
7203818e4a7Sdavid.wu 	},
7213818e4a7Sdavid.wu };
7223818e4a7Sdavid.wu 
rockchip_get_recalced_mux(struct rockchip_pin_bank * bank,int pin,int * reg,u8 * bit,int * mask)7233818e4a7Sdavid.wu static void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin,
7243818e4a7Sdavid.wu 				      int *reg, u8 *bit, int *mask)
72587065ca9SDavid Wu {
726bee55f2eSQuentin Schulz 	struct rockchip_pinctrl *info = bank->drvdata;
727bee55f2eSQuentin Schulz 	struct rockchip_pin_ctrl *ctrl = info->ctrl;
728bee55f2eSQuentin Schulz 	struct rockchip_mux_recalced_data *data;
729bee55f2eSQuentin Schulz 	int i;
730fe202ea8SJianqun Xu 
731fe202ea8SJianqun Xu 	for (i = 0; i < ctrl->niomux_recalced; i++) {
732bee55f2eSQuentin Schulz 		data = &ctrl->iomux_recalced[i];
733bee55f2eSQuentin Schulz 		if (data->num == bank->bank_num &&
734bee55f2eSQuentin Schulz 		    data->pin == pin)
735bee55f2eSQuentin Schulz 			break;
736bee55f2eSQuentin Schulz 	}
737bee55f2eSQuentin Schulz 
738bee55f2eSQuentin Schulz 	if (i >= ctrl->niomux_recalced)
739bee55f2eSQuentin Schulz 		return;
740bee55f2eSQuentin Schulz 
741bee55f2eSQuentin Schulz 	*reg = data->reg;
742bee55f2eSQuentin Schulz 	*mask = data->mask;
743bee55f2eSQuentin Schulz 	*bit = data->bit;
744bee55f2eSQuentin Schulz }
745bee55f2eSQuentin Schulz 
746bee55f2eSQuentin Schulz static struct rockchip_mux_route_data px30_mux_route_data[] = {
747bee55f2eSQuentin Schulz 	RK_MUXROUTE_SAME(2, RK_PB4, 1, 0x184, BIT(16 + 7)), /* cif-d0m0 */
748bee55f2eSQuentin Schulz 	RK_MUXROUTE_SAME(3, RK_PA1, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d0m1 */
749bee55f2eSQuentin Schulz 	RK_MUXROUTE_SAME(2, RK_PB6, 1, 0x184, BIT(16 + 7)), /* cif-d1m0 */
750bee55f2eSQuentin Schulz 	RK_MUXROUTE_SAME(3, RK_PA2, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d1m1 */
751bee55f2eSQuentin Schulz 	RK_MUXROUTE_SAME(2, RK_PA0, 1, 0x184, BIT(16 + 7)), /* cif-d2m0 */
752bee55f2eSQuentin Schulz 	RK_MUXROUTE_SAME(3, RK_PA3, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d2m1 */
753bee55f2eSQuentin Schulz 	RK_MUXROUTE_SAME(2, RK_PA1, 1, 0x184, BIT(16 + 7)), /* cif-d3m0 */
754bee55f2eSQuentin Schulz 	RK_MUXROUTE_SAME(3, RK_PA5, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d3m1 */
755bee55f2eSQuentin Schulz 	RK_MUXROUTE_SAME(2, RK_PA2, 1, 0x184, BIT(16 + 7)), /* cif-d4m0 */
756bee55f2eSQuentin Schulz 	RK_MUXROUTE_SAME(3, RK_PA7, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d4m1 */
757bee55f2eSQuentin Schulz 	RK_MUXROUTE_SAME(2, RK_PA3, 1, 0x184, BIT(16 + 7)), /* cif-d5m0 */
758fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(3, RK_PB0, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d5m1 */
759fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(2, RK_PA4, 1, 0x184, BIT(16 + 7)), /* cif-d6m0 */
760bee55f2eSQuentin Schulz 	RK_MUXROUTE_SAME(3, RK_PB1, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d6m1 */
761bee55f2eSQuentin Schulz 	RK_MUXROUTE_SAME(2, RK_PA5, 1, 0x184, BIT(16 + 7)), /* cif-d7m0 */
762fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(3, RK_PB4, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d7m1 */
763fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(2, RK_PA6, 1, 0x184, BIT(16 + 7)), /* cif-d8m0 */
764bee55f2eSQuentin Schulz 	RK_MUXROUTE_SAME(3, RK_PB6, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d8m1 */
765bee55f2eSQuentin Schulz 	RK_MUXROUTE_SAME(2, RK_PA7, 1, 0x184, BIT(16 + 7)), /* cif-d9m0 */
766fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(3, RK_PB7, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d9m1 */
767fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(2, RK_PB7, 1, 0x184, BIT(16 + 7)), /* cif-d10m0 */
768bee55f2eSQuentin Schulz 	RK_MUXROUTE_SAME(3, RK_PC6, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d10m1 */
769bee55f2eSQuentin Schulz 	RK_MUXROUTE_SAME(2, RK_PC0, 1, 0x184, BIT(16 + 7)), /* cif-d11m0 */
770bee55f2eSQuentin Schulz 	RK_MUXROUTE_SAME(3, RK_PC7, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d11m1 */
771bee55f2eSQuentin Schulz 	RK_MUXROUTE_SAME(2, RK_PB0, 1, 0x184, BIT(16 + 7)), /* cif-vsyncm0 */
772bee55f2eSQuentin Schulz 	RK_MUXROUTE_SAME(3, RK_PD1, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-vsyncm1 */
773bee55f2eSQuentin Schulz 	RK_MUXROUTE_SAME(2, RK_PB1, 1, 0x184, BIT(16 + 7)), /* cif-hrefm0 */
77487065ca9SDavid Wu 	RK_MUXROUTE_SAME(3, RK_PD2, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-hrefm1 */
77587065ca9SDavid Wu 	RK_MUXROUTE_SAME(2, RK_PB2, 1, 0x184, BIT(16 + 7)), /* cif-clkinm0 */
776fd4ea486SJagan Teki 	RK_MUXROUTE_SAME(3, RK_PD3, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-clkinm1 */
777fd4ea486SJagan Teki 	RK_MUXROUTE_SAME(2, RK_PB3, 1, 0x184, BIT(16 + 7)), /* cif-clkoutm0 */
778fd4ea486SJagan Teki 	RK_MUXROUTE_SAME(3, RK_PD0, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-clkoutm1 */
779fd4ea486SJagan Teki 	RK_MUXROUTE_SAME(3, RK_PC6, 2, 0x184, BIT(16 + 8)), /* pdm-m0 */
780fd4ea486SJagan Teki 	RK_MUXROUTE_SAME(2, RK_PC6, 1, 0x184, BIT(16 + 8) | BIT(8)), /* pdm-m1 */
781fd4ea486SJagan Teki 	RK_MUXROUTE_SAME(3, RK_PD3, 2, 0x184, BIT(16 + 8)), /* pdm-sdi0m0 */
782fd4ea486SJagan Teki 	RK_MUXROUTE_SAME(2, RK_PC5, 2, 0x184, BIT(16 + 8) | BIT(8)), /* pdm-sdi0m1 */
783fd4ea486SJagan Teki 	RK_MUXROUTE_SAME(1, RK_PD3, 2, 0x184, BIT(16 + 10)), /* uart2-rxm0 */
784fd4ea486SJagan Teki 	RK_MUXROUTE_SAME(2, RK_PB6, 2, 0x184, BIT(16 + 10) | BIT(10)), /* uart2-rxm1 */
785fd4ea486SJagan Teki 	RK_MUXROUTE_SAME(1, RK_PD2, 2, 0x184, BIT(16 + 10)), /* uart2-txm0 */
786fd4ea486SJagan Teki 	RK_MUXROUTE_SAME(2, RK_PB4, 2, 0x184, BIT(16 + 10) | BIT(10)), /* uart2-txm1 */
787fd4ea486SJagan Teki 	RK_MUXROUTE_SAME(0, RK_PC1, 2, 0x184, BIT(16 + 9)), /* uart3-rxm0 */
788fd4ea486SJagan Teki 	RK_MUXROUTE_SAME(1, RK_PB7, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-rxm1 */
789fd4ea486SJagan Teki 	RK_MUXROUTE_SAME(0, RK_PC0, 2, 0x184, BIT(16 + 9)), /* uart3-txm0 */
790fd4ea486SJagan Teki 	RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-txm1 */
791fd4ea486SJagan Teki 	RK_MUXROUTE_SAME(0, RK_PC2, 2, 0x184, BIT(16 + 9)), /* uart3-ctsm0 */
792fd4ea486SJagan Teki 	RK_MUXROUTE_SAME(1, RK_PB4, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-ctsm1 */
793fd4ea486SJagan Teki 	RK_MUXROUTE_SAME(0, RK_PC3, 2, 0x184, BIT(16 + 9)), /* uart3-rtsm0 */
794fd4ea486SJagan Teki 	RK_MUXROUTE_SAME(1, RK_PB5, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-rtsm1 */
795fd4ea486SJagan Teki };
796fd4ea486SJagan Teki 
797fd4ea486SJagan Teki static struct rockchip_mux_route_data rv1126_mux_route_data[] = {
798fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(3, RK_PD2, 1, 0x10260, WRITE_MASK_VAL(0, 0, 0)), /* I2S0_MCLK_M0 */
799fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(3, RK_PB0, 3, 0x10260, WRITE_MASK_VAL(0, 0, 1)), /* I2S0_MCLK_M1 */
800fd4ea486SJagan Teki 
801fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(0, RK_PD4, 4, 0x10260, WRITE_MASK_VAL(3, 2, 0)), /* I2S1_MCLK_M0 */
802fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(1, RK_PD5, 2, 0x10260, WRITE_MASK_VAL(3, 2, 1)), /* I2S1_MCLK_M1 */
803fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(2, RK_PC7, 6, 0x10260, WRITE_MASK_VAL(3, 2, 2)), /* I2S1_MCLK_M2 */
804fd4ea486SJagan Teki 
805fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(1, RK_PD0, 1, 0x10260, WRITE_MASK_VAL(4, 4, 0)), /* I2S2_MCLK_M0 */
806fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(2, RK_PB3, 2, 0x10260, WRITE_MASK_VAL(4, 4, 1)), /* I2S2_MCLK_M1 */
807fd4ea486SJagan Teki 
808fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(3, RK_PD4, 2, 0x10260, WRITE_MASK_VAL(12, 12, 0)), /* PDM_CLK0_M0 */
809fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(3, RK_PC0, 3, 0x10260, WRITE_MASK_VAL(12, 12, 1)), /* PDM_CLK0_M1 */
810fd4ea486SJagan Teki 
811fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(3, RK_PC6, 1, 0x10264, WRITE_MASK_VAL(0, 0, 0)), /* CIF_CLKOUT_M0 */
812fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(2, RK_PD1, 3, 0x10264, WRITE_MASK_VAL(0, 0, 1)), /* CIF_CLKOUT_M1 */
813fd4ea486SJagan Teki 
814fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(3, RK_PA4, 5, 0x10264, WRITE_MASK_VAL(5, 4, 0)), /* I2C3_SCL_M0 */
815fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(2, RK_PD4, 7, 0x10264, WRITE_MASK_VAL(5, 4, 1)), /* I2C3_SCL_M1 */
816fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(1, RK_PD6, 3, 0x10264, WRITE_MASK_VAL(5, 4, 2)), /* I2C3_SCL_M2 */
817fd4ea486SJagan Teki 
818fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(3, RK_PA0, 7, 0x10264, WRITE_MASK_VAL(6, 6, 0)), /* I2C4_SCL_M0 */
819fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(4, RK_PA0, 4, 0x10264, WRITE_MASK_VAL(6, 6, 1)), /* I2C4_SCL_M1 */
820fd4ea486SJagan Teki 
821fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(2, RK_PA5, 7, 0x10264, WRITE_MASK_VAL(9, 8, 0)), /* I2C5_SCL_M0 */
822fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(3, RK_PB0, 5, 0x10264, WRITE_MASK_VAL(9, 8, 1)), /* I2C5_SCL_M1 */
823fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(1, RK_PD0, 4, 0x10264, WRITE_MASK_VAL(9, 8, 2)), /* I2C5_SCL_M2 */
824fd4ea486SJagan Teki 
825fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(3, RK_PC0, 5, 0x10264, WRITE_MASK_VAL(11, 10, 0)), /* SPI1_CLK_M0 */
826fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(1, RK_PC6, 3, 0x10264, WRITE_MASK_VAL(11, 10, 1)), /* SPI1_CLK_M1 */
827fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(2, RK_PD5, 6, 0x10264, WRITE_MASK_VAL(11, 10, 2)), /* SPI1_CLK_M2 */
828fd4ea486SJagan Teki 
829fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(3, RK_PC0, 2, 0x10264, WRITE_MASK_VAL(12, 12, 0)), /* RGMII_CLK_M0 */
830fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(2, RK_PB7, 2, 0x10264, WRITE_MASK_VAL(12, 12, 1)), /* RGMII_CLK_M1 */
831fd4ea486SJagan Teki 
832fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(3, RK_PA1, 3, 0x10264, WRITE_MASK_VAL(13, 13, 0)), /* CAN_TXD_M0 */
833fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(3, RK_PA7, 5, 0x10264, WRITE_MASK_VAL(13, 13, 1)), /* CAN_TXD_M1 */
834fd4ea486SJagan Teki 
835fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(3, RK_PA4, 6, 0x10268, WRITE_MASK_VAL(0, 0, 0)), /* PWM8_M0 */
836fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(2, RK_PD7, 5, 0x10268, WRITE_MASK_VAL(0, 0, 1)), /* PWM8_M1 */
837fd4ea486SJagan Teki 
838fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(3, RK_PA5, 6, 0x10268, WRITE_MASK_VAL(2, 2, 0)), /* PWM9_M0 */
839fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(2, RK_PD6, 5, 0x10268, WRITE_MASK_VAL(2, 2, 1)), /* PWM9_M1 */
840fd4ea486SJagan Teki 
841fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(3, RK_PA6, 6, 0x10268, WRITE_MASK_VAL(4, 4, 0)), /* PWM10_M0 */
842fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(2, RK_PD5, 5, 0x10268, WRITE_MASK_VAL(4, 4, 1)), /* PWM10_M1 */
843fd4ea486SJagan Teki 
844fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(3, RK_PA7, 6, 0x10268, WRITE_MASK_VAL(6, 6, 0)), /* PWM11_IR_M0 */
845fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(3, RK_PA1, 5, 0x10268, WRITE_MASK_VAL(6, 6, 1)), /* PWM11_IR_M1 */
846fd4ea486SJagan Teki 
847fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(1, RK_PA5, 3, 0x10268, WRITE_MASK_VAL(8, 8, 0)), /* UART2_TX_M0 */
848fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(3, RK_PA2, 1, 0x10268, WRITE_MASK_VAL(8, 8, 1)), /* UART2_TX_M1 */
849fd4ea486SJagan Teki 
850fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(3, RK_PC6, 3, 0x10268, WRITE_MASK_VAL(11, 10, 0)), /* UART3_TX_M0 */
851fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(1, RK_PA7, 2, 0x10268, WRITE_MASK_VAL(11, 10, 1)), /* UART3_TX_M1 */
852fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(3, RK_PA0, 4, 0x10268, WRITE_MASK_VAL(11, 10, 2)), /* UART3_TX_M2 */
853fd4ea486SJagan Teki 
854fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(3, RK_PA4, 4, 0x10268, WRITE_MASK_VAL(13, 12, 0)), /* UART4_TX_M0 */
855fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(2, RK_PA6, 4, 0x10268, WRITE_MASK_VAL(13, 12, 1)), /* UART4_TX_M1 */
856fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(1, RK_PD5, 3, 0x10268, WRITE_MASK_VAL(13, 12, 2)), /* UART4_TX_M2 */
857fd4ea486SJagan Teki 
858fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(3, RK_PA6, 4, 0x10268, WRITE_MASK_VAL(15, 14, 0)), /* UART5_TX_M0 */
859fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(2, RK_PB0, 4, 0x10268, WRITE_MASK_VAL(15, 14, 1)), /* UART5_TX_M1 */
860fd4ea486SJagan Teki 	RK_MUXROUTE_GRF(2, RK_PA0, 3, 0x10268, WRITE_MASK_VAL(15, 14, 2)), /* UART5_TX_M2 */
861fd4ea486SJagan Teki 
862fd4ea486SJagan Teki 	RK_MUXROUTE_PMU(0, RK_PB6, 3, 0x0114, WRITE_MASK_VAL(0, 0, 0)), /* PWM0_M0 */
863fd4ea486SJagan Teki 	RK_MUXROUTE_PMU(2, RK_PB3, 5, 0x0114, WRITE_MASK_VAL(0, 0, 1)), /* PWM0_M1 */
864fd4ea486SJagan Teki 
865fd4ea486SJagan Teki 	RK_MUXROUTE_PMU(0, RK_PB7, 3, 0x0114, WRITE_MASK_VAL(2, 2, 0)), /* PWM1_M0 */
866fd4ea486SJagan Teki 	RK_MUXROUTE_PMU(2, RK_PB2, 5, 0x0114, WRITE_MASK_VAL(2, 2, 1)), /* PWM1_M1 */
867fd4ea486SJagan Teki 
868fd4ea486SJagan Teki 	RK_MUXROUTE_PMU(0, RK_PC0, 3, 0x0114, WRITE_MASK_VAL(4, 4, 0)), /* PWM2_M0 */
869fd4ea486SJagan Teki 	RK_MUXROUTE_PMU(2, RK_PB1, 5, 0x0114, WRITE_MASK_VAL(4, 4, 1)), /* PWM2_M1 */
870fd4ea486SJagan Teki 
871fd4ea486SJagan Teki 	RK_MUXROUTE_PMU(0, RK_PC1, 3, 0x0114, WRITE_MASK_VAL(6, 6, 0)), /* PWM3_IR_M0 */
872fd4ea486SJagan Teki 	RK_MUXROUTE_PMU(2, RK_PB0, 5, 0x0114, WRITE_MASK_VAL(6, 6, 1)), /* PWM3_IR_M1 */
873d23c66dfSDavid Wu 
874fe202ea8SJianqun Xu 	RK_MUXROUTE_PMU(0, RK_PC2, 3, 0x0114, WRITE_MASK_VAL(8, 8, 0)), /* PWM4_M0 */
875fe202ea8SJianqun Xu 	RK_MUXROUTE_PMU(2, RK_PA7, 5, 0x0114, WRITE_MASK_VAL(8, 8, 1)), /* PWM4_M1 */
876fe202ea8SJianqun Xu 
877fe202ea8SJianqun Xu 	RK_MUXROUTE_PMU(0, RK_PC3, 3, 0x0114, WRITE_MASK_VAL(10, 10, 0)), /* PWM5_M0 */
878fe202ea8SJianqun Xu 	RK_MUXROUTE_PMU(2, RK_PA6, 5, 0x0114, WRITE_MASK_VAL(10, 10, 1)), /* PWM5_M1 */
879fe202ea8SJianqun Xu 
880fe202ea8SJianqun Xu 	RK_MUXROUTE_PMU(0, RK_PB2, 3, 0x0114, WRITE_MASK_VAL(12, 12, 0)), /* PWM6_M0 */
881d23c66dfSDavid Wu 	RK_MUXROUTE_PMU(2, RK_PD4, 5, 0x0114, WRITE_MASK_VAL(12, 12, 1)), /* PWM6_M1 */
882d23c66dfSDavid Wu 
883ada62b7cSHeiko Stuebner 	RK_MUXROUTE_PMU(0, RK_PB1, 3, 0x0114, WRITE_MASK_VAL(14, 14, 0)), /* PWM7_IR_M0 */
884fe202ea8SJianqun Xu 	RK_MUXROUTE_PMU(3, RK_PA0, 5, 0x0114, WRITE_MASK_VAL(14, 14, 1)), /* PWM7_IR_M1 */
885fe202ea8SJianqun Xu 
886ada62b7cSHeiko Stuebner 	RK_MUXROUTE_PMU(0, RK_PB0, 1, 0x0118, WRITE_MASK_VAL(1, 0, 0)), /* SPI0_CLK_M0 */
887ada62b7cSHeiko Stuebner 	RK_MUXROUTE_PMU(2, RK_PA1, 1, 0x0118, WRITE_MASK_VAL(1, 0, 1)), /* SPI0_CLK_M1 */
888d4970ee0SDavid Wu 	RK_MUXROUTE_PMU(2, RK_PB2, 6, 0x0118, WRITE_MASK_VAL(1, 0, 2)), /* SPI0_CLK_M2 */
889fe202ea8SJianqun Xu 
890fe202ea8SJianqun Xu 	RK_MUXROUTE_PMU(0, RK_PB6, 2, 0x0118, WRITE_MASK_VAL(2, 2, 0)), /* UART1_TX_M0 */
891fe202ea8SJianqun Xu 	RK_MUXROUTE_PMU(1, RK_PD0, 5, 0x0118, WRITE_MASK_VAL(2, 2, 1)), /* UART1_TX_M1 */
892fe202ea8SJianqun Xu };
893fe202ea8SJianqun Xu 
894fe202ea8SJianqun Xu static struct rockchip_mux_route_data rk3128_mux_route_data[] = {
895fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(1, RK_PB2, 1, 0x144, BIT(16 + 3) | BIT(16 + 4)), /* spi-0 */
896fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(1, RK_PD3, 3, 0x144, BIT(16 + 3) | BIT(16 + 4) | BIT(3)), /* spi-1 */
897fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(0, RK_PB5, 2, 0x144, BIT(16 + 3) | BIT(16 + 4) | BIT(4)), /* spi-2 */
898fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(1, RK_PA5, 1, 0x144, BIT(16 + 5)), /* i2s-0 */
899fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(0, RK_PB6, 1, 0x144, BIT(16 + 5) | BIT(5)), /* i2s-1 */
900fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x144, BIT(16 + 6)), /* emmc-0 */
901fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x144, BIT(16 + 6) | BIT(6)), /* emmc-1 */
902fe202ea8SJianqun Xu };
903fe202ea8SJianqun Xu 
904fe202ea8SJianqun Xu static struct rockchip_mux_route_data rk3188_mux_route_data[] = {
905fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(0, RK_PD0, 1, 0xa0, BIT(16 + 11)), /* non-iomuxed emmc/flash pins on flash-dqs */
906fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(0, RK_PD0, 2, 0xa0, BIT(16 + 11) | BIT(11)), /* non-iomuxed emmc/flash pins on emmc-clk */
907d4970ee0SDavid Wu };
908d4970ee0SDavid Wu 
9094e96fd30SHeiko Stuebner static struct rockchip_mux_route_data rk3228_mux_route_data[] = {
910fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(0, RK_PD2, 1, 0x50, BIT(16)), /* pwm0-0 */
911fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(3, RK_PC5, 1, 0x50, BIT(16) | BIT(0)), /* pwm0-1 */
9124e96fd30SHeiko Stuebner 	RK_MUXROUTE_SAME(0, RK_PD3, 1, 0x50, BIT(16 + 1)), /* pwm1-0 */
9134e96fd30SHeiko Stuebner 	RK_MUXROUTE_SAME(0, RK_PD6, 2, 0x50, BIT(16 + 1) | BIT(1)), /* pwm1-1 */
9147825aeb7SJianqun Xu 	RK_MUXROUTE_SAME(0, RK_PD4, 1, 0x50, BIT(16 + 2)), /* pwm2-0 */
915fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(1, RK_PB4, 2, 0x50, BIT(16 + 2) | BIT(2)), /* pwm2-1 */
916fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(3, RK_PD2, 1, 0x50, BIT(16 + 3)), /* pwm3-0 */
917fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(1, RK_PB3, 2, 0x50, BIT(16 + 3) | BIT(3)), /* pwm3-1 */
918a8f25485SDmitry Yashin 	RK_MUXROUTE_SAME(1, RK_PA1, 1, 0x50, BIT(16 + 4)), /* sdio-0_d0 */
919a8f25485SDmitry Yashin 	RK_MUXROUTE_SAME(3, RK_PA2, 1, 0x50, BIT(16 + 4) | BIT(4)), /* sdio-1_d0 */
920fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(0, RK_PB5, 2, 0x50, BIT(16 + 5)), /* spi-0_rx */
921fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(2, RK_PA0, 2, 0x50, BIT(16 + 5) | BIT(5)), /* spi-1_rx */
922fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x50, BIT(16 + 7)), /* emmc-0_cmd */
923fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x50, BIT(16 + 7) | BIT(7)), /* emmc-1_cmd */
924fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(1, RK_PC3, 2, 0x50, BIT(16 + 8)), /* uart2-0_rx */
925fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(1, RK_PB2, 2, 0x50, BIT(16 + 8) | BIT(8)), /* uart2-1_rx */
926fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(1, RK_PB2, 1, 0x50, BIT(16 + 11)), /* uart1-0_rx */
927fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(3, RK_PB5, 1, 0x50, BIT(16 + 11) | BIT(11)), /* uart1-1_rx */
9287825aeb7SJianqun Xu };
9297825aeb7SJianqun Xu 
930cedc964aSDavid Wu static struct rockchip_mux_route_data rk3288_mux_route_data[] = {
931fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(7, RK_PC0, 2, 0x264, BIT(16 + 12) | BIT(12)), /* edphdmi_cecinoutt1 */
932fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(7, RK_PC7, 4, 0x264, BIT(16 + 12)), /* edphdmi_cecinout */
933fe202ea8SJianqun Xu };
934fe202ea8SJianqun Xu 
935fe202ea8SJianqun Xu static struct rockchip_mux_route_data rk3308_mux_route_data[] = {
936fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(0, RK_PC3, 1, 0x314, BIT(16 + 0) | BIT(0)), /* rtc_clk */
937fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x314, BIT(16 + 2) | BIT(16 + 3)), /* uart2_rxm0 */
938fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(4, RK_PD2, 2, 0x314, BIT(16 + 2) | BIT(16 + 3) | BIT(2)), /* uart2_rxm1 */
939fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(0, RK_PB7, 2, 0x314, BIT(16 + 4)), /* i2c3_sdam0 */
940fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(3, RK_PB4, 2, 0x314, BIT(16 + 4) | BIT(4)), /* i2c3_sdam1 */
941fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(1, RK_PA3, 2, 0x308, BIT(16 + 3)), /* i2s-8ch-1-sclktxm0 */
942fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(1, RK_PA4, 2, 0x308, BIT(16 + 3)), /* i2s-8ch-1-sclkrxm0 */
943cedc964aSDavid Wu 	RK_MUXROUTE_SAME(1, RK_PB5, 2, 0x308, BIT(16 + 3) | BIT(3)), /* i2s-8ch-1-sclktxm1 */
944cedc964aSDavid Wu 	RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x308, BIT(16 + 3) | BIT(3)), /* i2s-8ch-1-sclkrxm1 */
945accc1ce7SDavid Wu 	RK_MUXROUTE_SAME(1, RK_PA4, 3, 0x308, BIT(16 + 12) | BIT(16 + 13)), /* pdm-clkm0 */
946fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(1, RK_PB6, 4, 0x308, BIT(16 + 12) | BIT(16 + 13) | BIT(12)), /* pdm-clkm1 */
947fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(2, RK_PA6, 2, 0x308, BIT(16 + 12) | BIT(16 + 13) | BIT(13)), /* pdm-clkm2 */
948fe202ea8SJianqun Xu 	RK_MUXROUTE_SAME(2, RK_PA4, 3, 0x600, BIT(16 + 2) | BIT(2)), /* pdm-clkm-m2 */
949fe202ea8SJianqun Xu };
950fe202ea8SJianqun Xu 
951accc1ce7SDavid Wu static struct rockchip_mux_route_data rk3328_mux_route_data[] = {
952accc1ce7SDavid Wu 	RK_MUXROUTE_SAME(1, RK_PA1, 2, 0x50, BIT(16) | BIT(16 + 1)), /* uart2dbg_rxm0 */
953c0dadc0eSJianqun Xu 	RK_MUXROUTE_SAME(2, RK_PA1, 1, 0x50, BIT(16) | BIT(16 + 1) | BIT(0)), /* uart2dbg_rxm1 */
954c0dadc0eSJianqun Xu 	RK_MUXROUTE_SAME(1, RK_PB3, 2, 0x50, BIT(16 + 2) | BIT(2)), /* gmac-m1_rxd0 */
955c0dadc0eSJianqun Xu 	RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x50, BIT(16 + 10) | BIT(10)), /* gmac-m1-optimized_rxd3 */
956c0dadc0eSJianqun Xu 	RK_MUXROUTE_SAME(2, RK_PC3, 2, 0x50, BIT(16 + 3)), /* pdm_sdi0m0 */
957c0dadc0eSJianqun Xu 	RK_MUXROUTE_SAME(1, RK_PC7, 3, 0x50, BIT(16 + 3) | BIT(3)), /* pdm_sdi0m1 */
958c0dadc0eSJianqun Xu 	RK_MUXROUTE_SAME(3, RK_PA2, 4, 0x50, BIT(16 + 4) | BIT(16 + 5) | BIT(5)), /* spi_rxdm2 */
959c0dadc0eSJianqun Xu 	RK_MUXROUTE_SAME(1, RK_PD0, 1, 0x50, BIT(16 + 6)), /* i2s2_sdim0 */
960431d1531SJonas Karlman 	RK_MUXROUTE_SAME(3, RK_PA2, 6, 0x50, BIT(16 + 6) | BIT(6)), /* i2s2_sdim1 */
961c0dadc0eSJianqun Xu 	RK_MUXROUTE_SAME(2, RK_PC6, 3, 0x50, BIT(16 + 7) | BIT(7)), /* card_iom1 */
962c0dadc0eSJianqun Xu 	RK_MUXROUTE_SAME(2, RK_PC0, 3, 0x50, BIT(16 + 8) | BIT(8)), /* tsp_d5m1 */
963c0dadc0eSJianqun Xu 	RK_MUXROUTE_SAME(2, RK_PC0, 4, 0x50, BIT(16 + 9) | BIT(9)), /* cif_data5m1 */
964c0dadc0eSJianqun Xu };
965c0dadc0eSJianqun Xu 
966c0dadc0eSJianqun Xu static struct rockchip_mux_route_data rk3399_mux_route_data[] = {
967431d1531SJonas Karlman 	RK_MUXROUTE_SAME(4, RK_PB0, 2, 0xe21c, BIT(16 + 10) | BIT(16 + 11)), /* uart2dbga_rx */
968c0dadc0eSJianqun Xu 	RK_MUXROUTE_SAME(4, RK_PC0, 2, 0xe21c, BIT(16 + 10) | BIT(16 + 11) | BIT(10)), /* uart2dbgb_rx */
969c0dadc0eSJianqun Xu 	RK_MUXROUTE_SAME(4, RK_PC3, 1, 0xe21c, BIT(16 + 10) | BIT(16 + 11) | BIT(11)), /* uart2dbgc_rx */
970c0dadc0eSJianqun Xu 	RK_MUXROUTE_SAME(2, RK_PD2, 2, 0xe21c, BIT(16 + 14)), /* pcie_clkreqn */
971431d1531SJonas Karlman 	RK_MUXROUTE_SAME(4, RK_PD0, 1, 0xe21c, BIT(16 + 14) | BIT(14)), /* pcie_clkreqnb */
972431d1531SJonas Karlman };
973c0dadc0eSJianqun Xu 
974c0dadc0eSJianqun Xu static struct rockchip_mux_route_data rk3568_mux_route_data[] = {
975c0dadc0eSJianqun Xu 	RK_MUXROUTE_PMU(0, RK_PB7, 1, 0x0110, WRITE_MASK_VAL(1, 0, 0)), /* PWM0 IO mux M0 */
976c0dadc0eSJianqun Xu 	RK_MUXROUTE_PMU(0, RK_PC7, 2, 0x0110, WRITE_MASK_VAL(1, 0, 1)), /* PWM0 IO mux M1 */
977c0dadc0eSJianqun Xu 	RK_MUXROUTE_PMU(0, RK_PC0, 1, 0x0110, WRITE_MASK_VAL(3, 2, 0)), /* PWM1 IO mux M0 */
978c0dadc0eSJianqun Xu 	RK_MUXROUTE_PMU(0, RK_PB5, 4, 0x0110, WRITE_MASK_VAL(3, 2, 1)), /* PWM1 IO mux M1 */
979c0dadc0eSJianqun Xu 	RK_MUXROUTE_PMU(0, RK_PC1, 1, 0x0110, WRITE_MASK_VAL(5, 4, 0)), /* PWM2 IO mux M0 */
980c0dadc0eSJianqun Xu 	RK_MUXROUTE_PMU(0, RK_PB6, 4, 0x0110, WRITE_MASK_VAL(5, 4, 1)), /* PWM2 IO mux M1 */
981c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(0, RK_PB3, 2, 0x0300, WRITE_MASK_VAL(0, 0, 0)), /* CAN0 IO mux M0 */
982c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(2, RK_PA1, 4, 0x0300, WRITE_MASK_VAL(0, 0, 1)), /* CAN0 IO mux M1 */
983c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(1, RK_PA1, 3, 0x0300, WRITE_MASK_VAL(2, 2, 0)), /* CAN1 IO mux M0 */
984c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(4, RK_PC3, 3, 0x0300, WRITE_MASK_VAL(2, 2, 1)), /* CAN1 IO mux M1 */
985c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(4, RK_PB5, 3, 0x0300, WRITE_MASK_VAL(4, 4, 0)), /* CAN2 IO mux M0 */
986c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(2, RK_PB2, 4, 0x0300, WRITE_MASK_VAL(4, 4, 1)), /* CAN2 IO mux M1 */
987c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(4, RK_PC4, 1, 0x0300, WRITE_MASK_VAL(6, 6, 0)), /* HPDIN IO mux M0 */
988c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(0, RK_PC2, 2, 0x0300, WRITE_MASK_VAL(6, 6, 1)), /* HPDIN IO mux M1 */
989c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(3, RK_PB1, 3, 0x0300, WRITE_MASK_VAL(8, 8, 0)), /* GMAC1 IO mux M0 */
990c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(4, RK_PA7, 3, 0x0300, WRITE_MASK_VAL(8, 8, 1)), /* GMAC1 IO mux M1 */
991c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(4, RK_PD1, 1, 0x0300, WRITE_MASK_VAL(10, 10, 0)), /* HDMITX IO mux M0 */
992c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(0, RK_PC7, 1, 0x0300, WRITE_MASK_VAL(10, 10, 1)), /* HDMITX IO mux M1 */
993c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(0, RK_PB6, 1, 0x0300, WRITE_MASK_VAL(14, 14, 0)), /* I2C2 IO mux M0 */
994c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(4, RK_PB4, 1, 0x0300, WRITE_MASK_VAL(14, 14, 1)), /* I2C2 IO mux M1 */
995c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(1, RK_PA0, 1, 0x0304, WRITE_MASK_VAL(0, 0, 0)), /* I2C3 IO mux M0 */
996c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(3, RK_PB6, 4, 0x0304, WRITE_MASK_VAL(0, 0, 1)), /* I2C3 IO mux M1 */
997c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(4, RK_PB2, 1, 0x0304, WRITE_MASK_VAL(2, 2, 0)), /* I2C4 IO mux M0 */
998431d1531SJonas Karlman 	RK_MUXROUTE_GRF(2, RK_PB1, 2, 0x0304, WRITE_MASK_VAL(2, 2, 1)), /* I2C4 IO mux M1 */
999c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(3, RK_PB4, 4, 0x0304, WRITE_MASK_VAL(4, 4, 0)), /* I2C5 IO mux M0 */
1000c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(4, RK_PD0, 2, 0x0304, WRITE_MASK_VAL(4, 4, 1)), /* I2C5 IO mux M1 */
1001c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(3, RK_PB1, 5, 0x0304, WRITE_MASK_VAL(14, 14, 0)), /* PWM8 IO mux M0 */
1002c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(1, RK_PD5, 4, 0x0304, WRITE_MASK_VAL(14, 14, 1)), /* PWM8 IO mux M1 */
1003c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(3, RK_PB2, 5, 0x0308, WRITE_MASK_VAL(0, 0, 0)), /* PWM9 IO mux M0 */
1004c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(1, RK_PD6, 4, 0x0308, WRITE_MASK_VAL(0, 0, 1)), /* PWM9 IO mux M1 */
1005c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(3, RK_PB5, 5, 0x0308, WRITE_MASK_VAL(2, 2, 0)), /* PWM10 IO mux M0 */
1006c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(2, RK_PA1, 2, 0x0308, WRITE_MASK_VAL(2, 2, 1)), /* PWM10 IO mux M1 */
1007431d1531SJonas Karlman 	RK_MUXROUTE_GRF(3, RK_PB6, 5, 0x0308, WRITE_MASK_VAL(4, 4, 0)), /* PWM11 IO mux M0 */
1008431d1531SJonas Karlman 	RK_MUXROUTE_GRF(4, RK_PC0, 3, 0x0308, WRITE_MASK_VAL(4, 4, 1)), /* PWM11 IO mux M1 */
1009c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(3, RK_PB7, 2, 0x0308, WRITE_MASK_VAL(6, 6, 0)), /* PWM12 IO mux M0 */
1010c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(4, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(6, 6, 1)), /* PWM12 IO mux M1 */
1011c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(3, RK_PC0, 2, 0x0308, WRITE_MASK_VAL(8, 8, 0)), /* PWM13 IO mux M0 */
1012c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(4, RK_PC6, 1, 0x0308, WRITE_MASK_VAL(8, 8, 1)), /* PWM13 IO mux M1 */
1013c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(3, RK_PC4, 1, 0x0308, WRITE_MASK_VAL(10, 10, 0)), /* PWM14 IO mux M0 */
1014c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(4, RK_PC2, 1, 0x0308, WRITE_MASK_VAL(10, 10, 1)), /* PWM14 IO mux M1 */
1015c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(3, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(12, 12, 0)), /* PWM15 IO mux M0 */
1016c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(4, RK_PC3, 1, 0x0308, WRITE_MASK_VAL(12, 12, 1)), /* PWM15 IO mux M1 */
1017c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(3, RK_PD2, 3, 0x0308, WRITE_MASK_VAL(14, 14, 0)), /* SDMMC2 IO mux M0 */
1018c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(3, RK_PA5, 5, 0x0308, WRITE_MASK_VAL(14, 14, 1)), /* SDMMC2 IO mux M1 */
1019c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(0, RK_PB5, 2, 0x030c, WRITE_MASK_VAL(0, 0, 0)), /* SPI0 IO mux M0 */
1020c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(2, RK_PD3, 3, 0x030c, WRITE_MASK_VAL(0, 0, 1)), /* SPI0 IO mux M1 */
1021c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(2, RK_PB5, 3, 0x030c, WRITE_MASK_VAL(2, 2, 0)), /* SPI1 IO mux M0 */
1022c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(3, RK_PC3, 3, 0x030c, WRITE_MASK_VAL(2, 2, 1)), /* SPI1 IO mux M1 */
1023c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(2, RK_PC1, 4, 0x030c, WRITE_MASK_VAL(4, 4, 0)), /* SPI2 IO mux M0 */
1024c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(3, RK_PA0, 3, 0x030c, WRITE_MASK_VAL(4, 4, 1)), /* SPI2 IO mux M1 */
1025c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(4, RK_PB3, 4, 0x030c, WRITE_MASK_VAL(6, 6, 0)), /* SPI3 IO mux M0 */
1026c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(4, RK_PC2, 2, 0x030c, WRITE_MASK_VAL(6, 6, 1)), /* SPI3 IO mux M1 */
1027c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(2, RK_PB4, 2, 0x030c, WRITE_MASK_VAL(8, 8, 0)), /* UART1 IO mux M0 */
1028c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(3, RK_PD6, 4, 0x030c, WRITE_MASK_VAL(8, 8, 1)), /* UART1 IO mux M1 */
1029c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(10, 10, 0)), /* UART2 IO mux M0 */
1030c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(1, RK_PD5, 2, 0x030c, WRITE_MASK_VAL(10, 10, 1)), /* UART2 IO mux M1 */
1031c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(1, RK_PA1, 2, 0x030c, WRITE_MASK_VAL(12, 12, 0)), /* UART3 IO mux M0 */
1032c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(3, RK_PB7, 4, 0x030c, WRITE_MASK_VAL(12, 12, 1)), /* UART3 IO mux M1 */
1033c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(1, RK_PA6, 2, 0x030c, WRITE_MASK_VAL(14, 14, 0)), /* UART4 IO mux M0 */
1034c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(3, RK_PB2, 4, 0x030c, WRITE_MASK_VAL(14, 14, 1)), /* UART4 IO mux M1 */
1035c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(2, RK_PA2, 3, 0x0310, WRITE_MASK_VAL(0, 0, 0)), /* UART5 IO mux M0 */
1036c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(3, RK_PC2, 4, 0x0310, WRITE_MASK_VAL(0, 0, 1)), /* UART5 IO mux M1 */
1037c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(2, RK_PA4, 3, 0x0310, WRITE_MASK_VAL(2, 2, 0)), /* UART6 IO mux M0 */
1038431d1531SJonas Karlman 	RK_MUXROUTE_GRF(1, RK_PD5, 3, 0x0310, WRITE_MASK_VAL(2, 2, 1)), /* UART6 IO mux M1 */
1039c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(2, RK_PA6, 3, 0x0310, WRITE_MASK_VAL(5, 4, 0)), /* UART7 IO mux M0 */
1040c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(3, RK_PC4, 4, 0x0310, WRITE_MASK_VAL(5, 4, 1)), /* UART7 IO mux M1 */
1041431d1531SJonas Karlman 	RK_MUXROUTE_GRF(4, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(5, 4, 2)), /* UART7 IO mux M2 */
1042c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(2, RK_PC5, 3, 0x0310, WRITE_MASK_VAL(6, 6, 0)), /* UART8 IO mux M0 */
1043c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(2, RK_PD7, 4, 0x0310, WRITE_MASK_VAL(6, 6, 1)), /* UART8 IO mux M1 */
1044431d1531SJonas Karlman 	RK_MUXROUTE_GRF(2, RK_PB0, 3, 0x0310, WRITE_MASK_VAL(9, 8, 0)), /* UART9 IO mux M0 */
1045c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(4, RK_PC5, 4, 0x0310, WRITE_MASK_VAL(9, 8, 1)), /* UART9 IO mux M1 */
1046c0dadc0eSJianqun Xu 	RK_MUXROUTE_GRF(4, RK_PA4, 4, 0x0310, WRITE_MASK_VAL(9, 8, 2)), /* UART9 IO mux M2 */
1047d3e51161SHeiko Stübner 	RK_MUXROUTE_GRF(1, RK_PA2, 1, 0x0310, WRITE_MASK_VAL(11, 10, 0)), /* I2S1 IO mux M0 */
1048d3e51161SHeiko Stübner 	RK_MUXROUTE_GRF(3, RK_PC6, 4, 0x0310, WRITE_MASK_VAL(11, 10, 1)), /* I2S1 IO mux M1 */
1049bd35b9bfSDavid Wu 	RK_MUXROUTE_GRF(2, RK_PD0, 5, 0x0310, WRITE_MASK_VAL(11, 10, 2)), /* I2S1 IO mux M2 */
105051ff47aaSHeiko Stuebner 	RK_MUXROUTE_GRF(2, RK_PC1, 1, 0x0310, WRITE_MASK_VAL(12, 12, 0)), /* I2S2 IO mux M0 */
1051bd35b9bfSDavid Wu 	RK_MUXROUTE_GRF(4, RK_PB6, 5, 0x0310, WRITE_MASK_VAL(12, 12, 1)), /* I2S2 IO mux M1 */
1052bd35b9bfSDavid Wu 	RK_MUXROUTE_GRF(3, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(14, 14, 0)), /* I2S3 IO mux M0 */
1053bd35b9bfSDavid Wu 	RK_MUXROUTE_GRF(4, RK_PC2, 5, 0x0310, WRITE_MASK_VAL(14, 14, 1)), /* I2S3 IO mux M1 */
1054bd35b9bfSDavid Wu 	RK_MUXROUTE_GRF(1, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO mux M0 */
1055bd35b9bfSDavid Wu 	RK_MUXROUTE_GRF(1, RK_PA6, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO mux M0 */
1056bd35b9bfSDavid Wu 	RK_MUXROUTE_GRF(3, RK_PD6, 5, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */
1057bd35b9bfSDavid Wu 	RK_MUXROUTE_GRF(4, RK_PA0, 4, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */
1058bd35b9bfSDavid Wu 	RK_MUXROUTE_GRF(3, RK_PC4, 5, 0x0314, WRITE_MASK_VAL(1, 0, 2)), /* PDM IO mux M2 */
1059bd35b9bfSDavid Wu 	RK_MUXROUTE_GRF(0, RK_PA5, 3, 0x0314, WRITE_MASK_VAL(3, 2, 0)), /* PCIE20 IO mux M0 */
1060bd35b9bfSDavid Wu 	RK_MUXROUTE_GRF(2, RK_PD0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 1)), /* PCIE20 IO mux M1 */
1061bd35b9bfSDavid Wu 	RK_MUXROUTE_GRF(1, RK_PB0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 2)), /* PCIE20 IO mux M2 */
1062bd35b9bfSDavid Wu 	RK_MUXROUTE_GRF(0, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(5, 4, 0)), /* PCIE30X1 IO mux M0 */
1063bd35b9bfSDavid Wu 	RK_MUXROUTE_GRF(2, RK_PD2, 4, 0x0314, WRITE_MASK_VAL(5, 4, 1)), /* PCIE30X1 IO mux M1 */
1064bd35b9bfSDavid Wu 	RK_MUXROUTE_GRF(1, RK_PA5, 4, 0x0314, WRITE_MASK_VAL(5, 4, 2)), /* PCIE30X1 IO mux M2 */
1065bd35b9bfSDavid Wu 	RK_MUXROUTE_GRF(0, RK_PA6, 2, 0x0314, WRITE_MASK_VAL(7, 6, 0)), /* PCIE30X2 IO mux M0 */
1066bd35b9bfSDavid Wu 	RK_MUXROUTE_GRF(2, RK_PD4, 4, 0x0314, WRITE_MASK_VAL(7, 6, 1)), /* PCIE30X2 IO mux M1 */
106751ff47aaSHeiko Stuebner 	RK_MUXROUTE_GRF(4, RK_PC2, 4, 0x0314, WRITE_MASK_VAL(7, 6, 2)), /* PCIE30X2 IO mux M2 */
1068bd35b9bfSDavid Wu };
1069bd35b9bfSDavid Wu 
rockchip_get_mux_route(struct rockchip_pin_bank * bank,int pin,int mux,u32 * loc,u32 * reg,u32 * value)1070bd35b9bfSDavid Wu static bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin,
1071bd35b9bfSDavid Wu 				   int mux, u32 *loc, u32 *reg, u32 *value)
1072bd35b9bfSDavid Wu {
1073bd35b9bfSDavid Wu 	struct rockchip_pinctrl *info = bank->drvdata;
1074a076e2edSHeiko Stübner 	struct rockchip_pin_ctrl *ctrl = info->ctrl;
1075a076e2edSHeiko Stübner 	struct rockchip_mux_route_data *data;
1076a076e2edSHeiko Stübner 	int i;
1077fdc33ebaSJianqun Xu 
1078fc72c923SHeiko Stübner 	for (i = 0; i < ctrl->niomux_routes; i++) {
107995ec8ae4SHeiko Stübner 		data = &ctrl->iomux_routes[i];
1080751a99abSHeiko Stübner 		if ((data->bank_num == bank->bank_num) &&
1081ea262ad6Sdavid.wu 		    (data->pin == pin) && (data->func == mux))
1082a076e2edSHeiko Stübner 			break;
1083a076e2edSHeiko Stübner 	}
1084fc72c923SHeiko Stübner 
1085fc72c923SHeiko Stübner 	if (i >= ctrl->niomux_routes)
1086fc72c923SHeiko Stübner 		return false;
108762f49226SHeiko Stübner 
108862f49226SHeiko Stübner 	*loc = data->route_location;
108962f49226SHeiko Stübner 	*reg = data->route_offset;
109062f49226SHeiko Stübner 	*value = data->route_val;
109162f49226SHeiko Stübner 
1092fc72c923SHeiko Stübner 	return true;
1093a076e2edSHeiko Stübner }
1094a076e2edSHeiko Stübner 
rockchip_get_mux(struct rockchip_pin_bank * bank,int pin)1095fd4ea486SJagan Teki static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
1096fd4ea486SJagan Teki {
1097fd4ea486SJagan Teki 	struct rockchip_pinctrl *info = bank->drvdata;
1098fd4ea486SJagan Teki 	struct rockchip_pin_ctrl *ctrl = info->ctrl;
1099fd4ea486SJagan Teki 	int iomux_num = (pin / 8);
1100fd4ea486SJagan Teki 	struct regmap *regmap;
110195ec8ae4SHeiko Stübner 	unsigned int val;
1102a076e2edSHeiko Stübner 	int reg, ret, mask, mux_type;
1103ea262ad6Sdavid.wu 	u8 bit;
11046bc0d121SHeiko Stübner 
1105ea262ad6Sdavid.wu 	if (iomux_num > 3)
110603716e1dSHeiko Stübner 		return -EINVAL;
110703716e1dSHeiko Stübner 
110803716e1dSHeiko Stübner 	if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) {
11098b6c6f93Sdavid.wu 		dev_err(info->dev, "pin %d is unrouted\n", pin);
1110ea262ad6Sdavid.wu 		return -EINVAL;
11118b6c6f93Sdavid.wu 	}
11128b6c6f93Sdavid.wu 
11138b6c6f93Sdavid.wu 	if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY)
11148b6c6f93Sdavid.wu 		return RK_FUNC_GPIO;
111503716e1dSHeiko Stübner 
1116a076e2edSHeiko Stübner 	if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
11178b6c6f93Sdavid.wu 		regmap = info->regmap_pmu;
111803716e1dSHeiko Stübner 	else if (bank->iomux[iomux_num].type & IOMUX_L_SOURCE_PMU)
1119a076e2edSHeiko Stübner 		regmap = (pin % 8 < 4) ? info->regmap_pmu : info->regmap_base;
1120c04c3fa6SDavid Wu 	else
1121c04c3fa6SDavid Wu 		regmap = info->regmap_base;
1122ea262ad6Sdavid.wu 
1123fdc33ebaSJianqun Xu 	/* get basic quadrupel of mux registers and the correct reg inside */
1124fdc33ebaSJianqun Xu 	mux_type = bank->iomux[iomux_num].type;
1125fdc33ebaSJianqun Xu 	reg = bank->iomux[iomux_num].offset;
1126fdc33ebaSJianqun Xu 	if (mux_type & IOMUX_WIDTH_4BIT) {
1127fdc33ebaSJianqun Xu 		if ((pin % 8) >= 4)
1128fdc33ebaSJianqun Xu 			reg += 0x4;
1129fdc33ebaSJianqun Xu 		bit = (pin % 4) * 4;
1130fdc33ebaSJianqun Xu 		mask = 0xf;
1131fdc33ebaSJianqun Xu 	} else if (mux_type & IOMUX_WIDTH_3BIT) {
1132fdc33ebaSJianqun Xu 		if ((pin % 8) >= 5)
1133fdc33ebaSJianqun Xu 			reg += 0x4;
1134fdc33ebaSJianqun Xu 		bit = (pin % 8 % 5) * 3;
1135fdc33ebaSJianqun Xu 		mask = 0x7;
1136fdc33ebaSJianqun Xu 	} else {
1137fdc33ebaSJianqun Xu 		bit = (pin % 8) * 2;
1138fdc33ebaSJianqun Xu 		mask = 0x3;
1139fdc33ebaSJianqun Xu 	}
1140fdc33ebaSJianqun Xu 
1141fdc33ebaSJianqun Xu 	if (bank->recalced_mask & BIT(pin))
1142fdc33ebaSJianqun Xu 		rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
1143fdc33ebaSJianqun Xu 
114495ec8ae4SHeiko Stübner 	if (ctrl->type == RK3576) {
1145751a99abSHeiko Stübner 		if ((bank->bank_num == 0) && (pin >= RK_PB4) && (pin <= RK_PB7))
1146751a99abSHeiko Stübner 			reg += 0x1ff4; /* GPIO0_IOC_GPIO0B_IOMUX_SEL_H */
1147751a99abSHeiko Stübner 	}
114803716e1dSHeiko Stübner 
1149a076e2edSHeiko Stübner 	if (ctrl->type == RK3588) {
1150a076e2edSHeiko Stübner 		if (bank->bank_num == 0) {
115105709c3eSJohn Keeping 			if ((pin >= RK_PB4) && (pin <= RK_PD7)) {
115205709c3eSJohn Keeping 				u32 reg0 = 0;
115305709c3eSJohn Keeping 
115405709c3eSJohn Keeping 				reg0 = reg + 0x4000 - 0xC; /* PMU2_IOC_BASE */
1155e4dd7fd5SAndy Shevchenko 				ret = regmap_read(regmap, reg0, &val);
115605709c3eSJohn Keeping 				if (ret)
115705709c3eSJohn Keeping 					return ret;
115805709c3eSJohn Keeping 
115905709c3eSJohn Keeping 				if (!(val & BIT(8)))
116005709c3eSJohn Keeping 					return ((val >> bit) & mask);
116105709c3eSJohn Keeping 
1162e4dd7fd5SAndy Shevchenko 				reg = reg + 0x8000; /* BUS_IOC_BASE */
116305709c3eSJohn Keeping 				regmap = info->regmap_base;
116405709c3eSJohn Keeping 			}
116505709c3eSJohn Keeping 		} else if (bank->bank_num > 0) {
116605709c3eSJohn Keeping 			reg += 0x8000; /* BUS_IOC_BASE */
116705709c3eSJohn Keeping 		}
1168e4dd7fd5SAndy Shevchenko 	}
116905709c3eSJohn Keeping 
117005709c3eSJohn Keeping 	ret = regmap_read(regmap, reg, &val);
117105709c3eSJohn Keeping 	if (ret)
117205709c3eSJohn Keeping 		return ret;
117305709c3eSJohn Keeping 
117405709c3eSJohn Keeping 	return ((val >> bit) & mask);
117505709c3eSJohn Keeping }
1176d3e51161SHeiko Stübner 
rockchip_verify_mux(struct rockchip_pin_bank * bank,int pin,int mux)1177d3e51161SHeiko Stübner static int rockchip_verify_mux(struct rockchip_pin_bank *bank,
1178d3e51161SHeiko Stübner 			       int pin, int mux)
1179d3e51161SHeiko Stübner {
1180d3e51161SHeiko Stübner 	struct rockchip_pinctrl *info = bank->drvdata;
1181d3e51161SHeiko Stübner 	struct device *dev = info->dev;
1182d3e51161SHeiko Stübner 	int iomux_num = (pin / 8);
1183d3e51161SHeiko Stübner 
1184d3e51161SHeiko Stübner 	if (iomux_num > 3)
1185d3e51161SHeiko Stübner 		return -EINVAL;
1186d3e51161SHeiko Stübner 
1187d3e51161SHeiko Stübner 	if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) {
1188d3e51161SHeiko Stübner 		dev_err(dev, "pin %d is unrouted\n", pin);
118914797189SHeiko Stübner 		return -EINVAL;
1190d3e51161SHeiko Stübner 	}
1191d3e51161SHeiko Stübner 
1192fdc33ebaSJianqun Xu 	if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) {
1193e4dd7fd5SAndy Shevchenko 		if (mux != RK_FUNC_GPIO) {
1194fc72c923SHeiko Stübner 			dev_err(dev, "pin %d only supports a gpio mux\n", pin);
119595ec8ae4SHeiko Stübner 			return -ENOTSUPP;
1196ea262ad6Sdavid.wu 		}
1197d3e51161SHeiko Stübner 	}
119851ff47aaSHeiko Stuebner 
1199d3e51161SHeiko Stübner 	return 0;
120005709c3eSJohn Keeping }
120105709c3eSJohn Keeping 
120205709c3eSJohn Keeping /*
1203fc72c923SHeiko Stübner  * Set a new mux function for a pin.
120405709c3eSJohn Keeping  *
1205c4a532deSHeiko Stübner  * The register is divided into the upper and lower 16 bit. When changing
1206c4a532deSHeiko Stübner  * a value, the previous register value is not read and changed. Instead
1207e4dd7fd5SAndy Shevchenko  * it seems the changed bits are marked in the upper 16 bit, while the
1208d3e51161SHeiko Stübner  * changed value gets set in the same offset in the lower 16 bit.
1209fd4ea486SJagan Teki  * All pin settings seem to be 2 bit wide in both the upper and lower
1210fd4ea486SJagan Teki  * parts.
1211fd4ea486SJagan Teki  * @bank: pin bank to change
1212fd4ea486SJagan Teki  * @pin: pin to change
1213fd4ea486SJagan Teki  * @mux: new mux function to set
1214fd4ea486SJagan Teki  */
rockchip_set_mux(struct rockchip_pin_bank * bank,int pin,int mux)121595ec8ae4SHeiko Stübner static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
1216d3e51161SHeiko Stübner {
1217ea262ad6Sdavid.wu 	struct rockchip_pinctrl *info = bank->drvdata;
12186bc0d121SHeiko Stübner 	struct rockchip_pin_ctrl *ctrl = info->ctrl;
1219ea262ad6Sdavid.wu 	struct device *dev = info->dev;
122003716e1dSHeiko Stübner 	int iomux_num = (pin / 8);
122103716e1dSHeiko Stübner 	struct regmap *regmap;
122203716e1dSHeiko Stübner 	int reg, ret, mask, mux_type;
12238b6c6f93Sdavid.wu 	u8 bit;
1224ea262ad6Sdavid.wu 	u32 data, rmask, route_location, route_reg, route_val;
12258b6c6f93Sdavid.wu 
12268b6c6f93Sdavid.wu 	ret = rockchip_verify_mux(bank, pin, mux);
12278b6c6f93Sdavid.wu 	if (ret < 0)
12288b6c6f93Sdavid.wu 		return ret;
122903716e1dSHeiko Stübner 
1230d3e51161SHeiko Stübner 	if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY)
12318b6c6f93Sdavid.wu 		return 0;
123203716e1dSHeiko Stübner 
1233d3e51161SHeiko Stübner 	dev_dbg(dev, "setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux);
1234c04c3fa6SDavid Wu 
1235c04c3fa6SDavid Wu 	if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
1236ea262ad6Sdavid.wu 		regmap = info->regmap_pmu;
1237fdc33ebaSJianqun Xu 	else if (bank->iomux[iomux_num].type & IOMUX_L_SOURCE_PMU)
1238fdc33ebaSJianqun Xu 		regmap = (pin % 8 < 4) ? info->regmap_pmu : info->regmap_base;
1239fdc33ebaSJianqun Xu 	else
1240fdc33ebaSJianqun Xu 		regmap = info->regmap_base;
1241fdc33ebaSJianqun Xu 
1242fdc33ebaSJianqun Xu 	/* get basic quadrupel of mux registers and the correct reg inside */
1243fdc33ebaSJianqun Xu 	mux_type = bank->iomux[iomux_num].type;
1244fdc33ebaSJianqun Xu 	reg = bank->iomux[iomux_num].offset;
1245fdc33ebaSJianqun Xu 	if (mux_type & IOMUX_WIDTH_4BIT) {
1246fdc33ebaSJianqun Xu 		if ((pin % 8) >= 4)
1247fdc33ebaSJianqun Xu 			reg += 0x4;
1248fdc33ebaSJianqun Xu 		bit = (pin % 4) * 4;
1249fdc33ebaSJianqun Xu 		mask = 0xf;
1250fdc33ebaSJianqun Xu 	} else if (mux_type & IOMUX_WIDTH_3BIT) {
1251fdc33ebaSJianqun Xu 		if ((pin % 8) >= 5)
1252fdc33ebaSJianqun Xu 			reg += 0x4;
1253fdc33ebaSJianqun Xu 		bit = (pin % 8 % 5) * 3;
1254fdc33ebaSJianqun Xu 		mask = 0x7;
1255fdc33ebaSJianqun Xu 	} else {
1256fdc33ebaSJianqun Xu 		bit = (pin % 8) * 2;
1257fdc33ebaSJianqun Xu 		mask = 0x3;
1258fdc33ebaSJianqun Xu 	}
1259fdc33ebaSJianqun Xu 
1260fdc33ebaSJianqun Xu 	if (bank->recalced_mask & BIT(pin))
1261fdc33ebaSJianqun Xu 		rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
1262fdc33ebaSJianqun Xu 
1263fdc33ebaSJianqun Xu 	if (ctrl->type == RK3576) {
1264fdc33ebaSJianqun Xu 		if ((bank->bank_num == 0) && (pin >= RK_PB4) && (pin <= RK_PB7))
1265fdc33ebaSJianqun Xu 			reg += 0x1ff4; /* GPIO0_IOC_GPIO0B_IOMUX_SEL_H */
1266fdc33ebaSJianqun Xu 	}
1267fdc33ebaSJianqun Xu 
1268fdc33ebaSJianqun Xu 	if (ctrl->type == RK3588) {
1269fdc33ebaSJianqun Xu 		if (bank->bank_num == 0) {
1270fdc33ebaSJianqun Xu 			if ((pin >= RK_PB4) && (pin <= RK_PD7)) {
1271fdc33ebaSJianqun Xu 				if (mux < 8) {
1272fdc33ebaSJianqun Xu 					reg += 0x4000 - 0xC; /* PMU2_IOC_BASE */
1273fdc33ebaSJianqun Xu 					data = (mask << (bit + 16));
1274fdc33ebaSJianqun Xu 					rmask = data | (data >> 16);
1275fdc33ebaSJianqun Xu 					data |= (mux & mask) << bit;
1276fdc33ebaSJianqun Xu 					ret = regmap_update_bits(regmap, reg, rmask, data);
1277bd35b9bfSDavid Wu 				} else {
127851ff47aaSHeiko Stuebner 					u32 reg0 = 0;
127951ff47aaSHeiko Stuebner 
128051ff47aaSHeiko Stuebner 					reg0 = reg + 0x4000 - 0xC; /* PMU2_IOC_BASE */
128151ff47aaSHeiko Stuebner 					data = (mask << (bit + 16));
128251ff47aaSHeiko Stuebner 					rmask = data | (data >> 16);
128351ff47aaSHeiko Stuebner 					data |= 8 << bit;
128451ff47aaSHeiko Stuebner 					ret = regmap_update_bits(regmap, reg0, rmask, data);
128551ff47aaSHeiko Stuebner 
128651ff47aaSHeiko Stuebner 					reg0 = reg + 0x8000; /* BUS_IOC_BASE */
128751ff47aaSHeiko Stuebner 					data = (mask << (bit + 16));
128851ff47aaSHeiko Stuebner 					rmask = data | (data >> 16);
128951ff47aaSHeiko Stuebner 					data |= mux << bit;
129051ff47aaSHeiko Stuebner 					regmap = info->regmap_base;
129151ff47aaSHeiko Stuebner 					ret |= regmap_update_bits(regmap, reg0, rmask, data);
129251ff47aaSHeiko Stuebner 				}
1293bd35b9bfSDavid Wu 			} else {
1294bd35b9bfSDavid Wu 				data = (mask << (bit + 16));
1295bd35b9bfSDavid Wu 				rmask = data | (data >> 16);
1296bd35b9bfSDavid Wu 				data |= (mux & mask) << bit;
1297bd35b9bfSDavid Wu 				ret = regmap_update_bits(regmap, reg, rmask, data);
129803716e1dSHeiko Stübner 			}
129999e872d9SSonny Rao 			return ret;
130003716e1dSHeiko Stübner 		} else if (bank->bank_num > 0) {
130199e872d9SSonny Rao 			reg += 0x8000; /* BUS_IOC_BASE */
1302d3e51161SHeiko Stübner 		}
1303751a99abSHeiko Stübner 	}
1304d3e51161SHeiko Stübner 
1305d3e51161SHeiko Stübner 	if (mux > mask)
130687065ca9SDavid Wu 		return -EINVAL;
130787065ca9SDavid Wu 
130887065ca9SDavid Wu 	if (bank->route_mask & BIT(pin)) {
130987065ca9SDavid Wu 		if (rockchip_get_mux_route(bank, pin, mux, &route_location,
131087065ca9SDavid Wu 					   &route_reg, &route_val)) {
131187065ca9SDavid Wu 			struct regmap *route_regmap = regmap;
131242573ab3SSebastian Reichel 
131387065ca9SDavid Wu 			/* handle special locations */
131487065ca9SDavid Wu 			switch (route_location) {
131587065ca9SDavid Wu 			case ROCKCHIP_ROUTE_PMU:
131687065ca9SDavid Wu 				route_regmap = info->regmap_pmu;
131787065ca9SDavid Wu 				break;
131887065ca9SDavid Wu 			case ROCKCHIP_ROUTE_GRF:
131987065ca9SDavid Wu 				route_regmap = info->regmap_base;
132087065ca9SDavid Wu 				break;
132187065ca9SDavid Wu 			}
132287065ca9SDavid Wu 
132387065ca9SDavid Wu 			ret = regmap_write(route_regmap, route_reg, route_val);
132487065ca9SDavid Wu 			if (ret)
132587065ca9SDavid Wu 				return ret;
132687065ca9SDavid Wu 		}
132787065ca9SDavid Wu 	}
132887065ca9SDavid Wu 
132987065ca9SDavid Wu 	data = (mask << (bit + 16));
133087065ca9SDavid Wu 	rmask = data | (data >> 16);
133187065ca9SDavid Wu 	data |= (mux & mask) << bit;
133287065ca9SDavid Wu 	ret = regmap_update_bits(regmap, reg, rmask, data);
133387065ca9SDavid Wu 
133442573ab3SSebastian Reichel 	return ret;
133542573ab3SSebastian Reichel }
133687065ca9SDavid Wu 
133787065ca9SDavid Wu #define PX30_PULL_PMU_OFFSET		0x10
133887065ca9SDavid Wu #define PX30_PULL_GRF_OFFSET		0x60
133987065ca9SDavid Wu #define PX30_PULL_BITS_PER_PIN		2
134087065ca9SDavid Wu #define PX30_PULL_PINS_PER_REG		8
134187065ca9SDavid Wu #define PX30_PULL_BANK_STRIDE		16
134287065ca9SDavid Wu 
px30_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)134387065ca9SDavid Wu static int px30_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
134442573ab3SSebastian Reichel 				      int pin_num, struct regmap **regmap,
134587065ca9SDavid Wu 				      int *reg, u8 *bit)
134687065ca9SDavid Wu {
134787065ca9SDavid Wu 	struct rockchip_pinctrl *info = bank->drvdata;
134887065ca9SDavid Wu 
134987065ca9SDavid Wu 	/* The first 32 pins of the first bank are located in PMU */
135087065ca9SDavid Wu 	if (bank->bank_num == 0) {
135187065ca9SDavid Wu 		*regmap = info->regmap_pmu;
135287065ca9SDavid Wu 		*reg = PX30_PULL_PMU_OFFSET;
135387065ca9SDavid Wu 	} else {
135487065ca9SDavid Wu 		*regmap = info->regmap_base;
135587065ca9SDavid Wu 		*reg = PX30_PULL_GRF_OFFSET;
135687065ca9SDavid Wu 
135787065ca9SDavid Wu 		/* correct the offset, as we're starting with the 2nd bank */
135887065ca9SDavid Wu 		*reg -= 0x10;
135987065ca9SDavid Wu 		*reg += bank->bank_num * PX30_PULL_BANK_STRIDE;
136087065ca9SDavid Wu 	}
136187065ca9SDavid Wu 
136287065ca9SDavid Wu 	*reg += ((pin_num / PX30_PULL_PINS_PER_REG) * 4);
136387065ca9SDavid Wu 	*bit = (pin_num % PX30_PULL_PINS_PER_REG);
136487065ca9SDavid Wu 	*bit *= PX30_PULL_BITS_PER_PIN;
136587065ca9SDavid Wu 
136642573ab3SSebastian Reichel 	return 0;
136742573ab3SSebastian Reichel }
136887065ca9SDavid Wu 
136987065ca9SDavid Wu #define PX30_DRV_PMU_OFFSET		0x20
137087065ca9SDavid Wu #define PX30_DRV_GRF_OFFSET		0xf0
137187065ca9SDavid Wu #define PX30_DRV_BITS_PER_PIN		2
137287065ca9SDavid Wu #define PX30_DRV_PINS_PER_REG		8
137387065ca9SDavid Wu #define PX30_DRV_BANK_STRIDE		16
137487065ca9SDavid Wu 
px30_calc_drv_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)137587065ca9SDavid Wu static int px30_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
137687065ca9SDavid Wu 				     int pin_num, struct regmap **regmap,
137787065ca9SDavid Wu 				     int *reg, u8 *bit)
137887065ca9SDavid Wu {
137987065ca9SDavid Wu 	struct rockchip_pinctrl *info = bank->drvdata;
138087065ca9SDavid Wu 
138187065ca9SDavid Wu 	/* The first 32 pins of the first bank are located in PMU */
138287065ca9SDavid Wu 	if (bank->bank_num == 0) {
138387065ca9SDavid Wu 		*regmap = info->regmap_pmu;
138487065ca9SDavid Wu 		*reg = PX30_DRV_PMU_OFFSET;
138587065ca9SDavid Wu 	} else {
138687065ca9SDavid Wu 		*regmap = info->regmap_base;
138787065ca9SDavid Wu 		*reg = PX30_DRV_GRF_OFFSET;
138887065ca9SDavid Wu 
138987065ca9SDavid Wu 		/* correct the offset, as we're starting with the 2nd bank */
139087065ca9SDavid Wu 		*reg -= 0x10;
139187065ca9SDavid Wu 		*reg += bank->bank_num * PX30_DRV_BANK_STRIDE;
139287065ca9SDavid Wu 	}
139387065ca9SDavid Wu 
139487065ca9SDavid Wu 	*reg += ((pin_num / PX30_DRV_PINS_PER_REG) * 4);
139587065ca9SDavid Wu 	*bit = (pin_num % PX30_DRV_PINS_PER_REG);
139687065ca9SDavid Wu 	*bit *= PX30_DRV_BITS_PER_PIN;
139787065ca9SDavid Wu 
139887065ca9SDavid Wu 	return 0;
139987065ca9SDavid Wu }
140087065ca9SDavid Wu 
1401b9c6dcabSAndy Yan #define PX30_SCHMITT_PMU_OFFSET			0x38
1402b9c6dcabSAndy Yan #define PX30_SCHMITT_GRF_OFFSET			0xc0
1403b9c6dcabSAndy Yan #define PX30_SCHMITT_PINS_PER_PMU_REG		16
1404b9c6dcabSAndy Yan #define PX30_SCHMITT_BANK_STRIDE		16
1405b9c6dcabSAndy Yan #define PX30_SCHMITT_PINS_PER_GRF_REG		8
1406688daf23SAndy Yan 
px30_calc_schmitt_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)140742573ab3SSebastian Reichel static int px30_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
1408688daf23SAndy Yan 					 int pin_num,
1409688daf23SAndy Yan 					 struct regmap **regmap,
1410688daf23SAndy Yan 					 int *reg, u8 *bit)
1411688daf23SAndy Yan {
1412688daf23SAndy Yan 	struct rockchip_pinctrl *info = bank->drvdata;
1413688daf23SAndy Yan 	int pins_per_reg;
1414688daf23SAndy Yan 
1415688daf23SAndy Yan 	if (bank->bank_num == 0) {
1416b9c6dcabSAndy Yan 		*regmap = info->regmap_pmu;
1417688daf23SAndy Yan 		*reg = PX30_SCHMITT_PMU_OFFSET;
1418b9c6dcabSAndy Yan 		pins_per_reg = PX30_SCHMITT_PINS_PER_PMU_REG;
1419688daf23SAndy Yan 	} else {
1420688daf23SAndy Yan 		*regmap = info->regmap_base;
1421688daf23SAndy Yan 		*reg = PX30_SCHMITT_GRF_OFFSET;
1422b9c6dcabSAndy Yan 		pins_per_reg = PX30_SCHMITT_PINS_PER_GRF_REG;
1423688daf23SAndy Yan 		*reg += (bank->bank_num  - 1) * PX30_SCHMITT_BANK_STRIDE;
1424688daf23SAndy Yan 	}
1425b9c6dcabSAndy Yan 
1426b9c6dcabSAndy Yan 	*reg += ((pin_num / pins_per_reg) * 4);
1427b9c6dcabSAndy Yan 	*bit = pin_num % pins_per_reg;
142842573ab3SSebastian Reichel 
142942573ab3SSebastian Reichel 	return 0;
1430688daf23SAndy Yan }
1431688daf23SAndy Yan 
1432b9c6dcabSAndy Yan #define RV1108_PULL_PMU_OFFSET		0x10
1433b9c6dcabSAndy Yan #define RV1108_PULL_OFFSET		0x110
1434b9c6dcabSAndy Yan #define RV1108_PULL_PINS_PER_REG	8
1435b9c6dcabSAndy Yan #define RV1108_PULL_BITS_PER_PIN	2
1436b9c6dcabSAndy Yan #define RV1108_PULL_BANK_STRIDE		16
1437688daf23SAndy Yan 
rv1108_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)143842573ab3SSebastian Reichel static int rv1108_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
1439688daf23SAndy Yan 					int pin_num, struct regmap **regmap,
1440688daf23SAndy Yan 					int *reg, u8 *bit)
1441688daf23SAndy Yan {
1442688daf23SAndy Yan 	struct rockchip_pinctrl *info = bank->drvdata;
1443688daf23SAndy Yan 
1444688daf23SAndy Yan 	/* The first 24 pins of the first bank are located in PMU */
1445688daf23SAndy Yan 	if (bank->bank_num == 0) {
1446688daf23SAndy Yan 		*regmap = info->regmap_pmu;
1447b9c6dcabSAndy Yan 		*reg = RV1108_PULL_PMU_OFFSET;
1448688daf23SAndy Yan 	} else {
1449688daf23SAndy Yan 		*reg = RV1108_PULL_OFFSET;
1450b9c6dcabSAndy Yan 		*regmap = info->regmap_base;
1451688daf23SAndy Yan 		/* correct the offset, as we're starting with the 2nd bank */
1452688daf23SAndy Yan 		*reg -= 0x10;
1453688daf23SAndy Yan 		*reg += bank->bank_num * RV1108_PULL_BANK_STRIDE;
1454b9c6dcabSAndy Yan 	}
1455688daf23SAndy Yan 
1456688daf23SAndy Yan 	*reg += ((pin_num / RV1108_PULL_PINS_PER_REG) * 4);
1457b9c6dcabSAndy Yan 	*bit = (pin_num % RV1108_PULL_PINS_PER_REG);
1458b9c6dcabSAndy Yan 	*bit *= RV1108_PULL_BITS_PER_PIN;
1459b9c6dcabSAndy Yan 
146042573ab3SSebastian Reichel 	return 0;
146142573ab3SSebastian Reichel }
1462688daf23SAndy Yan 
1463688daf23SAndy Yan #define RV1108_DRV_PMU_OFFSET		0x20
14645caff7eaSAndy Yan #define RV1108_DRV_GRF_OFFSET		0x210
14655caff7eaSAndy Yan #define RV1108_DRV_BITS_PER_PIN		2
14665caff7eaSAndy Yan #define RV1108_DRV_PINS_PER_REG		8
14675caff7eaSAndy Yan #define RV1108_DRV_BANK_STRIDE		16
14685caff7eaSAndy Yan 
rv1108_calc_drv_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)14695caff7eaSAndy Yan static int rv1108_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
14705caff7eaSAndy Yan 				       int pin_num, struct regmap **regmap,
14715caff7eaSAndy Yan 				       int *reg, u8 *bit)
14725caff7eaSAndy Yan {
14735caff7eaSAndy Yan 	struct rockchip_pinctrl *info = bank->drvdata;
14745caff7eaSAndy Yan 
14755caff7eaSAndy Yan 	/* The first 24 pins of the first bank are located in PMU */
14765caff7eaSAndy Yan 	if (bank->bank_num == 0) {
14775caff7eaSAndy Yan 		*regmap = info->regmap_pmu;
14785caff7eaSAndy Yan 		*reg = RV1108_DRV_PMU_OFFSET;
14795caff7eaSAndy Yan 	} else {
14805caff7eaSAndy Yan 		*regmap = info->regmap_base;
14815caff7eaSAndy Yan 		*reg = RV1108_DRV_GRF_OFFSET;
14825caff7eaSAndy Yan 
14835caff7eaSAndy Yan 		/* correct the offset, as we're starting with the 2nd bank */
14845caff7eaSAndy Yan 		*reg -= 0x10;
14855caff7eaSAndy Yan 		*reg += bank->bank_num * RV1108_DRV_BANK_STRIDE;
14865caff7eaSAndy Yan 	}
14875caff7eaSAndy Yan 
14885caff7eaSAndy Yan 	*reg += ((pin_num / RV1108_DRV_PINS_PER_REG) * 4);
14895caff7eaSAndy Yan 	*bit = pin_num % RV1108_DRV_PINS_PER_REG;
14905caff7eaSAndy Yan 	*bit *= RV1108_DRV_BITS_PER_PIN;
14915caff7eaSAndy Yan 
14925caff7eaSAndy Yan 	return 0;
14935caff7eaSAndy Yan }
1494fd4ea486SJagan Teki 
1495fd4ea486SJagan Teki #define RV1108_SCHMITT_PMU_OFFSET		0x30
1496fd4ea486SJagan Teki #define RV1108_SCHMITT_GRF_OFFSET		0x388
1497fd4ea486SJagan Teki #define RV1108_SCHMITT_BANK_STRIDE		8
1498fd4ea486SJagan Teki #define RV1108_SCHMITT_PINS_PER_GRF_REG		16
1499fd4ea486SJagan Teki #define RV1108_SCHMITT_PINS_PER_PMU_REG		8
1500fd4ea486SJagan Teki 
rv1108_calc_schmitt_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)1501fd4ea486SJagan Teki static int rv1108_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
1502fd4ea486SJagan Teki 					   int pin_num,
1503fd4ea486SJagan Teki 					   struct regmap **regmap,
1504fd4ea486SJagan Teki 					   int *reg, u8 *bit)
1505fd4ea486SJagan Teki {
1506fd4ea486SJagan Teki 	struct rockchip_pinctrl *info = bank->drvdata;
1507fd4ea486SJagan Teki 	int pins_per_reg;
1508fd4ea486SJagan Teki 
1509fd4ea486SJagan Teki 	if (bank->bank_num == 0) {
1510fd4ea486SJagan Teki 		*regmap = info->regmap_pmu;
1511fd4ea486SJagan Teki 		*reg = RV1108_SCHMITT_PMU_OFFSET;
1512fd4ea486SJagan Teki 		pins_per_reg = RV1108_SCHMITT_PINS_PER_PMU_REG;
1513fd4ea486SJagan Teki 	} else {
1514fd4ea486SJagan Teki 		*regmap = info->regmap_base;
1515fd4ea486SJagan Teki 		*reg = RV1108_SCHMITT_GRF_OFFSET;
1516fd4ea486SJagan Teki 		pins_per_reg = RV1108_SCHMITT_PINS_PER_GRF_REG;
1517fd4ea486SJagan Teki 		*reg += (bank->bank_num  - 1) * RV1108_SCHMITT_BANK_STRIDE;
1518fd4ea486SJagan Teki 	}
1519fd4ea486SJagan Teki 	*reg += ((pin_num / pins_per_reg) * 4);
1520fd4ea486SJagan Teki 	*bit = pin_num % pins_per_reg;
1521fd4ea486SJagan Teki 
1522fd4ea486SJagan Teki 	return 0;
1523fd4ea486SJagan Teki }
1524fd4ea486SJagan Teki 
1525fd4ea486SJagan Teki #define RV1126_PULL_PMU_OFFSET		0x40
1526fd4ea486SJagan Teki #define RV1126_PULL_GRF_GPIO1A0_OFFSET	0x10108
1527fd4ea486SJagan Teki #define RV1126_PULL_PINS_PER_REG	8
1528fd4ea486SJagan Teki #define RV1126_PULL_BITS_PER_PIN	2
1529fd4ea486SJagan Teki #define RV1126_PULL_BANK_STRIDE		16
1530fd4ea486SJagan Teki #define RV1126_GPIO_C4_D7(p)		(p >= 20 && p <= 31) /* GPIO0_C4 ~ GPIO0_D7 */
1531fd4ea486SJagan Teki 
rv1126_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)1532fd4ea486SJagan Teki static int rv1126_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
1533fd4ea486SJagan Teki 					int pin_num, struct regmap **regmap,
1534fd4ea486SJagan Teki 					int *reg, u8 *bit)
1535fd4ea486SJagan Teki {
1536fd4ea486SJagan Teki 	struct rockchip_pinctrl *info = bank->drvdata;
1537fd4ea486SJagan Teki 
1538fd4ea486SJagan Teki 	/* The first 24 pins of the first bank are located in PMU */
1539fd4ea486SJagan Teki 	if (bank->bank_num == 0) {
1540fd4ea486SJagan Teki 		if (RV1126_GPIO_C4_D7(pin_num)) {
1541fd4ea486SJagan Teki 			*regmap = info->regmap_base;
1542fd4ea486SJagan Teki 			*reg = RV1126_PULL_GRF_GPIO1A0_OFFSET;
1543fd4ea486SJagan Teki 			*reg -= (((31 - pin_num) / RV1126_PULL_PINS_PER_REG + 1) * 4);
1544fd4ea486SJagan Teki 			*bit = pin_num % RV1126_PULL_PINS_PER_REG;
1545fd4ea486SJagan Teki 			*bit *= RV1126_PULL_BITS_PER_PIN;
1546fd4ea486SJagan Teki 			return 0;
1547fd4ea486SJagan Teki 		}
1548fd4ea486SJagan Teki 		*regmap = info->regmap_pmu;
1549fd4ea486SJagan Teki 		*reg = RV1126_PULL_PMU_OFFSET;
1550fd4ea486SJagan Teki 	} else {
1551fd4ea486SJagan Teki 		*reg = RV1126_PULL_GRF_GPIO1A0_OFFSET;
1552fd4ea486SJagan Teki 		*regmap = info->regmap_base;
1553fd4ea486SJagan Teki 		*reg += (bank->bank_num - 1) * RV1126_PULL_BANK_STRIDE;
1554fd4ea486SJagan Teki 	}
1555fd4ea486SJagan Teki 
1556fd4ea486SJagan Teki 	*reg += ((pin_num / RV1126_PULL_PINS_PER_REG) * 4);
1557fd4ea486SJagan Teki 	*bit = (pin_num % RV1126_PULL_PINS_PER_REG);
1558fd4ea486SJagan Teki 	*bit *= RV1126_PULL_BITS_PER_PIN;
1559fd4ea486SJagan Teki 
1560fd4ea486SJagan Teki 	return 0;
1561fd4ea486SJagan Teki }
1562fd4ea486SJagan Teki 
1563fd4ea486SJagan Teki #define RV1126_DRV_PMU_OFFSET		0x20
1564fd4ea486SJagan Teki #define RV1126_DRV_GRF_GPIO1A0_OFFSET	0x10090
1565fd4ea486SJagan Teki #define RV1126_DRV_BITS_PER_PIN		4
1566fd4ea486SJagan Teki #define RV1126_DRV_PINS_PER_REG		4
1567fd4ea486SJagan Teki #define RV1126_DRV_BANK_STRIDE		32
1568fd4ea486SJagan Teki 
rv1126_calc_drv_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)1569fd4ea486SJagan Teki static int rv1126_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
1570fd4ea486SJagan Teki 				       int pin_num, struct regmap **regmap,
1571fd4ea486SJagan Teki 				       int *reg, u8 *bit)
1572fd4ea486SJagan Teki {
1573fd4ea486SJagan Teki 	struct rockchip_pinctrl *info = bank->drvdata;
1574fd4ea486SJagan Teki 
1575fd4ea486SJagan Teki 	/* The first 24 pins of the first bank are located in PMU */
1576fd4ea486SJagan Teki 	if (bank->bank_num == 0) {
1577fd4ea486SJagan Teki 		if (RV1126_GPIO_C4_D7(pin_num)) {
1578fd4ea486SJagan Teki 			*regmap = info->regmap_base;
1579fd4ea486SJagan Teki 			*reg = RV1126_DRV_GRF_GPIO1A0_OFFSET;
1580fd4ea486SJagan Teki 			*reg -= (((31 - pin_num) / RV1126_DRV_PINS_PER_REG + 1) * 4);
1581fd4ea486SJagan Teki 			*reg -= 0x4;
1582fd4ea486SJagan Teki 			*bit = pin_num % RV1126_DRV_PINS_PER_REG;
1583fd4ea486SJagan Teki 			*bit *= RV1126_DRV_BITS_PER_PIN;
1584fd4ea486SJagan Teki 			return 0;
1585fd4ea486SJagan Teki 		}
1586fd4ea486SJagan Teki 		*regmap = info->regmap_pmu;
1587fd4ea486SJagan Teki 		*reg = RV1126_DRV_PMU_OFFSET;
1588fd4ea486SJagan Teki 	} else {
1589fd4ea486SJagan Teki 		*regmap = info->regmap_base;
1590fd4ea486SJagan Teki 		*reg = RV1126_DRV_GRF_GPIO1A0_OFFSET;
1591fd4ea486SJagan Teki 		*reg += (bank->bank_num - 1) * RV1126_DRV_BANK_STRIDE;
1592fd4ea486SJagan Teki 	}
1593fd4ea486SJagan Teki 
1594fd4ea486SJagan Teki 	*reg += ((pin_num / RV1126_DRV_PINS_PER_REG) * 4);
1595fd4ea486SJagan Teki 	*bit = pin_num % RV1126_DRV_PINS_PER_REG;
1596fd4ea486SJagan Teki 	*bit *= RV1126_DRV_BITS_PER_PIN;
1597fd4ea486SJagan Teki 
1598fd4ea486SJagan Teki 	return 0;
1599fd4ea486SJagan Teki }
1600fd4ea486SJagan Teki 
1601fd4ea486SJagan Teki #define RV1126_SCHMITT_PMU_OFFSET		0x60
1602fd4ea486SJagan Teki #define RV1126_SCHMITT_GRF_GPIO1A0_OFFSET	0x10188
1603fd4ea486SJagan Teki #define RV1126_SCHMITT_BANK_STRIDE		16
1604fd4ea486SJagan Teki #define RV1126_SCHMITT_PINS_PER_GRF_REG		8
1605fd4ea486SJagan Teki #define RV1126_SCHMITT_PINS_PER_PMU_REG		8
1606fd4ea486SJagan Teki 
rv1126_calc_schmitt_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)16077825aeb7SJianqun Xu static int rv1126_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
16087825aeb7SJianqun Xu 					   int pin_num,
16097825aeb7SJianqun Xu 					   struct regmap **regmap,
16107825aeb7SJianqun Xu 					   int *reg, u8 *bit)
16117825aeb7SJianqun Xu {
16127825aeb7SJianqun Xu 	struct rockchip_pinctrl *info = bank->drvdata;
16137825aeb7SJianqun Xu 	int pins_per_reg;
16147825aeb7SJianqun Xu 
16157825aeb7SJianqun Xu 	if (bank->bank_num == 0) {
16167825aeb7SJianqun Xu 		if (RV1126_GPIO_C4_D7(pin_num)) {
16177825aeb7SJianqun Xu 			*regmap = info->regmap_base;
16187825aeb7SJianqun Xu 			*reg = RV1126_SCHMITT_GRF_GPIO1A0_OFFSET;
16197825aeb7SJianqun Xu 			*reg -= (((31 - pin_num) / RV1126_SCHMITT_PINS_PER_GRF_REG + 1) * 4);
16207825aeb7SJianqun Xu 			*bit = pin_num % RV1126_SCHMITT_PINS_PER_GRF_REG;
16217825aeb7SJianqun Xu 			return 0;
16227825aeb7SJianqun Xu 		}
16237825aeb7SJianqun Xu 		*regmap = info->regmap_pmu;
16247825aeb7SJianqun Xu 		*reg = RV1126_SCHMITT_PMU_OFFSET;
16257825aeb7SJianqun Xu 		pins_per_reg = RV1126_SCHMITT_PINS_PER_PMU_REG;
16267825aeb7SJianqun Xu 	} else {
1627a282926dSHeiko Stübner 		*regmap = info->regmap_base;
1628a282926dSHeiko Stübner 		*reg = RV1126_SCHMITT_GRF_GPIO1A0_OFFSET;
1629a282926dSHeiko Stübner 		pins_per_reg = RV1126_SCHMITT_PINS_PER_GRF_REG;
1630a282926dSHeiko Stübner 		*reg += (bank->bank_num - 1) * RV1126_SCHMITT_BANK_STRIDE;
163142573ab3SSebastian Reichel 	}
1632751a99abSHeiko Stübner 	*reg += ((pin_num / pins_per_reg) * 4);
1633751a99abSHeiko Stübner 	*bit = pin_num % pins_per_reg;
1634a282926dSHeiko Stübner 
1635a282926dSHeiko Stübner 	return 0;
1636a282926dSHeiko Stübner }
1637751a99abSHeiko Stübner 
1638751a99abSHeiko Stübner #define RK3308_SCHMITT_PINS_PER_REG		8
1639a282926dSHeiko Stübner #define RK3308_SCHMITT_BANK_STRIDE		16
1640a282926dSHeiko Stübner #define RK3308_SCHMITT_GRF_OFFSET		0x1a0
1641a282926dSHeiko Stübner 
rk3308_calc_schmitt_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)1642a282926dSHeiko Stübner static int rk3308_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
164342573ab3SSebastian Reichel 				    int pin_num, struct regmap **regmap,
164442573ab3SSebastian Reichel 				    int *reg, u8 *bit)
1645a282926dSHeiko Stübner {
1646a282926dSHeiko Stübner 	struct rockchip_pinctrl *info = bank->drvdata;
1647d23c66dfSDavid Wu 
1648d23c66dfSDavid Wu 	*regmap = info->regmap_base;
164942573ab3SSebastian Reichel 	*reg = RK3308_SCHMITT_GRF_OFFSET;
1650d23c66dfSDavid Wu 
1651d23c66dfSDavid Wu 	*reg += bank->bank_num * RK3308_SCHMITT_BANK_STRIDE;
1652d23c66dfSDavid Wu 	*reg += ((pin_num / RK3308_SCHMITT_PINS_PER_REG) * 4);
1653d23c66dfSDavid Wu 	*bit = pin_num % RK3308_SCHMITT_PINS_PER_REG;
1654d23c66dfSDavid Wu 
1655d23c66dfSDavid Wu 	return 0;
1656d23c66dfSDavid Wu }
1657d23c66dfSDavid Wu 
1658d23c66dfSDavid Wu #define RK2928_PULL_OFFSET		0x118
1659d23c66dfSDavid Wu #define RK2928_PULL_PINS_PER_REG	16
1660d23c66dfSDavid Wu #define RK2928_PULL_BANK_STRIDE		8
166142573ab3SSebastian Reichel 
rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)166242573ab3SSebastian Reichel static int rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
1663d23c66dfSDavid Wu 					int pin_num, struct regmap **regmap,
1664d23c66dfSDavid Wu 					int *reg, u8 *bit)
1665bfc7a42aSHeiko Stübner {
16666ca5274dSHeiko Stübner 	struct rockchip_pinctrl *info = bank->drvdata;
16676ca5274dSHeiko Stübner 
16686ca5274dSHeiko Stübner 	*regmap = info->regmap_base;
166914dee867SHeiko Stübner 	*reg = RK2928_PULL_OFFSET;
16706ca5274dSHeiko Stübner 	*reg += bank->bank_num * RK2928_PULL_BANK_STRIDE;
167142573ab3SSebastian Reichel 	*reg += (pin_num / RK2928_PULL_PINS_PER_REG) * 4;
1672751a99abSHeiko Stübner 
1673751a99abSHeiko Stübner 	*bit = pin_num % RK2928_PULL_PINS_PER_REG;
16746ca5274dSHeiko Stübner 
16756ca5274dSHeiko Stübner 	return 0;
16766ca5274dSHeiko Stübner };
16776ca5274dSHeiko Stübner 
1678fc72c923SHeiko Stübner #define RK3128_PULL_OFFSET	0x118
167914dee867SHeiko Stübner 
rk3128_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)168014dee867SHeiko Stübner static int rk3128_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
168114dee867SHeiko Stübner 					int pin_num, struct regmap **regmap,
1682751a99abSHeiko Stübner 					int *reg, u8 *bit)
16836ca5274dSHeiko Stübner {
16846ca5274dSHeiko Stübner 	struct rockchip_pinctrl *info = bank->drvdata;
16856ca5274dSHeiko Stübner 
1686751a99abSHeiko Stübner 	*regmap = info->regmap_base;
1687751a99abSHeiko Stübner 	*reg = RK3128_PULL_OFFSET;
1688751a99abSHeiko Stübner 	*reg += bank->bank_num * RK2928_PULL_BANK_STRIDE;
1689751a99abSHeiko Stübner 	*reg += ((pin_num / RK2928_PULL_PINS_PER_REG) * 4);
1690bfc7a42aSHeiko Stübner 
1691bfc7a42aSHeiko Stübner 	*bit = pin_num % RK2928_PULL_PINS_PER_REG;
16926ca5274dSHeiko Stübner 
16936ca5274dSHeiko Stübner 	return 0;
16946ca5274dSHeiko Stübner }
16956ca5274dSHeiko Stübner 
16966ca5274dSHeiko Stübner #define RK3188_PULL_OFFSET		0x164
16976ca5274dSHeiko Stübner #define RK3188_PULL_BITS_PER_PIN	2
16986ca5274dSHeiko Stübner #define RK3188_PULL_PINS_PER_REG	8
16996ca5274dSHeiko Stübner #define RK3188_PULL_BANK_STRIDE		16
17006ca5274dSHeiko Stübner #define RK3188_PULL_PMU_OFFSET		0x64
17016ca5274dSHeiko Stübner 
rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)17026ca5274dSHeiko Stübner static int rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
170342573ab3SSebastian Reichel 					int pin_num, struct regmap **regmap,
170442573ab3SSebastian Reichel 					int *reg, u8 *bit)
17056ca5274dSHeiko Stübner {
17066ca5274dSHeiko Stübner 	struct rockchip_pinctrl *info = bank->drvdata;
1707304f077dSHeiko Stübner 
170842573ab3SSebastian Reichel 	/* The first 12 pins of the first bank are located elsewhere */
1709304f077dSHeiko Stübner 	if (bank->bank_num == 0 && pin_num < 12) {
1710304f077dSHeiko Stübner 		*regmap = info->regmap_pmu ? info->regmap_pmu
1711304f077dSHeiko Stübner 					   : bank->regmap_pull;
1712304f077dSHeiko Stübner 		*reg = info->regmap_pmu ? RK3188_PULL_PMU_OFFSET : 0;
1713304f077dSHeiko Stübner 		*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
1714304f077dSHeiko Stübner 		*bit = pin_num % RK3188_PULL_PINS_PER_REG;
1715304f077dSHeiko Stübner 		*bit *= RK3188_PULL_BITS_PER_PIN;
1716304f077dSHeiko Stübner 	} else {
1717304f077dSHeiko Stübner 		*regmap = info->regmap_pull ? info->regmap_pull
1718304f077dSHeiko Stübner 					    : info->regmap_base;
1719304f077dSHeiko Stübner 		*reg = info->regmap_pull ? 0 : RK3188_PULL_OFFSET;
1720304f077dSHeiko Stübner 
1721304f077dSHeiko Stübner 		/* correct the offset, as it is the 2nd pull register */
1722304f077dSHeiko Stübner 		*reg -= 4;
1723304f077dSHeiko Stübner 		*reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
1724304f077dSHeiko Stübner 		*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
1725304f077dSHeiko Stübner 
1726304f077dSHeiko Stübner 		/*
1727304f077dSHeiko Stübner 		 * The bits in these registers have an inverse ordering
1728304f077dSHeiko Stübner 		 * with the lowest pin being in bits 15:14 and the highest
1729304f077dSHeiko Stübner 		 * pin in bits 1:0
1730304f077dSHeiko Stübner 		 */
1731304f077dSHeiko Stübner 		*bit = 7 - (pin_num % RK3188_PULL_PINS_PER_REG);
1732304f077dSHeiko Stübner 		*bit *= RK3188_PULL_BITS_PER_PIN;
1733304f077dSHeiko Stübner 	}
173442573ab3SSebastian Reichel 
173542573ab3SSebastian Reichel 	return 0;
1736304f077dSHeiko Stübner }
1737304f077dSHeiko Stübner 
1738b547c800SHeiko Stübner #define RK3288_PULL_OFFSET		0x140
rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)1739b547c800SHeiko Stübner static int rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
1740b547c800SHeiko Stübner 					int pin_num, struct regmap **regmap,
1741b547c800SHeiko Stübner 					int *reg, u8 *bit)
1742b547c800SHeiko Stübner {
1743b547c800SHeiko Stübner 	struct rockchip_pinctrl *info = bank->drvdata;
174442573ab3SSebastian Reichel 
1745b547c800SHeiko Stübner 	/* The first 24 pins of the first bank are located in PMU */
1746b547c800SHeiko Stübner 	if (bank->bank_num == 0) {
1747b547c800SHeiko Stübner 		*regmap = info->regmap_pmu;
1748b547c800SHeiko Stübner 		*reg = RK3188_PULL_PMU_OFFSET;
1749b547c800SHeiko Stübner 
1750b547c800SHeiko Stübner 		*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
1751b547c800SHeiko Stübner 		*bit = pin_num % RK3188_PULL_PINS_PER_REG;
1752b547c800SHeiko Stübner 		*bit *= RK3188_PULL_BITS_PER_PIN;
1753b547c800SHeiko Stübner 	} else {
1754b547c800SHeiko Stübner 		*regmap = info->regmap_base;
1755b547c800SHeiko Stübner 		*reg = RK3288_PULL_OFFSET;
1756b547c800SHeiko Stübner 
1757b547c800SHeiko Stübner 		/* correct the offset, as we're starting with the 2nd bank */
1758b547c800SHeiko Stübner 		*reg -= 0x10;
1759b547c800SHeiko Stübner 		*reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
1760b547c800SHeiko Stübner 		*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
1761b547c800SHeiko Stübner 
1762b547c800SHeiko Stübner 		*bit = (pin_num % RK3188_PULL_PINS_PER_REG);
1763b547c800SHeiko Stübner 		*bit *= RK3188_PULL_BITS_PER_PIN;
1764b547c800SHeiko Stübner 	}
1765b547c800SHeiko Stübner 
1766b547c800SHeiko Stübner 	return 0;
1767b547c800SHeiko Stübner }
1768b547c800SHeiko Stübner 
1769b547c800SHeiko Stübner #define RK3288_DRV_PMU_OFFSET		0x70
177042573ab3SSebastian Reichel #define RK3288_DRV_GRF_OFFSET		0x1c0
177142573ab3SSebastian Reichel #define RK3288_DRV_BITS_PER_PIN		2
1772b547c800SHeiko Stübner #define RK3288_DRV_PINS_PER_REG		8
1773b547c800SHeiko Stübner #define RK3288_DRV_BANK_STRIDE		16
1774fea0fe60SJeffy Chen 
rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)1775fea0fe60SJeffy Chen static int rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
177642573ab3SSebastian Reichel 				       int pin_num, struct regmap **regmap,
1777fea0fe60SJeffy Chen 				       int *reg, u8 *bit)
1778fea0fe60SJeffy Chen {
1779fea0fe60SJeffy Chen 	struct rockchip_pinctrl *info = bank->drvdata;
1780fea0fe60SJeffy Chen 
1781fea0fe60SJeffy Chen 	/* The first 24 pins of the first bank are located in PMU */
1782fea0fe60SJeffy Chen 	if (bank->bank_num == 0) {
1783fea0fe60SJeffy Chen 		*regmap = info->regmap_pmu;
1784fea0fe60SJeffy Chen 		*reg = RK3288_DRV_PMU_OFFSET;
1785fea0fe60SJeffy Chen 
1786fea0fe60SJeffy Chen 		*reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
1787fea0fe60SJeffy Chen 		*bit = pin_num % RK3288_DRV_PINS_PER_REG;
1788fea0fe60SJeffy Chen 		*bit *= RK3288_DRV_BITS_PER_PIN;
178942573ab3SSebastian Reichel 	} else {
179042573ab3SSebastian Reichel 		*regmap = info->regmap_base;
1791fea0fe60SJeffy Chen 		*reg = RK3288_DRV_GRF_OFFSET;
1792fea0fe60SJeffy Chen 
1793fea0fe60SJeffy Chen 		/* correct the offset, as we're starting with the 2nd bank */
1794fea0fe60SJeffy Chen 		*reg -= 0x10;
179542573ab3SSebastian Reichel 		*reg += bank->bank_num * RK3288_DRV_BANK_STRIDE;
1796fea0fe60SJeffy Chen 		*reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
1797fea0fe60SJeffy Chen 
1798fea0fe60SJeffy Chen 		*bit = (pin_num % RK3288_DRV_PINS_PER_REG);
1799fea0fe60SJeffy Chen 		*bit *= RK3288_DRV_BITS_PER_PIN;
1800fea0fe60SJeffy Chen 	}
1801fea0fe60SJeffy Chen 
1802fea0fe60SJeffy Chen 	return 0;
1803fea0fe60SJeffy Chen }
1804fea0fe60SJeffy Chen 
1805fea0fe60SJeffy Chen #define RK3228_PULL_OFFSET		0x100
1806fea0fe60SJeffy Chen 
rk3228_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)1807fea0fe60SJeffy Chen static int rk3228_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
180842573ab3SSebastian Reichel 					int pin_num, struct regmap **regmap,
180942573ab3SSebastian Reichel 					int *reg, u8 *bit)
1810fea0fe60SJeffy Chen {
1811fea0fe60SJeffy Chen 	struct rockchip_pinctrl *info = bank->drvdata;
18127825aeb7SJianqun Xu 
18137825aeb7SJianqun Xu 	*regmap = info->regmap_base;
181442573ab3SSebastian Reichel 	*reg = RK3228_PULL_OFFSET;
18157825aeb7SJianqun Xu 	*reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
18167825aeb7SJianqun Xu 	*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
18177825aeb7SJianqun Xu 
18187825aeb7SJianqun Xu 	*bit = (pin_num % RK3188_PULL_PINS_PER_REG);
18197825aeb7SJianqun Xu 	*bit *= RK3188_PULL_BITS_PER_PIN;
18207825aeb7SJianqun Xu 
18217825aeb7SJianqun Xu 	return 0;
18227825aeb7SJianqun Xu }
18237825aeb7SJianqun Xu 
18247825aeb7SJianqun Xu #define RK3228_DRV_GRF_OFFSET		0x200
18257825aeb7SJianqun Xu 
rk3228_calc_drv_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)18267825aeb7SJianqun Xu static int rk3228_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
182742573ab3SSebastian Reichel 				       int pin_num, struct regmap **regmap,
182842573ab3SSebastian Reichel 				       int *reg, u8 *bit)
18297825aeb7SJianqun Xu {
18307825aeb7SJianqun Xu 	struct rockchip_pinctrl *info = bank->drvdata;
18317825aeb7SJianqun Xu 
18327825aeb7SJianqun Xu 	*regmap = info->regmap_base;
183342573ab3SSebastian Reichel 	*reg = RK3228_DRV_GRF_OFFSET;
18347825aeb7SJianqun Xu 	*reg += bank->bank_num * RK3288_DRV_BANK_STRIDE;
18357825aeb7SJianqun Xu 	*reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
18367825aeb7SJianqun Xu 
18377825aeb7SJianqun Xu 	*bit = (pin_num % RK3288_DRV_PINS_PER_REG);
18387825aeb7SJianqun Xu 	*bit *= RK3288_DRV_BITS_PER_PIN;
18397825aeb7SJianqun Xu 
18407825aeb7SJianqun Xu 	return 0;
18417825aeb7SJianqun Xu }
18427825aeb7SJianqun Xu 
18437825aeb7SJianqun Xu #define RK3308_PULL_OFFSET		0xa0
18447825aeb7SJianqun Xu 
rk3308_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)18457825aeb7SJianqun Xu static int rk3308_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
184642573ab3SSebastian Reichel 					int pin_num, struct regmap **regmap,
184742573ab3SSebastian Reichel 					int *reg, u8 *bit)
18487825aeb7SJianqun Xu {
18497825aeb7SJianqun Xu 	struct rockchip_pinctrl *info = bank->drvdata;
1850daecdc66SHeiko Stübner 
1851daecdc66SHeiko Stübner 	*regmap = info->regmap_base;
1852daecdc66SHeiko Stübner 	*reg = RK3308_PULL_OFFSET;
185342573ab3SSebastian Reichel 	*reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
1854daecdc66SHeiko Stübner 	*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
1855daecdc66SHeiko Stübner 
1856daecdc66SHeiko Stübner 	*bit = (pin_num % RK3188_PULL_PINS_PER_REG);
1857daecdc66SHeiko Stübner 	*bit *= RK3188_PULL_BITS_PER_PIN;
1858daecdc66SHeiko Stübner 
1859daecdc66SHeiko Stübner 	return 0;
1860daecdc66SHeiko Stübner }
1861daecdc66SHeiko Stübner 
1862daecdc66SHeiko Stübner #define RK3308_DRV_GRF_OFFSET		0x100
1863daecdc66SHeiko Stübner 
rk3308_calc_drv_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)1864daecdc66SHeiko Stübner static int rk3308_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
1865daecdc66SHeiko Stübner 				       int pin_num, struct regmap **regmap,
1866daecdc66SHeiko Stübner 				       int *reg, u8 *bit)
1867daecdc66SHeiko Stübner {
1868daecdc66SHeiko Stübner 	struct rockchip_pinctrl *info = bank->drvdata;
1869daecdc66SHeiko Stübner 
1870daecdc66SHeiko Stübner 	*regmap = info->regmap_base;
1871daecdc66SHeiko Stübner 	*reg = RK3308_DRV_GRF_OFFSET;
1872daecdc66SHeiko Stübner 	*reg += bank->bank_num * RK3288_DRV_BANK_STRIDE;
1873daecdc66SHeiko Stübner 	*reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
1874daecdc66SHeiko Stübner 
1875daecdc66SHeiko Stübner 	*bit = (pin_num % RK3288_DRV_PINS_PER_REG);
1876daecdc66SHeiko Stübner 	*bit *= RK3288_DRV_BITS_PER_PIN;
1877daecdc66SHeiko Stübner 
1878daecdc66SHeiko Stübner 	return 0;
187942573ab3SSebastian Reichel }
188042573ab3SSebastian Reichel 
1881daecdc66SHeiko Stübner #define RK3368_PULL_GRF_OFFSET		0x100
1882daecdc66SHeiko Stübner #define RK3368_PULL_PMU_OFFSET		0x10
1883daecdc66SHeiko Stübner 
rk3368_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)1884daecdc66SHeiko Stübner static int rk3368_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
1885daecdc66SHeiko Stübner 					int pin_num, struct regmap **regmap,
188642573ab3SSebastian Reichel 					int *reg, u8 *bit)
1887daecdc66SHeiko Stübner {
1888daecdc66SHeiko Stübner 	struct rockchip_pinctrl *info = bank->drvdata;
1889daecdc66SHeiko Stübner 
1890daecdc66SHeiko Stübner 	/* The first 32 pins of the first bank are located in PMU */
1891daecdc66SHeiko Stübner 	if (bank->bank_num == 0) {
1892daecdc66SHeiko Stübner 		*regmap = info->regmap_pmu;
1893daecdc66SHeiko Stübner 		*reg = RK3368_PULL_PMU_OFFSET;
1894daecdc66SHeiko Stübner 
1895daecdc66SHeiko Stübner 		*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
1896daecdc66SHeiko Stübner 		*bit = pin_num % RK3188_PULL_PINS_PER_REG;
1897daecdc66SHeiko Stübner 		*bit *= RK3188_PULL_BITS_PER_PIN;
1898daecdc66SHeiko Stübner 	} else {
1899daecdc66SHeiko Stübner 		*regmap = info->regmap_base;
1900daecdc66SHeiko Stübner 		*reg = RK3368_PULL_GRF_OFFSET;
1901daecdc66SHeiko Stübner 
1902daecdc66SHeiko Stübner 		/* correct the offset, as we're starting with the 2nd bank */
1903daecdc66SHeiko Stübner 		*reg -= 0x10;
1904daecdc66SHeiko Stübner 		*reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
1905daecdc66SHeiko Stübner 		*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
1906daecdc66SHeiko Stübner 
1907daecdc66SHeiko Stübner 		*bit = (pin_num % RK3188_PULL_PINS_PER_REG);
1908daecdc66SHeiko Stübner 		*bit *= RK3188_PULL_BITS_PER_PIN;
1909daecdc66SHeiko Stübner 	}
1910daecdc66SHeiko Stübner 
1911daecdc66SHeiko Stübner 	return 0;
191242573ab3SSebastian Reichel }
191342573ab3SSebastian Reichel 
1914daecdc66SHeiko Stübner #define RK3368_DRV_PMU_OFFSET		0x20
1915daecdc66SHeiko Stübner #define RK3368_DRV_GRF_OFFSET		0x200
1916b6c23275SDavid Wu 
rk3368_calc_drv_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)1917b6c23275SDavid Wu static int rk3368_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
1918b6c23275SDavid Wu 				       int pin_num, struct regmap **regmap,
1919b6c23275SDavid Wu 				       int *reg, u8 *bit)
192042573ab3SSebastian Reichel {
1921b6c23275SDavid Wu 	struct rockchip_pinctrl *info = bank->drvdata;
1922b6c23275SDavid Wu 
1923b6c23275SDavid Wu 	/* The first 32 pins of the first bank are located in PMU */
1924b6c23275SDavid Wu 	if (bank->bank_num == 0) {
1925b6c23275SDavid Wu 		*regmap = info->regmap_pmu;
1926b6c23275SDavid Wu 		*reg = RK3368_DRV_PMU_OFFSET;
1927b6c23275SDavid Wu 
1928b6c23275SDavid Wu 		*reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
1929b6c23275SDavid Wu 		*bit = pin_num % RK3288_DRV_PINS_PER_REG;
1930b6c23275SDavid Wu 		*bit *= RK3288_DRV_BITS_PER_PIN;
1931b6c23275SDavid Wu 	} else {
1932b6c23275SDavid Wu 		*regmap = info->regmap_base;
1933b6c23275SDavid Wu 		*reg = RK3368_DRV_GRF_OFFSET;
1934b6c23275SDavid Wu 
1935b6c23275SDavid Wu 		/* correct the offset, as we're starting with the 2nd bank */
1936b6c23275SDavid Wu 		*reg -= 0x10;
1937b6c23275SDavid Wu 		*reg += bank->bank_num * RK3288_DRV_BANK_STRIDE;
1938b6c23275SDavid Wu 		*reg += ((pin_num / RK3288_DRV_PINS_PER_REG) * 4);
1939b6c23275SDavid Wu 
1940b6c23275SDavid Wu 		*bit = (pin_num % RK3288_DRV_PINS_PER_REG);
1941b6c23275SDavid Wu 		*bit *= RK3288_DRV_BITS_PER_PIN;
1942b6c23275SDavid Wu 	}
1943b6c23275SDavid Wu 
1944b6c23275SDavid Wu 	return 0;
1945b6c23275SDavid Wu }
1946b6c23275SDavid Wu 
1947b6c23275SDavid Wu #define RK3399_PULL_GRF_OFFSET		0xe040
194842573ab3SSebastian Reichel #define RK3399_PULL_PMU_OFFSET		0x40
194942573ab3SSebastian Reichel #define RK3399_DRV_3BITS_PER_PIN	3
1950b6c23275SDavid Wu 
rk3399_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)1951b6c23275SDavid Wu static int rk3399_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
195242573ab3SSebastian Reichel 					int pin_num, struct regmap **regmap,
1953b6c23275SDavid Wu 					int *reg, u8 *bit)
1954b6c23275SDavid Wu {
1955b6c23275SDavid Wu 	struct rockchip_pinctrl *info = bank->drvdata;
1956b6c23275SDavid Wu 
1957b6c23275SDavid Wu 	/* The bank0:16 and bank1:32 pins are located in PMU */
1958b6c23275SDavid Wu 	if ((bank->bank_num == 0) || (bank->bank_num == 1)) {
1959b6c23275SDavid Wu 		*regmap = info->regmap_pmu;
1960b6c23275SDavid Wu 		*reg = RK3399_PULL_PMU_OFFSET;
1961b6c23275SDavid Wu 
1962b6c23275SDavid Wu 		*reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
1963b6c23275SDavid Wu 
1964b6c23275SDavid Wu 		*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
1965b6c23275SDavid Wu 		*bit = pin_num % RK3188_PULL_PINS_PER_REG;
1966b6c23275SDavid Wu 		*bit *= RK3188_PULL_BITS_PER_PIN;
1967b6c23275SDavid Wu 	} else {
1968b6c23275SDavid Wu 		*regmap = info->regmap_base;
1969b6c23275SDavid Wu 		*reg = RK3399_PULL_GRF_OFFSET;
1970b6c23275SDavid Wu 
197142573ab3SSebastian Reichel 		/* correct the offset, as we're starting with the 3rd bank */
197242573ab3SSebastian Reichel 		*reg -= 0x20;
1973b6c23275SDavid Wu 		*reg += bank->bank_num * RK3188_PULL_BANK_STRIDE;
1974b6c23275SDavid Wu 		*reg += ((pin_num / RK3188_PULL_PINS_PER_REG) * 4);
1975c0dadc0eSJianqun Xu 
1976c0dadc0eSJianqun Xu 		*bit = (pin_num % RK3188_PULL_PINS_PER_REG);
1977c0dadc0eSJianqun Xu 		*bit *= RK3188_PULL_BITS_PER_PIN;
1978c0dadc0eSJianqun Xu 	}
1979c0dadc0eSJianqun Xu 
1980c0dadc0eSJianqun Xu 	return 0;
198142573ab3SSebastian Reichel }
1982c0dadc0eSJianqun Xu 
rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)1983c0dadc0eSJianqun Xu static int rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
1984c0dadc0eSJianqun Xu 				       int pin_num, struct regmap **regmap,
1985c0dadc0eSJianqun Xu 				       int *reg, u8 *bit)
1986c0dadc0eSJianqun Xu {
1987c0dadc0eSJianqun Xu 	struct rockchip_pinctrl *info = bank->drvdata;
1988c0dadc0eSJianqun Xu 	int drv_num = (pin_num / 8);
1989c0dadc0eSJianqun Xu 
1990c0dadc0eSJianqun Xu 	/*  The bank0:16 and bank1:32 pins are located in PMU */
1991c0dadc0eSJianqun Xu 	if ((bank->bank_num == 0) || (bank->bank_num == 1))
1992c0dadc0eSJianqun Xu 		*regmap = info->regmap_pmu;
1993c0dadc0eSJianqun Xu 	else
1994c0dadc0eSJianqun Xu 		*regmap = info->regmap_base;
1995c0dadc0eSJianqun Xu 
1996c0dadc0eSJianqun Xu 	*reg = bank->drv[drv_num].offset;
1997c0dadc0eSJianqun Xu 	if ((bank->drv[drv_num].drv_type == DRV_TYPE_IO_1V8_3V0_AUTO) ||
1998c0dadc0eSJianqun Xu 	    (bank->drv[drv_num].drv_type == DRV_TYPE_IO_3V3_ONLY))
1999c0dadc0eSJianqun Xu 		*bit = (pin_num % 8) * 3;
2000c0dadc0eSJianqun Xu 	else
2001c0dadc0eSJianqun Xu 		*bit = (pin_num % 8) * 2;
2002c0dadc0eSJianqun Xu 
2003c0dadc0eSJianqun Xu 	return 0;
200442573ab3SSebastian Reichel }
200542573ab3SSebastian Reichel 
2006c0dadc0eSJianqun Xu #define RK3568_PULL_PMU_OFFSET		0x20
2007c0dadc0eSJianqun Xu #define RK3568_PULL_GRF_OFFSET		0x80
2008c0dadc0eSJianqun Xu #define RK3568_PULL_BITS_PER_PIN	2
2009c0dadc0eSJianqun Xu #define RK3568_PULL_PINS_PER_REG	8
2010c0dadc0eSJianqun Xu #define RK3568_PULL_BANK_STRIDE		0x10
2011c0dadc0eSJianqun Xu 
rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)2012c0dadc0eSJianqun Xu static int rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
2013c0dadc0eSJianqun Xu 					int pin_num, struct regmap **regmap,
201442573ab3SSebastian Reichel 					int *reg, u8 *bit)
2015c0dadc0eSJianqun Xu {
2016c0dadc0eSJianqun Xu 	struct rockchip_pinctrl *info = bank->drvdata;
2017c0dadc0eSJianqun Xu 
2018c0dadc0eSJianqun Xu 	if (bank->bank_num == 0) {
2019c0dadc0eSJianqun Xu 		*regmap = info->regmap_pmu;
2020c0dadc0eSJianqun Xu 		*reg = RK3568_PULL_PMU_OFFSET;
2021c0dadc0eSJianqun Xu 		*reg += bank->bank_num * RK3568_PULL_BANK_STRIDE;
2022c0dadc0eSJianqun Xu 		*reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4);
2023c0dadc0eSJianqun Xu 
2024c0dadc0eSJianqun Xu 		*bit = pin_num % RK3568_PULL_PINS_PER_REG;
2025c0dadc0eSJianqun Xu 		*bit *= RK3568_PULL_BITS_PER_PIN;
2026c0dadc0eSJianqun Xu 	} else {
2027c0dadc0eSJianqun Xu 		*regmap = info->regmap_base;
2028c0dadc0eSJianqun Xu 		*reg = RK3568_PULL_GRF_OFFSET;
2029c0dadc0eSJianqun Xu 		*reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE;
2030c0dadc0eSJianqun Xu 		*reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4);
2031c0dadc0eSJianqun Xu 
2032c0dadc0eSJianqun Xu 		*bit = (pin_num % RK3568_PULL_PINS_PER_REG);
2033c0dadc0eSJianqun Xu 		*bit *= RK3568_PULL_BITS_PER_PIN;
2034c0dadc0eSJianqun Xu 	}
2035c0dadc0eSJianqun Xu 
2036c0dadc0eSJianqun Xu 	return 0;
203742573ab3SSebastian Reichel }
203842573ab3SSebastian Reichel 
2039c0dadc0eSJianqun Xu #define RK3568_DRV_PMU_OFFSET		0x70
2040c0dadc0eSJianqun Xu #define RK3568_DRV_GRF_OFFSET		0x200
2041fdc33ebaSJianqun Xu #define RK3568_DRV_BITS_PER_PIN		8
2042fdc33ebaSJianqun Xu #define RK3568_DRV_PINS_PER_REG		2
2043fdc33ebaSJianqun Xu #define RK3568_DRV_BANK_STRIDE		0x40
2044fdc33ebaSJianqun Xu 
rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)2045fdc33ebaSJianqun Xu static int rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
2046fdc33ebaSJianqun Xu 				       int pin_num, struct regmap **regmap,
2047fdc33ebaSJianqun Xu 				       int *reg, u8 *bit)
2048fdc33ebaSJianqun Xu {
2049fdc33ebaSJianqun Xu 	struct rockchip_pinctrl *info = bank->drvdata;
2050fdc33ebaSJianqun Xu 
2051fdc33ebaSJianqun Xu 	/* The first 32 pins of the first bank are located in PMU */
2052fdc33ebaSJianqun Xu 	if (bank->bank_num == 0) {
2053fdc33ebaSJianqun Xu 		*regmap = info->regmap_pmu;
2054fdc33ebaSJianqun Xu 		*reg = RK3568_DRV_PMU_OFFSET;
2055fdc33ebaSJianqun Xu 		*reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4);
2056fdc33ebaSJianqun Xu 
2057fdc33ebaSJianqun Xu 		*bit = pin_num % RK3568_DRV_PINS_PER_REG;
2058fdc33ebaSJianqun Xu 		*bit *= RK3568_DRV_BITS_PER_PIN;
2059fdc33ebaSJianqun Xu 	} else {
2060fdc33ebaSJianqun Xu 		*regmap = info->regmap_base;
2061fdc33ebaSJianqun Xu 		*reg = RK3568_DRV_GRF_OFFSET;
2062fdc33ebaSJianqun Xu 		*reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE;
2063fdc33ebaSJianqun Xu 		*reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4);
2064fdc33ebaSJianqun Xu 
2065fdc33ebaSJianqun Xu 		*bit = (pin_num % RK3568_DRV_PINS_PER_REG);
2066fdc33ebaSJianqun Xu 		*bit *= RK3568_DRV_BITS_PER_PIN;
2067fdc33ebaSJianqun Xu 	}
2068fdc33ebaSJianqun Xu 
2069fdc33ebaSJianqun Xu 	return 0;
2070fdc33ebaSJianqun Xu }
2071fdc33ebaSJianqun Xu 
2072fdc33ebaSJianqun Xu #define RK3576_DRV_BITS_PER_PIN		4
2073fdc33ebaSJianqun Xu #define RK3576_DRV_PINS_PER_REG		4
2074fdc33ebaSJianqun Xu #define RK3576_DRV_GPIO0_AL_OFFSET	0x10
2075fdc33ebaSJianqun Xu #define RK3576_DRV_GPIO0_BH_OFFSET	0x2014
2076fdc33ebaSJianqun Xu #define RK3576_DRV_GPIO1_OFFSET		0x6020
2077fdc33ebaSJianqun Xu #define RK3576_DRV_GPIO2_OFFSET		0x6040
2078fdc33ebaSJianqun Xu #define RK3576_DRV_GPIO3_OFFSET		0x6060
2079fdc33ebaSJianqun Xu #define RK3576_DRV_GPIO4_AL_OFFSET	0x6080
2080fdc33ebaSJianqun Xu #define RK3576_DRV_GPIO4_CL_OFFSET	0xA090
2081fdc33ebaSJianqun Xu #define RK3576_DRV_GPIO4_DL_OFFSET	0xB098
2082fdc33ebaSJianqun Xu 
rk3576_calc_drv_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)2083fdc33ebaSJianqun Xu static int rk3576_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
2084fdc33ebaSJianqun Xu 					int pin_num, struct regmap **regmap,
2085fdc33ebaSJianqun Xu 					int *reg, u8 *bit)
2086fdc33ebaSJianqun Xu {
2087fdc33ebaSJianqun Xu 	struct rockchip_pinctrl *info = bank->drvdata;
2088fdc33ebaSJianqun Xu 
2089fdc33ebaSJianqun Xu 	*regmap = info->regmap_base;
2090fdc33ebaSJianqun Xu 
2091fdc33ebaSJianqun Xu 	if (bank->bank_num == 0 && pin_num < 12)
2092fdc33ebaSJianqun Xu 		*reg = RK3576_DRV_GPIO0_AL_OFFSET;
2093fdc33ebaSJianqun Xu 	else if (bank->bank_num == 0)
2094fdc33ebaSJianqun Xu 		*reg = RK3576_DRV_GPIO0_BH_OFFSET - 0xc;
2095fdc33ebaSJianqun Xu 	else if (bank->bank_num == 1)
2096fdc33ebaSJianqun Xu 		*reg = RK3576_DRV_GPIO1_OFFSET;
2097fdc33ebaSJianqun Xu 	else if (bank->bank_num == 2)
2098fdc33ebaSJianqun Xu 		*reg = RK3576_DRV_GPIO2_OFFSET;
2099fdc33ebaSJianqun Xu 	else if (bank->bank_num == 3)
2100fdc33ebaSJianqun Xu 		*reg = RK3576_DRV_GPIO3_OFFSET;
2101fdc33ebaSJianqun Xu 	else if (bank->bank_num == 4 && pin_num < 16)
2102fdc33ebaSJianqun Xu 		*reg = RK3576_DRV_GPIO4_AL_OFFSET;
2103fdc33ebaSJianqun Xu 	else if (bank->bank_num == 4 && pin_num < 24)
2104fdc33ebaSJianqun Xu 		*reg = RK3576_DRV_GPIO4_CL_OFFSET - 0x10;
2105fdc33ebaSJianqun Xu 	else if (bank->bank_num == 4)
2106fdc33ebaSJianqun Xu 		*reg = RK3576_DRV_GPIO4_DL_OFFSET - 0x18;
2107fdc33ebaSJianqun Xu 	else
2108fdc33ebaSJianqun Xu 		dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num);
2109fdc33ebaSJianqun Xu 
2110fdc33ebaSJianqun Xu 	*reg += ((pin_num / RK3576_DRV_PINS_PER_REG) * 4);
2111fdc33ebaSJianqun Xu 	*bit = pin_num % RK3576_DRV_PINS_PER_REG;
2112fdc33ebaSJianqun Xu 	*bit *= RK3576_DRV_BITS_PER_PIN;
2113fdc33ebaSJianqun Xu 
2114fdc33ebaSJianqun Xu 	return 0;
2115fdc33ebaSJianqun Xu }
2116fdc33ebaSJianqun Xu 
2117fdc33ebaSJianqun Xu #define RK3576_PULL_BITS_PER_PIN	2
2118fdc33ebaSJianqun Xu #define RK3576_PULL_PINS_PER_REG	8
2119fdc33ebaSJianqun Xu #define RK3576_PULL_GPIO0_AL_OFFSET	0x20
2120fdc33ebaSJianqun Xu #define RK3576_PULL_GPIO0_BH_OFFSET	0x2028
2121fdc33ebaSJianqun Xu #define RK3576_PULL_GPIO1_OFFSET	0x6110
2122fdc33ebaSJianqun Xu #define RK3576_PULL_GPIO2_OFFSET	0x6120
2123fdc33ebaSJianqun Xu #define RK3576_PULL_GPIO3_OFFSET	0x6130
2124fdc33ebaSJianqun Xu #define RK3576_PULL_GPIO4_AL_OFFSET	0x6140
2125fdc33ebaSJianqun Xu #define RK3576_PULL_GPIO4_CL_OFFSET	0xA148
2126fdc33ebaSJianqun Xu #define RK3576_PULL_GPIO4_DL_OFFSET	0xB14C
2127fdc33ebaSJianqun Xu 
rk3576_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)2128fdc33ebaSJianqun Xu static int rk3576_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
2129fdc33ebaSJianqun Xu 					 int pin_num, struct regmap **regmap,
2130fdc33ebaSJianqun Xu 					 int *reg, u8 *bit)
2131fdc33ebaSJianqun Xu {
2132fdc33ebaSJianqun Xu 	struct rockchip_pinctrl *info = bank->drvdata;
2133fdc33ebaSJianqun Xu 
2134fdc33ebaSJianqun Xu 	*regmap = info->regmap_base;
2135fdc33ebaSJianqun Xu 
2136fdc33ebaSJianqun Xu 	if (bank->bank_num == 0 && pin_num < 12)
2137fdc33ebaSJianqun Xu 		*reg = RK3576_PULL_GPIO0_AL_OFFSET;
2138fdc33ebaSJianqun Xu 	else if (bank->bank_num == 0)
2139fdc33ebaSJianqun Xu 		*reg = RK3576_PULL_GPIO0_BH_OFFSET - 0x4;
2140fdc33ebaSJianqun Xu 	else if (bank->bank_num == 1)
2141fdc33ebaSJianqun Xu 		*reg = RK3576_PULL_GPIO1_OFFSET;
2142fdc33ebaSJianqun Xu 	else if (bank->bank_num == 2)
2143fdc33ebaSJianqun Xu 		*reg = RK3576_PULL_GPIO2_OFFSET;
2144fdc33ebaSJianqun Xu 	else if (bank->bank_num == 3)
2145fdc33ebaSJianqun Xu 		*reg = RK3576_PULL_GPIO3_OFFSET;
2146fdc33ebaSJianqun Xu 	else if (bank->bank_num == 4 && pin_num < 16)
2147fdc33ebaSJianqun Xu 		*reg = RK3576_PULL_GPIO4_AL_OFFSET;
2148fdc33ebaSJianqun Xu 	else if (bank->bank_num == 4 && pin_num < 24)
2149fdc33ebaSJianqun Xu 		*reg = RK3576_PULL_GPIO4_CL_OFFSET - 0x8;
2150fdc33ebaSJianqun Xu 	else if (bank->bank_num == 4)
2151fdc33ebaSJianqun Xu 		*reg = RK3576_PULL_GPIO4_DL_OFFSET - 0xc;
2152fdc33ebaSJianqun Xu 	else
2153fdc33ebaSJianqun Xu 		dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num);
2154fdc33ebaSJianqun Xu 
2155fdc33ebaSJianqun Xu 	*reg += ((pin_num / RK3576_PULL_PINS_PER_REG) * 4);
2156fdc33ebaSJianqun Xu 	*bit = pin_num % RK3576_PULL_PINS_PER_REG;
2157fdc33ebaSJianqun Xu 	*bit *= RK3576_PULL_BITS_PER_PIN;
2158fdc33ebaSJianqun Xu 
2159fdc33ebaSJianqun Xu 	return 0;
2160fdc33ebaSJianqun Xu }
2161fdc33ebaSJianqun Xu 
2162fdc33ebaSJianqun Xu #define RK3576_SMT_BITS_PER_PIN		1
2163fdc33ebaSJianqun Xu #define RK3576_SMT_PINS_PER_REG		8
2164fdc33ebaSJianqun Xu #define RK3576_SMT_GPIO0_AL_OFFSET	0x30
2165fdc33ebaSJianqun Xu #define RK3576_SMT_GPIO0_BH_OFFSET	0x2040
2166fdc33ebaSJianqun Xu #define RK3576_SMT_GPIO1_OFFSET		0x6210
2167fdc33ebaSJianqun Xu #define RK3576_SMT_GPIO2_OFFSET		0x6220
2168fdc33ebaSJianqun Xu #define RK3576_SMT_GPIO3_OFFSET		0x6230
2169fdc33ebaSJianqun Xu #define RK3576_SMT_GPIO4_AL_OFFSET	0x6240
2170fdc33ebaSJianqun Xu #define RK3576_SMT_GPIO4_CL_OFFSET	0xA248
2171fdc33ebaSJianqun Xu #define RK3576_SMT_GPIO4_DL_OFFSET	0xB24C
2172fdc33ebaSJianqun Xu 
rk3576_calc_schmitt_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)2173fdc33ebaSJianqun Xu static int rk3576_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
2174fdc33ebaSJianqun Xu 					   int pin_num,
2175fdc33ebaSJianqun Xu 					   struct regmap **regmap,
2176fdc33ebaSJianqun Xu 					   int *reg, u8 *bit)
2177fdc33ebaSJianqun Xu {
2178fdc33ebaSJianqun Xu 	struct rockchip_pinctrl *info = bank->drvdata;
2179fdc33ebaSJianqun Xu 
2180fdc33ebaSJianqun Xu 	*regmap = info->regmap_base;
2181fdc33ebaSJianqun Xu 
2182fdc33ebaSJianqun Xu 	if (bank->bank_num == 0 && pin_num < 12)
2183fdc33ebaSJianqun Xu 		*reg = RK3576_SMT_GPIO0_AL_OFFSET;
2184fdc33ebaSJianqun Xu 	else if (bank->bank_num == 0)
2185fdc33ebaSJianqun Xu 		*reg = RK3576_SMT_GPIO0_BH_OFFSET - 0x4;
2186fdc33ebaSJianqun Xu 	else if (bank->bank_num == 1)
2187fdc33ebaSJianqun Xu 		*reg = RK3576_SMT_GPIO1_OFFSET;
2188fdc33ebaSJianqun Xu 	else if (bank->bank_num == 2)
2189fdc33ebaSJianqun Xu 		*reg = RK3576_SMT_GPIO2_OFFSET;
2190fdc33ebaSJianqun Xu 	else if (bank->bank_num == 3)
2191fdc33ebaSJianqun Xu 		*reg = RK3576_SMT_GPIO3_OFFSET;
2192fdc33ebaSJianqun Xu 	else if (bank->bank_num == 4 && pin_num < 16)
2193fdc33ebaSJianqun Xu 		*reg = RK3576_SMT_GPIO4_AL_OFFSET;
2194fdc33ebaSJianqun Xu 	else if (bank->bank_num == 4 && pin_num < 24)
2195fdc33ebaSJianqun Xu 		*reg = RK3576_SMT_GPIO4_CL_OFFSET - 0x8;
2196fdc33ebaSJianqun Xu 	else if (bank->bank_num == 4)
2197fdc33ebaSJianqun Xu 		*reg = RK3576_SMT_GPIO4_DL_OFFSET - 0xc;
2198fdc33ebaSJianqun Xu 	else
2199fdc33ebaSJianqun Xu 		dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num);
2200fdc33ebaSJianqun Xu 
2201fdc33ebaSJianqun Xu 	*reg += ((pin_num / RK3576_SMT_PINS_PER_REG) * 4);
2202fdc33ebaSJianqun Xu 	*bit = pin_num % RK3576_SMT_PINS_PER_REG;
2203fdc33ebaSJianqun Xu 	*bit *= RK3576_SMT_BITS_PER_PIN;
2204fdc33ebaSJianqun Xu 
2205fdc33ebaSJianqun Xu 	return 0;
2206fdc33ebaSJianqun Xu }
2207fdc33ebaSJianqun Xu 
2208fdc33ebaSJianqun Xu #define RK3588_PMU1_IOC_REG		(0x0000)
2209fdc33ebaSJianqun Xu #define RK3588_PMU2_IOC_REG		(0x4000)
2210fdc33ebaSJianqun Xu #define RK3588_BUS_IOC_REG		(0x8000)
2211fdc33ebaSJianqun Xu #define RK3588_VCCIO1_4_IOC_REG		(0x9000)
2212fdc33ebaSJianqun Xu #define RK3588_VCCIO3_5_IOC_REG		(0xA000)
2213fdc33ebaSJianqun Xu #define RK3588_VCCIO2_IOC_REG		(0xB000)
2214fdc33ebaSJianqun Xu #define RK3588_VCCIO6_IOC_REG		(0xC000)
2215fdc33ebaSJianqun Xu #define RK3588_EMMC_IOC_REG		(0xD000)
2216fdc33ebaSJianqun Xu 
2217fdc33ebaSJianqun Xu static const u32 rk3588_ds_regs[][2] = {
2218fdc33ebaSJianqun Xu 	{RK_GPIO0_A0, RK3588_PMU1_IOC_REG + 0x0010},
2219fdc33ebaSJianqun Xu 	{RK_GPIO0_A4, RK3588_PMU1_IOC_REG + 0x0014},
2220fdc33ebaSJianqun Xu 	{RK_GPIO0_B0, RK3588_PMU1_IOC_REG + 0x0018},
2221fdc33ebaSJianqun Xu 	{RK_GPIO0_B4, RK3588_PMU2_IOC_REG + 0x0014},
2222b6c23275SDavid Wu 	{RK_GPIO0_C0, RK3588_PMU2_IOC_REG + 0x0018},
2223b6c23275SDavid Wu 	{RK_GPIO0_C4, RK3588_PMU2_IOC_REG + 0x001C},
2224b6c23275SDavid Wu 	{RK_GPIO0_D0, RK3588_PMU2_IOC_REG + 0x0020},
2225b6c23275SDavid Wu 	{RK_GPIO0_D4, RK3588_PMU2_IOC_REG + 0x0024},
2226b6c23275SDavid Wu 	{RK_GPIO1_A0, RK3588_VCCIO1_4_IOC_REG + 0x0020},
2227b6c23275SDavid Wu 	{RK_GPIO1_A4, RK3588_VCCIO1_4_IOC_REG + 0x0024},
2228b6c23275SDavid Wu 	{RK_GPIO1_B0, RK3588_VCCIO1_4_IOC_REG + 0x0028},
2229ef17f69fSHeiko Stübner 	{RK_GPIO1_B4, RK3588_VCCIO1_4_IOC_REG + 0x002C},
2230ef17f69fSHeiko Stübner 	{RK_GPIO1_C0, RK3588_VCCIO1_4_IOC_REG + 0x0030},
2231ef17f69fSHeiko Stübner 	{RK_GPIO1_C4, RK3588_VCCIO1_4_IOC_REG + 0x0034},
2232b547c800SHeiko Stübner 	{RK_GPIO1_D0, RK3588_VCCIO1_4_IOC_REG + 0x0038},
2233ef17f69fSHeiko Stübner 	{RK_GPIO1_D4, RK3588_VCCIO1_4_IOC_REG + 0x003C},
2234ef17f69fSHeiko Stübner 	{RK_GPIO2_A0, RK3588_EMMC_IOC_REG + 0x0040},
2235e4dd7fd5SAndy Shevchenko 	{RK_GPIO2_A4, RK3588_VCCIO3_5_IOC_REG + 0x0044},
2236b547c800SHeiko Stübner 	{RK_GPIO2_B0, RK3588_VCCIO3_5_IOC_REG + 0x0048},
2237b547c800SHeiko Stübner 	{RK_GPIO2_B4, RK3588_VCCIO3_5_IOC_REG + 0x004C},
2238b6c23275SDavid Wu 	{RK_GPIO2_C0, RK3588_VCCIO3_5_IOC_REG + 0x0050},
2239b547c800SHeiko Stübner 	{RK_GPIO2_C4, RK3588_VCCIO3_5_IOC_REG + 0x0054},
2240b6c23275SDavid Wu 	{RK_GPIO2_D0, RK3588_EMMC_IOC_REG + 0x0058},
2241b547c800SHeiko Stübner 	{RK_GPIO2_D4, RK3588_EMMC_IOC_REG + 0x005C},
224242573ab3SSebastian Reichel 	{RK_GPIO3_A0, RK3588_VCCIO3_5_IOC_REG + 0x0060},
224342573ab3SSebastian Reichel 	{RK_GPIO3_A4, RK3588_VCCIO3_5_IOC_REG + 0x0064},
224442573ab3SSebastian Reichel 	{RK_GPIO3_B0, RK3588_VCCIO3_5_IOC_REG + 0x0068},
2245b547c800SHeiko Stübner 	{RK_GPIO3_B4, RK3588_VCCIO3_5_IOC_REG + 0x006C},
2246b6c23275SDavid Wu 	{RK_GPIO3_C0, RK3588_VCCIO3_5_IOC_REG + 0x0070},
2247b6c23275SDavid Wu 	{RK_GPIO3_C4, RK3588_VCCIO3_5_IOC_REG + 0x0074},
2248b6c23275SDavid Wu 	{RK_GPIO3_D0, RK3588_VCCIO3_5_IOC_REG + 0x0078},
2249b6c23275SDavid Wu 	{RK_GPIO3_D4, RK3588_VCCIO3_5_IOC_REG + 0x007C},
2250b6c23275SDavid Wu 	{RK_GPIO4_A0, RK3588_VCCIO6_IOC_REG + 0x0080},
2251b6c23275SDavid Wu 	{RK_GPIO4_A4, RK3588_VCCIO6_IOC_REG + 0x0084},
2252b6c23275SDavid Wu 	{RK_GPIO4_B0, RK3588_VCCIO6_IOC_REG + 0x0088},
2253b6c23275SDavid Wu 	{RK_GPIO4_B4, RK3588_VCCIO6_IOC_REG + 0x008C},
2254b6c23275SDavid Wu 	{RK_GPIO4_C0, RK3588_VCCIO6_IOC_REG + 0x0090},
2255b6c23275SDavid Wu 	{RK_GPIO4_C2, RK3588_VCCIO3_5_IOC_REG + 0x0090},
2256b6c23275SDavid Wu 	{RK_GPIO4_C4, RK3588_VCCIO3_5_IOC_REG + 0x0094},
2257b6c23275SDavid Wu 	{RK_GPIO4_D0, RK3588_VCCIO2_IOC_REG + 0x0098},
2258b6c23275SDavid Wu 	{RK_GPIO4_D4, RK3588_VCCIO2_IOC_REG + 0x009C},
2259b6c23275SDavid Wu };
2260b6c23275SDavid Wu 
2261b6c23275SDavid Wu static const u32 rk3588_p_regs[][2] = {
2262b6c23275SDavid Wu 	{RK_GPIO0_A0, RK3588_PMU1_IOC_REG + 0x0020},
2263b6c23275SDavid Wu 	{RK_GPIO0_B0, RK3588_PMU1_IOC_REG + 0x0024},
2264b6c23275SDavid Wu 	{RK_GPIO0_B5, RK3588_PMU2_IOC_REG + 0x0028},
2265b6c23275SDavid Wu 	{RK_GPIO0_C0, RK3588_PMU2_IOC_REG + 0x002C},
2266b6c23275SDavid Wu 	{RK_GPIO0_D0, RK3588_PMU2_IOC_REG + 0x0030},
2267b6c23275SDavid Wu 	{RK_GPIO1_A0, RK3588_VCCIO1_4_IOC_REG + 0x0110},
2268b6c23275SDavid Wu 	{RK_GPIO1_B0, RK3588_VCCIO1_4_IOC_REG + 0x0114},
2269b6c23275SDavid Wu 	{RK_GPIO1_C0, RK3588_VCCIO1_4_IOC_REG + 0x0118},
2270b6c23275SDavid Wu 	{RK_GPIO1_D0, RK3588_VCCIO1_4_IOC_REG + 0x011C},
2271b6c23275SDavid Wu 	{RK_GPIO2_A0, RK3588_EMMC_IOC_REG + 0x0120},
2272b6c23275SDavid Wu 	{RK_GPIO2_A6, RK3588_VCCIO3_5_IOC_REG + 0x0120},
2273b6c23275SDavid Wu 	{RK_GPIO2_B0, RK3588_VCCIO3_5_IOC_REG + 0x0124},
2274b6c23275SDavid Wu 	{RK_GPIO2_C0, RK3588_VCCIO3_5_IOC_REG + 0x0128},
2275b6c23275SDavid Wu 	{RK_GPIO2_D0, RK3588_EMMC_IOC_REG + 0x012C},
2276b6c23275SDavid Wu 	{RK_GPIO3_A0, RK3588_VCCIO3_5_IOC_REG + 0x0130},
2277b6c23275SDavid Wu 	{RK_GPIO3_B0, RK3588_VCCIO3_5_IOC_REG + 0x0134},
2278b6c23275SDavid Wu 	{RK_GPIO3_C0, RK3588_VCCIO3_5_IOC_REG + 0x0138},
2279b6c23275SDavid Wu 	{RK_GPIO3_D0, RK3588_VCCIO3_5_IOC_REG + 0x013C},
2280b6c23275SDavid Wu 	{RK_GPIO4_A0, RK3588_VCCIO6_IOC_REG + 0x0140},
2281b6c23275SDavid Wu 	{RK_GPIO4_B0, RK3588_VCCIO6_IOC_REG + 0x0144},
2282b6c23275SDavid Wu 	{RK_GPIO4_C0, RK3588_VCCIO6_IOC_REG + 0x0148},
2283e4dd7fd5SAndy Shevchenko 	{RK_GPIO4_C2, RK3588_VCCIO3_5_IOC_REG + 0x0148},
2284b6c23275SDavid Wu 	{RK_GPIO4_D0, RK3588_VCCIO2_IOC_REG + 0x014C},
2285b6c23275SDavid Wu };
2286b6c23275SDavid Wu 
2287b6c23275SDavid Wu static const u32 rk3588_smt_regs[][2] = {
2288b6c23275SDavid Wu 	{RK_GPIO0_A0, RK3588_PMU1_IOC_REG + 0x0030},
2289b6c23275SDavid Wu 	{RK_GPIO0_B0, RK3588_PMU1_IOC_REG + 0x0034},
2290b6c23275SDavid Wu 	{RK_GPIO0_B5, RK3588_PMU2_IOC_REG + 0x0040},
2291b6c23275SDavid Wu 	{RK_GPIO0_C0, RK3588_PMU2_IOC_REG + 0x0044},
2292b6c23275SDavid Wu 	{RK_GPIO0_D0, RK3588_PMU2_IOC_REG + 0x0048},
2293b6c23275SDavid Wu 	{RK_GPIO1_A0, RK3588_VCCIO1_4_IOC_REG + 0x0210},
2294b6c23275SDavid Wu 	{RK_GPIO1_B0, RK3588_VCCIO1_4_IOC_REG + 0x0214},
2295e4dd7fd5SAndy Shevchenko 	{RK_GPIO1_C0, RK3588_VCCIO1_4_IOC_REG + 0x0218},
2296b6c23275SDavid Wu 	{RK_GPIO1_D0, RK3588_VCCIO1_4_IOC_REG + 0x021C},
2297b6c23275SDavid Wu 	{RK_GPIO2_A0, RK3588_EMMC_IOC_REG + 0x0220},
2298b6c23275SDavid Wu 	{RK_GPIO2_A6, RK3588_VCCIO3_5_IOC_REG + 0x0220},
2299b547c800SHeiko Stübner 	{RK_GPIO2_B0, RK3588_VCCIO3_5_IOC_REG + 0x0224},
2300b547c800SHeiko Stübner 	{RK_GPIO2_C0, RK3588_VCCIO3_5_IOC_REG + 0x0228},
2301b547c800SHeiko Stübner 	{RK_GPIO2_D0, RK3588_EMMC_IOC_REG + 0x022C},
2302b547c800SHeiko Stübner 	{RK_GPIO3_A0, RK3588_VCCIO3_5_IOC_REG + 0x0230},
2303b547c800SHeiko Stübner 	{RK_GPIO3_B0, RK3588_VCCIO3_5_IOC_REG + 0x0234},
2304b6c23275SDavid Wu 	{RK_GPIO3_C0, RK3588_VCCIO3_5_IOC_REG + 0x0238},
2305b547c800SHeiko Stübner 	{RK_GPIO3_D0, RK3588_VCCIO3_5_IOC_REG + 0x023C},
2306b6c23275SDavid Wu 	{RK_GPIO4_A0, RK3588_VCCIO6_IOC_REG + 0x0240},
2307b547c800SHeiko Stübner 	{RK_GPIO4_B0, RK3588_VCCIO6_IOC_REG + 0x0244},
2308b547c800SHeiko Stübner 	{RK_GPIO4_C0, RK3588_VCCIO6_IOC_REG + 0x0248},
2309ef17f69fSHeiko Stübner 	{RK_GPIO4_C2, RK3588_VCCIO3_5_IOC_REG + 0x0248},
2310ef17f69fSHeiko Stübner 	{RK_GPIO4_D0, RK3588_VCCIO2_IOC_REG + 0x024C},
2311b547c800SHeiko Stübner };
2312b547c800SHeiko Stübner 
2313ef17f69fSHeiko Stübner #define RK3588_PULL_BITS_PER_PIN		2
2314e4dd7fd5SAndy Shevchenko #define RK3588_PULL_PINS_PER_REG		8
2315b547c800SHeiko Stübner 
rk3588_calc_pull_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)2316b547c800SHeiko Stübner static int rk3588_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
2317b6c23275SDavid Wu 					int pin_num, struct regmap **regmap,
2318b547c800SHeiko Stübner 					int *reg, u8 *bit)
2319b6c23275SDavid Wu {
2320b6c23275SDavid Wu 	struct rockchip_pinctrl *info = bank->drvdata;
2321e4dd7fd5SAndy Shevchenko 	u8 bank_num = bank->bank_num;
2322b6c23275SDavid Wu 	u32 pin = bank_num * 32 + pin_num;
2323b547c800SHeiko Stübner 	int i;
232442573ab3SSebastian Reichel 
232542573ab3SSebastian Reichel 	for (i = ARRAY_SIZE(rk3588_p_regs) - 1; i >= 0; i--) {
232642573ab3SSebastian Reichel 		if (pin >= rk3588_p_regs[i][0]) {
2327fdc33ebaSJianqun Xu 			*reg = rk3588_p_regs[i][1];
2328fdc33ebaSJianqun Xu 			*regmap = info->regmap_base;
2329fdc33ebaSJianqun Xu 			*bit = pin_num % RK3588_PULL_PINS_PER_REG;
2330fdc33ebaSJianqun Xu 			*bit *= RK3588_PULL_BITS_PER_PIN;
2331fdc33ebaSJianqun Xu 			return 0;
2332c0dadc0eSJianqun Xu 		}
2333c0dadc0eSJianqun Xu 	}
2334c0dadc0eSJianqun Xu 
2335c0dadc0eSJianqun Xu 	return -EINVAL;
2336b547c800SHeiko Stübner }
2337fd4ea486SJagan Teki 
2338fd4ea486SJagan Teki #define RK3588_DRV_BITS_PER_PIN		4
2339fd4ea486SJagan Teki #define RK3588_DRV_PINS_PER_REG		4
2340fd4ea486SJagan Teki 
rk3588_calc_drv_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)2341fd4ea486SJagan Teki static int rk3588_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
2342fd4ea486SJagan Teki 				       int pin_num, struct regmap **regmap,
2343b547c800SHeiko Stübner 				       int *reg, u8 *bit)
2344b6c23275SDavid Wu {
2345b6c23275SDavid Wu 	struct rockchip_pinctrl *info = bank->drvdata;
2346b547c800SHeiko Stübner 	u8 bank_num = bank->bank_num;
2347b547c800SHeiko Stübner 	u32 pin = bank_num * 32 + pin_num;
2348b6c23275SDavid Wu 	int i;
2349b6c23275SDavid Wu 
2350b6c23275SDavid Wu 	for (i = ARRAY_SIZE(rk3588_ds_regs) - 1; i >= 0; i--) {
2351b547c800SHeiko Stübner 		if (pin >= rk3588_ds_regs[i][0]) {
2352b547c800SHeiko Stübner 			*reg = rk3588_ds_regs[i][1];
2353b547c800SHeiko Stübner 			*regmap = info->regmap_base;
2354b547c800SHeiko Stübner 			*bit = pin_num % RK3588_DRV_PINS_PER_REG;
2355e4dd7fd5SAndy Shevchenko 			*bit *= RK3588_DRV_BITS_PER_PIN;
2356b547c800SHeiko Stübner 			return 0;
2357b547c800SHeiko Stübner 		}
2358b547c800SHeiko Stübner 	}
2359b6c23275SDavid Wu 
2360b6c23275SDavid Wu 	return -EINVAL;
2361b6c23275SDavid Wu }
2362b6c23275SDavid Wu 
2363b6c23275SDavid Wu #define RK3588_SMT_BITS_PER_PIN		1
2364b6c23275SDavid Wu #define RK3588_SMT_PINS_PER_REG		8
2365b6c23275SDavid Wu 
rk3588_calc_schmitt_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)2366b6c23275SDavid Wu static int rk3588_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
2367b6c23275SDavid Wu 					   int pin_num,
2368b6c23275SDavid Wu 					   struct regmap **regmap,
2369b6c23275SDavid Wu 					   int *reg, u8 *bit)
2370b6c23275SDavid Wu {
2371b6c23275SDavid Wu 	struct rockchip_pinctrl *info = bank->drvdata;
2372b6c23275SDavid Wu 	u8 bank_num = bank->bank_num;
2373b6c23275SDavid Wu 	u32 pin = bank_num * 32 + pin_num;
2374b6c23275SDavid Wu 	int i;
2375b6c23275SDavid Wu 
2376b6c23275SDavid Wu 	for (i = ARRAY_SIZE(rk3588_smt_regs) - 1; i >= 0; i--) {
2377b6c23275SDavid Wu 		if (pin >= rk3588_smt_regs[i][0]) {
2378b6c23275SDavid Wu 			*reg = rk3588_smt_regs[i][1];
2379f07bedc3SJohn Keeping 			*regmap = info->regmap_base;
2380b6c23275SDavid Wu 			*bit = pin_num % RK3588_SMT_PINS_PER_REG;
2381b6c23275SDavid Wu 			*bit *= RK3588_SMT_BITS_PER_PIN;
2382b6c23275SDavid Wu 			return 0;
2383b6c23275SDavid Wu 		}
2384b6c23275SDavid Wu 	}
2385b6c23275SDavid Wu 
2386b6c23275SDavid Wu 	return -EINVAL;
2387b6c23275SDavid Wu }
2388b6c23275SDavid Wu 
2389b6c23275SDavid Wu static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = {
2390b6c23275SDavid Wu 	{ 2, 4, 8, 12, -1, -1, -1, -1 },
2391b6c23275SDavid Wu 	{ 3, 6, 9, 12, -1, -1, -1, -1 },
2392b6c23275SDavid Wu 	{ 5, 10, 15, 20, -1, -1, -1, -1 },
2393b6c23275SDavid Wu 	{ 4, 6, 8, 10, 12, 14, 16, 18 },
2394e4dd7fd5SAndy Shevchenko 	{ 4, 7, 10, 13, 16, 19, 22, 26 }
2395b6c23275SDavid Wu };
2396b6c23275SDavid Wu 
rockchip_get_drive_perpin(struct rockchip_pin_bank * bank,int pin_num)2397b6c23275SDavid Wu static int rockchip_get_drive_perpin(struct rockchip_pin_bank *bank,
2398b6c23275SDavid Wu 				     int pin_num)
2399b6c23275SDavid Wu {
2400b6c23275SDavid Wu 	struct rockchip_pinctrl *info = bank->drvdata;
2401b6c23275SDavid Wu 	struct rockchip_pin_ctrl *ctrl = info->ctrl;
2402b6c23275SDavid Wu 	struct device *dev = info->dev;
2403b6c23275SDavid Wu 	struct regmap *regmap;
2404b6c23275SDavid Wu 	int reg, ret;
2405e4dd7fd5SAndy Shevchenko 	u32 data, temp, rmask_bits;
2406b6c23275SDavid Wu 	u8 bit;
2407b6c23275SDavid Wu 	int drv_type = bank->drv[pin_num / 8].drv_type;
2408b6c23275SDavid Wu 
2409c0dadc0eSJianqun Xu 	ret = ctrl->drv_calc_reg(bank, pin_num, &regmap, &reg, &bit);
2410b547c800SHeiko Stübner 	if (ret)
2411b6c23275SDavid Wu 		return ret;
241299e872d9SSonny Rao 
2413b547c800SHeiko Stübner 	switch (drv_type) {
2414b547c800SHeiko Stübner 	case DRV_TYPE_IO_1V8_3V0_AUTO:
241599e872d9SSonny Rao 	case DRV_TYPE_IO_3V3_ONLY:
2416b547c800SHeiko Stübner 		rmask_bits = RK3399_DRV_3BITS_PER_PIN;
2417b547c800SHeiko Stübner 		switch (bit) {
2418b547c800SHeiko Stübner 		case 0 ... 12:
2419b547c800SHeiko Stübner 			/* regular case, nothing to do */
24203ba6767aSDavid Wu 			break;
24213ba6767aSDavid Wu 		case 15:
24223ba6767aSDavid Wu 			/*
24233ba6767aSDavid Wu 			 * drive-strength offset is special, as it is
24243ba6767aSDavid Wu 			 * spread over 2 registers
24253ba6767aSDavid Wu 			 */
24263ba6767aSDavid Wu 			ret = regmap_read(regmap, reg, &data);
24273ba6767aSDavid Wu 			if (ret)
24283ba6767aSDavid Wu 				return ret;
24293ba6767aSDavid Wu 
24303ba6767aSDavid Wu 			ret = regmap_read(regmap, reg + 0x4, &temp);
24313ba6767aSDavid Wu 			if (ret)
24323ba6767aSDavid Wu 				return ret;
24333ba6767aSDavid Wu 
24343ba6767aSDavid Wu 			/*
2435d3e51161SHeiko Stübner 			 * the bit data[15] contains bit 0 of the value
2436d3e51161SHeiko Stübner 			 * while temp[1:0] contains bits 2 and 1
2437d3e51161SHeiko Stübner 			 */
2438d3e51161SHeiko Stübner 			data >>= 15;
2439e4dd7fd5SAndy Shevchenko 			temp &= 0x3;
2440751a99abSHeiko Stübner 			temp <<= 1;
24413ba6767aSDavid Wu 			data |= temp;
2442d3e51161SHeiko Stübner 
24436ca5274dSHeiko Stübner 			return rockchip_perpin_drv_list[drv_type][data];
2444d3e51161SHeiko Stübner 		case 18 ... 21:
2445d3e51161SHeiko Stübner 			/* setting fully enclosed in the second register */
2446a282926dSHeiko Stübner 			reg += 4;
2447d3e51161SHeiko Stübner 			bit -= 16;
2448d3e51161SHeiko Stübner 			break;
244942573ab3SSebastian Reichel 		default:
245042573ab3SSebastian Reichel 			dev_err(dev, "unsupported bit: %d for pinctrl drive type: %d\n",
245142573ab3SSebastian Reichel 				bit, drv_type);
2452751a99abSHeiko Stübner 			return -EINVAL;
2453751a99abSHeiko Stübner 		}
2454751a99abSHeiko Stübner 
2455751a99abSHeiko Stübner 		break;
24566ca5274dSHeiko Stübner 	case DRV_TYPE_IO_DEFAULT:
2457a282926dSHeiko Stübner 	case DRV_TYPE_IO_1V8_OR_3V0:
2458a282926dSHeiko Stübner 	case DRV_TYPE_IO_1V8_ONLY:
2459d23c66dfSDavid Wu 		rmask_bits = RK3288_DRV_BITS_PER_PIN;
2460751a99abSHeiko Stübner 		break;
2461d3e51161SHeiko Stübner 	default:
2462d3e51161SHeiko Stübner 		dev_err(dev, "unsupported pinctrl drive type: %d\n", drv_type);
246387065ca9SDavid Wu 		return -EINVAL;
2464b9c6dcabSAndy Yan 	}
2465a282926dSHeiko Stübner 
246666d750e1SHeiko Stübner 	ret = regmap_read(regmap, reg, &data);
24677825aeb7SJianqun Xu 	if (ret)
246801b4b1d1SHuang-Huang Bao 		return ret;
2469daecdc66SHeiko Stübner 
2470b6c23275SDavid Wu 	data >>= bit;
247131b62a98SJonas Karlman 	data &= (1 << rmask_bits) - 1;
2472fdc33ebaSJianqun Xu 
24733ba6767aSDavid Wu 	return rockchip_perpin_drv_list[drv_type][data];
2474751a99abSHeiko Stübner }
24756ca5274dSHeiko Stübner 
rockchip_set_drive_perpin(struct rockchip_pin_bank * bank,int pin_num,int strength)247631b62a98SJonas Karlman static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
247731b62a98SJonas Karlman 				     int pin_num, int strength)
247831b62a98SJonas Karlman {
247931b62a98SJonas Karlman 	struct rockchip_pinctrl *info = bank->drvdata;
248031b62a98SJonas Karlman 	struct rockchip_pin_ctrl *ctrl = info->ctrl;
248131b62a98SJonas Karlman 	struct device *dev = info->dev;
248231b62a98SJonas Karlman 	struct regmap *regmap;
248331b62a98SJonas Karlman 	int reg, ret, i;
24846ca5274dSHeiko Stübner 	u32 data, rmask, rmask_bits, temp;
24853ba6767aSDavid Wu 	u8 bit;
2486a282926dSHeiko Stübner 	int drv_type = bank->drv[pin_num / 8].drv_type;
2487e4dd7fd5SAndy Shevchenko 
2488a282926dSHeiko Stübner 	dev_dbg(dev, "setting drive of GPIO%d-%d to %d\n",
2489a282926dSHeiko Stübner 		bank->bank_num, pin_num, strength);
2490d3e51161SHeiko Stübner 
2491d3e51161SHeiko Stübner 	ret = ctrl->drv_calc_reg(bank, pin_num, &regmap, &reg, &bit);
2492d3e51161SHeiko Stübner 	if (ret)
2493d3e51161SHeiko Stübner 		return ret;
2494d3e51161SHeiko Stübner 	if (ctrl->type == RK3588) {
2495d3e51161SHeiko Stübner 		rmask_bits = RK3588_DRV_BITS_PER_PIN;
2496d3e51161SHeiko Stübner 		ret = strength;
2497e4dd7fd5SAndy Shevchenko 		goto config;
2498751a99abSHeiko Stübner 	} else if (ctrl->type == RK3568) {
24993ba6767aSDavid Wu 		rmask_bits = RK3568_DRV_BITS_PER_PIN;
2500d3e51161SHeiko Stübner 		ret = (1 << (strength + 1)) - 1;
250199e872d9SSonny Rao 		goto config;
2502d3e51161SHeiko Stübner 	} else if (ctrl->type == RK3576) {
2503e4dd7fd5SAndy Shevchenko 		rmask_bits = RK3576_DRV_BITS_PER_PIN;
2504d3e51161SHeiko Stübner 		ret = ((strength & BIT(2)) >> 2) | ((strength & BIT(0)) << 2) | (strength & BIT(1));
2505d3e51161SHeiko Stübner 		goto config;
2506a282926dSHeiko Stübner 	}
2507d3e51161SHeiko Stübner 
2508d3e51161SHeiko Stübner 	if (ctrl->type == RV1126) {
250942573ab3SSebastian Reichel 		rmask_bits = RV1126_DRV_BITS_PER_PIN;
251042573ab3SSebastian Reichel 		ret = strength;
251142573ab3SSebastian Reichel 		goto config;
2512d3e51161SHeiko Stübner 	}
25136ca5274dSHeiko Stübner 
25146ca5274dSHeiko Stübner 	ret = -EINVAL;
2515d23c66dfSDavid Wu 	for (i = 0; i < ARRAY_SIZE(rockchip_perpin_drv_list[drv_type]); i++) {
2516d3e51161SHeiko Stübner 		if (rockchip_perpin_drv_list[drv_type][i] == strength) {
2517d3e51161SHeiko Stübner 			ret = i;
2518d3e51161SHeiko Stübner 			break;
2519751a99abSHeiko Stübner 		} else if (rockchip_perpin_drv_list[drv_type][i] < 0) {
2520a282926dSHeiko Stübner 			ret = rockchip_perpin_drv_list[drv_type][i];
252187065ca9SDavid Wu 			break;
2522b9c6dcabSAndy Yan 		}
2523fd4ea486SJagan Teki 	}
2524a282926dSHeiko Stübner 
252566d750e1SHeiko Stübner 	if (ret < 0) {
25267825aeb7SJianqun Xu 		dev_err(dev, "unsupported driver strength %d\n", strength);
252701b4b1d1SHuang-Huang Bao 		return ret;
2528daecdc66SHeiko Stübner 	}
2529b6c23275SDavid Wu 
2530c0dadc0eSJianqun Xu 	switch (drv_type) {
2531fdc33ebaSJianqun Xu 	case DRV_TYPE_IO_1V8_3V0_AUTO:
25323ba6767aSDavid Wu 	case DRV_TYPE_IO_3V3_ONLY:
25333ba6767aSDavid Wu 		rmask_bits = RK3399_DRV_3BITS_PER_PIN;
25343ba6767aSDavid Wu 		switch (bit) {
25353ba6767aSDavid Wu 		case 0 ... 12:
25363ba6767aSDavid Wu 			/* regular case, nothing to do */
25373ba6767aSDavid Wu 			break;
25383ba6767aSDavid Wu 		case 15:
25393ba6767aSDavid Wu 			/*
25403ba6767aSDavid Wu 			 * drive-strength offset is special, as it is spread
2541c0dadc0eSJianqun Xu 			 * over 2 registers, the bit data[15] contains bit 0
254231b62a98SJonas Karlman 			 * of the value while temp[1:0] contains bits 2 and 1
2543c0dadc0eSJianqun Xu 			 */
2544c0dadc0eSJianqun Xu 			data = (ret & 0x1) << 15;
2545c0dadc0eSJianqun Xu 			temp = (ret >> 0x1) & 0x3;
2546c0dadc0eSJianqun Xu 
2547c0dadc0eSJianqun Xu 			rmask = BIT(15) | BIT(31);
2548c0dadc0eSJianqun Xu 			data |= BIT(31);
25493ba6767aSDavid Wu 			ret = regmap_update_bits(regmap, reg, rmask, data);
25503ba6767aSDavid Wu 			if (ret)
2551e4dd7fd5SAndy Shevchenko 				return ret;
25523ba6767aSDavid Wu 
25533ba6767aSDavid Wu 			rmask = 0x3 | (0x3 << 16);
25543ba6767aSDavid Wu 			temp |= (0x3 << 16);
25556ca5274dSHeiko Stübner 			reg += 0x4;
25566ca5274dSHeiko Stübner 			ret = regmap_update_bits(regmap, reg, rmask, temp);
255799e872d9SSonny Rao 
25583ba6767aSDavid Wu 			return ret;
25596ca5274dSHeiko Stübner 		case 18 ... 21:
256099e872d9SSonny Rao 			/* setting fully enclosed in the second register */
25616ca5274dSHeiko Stübner 			reg += 4;
2562a282926dSHeiko Stübner 			bit -= 16;
2563e4dd7fd5SAndy Shevchenko 			break;
2564a282926dSHeiko Stübner 		default:
2565d3e51161SHeiko Stübner 			dev_err(dev, "unsupported bit: %d for pinctrl drive type: %d\n",
2566d3e51161SHeiko Stübner 				bit, drv_type);
2567751a99abSHeiko Stübner 			return -EINVAL;
2568d3e51161SHeiko Stübner 		}
2569d3e51161SHeiko Stübner 		break;
2570728d3f5aSdavid.wu 	case DRV_TYPE_IO_DEFAULT:
2571728d3f5aSdavid.wu 	case DRV_TYPE_IO_1V8_OR_3V0:
2572728d3f5aSdavid.wu 	case DRV_TYPE_IO_1V8_ONLY:
2573728d3f5aSdavid.wu 		rmask_bits = RK3288_DRV_BITS_PER_PIN;
2574728d3f5aSdavid.wu 		break;
2575728d3f5aSdavid.wu 	default:
2576728d3f5aSdavid.wu 		dev_err(dev, "unsupported pinctrl drive type: %d\n", drv_type);
2577728d3f5aSdavid.wu 		return -EINVAL;
2578728d3f5aSdavid.wu 	}
2579728d3f5aSdavid.wu 
2580728d3f5aSdavid.wu config:
2581728d3f5aSdavid.wu 	/* enable the write to the equivalent lower bits */
2582728d3f5aSdavid.wu 	data = ((1 << rmask_bits) - 1) << (bit + 16);
2583728d3f5aSdavid.wu 	rmask = data | (data >> 16);
2584728d3f5aSdavid.wu 	data |= (ret << bit);
2585728d3f5aSdavid.wu 
2586728d3f5aSdavid.wu 	ret = regmap_update_bits(regmap, reg, rmask, data);
2587728d3f5aSdavid.wu 
2588728d3f5aSdavid.wu 	return ret;
2589728d3f5aSdavid.wu }
2590728d3f5aSdavid.wu 
2591728d3f5aSdavid.wu static int rockchip_pull_list[PULL_TYPE_MAX][4] = {
2592c0dadc0eSJianqun Xu 	{
2593c0dadc0eSJianqun Xu 		PIN_CONFIG_BIAS_DISABLE,
2594c0dadc0eSJianqun Xu 		PIN_CONFIG_BIAS_PULL_UP,
2595c0dadc0eSJianqun Xu 		PIN_CONFIG_BIAS_PULL_DOWN,
2596c0dadc0eSJianqun Xu 		PIN_CONFIG_BIAS_BUS_HOLD
2597c0dadc0eSJianqun Xu 	},
2598c0dadc0eSJianqun Xu 	{
2599c0dadc0eSJianqun Xu 		PIN_CONFIG_BIAS_DISABLE,
2600c0dadc0eSJianqun Xu 		PIN_CONFIG_BIAS_PULL_DOWN,
2601c0dadc0eSJianqun Xu 		PIN_CONFIG_BIAS_DISABLE,
2602c0dadc0eSJianqun Xu 		PIN_CONFIG_BIAS_PULL_UP
2603c0dadc0eSJianqun Xu 	},
2604c0dadc0eSJianqun Xu };
2605c0dadc0eSJianqun Xu 
rockchip_get_pull(struct rockchip_pin_bank * bank,int pin_num)2606c0dadc0eSJianqun Xu static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
2607c0dadc0eSJianqun Xu {
2608c0dadc0eSJianqun Xu 	struct rockchip_pinctrl *info = bank->drvdata;
2609c0dadc0eSJianqun Xu 	struct rockchip_pin_ctrl *ctrl = info->ctrl;
2610c0dadc0eSJianqun Xu 	struct device *dev = info->dev;
2611c0dadc0eSJianqun Xu 	struct regmap *regmap;
2612c0dadc0eSJianqun Xu 	int reg, ret, pull_type;
2613c0dadc0eSJianqun Xu 	u8 bit;
2614c0dadc0eSJianqun Xu 	u32 data;
2615c0dadc0eSJianqun Xu 
2616c0dadc0eSJianqun Xu 	/* rk3066b does support any pulls */
2617c0dadc0eSJianqun Xu 	if (ctrl->type == RK3066B)
2618c0dadc0eSJianqun Xu 		return PIN_CONFIG_BIAS_DISABLE;
2619c0dadc0eSJianqun Xu 
2620c0dadc0eSJianqun Xu 	ret = ctrl->pull_calc_reg(bank, pin_num, &regmap, &reg, &bit);
2621e3b357d7Sdavid.wu 	if (ret)
2622e3b357d7Sdavid.wu 		return ret;
2623e3b357d7Sdavid.wu 
2624e3b357d7Sdavid.wu 	ret = regmap_read(regmap, reg, &data);
2625e3b357d7Sdavid.wu 	if (ret)
2626e3b357d7Sdavid.wu 		return ret;
2627e3b357d7Sdavid.wu 
2628e3b357d7Sdavid.wu 	switch (ctrl->type) {
2629e3b357d7Sdavid.wu 	case RK2928:
2630e3b357d7Sdavid.wu 	case RK3128:
2631e3b357d7Sdavid.wu 		return !(data & BIT(bit))
2632e3b357d7Sdavid.wu 				? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT
2633e3b357d7Sdavid.wu 				: PIN_CONFIG_BIAS_DISABLE;
2634e3b357d7Sdavid.wu 	case PX30:
2635e3b357d7Sdavid.wu 	case RV1108:
2636e3b357d7Sdavid.wu 	case RK3188:
2637e3b357d7Sdavid.wu 	case RK3288:
2638e3b357d7Sdavid.wu 	case RK3308:
2639c0dadc0eSJianqun Xu 	case RK3328:
2640c0dadc0eSJianqun Xu 	case RK3368:
2641c0dadc0eSJianqun Xu 	case RK3399:
2642c0dadc0eSJianqun Xu 	case RK3568:
2643c0dadc0eSJianqun Xu 	case RK3576:
2644c0dadc0eSJianqun Xu 	case RK3588:
2645c0dadc0eSJianqun Xu 		pull_type = bank->pull_type[pin_num / 8];
2646e3b357d7Sdavid.wu 		data >>= bit;
2647e3b357d7Sdavid.wu 		data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1;
2648e3b357d7Sdavid.wu 		/*
2649e3b357d7Sdavid.wu 		 * In the TRM, pull-up being 1 for everything except the GPIO0_D3-D6,
2650e3b357d7Sdavid.wu 		 * where that pull up value becomes 3.
2651e3b357d7Sdavid.wu 		 */
2652e3b357d7Sdavid.wu 		if (ctrl->type == RK3568 && bank->bank_num == 0 && pin_num >= 27 && pin_num <= 30) {
2653e3b357d7Sdavid.wu 			if (data == 3)
2654e4dd7fd5SAndy Shevchenko 				data = 1;
2655e3b357d7Sdavid.wu 		}
2656e3b357d7Sdavid.wu 
2657e3b357d7Sdavid.wu 		return rockchip_pull_list[pull_type][data];
2658e3b357d7Sdavid.wu 	default:
2659e3b357d7Sdavid.wu 		dev_err(dev, "unsupported pinctrl type\n");
2660e4dd7fd5SAndy Shevchenko 		return -EINVAL;
2661e3b357d7Sdavid.wu 	};
2662e3b357d7Sdavid.wu }
2663e3b357d7Sdavid.wu 
rockchip_set_pull(struct rockchip_pin_bank * bank,int pin_num,int pull)2664e3b357d7Sdavid.wu static int rockchip_set_pull(struct rockchip_pin_bank *bank,
2665e3b357d7Sdavid.wu 					int pin_num, int pull)
2666e3b357d7Sdavid.wu {
2667e3b357d7Sdavid.wu 	struct rockchip_pinctrl *info = bank->drvdata;
2668c0dadc0eSJianqun Xu 	struct rockchip_pin_ctrl *ctrl = info->ctrl;
2669c0dadc0eSJianqun Xu 	struct device *dev = info->dev;
2670c0dadc0eSJianqun Xu 	struct regmap *regmap;
2671c0dadc0eSJianqun Xu 	int reg, ret, i, pull_type;
2672c0dadc0eSJianqun Xu 	u8 bit;
2673c0dadc0eSJianqun Xu 	u32 data, rmask;
2674c0dadc0eSJianqun Xu 
2675e3b357d7Sdavid.wu 	dev_dbg(dev, "setting pull of GPIO%d-%d to %d\n", bank->bank_num, pin_num, pull);
2676e3b357d7Sdavid.wu 
2677c0dadc0eSJianqun Xu 	/* rk3066b does support any pulls */
2678c0dadc0eSJianqun Xu 	if (ctrl->type == RK3066B)
2679e3b357d7Sdavid.wu 		return pull ? -EINVAL : 0;
2680f07bedc3SJohn Keeping 
2681e3b357d7Sdavid.wu 	ret = ctrl->pull_calc_reg(bank, pin_num, &regmap, &reg, &bit);
2682e3b357d7Sdavid.wu 	if (ret)
2683d3e51161SHeiko Stübner 		return ret;
2684d3e51161SHeiko Stübner 
2685d3e51161SHeiko Stübner 	switch (ctrl->type) {
2686d3e51161SHeiko Stübner 	case RK2928:
2687d3e51161SHeiko Stübner 	case RK3128:
2688d3e51161SHeiko Stübner 		data = BIT(bit + 16);
2689d3e51161SHeiko Stübner 		if (pull == PIN_CONFIG_BIAS_DISABLE)
2690d3e51161SHeiko Stübner 			data |= BIT(bit);
2691d3e51161SHeiko Stübner 		ret = regmap_write(regmap, reg, data);
2692d3e51161SHeiko Stübner 		break;
2693d3e51161SHeiko Stübner 	case PX30:
2694d3e51161SHeiko Stübner 	case RV1108:
2695d3e51161SHeiko Stübner 	case RV1126:
2696d3e51161SHeiko Stübner 	case RK3188:
2697d3e51161SHeiko Stübner 	case RK3288:
2698d3e51161SHeiko Stübner 	case RK3308:
2699d3e51161SHeiko Stübner 	case RK3328:
2700d3e51161SHeiko Stübner 	case RK3368:
2701d3e51161SHeiko Stübner 	case RK3399:
2702d3e51161SHeiko Stübner 	case RK3568:
2703d3e51161SHeiko Stübner 	case RK3576:
2704d3e51161SHeiko Stübner 	case RK3588:
2705d3e51161SHeiko Stübner 		pull_type = bank->pull_type[pin_num / 8];
2706d3e51161SHeiko Stübner 		ret = -EINVAL;
2707d3e51161SHeiko Stübner 		for (i = 0; i < ARRAY_SIZE(rockchip_pull_list[pull_type]);
2708d3e51161SHeiko Stübner 			i++) {
2709d3e51161SHeiko Stübner 			if (rockchip_pull_list[pull_type][i] == pull) {
2710d3e51161SHeiko Stübner 				ret = i;
2711d3e51161SHeiko Stübner 				break;
2712d3e51161SHeiko Stübner 			}
2713d3e51161SHeiko Stübner 		}
271403e9f0caSLinus Walleij 		/*
2715d3e51161SHeiko Stübner 		 * In the TRM, pull-up being 1 for everything except the GPIO0_D3-D6,
2716d3e51161SHeiko Stübner 		 * where that pull up value becomes 3.
2717d3e51161SHeiko Stübner 		 */
2718d3e51161SHeiko Stübner 		if (ctrl->type == RK3568 && bank->bank_num == 0 && pin_num >= 27 && pin_num <= 30) {
2719d3e51161SHeiko Stübner 			if (ret == 1)
2720e4dd7fd5SAndy Shevchenko 				ret = 3;
2721d3e51161SHeiko Stübner 		}
272214797189SHeiko Stübner 
2723d3e51161SHeiko Stübner 		if (ret < 0) {
2724e4dd7fd5SAndy Shevchenko 			dev_err(dev, "unsupported pull setting %d\n", pull);
2725d3e51161SHeiko Stübner 			return ret;
2726d3e51161SHeiko Stübner 		}
2727d3e51161SHeiko Stübner 
272885dc397aSMarkus Elfring 		/* enable the write to the equivalent lower bits */
2729d3e51161SHeiko Stübner 		data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16);
2730d3e51161SHeiko Stübner 		rmask = data | (data >> 16);
2731d3e51161SHeiko Stübner 		data |= (ret << bit);
2732d3e51161SHeiko Stübner 
273314797189SHeiko Stübner 		ret = regmap_update_bits(regmap, reg, rmask, data);
2734d3e51161SHeiko Stübner 		break;
273514797189SHeiko Stübner 	default:
273614797189SHeiko Stübner 		dev_err(dev, "unsupported pinctrl type\n");
273714797189SHeiko Stübner 		return -EINVAL;
273814797189SHeiko Stübner 	}
273914797189SHeiko Stübner 
274014797189SHeiko Stübner 	return ret;
27414ea4d480SHuang-Huang Bao }
27424ea4d480SHuang-Huang Bao 
274314797189SHeiko Stübner #define RK3328_SCHMITT_BITS_PER_PIN		1
27444ea4d480SHuang-Huang Bao #define RK3328_SCHMITT_PINS_PER_REG		16
274514797189SHeiko Stübner #define RK3328_SCHMITT_BANK_STRIDE		8
274614797189SHeiko Stübner #define RK3328_SCHMITT_GRF_OFFSET		0x380
2747d3e51161SHeiko Stübner 
rk3328_calc_schmitt_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)2748d3e51161SHeiko Stübner static int rk3328_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
2749d3e51161SHeiko Stübner 					   int pin_num,
2750d3e51161SHeiko Stübner 					   struct regmap **regmap,
2751d3e51161SHeiko Stübner 					   int *reg, u8 *bit)
27524635c0e2SQuentin Schulz {
27534635c0e2SQuentin Schulz 	struct rockchip_pinctrl *info = bank->drvdata;
27544635c0e2SQuentin Schulz 
27554635c0e2SQuentin Schulz 	*regmap = info->regmap_base;
27564635c0e2SQuentin Schulz 	*reg = RK3328_SCHMITT_GRF_OFFSET;
27574635c0e2SQuentin Schulz 
27584635c0e2SQuentin Schulz 	*reg += bank->bank_num * RK3328_SCHMITT_BANK_STRIDE;
27594635c0e2SQuentin Schulz 	*reg += ((pin_num / RK3328_SCHMITT_PINS_PER_REG) * 4);
27604635c0e2SQuentin Schulz 	*bit = pin_num % RK3328_SCHMITT_PINS_PER_REG;
27614635c0e2SQuentin Schulz 
27624635c0e2SQuentin Schulz 	return 0;
27634635c0e2SQuentin Schulz }
2764d3e51161SHeiko Stübner 
2765d3e51161SHeiko Stübner #define RK3568_SCHMITT_BITS_PER_PIN		2
2766d3e51161SHeiko Stübner #define RK3568_SCHMITT_PINS_PER_REG		8
2767d3e51161SHeiko Stübner #define RK3568_SCHMITT_BANK_STRIDE		0x10
276803e9f0caSLinus Walleij #define RK3568_SCHMITT_GRF_OFFSET		0xc0
27694635c0e2SQuentin Schulz #define RK3568_SCHMITT_PMUGRF_OFFSET		0x30
2770d3e51161SHeiko Stübner 
rk3568_calc_schmitt_reg_and_bit(struct rockchip_pin_bank * bank,int pin_num,struct regmap ** regmap,int * reg,u8 * bit)2771d3e51161SHeiko Stübner static int rk3568_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
2772d3e51161SHeiko Stübner 					   int pin_num,
2773d3e51161SHeiko Stübner 					   struct regmap **regmap,
2774d3e51161SHeiko Stübner 					   int *reg, u8 *bit)
2775d3e51161SHeiko Stübner {
277644b6d930SHeiko Stübner 	struct rockchip_pinctrl *info = bank->drvdata;
277744b6d930SHeiko Stübner 
277844b6d930SHeiko Stübner 	if (bank->bank_num == 0) {
2779a282926dSHeiko Stübner 		*regmap = info->regmap_pmu;
2780a282926dSHeiko Stübner 		*reg = RK3568_SCHMITT_PMUGRF_OFFSET;
2781d23c66dfSDavid Wu 	} else {
2782a282926dSHeiko Stübner 		*regmap = info->regmap_base;
2783a282926dSHeiko Stübner 		*reg = RK3568_SCHMITT_GRF_OFFSET;
2784a282926dSHeiko Stübner 		*reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE;
278544b6d930SHeiko Stübner 	}
278687065ca9SDavid Wu 
2787b9c6dcabSAndy Yan 	*reg += ((pin_num / RK3568_SCHMITT_PINS_PER_REG) * 4);
2788fd4ea486SJagan Teki 	*bit = pin_num % RK3568_SCHMITT_PINS_PER_REG;
2789a282926dSHeiko Stübner 	*bit *= RK3568_SCHMITT_BITS_PER_PIN;
279066d750e1SHeiko Stübner 
27917825aeb7SJianqun Xu 	return 0;
279201b4b1d1SHuang-Huang Bao }
2793daecdc66SHeiko Stübner 
rockchip_get_schmitt(struct rockchip_pin_bank * bank,int pin_num)2794b6c23275SDavid Wu static int rockchip_get_schmitt(struct rockchip_pin_bank *bank, int pin_num)
2795c0dadc0eSJianqun Xu {
2796fdc33ebaSJianqun Xu 	struct rockchip_pinctrl *info = bank->drvdata;
2797a282926dSHeiko Stübner 	struct rockchip_pin_ctrl *ctrl = info->ctrl;
279844b6d930SHeiko Stübner 	struct regmap *regmap;
279944b6d930SHeiko Stübner 	int reg, ret;
2800a282926dSHeiko Stübner 	u8 bit;
280144b6d930SHeiko Stübner 	u32 data;
280244b6d930SHeiko Stübner 
28038ce5ef64SCaleb Connolly 	ret = ctrl->schmitt_calc_reg(bank, pin_num, &regmap, &reg, &bit);
28048ce5ef64SCaleb Connolly 	if (ret)
2805e7165b1dSHeiko Stuebner 		return ret;
28068ce5ef64SCaleb Connolly 
2807e7165b1dSHeiko Stuebner 	ret = regmap_read(regmap, reg, &data);
2808e7165b1dSHeiko Stuebner 	if (ret)
2809e7165b1dSHeiko Stuebner 		return ret;
2810e7165b1dSHeiko Stuebner 
2811e7165b1dSHeiko Stuebner 	data >>= bit;
2812e7165b1dSHeiko Stuebner 	switch (ctrl->type) {
28138ce5ef64SCaleb Connolly 	case RK3568:
2814e7165b1dSHeiko Stuebner 		return data & ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1);
2815e7165b1dSHeiko Stuebner 	default:
28168ce5ef64SCaleb Connolly 		break;
2817e7165b1dSHeiko Stuebner 	}
2818e7165b1dSHeiko Stuebner 
2819e7165b1dSHeiko Stuebner 	return data & 0x1;
2820e7165b1dSHeiko Stuebner }
2821d3e51161SHeiko Stübner 
rockchip_set_schmitt(struct rockchip_pin_bank * bank,int pin_num,int enable)2822d3e51161SHeiko Stübner static int rockchip_set_schmitt(struct rockchip_pin_bank *bank,
282303b054e9SSherman Yin 				int pin_num, int enable)
2824d3e51161SHeiko Stübner {
2825d3e51161SHeiko Stübner 	struct rockchip_pinctrl *info = bank->drvdata;
2826d3e51161SHeiko Stübner 	struct rockchip_pin_ctrl *ctrl = info->ctrl;
28279ce9a020SJianqun Xu 	struct device *dev = info->dev;
282803b054e9SSherman Yin 	struct regmap *regmap;
282958957d2eSMika Westerberg 	int reg, ret;
283003b054e9SSherman Yin 	u8 bit;
283103b054e9SSherman Yin 	u32 data, rmask;
283203b054e9SSherman Yin 
283303b054e9SSherman Yin 	dev_dbg(dev, "setting input schmitt of GPIO%d-%d to %d\n",
283403b054e9SSherman Yin 		bank->bank_num, pin_num, enable);
283503b054e9SSherman Yin 
2836d3e51161SHeiko Stübner 	ret = ctrl->schmitt_calc_reg(bank, pin_num, &regmap, &reg, &bit);
283742d90a1eSCaleb Connolly 	if (ret)
28388ce5ef64SCaleb Connolly 		return ret;
28398ce5ef64SCaleb Connolly 
28408ce5ef64SCaleb Connolly 	/* enable the write to the equivalent lower bits */
28418ce5ef64SCaleb Connolly 	switch (ctrl->type) {
28428ce5ef64SCaleb Connolly 	case RK3568:
28438ce5ef64SCaleb Connolly 		data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16);
28448ce5ef64SCaleb Connolly 		rmask = data | (data >> 16);
28458ce5ef64SCaleb Connolly 		data |= ((enable ? 0x2 : 0x1) << bit);
28468ce5ef64SCaleb Connolly 		break;
28478ce5ef64SCaleb Connolly 	default:
28488ce5ef64SCaleb Connolly 		data = BIT(bit + 16) | (enable << bit);
28498ce5ef64SCaleb Connolly 		rmask = BIT(bit + 16) | BIT(bit);
28508ce5ef64SCaleb Connolly 		break;
28518ce5ef64SCaleb Connolly 	}
28528ce5ef64SCaleb Connolly 
28538ce5ef64SCaleb Connolly 	return regmap_update_bits(regmap, reg, rmask, data);
28548ce5ef64SCaleb Connolly }
28558ce5ef64SCaleb Connolly 
2856d3e51161SHeiko Stübner /*
2857d3e51161SHeiko Stübner  * Pinmux_ops handling
285803b054e9SSherman Yin  */
285903b054e9SSherman Yin 
rockchip_pmx_get_funcs_count(struct pinctrl_dev * pctldev)286003b054e9SSherman Yin static int rockchip_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
286103b054e9SSherman Yin {
286244b6d930SHeiko Stübner 	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
2863d3e51161SHeiko Stübner 
2864d3e51161SHeiko Stübner 	return info->nfunctions;
2865d3e51161SHeiko Stübner }
28666ca5274dSHeiko Stübner 
rockchip_pmx_get_func_name(struct pinctrl_dev * pctldev,unsigned selector)286744b6d930SHeiko Stübner static const char *rockchip_pmx_get_func_name(struct pinctrl_dev *pctldev,
286844b6d930SHeiko Stübner 					  unsigned selector)
286944b6d930SHeiko Stübner {
287044b6d930SHeiko Stübner 	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
287144b6d930SHeiko Stübner 
287244b6d930SHeiko Stübner 	return info->functions[selector].name;
287303b054e9SSherman Yin }
287403b054e9SSherman Yin 
rockchip_pmx_get_groups(struct pinctrl_dev * pctldev,unsigned selector,const char * const ** groups,unsigned * const num_groups)287503b054e9SSherman Yin static int rockchip_pmx_get_groups(struct pinctrl_dev *pctldev,
287603b054e9SSherman Yin 				unsigned selector, const char * const **groups,
2877d3e51161SHeiko Stübner 				unsigned * const num_groups)
2878a076e2edSHeiko Stübner {
28799ce9a020SJianqun Xu 	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
28809ce9a020SJianqun Xu 
28819ce9a020SJianqun Xu 	*groups = info->functions[selector].groups;
28829ce9a020SJianqun Xu 	*num_groups = info->functions[selector].ngroups;
28839ce9a020SJianqun Xu 
28849ce9a020SJianqun Xu 	return 0;
28859ce9a020SJianqun Xu }
2886a076e2edSHeiko Stübner 
rockchip_pmx_set(struct pinctrl_dev * pctldev,unsigned selector,unsigned group)2887a076e2edSHeiko Stübner static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
2888a076e2edSHeiko Stübner 			    unsigned group)
288942d90a1eSCaleb Connolly {
289042d90a1eSCaleb Connolly 	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
289142d90a1eSCaleb Connolly 	const unsigned int *pins = info->groups[group].pins;
289242d90a1eSCaleb Connolly 	const struct rockchip_pin_config *data = info->groups[group].data;
289342d90a1eSCaleb Connolly 	struct device *dev = info->dev;
289442d90a1eSCaleb Connolly 	struct rockchip_pin_bank *bank;
289542d90a1eSCaleb Connolly 	int cnt, ret = 0;
289642d90a1eSCaleb Connolly 
289742d90a1eSCaleb Connolly 	dev_dbg(dev, "enable function %s group %s\n",
289842d90a1eSCaleb Connolly 		info->functions[selector].name, info->groups[group].name);
2899b547c800SHeiko Stübner 
2900b547c800SHeiko Stübner 	/*
2901ef17f69fSHeiko Stübner 	 * for each pin in the pin group selected, program the corresponding
2902b547c800SHeiko Stübner 	 * pin function number in the config register.
2903b547c800SHeiko Stübner 	 */
2904ef17f69fSHeiko Stübner 	for (cnt = 0; cnt < info->groups[group].npins; cnt++) {
2905ef17f69fSHeiko Stübner 		bank = pin_to_bank(info, pins[cnt]);
2906b547c800SHeiko Stübner 		ret = rockchip_set_mux(bank, pins[cnt] - bank->pin_base,
2907b547c800SHeiko Stübner 				       data[cnt].func);
2908b547c800SHeiko Stübner 		if (ret)
2909e3b357d7Sdavid.wu 			break;
2910e3b357d7Sdavid.wu 	}
2911e3b357d7Sdavid.wu 
2912e3b357d7Sdavid.wu 	if (ret) {
2913e3b357d7Sdavid.wu 		/* revert the already done pin settings */
2914e3b357d7Sdavid.wu 		for (cnt--; cnt >= 0; cnt--) {
2915e3b357d7Sdavid.wu 			bank = pin_to_bank(info, pins[cnt]);
2916e3b357d7Sdavid.wu 			rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0);
2917e3b357d7Sdavid.wu 		}
2918d3e51161SHeiko Stübner 
2919d3e51161SHeiko Stübner 		return ret;
2920d3e51161SHeiko Stübner 	}
2921d3e51161SHeiko Stübner 
292203b054e9SSherman Yin 	return 0;
2923d3e51161SHeiko Stübner }
2924d3e51161SHeiko Stübner 
rockchip_pmx_gpio_set_direction(struct pinctrl_dev * pctldev,struct pinctrl_gpio_range * range,unsigned offset,bool input)2925d3e51161SHeiko Stübner static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
2926d3e51161SHeiko Stübner 					   struct pinctrl_gpio_range *range,
2927d3e51161SHeiko Stübner 					   unsigned offset,
2928d3e51161SHeiko Stübner 					   bool input)
2929d3e51161SHeiko Stübner {
2930d3e51161SHeiko Stübner 	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
2931d3e51161SHeiko Stübner 	struct rockchip_pin_bank *bank;
2932d3e51161SHeiko Stübner 
29339ce9a020SJianqun Xu 	bank = pin_to_bank(info, offset);
2934d3e51161SHeiko Stübner 	return rockchip_set_mux(bank, offset - bank->pin_base, RK_FUNC_GPIO);
2935dab3eba7SHeiko Stübner }
2936a076e2edSHeiko Stübner 
2937d3e51161SHeiko Stübner static const struct pinmux_ops rockchip_pmx_ops = {
2938d3e51161SHeiko Stübner 	.get_functions_count	= rockchip_pmx_get_funcs_count,
2939d3e51161SHeiko Stübner 	.get_function_name	= rockchip_pmx_get_func_name,
294044b6d930SHeiko Stübner 	.get_function_groups	= rockchip_pmx_get_groups,
2941d3e51161SHeiko Stübner 	.set_mux		= rockchip_pmx_set,
2942d3e51161SHeiko Stübner 	.gpio_set_direction	= rockchip_pmx_gpio_set_direction,
2943dab3eba7SHeiko Stübner };
2944d3e51161SHeiko Stübner 
294544b6d930SHeiko Stübner /*
294644b6d930SHeiko Stübner  * Pinconf_ops handling
294744b6d930SHeiko Stübner  */
29486ca5274dSHeiko Stübner 
rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl * ctrl,enum pin_config_param pull)294944b6d930SHeiko Stübner static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
295044b6d930SHeiko Stübner 					enum pin_config_param pull)
295144b6d930SHeiko Stübner {
295244b6d930SHeiko Stübner 	switch (ctrl->type) {
295344b6d930SHeiko Stübner 	case RK2928:
295444b6d930SHeiko Stübner 	case RK3128:
2955dab3eba7SHeiko Stübner 		return (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT ||
295644b6d930SHeiko Stübner 					pull == PIN_CONFIG_BIAS_DISABLE);
2957a076e2edSHeiko Stübner 	case RK3066B:
2958a076e2edSHeiko Stübner 		return pull ? false : true;
2959a076e2edSHeiko Stübner 	case PX30:
2960a076e2edSHeiko Stübner 	case RV1108:
2961a076e2edSHeiko Stübner 	case RV1126:
2962e7165b1dSHeiko Stuebner 	case RK3188:
2963e7165b1dSHeiko Stuebner 	case RK3288:
2964e7165b1dSHeiko Stuebner 	case RK3308:
2965e7165b1dSHeiko Stuebner 	case RK3328:
2966e7165b1dSHeiko Stuebner 	case RK3368:
29679ce9a020SJianqun Xu 	case RK3399:
2968a076e2edSHeiko Stübner 	case RK3568:
2969a076e2edSHeiko Stübner 	case RK3576:
2970a076e2edSHeiko Stübner 	case RK3588:
2971a076e2edSHeiko Stübner 		return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT);
2972a076e2edSHeiko Stübner 	}
2973b547c800SHeiko Stübner 
2974b547c800SHeiko Stübner 	return false;
2975ef17f69fSHeiko Stübner }
2976b547c800SHeiko Stübner 
rockchip_pinconf_defer_pin(struct rockchip_pin_bank * bank,unsigned int pin,u32 param,u32 arg)2977b547c800SHeiko Stübner static int rockchip_pinconf_defer_pin(struct rockchip_pin_bank *bank,
2978ef17f69fSHeiko Stübner 					 unsigned int pin, u32 param, u32 arg)
2979b547c800SHeiko Stübner {
2980b547c800SHeiko Stübner 	struct rockchip_pin_deferred *cfg;
2981b547c800SHeiko Stübner 
2982b547c800SHeiko Stübner 	cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
2983b547c800SHeiko Stübner 	if (!cfg)
2984e3b357d7Sdavid.wu 		return -ENOMEM;
2985e3b357d7Sdavid.wu 
2986e3b357d7Sdavid.wu 	cfg->pin = pin;
2987e3b357d7Sdavid.wu 	cfg->param = param;
2988e3b357d7Sdavid.wu 	cfg->arg = arg;
2989e3b357d7Sdavid.wu 
2990e3b357d7Sdavid.wu 	list_add_tail(&cfg->head, &bank->deferred_pins);
2991e3b357d7Sdavid.wu 
2992e3b357d7Sdavid.wu 	return 0;
2993e3b357d7Sdavid.wu }
2994d3e51161SHeiko Stübner 
2995d3e51161SHeiko Stübner /* set the pin config settings for a specified pin */
rockchip_pinconf_set(struct pinctrl_dev * pctldev,unsigned int pin,unsigned long * configs,unsigned num_configs)2996d3e51161SHeiko Stübner static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
2997d3e51161SHeiko Stübner 				unsigned long *configs, unsigned num_configs)
2998d3e51161SHeiko Stübner {
2999dab3eba7SHeiko Stübner 	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
3000dab3eba7SHeiko Stübner 	struct rockchip_pin_bank *bank = pin_to_bank(info, pin);
3001d3e51161SHeiko Stübner 	struct gpio_chip *gpio = &bank->gpio_chip;
3002d3e51161SHeiko Stübner 	enum pin_config_param param;
3003d3e51161SHeiko Stübner 	u32 arg;
3004d3e51161SHeiko Stübner 	int i;
3005d3e51161SHeiko Stübner 	int rc;
3006d3e51161SHeiko Stübner 
3007ed62f2f2SHeiko Stübner 	for (i = 0; i < num_configs; i++) {
3008d3e51161SHeiko Stübner 		param = pinconf_to_config_param(configs[i]);
3009d3e51161SHeiko Stübner 		arg = pinconf_to_config_argument(configs[i]);
301065fca613SHeiko Stübner 
301165fca613SHeiko Stübner 		if (param == PIN_CONFIG_OUTPUT || param == PIN_CONFIG_INPUT_ENABLE) {
30126ca5274dSHeiko Stübner 			/*
301365fca613SHeiko Stübner 			 * Check for gpio driver not being probed yet.
301465fca613SHeiko Stübner 			 * The lock makes sure that either gpio-probe has completed
3015d3e51161SHeiko Stübner 			 * or the gpio driver hasn't probed yet.
3016d3e51161SHeiko Stübner 			 */
3017d3e51161SHeiko Stübner 			mutex_lock(&bank->deferred_lock);
3018d3e51161SHeiko Stübner 			if (!gpio || !gpio->direction_output) {
3019d3e51161SHeiko Stübner 				rc = rockchip_pinconf_defer_pin(bank, pin - bank->pin_base, param,
3020d3e51161SHeiko Stübner 								arg);
3021d3e51161SHeiko Stübner 				mutex_unlock(&bank->deferred_lock);
302265fca613SHeiko Stübner 				if (rc)
3023d3e51161SHeiko Stübner 					return rc;
3024d3e51161SHeiko Stübner 
3025d3e51161SHeiko Stübner 				break;
3026d3e51161SHeiko Stübner 			}
3027d3e51161SHeiko Stübner 			mutex_unlock(&bank->deferred_lock);
3028d3e51161SHeiko Stübner 		}
3029d3e51161SHeiko Stübner 
3030d3e51161SHeiko Stübner 		switch (param) {
3031d3e51161SHeiko Stübner 		case PIN_CONFIG_BIAS_DISABLE:
3032d3e51161SHeiko Stübner 			rc =  rockchip_set_pull(bank, pin - bank->pin_base,
3033d3e51161SHeiko Stübner 				param);
3034d3e51161SHeiko Stübner 			if (rc)
3035e4dd7fd5SAndy Shevchenko 				return rc;
3036d3e51161SHeiko Stübner 			break;
3037d3e51161SHeiko Stübner 		case PIN_CONFIG_BIAS_PULL_UP:
3038d3e51161SHeiko Stübner 		case PIN_CONFIG_BIAS_PULL_DOWN:
3039d3e51161SHeiko Stübner 		case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
3040d3e51161SHeiko Stübner 		case PIN_CONFIG_BIAS_BUS_HOLD:
3041d3e51161SHeiko Stübner 			if (!rockchip_pinconf_pull_valid(info->ctrl, param))
3042d3e51161SHeiko Stübner 				return -ENOTSUPP;
3043e4dd7fd5SAndy Shevchenko 
3044d3e51161SHeiko Stübner 			if (!arg)
3045d3e51161SHeiko Stübner 				return -EINVAL;
3046d3e51161SHeiko Stübner 
3047d3e51161SHeiko Stübner 			rc = rockchip_set_pull(bank, pin - bank->pin_base,
3048d3e51161SHeiko Stübner 				param);
3049d3e51161SHeiko Stübner 			if (rc)
3050d3e51161SHeiko Stübner 				return rc;
3051d3e51161SHeiko Stübner 			break;
3052d3e51161SHeiko Stübner 		case PIN_CONFIG_OUTPUT:
3053d3e51161SHeiko Stübner 			rc = rockchip_set_mux(bank, pin - bank->pin_base,
3054d3e51161SHeiko Stübner 					      RK_FUNC_GPIO);
30550045028fSAndy Shevchenko 			if (rc != RK_FUNC_GPIO)
30560045028fSAndy Shevchenko 				return -EINVAL;
3057d3e51161SHeiko Stübner 
3058d3e51161SHeiko Stübner 			rc = gpio->direction_output(gpio, pin - bank->pin_base,
3059d3e51161SHeiko Stübner 						    arg);
3060e4dd7fd5SAndy Shevchenko 			if (rc)
3061e4dd7fd5SAndy Shevchenko 				return rc;
3062d3e51161SHeiko Stübner 			break;
3063d3e51161SHeiko Stübner 		case PIN_CONFIG_INPUT_ENABLE:
3064d3e51161SHeiko Stübner 			rc = rockchip_set_mux(bank, pin - bank->pin_base,
3065d3e51161SHeiko Stübner 					      RK_FUNC_GPIO);
3066d3e51161SHeiko Stübner 			if (rc != RK_FUNC_GPIO)
3067d3e51161SHeiko Stübner 				return -EINVAL;
3068d3e51161SHeiko Stübner 
3069d3e51161SHeiko Stübner 			rc = gpio->direction_input(gpio, pin - bank->pin_base);
3070d3e51161SHeiko Stübner 			if (rc)
3071d3e51161SHeiko Stübner 				return rc;
3072d3e51161SHeiko Stübner 			break;
3073d3e51161SHeiko Stübner 		case PIN_CONFIG_DRIVE_STRENGTH:
3074d3e51161SHeiko Stübner 			/* rk3288 is the first with per-pin drive-strength */
3075d3e51161SHeiko Stübner 			if (!info->ctrl->drv_calc_reg)
3076d3e51161SHeiko Stübner 				return -ENOTSUPP;
3077d3e51161SHeiko Stübner 
3078d3e51161SHeiko Stübner 			rc = rockchip_set_drive_perpin(bank,
3079d3e51161SHeiko Stübner 						pin - bank->pin_base, arg);
3080d3e51161SHeiko Stübner 			if (rc < 0)
3081d3e51161SHeiko Stübner 				return rc;
3082dd4d01f7SSoren Brinkmann 			break;
3083d3e51161SHeiko Stübner 		case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
3084c818ae56SMiaoqian Lin 			if (!info->ctrl->schmitt_calc_reg)
3085d3e51161SHeiko Stübner 				return -ENOTSUPP;
3086d3e51161SHeiko Stübner 
3087d3e51161SHeiko Stübner 			rc = rockchip_set_schmitt(bank,
3088d3e51161SHeiko Stübner 						  pin - bank->pin_base, arg);
3089d3e51161SHeiko Stübner 			if (rc < 0)
3090d3e51161SHeiko Stübner 				return rc;
3091d3e51161SHeiko Stübner 			break;
3092d3e51161SHeiko Stübner 		default:
3093d3e51161SHeiko Stübner 			return -ENOTSUPP;
3094d3e51161SHeiko Stübner 			break;
3095d3e51161SHeiko Stübner 		}
3096e4dd7fd5SAndy Shevchenko 	} /* for each config */
3097d3e51161SHeiko Stübner 
3098d3e51161SHeiko Stübner 	return 0;
3099d3e51161SHeiko Stübner }
3100d3e51161SHeiko Stübner 
3101d3e51161SHeiko Stübner /* get the pin config settings for a specified pin */
rockchip_pinconf_get(struct pinctrl_dev * pctldev,unsigned int pin,unsigned long * config)3102d3e51161SHeiko Stübner static int rockchip_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
3103e4dd7fd5SAndy Shevchenko 							unsigned long *config)
3104d3e51161SHeiko Stübner {
3105d3e51161SHeiko Stübner 	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
3106d3e51161SHeiko Stübner 	struct rockchip_pin_bank *bank = pin_to_bank(info, pin);
3107d3e51161SHeiko Stübner 	struct gpio_chip *gpio = &bank->gpio_chip;
3108d3e51161SHeiko Stübner 	enum pin_config_param param = pinconf_to_config_param(*config);
3109d3e51161SHeiko Stübner 	u16 arg;
3110d3e51161SHeiko Stübner 	int rc;
3111d3e51161SHeiko Stübner 
3112d3e51161SHeiko Stübner 	switch (param) {
3113e4dd7fd5SAndy Shevchenko 	case PIN_CONFIG_BIAS_DISABLE:
3114d3e51161SHeiko Stübner 		if (rockchip_get_pull(bank, pin - bank->pin_base) != param)
3115d3e51161SHeiko Stübner 			return -EINVAL;
3116d3e51161SHeiko Stübner 
311756c42f6cSPeng Fan 		arg = 0;
3118d3e51161SHeiko Stübner 		break;
3119d3e51161SHeiko Stübner 	case PIN_CONFIG_BIAS_PULL_UP:
3120d3e51161SHeiko Stübner 	case PIN_CONFIG_BIAS_PULL_DOWN:
312156c42f6cSPeng Fan 	case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
3122d3e51161SHeiko Stübner 	case PIN_CONFIG_BIAS_BUS_HOLD:
3123d3e51161SHeiko Stübner 		if (!rockchip_pinconf_pull_valid(info->ctrl, param))
3124d3e51161SHeiko Stübner 			return -ENOTSUPP;
3125d3e51161SHeiko Stübner 
3126d3e51161SHeiko Stübner 		if (rockchip_get_pull(bank, pin - bank->pin_base) != param)
3127d3e51161SHeiko Stübner 			return -EINVAL;
3128d3e51161SHeiko Stübner 
3129d3e51161SHeiko Stübner 		arg = 1;
3130d3e51161SHeiko Stübner 		break;
3131d3e51161SHeiko Stübner 	case PIN_CONFIG_OUTPUT:
3132d3e51161SHeiko Stübner 		rc = rockchip_get_mux(bank, pin - bank->pin_base);
3133d3e51161SHeiko Stübner 		if (rc != RK_FUNC_GPIO)
3134d3e51161SHeiko Stübner 			return -EINVAL;
3135d3e51161SHeiko Stübner 
3136d3e51161SHeiko Stübner 		if (!gpio || !gpio->get) {
3137d3e51161SHeiko Stübner 			arg = 0;
3138e4dd7fd5SAndy Shevchenko 			break;
3139e4dd7fd5SAndy Shevchenko 		}
3140d3e51161SHeiko Stübner 
3141e4dd7fd5SAndy Shevchenko 		rc = gpio->get(gpio, pin - bank->pin_base);
314298c8ee73SMarkus Elfring 		if (rc < 0)
3143c4f333b7SDafna Hirschfeld 			return rc;
3144d3e51161SHeiko Stübner 
3145e4dd7fd5SAndy Shevchenko 		arg = rc ? 1 : 0;
314698c8ee73SMarkus Elfring 		break;
3147c4f333b7SDafna Hirschfeld 	case PIN_CONFIG_DRIVE_STRENGTH:
3148d3e51161SHeiko Stübner 		/* rk3288 is the first with per-pin drive-strength */
3149d3e51161SHeiko Stübner 		if (!info->ctrl->drv_calc_reg)
3150d3e51161SHeiko Stübner 			return -ENOTSUPP;
315156c42f6cSPeng Fan 
315265fca613SHeiko Stübner 		rc = rockchip_get_drive_perpin(bank, pin - bank->pin_base);
3153d3e51161SHeiko Stübner 		if (rc < 0)
315465fca613SHeiko Stübner 			return rc;
3155d3e51161SHeiko Stübner 
3156d3e51161SHeiko Stübner 		arg = rc;
3157e4dd7fd5SAndy Shevchenko 		break;
3158d3e51161SHeiko Stübner 	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
3159d3e51161SHeiko Stübner 		if (!info->ctrl->schmitt_calc_reg)
3160d3e51161SHeiko Stübner 			return -ENOTSUPP;
3161d3e51161SHeiko Stübner 
3162d3e51161SHeiko Stübner 		rc = rockchip_get_schmitt(bank, pin - bank->pin_base);
3163d3e51161SHeiko Stübner 		if (rc < 0)
3164d3e51161SHeiko Stübner 			return rc;
3165d3e51161SHeiko Stübner 
3166d3e51161SHeiko Stübner 		arg = rc;
3167d3e51161SHeiko Stübner 		break;
3168d3e51161SHeiko Stübner 	default:
3169d3e51161SHeiko Stübner 		return -ENOTSUPP;
3170d3e51161SHeiko Stübner 		break;
3171e4dd7fd5SAndy Shevchenko 	}
3172069d7796SAndy Shevchenko 
3173d3e51161SHeiko Stübner 	*config = pinconf_to_config_packed(param, arg);
3174d3e51161SHeiko Stübner 
3175d3e51161SHeiko Stübner 	return 0;
3176d3e51161SHeiko Stübner }
3177d3e51161SHeiko Stübner 
3178d3e51161SHeiko Stübner static const struct pinconf_ops rockchip_pinconf_ops = {
3179d3e51161SHeiko Stübner 	.pin_config_get			= rockchip_pinconf_get,
3180d3e51161SHeiko Stübner 	.pin_config_set			= rockchip_pinconf_set,
3181d3e51161SHeiko Stübner 	.is_generic			= true,
3182e4dd7fd5SAndy Shevchenko };
318398c8ee73SMarkus Elfring 
3184d3e51161SHeiko Stübner static const struct of_device_id rockchip_bank_match[] = {
318598c8ee73SMarkus Elfring 	{ .compatible = "rockchip,gpio-bank" },
3186d3e51161SHeiko Stübner 	{ .compatible = "rockchip,rk3188-gpio-bank0" },
3187d3e51161SHeiko Stübner 	{},
3188d3e51161SHeiko Stübner };
3189d3e51161SHeiko Stübner 
rockchip_pinctrl_child_count(struct rockchip_pinctrl * info,struct device_node * np)3190d3e51161SHeiko Stübner static void rockchip_pinctrl_child_count(struct rockchip_pinctrl *info,
3191d3e51161SHeiko Stübner 						struct device_node *np)
3192069d7796SAndy Shevchenko {
3193069d7796SAndy Shevchenko 	struct device_node *child;
3194069d7796SAndy Shevchenko 
3195069d7796SAndy Shevchenko 	for_each_child_of_node(np, child) {
3196069d7796SAndy Shevchenko 		if (of_match_node(rockchip_bank_match, child))
3197d3e51161SHeiko Stübner 			continue;
3198d3e51161SHeiko Stübner 
3199069d7796SAndy Shevchenko 		info->nfunctions++;
3200d3e51161SHeiko Stübner 		info->ngroups += of_get_child_count(child);
3201d3e51161SHeiko Stübner 	}
3202e7165b1dSHeiko Stuebner }
32038ce5ef64SCaleb Connolly 
rockchip_pinctrl_parse_groups(struct device_node * np,struct rockchip_pin_group * grp,struct rockchip_pinctrl * info,u32 index)3204e7165b1dSHeiko Stuebner static int rockchip_pinctrl_parse_groups(struct device_node *np,
3205d3e51161SHeiko Stübner 					      struct rockchip_pin_group *grp,
3206d3e51161SHeiko Stübner 					      struct rockchip_pinctrl *info,
32070fb7dcb1SDoug Anderson 					      u32 index)
32080fb7dcb1SDoug Anderson {
32090fb7dcb1SDoug Anderson 	struct device *dev = info->dev;
32100fb7dcb1SDoug Anderson 	struct rockchip_pin_bank *bank;
3211e4dd7fd5SAndy Shevchenko 	int size;
32120045028fSAndy Shevchenko 	const __be32 *list;
32130045028fSAndy Shevchenko 	int num;
3214d3e51161SHeiko Stübner 	int i, j;
3215d3e51161SHeiko Stübner 	int ret;
3216d3e51161SHeiko Stübner 
3217d3e51161SHeiko Stübner 	dev_dbg(dev, "group(%d): %pOFn\n", index, np);
3218d3e51161SHeiko Stübner 
3219d3e51161SHeiko Stübner 	/* Initialise group */
3220d3e51161SHeiko Stübner 	grp->name = np->name;
3221d3e51161SHeiko Stübner 
3222d3e51161SHeiko Stübner 	/*
3223d3e51161SHeiko Stübner 	 * the binding format is rockchip,pins = <bank pin mux CONFIG>,
3224d3e51161SHeiko Stübner 	 * do sanity check and calculate pins number
3225e4dd7fd5SAndy Shevchenko 	 */
3226e4dd7fd5SAndy Shevchenko 	list = of_get_property(np, "rockchip,pins", &size);
3227d3e51161SHeiko Stübner 	/* we do not check return since it's safe node passed down */
3228d3e51161SHeiko Stübner 	size /= sizeof(*list);
3229d3e51161SHeiko Stübner 	if (!size || size % 4)
3230b6c23275SDavid Wu 		return dev_err_probe(dev, -EINVAL, "wrong pins number or pins and configs should be by 4\n");
3231d3e51161SHeiko Stübner 
3232d3e51161SHeiko Stübner 	grp->npins = size / 4;
3233d3e51161SHeiko Stübner 
3234d3e51161SHeiko Stübner 	grp->pins = devm_kcalloc(dev, grp->npins, sizeof(*grp->pins), GFP_KERNEL);
323595ec8ae4SHeiko Stübner 	grp->data = devm_kcalloc(dev, grp->npins, sizeof(*grp->data), GFP_KERNEL);
323695ec8ae4SHeiko Stübner 	if (!grp->pins || !grp->data)
3237b6c23275SDavid Wu 		return -ENOMEM;
3238b6c23275SDavid Wu 
3239d3e51161SHeiko Stübner 	for (i = 0, j = 0; i < size; i += 4, j++) {
3240d3e51161SHeiko Stübner 		const __be32 *phandle;
32416bc0d121SHeiko Stübner 		struct device_node *np_config;
32426bc0d121SHeiko Stübner 
324370b7aa7aSJohn Keeping 		num = be32_to_cpu(*list++);
3244d3e51161SHeiko Stübner 		bank = bank_num_to_bank(info, num);
3245d3e51161SHeiko Stübner 		if (IS_ERR(bank))
3246d3e51161SHeiko Stübner 			return PTR_ERR(bank);
32476bc0d121SHeiko Stübner 
3248b6c23275SDavid Wu 		grp->pins[j] = bank->pin_base + be32_to_cpu(*list++);
32496bc0d121SHeiko Stübner 		grp->data[j].func = be32_to_cpu(*list++);
32506bc0d121SHeiko Stübner 
3251b6c23275SDavid Wu 		phandle = list++;
325203716e1dSHeiko Stübner 		if (!phandle)
32536bc0d121SHeiko Stübner 			return -EINVAL;
32546bc0d121SHeiko Stübner 
32556bc0d121SHeiko Stübner 		np_config = of_find_node_by_phandle(be32_to_cpup(phandle));
32566bc0d121SHeiko Stübner 		ret = pinconf_generic_parse_dt_config(np_config, NULL,
3257b6c23275SDavid Wu 				&grp->data[j].configs, &grp->data[j].nconfigs);
32586bc0d121SHeiko Stübner 		of_node_put(np_config);
3259fd4ea486SJagan Teki 		if (ret)
3260fd4ea486SJagan Teki 			return ret;
326195ec8ae4SHeiko Stübner 	}
326295ec8ae4SHeiko Stübner 
32636bc0d121SHeiko Stübner 	return 0;
3264b6c23275SDavid Wu }
3265fd4ea486SJagan Teki 
rockchip_pinctrl_parse_functions(struct device_node * np,struct rockchip_pinctrl * info,u32 index)3266fd4ea486SJagan Teki static int rockchip_pinctrl_parse_functions(struct device_node *np,
326795ec8ae4SHeiko Stübner 						struct rockchip_pinctrl *info,
32686bc0d121SHeiko Stübner 						u32 index)
32696bc0d121SHeiko Stübner {
3270b6c23275SDavid Wu 	struct device *dev = info->dev;
3271b6c23275SDavid Wu 	struct rockchip_pmx_func *func;
3272b6c23275SDavid Wu 	struct rockchip_pin_group *grp;
3273b6c23275SDavid Wu 	int ret;
3274b6c23275SDavid Wu 	static u32 grp_index;
3275b6c23275SDavid Wu 	u32 i = 0;
3276b6c23275SDavid Wu 
3277b6c23275SDavid Wu 	dev_dbg(dev, "parse function(%d): %pOFn\n", index, np);
3278b6c23275SDavid Wu 
3279b6c23275SDavid Wu 	func = &info->functions[index];
3280b6c23275SDavid Wu 
3281e4dd7fd5SAndy Shevchenko 	/* Initialise function */
3282b6c23275SDavid Wu 	func->name = np->name;
32836bc0d121SHeiko Stübner 	func->ngroups = of_get_child_count(np);
32846bc0d121SHeiko Stübner 	if (func->ngroups <= 0)
32856bc0d121SHeiko Stübner 		return 0;
328603716e1dSHeiko Stübner 
32876bc0d121SHeiko Stübner 	func->groups = devm_kcalloc(dev, func->ngroups, sizeof(*func->groups), GFP_KERNEL);
32888b6c6f93Sdavid.wu 	if (!func->groups)
32897825aeb7SJianqun Xu 		return -ENOMEM;
32907825aeb7SJianqun Xu 
3291fd4ea486SJagan Teki 	for_each_child_of_node_scoped(np, child) {
329295ec8ae4SHeiko Stübner 		func->groups[i] = child->name;
329395ec8ae4SHeiko Stübner 		grp = &info->groups[grp_index++];
329403716e1dSHeiko Stübner 		ret = rockchip_pinctrl_parse_groups(child, grp, info, i++);
32956bc0d121SHeiko Stübner 		if (ret)
3296b6c23275SDavid Wu 			return ret;
3297b6c23275SDavid Wu 	}
3298b6c23275SDavid Wu 
3299b6c23275SDavid Wu 	return 0;
3300b6c23275SDavid Wu }
3301b6c23275SDavid Wu 
rockchip_pinctrl_parse_dt(struct platform_device * pdev,struct rockchip_pinctrl * info)3302b6c23275SDavid Wu static int rockchip_pinctrl_parse_dt(struct platform_device *pdev,
3303b6c23275SDavid Wu 					      struct rockchip_pinctrl *info)
3304b6c23275SDavid Wu {
3305b6c23275SDavid Wu 	struct device *dev = &pdev->dev;
3306b6c23275SDavid Wu 	struct device_node *np = dev->of_node;
3307b6c23275SDavid Wu 	int ret;
3308b6c23275SDavid Wu 	int i;
3309b6c23275SDavid Wu 
3310b6c23275SDavid Wu 	rockchip_pinctrl_child_count(info, np);
33116bc0d121SHeiko Stübner 
33126bc0d121SHeiko Stübner 	dev_dbg(dev, "nfunctions = %d\n", info->nfunctions);
3313bd35b9bfSDavid Wu 	dev_dbg(dev, "ngroups = %d\n", info->ngroups);
3314c04c3fa6SDavid Wu 
3315c04c3fa6SDavid Wu 	info->functions = devm_kcalloc(dev, info->nfunctions, sizeof(*info->functions), GFP_KERNEL);
3316c04c3fa6SDavid Wu 	if (!info->functions)
3317c04c3fa6SDavid Wu 		return -ENOMEM;
3318c04c3fa6SDavid Wu 
3319c04c3fa6SDavid Wu 	info->groups = devm_kcalloc(dev, info->ngroups, sizeof(*info->groups), GFP_KERNEL);
3320c04c3fa6SDavid Wu 	if (!info->groups)
3321c04c3fa6SDavid Wu 		return -ENOMEM;
3322c04c3fa6SDavid Wu 
3323c04c3fa6SDavid Wu 	i = 0;
3324bd35b9bfSDavid Wu 
3325bd35b9bfSDavid Wu 	for_each_child_of_node_scoped(np, child) {
3326bd35b9bfSDavid Wu 		if (of_match_node(rockchip_bank_match, child))
3327bd35b9bfSDavid Wu 			continue;
3328bd35b9bfSDavid Wu 
3329bd35b9bfSDavid Wu 		ret = rockchip_pinctrl_parse_functions(child, info, i++);
3330bd35b9bfSDavid Wu 		if (ret) {
3331bd35b9bfSDavid Wu 			dev_err(dev, "failed to parse function\n");
3332bd35b9bfSDavid Wu 			return ret;
3333d3e51161SHeiko Stübner 		}
3334d3e51161SHeiko Stübner 	}
3335d3e51161SHeiko Stübner 
3336d3e51161SHeiko Stübner 	return 0;
3337d3e51161SHeiko Stübner }
33388dca9331SChris Zhong 
rockchip_pinctrl_register(struct platform_device * pdev,struct rockchip_pinctrl * info)33398dca9331SChris Zhong static int rockchip_pinctrl_register(struct platform_device *pdev,
33408dca9331SChris Zhong 					struct rockchip_pinctrl *info)
33418dca9331SChris Zhong {
33428dca9331SChris Zhong 	struct pinctrl_desc *ctrldesc = &info->pctl;
33439198f509SChris Zhong 	struct pinctrl_pin_desc *pindesc, *pdesc;
33449198f509SChris Zhong 	struct rockchip_pin_bank *pin_bank;
33459198f509SChris Zhong 	struct device *dev = &pdev->dev;
33468dca9331SChris Zhong 	char **pin_names;
33479198f509SChris Zhong 	int pin, bank, ret;
33488dca9331SChris Zhong 	int k;
33498dca9331SChris Zhong 
33508dca9331SChris Zhong 	ctrldesc->name = "rockchip-pinctrl";
33518dca9331SChris Zhong 	ctrldesc->owner = THIS_MODULE;
33528dca9331SChris Zhong 	ctrldesc->pctlops = &rockchip_pctrl_ops;
33538dca9331SChris Zhong 	ctrldesc->pmxops = &rockchip_pmx_ops;
33548dca9331SChris Zhong 	ctrldesc->confops = &rockchip_pinconf_ops;
33558dca9331SChris Zhong 
33568dca9331SChris Zhong 	pindesc = devm_kcalloc(dev, info->ctrl->nr_pins, sizeof(*pindesc), GFP_KERNEL);
33578dca9331SChris Zhong 	if (!pindesc)
33588dca9331SChris Zhong 		return -ENOMEM;
33598dca9331SChris Zhong 
33608dca9331SChris Zhong 	ctrldesc->pins = pindesc;
33618dca9331SChris Zhong 	ctrldesc->npins = info->ctrl->nr_pins;
33628dca9331SChris Zhong 
33638dca9331SChris Zhong 	pdesc = pindesc;
33648dca9331SChris Zhong 	for (bank = 0, k = 0; bank < info->ctrl->nr_banks; bank++) {
33659198f509SChris Zhong 		pin_bank = &info->ctrl->pin_banks[bank];
33669198f509SChris Zhong 
33679198f509SChris Zhong 		pin_names = devm_kasprintf_strarray(dev, pin_bank->name, pin_bank->nr_pins);
33689198f509SChris Zhong 		if (IS_ERR(pin_names))
33699198f509SChris Zhong 			return PTR_ERR(pin_names);
3370c971af25SWang Panzhenzhuan 
3371c971af25SWang Panzhenzhuan 		for (pin = 0; pin < pin_bank->nr_pins; pin++, k++) {
3372c971af25SWang Panzhenzhuan 			pdesc->number = k;
3373c971af25SWang Panzhenzhuan 			pdesc->name = pin_names[pin];
33748dca9331SChris Zhong 			pdesc++;
33758dca9331SChris Zhong 		}
33768dca9331SChris Zhong 
33778dca9331SChris Zhong 		INIT_LIST_HEAD(&pin_bank->deferred_pins);
3378c971af25SWang Panzhenzhuan 		mutex_init(&pin_bank->deferred_lock);
33799198f509SChris Zhong 	}
33809198f509SChris Zhong 
33819198f509SChris Zhong 	ret = rockchip_pinctrl_parse_dt(pdev, info);
33829198f509SChris Zhong 	if (ret)
33839198f509SChris Zhong 		return ret;
33849198f509SChris Zhong 
33859198f509SChris Zhong 	info->pctl_dev = devm_pinctrl_register(dev, ctrldesc, info);
3386d3e51161SHeiko Stübner 	if (IS_ERR(info->pctl_dev))
3387d3e51161SHeiko Stübner 		return dev_err_probe(dev, PTR_ERR(info->pctl_dev), "could not register pinctrl driver\n");
3388d3e51161SHeiko Stübner 
3389d3e51161SHeiko Stübner 	return 0;
3390e4dd7fd5SAndy Shevchenko }
3391d3e51161SHeiko Stübner 
3392d3e51161SHeiko Stübner static const struct of_device_id rockchip_pinctrl_dt_match[];
3393751a99abSHeiko Stübner 
3394d3e51161SHeiko Stübner /* retrieve the soc specific data */
rockchip_pinctrl_get_soc_data(struct rockchip_pinctrl * d,struct platform_device * pdev)3395d3e51161SHeiko Stübner static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
33960045028fSAndy Shevchenko 						struct rockchip_pinctrl *d,
33970045028fSAndy Shevchenko 						struct platform_device *pdev)
3398d3e51161SHeiko Stübner {
3399283b7ac9SMarkus Elfring 	struct device *dev = &pdev->dev;
3400d3e51161SHeiko Stübner 	struct device_node *node = dev->of_node;
3401d3e51161SHeiko Stübner 	const struct of_device_id *match;
3402d3e51161SHeiko Stübner 	struct rockchip_pin_ctrl *ctrl;
3403622f3237SHeiko Stübner 	struct rockchip_pin_bank *bank;
3404622f3237SHeiko Stübner 	int grf_offs, pmu_offs, drv_grf_offs, drv_pmu_offs, i, j;
3405d3e51161SHeiko Stübner 
34060045028fSAndy Shevchenko 	match = of_match_node(rockchip_pinctrl_dt_match, node);
34070045028fSAndy Shevchenko 	ctrl = (struct rockchip_pin_ctrl *)match->data;
3408d3e51161SHeiko Stübner 
3409d3e51161SHeiko Stübner 	grf_offs = ctrl->grf_mux_offset;
34101e747e59SHeiko Stübner 	pmu_offs = ctrl->pmu_mux_offset;
34111e747e59SHeiko Stübner 	drv_pmu_offs = ctrl->pmu_drv_offset;
34121e747e59SHeiko Stübner 	drv_grf_offs = ctrl->grf_drv_offset;
341389388f87SMiaoqian Lin 	bank = ctrl->pin_banks;
34141e747e59SHeiko Stübner 	for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
34151e747e59SHeiko Stübner 		int bank_pins = 0;
34161e747e59SHeiko Stübner 
3417fb17dcd7SAndy Shevchenko 		raw_spin_lock_init(&bank->slock);
3418751a99abSHeiko Stübner 		bank->drvdata = d;
3419751a99abSHeiko Stübner 		bank->pin_base = ctrl->nr_pins;
3420751a99abSHeiko Stübner 		ctrl->nr_pins += bank->nr_pins;
3421751a99abSHeiko Stübner 
3422751a99abSHeiko Stübner 		/* calculate iomux and drv offsets */
3423e4dd7fd5SAndy Shevchenko 		for (j = 0; j < 4; j++) {
3424e4dd7fd5SAndy Shevchenko 			struct rockchip_iomux *iom = &bank->iomux[j];
3425d3e51161SHeiko Stübner 			struct rockchip_drv *drv = &bank->drv[j];
3426bfc7a42aSHeiko Stübner 			int inc;
3427bfc7a42aSHeiko Stübner 
3428bfc7a42aSHeiko Stübner 			if (bank_pins >= bank->nr_pins)
3429bfc7a42aSHeiko Stübner 				break;
3430bfc7a42aSHeiko Stübner 
3431fb17dcd7SAndy Shevchenko 			/* preset iomux offset value, set new start value */
3432751a99abSHeiko Stübner 			if (iom->offset >= 0) {
3433751a99abSHeiko Stübner 				if ((iom->type & IOMUX_SOURCE_PMU) ||
3434751a99abSHeiko Stübner 				    (iom->type & IOMUX_L_SOURCE_PMU))
3435e4dd7fd5SAndy Shevchenko 					pmu_offs = iom->offset;
3436751a99abSHeiko Stübner 				else
3437e4dd7fd5SAndy Shevchenko 					grf_offs = iom->offset;
3438e4dd7fd5SAndy Shevchenko 			} else { /* set current iomux offset */
34396ca5274dSHeiko Stübner 				iom->offset = ((iom->type & IOMUX_SOURCE_PMU) ||
34401e747e59SHeiko Stübner 					       (iom->type & IOMUX_L_SOURCE_PMU)) ?
34416ca5274dSHeiko Stübner 							pmu_offs : grf_offs;
344214dee867SHeiko Stübner 			}
344314dee867SHeiko Stübner 
344414dee867SHeiko Stübner 			/* preset drv offset value, set new start value */
344514dee867SHeiko Stübner 			if (drv->offset >= 0) {
344689388f87SMiaoqian Lin 				if (iom->type & IOMUX_SOURCE_PMU)
344714dee867SHeiko Stübner 					drv_pmu_offs = drv->offset;
344814dee867SHeiko Stübner 				else
344914dee867SHeiko Stübner 					drv_grf_offs = drv->offset;
345014dee867SHeiko Stübner 			} else { /* set current drv offset */
34519ce9a020SJianqun Xu 				drv->offset = (iom->type & IOMUX_SOURCE_PMU) ?
3452d3e51161SHeiko Stübner 						drv_pmu_offs : drv_grf_offs;
3453d3e51161SHeiko Stübner 			}
3454d3e51161SHeiko Stübner 
34559ce9a020SJianqun Xu 			dev_dbg(dev, "bank %d, iomux %d has iom_offset 0x%x drv_offset 0x%x\n",
34569ce9a020SJianqun Xu 				i, j, iom->offset, drv->offset);
3457bceb6732SJohn Keeping 
34580045028fSAndy Shevchenko 			/*
34590045028fSAndy Shevchenko 			 * Increase offset according to iomux width.
3460d3e51161SHeiko Stübner 			 * 4bit iomux'es are spread over two registers.
3461d3e51161SHeiko Stübner 			 */
3462d3e51161SHeiko Stübner 			inc = (iom->type & (IOMUX_WIDTH_4BIT |
3463d3e51161SHeiko Stübner 					    IOMUX_WIDTH_3BIT |
346497258777SUwe Kleine-König 					    IOMUX_WIDTH_2BIT)) ? 8 : 4;
3465e7165b1dSHeiko Stuebner 			if ((iom->type & IOMUX_SOURCE_PMU) || (iom->type & IOMUX_L_SOURCE_PMU))
3466e7165b1dSHeiko Stuebner 				pmu_offs += inc;
3467e7165b1dSHeiko Stuebner 			else
34688ce5ef64SCaleb Connolly 				grf_offs += inc;
3469e7165b1dSHeiko Stuebner 
3470e7165b1dSHeiko Stuebner 			/*
3471e7165b1dSHeiko Stuebner 			 * Increase offset according to drv width.
3472e7165b1dSHeiko Stuebner 			 * 3bit drive-strenth'es are spread over two registers.
3473e7165b1dSHeiko Stuebner 			 */
3474e7165b1dSHeiko Stuebner 			if ((drv->drv_type == DRV_TYPE_IO_1V8_3V0_AUTO) ||
3475e7165b1dSHeiko Stuebner 			    (drv->drv_type == DRV_TYPE_IO_3V3_ONLY))
3476e7165b1dSHeiko Stuebner 				inc = 8;
34778ce5ef64SCaleb Connolly 			else
34788ce5ef64SCaleb Connolly 				inc = 4;
34798ce5ef64SCaleb Connolly 
3480e7165b1dSHeiko Stuebner 			if (iom->type & IOMUX_SOURCE_PMU)
3481e7165b1dSHeiko Stuebner 				drv_pmu_offs += inc;
3482e7165b1dSHeiko Stuebner 			else
3483e7165b1dSHeiko Stuebner 				drv_grf_offs += inc;
3484e7165b1dSHeiko Stuebner 
3485e7165b1dSHeiko Stuebner 			bank_pins += 8;
3486e7165b1dSHeiko Stuebner 		}
348787065ca9SDavid Wu 
348887065ca9SDavid Wu 		/* calculate the per-bank recalced_mask */
348987065ca9SDavid Wu 		for (j = 0; j < ctrl->niomux_recalced; j++) {
349087065ca9SDavid Wu 			int pin = 0;
349187065ca9SDavid Wu 
349287065ca9SDavid Wu 			if (ctrl->iomux_recalced[j].num == bank->bank_num) {
349387065ca9SDavid Wu 				pin = ctrl->iomux_recalced[j].pin;
349487065ca9SDavid Wu 				bank->recalced_mask |= BIT(pin);
349587065ca9SDavid Wu 			}
349687065ca9SDavid Wu 		}
349787065ca9SDavid Wu 
349887065ca9SDavid Wu 		/* calculate the per-bank route_mask */
349987065ca9SDavid Wu 		for (j = 0; j < ctrl->niomux_routes; j++) {
350087065ca9SDavid Wu 			int pin = 0;
350187065ca9SDavid Wu 
350287065ca9SDavid Wu 			if (ctrl->iomux_routes[j].bank_num == bank->bank_num) {
350387065ca9SDavid Wu 				pin = ctrl->iomux_routes[j].pin;
350487065ca9SDavid Wu 				bank->route_mask |= BIT(pin);
350587065ca9SDavid Wu 			}
350687065ca9SDavid Wu 		}
350787065ca9SDavid Wu 	}
350887065ca9SDavid Wu 
350987065ca9SDavid Wu 	return ctrl;
351087065ca9SDavid Wu }
351187065ca9SDavid Wu 
351287065ca9SDavid Wu #define RK3288_GRF_GPIO6C_IOMUX		0x64
351387065ca9SDavid Wu #define GPIO6C6_SEL_WRITE_ENABLE	BIT(28)
351487065ca9SDavid Wu 
351587065ca9SDavid Wu static u32 rk3288_grf_gpio6c_iomux;
351687065ca9SDavid Wu 
rockchip_pinctrl_suspend(struct device * dev)351787065ca9SDavid Wu static int __maybe_unused rockchip_pinctrl_suspend(struct device *dev)
351887065ca9SDavid Wu {
351987065ca9SDavid Wu 	struct rockchip_pinctrl *info = dev_get_drvdata(dev);
352087065ca9SDavid Wu 	int ret = pinctrl_force_sleep(info->pctl_dev);
352187065ca9SDavid Wu 
352287065ca9SDavid Wu 	if (ret)
352387065ca9SDavid Wu 		return ret;
3524b9c6dcabSAndy Yan 
3525688daf23SAndy Yan 	/*
3526688daf23SAndy Yan 	 * RK3288 GPIO6_C6 mux would be modified by Maskrom when resume, so save
3527688daf23SAndy Yan 	 * the setting here, and restore it at resume.
3528688daf23SAndy Yan 	 */
3529688daf23SAndy Yan 	if (info->ctrl->type == RK3288) {
3530688daf23SAndy Yan 		ret = regmap_read(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX,
3531688daf23SAndy Yan 				  &rk3288_grf_gpio6c_iomux);
3532688daf23SAndy Yan 		if (ret) {
3533688daf23SAndy Yan 			pinctrl_force_default(info->pctl_dev);
3534b9c6dcabSAndy Yan 			return ret;
3535b9c6dcabSAndy Yan 		}
3536b9c6dcabSAndy Yan 	}
3537b9c6dcabSAndy Yan 
3538b9c6dcabSAndy Yan 	return 0;
3539688daf23SAndy Yan }
3540688daf23SAndy Yan 
rockchip_pinctrl_resume(struct device * dev)354112b8f018SDavid Wu static int __maybe_unused rockchip_pinctrl_resume(struct device *dev)
354212b8f018SDavid Wu {
3543b9c6dcabSAndy Yan 	struct rockchip_pinctrl *info = dev_get_drvdata(dev);
3544b9c6dcabSAndy Yan 	int ret;
35455caff7eaSAndy Yan 
3546688daf23SAndy Yan 	if (info->ctrl->type == RK3288) {
3547688daf23SAndy Yan 		ret = regmap_write(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX,
3548fd4ea486SJagan Teki 				   rk3288_grf_gpio6c_iomux |
3549fd4ea486SJagan Teki 				   GPIO6C6_SEL_WRITE_ENABLE);
3550fd4ea486SJagan Teki 		if (ret)
3551fd4ea486SJagan Teki 			return ret;
3552fd4ea486SJagan Teki 	}
3553fd4ea486SJagan Teki 
3554fd4ea486SJagan Teki 	return pinctrl_force_default(info->pctl_dev);
3555fd4ea486SJagan Teki }
3556fd4ea486SJagan Teki 
3557fd4ea486SJagan Teki static SIMPLE_DEV_PM_OPS(rockchip_pinctrl_dev_pm_ops, rockchip_pinctrl_suspend,
3558fd4ea486SJagan Teki 			 rockchip_pinctrl_resume);
3559fd4ea486SJagan Teki 
rockchip_pinctrl_probe(struct platform_device * pdev)3560fd4ea486SJagan Teki static int rockchip_pinctrl_probe(struct platform_device *pdev)
3561fd4ea486SJagan Teki {
3562fd4ea486SJagan Teki 	struct rockchip_pinctrl *info;
3563fd4ea486SJagan Teki 	struct device *dev = &pdev->dev;
3564fd4ea486SJagan Teki 	struct device_node *np = dev->of_node, *node;
3565fd4ea486SJagan Teki 	struct rockchip_pin_ctrl *ctrl;
3566fd4ea486SJagan Teki 	struct resource *res;
3567fd4ea486SJagan Teki 	void __iomem *base;
3568fd4ea486SJagan Teki 	int ret;
3569fd4ea486SJagan Teki 
3570fd4ea486SJagan Teki 	if (!dev->of_node)
3571fd4ea486SJagan Teki 		return dev_err_probe(dev, -ENODEV, "device tree node not found\n");
3572fd4ea486SJagan Teki 
3573fd4ea486SJagan Teki 	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
3574fd4ea486SJagan Teki 	if (!info)
3575fd4ea486SJagan Teki 		return -ENOMEM;
3576fd4ea486SJagan Teki 
3577fd4ea486SJagan Teki 	info->dev = dev;
3578fd4ea486SJagan Teki 
3579fd4ea486SJagan Teki 	ctrl = rockchip_pinctrl_get_soc_data(info, pdev);
3580fd4ea486SJagan Teki 	if (!ctrl)
3581fd4ea486SJagan Teki 		return dev_err_probe(dev, -EINVAL, "driver data not available\n");
3582fd4ea486SJagan Teki 	info->ctrl = ctrl;
3583fd4ea486SJagan Teki 
3584fd4ea486SJagan Teki 	node = of_parse_phandle(np, "rockchip,grf", 0);
3585fd4ea486SJagan Teki 	if (node) {
3586fd4ea486SJagan Teki 		info->regmap_base = syscon_node_to_regmap(node);
3587fd4ea486SJagan Teki 		of_node_put(node);
3588fd4ea486SJagan Teki 		if (IS_ERR(info->regmap_base))
3589fd4ea486SJagan Teki 			return PTR_ERR(info->regmap_base);
3590d3e51161SHeiko Stübner 	} else {
3591d3e51161SHeiko Stübner 		base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
3592d3e51161SHeiko Stübner 		if (IS_ERR(base))
3593d3e51161SHeiko Stübner 			return PTR_ERR(base);
3594d3e51161SHeiko Stübner 
3595d3e51161SHeiko Stübner 		rockchip_regmap_config.max_register = resource_size(res) - 4;
3596d3e51161SHeiko Stübner 		rockchip_regmap_config.name = "rockchip,pinctrl";
3597d3e51161SHeiko Stübner 		info->regmap_base =
3598d3e51161SHeiko Stübner 			devm_regmap_init_mmio(dev, base, &rockchip_regmap_config);
3599d3e51161SHeiko Stübner 
3600d3e51161SHeiko Stübner 		/* to check for the old dt-bindings */
3601a282926dSHeiko Stübner 		info->reg_size = resource_size(res);
360295ec8ae4SHeiko Stübner 
3603a282926dSHeiko Stübner 		/* Honor the old binding, with pull registers as 2nd resource */
3604d3e51161SHeiko Stübner 		if (ctrl->type == RK3188 && info->reg_size < 0x200) {
3605d3e51161SHeiko Stübner 			base = devm_platform_get_and_ioremap_resource(pdev, 1, &res);
3606c5ce7670SXing Zheng 			if (IS_ERR(base))
3607c5ce7670SXing Zheng 				return PTR_ERR(base);
3608c5ce7670SXing Zheng 
3609c5ce7670SXing Zheng 			rockchip_regmap_config.max_register = resource_size(res) - 4;
3610c5ce7670SXing Zheng 			rockchip_regmap_config.name = "rockchip,pinctrl-pull";
3611c5ce7670SXing Zheng 			info->regmap_pull =
3612c5ce7670SXing Zheng 				devm_regmap_init_mmio(dev, base, &rockchip_regmap_config);
3613c5ce7670SXing Zheng 		}
3614c5ce7670SXing Zheng 	}
3615c5ce7670SXing Zheng 
3616c5ce7670SXing Zheng 	/* try to find the optional reference to the pmu syscon */
3617c5ce7670SXing Zheng 	node = of_parse_phandle(np, "rockchip,pmu", 0);
3618c5ce7670SXing Zheng 	if (node) {
3619c5ce7670SXing Zheng 		info->regmap_pmu = syscon_node_to_regmap(node);
3620c5ce7670SXing Zheng 		of_node_put(node);
3621d3e51161SHeiko Stübner 		if (IS_ERR(info->regmap_pmu))
3622d3e51161SHeiko Stübner 			return PTR_ERR(info->regmap_pmu);
3623d3e51161SHeiko Stübner 	}
3624d3e51161SHeiko Stübner 
3625d3e51161SHeiko Stübner 	ret = rockchip_pinctrl_register(pdev, info);
3626d3e51161SHeiko Stübner 	if (ret)
3627d3e51161SHeiko Stübner 		return ret;
3628d3e51161SHeiko Stübner 
3629d3e51161SHeiko Stübner 	platform_set_drvdata(pdev, info);
3630d3e51161SHeiko Stübner 
3631d3e51161SHeiko Stübner 	ret = of_platform_populate(np, NULL, NULL, &pdev->dev);
3632d3e51161SHeiko Stübner 	if (ret)
3633d3e51161SHeiko Stübner 		return dev_err_probe(dev, ret, "failed to register gpio device\n");
3634a282926dSHeiko Stübner 
363595ec8ae4SHeiko Stübner 	return 0;
3636a282926dSHeiko Stübner }
3637d3e51161SHeiko Stübner 
rockchip_pinctrl_remove(struct platform_device * pdev)3638d3e51161SHeiko Stübner static void rockchip_pinctrl_remove(struct platform_device *pdev)
3639d3e51161SHeiko Stübner {
3640d3e51161SHeiko Stübner 	struct rockchip_pinctrl *info = platform_get_drvdata(pdev);
3641d3e51161SHeiko Stübner 	struct rockchip_pin_bank *bank;
3642d3e51161SHeiko Stübner 	struct rockchip_pin_deferred *cfg;
3643d3e51161SHeiko Stübner 	int i;
3644d3e51161SHeiko Stübner 
3645d3e51161SHeiko Stübner 	of_platform_depopulate(&pdev->dev);
3646d3e51161SHeiko Stübner 
3647d3e51161SHeiko Stübner 	for (i = 0; i < info->ctrl->nr_banks; i++) {
3648d3e51161SHeiko Stübner 		bank = &info->ctrl->pin_banks[i];
3649d3e51161SHeiko Stübner 
3650a282926dSHeiko Stübner 		mutex_lock(&bank->deferred_lock);
365195ec8ae4SHeiko Stübner 		while (!list_empty(&bank->deferred_pins)) {
3652d3e51161SHeiko Stübner 			cfg = list_first_entry(&bank->deferred_pins,
3653d3e51161SHeiko Stübner 					       struct rockchip_pin_deferred, head);
3654d23c66dfSDavid Wu 			list_del(&cfg->head);
3655d23c66dfSDavid Wu 			kfree(cfg);
3656d23c66dfSDavid Wu 		}
3657d23c66dfSDavid Wu 		mutex_unlock(&bank->deferred_lock);
3658d23c66dfSDavid Wu 	}
3659d23c66dfSDavid Wu }
3660d23c66dfSDavid Wu 
3661d23c66dfSDavid Wu static struct rockchip_pin_bank px30_pin_banks[] = {
3662d23c66dfSDavid Wu 	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU,
3663d23c66dfSDavid Wu 					     IOMUX_SOURCE_PMU,
3664d23c66dfSDavid Wu 					     IOMUX_SOURCE_PMU,
3665d23c66dfSDavid Wu 					     IOMUX_SOURCE_PMU
3666d23c66dfSDavid Wu 			    ),
3667d23c66dfSDavid Wu 	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT,
3668d23c66dfSDavid Wu 					     IOMUX_WIDTH_4BIT,
3669d23c66dfSDavid Wu 					     IOMUX_WIDTH_4BIT,
3670d23c66dfSDavid Wu 					     IOMUX_WIDTH_4BIT
3671d23c66dfSDavid Wu 			    ),
3672d23c66dfSDavid Wu 	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT,
3673d23c66dfSDavid Wu 					     IOMUX_WIDTH_4BIT,
3674d3e51161SHeiko Stübner 					     IOMUX_WIDTH_4BIT,
3675fc72c923SHeiko Stübner 					     IOMUX_WIDTH_4BIT
3676d3e51161SHeiko Stübner 			    ),
3677d3e51161SHeiko Stübner 	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT,
3678d3e51161SHeiko Stübner 					     IOMUX_WIDTH_4BIT,
3679d3e51161SHeiko Stübner 					     IOMUX_WIDTH_4BIT,
3680d3e51161SHeiko Stübner 					     IOMUX_WIDTH_4BIT
3681d3e51161SHeiko Stübner 			    ),
3682d3e51161SHeiko Stübner };
3683d3e51161SHeiko Stübner 
3684d3e51161SHeiko Stübner static struct rockchip_pin_ctrl px30_pin_ctrl = {
3685a282926dSHeiko Stübner 		.pin_banks		= px30_pin_banks,
368695ec8ae4SHeiko Stübner 		.nr_banks		= ARRAY_SIZE(px30_pin_banks),
3687ada62b7cSHeiko Stuebner 		.label			= "PX30-GPIO",
3688ada62b7cSHeiko Stuebner 		.type			= PX30,
36896ca5274dSHeiko Stübner 		.grf_mux_offset		= 0x0,
3690d3e51161SHeiko Stübner 		.pmu_mux_offset		= 0x0,
3691d3e51161SHeiko Stübner 		.iomux_routes		= px30_mux_route_data,
3692fea0fe60SJeffy Chen 		.niomux_routes		= ARRAY_SIZE(px30_mux_route_data),
3693fea0fe60SJeffy Chen 		.pull_calc_reg		= px30_calc_pull_reg_and_bit,
3694fea0fe60SJeffy Chen 		.drv_calc_reg		= px30_calc_drv_reg_and_bit,
3695fea0fe60SJeffy Chen 		.schmitt_calc_reg	= px30_calc_schmitt_reg_and_bit,
3696fea0fe60SJeffy Chen };
3697fea0fe60SJeffy Chen 
3698fea0fe60SJeffy Chen static struct rockchip_pin_bank rv1108_pin_banks[] = {
3699fea0fe60SJeffy Chen 	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU,
3700fea0fe60SJeffy Chen 					     IOMUX_SOURCE_PMU,
3701fea0fe60SJeffy Chen 					     IOMUX_SOURCE_PMU,
3702fea0fe60SJeffy Chen 					     IOMUX_SOURCE_PMU),
3703fea0fe60SJeffy Chen 	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0),
3704fea0fe60SJeffy Chen 	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, 0),
3705d4970ee0SDavid Wu 	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, 0),
3706d4970ee0SDavid Wu };
3707fea0fe60SJeffy Chen 
3708fea0fe60SJeffy Chen static struct rockchip_pin_ctrl rv1108_pin_ctrl = {
3709fea0fe60SJeffy Chen 	.pin_banks		= rv1108_pin_banks,
3710fea0fe60SJeffy Chen 	.nr_banks		= ARRAY_SIZE(rv1108_pin_banks),
3711304f077dSHeiko Stübner 	.label			= "RV1108-GPIO",
3712304f077dSHeiko Stübner 	.type			= RV1108,
3713304f077dSHeiko Stübner 	.grf_mux_offset		= 0x10,
3714304f077dSHeiko Stübner 	.pmu_mux_offset		= 0x0,
3715304f077dSHeiko Stübner 	.iomux_recalced		= rv1108_mux_recalced_data,
3716304f077dSHeiko Stübner 	.niomux_recalced	= ARRAY_SIZE(rv1108_mux_recalced_data),
3717304f077dSHeiko Stübner 	.pull_calc_reg		= rv1108_calc_pull_reg_and_bit,
3718304f077dSHeiko Stübner 	.drv_calc_reg		= rv1108_calc_drv_reg_and_bit,
3719304f077dSHeiko Stübner 	.schmitt_calc_reg	= rv1108_calc_schmitt_reg_and_bit,
3720304f077dSHeiko Stübner };
3721304f077dSHeiko Stübner 
3722304f077dSHeiko Stübner static struct rockchip_pin_bank rv1126_pin_banks[] = {
3723304f077dSHeiko Stübner 	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0",
3724304f077dSHeiko Stübner 			     IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU,
3725304f077dSHeiko Stübner 			     IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU,
3726304f077dSHeiko Stübner 			     IOMUX_WIDTH_4BIT | IOMUX_L_SOURCE_PMU,
3727304f077dSHeiko Stübner 			     IOMUX_WIDTH_4BIT),
3728304f077dSHeiko Stübner 	PIN_BANK_IOMUX_FLAGS_OFFSET(1, 32, "gpio1",
3729304f077dSHeiko Stübner 				    IOMUX_WIDTH_4BIT,
3730304f077dSHeiko Stübner 				    IOMUX_WIDTH_4BIT,
3731304f077dSHeiko Stübner 				    IOMUX_WIDTH_4BIT,
3732304f077dSHeiko Stübner 				    IOMUX_WIDTH_4BIT,
3733304f077dSHeiko Stübner 				    0x10010, 0x10018, 0x10020, 0x10028),
3734304f077dSHeiko Stübner 	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2",
3735304f077dSHeiko Stübner 			     IOMUX_WIDTH_4BIT,
3736304f077dSHeiko Stübner 			     IOMUX_WIDTH_4BIT,
3737304f077dSHeiko Stübner 			     IOMUX_WIDTH_4BIT,
3738304f077dSHeiko Stübner 			     IOMUX_WIDTH_4BIT),
3739304f077dSHeiko Stübner 	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3",
3740304f077dSHeiko Stübner 			     IOMUX_WIDTH_4BIT,
3741304f077dSHeiko Stübner 			     IOMUX_WIDTH_4BIT,
3742304f077dSHeiko Stübner 			     IOMUX_WIDTH_4BIT,
3743304f077dSHeiko Stübner 			     IOMUX_WIDTH_4BIT),
3744304f077dSHeiko Stübner 	PIN_BANK_IOMUX_FLAGS(4, 2, "gpio4",
3745304f077dSHeiko Stübner 			     IOMUX_WIDTH_4BIT, 0, 0, 0),
3746304f077dSHeiko Stübner };
374766d750e1SHeiko Stübner 
3748304f077dSHeiko Stübner static struct rockchip_pin_ctrl rv1126_pin_ctrl = {
3749304f077dSHeiko Stübner 	.pin_banks		= rv1126_pin_banks,
37504e96fd30SHeiko Stuebner 	.nr_banks		= ARRAY_SIZE(rv1126_pin_banks),
37514e96fd30SHeiko Stuebner 	.label			= "RV1126-GPIO",
3752304f077dSHeiko Stübner 	.type			= RV1126,
3753ef17f69fSHeiko Stübner 	.grf_mux_offset		= 0x10004, /* mux offset from GPIO0_D0 */
3754304f077dSHeiko Stübner 	.pmu_mux_offset		= 0x0,
3755304f077dSHeiko Stübner 	.iomux_routes		= rv1126_mux_route_data,
37567825aeb7SJianqun Xu 	.niomux_routes		= ARRAY_SIZE(rv1126_mux_route_data),
37577825aeb7SJianqun Xu 	.iomux_recalced		= rv1126_mux_recalced_data,
37587825aeb7SJianqun Xu 	.niomux_recalced	= ARRAY_SIZE(rv1126_mux_recalced_data),
37597825aeb7SJianqun Xu 	.pull_calc_reg		= rv1126_calc_pull_reg_and_bit,
37607825aeb7SJianqun Xu 	.drv_calc_reg		= rv1126_calc_drv_reg_and_bit,
37617825aeb7SJianqun Xu 	.schmitt_calc_reg	= rv1126_calc_schmitt_reg_and_bit,
37627825aeb7SJianqun Xu };
37637825aeb7SJianqun Xu 
37647825aeb7SJianqun Xu static struct rockchip_pin_bank rk2928_pin_banks[] = {
37657825aeb7SJianqun Xu 	PIN_BANK(0, 32, "gpio0"),
37667825aeb7SJianqun Xu 	PIN_BANK(1, 32, "gpio1"),
37677825aeb7SJianqun Xu 	PIN_BANK(2, 32, "gpio2"),
37687825aeb7SJianqun Xu 	PIN_BANK(3, 32, "gpio3"),
37697825aeb7SJianqun Xu };
37707825aeb7SJianqun Xu 
37717825aeb7SJianqun Xu static struct rockchip_pin_ctrl rk2928_pin_ctrl = {
37727825aeb7SJianqun Xu 		.pin_banks		= rk2928_pin_banks,
37737825aeb7SJianqun Xu 		.nr_banks		= ARRAY_SIZE(rk2928_pin_banks),
37747825aeb7SJianqun Xu 		.label			= "RK2928-GPIO",
37757825aeb7SJianqun Xu 		.type			= RK2928,
37767825aeb7SJianqun Xu 		.grf_mux_offset		= 0xa8,
37777825aeb7SJianqun Xu 		.pull_calc_reg		= rk2928_calc_pull_reg_and_bit,
37787825aeb7SJianqun Xu };
37797825aeb7SJianqun Xu 
37807825aeb7SJianqun Xu static struct rockchip_pin_bank rk3036_pin_banks[] = {
37817825aeb7SJianqun Xu 	PIN_BANK(0, 32, "gpio0"),
37827825aeb7SJianqun Xu 	PIN_BANK(1, 32, "gpio1"),
37837825aeb7SJianqun Xu 	PIN_BANK(2, 32, "gpio2"),
37847825aeb7SJianqun Xu };
37857825aeb7SJianqun Xu 
37867825aeb7SJianqun Xu static struct rockchip_pin_ctrl rk3036_pin_ctrl = {
37877825aeb7SJianqun Xu 		.pin_banks		= rk3036_pin_banks,
37887825aeb7SJianqun Xu 		.nr_banks		= ARRAY_SIZE(rk3036_pin_banks),
37897825aeb7SJianqun Xu 		.label			= "RK3036-GPIO",
37907825aeb7SJianqun Xu 		.type			= RK2928,
37917825aeb7SJianqun Xu 		.grf_mux_offset		= 0xa8,
37927825aeb7SJianqun Xu 		.pull_calc_reg		= rk2928_calc_pull_reg_and_bit,
37937825aeb7SJianqun Xu };
37943818e4a7Sdavid.wu 
37953818e4a7Sdavid.wu static struct rockchip_pin_bank rk3066a_pin_banks[] = {
37963818e4a7Sdavid.wu 	PIN_BANK(0, 32, "gpio0"),
37973818e4a7Sdavid.wu 	PIN_BANK(1, 32, "gpio1"),
3798*128f71feSHuang-Huang Bao 	PIN_BANK(2, 32, "gpio2"),
3799c04c3fa6SDavid Wu 	PIN_BANK(3, 32, "gpio3"),
38003818e4a7Sdavid.wu 	PIN_BANK(4, 32, "gpio4"),
38013818e4a7Sdavid.wu 	PIN_BANK(6, 16, "gpio6"),
38023818e4a7Sdavid.wu };
3803c04c3fa6SDavid Wu 
38043818e4a7Sdavid.wu static struct rockchip_pin_ctrl rk3066a_pin_ctrl = {
38053818e4a7Sdavid.wu 		.pin_banks		= rk3066a_pin_banks,
38063818e4a7Sdavid.wu 		.nr_banks		= ARRAY_SIZE(rk3066a_pin_banks),
38073818e4a7Sdavid.wu 		.label			= "RK3066a-GPIO",
38083818e4a7Sdavid.wu 		.type			= RK2928,
38093818e4a7Sdavid.wu 		.grf_mux_offset		= 0xa8,
38103818e4a7Sdavid.wu 		.pull_calc_reg		= rk2928_calc_pull_reg_and_bit,
38113818e4a7Sdavid.wu };
381201b4b1d1SHuang-Huang Bao 
38133818e4a7Sdavid.wu static struct rockchip_pin_bank rk3066b_pin_banks[] = {
3814c04c3fa6SDavid Wu 	PIN_BANK(0, 32, "gpio0"),
3815c04c3fa6SDavid Wu 	PIN_BANK(1, 32, "gpio1"),
3816cedc964aSDavid Wu 	PIN_BANK(2, 32, "gpio2"),
3817cedc964aSDavid Wu 	PIN_BANK(3, 32, "gpio3"),
38183818e4a7Sdavid.wu };
38193818e4a7Sdavid.wu 
3820728d3f5aSdavid.wu static struct rockchip_pin_ctrl rk3066b_pin_ctrl = {
38213818e4a7Sdavid.wu 		.pin_banks	= rk3066b_pin_banks,
38223818e4a7Sdavid.wu 		.nr_banks	= ARRAY_SIZE(rk3066b_pin_banks),
3823daecdc66SHeiko Stübner 		.label		= "RK3066b-GPIO",
3824daecdc66SHeiko Stübner 		.type		= RK3066B,
3825daecdc66SHeiko Stübner 		.grf_mux_offset	= 0x60,
3826daecdc66SHeiko Stübner };
3827daecdc66SHeiko Stübner 
3828daecdc66SHeiko Stübner static struct rockchip_pin_bank rk3128_pin_banks[] = {
3829daecdc66SHeiko Stübner 	PIN_BANK(0, 32, "gpio0"),
3830daecdc66SHeiko Stübner 	PIN_BANK(1, 32, "gpio1"),
3831daecdc66SHeiko Stübner 	PIN_BANK(2, 32, "gpio2"),
3832daecdc66SHeiko Stübner 	PIN_BANK(3, 32, "gpio3"),
3833daecdc66SHeiko Stübner };
3834daecdc66SHeiko Stübner 
3835daecdc66SHeiko Stübner static struct rockchip_pin_ctrl rk3128_pin_ctrl = {
3836daecdc66SHeiko Stübner 		.pin_banks		= rk3128_pin_banks,
3837daecdc66SHeiko Stübner 		.nr_banks		= ARRAY_SIZE(rk3128_pin_banks),
3838daecdc66SHeiko Stübner 		.label			= "RK3128-GPIO",
3839daecdc66SHeiko Stübner 		.type			= RK3128,
3840daecdc66SHeiko Stübner 		.grf_mux_offset		= 0xa8,
3841daecdc66SHeiko Stübner 		.iomux_recalced		= rk3128_mux_recalced_data,
3842daecdc66SHeiko Stübner 		.niomux_recalced	= ARRAY_SIZE(rk3128_mux_recalced_data),
3843daecdc66SHeiko Stübner 		.iomux_routes		= rk3128_mux_route_data,
3844daecdc66SHeiko Stübner 		.niomux_routes		= ARRAY_SIZE(rk3128_mux_route_data),
3845b6c23275SDavid Wu 		.pull_calc_reg		= rk3128_calc_pull_reg_and_bit,
38463ba6767aSDavid Wu };
38473ba6767aSDavid Wu 
3848b6c23275SDavid Wu static struct rockchip_pin_bank rk3188_pin_banks[] = {
3849b6c23275SDavid Wu 	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_GPIO_ONLY, 0, 0, 0),
3850b6c23275SDavid Wu 	PIN_BANK(1, 32, "gpio1"),
3851b6c23275SDavid Wu 	PIN_BANK(2, 32, "gpio2"),
3852b6c23275SDavid Wu 	PIN_BANK(3, 32, "gpio3"),
3853b6c23275SDavid Wu };
3854b6c23275SDavid Wu 
3855c437f65cSDavid Wu static struct rockchip_pin_ctrl rk3188_pin_ctrl = {
3856c437f65cSDavid Wu 		.pin_banks		= rk3188_pin_banks,
3857b6c23275SDavid Wu 		.nr_banks		= ARRAY_SIZE(rk3188_pin_banks),
38583ba6767aSDavid Wu 		.label			= "RK3188-GPIO",
38593ba6767aSDavid Wu 		.type			= RK3188,
38603ba6767aSDavid Wu 		.grf_mux_offset		= 0x60,
38613ba6767aSDavid Wu 		.iomux_routes		= rk3188_mux_route_data,
38623ba6767aSDavid Wu 		.niomux_routes		= ARRAY_SIZE(rk3188_mux_route_data),
3863b6c23275SDavid Wu 		.pull_calc_reg		= rk3188_calc_pull_reg_and_bit,
3864b6c23275SDavid Wu };
3865b6c23275SDavid Wu 
3866b6c23275SDavid Wu static struct rockchip_pin_bank rk3228_pin_banks[] = {
3867b6c23275SDavid Wu 	PIN_BANK(0, 32, "gpio0"),
3868b6c23275SDavid Wu 	PIN_BANK(1, 32, "gpio1"),
3869b6c23275SDavid Wu 	PIN_BANK(2, 32, "gpio2"),
3870b6c23275SDavid Wu 	PIN_BANK(3, 32, "gpio3"),
3871b6c23275SDavid Wu };
3872c437f65cSDavid Wu 
3873c437f65cSDavid Wu static struct rockchip_pin_ctrl rk3228_pin_ctrl = {
3874c437f65cSDavid Wu 		.pin_banks		= rk3228_pin_banks,
3875c437f65cSDavid Wu 		.nr_banks		= ARRAY_SIZE(rk3228_pin_banks),
3876b6c23275SDavid Wu 		.label			= "RK3228-GPIO",
38773ba6767aSDavid Wu 		.type			= RK3288,
3878b6c23275SDavid Wu 		.grf_mux_offset		= 0x0,
3879b6c23275SDavid Wu 		.iomux_routes		= rk3228_mux_route_data,
38803ba6767aSDavid Wu 		.niomux_routes		= ARRAY_SIZE(rk3228_mux_route_data),
38813ba6767aSDavid Wu 		.pull_calc_reg		= rk3228_calc_pull_reg_and_bit,
38823ba6767aSDavid Wu 		.drv_calc_reg		= rk3228_calc_drv_reg_and_bit,
38833ba6767aSDavid Wu };
38843ba6767aSDavid Wu 
3885b6c23275SDavid Wu static struct rockchip_pin_bank rk3288_pin_banks[] = {
3886b6c23275SDavid Wu 	PIN_BANK_IOMUX_FLAGS(0, 24, "gpio0", IOMUX_SOURCE_PMU,
3887b6c23275SDavid Wu 					     IOMUX_SOURCE_PMU,
3888b6c23275SDavid Wu 					     IOMUX_SOURCE_PMU,
3889b6c23275SDavid Wu 					     IOMUX_UNROUTED
3890b6c23275SDavid Wu 			    ),
3891b6c23275SDavid Wu 	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_UNROUTED,
3892b6c23275SDavid Wu 					     IOMUX_UNROUTED,
3893b6c23275SDavid Wu 					     IOMUX_UNROUTED,
3894b6c23275SDavid Wu 					     0
3895b6c23275SDavid Wu 			    ),
3896b6c23275SDavid Wu 	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, IOMUX_UNROUTED),
3897b6c23275SDavid Wu 	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, IOMUX_WIDTH_4BIT),
3898b6c23275SDavid Wu 	PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
3899b6c23275SDavid Wu 					     IOMUX_WIDTH_4BIT,
3900b6c23275SDavid Wu 					     0,
3901b6c23275SDavid Wu 					     0
3902b6c23275SDavid Wu 			    ),
3903b6c23275SDavid Wu 	PIN_BANK_IOMUX_FLAGS(5, 32, "gpio5", IOMUX_UNROUTED,
3904b6c23275SDavid Wu 					     0,
3905b6c23275SDavid Wu 					     0,
3906b6c23275SDavid Wu 					     IOMUX_UNROUTED
3907accc1ce7SDavid Wu 			    ),
3908accc1ce7SDavid Wu 	PIN_BANK_IOMUX_FLAGS(6, 32, "gpio6", 0, 0, 0, IOMUX_UNROUTED),
3909b6c23275SDavid Wu 	PIN_BANK_IOMUX_FLAGS(7, 32, "gpio7", 0,
3910b6c23275SDavid Wu 					     0,
3911b6c23275SDavid Wu 					     IOMUX_WIDTH_4BIT,
3912daecdc66SHeiko Stübner 					     IOMUX_UNROUTED
3913c0dadc0eSJianqun Xu 			    ),
3914c0dadc0eSJianqun Xu 	PIN_BANK(8, 16, "gpio8"),
3915c0dadc0eSJianqun Xu };
3916c0dadc0eSJianqun Xu 
3917c0dadc0eSJianqun Xu static struct rockchip_pin_ctrl rk3288_pin_ctrl = {
3918c0dadc0eSJianqun Xu 		.pin_banks		= rk3288_pin_banks,
3919c0dadc0eSJianqun Xu 		.nr_banks		= ARRAY_SIZE(rk3288_pin_banks),
3920c0dadc0eSJianqun Xu 		.label			= "RK3288-GPIO",
3921c0dadc0eSJianqun Xu 		.type			= RK3288,
3922c0dadc0eSJianqun Xu 		.grf_mux_offset		= 0x0,
3923c0dadc0eSJianqun Xu 		.pmu_mux_offset		= 0x84,
3924c0dadc0eSJianqun Xu 		.iomux_routes		= rk3288_mux_route_data,
3925c0dadc0eSJianqun Xu 		.niomux_routes		= ARRAY_SIZE(rk3288_mux_route_data),
3926c0dadc0eSJianqun Xu 		.pull_calc_reg		= rk3288_calc_pull_reg_and_bit,
3927c0dadc0eSJianqun Xu 		.drv_calc_reg		= rk3288_calc_drv_reg_and_bit,
3928c0dadc0eSJianqun Xu };
3929c0dadc0eSJianqun Xu 
3930c0dadc0eSJianqun Xu static struct rockchip_pin_bank rk3308_pin_banks[] = {
3931c0dadc0eSJianqun Xu 	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_WIDTH_2BIT,
3932c0dadc0eSJianqun Xu 					     IOMUX_WIDTH_2BIT,
3933c0dadc0eSJianqun Xu 					     IOMUX_WIDTH_2BIT,
3934c0dadc0eSJianqun Xu 					     IOMUX_WIDTH_2BIT),
3935c0dadc0eSJianqun Xu 	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_2BIT,
3936c0dadc0eSJianqun Xu 					     IOMUX_WIDTH_2BIT,
3937c0dadc0eSJianqun Xu 					     IOMUX_WIDTH_2BIT,
3938c0dadc0eSJianqun Xu 					     IOMUX_WIDTH_2BIT),
3939c0dadc0eSJianqun Xu 	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_2BIT,
3940c0dadc0eSJianqun Xu 					     IOMUX_WIDTH_2BIT,
3941c0dadc0eSJianqun Xu 					     IOMUX_WIDTH_2BIT,
3942c0dadc0eSJianqun Xu 					     IOMUX_WIDTH_2BIT),
3943c0dadc0eSJianqun Xu 	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_2BIT,
3944c0dadc0eSJianqun Xu 					     IOMUX_WIDTH_2BIT,
3945c0dadc0eSJianqun Xu 					     IOMUX_WIDTH_2BIT,
3946c0dadc0eSJianqun Xu 					     IOMUX_WIDTH_2BIT),
3947c0dadc0eSJianqun Xu 	PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_2BIT,
3948c0dadc0eSJianqun Xu 					     IOMUX_WIDTH_2BIT,
3949c0dadc0eSJianqun Xu 					     IOMUX_WIDTH_2BIT,
3950c0dadc0eSJianqun Xu 					     IOMUX_WIDTH_2BIT),
3951c0dadc0eSJianqun Xu };
3952fdc33ebaSJianqun Xu 
3953fdc33ebaSJianqun Xu static struct rockchip_pin_ctrl rk3308_pin_ctrl = {
3954fdc33ebaSJianqun Xu 		.pin_banks		= rk3308_pin_banks,
3955fdc33ebaSJianqun Xu 		.nr_banks		= ARRAY_SIZE(rk3308_pin_banks),
3956fdc33ebaSJianqun Xu 		.label			= "RK3308-GPIO",
3957fdc33ebaSJianqun Xu 		.type			= RK3308,
3958fdc33ebaSJianqun Xu 		.grf_mux_offset		= 0x0,
3959fdc33ebaSJianqun Xu 		.iomux_recalced		= rk3308_mux_recalced_data,
3960fdc33ebaSJianqun Xu 		.niomux_recalced	= ARRAY_SIZE(rk3308_mux_recalced_data),
3961fdc33ebaSJianqun Xu 		.iomux_routes		= rk3308_mux_route_data,
3962fdc33ebaSJianqun Xu 		.niomux_routes		= ARRAY_SIZE(rk3308_mux_route_data),
3963fdc33ebaSJianqun Xu 		.pull_calc_reg		= rk3308_calc_pull_reg_and_bit,
3964fdc33ebaSJianqun Xu 		.drv_calc_reg		= rk3308_calc_drv_reg_and_bit,
3965fdc33ebaSJianqun Xu 		.schmitt_calc_reg	= rk3308_calc_schmitt_reg_and_bit,
3966fdc33ebaSJianqun Xu };
3967fdc33ebaSJianqun Xu 
3968fdc33ebaSJianqun Xu static struct rockchip_pin_bank rk3328_pin_banks[] = {
3969fdc33ebaSJianqun Xu 	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", 0, 0, 0, 0),
3970fdc33ebaSJianqun Xu 	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0),
3971fdc33ebaSJianqun Xu 	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0,
3972fdc33ebaSJianqun Xu 			     IOMUX_WIDTH_2BIT,
3973fdc33ebaSJianqun Xu 			     IOMUX_WIDTH_3BIT,
3974fdc33ebaSJianqun Xu 			     0),
3975d3e51161SHeiko Stübner 	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3",
397687065ca9SDavid Wu 			     IOMUX_WIDTH_3BIT,
397787065ca9SDavid Wu 			     IOMUX_WIDTH_3BIT,
3978b9c6dcabSAndy Yan 			     0,
3979cdbbd26fSMasahiro Yamada 			     0),
3980fd4ea486SJagan Teki };
3981fd4ea486SJagan Teki 
3982d3e51161SHeiko Stübner static struct rockchip_pin_ctrl rk3328_pin_ctrl = {
3983cdbbd26fSMasahiro Yamada 		.pin_banks		= rk3328_pin_banks,
3984c5ce7670SXing Zheng 		.nr_banks		= ARRAY_SIZE(rk3328_pin_banks),
3985cdbbd26fSMasahiro Yamada 		.label			= "RK3328-GPIO",
3986d3e51161SHeiko Stübner 		.type			= RK3328,
3987cdbbd26fSMasahiro Yamada 		.grf_mux_offset		= 0x0,
3988d3e51161SHeiko Stübner 		.iomux_recalced		= rk3328_mux_recalced_data,
3989cdbbd26fSMasahiro Yamada 		.niomux_recalced	= ARRAY_SIZE(rk3328_mux_recalced_data),
3990d23c66dfSDavid Wu 		.iomux_routes		= rk3328_mux_route_data,
3991d23c66dfSDavid Wu 		.niomux_routes		= ARRAY_SIZE(rk3328_mux_route_data),
3992d3e51161SHeiko Stübner 		.pull_calc_reg		= rk3228_calc_pull_reg_and_bit,
3993cdbbd26fSMasahiro Yamada 		.drv_calc_reg		= rk3228_calc_drv_reg_and_bit,
3994fea0fe60SJeffy Chen 		.schmitt_calc_reg	= rk3328_calc_schmitt_reg_and_bit,
3995cdbbd26fSMasahiro Yamada };
3996304f077dSHeiko Stübner 
3997cdbbd26fSMasahiro Yamada static struct rockchip_pin_bank rk3368_pin_banks[] = {
39987825aeb7SJianqun Xu 	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU,
39997825aeb7SJianqun Xu 					     IOMUX_SOURCE_PMU,
40003818e4a7Sdavid.wu 					     IOMUX_SOURCE_PMU,
4001cdbbd26fSMasahiro Yamada 					     IOMUX_SOURCE_PMU
4002daecdc66SHeiko Stübner 			    ),
4003cdbbd26fSMasahiro Yamada 	PIN_BANK(1, 32, "gpio1"),
4004b6c23275SDavid Wu 	PIN_BANK(2, 32, "gpio2"),
4005cdbbd26fSMasahiro Yamada 	PIN_BANK(3, 32, "gpio3"),
4006c0dadc0eSJianqun Xu };
4007c0dadc0eSJianqun Xu 
4008fdc33ebaSJianqun Xu static struct rockchip_pin_ctrl rk3368_pin_ctrl = {
4009fdc33ebaSJianqun Xu 		.pin_banks		= rk3368_pin_banks,
4010d3e51161SHeiko Stübner 		.nr_banks		= ARRAY_SIZE(rk3368_pin_banks),
4011d3e51161SHeiko Stübner 		.label			= "RK3368-GPIO",
4012d3e51161SHeiko Stübner 		.type			= RK3368,
4013d3e51161SHeiko Stübner 		.grf_mux_offset		= 0x0,
4014d3e51161SHeiko Stübner 		.pmu_mux_offset		= 0x0,
401597258777SUwe Kleine-König 		.pull_calc_reg		= rk3368_calc_pull_reg_and_bit,
4016d3e51161SHeiko Stübner 		.drv_calc_reg		= rk3368_calc_drv_reg_and_bit,
4017d3e51161SHeiko Stübner };
40189198f509SChris Zhong 
40190be9e70dSAxel Lin static struct rockchip_pin_bank rk3399_pin_banks[] = {
4020d3e51161SHeiko Stübner 	PIN_BANK_IOMUX_FLAGS_DRV_FLAGS_OFFSET_PULL_FLAGS(0, 32, "gpio0",
4021d3e51161SHeiko Stübner 							 IOMUX_SOURCE_PMU,
4022d3e51161SHeiko Stübner 							 IOMUX_SOURCE_PMU,
4023d3e51161SHeiko Stübner 							 IOMUX_SOURCE_PMU,
4024d3e51161SHeiko Stübner 							 IOMUX_SOURCE_PMU,
4025d3e51161SHeiko Stübner 							 DRV_TYPE_IO_1V8_ONLY,
4026d3e51161SHeiko Stübner 							 DRV_TYPE_IO_1V8_ONLY,
4027d3e51161SHeiko Stübner 							 DRV_TYPE_IO_DEFAULT,
4028be786ac5SJianqun Xu 							 DRV_TYPE_IO_DEFAULT,
4029be786ac5SJianqun Xu 							 0x80,
4030be786ac5SJianqun Xu 							 0x88,
4031be786ac5SJianqun Xu 							 -1,
4032be786ac5SJianqun Xu 							 -1,
4033be786ac5SJianqun Xu 							 PULL_TYPE_IO_1V8_ONLY,
4034be786ac5SJianqun Xu 							 PULL_TYPE_IO_1V8_ONLY,
4035be786ac5SJianqun Xu 							 PULL_TYPE_IO_DEFAULT,
4036be786ac5SJianqun Xu 							 PULL_TYPE_IO_DEFAULT
4037be786ac5SJianqun Xu 							),
4038be786ac5SJianqun Xu 	PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(1, 32, "gpio1", IOMUX_SOURCE_PMU,
4039 					IOMUX_SOURCE_PMU,
4040 					IOMUX_SOURCE_PMU,
4041 					IOMUX_SOURCE_PMU,
4042 					DRV_TYPE_IO_1V8_OR_3V0,
4043 					DRV_TYPE_IO_1V8_OR_3V0,
4044 					DRV_TYPE_IO_1V8_OR_3V0,
4045 					DRV_TYPE_IO_1V8_OR_3V0,
4046 					0xa0,
4047 					0xa8,
4048 					0xb0,
4049 					0xb8
4050 					),
4051 	PIN_BANK_DRV_FLAGS_PULL_FLAGS(2, 32, "gpio2", DRV_TYPE_IO_1V8_OR_3V0,
4052 				      DRV_TYPE_IO_1V8_OR_3V0,
4053 				      DRV_TYPE_IO_1V8_ONLY,
4054 				      DRV_TYPE_IO_1V8_ONLY,
4055 				      PULL_TYPE_IO_DEFAULT,
4056 				      PULL_TYPE_IO_DEFAULT,
4057 				      PULL_TYPE_IO_1V8_ONLY,
4058 				      PULL_TYPE_IO_1V8_ONLY
4059 				      ),
4060 	PIN_BANK_DRV_FLAGS(3, 32, "gpio3", DRV_TYPE_IO_3V3_ONLY,
4061 			   DRV_TYPE_IO_3V3_ONLY,
4062 			   DRV_TYPE_IO_3V3_ONLY,
4063 			   DRV_TYPE_IO_1V8_OR_3V0
4064 			   ),
4065 	PIN_BANK_DRV_FLAGS(4, 32, "gpio4", DRV_TYPE_IO_1V8_OR_3V0,
4066 			   DRV_TYPE_IO_1V8_3V0_AUTO,
4067 			   DRV_TYPE_IO_1V8_OR_3V0,
4068 			   DRV_TYPE_IO_1V8_OR_3V0
4069 			   ),
4070 };
4071 
4072 static struct rockchip_pin_ctrl rk3399_pin_ctrl = {
4073 		.pin_banks		= rk3399_pin_banks,
4074 		.nr_banks		= ARRAY_SIZE(rk3399_pin_banks),
4075 		.label			= "RK3399-GPIO",
4076 		.type			= RK3399,
4077 		.grf_mux_offset		= 0xe000,
4078 		.pmu_mux_offset		= 0x0,
4079 		.grf_drv_offset		= 0xe100,
4080 		.pmu_drv_offset		= 0x80,
4081 		.iomux_routes		= rk3399_mux_route_data,
4082 		.niomux_routes		= ARRAY_SIZE(rk3399_mux_route_data),
4083 		.pull_calc_reg		= rk3399_calc_pull_reg_and_bit,
4084 		.drv_calc_reg		= rk3399_calc_drv_reg_and_bit,
4085 };
4086 
4087 static struct rockchip_pin_bank rk3568_pin_banks[] = {
4088 	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
4089 					     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
4090 					     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
4091 					     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT),
4092 	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT,
4093 					     IOMUX_WIDTH_4BIT,
4094 					     IOMUX_WIDTH_4BIT,
4095 					     IOMUX_WIDTH_4BIT),
4096 	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT,
4097 					     IOMUX_WIDTH_4BIT,
4098 					     IOMUX_WIDTH_4BIT,
4099 					     IOMUX_WIDTH_4BIT),
4100 	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT,
4101 					     IOMUX_WIDTH_4BIT,
4102 					     IOMUX_WIDTH_4BIT,
4103 					     IOMUX_WIDTH_4BIT),
4104 	PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
4105 					     IOMUX_WIDTH_4BIT,
4106 					     IOMUX_WIDTH_4BIT,
4107 					     IOMUX_WIDTH_4BIT),
4108 };
4109 
4110 static struct rockchip_pin_ctrl rk3568_pin_ctrl = {
4111 	.pin_banks		= rk3568_pin_banks,
4112 	.nr_banks		= ARRAY_SIZE(rk3568_pin_banks),
4113 	.label			= "RK3568-GPIO",
4114 	.type			= RK3568,
4115 	.grf_mux_offset		= 0x0,
4116 	.pmu_mux_offset		= 0x0,
4117 	.grf_drv_offset		= 0x0200,
4118 	.pmu_drv_offset		= 0x0070,
4119 	.iomux_routes		= rk3568_mux_route_data,
4120 	.niomux_routes		= ARRAY_SIZE(rk3568_mux_route_data),
4121 	.pull_calc_reg		= rk3568_calc_pull_reg_and_bit,
4122 	.drv_calc_reg		= rk3568_calc_drv_reg_and_bit,
4123 	.schmitt_calc_reg	= rk3568_calc_schmitt_reg_and_bit,
4124 };
4125 
4126 #define RK3576_PIN_BANK(ID, LABEL, OFFSET0, OFFSET1, OFFSET2, OFFSET3)	\
4127 	PIN_BANK_IOMUX_FLAGS_OFFSET_PULL_FLAGS(ID, 32, LABEL,		\
4128 					       IOMUX_WIDTH_4BIT,	\
4129 					       IOMUX_WIDTH_4BIT,	\
4130 					       IOMUX_WIDTH_4BIT,	\
4131 					       IOMUX_WIDTH_4BIT,	\
4132 					       OFFSET0, OFFSET1,	\
4133 					       OFFSET2, OFFSET3,	\
4134 					       PULL_TYPE_IO_1V8_ONLY,	\
4135 					       PULL_TYPE_IO_1V8_ONLY,	\
4136 					       PULL_TYPE_IO_1V8_ONLY,	\
4137 					       PULL_TYPE_IO_1V8_ONLY)
4138 
4139 static struct rockchip_pin_bank rk3576_pin_banks[] = {
4140 	RK3576_PIN_BANK(0, "gpio0", 0, 0x8, 0x2004, 0x200C),
4141 	RK3576_PIN_BANK(1, "gpio1", 0x4020, 0x4028, 0x4030, 0x4038),
4142 	RK3576_PIN_BANK(2, "gpio2", 0x4040, 0x4048, 0x4050, 0x4058),
4143 	RK3576_PIN_BANK(3, "gpio3", 0x4060, 0x4068, 0x4070, 0x4078),
4144 	RK3576_PIN_BANK(4, "gpio4", 0x4080, 0x4088, 0xA390, 0xB398),
4145 };
4146 
4147 static struct rockchip_pin_ctrl rk3576_pin_ctrl __maybe_unused = {
4148 	.pin_banks		= rk3576_pin_banks,
4149 	.nr_banks		= ARRAY_SIZE(rk3576_pin_banks),
4150 	.label			= "RK3576-GPIO",
4151 	.type			= RK3576,
4152 	.pull_calc_reg		= rk3576_calc_pull_reg_and_bit,
4153 	.drv_calc_reg		= rk3576_calc_drv_reg_and_bit,
4154 	.schmitt_calc_reg	= rk3576_calc_schmitt_reg_and_bit,
4155 };
4156 
4157 static struct rockchip_pin_bank rk3588_pin_banks[] = {
4158 	RK3588_PIN_BANK_FLAGS(0, 32, "gpio0",
4159 			      IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY),
4160 	RK3588_PIN_BANK_FLAGS(1, 32, "gpio1",
4161 			      IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY),
4162 	RK3588_PIN_BANK_FLAGS(2, 32, "gpio2",
4163 			      IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY),
4164 	RK3588_PIN_BANK_FLAGS(3, 32, "gpio3",
4165 			      IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY),
4166 	RK3588_PIN_BANK_FLAGS(4, 32, "gpio4",
4167 			      IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY),
4168 };
4169 
4170 static struct rockchip_pin_ctrl rk3588_pin_ctrl = {
4171 	.pin_banks		= rk3588_pin_banks,
4172 	.nr_banks		= ARRAY_SIZE(rk3588_pin_banks),
4173 	.label			= "RK3588-GPIO",
4174 	.type			= RK3588,
4175 	.pull_calc_reg		= rk3588_calc_pull_reg_and_bit,
4176 	.drv_calc_reg		= rk3588_calc_drv_reg_and_bit,
4177 	.schmitt_calc_reg	= rk3588_calc_schmitt_reg_and_bit,
4178 };
4179 
4180 static const struct of_device_id rockchip_pinctrl_dt_match[] = {
4181 	{ .compatible = "rockchip,px30-pinctrl",
4182 		.data = &px30_pin_ctrl },
4183 	{ .compatible = "rockchip,rv1108-pinctrl",
4184 		.data = &rv1108_pin_ctrl },
4185 	{ .compatible = "rockchip,rv1126-pinctrl",
4186 		.data = &rv1126_pin_ctrl },
4187 	{ .compatible = "rockchip,rk2928-pinctrl",
4188 		.data = &rk2928_pin_ctrl },
4189 	{ .compatible = "rockchip,rk3036-pinctrl",
4190 		.data = &rk3036_pin_ctrl },
4191 	{ .compatible = "rockchip,rk3066a-pinctrl",
4192 		.data = &rk3066a_pin_ctrl },
4193 	{ .compatible = "rockchip,rk3066b-pinctrl",
4194 		.data = &rk3066b_pin_ctrl },
4195 	{ .compatible = "rockchip,rk3128-pinctrl",
4196 		.data = (void *)&rk3128_pin_ctrl },
4197 	{ .compatible = "rockchip,rk3188-pinctrl",
4198 		.data = &rk3188_pin_ctrl },
4199 	{ .compatible = "rockchip,rk3228-pinctrl",
4200 		.data = &rk3228_pin_ctrl },
4201 	{ .compatible = "rockchip,rk3288-pinctrl",
4202 		.data = &rk3288_pin_ctrl },
4203 	{ .compatible = "rockchip,rk3308-pinctrl",
4204 		.data = &rk3308_pin_ctrl },
4205 	{ .compatible = "rockchip,rk3328-pinctrl",
4206 		.data = &rk3328_pin_ctrl },
4207 	{ .compatible = "rockchip,rk3368-pinctrl",
4208 		.data = &rk3368_pin_ctrl },
4209 	{ .compatible = "rockchip,rk3399-pinctrl",
4210 		.data = &rk3399_pin_ctrl },
4211 	{ .compatible = "rockchip,rk3568-pinctrl",
4212 		.data = &rk3568_pin_ctrl },
4213 	{ .compatible = "rockchip,rk3576-pinctrl",
4214 		.data = &rk3576_pin_ctrl },
4215 	{ .compatible = "rockchip,rk3588-pinctrl",
4216 		.data = &rk3588_pin_ctrl },
4217 	{},
4218 };
4219 
4220 static struct platform_driver rockchip_pinctrl_driver = {
4221 	.probe		= rockchip_pinctrl_probe,
4222 	.remove_new	= rockchip_pinctrl_remove,
4223 	.driver = {
4224 		.name	= "rockchip-pinctrl",
4225 		.pm = &rockchip_pinctrl_dev_pm_ops,
4226 		.of_match_table = rockchip_pinctrl_dt_match,
4227 	},
4228 };
4229 
rockchip_pinctrl_drv_register(void)4230 static int __init rockchip_pinctrl_drv_register(void)
4231 {
4232 	return platform_driver_register(&rockchip_pinctrl_driver);
4233 }
4234 postcore_initcall(rockchip_pinctrl_drv_register);
4235 
rockchip_pinctrl_drv_unregister(void)4236 static void __exit rockchip_pinctrl_drv_unregister(void)
4237 {
4238 	platform_driver_unregister(&rockchip_pinctrl_driver);
4239 }
4240 module_exit(rockchip_pinctrl_drv_unregister);
4241 
4242 MODULE_DESCRIPTION("ROCKCHIP Pin Controller Driver");
4243 MODULE_LICENSE("GPL");
4244 MODULE_ALIAS("platform:pinctrl-rockchip");
4245 MODULE_DEVICE_TABLE(of, rockchip_pinctrl_dt_match);
4246