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