xref: /linux/drivers/pinctrl/renesas/pinctrl-rzt2h.c (revision 34d4d093077a5c60d452a2f42d0c1a08e55b8614)
1*34d4d093SThierry Bultel // SPDX-License-Identifier: GPL-2.0
2*34d4d093SThierry Bultel /*
3*34d4d093SThierry Bultel  * Renesas RZ/T2H Pin Control and GPIO driver core
4*34d4d093SThierry Bultel  *
5*34d4d093SThierry Bultel  * Based on drivers/pinctrl/renesas/pinctrl-rzg2l.c
6*34d4d093SThierry Bultel  *
7*34d4d093SThierry Bultel  * Copyright (C) 2025 Renesas Electronics Corporation.
8*34d4d093SThierry Bultel  */
9*34d4d093SThierry Bultel 
10*34d4d093SThierry Bultel #include <linux/bitfield.h>
11*34d4d093SThierry Bultel #include <linux/bitops.h>
12*34d4d093SThierry Bultel #include <linux/bits.h>
13*34d4d093SThierry Bultel #include <linux/cleanup.h>
14*34d4d093SThierry Bultel #include <linux/clk.h>
15*34d4d093SThierry Bultel #include <linux/gpio/driver.h>
16*34d4d093SThierry Bultel #include <linux/io.h>
17*34d4d093SThierry Bultel #include <linux/ioport.h>
18*34d4d093SThierry Bultel #include <linux/module.h>
19*34d4d093SThierry Bultel #include <linux/mutex.h>
20*34d4d093SThierry Bultel #include <linux/of_device.h>
21*34d4d093SThierry Bultel #include <linux/platform_device.h>
22*34d4d093SThierry Bultel #include <linux/pm_runtime.h>
23*34d4d093SThierry Bultel #include <linux/spinlock.h>
24*34d4d093SThierry Bultel #include <linux/types.h>
25*34d4d093SThierry Bultel 
26*34d4d093SThierry Bultel #include <linux/pinctrl/consumer.h>
27*34d4d093SThierry Bultel #include <linux/pinctrl/pinconf-generic.h>
28*34d4d093SThierry Bultel #include <linux/pinctrl/pinconf.h>
29*34d4d093SThierry Bultel #include <linux/pinctrl/pinctrl.h>
30*34d4d093SThierry Bultel #include <linux/pinctrl/pinmux.h>
31*34d4d093SThierry Bultel 
32*34d4d093SThierry Bultel #include <dt-bindings/pinctrl/renesas,r9a09g077-pinctrl.h>
33*34d4d093SThierry Bultel 
34*34d4d093SThierry Bultel #include "../core.h"
35*34d4d093SThierry Bultel #include "../pinconf.h"
36*34d4d093SThierry Bultel #include "../pinmux.h"
37*34d4d093SThierry Bultel 
38*34d4d093SThierry Bultel #define DRV_NAME	"pinctrl-rzt2h"
39*34d4d093SThierry Bultel 
40*34d4d093SThierry Bultel #define P(m)		(0x001 * (m))
41*34d4d093SThierry Bultel #define PM(m)		(0x200 + 2 * (m))
42*34d4d093SThierry Bultel #define PMC(m)		(0x400 + (m))
43*34d4d093SThierry Bultel #define PFC(m)		(0x600 + 8 * (m))
44*34d4d093SThierry Bultel #define PIN(m)		(0x800 + (m))
45*34d4d093SThierry Bultel #define RSELP(m)	(0xc00 + (m))
46*34d4d093SThierry Bultel 
47*34d4d093SThierry Bultel #define PM_MASK			GENMASK(1, 0)
48*34d4d093SThierry Bultel #define PM_PIN_MASK(pin)	(PM_MASK << ((pin) * 2))
49*34d4d093SThierry Bultel #define PM_INPUT		BIT(0)
50*34d4d093SThierry Bultel #define PM_OUTPUT		BIT(1)
51*34d4d093SThierry Bultel 
52*34d4d093SThierry Bultel #define PFC_MASK		GENMASK_ULL(5, 0)
53*34d4d093SThierry Bultel #define PFC_PIN_MASK(pin)	(PFC_MASK << ((pin) * 8))
54*34d4d093SThierry Bultel 
55*34d4d093SThierry Bultel /*
56*34d4d093SThierry Bultel  * Use 16 lower bits [15:0] for pin identifier
57*34d4d093SThierry Bultel  * Use 8 higher bits [23:16] for pin mux function
58*34d4d093SThierry Bultel  */
59*34d4d093SThierry Bultel #define MUX_PIN_ID_MASK		GENMASK(15, 0)
60*34d4d093SThierry Bultel #define MUX_FUNC_MASK		GENMASK(23, 16)
61*34d4d093SThierry Bultel 
62*34d4d093SThierry Bultel #define RZT2H_PIN_ID_TO_PORT(id)	((id) / RZT2H_PINS_PER_PORT)
63*34d4d093SThierry Bultel #define RZT2H_PIN_ID_TO_PIN(id)		((id) % RZT2H_PINS_PER_PORT)
64*34d4d093SThierry Bultel 
65*34d4d093SThierry Bultel #define RZT2H_MAX_SAFETY_PORTS		12
66*34d4d093SThierry Bultel 
67*34d4d093SThierry Bultel struct rzt2h_pinctrl_data {
68*34d4d093SThierry Bultel 	unsigned int n_port_pins;
69*34d4d093SThierry Bultel 	const u8 *port_pin_configs;
70*34d4d093SThierry Bultel 	unsigned int n_ports;
71*34d4d093SThierry Bultel };
72*34d4d093SThierry Bultel 
73*34d4d093SThierry Bultel struct rzt2h_pinctrl {
74*34d4d093SThierry Bultel 	struct pinctrl_dev		*pctl;
75*34d4d093SThierry Bultel 	struct pinctrl_desc		desc;
76*34d4d093SThierry Bultel 	struct pinctrl_pin_desc		*pins;
77*34d4d093SThierry Bultel 	const struct rzt2h_pinctrl_data	*data;
78*34d4d093SThierry Bultel 	void __iomem			*base0, *base1;
79*34d4d093SThierry Bultel 	struct device			*dev;
80*34d4d093SThierry Bultel 	struct gpio_chip		gpio_chip;
81*34d4d093SThierry Bultel 	struct pinctrl_gpio_range	gpio_range;
82*34d4d093SThierry Bultel 	spinlock_t			lock; /* lock read/write registers */
83*34d4d093SThierry Bultel 	struct mutex			mutex; /* serialize adding groups and functions */
84*34d4d093SThierry Bultel 	bool				safety_port_enabled;
85*34d4d093SThierry Bultel };
86*34d4d093SThierry Bultel 
87*34d4d093SThierry Bultel #define RZT2H_GET_BASE(pctrl, port) \
88*34d4d093SThierry Bultel 	((port) > RZT2H_MAX_SAFETY_PORTS ? (pctrl)->base0 : (pctrl)->base1)
89*34d4d093SThierry Bultel 
90*34d4d093SThierry Bultel #define RZT2H_PINCTRL_REG_ACCESS(size, type)						\
91*34d4d093SThierry Bultel static inline void rzt2h_pinctrl_write##size(struct rzt2h_pinctrl *pctrl, u8 port,	\
92*34d4d093SThierry Bultel 					     type val, unsigned int offset)		\
93*34d4d093SThierry Bultel {											\
94*34d4d093SThierry Bultel 	write##size(val, RZT2H_GET_BASE(pctrl, port) + offset);				\
95*34d4d093SThierry Bultel }											\
96*34d4d093SThierry Bultel static inline type rzt2h_pinctrl_read##size(struct rzt2h_pinctrl *pctrl, u8 port,	\
97*34d4d093SThierry Bultel 					    unsigned int offset)			\
98*34d4d093SThierry Bultel {											\
99*34d4d093SThierry Bultel 	return read##size(RZT2H_GET_BASE(pctrl, port) + offset);			\
100*34d4d093SThierry Bultel }
101*34d4d093SThierry Bultel 
102*34d4d093SThierry Bultel RZT2H_PINCTRL_REG_ACCESS(b, u8)
103*34d4d093SThierry Bultel RZT2H_PINCTRL_REG_ACCESS(w, u16)
104*34d4d093SThierry Bultel RZT2H_PINCTRL_REG_ACCESS(q, u64)
105*34d4d093SThierry Bultel 
106*34d4d093SThierry Bultel static int rzt2h_validate_pin(struct rzt2h_pinctrl *pctrl, unsigned int offset)
107*34d4d093SThierry Bultel {
108*34d4d093SThierry Bultel 	u8 port = RZT2H_PIN_ID_TO_PORT(offset);
109*34d4d093SThierry Bultel 	u8 pin = RZT2H_PIN_ID_TO_PIN(offset);
110*34d4d093SThierry Bultel 	u8 pincfg;
111*34d4d093SThierry Bultel 
112*34d4d093SThierry Bultel 	if (offset >= pctrl->data->n_port_pins || port >= pctrl->data->n_ports)
113*34d4d093SThierry Bultel 		return -EINVAL;
114*34d4d093SThierry Bultel 
115*34d4d093SThierry Bultel 	if (!pctrl->safety_port_enabled && port <= RZT2H_MAX_SAFETY_PORTS)
116*34d4d093SThierry Bultel 		return -EINVAL;
117*34d4d093SThierry Bultel 
118*34d4d093SThierry Bultel 	pincfg = pctrl->data->port_pin_configs[port];
119*34d4d093SThierry Bultel 	return (pincfg & BIT(pin)) ? 0 : -EINVAL;
120*34d4d093SThierry Bultel }
121*34d4d093SThierry Bultel 
122*34d4d093SThierry Bultel static void rzt2h_pinctrl_set_pfc_mode(struct rzt2h_pinctrl *pctrl,
123*34d4d093SThierry Bultel 				       u8 port, u8 pin, u8 func)
124*34d4d093SThierry Bultel {
125*34d4d093SThierry Bultel 	u64 reg64;
126*34d4d093SThierry Bultel 	u16 reg16;
127*34d4d093SThierry Bultel 
128*34d4d093SThierry Bultel 	guard(spinlock_irqsave)(&pctrl->lock);
129*34d4d093SThierry Bultel 
130*34d4d093SThierry Bultel 	/* Set pin to 'Non-use (Hi-Z input protection)'  */
131*34d4d093SThierry Bultel 	reg16 = rzt2h_pinctrl_readw(pctrl, port, PM(port));
132*34d4d093SThierry Bultel 	reg16 &= ~PM_PIN_MASK(pin);
133*34d4d093SThierry Bultel 	rzt2h_pinctrl_writew(pctrl, port, reg16, PM(port));
134*34d4d093SThierry Bultel 
135*34d4d093SThierry Bultel 	/* Temporarily switch to GPIO mode with PMC register */
136*34d4d093SThierry Bultel 	reg16 = rzt2h_pinctrl_readb(pctrl, port, PMC(port));
137*34d4d093SThierry Bultel 	rzt2h_pinctrl_writeb(pctrl, port, reg16 & ~BIT(pin), PMC(port));
138*34d4d093SThierry Bultel 
139*34d4d093SThierry Bultel 	/* Select Pin function mode with PFC register */
140*34d4d093SThierry Bultel 	reg64 = rzt2h_pinctrl_readq(pctrl, port, PFC(port));
141*34d4d093SThierry Bultel 	reg64 &= ~PFC_PIN_MASK(pin);
142*34d4d093SThierry Bultel 	rzt2h_pinctrl_writeq(pctrl, port, reg64 | ((u64)func << (pin * 8)), PFC(port));
143*34d4d093SThierry Bultel 
144*34d4d093SThierry Bultel 	/* Switch to Peripheral pin function with PMC register */
145*34d4d093SThierry Bultel 	reg16 = rzt2h_pinctrl_readb(pctrl, port, PMC(port));
146*34d4d093SThierry Bultel 	rzt2h_pinctrl_writeb(pctrl, port, reg16 | BIT(pin), PMC(port));
147*34d4d093SThierry Bultel };
148*34d4d093SThierry Bultel 
149*34d4d093SThierry Bultel static int rzt2h_pinctrl_set_mux(struct pinctrl_dev *pctldev,
150*34d4d093SThierry Bultel 				 unsigned int func_selector,
151*34d4d093SThierry Bultel 				 unsigned int group_selector)
152*34d4d093SThierry Bultel {
153*34d4d093SThierry Bultel 	struct rzt2h_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
154*34d4d093SThierry Bultel 	const struct function_desc *func;
155*34d4d093SThierry Bultel 	struct group_desc *group;
156*34d4d093SThierry Bultel 	const unsigned int *pins;
157*34d4d093SThierry Bultel 	unsigned int i;
158*34d4d093SThierry Bultel 	u8 *psel_val;
159*34d4d093SThierry Bultel 	int ret;
160*34d4d093SThierry Bultel 
161*34d4d093SThierry Bultel 	func = pinmux_generic_get_function(pctldev, func_selector);
162*34d4d093SThierry Bultel 	if (!func)
163*34d4d093SThierry Bultel 		return -EINVAL;
164*34d4d093SThierry Bultel 
165*34d4d093SThierry Bultel 	group = pinctrl_generic_get_group(pctldev, group_selector);
166*34d4d093SThierry Bultel 	if (!group)
167*34d4d093SThierry Bultel 		return -EINVAL;
168*34d4d093SThierry Bultel 
169*34d4d093SThierry Bultel 	psel_val = func->data;
170*34d4d093SThierry Bultel 	pins = group->grp.pins;
171*34d4d093SThierry Bultel 
172*34d4d093SThierry Bultel 	for (i = 0; i < group->grp.npins; i++) {
173*34d4d093SThierry Bultel 		dev_dbg(pctrl->dev, "port:%u pin:%u PSEL:%u\n",
174*34d4d093SThierry Bultel 			RZT2H_PIN_ID_TO_PORT(pins[i]), RZT2H_PIN_ID_TO_PIN(pins[i]),
175*34d4d093SThierry Bultel 			psel_val[i]);
176*34d4d093SThierry Bultel 		ret = rzt2h_validate_pin(pctrl, pins[i]);
177*34d4d093SThierry Bultel 		if (ret)
178*34d4d093SThierry Bultel 			return ret;
179*34d4d093SThierry Bultel 
180*34d4d093SThierry Bultel 		rzt2h_pinctrl_set_pfc_mode(pctrl, RZT2H_PIN_ID_TO_PORT(pins[i]),
181*34d4d093SThierry Bultel 					   RZT2H_PIN_ID_TO_PIN(pins[i]), psel_val[i]);
182*34d4d093SThierry Bultel 	}
183*34d4d093SThierry Bultel 
184*34d4d093SThierry Bultel 	return 0;
185*34d4d093SThierry Bultel };
186*34d4d093SThierry Bultel 
187*34d4d093SThierry Bultel static int rzt2h_map_add_config(struct pinctrl_map *map,
188*34d4d093SThierry Bultel 				const char *group_or_pin,
189*34d4d093SThierry Bultel 				enum pinctrl_map_type type,
190*34d4d093SThierry Bultel 				unsigned long *configs,
191*34d4d093SThierry Bultel 				unsigned int num_configs)
192*34d4d093SThierry Bultel {
193*34d4d093SThierry Bultel 	unsigned long *cfgs;
194*34d4d093SThierry Bultel 
195*34d4d093SThierry Bultel 	cfgs = kmemdup_array(configs, num_configs, sizeof(*cfgs), GFP_KERNEL);
196*34d4d093SThierry Bultel 	if (!cfgs)
197*34d4d093SThierry Bultel 		return -ENOMEM;
198*34d4d093SThierry Bultel 
199*34d4d093SThierry Bultel 	map->type = type;
200*34d4d093SThierry Bultel 	map->data.configs.group_or_pin = group_or_pin;
201*34d4d093SThierry Bultel 	map->data.configs.configs = cfgs;
202*34d4d093SThierry Bultel 	map->data.configs.num_configs = num_configs;
203*34d4d093SThierry Bultel 
204*34d4d093SThierry Bultel 	return 0;
205*34d4d093SThierry Bultel }
206*34d4d093SThierry Bultel 
207*34d4d093SThierry Bultel static int rzt2h_dt_subnode_to_map(struct pinctrl_dev *pctldev,
208*34d4d093SThierry Bultel 				   struct device_node *np,
209*34d4d093SThierry Bultel 				   struct device_node *parent,
210*34d4d093SThierry Bultel 				   struct pinctrl_map **map,
211*34d4d093SThierry Bultel 				   unsigned int *num_maps,
212*34d4d093SThierry Bultel 				   unsigned int *index)
213*34d4d093SThierry Bultel {
214*34d4d093SThierry Bultel 	struct rzt2h_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
215*34d4d093SThierry Bultel 	struct pinctrl_map *maps = *map;
216*34d4d093SThierry Bultel 	unsigned int nmaps = *num_maps;
217*34d4d093SThierry Bultel 	unsigned long *configs = NULL;
218*34d4d093SThierry Bultel 	unsigned int num_pinmux = 0;
219*34d4d093SThierry Bultel 	unsigned int idx = *index;
220*34d4d093SThierry Bultel 	unsigned int num_pins, i;
221*34d4d093SThierry Bultel 	unsigned int num_configs;
222*34d4d093SThierry Bultel 	struct property *pinmux;
223*34d4d093SThierry Bultel 	struct property *prop;
224*34d4d093SThierry Bultel 	int ret, gsel, fsel;
225*34d4d093SThierry Bultel 	const char **pin_fn;
226*34d4d093SThierry Bultel 	unsigned int *pins;
227*34d4d093SThierry Bultel 	const char *name;
228*34d4d093SThierry Bultel 	const char *pin;
229*34d4d093SThierry Bultel 	u8 *psel_val;
230*34d4d093SThierry Bultel 
231*34d4d093SThierry Bultel 	pinmux = of_find_property(np, "pinmux", NULL);
232*34d4d093SThierry Bultel 	if (pinmux)
233*34d4d093SThierry Bultel 		num_pinmux = pinmux->length / sizeof(u32);
234*34d4d093SThierry Bultel 
235*34d4d093SThierry Bultel 	ret = of_property_count_strings(np, "pins");
236*34d4d093SThierry Bultel 	if (ret == -EINVAL) {
237*34d4d093SThierry Bultel 		num_pins = 0;
238*34d4d093SThierry Bultel 	} else if (ret < 0) {
239*34d4d093SThierry Bultel 		dev_err(pctrl->dev, "Invalid pins list in DT\n");
240*34d4d093SThierry Bultel 		return ret;
241*34d4d093SThierry Bultel 	} else {
242*34d4d093SThierry Bultel 		num_pins = ret;
243*34d4d093SThierry Bultel 	}
244*34d4d093SThierry Bultel 
245*34d4d093SThierry Bultel 	if (!num_pinmux && !num_pins)
246*34d4d093SThierry Bultel 		return 0;
247*34d4d093SThierry Bultel 
248*34d4d093SThierry Bultel 	if (num_pinmux && num_pins) {
249*34d4d093SThierry Bultel 		dev_err(pctrl->dev,
250*34d4d093SThierry Bultel 			"DT node must contain either a pinmux or pins and not both\n");
251*34d4d093SThierry Bultel 		return -EINVAL;
252*34d4d093SThierry Bultel 	}
253*34d4d093SThierry Bultel 
254*34d4d093SThierry Bultel 	ret = pinconf_generic_parse_dt_config(np, pctldev, &configs, &num_configs);
255*34d4d093SThierry Bultel 	if (ret < 0)
256*34d4d093SThierry Bultel 		return ret;
257*34d4d093SThierry Bultel 
258*34d4d093SThierry Bultel 	if (num_pins && !num_configs) {
259*34d4d093SThierry Bultel 		dev_err(pctrl->dev, "DT node must contain a config\n");
260*34d4d093SThierry Bultel 		ret = -ENODEV;
261*34d4d093SThierry Bultel 		goto done;
262*34d4d093SThierry Bultel 	}
263*34d4d093SThierry Bultel 
264*34d4d093SThierry Bultel 	if (num_pinmux) {
265*34d4d093SThierry Bultel 		nmaps += 1;
266*34d4d093SThierry Bultel 		if (num_configs)
267*34d4d093SThierry Bultel 			nmaps += 1;
268*34d4d093SThierry Bultel 	}
269*34d4d093SThierry Bultel 
270*34d4d093SThierry Bultel 	if (num_pins)
271*34d4d093SThierry Bultel 		nmaps += num_pins;
272*34d4d093SThierry Bultel 
273*34d4d093SThierry Bultel 	maps = krealloc_array(maps, nmaps, sizeof(*maps), GFP_KERNEL);
274*34d4d093SThierry Bultel 	if (!maps) {
275*34d4d093SThierry Bultel 		ret = -ENOMEM;
276*34d4d093SThierry Bultel 		goto done;
277*34d4d093SThierry Bultel 	}
278*34d4d093SThierry Bultel 
279*34d4d093SThierry Bultel 	*map = maps;
280*34d4d093SThierry Bultel 	*num_maps = nmaps;
281*34d4d093SThierry Bultel 	if (num_pins) {
282*34d4d093SThierry Bultel 		of_property_for_each_string(np, "pins", prop, pin) {
283*34d4d093SThierry Bultel 			ret = rzt2h_map_add_config(&maps[idx], pin,
284*34d4d093SThierry Bultel 						   PIN_MAP_TYPE_CONFIGS_PIN,
285*34d4d093SThierry Bultel 						   configs, num_configs);
286*34d4d093SThierry Bultel 			if (ret < 0)
287*34d4d093SThierry Bultel 				goto done;
288*34d4d093SThierry Bultel 
289*34d4d093SThierry Bultel 			idx++;
290*34d4d093SThierry Bultel 		}
291*34d4d093SThierry Bultel 		ret = 0;
292*34d4d093SThierry Bultel 		goto done;
293*34d4d093SThierry Bultel 	}
294*34d4d093SThierry Bultel 
295*34d4d093SThierry Bultel 	pins = devm_kcalloc(pctrl->dev, num_pinmux, sizeof(*pins), GFP_KERNEL);
296*34d4d093SThierry Bultel 	psel_val = devm_kcalloc(pctrl->dev, num_pinmux, sizeof(*psel_val),
297*34d4d093SThierry Bultel 				GFP_KERNEL);
298*34d4d093SThierry Bultel 	pin_fn = devm_kzalloc(pctrl->dev, sizeof(*pin_fn), GFP_KERNEL);
299*34d4d093SThierry Bultel 	if (!pins || !psel_val || !pin_fn) {
300*34d4d093SThierry Bultel 		ret = -ENOMEM;
301*34d4d093SThierry Bultel 		goto done;
302*34d4d093SThierry Bultel 	}
303*34d4d093SThierry Bultel 
304*34d4d093SThierry Bultel 	/* Collect pin locations and mux settings from DT properties */
305*34d4d093SThierry Bultel 	for (i = 0; i < num_pinmux; ++i) {
306*34d4d093SThierry Bultel 		u32 value;
307*34d4d093SThierry Bultel 
308*34d4d093SThierry Bultel 		ret = of_property_read_u32_index(np, "pinmux", i, &value);
309*34d4d093SThierry Bultel 		if (ret)
310*34d4d093SThierry Bultel 			goto done;
311*34d4d093SThierry Bultel 		pins[i] = FIELD_GET(MUX_PIN_ID_MASK, value);
312*34d4d093SThierry Bultel 		psel_val[i] = FIELD_GET(MUX_FUNC_MASK, value);
313*34d4d093SThierry Bultel 	}
314*34d4d093SThierry Bultel 
315*34d4d093SThierry Bultel 	if (parent) {
316*34d4d093SThierry Bultel 		name = devm_kasprintf(pctrl->dev, GFP_KERNEL, "%pOFn.%pOFn",
317*34d4d093SThierry Bultel 				      parent, np);
318*34d4d093SThierry Bultel 		if (!name) {
319*34d4d093SThierry Bultel 			ret = -ENOMEM;
320*34d4d093SThierry Bultel 			goto done;
321*34d4d093SThierry Bultel 		}
322*34d4d093SThierry Bultel 	} else {
323*34d4d093SThierry Bultel 		name = np->name;
324*34d4d093SThierry Bultel 	}
325*34d4d093SThierry Bultel 
326*34d4d093SThierry Bultel 	if (num_configs) {
327*34d4d093SThierry Bultel 		ret = rzt2h_map_add_config(&maps[idx], name,
328*34d4d093SThierry Bultel 					   PIN_MAP_TYPE_CONFIGS_GROUP,
329*34d4d093SThierry Bultel 					   configs, num_configs);
330*34d4d093SThierry Bultel 		if (ret < 0)
331*34d4d093SThierry Bultel 			goto done;
332*34d4d093SThierry Bultel 
333*34d4d093SThierry Bultel 		idx++;
334*34d4d093SThierry Bultel 	}
335*34d4d093SThierry Bultel 
336*34d4d093SThierry Bultel 	scoped_guard(mutex, &pctrl->mutex) {
337*34d4d093SThierry Bultel 		/* Register a single pin group listing all the pins we read from DT */
338*34d4d093SThierry Bultel 		gsel = pinctrl_generic_add_group(pctldev, name, pins, num_pinmux, NULL);
339*34d4d093SThierry Bultel 		if (gsel < 0) {
340*34d4d093SThierry Bultel 			ret = gsel;
341*34d4d093SThierry Bultel 			goto done;
342*34d4d093SThierry Bultel 		}
343*34d4d093SThierry Bultel 
344*34d4d093SThierry Bultel 		/*
345*34d4d093SThierry Bultel 		 * Register a single group function where the 'data' is an array PSEL
346*34d4d093SThierry Bultel 		 * register values read from DT.
347*34d4d093SThierry Bultel 		 */
348*34d4d093SThierry Bultel 		pin_fn[0] = name;
349*34d4d093SThierry Bultel 		fsel = pinmux_generic_add_function(pctldev, name, pin_fn, 1, psel_val);
350*34d4d093SThierry Bultel 		if (fsel < 0) {
351*34d4d093SThierry Bultel 			ret = fsel;
352*34d4d093SThierry Bultel 			goto remove_group;
353*34d4d093SThierry Bultel 		}
354*34d4d093SThierry Bultel 	}
355*34d4d093SThierry Bultel 
356*34d4d093SThierry Bultel 	maps[idx].type = PIN_MAP_TYPE_MUX_GROUP;
357*34d4d093SThierry Bultel 	maps[idx].data.mux.group = name;
358*34d4d093SThierry Bultel 	maps[idx].data.mux.function = name;
359*34d4d093SThierry Bultel 	idx++;
360*34d4d093SThierry Bultel 
361*34d4d093SThierry Bultel 	dev_dbg(pctrl->dev, "Parsed %pOF with %d pins\n", np, num_pinmux);
362*34d4d093SThierry Bultel 	ret = 0;
363*34d4d093SThierry Bultel 	goto done;
364*34d4d093SThierry Bultel 
365*34d4d093SThierry Bultel remove_group:
366*34d4d093SThierry Bultel 	pinctrl_generic_remove_group(pctldev, gsel);
367*34d4d093SThierry Bultel done:
368*34d4d093SThierry Bultel 	*index = idx;
369*34d4d093SThierry Bultel 	kfree(configs);
370*34d4d093SThierry Bultel 	return ret;
371*34d4d093SThierry Bultel }
372*34d4d093SThierry Bultel 
373*34d4d093SThierry Bultel static void rzt2h_dt_free_map(struct pinctrl_dev *pctldev,
374*34d4d093SThierry Bultel 			      struct pinctrl_map *map,
375*34d4d093SThierry Bultel 			      unsigned int num_maps)
376*34d4d093SThierry Bultel {
377*34d4d093SThierry Bultel 	unsigned int i;
378*34d4d093SThierry Bultel 
379*34d4d093SThierry Bultel 	if (!map)
380*34d4d093SThierry Bultel 		return;
381*34d4d093SThierry Bultel 
382*34d4d093SThierry Bultel 	for (i = 0; i < num_maps; ++i) {
383*34d4d093SThierry Bultel 		if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP ||
384*34d4d093SThierry Bultel 		    map[i].type == PIN_MAP_TYPE_CONFIGS_PIN)
385*34d4d093SThierry Bultel 			kfree(map[i].data.configs.configs);
386*34d4d093SThierry Bultel 	}
387*34d4d093SThierry Bultel 	kfree(map);
388*34d4d093SThierry Bultel }
389*34d4d093SThierry Bultel 
390*34d4d093SThierry Bultel static int rzt2h_dt_node_to_map(struct pinctrl_dev *pctldev,
391*34d4d093SThierry Bultel 				struct device_node *np,
392*34d4d093SThierry Bultel 				struct pinctrl_map **map,
393*34d4d093SThierry Bultel 				unsigned int *num_maps)
394*34d4d093SThierry Bultel {
395*34d4d093SThierry Bultel 	struct rzt2h_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
396*34d4d093SThierry Bultel 	unsigned int index;
397*34d4d093SThierry Bultel 	int ret;
398*34d4d093SThierry Bultel 
399*34d4d093SThierry Bultel 	*map = NULL;
400*34d4d093SThierry Bultel 	*num_maps = 0;
401*34d4d093SThierry Bultel 	index = 0;
402*34d4d093SThierry Bultel 
403*34d4d093SThierry Bultel 	for_each_child_of_node_scoped(np, child) {
404*34d4d093SThierry Bultel 		ret = rzt2h_dt_subnode_to_map(pctldev, child, np, map,
405*34d4d093SThierry Bultel 					      num_maps, &index);
406*34d4d093SThierry Bultel 		if (ret < 0)
407*34d4d093SThierry Bultel 			goto done;
408*34d4d093SThierry Bultel 	}
409*34d4d093SThierry Bultel 
410*34d4d093SThierry Bultel 	if (*num_maps == 0) {
411*34d4d093SThierry Bultel 		ret = rzt2h_dt_subnode_to_map(pctldev, np, NULL, map,
412*34d4d093SThierry Bultel 					      num_maps, &index);
413*34d4d093SThierry Bultel 		if (ret < 0)
414*34d4d093SThierry Bultel 			goto done;
415*34d4d093SThierry Bultel 	}
416*34d4d093SThierry Bultel 
417*34d4d093SThierry Bultel 	if (*num_maps)
418*34d4d093SThierry Bultel 		return 0;
419*34d4d093SThierry Bultel 
420*34d4d093SThierry Bultel 	dev_err(pctrl->dev, "no mapping found in node %pOF\n", np);
421*34d4d093SThierry Bultel 	ret = -EINVAL;
422*34d4d093SThierry Bultel 
423*34d4d093SThierry Bultel done:
424*34d4d093SThierry Bultel 	rzt2h_dt_free_map(pctldev, *map, *num_maps);
425*34d4d093SThierry Bultel 	return ret;
426*34d4d093SThierry Bultel }
427*34d4d093SThierry Bultel 
428*34d4d093SThierry Bultel static const struct pinctrl_ops rzt2h_pinctrl_pctlops = {
429*34d4d093SThierry Bultel 	.get_groups_count = pinctrl_generic_get_group_count,
430*34d4d093SThierry Bultel 	.get_group_name = pinctrl_generic_get_group_name,
431*34d4d093SThierry Bultel 	.get_group_pins = pinctrl_generic_get_group_pins,
432*34d4d093SThierry Bultel 	.dt_node_to_map = rzt2h_dt_node_to_map,
433*34d4d093SThierry Bultel 	.dt_free_map = rzt2h_dt_free_map,
434*34d4d093SThierry Bultel };
435*34d4d093SThierry Bultel 
436*34d4d093SThierry Bultel static const struct pinmux_ops rzt2h_pinctrl_pmxops = {
437*34d4d093SThierry Bultel 	.get_functions_count = pinmux_generic_get_function_count,
438*34d4d093SThierry Bultel 	.get_function_name = pinmux_generic_get_function_name,
439*34d4d093SThierry Bultel 	.get_function_groups = pinmux_generic_get_function_groups,
440*34d4d093SThierry Bultel 	.set_mux = rzt2h_pinctrl_set_mux,
441*34d4d093SThierry Bultel 	.strict = true,
442*34d4d093SThierry Bultel };
443*34d4d093SThierry Bultel 
444*34d4d093SThierry Bultel static int rzt2h_gpio_request(struct gpio_chip *chip, unsigned int offset)
445*34d4d093SThierry Bultel {
446*34d4d093SThierry Bultel 	struct rzt2h_pinctrl *pctrl = gpiochip_get_data(chip);
447*34d4d093SThierry Bultel 	u8 port = RZT2H_PIN_ID_TO_PORT(offset);
448*34d4d093SThierry Bultel 	u8 bit = RZT2H_PIN_ID_TO_PIN(offset);
449*34d4d093SThierry Bultel 	int ret;
450*34d4d093SThierry Bultel 	u8 reg;
451*34d4d093SThierry Bultel 
452*34d4d093SThierry Bultel 	ret = rzt2h_validate_pin(pctrl, offset);
453*34d4d093SThierry Bultel 	if (ret)
454*34d4d093SThierry Bultel 		return ret;
455*34d4d093SThierry Bultel 
456*34d4d093SThierry Bultel 	ret = pinctrl_gpio_request(chip, offset);
457*34d4d093SThierry Bultel 	if (ret)
458*34d4d093SThierry Bultel 		return ret;
459*34d4d093SThierry Bultel 
460*34d4d093SThierry Bultel 	guard(spinlock_irqsave)(&pctrl->lock);
461*34d4d093SThierry Bultel 
462*34d4d093SThierry Bultel 	/* Select GPIO mode in PMC Register */
463*34d4d093SThierry Bultel 	reg = rzt2h_pinctrl_readb(pctrl, port, PMC(port));
464*34d4d093SThierry Bultel 	reg &= ~BIT(bit);
465*34d4d093SThierry Bultel 	rzt2h_pinctrl_writeb(pctrl, port, reg, PMC(port));
466*34d4d093SThierry Bultel 
467*34d4d093SThierry Bultel 	return 0;
468*34d4d093SThierry Bultel }
469*34d4d093SThierry Bultel 
470*34d4d093SThierry Bultel static void rzt2h_gpio_set_direction(struct rzt2h_pinctrl *pctrl, u32 port,
471*34d4d093SThierry Bultel 				     u8 bit, bool output)
472*34d4d093SThierry Bultel {
473*34d4d093SThierry Bultel 	u16 reg;
474*34d4d093SThierry Bultel 
475*34d4d093SThierry Bultel 	guard(spinlock_irqsave)(&pctrl->lock);
476*34d4d093SThierry Bultel 
477*34d4d093SThierry Bultel 	reg = rzt2h_pinctrl_readw(pctrl, port, PM(port));
478*34d4d093SThierry Bultel 	reg &= ~PM_PIN_MASK(bit);
479*34d4d093SThierry Bultel 
480*34d4d093SThierry Bultel 	reg |= (output ? PM_OUTPUT : PM_INPUT) << (bit * 2);
481*34d4d093SThierry Bultel 	rzt2h_pinctrl_writew(pctrl, port, reg, PM(port));
482*34d4d093SThierry Bultel }
483*34d4d093SThierry Bultel 
484*34d4d093SThierry Bultel static int rzt2h_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
485*34d4d093SThierry Bultel {
486*34d4d093SThierry Bultel 	struct rzt2h_pinctrl *pctrl = gpiochip_get_data(chip);
487*34d4d093SThierry Bultel 	u8 port = RZT2H_PIN_ID_TO_PORT(offset);
488*34d4d093SThierry Bultel 	u8 bit = RZT2H_PIN_ID_TO_PIN(offset);
489*34d4d093SThierry Bultel 	u16 reg;
490*34d4d093SThierry Bultel 	int ret;
491*34d4d093SThierry Bultel 
492*34d4d093SThierry Bultel 	ret = rzt2h_validate_pin(pctrl, offset);
493*34d4d093SThierry Bultel 	if (ret)
494*34d4d093SThierry Bultel 		return ret;
495*34d4d093SThierry Bultel 
496*34d4d093SThierry Bultel 	if (rzt2h_pinctrl_readb(pctrl, port, PMC(port)) & BIT(bit))
497*34d4d093SThierry Bultel 		return -EINVAL;
498*34d4d093SThierry Bultel 
499*34d4d093SThierry Bultel 	reg = rzt2h_pinctrl_readw(pctrl, port, PM(port));
500*34d4d093SThierry Bultel 	reg = (reg >> (bit * 2)) & PM_MASK;
501*34d4d093SThierry Bultel 	if (reg & PM_OUTPUT)
502*34d4d093SThierry Bultel 		return GPIO_LINE_DIRECTION_OUT;
503*34d4d093SThierry Bultel 	if (reg & PM_INPUT)
504*34d4d093SThierry Bultel 		return GPIO_LINE_DIRECTION_IN;
505*34d4d093SThierry Bultel 
506*34d4d093SThierry Bultel 	return -EINVAL;
507*34d4d093SThierry Bultel }
508*34d4d093SThierry Bultel 
509*34d4d093SThierry Bultel static int rzt2h_gpio_set(struct gpio_chip *chip, unsigned int offset,
510*34d4d093SThierry Bultel 			  int value)
511*34d4d093SThierry Bultel {
512*34d4d093SThierry Bultel 	struct rzt2h_pinctrl *pctrl = gpiochip_get_data(chip);
513*34d4d093SThierry Bultel 	u8 port = RZT2H_PIN_ID_TO_PORT(offset);
514*34d4d093SThierry Bultel 	u8 bit = RZT2H_PIN_ID_TO_PIN(offset);
515*34d4d093SThierry Bultel 	u8 reg;
516*34d4d093SThierry Bultel 
517*34d4d093SThierry Bultel 	guard(spinlock_irqsave)(&pctrl->lock);
518*34d4d093SThierry Bultel 
519*34d4d093SThierry Bultel 	reg = rzt2h_pinctrl_readb(pctrl, port, P(port));
520*34d4d093SThierry Bultel 	if (value)
521*34d4d093SThierry Bultel 		rzt2h_pinctrl_writeb(pctrl, port, reg | BIT(bit), P(port));
522*34d4d093SThierry Bultel 	else
523*34d4d093SThierry Bultel 		rzt2h_pinctrl_writeb(pctrl, port, reg & ~BIT(bit), P(port));
524*34d4d093SThierry Bultel 
525*34d4d093SThierry Bultel 	return 0;
526*34d4d093SThierry Bultel }
527*34d4d093SThierry Bultel 
528*34d4d093SThierry Bultel static int rzt2h_gpio_get(struct gpio_chip *chip, unsigned int offset)
529*34d4d093SThierry Bultel {
530*34d4d093SThierry Bultel 	struct rzt2h_pinctrl *pctrl = gpiochip_get_data(chip);
531*34d4d093SThierry Bultel 	u8 port = RZT2H_PIN_ID_TO_PORT(offset);
532*34d4d093SThierry Bultel 	u8 bit = RZT2H_PIN_ID_TO_PIN(offset);
533*34d4d093SThierry Bultel 	u16 reg;
534*34d4d093SThierry Bultel 
535*34d4d093SThierry Bultel 	reg = rzt2h_pinctrl_readw(pctrl, port, PM(port));
536*34d4d093SThierry Bultel 	reg = (reg >> (bit * 2)) & PM_MASK;
537*34d4d093SThierry Bultel 	if (reg & PM_INPUT)
538*34d4d093SThierry Bultel 		return !!(rzt2h_pinctrl_readb(pctrl, port, PIN(port)) & BIT(bit));
539*34d4d093SThierry Bultel 	if (reg & PM_OUTPUT)
540*34d4d093SThierry Bultel 		return !!(rzt2h_pinctrl_readb(pctrl, port, P(port)) & BIT(bit));
541*34d4d093SThierry Bultel 
542*34d4d093SThierry Bultel 	return -EINVAL;
543*34d4d093SThierry Bultel }
544*34d4d093SThierry Bultel 
545*34d4d093SThierry Bultel static int rzt2h_gpio_direction_input(struct gpio_chip *chip,
546*34d4d093SThierry Bultel 				      unsigned int offset)
547*34d4d093SThierry Bultel {
548*34d4d093SThierry Bultel 	struct rzt2h_pinctrl *pctrl = gpiochip_get_data(chip);
549*34d4d093SThierry Bultel 	u8 port = RZT2H_PIN_ID_TO_PORT(offset);
550*34d4d093SThierry Bultel 	u8 bit = RZT2H_PIN_ID_TO_PIN(offset);
551*34d4d093SThierry Bultel 
552*34d4d093SThierry Bultel 	rzt2h_gpio_set_direction(pctrl, port, bit, false);
553*34d4d093SThierry Bultel 
554*34d4d093SThierry Bultel 	return 0;
555*34d4d093SThierry Bultel }
556*34d4d093SThierry Bultel 
557*34d4d093SThierry Bultel static int rzt2h_gpio_direction_output(struct gpio_chip *chip,
558*34d4d093SThierry Bultel 				       unsigned int offset, int value)
559*34d4d093SThierry Bultel {
560*34d4d093SThierry Bultel 	struct rzt2h_pinctrl *pctrl = gpiochip_get_data(chip);
561*34d4d093SThierry Bultel 	u8 port = RZT2H_PIN_ID_TO_PORT(offset);
562*34d4d093SThierry Bultel 	u8 bit = RZT2H_PIN_ID_TO_PIN(offset);
563*34d4d093SThierry Bultel 
564*34d4d093SThierry Bultel 	rzt2h_gpio_set(chip, offset, value);
565*34d4d093SThierry Bultel 	rzt2h_gpio_set_direction(pctrl, port, bit, true);
566*34d4d093SThierry Bultel 
567*34d4d093SThierry Bultel 	return 0;
568*34d4d093SThierry Bultel }
569*34d4d093SThierry Bultel 
570*34d4d093SThierry Bultel static void rzt2h_gpio_free(struct gpio_chip *chip, unsigned int offset)
571*34d4d093SThierry Bultel {
572*34d4d093SThierry Bultel 	pinctrl_gpio_free(chip, offset);
573*34d4d093SThierry Bultel 
574*34d4d093SThierry Bultel 	/*
575*34d4d093SThierry Bultel 	 * Set the GPIO as an input to ensure that the next GPIO request won't
576*34d4d093SThierry Bultel 	 * drive the GPIO pin as an output.
577*34d4d093SThierry Bultel 	 */
578*34d4d093SThierry Bultel 	rzt2h_gpio_direction_input(chip, offset);
579*34d4d093SThierry Bultel }
580*34d4d093SThierry Bultel 
581*34d4d093SThierry Bultel static const char * const rzt2h_gpio_names[] = {
582*34d4d093SThierry Bultel 	"P00_0", "P00_1", "P00_2", "P00_3", "P00_4", "P00_5", "P00_6", "P00_7",
583*34d4d093SThierry Bultel 	"P01_0", "P01_1", "P01_2", "P01_3", "P01_4", "P01_5", "P01_6", "P01_7",
584*34d4d093SThierry Bultel 	"P02_0", "P02_1", "P02_2", "P02_3", "P02_4", "P02_5", "P02_6", "P02_7",
585*34d4d093SThierry Bultel 	"P03_0", "P03_1", "P03_2", "P03_3", "P03_4", "P03_5", "P03_6", "P03_7",
586*34d4d093SThierry Bultel 	"P04_0", "P04_1", "P04_2", "P04_3", "P04_4", "P04_5", "P04_6", "P04_7",
587*34d4d093SThierry Bultel 	"P05_0", "P05_1", "P05_2", "P05_3", "P05_4", "P05_5", "P05_6", "P05_7",
588*34d4d093SThierry Bultel 	"P06_0", "P06_1", "P06_2", "P06_3", "P06_4", "P06_5", "P06_6", "P06_7",
589*34d4d093SThierry Bultel 	"P07_0", "P07_1", "P07_2", "P07_3", "P07_4", "P07_5", "P07_6", "P07_7",
590*34d4d093SThierry Bultel 	"P08_0", "P08_1", "P08_2", "P08_3", "P08_4", "P08_5", "P08_6", "P08_7",
591*34d4d093SThierry Bultel 	"P09_0", "P09_1", "P09_2", "P09_3", "P09_4", "P09_5", "P09_6", "P09_7",
592*34d4d093SThierry Bultel 	"P10_0", "P10_1", "P10_2", "P10_3", "P10_4", "P10_5", "P10_6", "P10_7",
593*34d4d093SThierry Bultel 	"P11_0", "P11_1", "P11_2", "P11_3", "P11_4", "P11_5", "P11_6", "P11_7",
594*34d4d093SThierry Bultel 	"P12_0", "P12_1", "P12_2", "P12_3", "P12_4", "P12_5", "P12_6", "P12_7",
595*34d4d093SThierry Bultel 	"P13_0", "P13_1", "P13_2", "P13_3", "P13_4", "P13_5", "P13_6", "P13_7",
596*34d4d093SThierry Bultel 	"P14_0", "P14_1", "P14_2", "P14_3", "P14_4", "P14_5", "P14_6", "P14_7",
597*34d4d093SThierry Bultel 	"P15_0", "P15_1", "P15_2", "P15_3", "P15_4", "P15_5", "P15_6", "P15_7",
598*34d4d093SThierry Bultel 	"P16_0", "P16_1", "P16_2", "P16_3", "P16_4", "P16_5", "P16_6", "P16_7",
599*34d4d093SThierry Bultel 	"P17_0", "P17_1", "P17_2", "P17_3", "P17_4", "P17_5", "P17_6", "P17_7",
600*34d4d093SThierry Bultel 	"P18_0", "P18_1", "P18_2", "P18_3", "P18_4", "P18_5", "P18_6", "P18_7",
601*34d4d093SThierry Bultel 	"P19_0", "P19_1", "P19_2", "P19_3", "P19_4", "P19_5", "P19_6", "P19_7",
602*34d4d093SThierry Bultel 	"P20_0", "P20_1", "P20_2", "P20_3", "P20_4", "P20_5", "P20_6", "P20_7",
603*34d4d093SThierry Bultel 	"P21_0", "P21_1", "P21_2", "P21_3", "P21_4", "P21_5", "P21_6", "P21_7",
604*34d4d093SThierry Bultel 	"P22_0", "P22_1", "P22_2", "P22_3", "P22_4", "P22_5", "P22_6", "P22_7",
605*34d4d093SThierry Bultel 	"P23_0", "P23_1", "P23_2", "P23_3", "P23_4", "P23_5", "P23_6", "P23_7",
606*34d4d093SThierry Bultel 	"P24_0", "P24_1", "P24_2", "P24_3", "P24_4", "P24_5", "P24_6", "P24_7",
607*34d4d093SThierry Bultel 	"P25_0", "P25_1", "P25_2", "P25_3", "P25_4", "P25_5", "P25_6", "P25_7",
608*34d4d093SThierry Bultel 	"P26_0", "P26_1", "P26_2", "P26_3", "P26_4", "P26_5", "P26_6", "P26_7",
609*34d4d093SThierry Bultel 	"P27_0", "P27_1", "P27_2", "P27_3", "P27_4", "P27_5", "P27_6", "P27_7",
610*34d4d093SThierry Bultel 	"P28_0", "P28_1", "P28_2", "P28_3", "P28_4", "P28_5", "P28_6", "P28_7",
611*34d4d093SThierry Bultel 	"P29_0", "P29_1", "P29_2", "P29_3", "P29_4", "P29_5", "P29_6", "P29_7",
612*34d4d093SThierry Bultel 	"P30_0", "P30_1", "P30_2", "P30_3", "P30_4", "P30_5", "P30_6", "P30_7",
613*34d4d093SThierry Bultel 	"P31_0", "P31_1", "P31_2", "P31_3", "P31_4", "P31_5", "P31_6", "P31_7",
614*34d4d093SThierry Bultel 	"P32_0", "P32_1", "P32_2", "P32_3", "P32_4", "P32_5", "P32_6", "P32_7",
615*34d4d093SThierry Bultel 	"P33_0", "P33_1", "P33_2", "P33_3", "P33_4", "P33_5", "P33_6", "P33_7",
616*34d4d093SThierry Bultel 	"P34_0", "P34_1", "P34_2", "P34_3", "P34_4", "P34_5", "P34_6", "P34_7",
617*34d4d093SThierry Bultel 	"P35_0", "P35_1", "P35_2", "P35_3", "P35_4", "P35_5", "P35_6", "P35_7",
618*34d4d093SThierry Bultel };
619*34d4d093SThierry Bultel 
620*34d4d093SThierry Bultel static int rzt2h_gpio_register(struct rzt2h_pinctrl *pctrl)
621*34d4d093SThierry Bultel {
622*34d4d093SThierry Bultel 	struct pinctrl_gpio_range *range = &pctrl->gpio_range;
623*34d4d093SThierry Bultel 	struct gpio_chip *chip = &pctrl->gpio_chip;
624*34d4d093SThierry Bultel 	struct device *dev = pctrl->dev;
625*34d4d093SThierry Bultel 	struct of_phandle_args of_args;
626*34d4d093SThierry Bultel 	int ret;
627*34d4d093SThierry Bultel 
628*34d4d093SThierry Bultel 	ret = of_parse_phandle_with_fixed_args(dev->of_node, "gpio-ranges", 3, 0, &of_args);
629*34d4d093SThierry Bultel 	if (ret)
630*34d4d093SThierry Bultel 		return dev_err_probe(dev, ret, "Unable to parse gpio-ranges\n");
631*34d4d093SThierry Bultel 
632*34d4d093SThierry Bultel 	if (of_args.args[0] != 0 || of_args.args[1] != 0 ||
633*34d4d093SThierry Bultel 	    of_args.args[2] != pctrl->data->n_port_pins)
634*34d4d093SThierry Bultel 		return dev_err_probe(dev, -EINVAL,
635*34d4d093SThierry Bultel 				     "gpio-ranges does not match selected SOC\n");
636*34d4d093SThierry Bultel 
637*34d4d093SThierry Bultel 	chip->base = -1;
638*34d4d093SThierry Bultel 	chip->parent = dev;
639*34d4d093SThierry Bultel 	chip->owner = THIS_MODULE;
640*34d4d093SThierry Bultel 	chip->ngpio = of_args.args[2];
641*34d4d093SThierry Bultel 	chip->names = rzt2h_gpio_names;
642*34d4d093SThierry Bultel 	chip->request = rzt2h_gpio_request;
643*34d4d093SThierry Bultel 	chip->free = rzt2h_gpio_free;
644*34d4d093SThierry Bultel 	chip->get_direction = rzt2h_gpio_get_direction;
645*34d4d093SThierry Bultel 	chip->direction_input = rzt2h_gpio_direction_input;
646*34d4d093SThierry Bultel 	chip->direction_output = rzt2h_gpio_direction_output;
647*34d4d093SThierry Bultel 	chip->get = rzt2h_gpio_get;
648*34d4d093SThierry Bultel 	chip->set = rzt2h_gpio_set;
649*34d4d093SThierry Bultel 	chip->label = dev_name(dev);
650*34d4d093SThierry Bultel 
651*34d4d093SThierry Bultel 	range->id = 0;
652*34d4d093SThierry Bultel 	range->pin_base = 0;
653*34d4d093SThierry Bultel 	range->base = 0;
654*34d4d093SThierry Bultel 	range->npins = chip->ngpio;
655*34d4d093SThierry Bultel 	range->name = chip->label;
656*34d4d093SThierry Bultel 	range->gc = chip;
657*34d4d093SThierry Bultel 
658*34d4d093SThierry Bultel 	ret = devm_gpiochip_add_data(dev, chip, pctrl);
659*34d4d093SThierry Bultel 	if (ret)
660*34d4d093SThierry Bultel 		return dev_err_probe(dev, ret, "gpiochip registration failed\n");
661*34d4d093SThierry Bultel 
662*34d4d093SThierry Bultel 	return ret;
663*34d4d093SThierry Bultel }
664*34d4d093SThierry Bultel 
665*34d4d093SThierry Bultel static int rzt2h_pinctrl_register(struct rzt2h_pinctrl *pctrl)
666*34d4d093SThierry Bultel {
667*34d4d093SThierry Bultel 	struct pinctrl_desc *desc = &pctrl->desc;
668*34d4d093SThierry Bultel 	struct device *dev = pctrl->dev;
669*34d4d093SThierry Bultel 	struct pinctrl_pin_desc *pins;
670*34d4d093SThierry Bultel 	unsigned int i, j;
671*34d4d093SThierry Bultel 	int ret;
672*34d4d093SThierry Bultel 
673*34d4d093SThierry Bultel 	desc->name = DRV_NAME;
674*34d4d093SThierry Bultel 	desc->npins = pctrl->data->n_port_pins;
675*34d4d093SThierry Bultel 	desc->pctlops = &rzt2h_pinctrl_pctlops;
676*34d4d093SThierry Bultel 	desc->pmxops = &rzt2h_pinctrl_pmxops;
677*34d4d093SThierry Bultel 	desc->owner = THIS_MODULE;
678*34d4d093SThierry Bultel 
679*34d4d093SThierry Bultel 	pins = devm_kcalloc(dev, desc->npins, sizeof(*pins), GFP_KERNEL);
680*34d4d093SThierry Bultel 	if (!pins)
681*34d4d093SThierry Bultel 		return -ENOMEM;
682*34d4d093SThierry Bultel 
683*34d4d093SThierry Bultel 	pctrl->pins = pins;
684*34d4d093SThierry Bultel 	desc->pins = pins;
685*34d4d093SThierry Bultel 
686*34d4d093SThierry Bultel 	for (i = 0, j = 0; i < pctrl->data->n_port_pins; i++) {
687*34d4d093SThierry Bultel 		pins[i].number = i;
688*34d4d093SThierry Bultel 		pins[i].name = rzt2h_gpio_names[i];
689*34d4d093SThierry Bultel 		if (i && !(i % RZT2H_PINS_PER_PORT))
690*34d4d093SThierry Bultel 			j++;
691*34d4d093SThierry Bultel 	}
692*34d4d093SThierry Bultel 
693*34d4d093SThierry Bultel 	ret = devm_pinctrl_register_and_init(dev, desc, pctrl, &pctrl->pctl);
694*34d4d093SThierry Bultel 	if (ret)
695*34d4d093SThierry Bultel 		return dev_err_probe(dev, ret, "pinctrl registration failed\n");
696*34d4d093SThierry Bultel 
697*34d4d093SThierry Bultel 	ret = pinctrl_enable(pctrl->pctl);
698*34d4d093SThierry Bultel 	if (ret)
699*34d4d093SThierry Bultel 		return dev_err_probe(dev, ret, "pinctrl enable failed\n");
700*34d4d093SThierry Bultel 
701*34d4d093SThierry Bultel 	return rzt2h_gpio_register(pctrl);
702*34d4d093SThierry Bultel }
703*34d4d093SThierry Bultel 
704*34d4d093SThierry Bultel static int rzt2h_pinctrl_cfg_regions(struct platform_device *pdev,
705*34d4d093SThierry Bultel 				     struct rzt2h_pinctrl *pctrl)
706*34d4d093SThierry Bultel {
707*34d4d093SThierry Bultel 	struct resource *res;
708*34d4d093SThierry Bultel 
709*34d4d093SThierry Bultel 	pctrl->base0 = devm_platform_ioremap_resource_byname(pdev, "nsr");
710*34d4d093SThierry Bultel 	if (IS_ERR(pctrl->base0))
711*34d4d093SThierry Bultel 		return PTR_ERR(pctrl->base0);
712*34d4d093SThierry Bultel 
713*34d4d093SThierry Bultel 	/*
714*34d4d093SThierry Bultel 	 * Open-coded instead of using devm_platform_ioremap_resource_byname()
715*34d4d093SThierry Bultel 	 * because the "srs" region is optional.
716*34d4d093SThierry Bultel 	 */
717*34d4d093SThierry Bultel 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "srs");
718*34d4d093SThierry Bultel 	if (res) {
719*34d4d093SThierry Bultel 		u8 port;
720*34d4d093SThierry Bultel 
721*34d4d093SThierry Bultel 		pctrl->base1 = devm_ioremap_resource(&pdev->dev, res);
722*34d4d093SThierry Bultel 		if (IS_ERR(pctrl->base1))
723*34d4d093SThierry Bultel 			return PTR_ERR(pctrl->base1);
724*34d4d093SThierry Bultel 
725*34d4d093SThierry Bultel 		pctrl->safety_port_enabled = true;
726*34d4d093SThierry Bultel 
727*34d4d093SThierry Bultel 		/* Configure to select safety region 0x812c0xxx */
728*34d4d093SThierry Bultel 		for (port = 0; port <= RZT2H_MAX_SAFETY_PORTS; port++)
729*34d4d093SThierry Bultel 			writeb(0x0, pctrl->base1 + RSELP(port));
730*34d4d093SThierry Bultel 	}
731*34d4d093SThierry Bultel 
732*34d4d093SThierry Bultel 	return 0;
733*34d4d093SThierry Bultel }
734*34d4d093SThierry Bultel 
735*34d4d093SThierry Bultel static int rzt2h_pinctrl_probe(struct platform_device *pdev)
736*34d4d093SThierry Bultel {
737*34d4d093SThierry Bultel 	struct device *dev = &pdev->dev;
738*34d4d093SThierry Bultel 	struct rzt2h_pinctrl *pctrl;
739*34d4d093SThierry Bultel 	int ret;
740*34d4d093SThierry Bultel 
741*34d4d093SThierry Bultel 	pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL);
742*34d4d093SThierry Bultel 	if (!pctrl)
743*34d4d093SThierry Bultel 		return -ENOMEM;
744*34d4d093SThierry Bultel 
745*34d4d093SThierry Bultel 	pctrl->dev = dev;
746*34d4d093SThierry Bultel 	pctrl->data = of_device_get_match_data(dev);
747*34d4d093SThierry Bultel 
748*34d4d093SThierry Bultel 	ret = rzt2h_pinctrl_cfg_regions(pdev, pctrl);
749*34d4d093SThierry Bultel 	if (ret)
750*34d4d093SThierry Bultel 		return ret;
751*34d4d093SThierry Bultel 
752*34d4d093SThierry Bultel 	spin_lock_init(&pctrl->lock);
753*34d4d093SThierry Bultel 	mutex_init(&pctrl->mutex);
754*34d4d093SThierry Bultel 	platform_set_drvdata(pdev, pctrl);
755*34d4d093SThierry Bultel 
756*34d4d093SThierry Bultel 	return rzt2h_pinctrl_register(pctrl);
757*34d4d093SThierry Bultel }
758*34d4d093SThierry Bultel 
759*34d4d093SThierry Bultel static const u8 r9a09g077_gpio_configs[] = {
760*34d4d093SThierry Bultel 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
761*34d4d093SThierry Bultel 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
762*34d4d093SThierry Bultel 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
763*34d4d093SThierry Bultel };
764*34d4d093SThierry Bultel 
765*34d4d093SThierry Bultel static struct rzt2h_pinctrl_data r9a09g077_data = {
766*34d4d093SThierry Bultel 	.n_port_pins = ARRAY_SIZE(r9a09g077_gpio_configs) * RZT2H_PINS_PER_PORT,
767*34d4d093SThierry Bultel 	.port_pin_configs = r9a09g077_gpio_configs,
768*34d4d093SThierry Bultel 	.n_ports = ARRAY_SIZE(r9a09g077_gpio_configs),
769*34d4d093SThierry Bultel };
770*34d4d093SThierry Bultel 
771*34d4d093SThierry Bultel static const struct of_device_id rzt2h_pinctrl_of_table[] = {
772*34d4d093SThierry Bultel 	{
773*34d4d093SThierry Bultel 		.compatible = "renesas,r9a09g077-pinctrl",
774*34d4d093SThierry Bultel 		.data = &r9a09g077_data,
775*34d4d093SThierry Bultel 	},
776*34d4d093SThierry Bultel 	{ /* sentinel */ }
777*34d4d093SThierry Bultel };
778*34d4d093SThierry Bultel 
779*34d4d093SThierry Bultel static struct platform_driver rzt2h_pinctrl_driver = {
780*34d4d093SThierry Bultel 	.driver = {
781*34d4d093SThierry Bultel 		.name = DRV_NAME,
782*34d4d093SThierry Bultel 		.of_match_table = of_match_ptr(rzt2h_pinctrl_of_table),
783*34d4d093SThierry Bultel 		.suppress_bind_attrs = true,
784*34d4d093SThierry Bultel 	},
785*34d4d093SThierry Bultel 	.probe = rzt2h_pinctrl_probe,
786*34d4d093SThierry Bultel };
787*34d4d093SThierry Bultel 
788*34d4d093SThierry Bultel static int __init rzt2h_pinctrl_init(void)
789*34d4d093SThierry Bultel {
790*34d4d093SThierry Bultel 	return platform_driver_register(&rzt2h_pinctrl_driver);
791*34d4d093SThierry Bultel }
792*34d4d093SThierry Bultel core_initcall(rzt2h_pinctrl_init);
793*34d4d093SThierry Bultel 
794*34d4d093SThierry Bultel MODULE_LICENSE("GPL");
795*34d4d093SThierry Bultel MODULE_AUTHOR("Thierry Bultel <thierry.bultel.yh@bp.renesas.com>");
796*34d4d093SThierry Bultel MODULE_AUTHOR("Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>");
797*34d4d093SThierry Bultel MODULE_DESCRIPTION("Pin and gpio controller driver for the RZ/T2H family");
798