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