xref: /linux/drivers/pinctrl/pinctrl-eyeq5.c (revision 5ea5880764cbb164afb17a62e76ca75dc371409d)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Pinctrl driver for the Mobileye EyeQ5 platform.
4  *
5  * The registers are located in a syscon region called OLB. There are two pin
6  * banks, each being controlled by 5 registers (see enum eq5p_regs) for
7  * pull-down, pull-up, drive strength and muxing.
8  *
9  * For each pin, muxing is between two functions: (0) GPIO or (1) another one
10  * that is pin-dependent. Functions are declared statically in this driver.
11  *
12  * We create pinctrl groups that are 1:1 equivalent to pins: each group has a
13  * single pin, and its index/selector is the pin number.
14  *
15  * We use eq5p_ as prefix, as-in "EyeQ5 Pinctrl", but way shorter.
16  *
17  * Copyright (C) 2024 Mobileye Vision Technologies Ltd.
18  */
19 
20 #include <linux/array_size.h>
21 #include <linux/auxiliary_bus.h>
22 #include <linux/bits.h>
23 #include <linux/bug.h>
24 #include <linux/device.h>
25 #include <linux/err.h>
26 #include <linux/errno.h>
27 #include <linux/io.h>
28 #include <linux/mod_devicetable.h>
29 #include <linux/of.h>
30 #include <linux/seq_file.h>
31 #include <linux/slab.h>
32 #include <linux/types.h>
33 
34 #include <linux/pinctrl/pinconf-generic.h>
35 #include <linux/pinctrl/pinconf.h>
36 #include <linux/pinctrl/pinctrl.h>
37 #include <linux/pinctrl/pinmux.h>
38 
39 #include "core.h"
40 #include "pinctrl-utils.h"
41 
42 enum eq5p_regs {
43 	EQ5P_PD,
44 	EQ5P_PU,
45 	EQ5P_DS_LOW,
46 	EQ5P_DS_HIGH,
47 	EQ5P_IOCR,
48 
49 	EQ5P_REG_COUNT,
50 };
51 
52 struct eq5p_bank {
53 	const unsigned int npins;
54 	const unsigned int regs[EQ5P_REG_COUNT];
55 };
56 
57 struct eq5p_match_data {
58 	const unsigned int npins;
59 	const unsigned int nfunctions;
60 	const unsigned int nbanks;
61 	const struct pinctrl_pin_desc *pins;
62 	const struct pinfunction *functions;
63 	const struct eq5p_bank *banks;
64 };
65 
66 struct eq5p_pinctrl {
67 	struct pinctrl_desc		desc;
68 	void __iomem			*base;
69 	const struct eq5p_match_data	*data;
70 };
71 
72 /*
73  * Drive strength; two bits per pin.
74  */
75 #define EQ5P_DS_MASK	GENMASK(1, 0)
76 
77 /*
78  * The GPIO function is always the first function
79  */
80 #define EQ5P_GPIO_FUNC_SELECTOR 0
81 
82 /* Helper to declare pinfunction */
83 #define EQ5P_PINFUNCTION(func, groups) PINCTRL_PINFUNCTION(func, groups, ARRAY_SIZE(groups))
84 
85 /*
86  * Comments to the right of each pin are the "signal name" in the datasheet.
87  */
88 static const struct pinctrl_pin_desc eq5p_eyeq5_pins[] = {
89 	/* Bank A */
90 	PINCTRL_PIN(0,  "PA0"),  /* A0_TIMER0_CK */
91 	PINCTRL_PIN(1,  "PA1"),  /* A1_TIMER0_EOC */
92 	PINCTRL_PIN(2,  "PA2"),  /* A2_TIMER1_CK */
93 	PINCTRL_PIN(3,  "PA3"),  /* A3_TIMER1_EOC */
94 	PINCTRL_PIN(4,  "PA4"),  /* A4_TIMER2_CK */
95 	PINCTRL_PIN(5,  "PA5"),  /* A5_TIMER2_EOC */
96 	PINCTRL_PIN(6,  "PA6"),  /* A6_TIMER5_EXT_INCAP1 */
97 	PINCTRL_PIN(7,  "PA7"),  /* A7_TIMER5_EXT_INCAP2 */
98 	PINCTRL_PIN(8,  "PA8"),  /* A8_TIMER5_EXT_OUTCMP1 */
99 	PINCTRL_PIN(9,  "PA9"),  /* A9_TIMER5_EXT_OUTCMP2 */
100 	PINCTRL_PIN(10, "PA10"), /* A10_UART_0_TX */
101 	PINCTRL_PIN(11, "PA11"), /* A11_UART_0_RX */
102 	PINCTRL_PIN(12, "PA12"), /* A12_UART_1_TX */
103 	PINCTRL_PIN(13, "PA13"), /* A13_UART_1_RX */
104 	PINCTRL_PIN(14, "PA14"), /* A14_CAN_0_TX */
105 	PINCTRL_PIN(15, "PA15"), /* A15_CAN_0_RX */
106 	PINCTRL_PIN(16, "PA16"), /* A16_CAN_1_TX */
107 	PINCTRL_PIN(17, "PA17"), /* A17_CAN_1_RX */
108 	PINCTRL_PIN(18, "PA18"), /* A18_SPI_0_DO */
109 	PINCTRL_PIN(19, "PA19"), /* A19_SPI_0_DI */
110 	PINCTRL_PIN(20, "PA20"), /* A20_SPI_0_CK */
111 	PINCTRL_PIN(21, "PA21"), /* A21_SPI_0_CS0 */
112 	PINCTRL_PIN(22, "PA22"), /* A22_SPI_0_CS1 */
113 	PINCTRL_PIN(23, "PA23"), /* A23_SPI_1_DO */
114 	PINCTRL_PIN(24, "PA24"), /* A24_SPI_1_DI */
115 	PINCTRL_PIN(25, "PA25"), /* A25_SPI_1_CK */
116 	PINCTRL_PIN(26, "PA26"), /* A26_SPI_1_CS0 */
117 	PINCTRL_PIN(27, "PA27"), /* A27_SPI_1_CS1 */
118 	PINCTRL_PIN(28, "PA28"), /* A28_REF_CLK0 */
119 
120 #define EQ5P_EYEQ5_PIN_OFFSET_BANK_B	29
121 
122 	/* Bank B */
123 	PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 0,  "PB0"),  /* B0_TIMER3_CK */
124 	PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 1,  "PB1"),  /* B1_TIMER3_EOC */
125 	PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 2,  "PB2"),  /* B2_TIMER4_CK */
126 	PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 3,  "PB3"),  /* B3_TIMER4_EOC */
127 	PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 4,  "PB4"),  /* B4_TIMER6_EXT_INCAP1 */
128 	PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 5,  "PB5"),  /* B5_TIMER6_EXT_INCAP2 */
129 	PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 6,  "PB6"),  /* B6_TIMER6_EXT_OUTCMP1 */
130 	PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 7,  "PB7"),  /* B7_TIMER6_EXT_OUTCMP2 */
131 	PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 8,  "PB8"),  /* B8_UART_2_TX */
132 	PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 9,  "PB9"),  /* B9_UART_2_RX */
133 	PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 10, "PB10"), /* B10_CAN_2_TX */
134 	PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 11, "PB11"), /* B11_CAN_2_RX */
135 	PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 12, "PB12"), /* B12_SPI_2_DO */
136 	PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 13, "PB13"), /* B13_SPI_2_DI */
137 	PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 14, "PB14"), /* B14_SPI_2_CK */
138 	PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 15, "PB15"), /* B15_SPI_2_CS0 */
139 	PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 16, "PB16"), /* B16_SPI_2_CS1 */
140 	PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 17, "PB17"), /* B17_SPI_3_DO */
141 	PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 18, "PB18"), /* B18_SPI_3_DI */
142 	PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 19, "PB19"), /* B19_SPI_3_CK */
143 	PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 20, "PB20"), /* B20_SPI_3_CS0 */
144 	PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 21, "PB21"), /* B21_SPI_3_CS1 */
145 	PINCTRL_PIN(EQ5P_EYEQ5_PIN_OFFSET_BANK_B + 22, "PB22"), /* B22_MCLK0 */
146 };
147 
148 static const char * const eq5p_eyeq5_gpio_groups[] = {
149 	/* Bank A */
150 	"PA0",  "PA1",  "PA2",  "PA3",  "PA4",  "PA5",  "PA6",  "PA7",
151 	"PA8",  "PA9",  "PA10", "PA11", "PA12", "PA13", "PA14", "PA15",
152 	"PA16", "PA17", "PA18", "PA19", "PA20", "PA21", "PA22", "PA23",
153 	"PA24", "PA25", "PA26", "PA27", "PA28",
154 
155 	/* Bank B */
156 	"PB0",  "PB1",  "PB2",  "PB3",  "PB4",  "PB5",  "PB6",  "PB7",
157 	"PB8",  "PB9",  "PB10", "PB11", "PB12", "PB13", "PB14", "PB15",
158 	"PB16", "PB17", "PB18", "PB19", "PB20", "PB21", "PB22",
159 };
160 
161 /* Groups of functions on bank A */
162 static const char * const eq5p_eyeq5_timer0_groups[] = { "PA0", "PA1" };
163 static const char * const eq5p_eyeq5_timer1_groups[] = { "PA2", "PA3" };
164 static const char * const eq5p_eyeq5_timer2_groups[] = { "PA4", "PA5" };
165 static const char * const eq5p_eyeq5_timer5_groups[] = { "PA6", "PA7", "PA8", "PA9" };
166 static const char * const eq5p_eyeq5_uart0_groups[] = { "PA10", "PA11" };
167 static const char * const eq5p_eyeq5_uart1_groups[] = { "PA12", "PA13" };
168 static const char * const eq5p_eyeq5_can0_groups[] = { "PA14", "PA15" };
169 static const char * const eq5p_eyeq5_can1_groups[] = { "PA16", "PA17" };
170 static const char * const eq5p_eyeq5_spi0_groups[] = { "PA18", "PA19", "PA20", "PA21", "PA22" };
171 static const char * const eq5p_eyeq5_spi1_groups[] = { "PA23", "PA24", "PA25", "PA26", "PA27" };
172 static const char * const eq5p_eyeq5_refclk0_groups[] = { "PA28" };
173 
174 /* Groups of functions on bank B */
175 static const char * const eq5p_eyeq5_timer3_groups[] = { "PB0", "PB1" };
176 static const char * const eq5p_eyeq5_timer4_groups[] = { "PB2", "PB3" };
177 static const char * const eq5p_eyeq5_timer6_groups[] = { "PB4", "PB5", "PB6", "PB7" };
178 static const char * const eq5p_eyeq5_uart2_groups[] = { "PB8", "PB9" };
179 static const char * const eq5p_eyeq5_can2_groups[] = { "PB10", "PB11" };
180 static const char * const eq5p_eyeq5_spi2_groups[] = { "PB12", "PB13", "PB14", "PB15", "PB16" };
181 static const char * const eq5p_eyeq5_spi3_groups[] = { "PB17", "PB18", "PB19", "PB20", "PB21" };
182 static const char * const eq5p_eyeq5_mclk0_groups[] = { "PB22" };
183 
184 static const struct pinfunction eq5p_eyeq5_functions[] = {
185 	/* GPIO having a fixed index is depended upon, see EQ5P_GPIO_FUNC_SELECTOR. */
186 	EQ5P_PINFUNCTION("gpio", eq5p_eyeq5_gpio_groups),
187 
188 	/* Bank A functions */
189 	EQ5P_PINFUNCTION("timer0", eq5p_eyeq5_timer0_groups),
190 	EQ5P_PINFUNCTION("timer1", eq5p_eyeq5_timer1_groups),
191 	EQ5P_PINFUNCTION("timer2", eq5p_eyeq5_timer2_groups),
192 	EQ5P_PINFUNCTION("timer5", eq5p_eyeq5_timer5_groups),
193 	EQ5P_PINFUNCTION("uart0", eq5p_eyeq5_uart0_groups),
194 	EQ5P_PINFUNCTION("uart1", eq5p_eyeq5_uart1_groups),
195 	EQ5P_PINFUNCTION("can0", eq5p_eyeq5_can0_groups),
196 	EQ5P_PINFUNCTION("can1", eq5p_eyeq5_can1_groups),
197 	EQ5P_PINFUNCTION("spi0", eq5p_eyeq5_spi0_groups),
198 	EQ5P_PINFUNCTION("spi1", eq5p_eyeq5_spi1_groups),
199 	EQ5P_PINFUNCTION("refclk0", eq5p_eyeq5_refclk0_groups),
200 
201 	/* Bank B functions */
202 	EQ5P_PINFUNCTION("timer3", eq5p_eyeq5_timer3_groups),
203 	EQ5P_PINFUNCTION("timer4", eq5p_eyeq5_timer4_groups),
204 	EQ5P_PINFUNCTION("timer6", eq5p_eyeq5_timer6_groups),
205 	EQ5P_PINFUNCTION("uart2", eq5p_eyeq5_uart2_groups),
206 	EQ5P_PINFUNCTION("can2", eq5p_eyeq5_can2_groups),
207 	EQ5P_PINFUNCTION("spi2", eq5p_eyeq5_spi2_groups),
208 	EQ5P_PINFUNCTION("spi3", eq5p_eyeq5_spi3_groups),
209 	EQ5P_PINFUNCTION("mclk0", eq5p_eyeq5_mclk0_groups),
210 };
211 
212 static const struct eq5p_bank eq5p_eyeq5_banks[] = {
213 	{
214 		.npins = EQ5P_EYEQ5_PIN_OFFSET_BANK_B,
215 		.regs = {0x0C0, 0x0C4, 0x0D0, 0x0D4, 0x0B0},
216 	},
217 	{
218 		.npins = ARRAY_SIZE(eq5p_eyeq5_pins) - EQ5P_EYEQ5_PIN_OFFSET_BANK_B,
219 		.regs = {0x0C8, 0x0CC, 0x0D8, 0x0DC, 0x0B4},
220 	},
221 };
222 
223 static const struct eq5p_match_data eq5p_eyeq5_data = {
224 	.npins = ARRAY_SIZE(eq5p_eyeq5_pins),
225 	.nfunctions = ARRAY_SIZE(eq5p_eyeq5_functions),
226 	.nbanks = ARRAY_SIZE(eq5p_eyeq5_banks),
227 	.pins = eq5p_eyeq5_pins,
228 	.functions = eq5p_eyeq5_functions,
229 	.banks = eq5p_eyeq5_banks,
230 };
231 
232 static const struct pinctrl_pin_desc eq5p_eyeq6lplus_pins[] = {
233 	PINCTRL_PIN(0,  "PA0"),  /* GPIO_A0_TIMER0_CK0 */
234 	PINCTRL_PIN(1,  "PA1"),  /* GPIO_A1_TIMER0_EOC */
235 	PINCTRL_PIN(2,  "PA2"),  /* GPIO_A2_TIMER1_CK */
236 	PINCTRL_PIN(3,  "PA3"),  /* GPIO_A3_TIMER1_EOC1 */
237 	PINCTRL_PIN(4,  "PA4"),  /* GPIO_A4_SSI_UART_RX */
238 	PINCTRL_PIN(5,  "PA5"),  /* GPIO_A5_SSI_UART_TX */
239 	PINCTRL_PIN(6,  "PA6"),  /* GPIO_A6_SPI_0_CS */
240 	PINCTRL_PIN(7,  "PA7"),  /* GPIO_A7_SPI_0_DI */
241 	PINCTRL_PIN(8,  "PA8"),  /* GPIO_A8_SPI_0_CK */
242 	PINCTRL_PIN(9,  "PA9"),  /* GPIO_A9_SPI_0_DO */
243 	PINCTRL_PIN(10, "PA10"), /* GPIO_A10_SPI_0_CS1 */
244 	PINCTRL_PIN(11, "PA11"), /* GPIO_A11_UART_0_RX */
245 	PINCTRL_PIN(12, "PA12"), /* GPIO_A12_UART_0_TX */
246 	PINCTRL_PIN(13, "PA13"), /* GPIO_A13_TIMER2_CK */
247 	PINCTRL_PIN(14, "PA14"), /* GPIO_A14_TIMER2_EOC */
248 	PINCTRL_PIN(15, "PA15"), /* GPIO_A15_TIMER3_CK */
249 	PINCTRL_PIN(16, "PA16"), /* GPIO_A16_TIMER_EOC */
250 	PINCTRL_PIN(17, "PA17"), /* GPIO_A17_TIMER_EXT0_INCA P1 */
251 	PINCTRL_PIN(18, "PA18"), /* GPIO_A18_TIMER_EXT0_INCA P2 */
252 	PINCTRL_PIN(19, "PA19"), /* GPIO_A19_TIMER_EXT0_OUT CMP1 */
253 	PINCTRL_PIN(20, "PA20"), /* GPIO_A20_TIMER_EXT0_OUT CMP2 */
254 	PINCTRL_PIN(21, "PA21"), /* GPIO_A21_SPI_1_CS0 */
255 	PINCTRL_PIN(22, "PA22"), /* GPIO_A22_SPI_1_DI */
256 	PINCTRL_PIN(23, "PA23"), /* GPIO_A23_SPI_1_CK */
257 	PINCTRL_PIN(24, "PA24"), /* GPIO_A24_SPI_1_DO */
258 	PINCTRL_PIN(25, "PA25"), /* GPIO_A25_SPI_1_CS1 */
259 	PINCTRL_PIN(26, "PA26"), /* GPIO_A26_TIMER_EXT1_INCA P1 */
260 	PINCTRL_PIN(27, "PA27"), /* GPIO_A27_TIMER_EXT1_INCA P2 */
261 	PINCTRL_PIN(28, "PA28"), /* GPIO_A28_TIMER_EXT1_OUTC MP1 */
262 	PINCTRL_PIN(29, "PA29"), /* GPIO_A29_TIMER_EXT1_OUTC MP2 */
263 	PINCTRL_PIN(30, "PA30"), /* GPIO_A30_EXT_CLK */
264 	PINCTRL_PIN(31, "PA31"), /* GPIO_A31_VDI_MCLK */
265 };
266 
267 static const char * const eq5p_eyeq6lplus_gpio_groups[] = {
268 	/* Bank A */
269 	"PA0",  "PA1",  "PA2",  "PA3",  "PA4",  "PA5",  "PA6",  "PA7",
270 	"PA8",  "PA9",  "PA10", "PA11", "PA12", "PA13", "PA14", "PA15",
271 	"PA16", "PA17", "PA18", "PA19", "PA20", "PA21", "PA22", "PA23",
272 	"PA24", "PA25", "PA26", "PA27", "PA28", "PA29", "PA30", "PA31",
273 };
274 
275 /* Groups of functions on bank A */
276 static const char * const eq5p_eyeq6lplus_timer0_groups[] = { "PA0", "PA1" };
277 static const char * const eq5p_eyeq6lplus_timer1_groups[] = { "PA2", "PA3" };
278 static const char * const eq5p_eyeq6lplus_uart_ssi_groups[] = { "PA4", "PA5" };
279 static const char * const eq5p_eyeq6lplus_spi0_groups[] = { "PA6", "PA7", "PA8", "PA9", "PA10" };
280 static const char * const eq5p_eyeq6lplus_uart0_groups[] = { "PA11", "PA12" };
281 static const char * const eq5p_eyeq6lplus_timer2_groups[] = { "PA13", "PA14" };
282 static const char * const eq5p_eyeq6lplus_timer3_groups[] = { "PA15", "PA16" };
283 static const char * const eq5p_eyeq6lplus_timer_ext0_groups[] = { "PA17", "PA18", "PA19", "PA20" };
284 static const char * const eq5p_eyeq6lplus_spi1_groups[] = {
285 	"PA21", "PA22", "PA23", "PA24", "PA25"
286 };
287 static const char * const eq5p_eyeq6lplus_timer_ext1_groups[] = { "PA26", "PA27", "PA28", "PA29" };
288 static const char * const eq5p_eyeq6lplus_ext_ref_clk_groups[] = { "PA30" };
289 static const char * const eq5p_eyeq6lplus_mipi_ref_clk_groups[] = { "PA31" };
290 
291 static const struct pinfunction eq5p_eyeq6lplus_functions[] = {
292 	/* gpios function */
293 	EQ5P_PINFUNCTION("gpio", eq5p_eyeq6lplus_gpio_groups),
294 
295 	/* Bank A alternate functions */
296 	EQ5P_PINFUNCTION("timer0", eq5p_eyeq6lplus_timer0_groups),
297 	EQ5P_PINFUNCTION("timer1", eq5p_eyeq6lplus_timer1_groups),
298 	EQ5P_PINFUNCTION("uart_ssi", eq5p_eyeq6lplus_uart_ssi_groups),
299 	EQ5P_PINFUNCTION("spi0", eq5p_eyeq6lplus_spi0_groups),
300 	EQ5P_PINFUNCTION("uart0", eq5p_eyeq6lplus_uart0_groups),
301 	EQ5P_PINFUNCTION("timer2", eq5p_eyeq6lplus_timer2_groups),
302 	EQ5P_PINFUNCTION("timer3", eq5p_eyeq6lplus_timer3_groups),
303 	EQ5P_PINFUNCTION("timer_ext0", eq5p_eyeq6lplus_timer_ext0_groups),
304 	EQ5P_PINFUNCTION("spi1", eq5p_eyeq6lplus_spi1_groups),
305 	EQ5P_PINFUNCTION("timer_ext1", eq5p_eyeq6lplus_timer_ext1_groups),
306 	EQ5P_PINFUNCTION("ext_ref_clk", eq5p_eyeq6lplus_ext_ref_clk_groups),
307 	EQ5P_PINFUNCTION("mipi_ref_clk", eq5p_eyeq6lplus_mipi_ref_clk_groups),
308 };
309 
310 static const struct eq5p_bank eq5p_eyeq6lplus_banks[] = {
311 	{
312 		.npins = ARRAY_SIZE(eq5p_eyeq6lplus_pins),
313 		.regs = {0x0C0, 0x0C4, 0x0D0, 0x0D4, 0x0B0},
314 	},
315 };
316 
317 static const struct eq5p_match_data eq5p_eyeq6lplus_data = {
318 	.npins = ARRAY_SIZE(eq5p_eyeq6lplus_pins),
319 	.nfunctions = ARRAY_SIZE(eq5p_eyeq6lplus_functions),
320 	.nbanks = ARRAY_SIZE(eq5p_eyeq6lplus_banks),
321 	.pins = eq5p_eyeq6lplus_pins,
322 	.functions = eq5p_eyeq6lplus_functions,
323 	.banks = eq5p_eyeq6lplus_banks,
324 };
325 
326 static void eq5p_update_bits(const struct eq5p_pinctrl *pctrl,
327 			     const struct eq5p_bank *bank,
328 			     enum eq5p_regs reg, u32 mask, u32 val)
329 {
330 	void __iomem *ptr = pctrl->base + bank->regs[reg];
331 
332 	writel((readl(ptr) & ~mask) | (val & mask), ptr);
333 }
334 
335 static bool eq5p_test_bit(const struct eq5p_pinctrl *pctrl,
336 			  const struct eq5p_bank *bank,
337 			  enum eq5p_regs reg, int offset)
338 {
339 	u32 val = readl(pctrl->base + bank->regs[reg]);
340 
341 	if (WARN_ON(offset > 31))
342 		return false;
343 
344 	return (val & BIT(offset)) != 0;
345 }
346 
347 static int eq5p_pin_to_bank_offset(const struct eq5p_pinctrl *pctrl, unsigned int pin,
348 				   const struct eq5p_bank **bank, unsigned int *offset)
349 {
350 	for (unsigned int i = 0; i < pctrl->data->nbanks; i++) {
351 		const struct eq5p_bank *_bank = &pctrl->data->banks[i];
352 		unsigned int npins = _bank->npins;
353 
354 		if (pin < npins) {
355 			*bank = _bank;
356 			*offset = pin;
357 			return 0;
358 		}
359 		pin -= npins;
360 	}
361 
362 	return -EINVAL;
363 }
364 
365 static int eq5p_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
366 {
367 	struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
368 
369 	return pctrl->data->npins;
370 }
371 
372 static const char *eq5p_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
373 					       unsigned int selector)
374 {
375 	return pctldev->desc->pins[selector].name;
376 }
377 
378 static int eq5p_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
379 				       unsigned int selector,
380 				       const unsigned int **pins,
381 				       unsigned int *num_pins)
382 {
383 	*pins = &pctldev->desc->pins[selector].number;
384 	*num_pins = 1;
385 	return 0;
386 }
387 
388 static int eq5p_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
389 			    unsigned long *config)
390 {
391 	enum pin_config_param param = pinconf_to_config_param(*config);
392 	struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
393 	const struct eq5p_bank *bank;
394 	unsigned int offset;
395 	u32 val_ds, arg;
396 	bool pd, pu;
397 	int ret;
398 
399 	ret = eq5p_pin_to_bank_offset(pctrl, pin, &bank, &offset);
400 	if (ret)
401 		return ret;
402 
403 	pd = eq5p_test_bit(pctrl, bank, EQ5P_PD, offset);
404 	pu = eq5p_test_bit(pctrl, bank, EQ5P_PU, offset);
405 
406 	switch (param) {
407 	case PIN_CONFIG_BIAS_DISABLE:
408 		arg = !(pd || pu);
409 		break;
410 	case PIN_CONFIG_BIAS_PULL_DOWN:
411 		arg = pd;
412 		break;
413 	case PIN_CONFIG_BIAS_PULL_UP:
414 		arg = pu;
415 		break;
416 	case PIN_CONFIG_DRIVE_STRENGTH:
417 		offset *= 2; /* two bits per pin */
418 		if (offset >= 32) {
419 			val_ds = readl(pctrl->base + bank->regs[EQ5P_DS_HIGH]);
420 			offset -= 32;
421 		} else {
422 			val_ds = readl(pctrl->base + bank->regs[EQ5P_DS_LOW]);
423 		}
424 		arg = (val_ds >> offset) & EQ5P_DS_MASK;
425 		break;
426 	default:
427 		return -ENOTSUPP;
428 	}
429 
430 	*config = pinconf_to_config_packed(param, arg);
431 	return 0;
432 }
433 
434 static void eq5p_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
435 				      struct seq_file *s,
436 				      unsigned int pin)
437 {
438 	struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
439 	const char *pin_name = pctrl->desc.pins[pin].name;
440 	const struct eq5p_bank *bank;
441 	const char *func_name, *bias;
442 	unsigned long ds_config;
443 	unsigned int offset;
444 	u32 drive_strength;
445 	bool pd, pu;
446 	int i, j;
447 
448 	if (eq5p_pin_to_bank_offset(pctrl, pin, &bank, &offset)) {
449 		seq_puts(s, "unknown pin");
450 		return;
451 	}
452 
453 	/*
454 	 * First, let's get the function name. All pins have only two functions:
455 	 * GPIO (IOCR == 0) and something else (IOCR == 1).
456 	 */
457 	if (eq5p_test_bit(pctrl, bank, EQ5P_IOCR, offset)) {
458 		func_name = NULL;
459 		for (i = 0; i < pctrl->data->nfunctions; i++) {
460 			if (i == EQ5P_GPIO_FUNC_SELECTOR)
461 				continue;
462 
463 			for (j = 0; j < pctrl->data->functions[i].ngroups; j++) {
464 				/* Groups and pins are the same thing for us. */
465 				const char *x = pctrl->data->functions[i].groups[j];
466 
467 				if (strcmp(x, pin_name) == 0) {
468 					func_name = pctrl->data->functions[i].name;
469 					break;
470 				}
471 			}
472 
473 			if (func_name)
474 				break;
475 		}
476 
477 		/*
478 		 * We have not found the function attached to this pin, this
479 		 * should never occur as all pins have exactly two functions.
480 		 */
481 		if (!func_name)
482 			func_name = "unknown";
483 	} else {
484 		func_name = pctrl->data->functions[EQ5P_GPIO_FUNC_SELECTOR].name;
485 	}
486 
487 	/* Second, we retrieve the bias. */
488 	pd = eq5p_test_bit(pctrl, bank, EQ5P_PD, offset);
489 	pu = eq5p_test_bit(pctrl, bank, EQ5P_PU, offset);
490 	if (pd && pu)
491 		bias = "both";
492 	else if (pd && !pu)
493 		bias = "pulldown";
494 	else if (!pd && pu)
495 		bias = "pullup";
496 	else
497 		bias = "none";
498 
499 	/* Third, we get the drive strength. */
500 	ds_config = pinconf_to_config_packed(PIN_CONFIG_DRIVE_STRENGTH, 0);
501 	eq5p_pinconf_get(pctldev, pin, &ds_config);
502 	drive_strength = pinconf_to_config_argument(ds_config);
503 
504 	seq_printf(s, "function=%s bias=%s drive_strength=%d",
505 		   func_name, bias, drive_strength);
506 }
507 
508 static const struct pinctrl_ops eq5p_pinctrl_ops = {
509 	.get_groups_count	= eq5p_pinctrl_get_groups_count,
510 	.get_group_name		= eq5p_pinctrl_get_group_name,
511 	.get_group_pins		= eq5p_pinctrl_get_group_pins,
512 	.pin_dbg_show		= eq5p_pinctrl_pin_dbg_show,
513 	.dt_node_to_map		= pinconf_generic_dt_node_to_map_pin,
514 	.dt_free_map		= pinctrl_utils_free_map,
515 };
516 
517 static int eq5p_pinmux_get_functions_count(struct pinctrl_dev *pctldev)
518 {
519 	struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
520 
521 	return pctrl->data->nfunctions;
522 }
523 
524 static const char *eq5p_pinmux_get_function_name(struct pinctrl_dev *pctldev,
525 						 unsigned int selector)
526 {
527 	struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
528 
529 	return pctrl->data->functions[selector].name;
530 }
531 
532 static int eq5p_pinmux_get_function_groups(struct pinctrl_dev *pctldev,
533 					   unsigned int selector,
534 					   const char * const **groups,
535 					   unsigned int *num_groups)
536 {
537 	struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
538 
539 	*groups = pctrl->data->functions[selector].groups;
540 	*num_groups = pctrl->data->functions[selector].ngroups;
541 	return 0;
542 }
543 
544 static int eq5p_pinmux_set_mux(struct pinctrl_dev *pctldev,
545 			       unsigned int func_selector, unsigned int pin)
546 {
547 	struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
548 	const char *func_name = pctrl->data->functions[func_selector].name;
549 	const char *group_name = pctldev->desc->pins[pin].name;
550 	bool is_gpio = func_selector == EQ5P_GPIO_FUNC_SELECTOR;
551 	const struct eq5p_bank *bank;
552 	unsigned int offset;
553 	u32 mask, val;
554 	int ret;
555 
556 	ret = eq5p_pin_to_bank_offset(pctrl, pin, &bank, &offset);
557 	if (ret)
558 		return ret;
559 
560 	dev_dbg(pctldev->dev, "func=%s group=%s\n", func_name, group_name);
561 
562 	mask = BIT(offset);
563 	val = is_gpio ? 0 : mask;
564 	eq5p_update_bits(pctrl, bank, EQ5P_IOCR, mask, val);
565 	return 0;
566 }
567 
568 static int eq5p_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
569 					   struct pinctrl_gpio_range *range,
570 					   unsigned int pin)
571 {
572 	/* Pin numbers and group selectors are the same thing in our case. */
573 	return eq5p_pinmux_set_mux(pctldev, EQ5P_GPIO_FUNC_SELECTOR, pin);
574 }
575 
576 static const struct pinmux_ops eq5p_pinmux_ops = {
577 	.get_functions_count	= eq5p_pinmux_get_functions_count,
578 	.get_function_name	= eq5p_pinmux_get_function_name,
579 	.get_function_groups	= eq5p_pinmux_get_function_groups,
580 	.set_mux		= eq5p_pinmux_set_mux,
581 	.gpio_request_enable	= eq5p_pinmux_gpio_request_enable,
582 	.strict			= true,
583 };
584 
585 static int eq5p_pinconf_set_drive_strength(struct pinctrl_dev *pctldev,
586 					   unsigned int pin, u32 arg)
587 {
588 	struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
589 	const struct eq5p_bank *bank;
590 	unsigned int offset;
591 	unsigned int reg;
592 	u32 mask, val;
593 	int ret;
594 
595 	ret = eq5p_pin_to_bank_offset(pctrl, pin, &bank, &offset);
596 	if (ret)
597 		return ret;
598 
599 	if (arg & ~EQ5P_DS_MASK) {
600 		dev_err(pctldev->dev, "Unsupported drive strength: %u\n", arg);
601 		return -EINVAL;
602 	}
603 
604 	offset *= 2; /* two bits per pin */
605 
606 	if (offset >= 32) {
607 		reg = EQ5P_DS_HIGH;
608 		offset -= 32;
609 	} else {
610 		reg = EQ5P_DS_LOW;
611 	}
612 
613 	mask = EQ5P_DS_MASK << offset;
614 	val = arg << offset;
615 	eq5p_update_bits(pctrl, bank, reg, mask, val);
616 	return 0;
617 }
618 
619 static int eq5p_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
620 			    unsigned long *configs, unsigned int num_configs)
621 {
622 	struct eq5p_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
623 	const char *pin_name = pctldev->desc->pins[pin].name;
624 	struct device *dev = pctldev->dev;
625 	const struct eq5p_bank *bank;
626 	unsigned int offset;
627 	unsigned int i;
628 	u32 val;
629 	int ret;
630 
631 	ret = eq5p_pin_to_bank_offset(pctrl, pin, &bank, &offset);
632 	if (ret)
633 		return ret;
634 
635 	val = BIT(offset);
636 	for (i = 0; i < num_configs; i++) {
637 		enum pin_config_param param = pinconf_to_config_param(configs[i]);
638 		u32 arg = pinconf_to_config_argument(configs[i]);
639 
640 		switch (param) {
641 		case PIN_CONFIG_BIAS_DISABLE:
642 			dev_dbg(dev, "pin=%s bias_disable\n", pin_name);
643 
644 			eq5p_update_bits(pctrl, bank, EQ5P_PD, val, 0);
645 			eq5p_update_bits(pctrl, bank, EQ5P_PU, val, 0);
646 			break;
647 
648 		case PIN_CONFIG_BIAS_PULL_DOWN:
649 			dev_dbg(dev, "pin=%s bias_pull_down arg=%u\n",
650 				pin_name, arg);
651 
652 			if (arg == 0) /* cannot connect to GND */
653 				return -ENOTSUPP;
654 
655 			eq5p_update_bits(pctrl, bank, EQ5P_PD, val, val);
656 			eq5p_update_bits(pctrl, bank, EQ5P_PU, val, 0);
657 			break;
658 
659 		case PIN_CONFIG_BIAS_PULL_UP:
660 			dev_dbg(dev, "pin=%s bias_pull_up arg=%u\n",
661 				pin_name, arg);
662 
663 			if (arg == 0) /* cannot connect to VDD */
664 				return -ENOTSUPP;
665 
666 			eq5p_update_bits(pctrl, bank, EQ5P_PD, val, 0);
667 			eq5p_update_bits(pctrl, bank, EQ5P_PU, val, val);
668 			break;
669 
670 		case PIN_CONFIG_DRIVE_STRENGTH:
671 			dev_dbg(dev, "pin=%s drive_strength arg=%u\n",
672 				pin_name, arg);
673 
674 			eq5p_pinconf_set_drive_strength(pctldev, pin, arg);
675 			break;
676 
677 		default:
678 			dev_err(dev, "Unsupported pinconf %u\n", param);
679 			return -ENOTSUPP;
680 		}
681 	}
682 
683 	return 0;
684 }
685 
686 static const struct pinconf_ops eq5p_pinconf_ops = {
687 	.is_generic = true,
688 	.pin_config_get = eq5p_pinconf_get,
689 	.pin_config_set = eq5p_pinconf_set,
690 	/* Pins and groups are equivalent in this driver. */
691 	.pin_config_group_get = eq5p_pinconf_get,
692 	.pin_config_group_set = eq5p_pinconf_set,
693 };
694 
695 static int eq5p_probe(struct auxiliary_device *adev,
696 		      const struct auxiliary_device_id *id)
697 {
698 	const struct of_device_id *match;
699 	struct device *dev = &adev->dev;
700 	struct pinctrl_dev *pctldev;
701 	struct eq5p_pinctrl *pctrl;
702 	int ret;
703 
704 	/* Get match data based on parent OF node set in clk-eyeq */
705 	match = of_match_node(dev->driver->of_match_table, dev->of_node);
706 	if (!match || !match->data)
707 		return -ENODEV;
708 
709 	pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL);
710 	if (!pctrl)
711 		return -ENOMEM;
712 
713 	pctrl->base = (void __iomem *)dev_get_platdata(dev);
714 	pctrl->data = match->data;
715 	pctrl->desc.name = dev_name(dev);
716 	pctrl->desc.pins = pctrl->data->pins;
717 	pctrl->desc.npins = pctrl->data->npins;
718 	pctrl->desc.pctlops = &eq5p_pinctrl_ops;
719 	pctrl->desc.pmxops = &eq5p_pinmux_ops;
720 	pctrl->desc.confops = &eq5p_pinconf_ops;
721 	pctrl->desc.owner = THIS_MODULE;
722 
723 	ret = devm_pinctrl_register_and_init(dev, &pctrl->desc, pctrl, &pctldev);
724 	if (ret)
725 		return dev_err_probe(dev, ret, "failed registering pinctrl device\n");
726 
727 	ret = pinctrl_enable(pctldev);
728 	if (ret)
729 		return dev_err_probe(dev, ret, "failed enabling pinctrl device\n");
730 
731 	return 0;
732 }
733 
734 static const struct of_device_id eq5p_match_table[] = {
735 	{ .compatible = "mobileye,eyeq5-olb", .data = &eq5p_eyeq5_data },
736 	{ .compatible = "mobileye,eyeq6lplus-olb", .data = &eq5p_eyeq6lplus_data },
737 	{}
738 };
739 MODULE_DEVICE_TABLE(of, eq5p_match_table);
740 
741 static const struct auxiliary_device_id eq5p_id_table[] = {
742 	{ .name = "clk_eyeq.pinctrl" },
743 	{}
744 };
745 MODULE_DEVICE_TABLE(auxiliary, eq5p_id_table);
746 
747 static struct auxiliary_driver eq5p_driver = {
748 	.probe = eq5p_probe,
749 	.id_table = eq5p_id_table,
750 	.driver = {
751 		.of_match_table = eq5p_match_table,
752 	}
753 };
754 module_auxiliary_driver(eq5p_driver);
755