Commit | Line | Data |
---|---|---|
ffd4e739 LS |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* Copyright (C) 2020 Intel Corporation */ | |
3 | ||
4 | #include <linux/bitfield.h> | |
5 | #include <linux/bitops.h> | |
6 | #include <linux/gpio/driver.h> | |
7 | #include <linux/interrupt.h> | |
8 | #include <linux/io.h> | |
9 | #include <linux/module.h> | |
10 | ||
11 | #include <linux/pinctrl/pinconf.h> | |
12 | #include <linux/pinctrl/pinconf-generic.h> | |
13 | #include <linux/pinctrl/pinctrl.h> | |
14 | #include <linux/pinctrl/pinmux.h> | |
15 | ||
16 | #include <linux/platform_device.h> | |
17 | ||
18 | #include "core.h" | |
19 | #include "pinmux.h" | |
20 | ||
21 | /* GPIO data registers' offsets */ | |
22 | #define KEEMBAY_GPIO_DATA_OUT 0x000 | |
23 | #define KEEMBAY_GPIO_DATA_IN 0x020 | |
24 | #define KEEMBAY_GPIO_DATA_IN_RAW 0x040 | |
25 | #define KEEMBAY_GPIO_DATA_HIGH 0x060 | |
26 | #define KEEMBAY_GPIO_DATA_LOW 0x080 | |
27 | ||
28 | /* GPIO Interrupt and mode registers' offsets */ | |
29 | #define KEEMBAY_GPIO_INT_CFG 0x000 | |
30 | #define KEEMBAY_GPIO_MODE 0x070 | |
31 | ||
32 | /* GPIO mode register bit fields */ | |
33 | #define KEEMBAY_GPIO_MODE_PULLUP_MASK GENMASK(13, 12) | |
34 | #define KEEMBAY_GPIO_MODE_DRIVE_MASK GENMASK(8, 7) | |
35 | #define KEEMBAY_GPIO_MODE_INV_MASK GENMASK(5, 4) | |
36 | #define KEEMBAY_GPIO_MODE_SELECT_MASK GENMASK(2, 0) | |
37 | #define KEEMBAY_GPIO_MODE_DIR_OVR BIT(15) | |
38 | #define KEEMBAY_GPIO_MODE_REN BIT(11) | |
39 | #define KEEMBAY_GPIO_MODE_SCHMITT_EN BIT(10) | |
40 | #define KEEMBAY_GPIO_MODE_SLEW_RATE BIT(9) | |
41 | #define KEEMBAY_GPIO_IRQ_ENABLE BIT(7) | |
42 | #define KEEMBAY_GPIO_MODE_DIR BIT(3) | |
43 | #define KEEMBAY_GPIO_MODE_DEFAULT 0x7 | |
44 | #define KEEMBAY_GPIO_MODE_INV_VAL 0x3 | |
45 | ||
46 | #define KEEMBAY_GPIO_DISABLE 0 | |
47 | #define KEEMBAY_GPIO_PULL_UP 1 | |
48 | #define KEEMBAY_GPIO_PULL_DOWN 2 | |
49 | #define KEEMBAY_GPIO_BUS_HOLD 3 | |
50 | #define KEEMBAY_GPIO_NUM_IRQ 8 | |
51 | #define KEEMBAY_GPIO_MAX_PER_IRQ 4 | |
52 | #define KEEMBAY_GPIO_MAX_PER_REG 32 | |
53 | #define KEEMBAY_GPIO_MIN_STRENGTH 2 | |
54 | #define KEEMBAY_GPIO_MAX_STRENGTH 12 | |
55 | #define KEEMBAY_GPIO_SENSE_LOW (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING) | |
56 | ||
57 | /* GPIO reg address calculation */ | |
58 | #define KEEMBAY_GPIO_REG_OFFSET(pin) ((pin) * 4) | |
59 | ||
60 | /** | |
61 | * struct keembay_mux_desc - Mux properties of each GPIO pin | |
62 | * @mode: Pin mode when operating in this function | |
63 | * @name: Pin function name | |
64 | */ | |
65 | struct keembay_mux_desc { | |
66 | u8 mode; | |
67 | const char *name; | |
68 | }; | |
69 | ||
70 | #define KEEMBAY_PIN_DESC(pin_number, pin_name, ...) { \ | |
71 | .number = pin_number, \ | |
72 | .name = pin_name, \ | |
73 | .drv_data = &(struct keembay_mux_desc[]) { \ | |
74 | __VA_ARGS__, { } }, \ | |
75 | } \ | |
76 | ||
77 | #define KEEMBAY_MUX(pin_mode, pin_function) { \ | |
78 | .mode = pin_mode, \ | |
79 | .name = pin_function, \ | |
80 | } \ | |
81 | ||
82 | /** | |
83 | * struct keembay_gpio_irq - Config of each GPIO Interrupt sources | |
84 | * @source: Interrupt source number (0 - 7) | |
85 | * @line: Actual Interrupt line number | |
86 | * @pins: Array of GPIO pins using this Interrupt line | |
87 | * @trigger: Interrupt trigger type for this line | |
88 | * @num_share: Number of pins currently using this Interrupt line | |
89 | */ | |
90 | struct keembay_gpio_irq { | |
91 | unsigned int source; | |
92 | unsigned int line; | |
93 | unsigned int pins[KEEMBAY_GPIO_MAX_PER_IRQ]; | |
94 | unsigned int trigger; | |
95 | unsigned int num_share; | |
96 | }; | |
97 | ||
98 | /** | |
99 | * struct keembay_pinctrl - Intel Keembay pinctrl structure | |
100 | * @pctrl: Pointer to the pin controller device | |
101 | * @base0: First register base address | |
102 | * @base1: Second register base address | |
103 | * @dev: Pointer to the device structure | |
104 | * @chip: GPIO chip used by this pin controller | |
105 | * @soc: Pin control configuration data based on SoC | |
106 | * @lock: Spinlock to protect various gpio config register access | |
107 | * @ngroups: Number of pin groups available | |
108 | * @nfuncs: Number of pin functions available | |
109 | * @npins: Number of GPIO pins available | |
110 | * @irq: Store Interrupt source | |
111 | * @max_gpios_level_type: Store max level trigger type | |
112 | * @max_gpios_edge_type: Store max edge trigger type | |
113 | */ | |
114 | struct keembay_pinctrl { | |
115 | struct pinctrl_dev *pctrl; | |
116 | void __iomem *base0; | |
117 | void __iomem *base1; | |
118 | struct device *dev; | |
119 | struct gpio_chip chip; | |
120 | const struct keembay_pin_soc *soc; | |
121 | raw_spinlock_t lock; | |
122 | unsigned int ngroups; | |
123 | unsigned int nfuncs; | |
124 | unsigned int npins; | |
125 | struct keembay_gpio_irq irq[KEEMBAY_GPIO_NUM_IRQ]; | |
126 | int max_gpios_level_type; | |
127 | int max_gpios_edge_type; | |
128 | }; | |
129 | ||
130 | /** | |
131 | * struct keembay_pin_soc - Pin control config data based on SoC | |
132 | * @pins: Pin description structure | |
133 | */ | |
134 | struct keembay_pin_soc { | |
135 | const struct pinctrl_pin_desc *pins; | |
136 | }; | |
137 | ||
138 | static const struct pinctrl_pin_desc keembay_pins[] = { | |
139 | KEEMBAY_PIN_DESC(0, "GPIO0", | |
140 | KEEMBAY_MUX(0x0, "I2S0_M0"), | |
141 | KEEMBAY_MUX(0x1, "SD0_M1"), | |
142 | KEEMBAY_MUX(0x2, "SLVDS0_M2"), | |
143 | KEEMBAY_MUX(0x3, "I2C0_M3"), | |
144 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
145 | KEEMBAY_MUX(0x5, "ETH_M5"), | |
146 | KEEMBAY_MUX(0x6, "LCD_M6"), | |
147 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
148 | KEEMBAY_PIN_DESC(1, "GPIO1", | |
149 | KEEMBAY_MUX(0x0, "I2S0_M0"), | |
150 | KEEMBAY_MUX(0x1, "SD0_M1"), | |
151 | KEEMBAY_MUX(0x2, "SLVDS0_M2"), | |
152 | KEEMBAY_MUX(0x3, "I2C0_M3"), | |
153 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
154 | KEEMBAY_MUX(0x5, "ETH_M5"), | |
155 | KEEMBAY_MUX(0x6, "LCD_M6"), | |
156 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
157 | KEEMBAY_PIN_DESC(2, "GPIO2", | |
158 | KEEMBAY_MUX(0x0, "I2S0_M0"), | |
159 | KEEMBAY_MUX(0x1, "I2S0_M1"), | |
160 | KEEMBAY_MUX(0x2, "SLVDS0_M2"), | |
161 | KEEMBAY_MUX(0x3, "I2C1_M3"), | |
162 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
163 | KEEMBAY_MUX(0x5, "ETH_M5"), | |
164 | KEEMBAY_MUX(0x6, "LCD_M6"), | |
165 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
166 | KEEMBAY_PIN_DESC(3, "GPIO3", | |
167 | KEEMBAY_MUX(0x0, "I2S0_M0"), | |
168 | KEEMBAY_MUX(0x1, "I2S0_M1"), | |
169 | KEEMBAY_MUX(0x2, "SLVDS0_M2"), | |
170 | KEEMBAY_MUX(0x3, "I2C1_M3"), | |
171 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
172 | KEEMBAY_MUX(0x5, "ETH_M5"), | |
173 | KEEMBAY_MUX(0x6, "LCD_M6"), | |
174 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
175 | KEEMBAY_PIN_DESC(4, "GPIO4", | |
176 | KEEMBAY_MUX(0x0, "I2S0_M0"), | |
177 | KEEMBAY_MUX(0x1, "I2S0_M1"), | |
178 | KEEMBAY_MUX(0x2, "SLVDS0_M2"), | |
179 | KEEMBAY_MUX(0x3, "I2C2_M3"), | |
180 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
181 | KEEMBAY_MUX(0x5, "ETH_M5"), | |
182 | KEEMBAY_MUX(0x6, "LCD_M6"), | |
183 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
184 | KEEMBAY_PIN_DESC(5, "GPIO5", | |
185 | KEEMBAY_MUX(0x0, "I2S0_M0"), | |
186 | KEEMBAY_MUX(0x1, "I2S0_M1"), | |
187 | KEEMBAY_MUX(0x2, "SLVDS0_M2"), | |
188 | KEEMBAY_MUX(0x3, "I2C2_M3"), | |
189 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
190 | KEEMBAY_MUX(0x5, "ETH_M5"), | |
191 | KEEMBAY_MUX(0x6, "LCD_M6"), | |
192 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
193 | KEEMBAY_PIN_DESC(6, "GPIO6", | |
194 | KEEMBAY_MUX(0x0, "I2S1_M0"), | |
195 | KEEMBAY_MUX(0x1, "SD0_M1"), | |
196 | KEEMBAY_MUX(0x2, "SLVDS0_M2"), | |
197 | KEEMBAY_MUX(0x3, "I2C3_M3"), | |
198 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
199 | KEEMBAY_MUX(0x5, "ETH_M5"), | |
200 | KEEMBAY_MUX(0x6, "LCD_M6"), | |
201 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
202 | KEEMBAY_PIN_DESC(7, "GPIO7", | |
203 | KEEMBAY_MUX(0x0, "I2S1_M0"), | |
204 | KEEMBAY_MUX(0x1, "SD0_M1"), | |
205 | KEEMBAY_MUX(0x2, "SLVDS0_M2"), | |
206 | KEEMBAY_MUX(0x3, "I2C3_M3"), | |
207 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
208 | KEEMBAY_MUX(0x5, "ETH_M5"), | |
209 | KEEMBAY_MUX(0x6, "LCD_M6"), | |
210 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
211 | KEEMBAY_PIN_DESC(8, "GPIO8", | |
212 | KEEMBAY_MUX(0x0, "I2S1_M0"), | |
213 | KEEMBAY_MUX(0x1, "I2S1_M1"), | |
214 | KEEMBAY_MUX(0x2, "SLVDS0_M2"), | |
215 | KEEMBAY_MUX(0x3, "UART0_M3"), | |
216 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
217 | KEEMBAY_MUX(0x5, "ETH_M5"), | |
218 | KEEMBAY_MUX(0x6, "LCD_M6"), | |
219 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
220 | KEEMBAY_PIN_DESC(9, "GPIO9", | |
221 | KEEMBAY_MUX(0x0, "I2S1_M0"), | |
222 | KEEMBAY_MUX(0x1, "I2S1_M1"), | |
223 | KEEMBAY_MUX(0x2, "PWM_M2"), | |
224 | KEEMBAY_MUX(0x3, "UART0_M3"), | |
225 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
226 | KEEMBAY_MUX(0x5, "ETH_M5"), | |
227 | KEEMBAY_MUX(0x6, "LCD_M6"), | |
228 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
229 | KEEMBAY_PIN_DESC(10, "GPIO10", | |
230 | KEEMBAY_MUX(0x0, "I2S2_M0"), | |
231 | KEEMBAY_MUX(0x1, "SD0_M1"), | |
232 | KEEMBAY_MUX(0x2, "PWM_M2"), | |
233 | KEEMBAY_MUX(0x3, "UART0_M3"), | |
234 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
235 | KEEMBAY_MUX(0x5, "ETH_M5"), | |
236 | KEEMBAY_MUX(0x6, "LCD_M6"), | |
237 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
238 | KEEMBAY_PIN_DESC(11, "GPIO11", | |
239 | KEEMBAY_MUX(0x0, "I2S2_M0"), | |
240 | KEEMBAY_MUX(0x1, "SD0_M1"), | |
241 | KEEMBAY_MUX(0x2, "PWM_M2"), | |
242 | KEEMBAY_MUX(0x3, "UART0_M3"), | |
243 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
244 | KEEMBAY_MUX(0x5, "ETH_M5"), | |
245 | KEEMBAY_MUX(0x6, "LCD_M6"), | |
246 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
247 | KEEMBAY_PIN_DESC(12, "GPIO12", | |
248 | KEEMBAY_MUX(0x0, "I2S2_M0"), | |
249 | KEEMBAY_MUX(0x1, "I2S2_M1"), | |
250 | KEEMBAY_MUX(0x2, "PWM_M2"), | |
251 | KEEMBAY_MUX(0x3, "SPI0_M3"), | |
252 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
253 | KEEMBAY_MUX(0x5, "ETH_M5"), | |
254 | KEEMBAY_MUX(0x6, "LCD_M6"), | |
255 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
256 | KEEMBAY_PIN_DESC(13, "GPIO13", | |
257 | KEEMBAY_MUX(0x0, "I2S2_M0"), | |
258 | KEEMBAY_MUX(0x1, "I2S2_M1"), | |
259 | KEEMBAY_MUX(0x2, "PWM_M2"), | |
260 | KEEMBAY_MUX(0x3, "SPI0_M3"), | |
261 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
262 | KEEMBAY_MUX(0x5, "ETH_M5"), | |
263 | KEEMBAY_MUX(0x6, "LCD_M6"), | |
264 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
265 | KEEMBAY_PIN_DESC(14, "GPIO14", | |
266 | KEEMBAY_MUX(0x0, "UART0_M0"), | |
267 | KEEMBAY_MUX(0x1, "I2S3_M1"), | |
268 | KEEMBAY_MUX(0x2, "PWM_M2"), | |
269 | KEEMBAY_MUX(0x3, "SD1_M3"), | |
270 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
271 | KEEMBAY_MUX(0x5, "ETH_M5"), | |
272 | KEEMBAY_MUX(0x6, "LCD_M6"), | |
273 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
274 | KEEMBAY_PIN_DESC(15, "GPIO15", | |
275 | KEEMBAY_MUX(0x0, "UART0_M0"), | |
276 | KEEMBAY_MUX(0x1, "I2S3_M1"), | |
277 | KEEMBAY_MUX(0x2, "UART0_M2"), | |
278 | KEEMBAY_MUX(0x3, "SD1_M3"), | |
279 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
280 | KEEMBAY_MUX(0x5, "SPI1_M5"), | |
281 | KEEMBAY_MUX(0x6, "LCD_M6"), | |
282 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
283 | KEEMBAY_PIN_DESC(16, "GPIO16", | |
284 | KEEMBAY_MUX(0x0, "UART0_M0"), | |
285 | KEEMBAY_MUX(0x1, "I2S3_M1"), | |
286 | KEEMBAY_MUX(0x2, "UART0_M2"), | |
287 | KEEMBAY_MUX(0x3, "SD1_M3"), | |
288 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
289 | KEEMBAY_MUX(0x5, "SPI1_M5"), | |
290 | KEEMBAY_MUX(0x6, "LCD_M6"), | |
291 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
292 | KEEMBAY_PIN_DESC(17, "GPIO17", | |
293 | KEEMBAY_MUX(0x0, "UART0_M0"), | |
294 | KEEMBAY_MUX(0x1, "I2S3_M1"), | |
295 | KEEMBAY_MUX(0x2, "I2S3_M2"), | |
296 | KEEMBAY_MUX(0x3, "SD1_M3"), | |
297 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
298 | KEEMBAY_MUX(0x5, "SPI1_M5"), | |
299 | KEEMBAY_MUX(0x6, "LCD_M6"), | |
300 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
301 | KEEMBAY_PIN_DESC(18, "GPIO18", | |
302 | KEEMBAY_MUX(0x0, "UART1_M0"), | |
303 | KEEMBAY_MUX(0x1, "SPI0_M1"), | |
304 | KEEMBAY_MUX(0x2, "I2S3_M2"), | |
305 | KEEMBAY_MUX(0x3, "SD1_M3"), | |
306 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
307 | KEEMBAY_MUX(0x5, "SPI1_M5"), | |
308 | KEEMBAY_MUX(0x6, "LCD_M6"), | |
309 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
310 | KEEMBAY_PIN_DESC(19, "GPIO19", | |
311 | KEEMBAY_MUX(0x0, "UART1_M0"), | |
312 | KEEMBAY_MUX(0x1, "LCD_M1"), | |
313 | KEEMBAY_MUX(0x2, "DEBUG_M2"), | |
314 | KEEMBAY_MUX(0x3, "SD1_M3"), | |
315 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
316 | KEEMBAY_MUX(0x5, "SPI1_M5"), | |
317 | KEEMBAY_MUX(0x6, "LCD_M6"), | |
318 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
319 | KEEMBAY_PIN_DESC(20, "GPIO20", | |
320 | KEEMBAY_MUX(0x0, "UART1_M0"), | |
321 | KEEMBAY_MUX(0x1, "LCD_M1"), | |
322 | KEEMBAY_MUX(0x2, "DEBUG_M2"), | |
323 | KEEMBAY_MUX(0x3, "CPR_M3"), | |
324 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
325 | KEEMBAY_MUX(0x5, "SPI1_M5"), | |
326 | KEEMBAY_MUX(0x6, "SLVDS0_M6"), | |
327 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
328 | KEEMBAY_PIN_DESC(21, "GPIO21", | |
329 | KEEMBAY_MUX(0x0, "UART1_M0"), | |
330 | KEEMBAY_MUX(0x1, "LCD_M1"), | |
331 | KEEMBAY_MUX(0x2, "DEBUG_M2"), | |
332 | KEEMBAY_MUX(0x3, "CPR_M3"), | |
333 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
334 | KEEMBAY_MUX(0x5, "I3C0_M5"), | |
335 | KEEMBAY_MUX(0x6, "SLVDS0_M6"), | |
336 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
337 | KEEMBAY_PIN_DESC(22, "GPIO22", | |
338 | KEEMBAY_MUX(0x0, "I2C0_M0"), | |
339 | KEEMBAY_MUX(0x1, "UART2_M1"), | |
340 | KEEMBAY_MUX(0x2, "DEBUG_M2"), | |
341 | KEEMBAY_MUX(0x3, "CPR_M3"), | |
342 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
343 | KEEMBAY_MUX(0x5, "I3C0_M5"), | |
344 | KEEMBAY_MUX(0x6, "SLVDS0_M6"), | |
345 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
346 | KEEMBAY_PIN_DESC(23, "GPIO23", | |
347 | KEEMBAY_MUX(0x0, "I2C0_M0"), | |
348 | KEEMBAY_MUX(0x1, "UART2_M1"), | |
349 | KEEMBAY_MUX(0x2, "DEBUG_M2"), | |
350 | KEEMBAY_MUX(0x3, "CPR_M3"), | |
351 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
352 | KEEMBAY_MUX(0x5, "I3C1_M5"), | |
353 | KEEMBAY_MUX(0x6, "SLVDS0_M6"), | |
354 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
355 | KEEMBAY_PIN_DESC(24, "GPIO24", | |
356 | KEEMBAY_MUX(0x0, "I2C1_M0"), | |
357 | KEEMBAY_MUX(0x1, "UART2_M1"), | |
358 | KEEMBAY_MUX(0x2, "DEBUG_M2"), | |
359 | KEEMBAY_MUX(0x3, "CPR_M3"), | |
360 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
361 | KEEMBAY_MUX(0x5, "I3C1_M5"), | |
362 | KEEMBAY_MUX(0x6, "SLVDS0_M6"), | |
363 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
364 | KEEMBAY_PIN_DESC(25, "GPIO25", | |
365 | KEEMBAY_MUX(0x0, "I2C1_M0"), | |
366 | KEEMBAY_MUX(0x1, "UART2_M1"), | |
367 | KEEMBAY_MUX(0x2, "SPI0_M2"), | |
368 | KEEMBAY_MUX(0x3, "CPR_M3"), | |
369 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
370 | KEEMBAY_MUX(0x5, "I3C2_M5"), | |
371 | KEEMBAY_MUX(0x6, "SLVDS0_M6"), | |
372 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
373 | KEEMBAY_PIN_DESC(26, "GPIO26", | |
374 | KEEMBAY_MUX(0x0, "SPI0_M0"), | |
375 | KEEMBAY_MUX(0x1, "I2C2_M1"), | |
376 | KEEMBAY_MUX(0x2, "UART0_M2"), | |
377 | KEEMBAY_MUX(0x3, "DSU_M3"), | |
378 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
379 | KEEMBAY_MUX(0x5, "I3C2_M5"), | |
380 | KEEMBAY_MUX(0x6, "SLVDS0_M6"), | |
381 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
382 | KEEMBAY_PIN_DESC(27, "GPIO27", | |
383 | KEEMBAY_MUX(0x0, "SPI0_M0"), | |
384 | KEEMBAY_MUX(0x1, "I2C2_M1"), | |
385 | KEEMBAY_MUX(0x2, "UART0_M2"), | |
386 | KEEMBAY_MUX(0x3, "DSU_M3"), | |
387 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
388 | KEEMBAY_MUX(0x5, "I3C0_M5"), | |
389 | KEEMBAY_MUX(0x6, "SLVDS0_M6"), | |
390 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
391 | KEEMBAY_PIN_DESC(28, "GPIO28", | |
392 | KEEMBAY_MUX(0x0, "SPI0_M0"), | |
393 | KEEMBAY_MUX(0x1, "I2C3_M1"), | |
394 | KEEMBAY_MUX(0x2, "UART0_M2"), | |
395 | KEEMBAY_MUX(0x3, "PWM_M3"), | |
396 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
397 | KEEMBAY_MUX(0x5, "I3C1_M5"), | |
398 | KEEMBAY_MUX(0x6, "SLVDS0_M6"), | |
399 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
400 | KEEMBAY_PIN_DESC(29, "GPIO29", | |
401 | KEEMBAY_MUX(0x0, "SPI0_M0"), | |
402 | KEEMBAY_MUX(0x1, "I2C3_M1"), | |
403 | KEEMBAY_MUX(0x2, "UART0_M2"), | |
404 | KEEMBAY_MUX(0x3, "PWM_M3"), | |
405 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
406 | KEEMBAY_MUX(0x5, "I3C2_M5"), | |
407 | KEEMBAY_MUX(0x6, "SLVDS1_M6"), | |
408 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
409 | KEEMBAY_PIN_DESC(30, "GPIO30", | |
410 | KEEMBAY_MUX(0x0, "SPI0_M0"), | |
411 | KEEMBAY_MUX(0x1, "I2S0_M1"), | |
412 | KEEMBAY_MUX(0x2, "I2C4_M2"), | |
413 | KEEMBAY_MUX(0x3, "PWM_M3"), | |
414 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
415 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
416 | KEEMBAY_MUX(0x6, "SLVDS1_M6"), | |
417 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
418 | KEEMBAY_PIN_DESC(31, "GPIO31", | |
419 | KEEMBAY_MUX(0x0, "SPI0_M0"), | |
420 | KEEMBAY_MUX(0x1, "I2S0_M1"), | |
421 | KEEMBAY_MUX(0x2, "I2C4_M2"), | |
422 | KEEMBAY_MUX(0x3, "PWM_M3"), | |
423 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
424 | KEEMBAY_MUX(0x5, "UART1_M5"), | |
425 | KEEMBAY_MUX(0x6, "SLVDS1_M6"), | |
426 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
427 | KEEMBAY_PIN_DESC(32, "GPIO32", | |
428 | KEEMBAY_MUX(0x0, "SD0_M0"), | |
429 | KEEMBAY_MUX(0x1, "SPI0_M1"), | |
430 | KEEMBAY_MUX(0x2, "UART1_M2"), | |
431 | KEEMBAY_MUX(0x3, "PWM_M3"), | |
432 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
433 | KEEMBAY_MUX(0x5, "PCIE_M5"), | |
434 | KEEMBAY_MUX(0x6, "SLVDS1_M6"), | |
435 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
436 | KEEMBAY_PIN_DESC(33, "GPIO33", | |
437 | KEEMBAY_MUX(0x0, "SD0_M0"), | |
438 | KEEMBAY_MUX(0x1, "SPI0_M1"), | |
439 | KEEMBAY_MUX(0x2, "UART1_M2"), | |
440 | KEEMBAY_MUX(0x3, "PWM_M3"), | |
441 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
442 | KEEMBAY_MUX(0x5, "PCIE_M5"), | |
443 | KEEMBAY_MUX(0x6, "SLVDS1_M6"), | |
444 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
445 | KEEMBAY_PIN_DESC(34, "GPIO34", | |
446 | KEEMBAY_MUX(0x0, "SD0_M0"), | |
447 | KEEMBAY_MUX(0x1, "SPI0_M1"), | |
448 | KEEMBAY_MUX(0x2, "I2C0_M2"), | |
449 | KEEMBAY_MUX(0x3, "UART1_M3"), | |
450 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
451 | KEEMBAY_MUX(0x5, "I2S0_M5"), | |
452 | KEEMBAY_MUX(0x6, "SLVDS1_M6"), | |
453 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
454 | KEEMBAY_PIN_DESC(35, "GPIO35", | |
455 | KEEMBAY_MUX(0x0, "SD0_M0"), | |
456 | KEEMBAY_MUX(0x1, "PCIE_M1"), | |
457 | KEEMBAY_MUX(0x2, "I2C0_M2"), | |
458 | KEEMBAY_MUX(0x3, "UART1_M3"), | |
459 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
460 | KEEMBAY_MUX(0x5, "I2S0_M5"), | |
461 | KEEMBAY_MUX(0x6, "SLVDS1_M6"), | |
462 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
463 | KEEMBAY_PIN_DESC(36, "GPIO36", | |
464 | KEEMBAY_MUX(0x0, "SD0_M0"), | |
465 | KEEMBAY_MUX(0x1, "SPI3_M1"), | |
466 | KEEMBAY_MUX(0x2, "I2C1_M2"), | |
467 | KEEMBAY_MUX(0x3, "DEBUG_M3"), | |
468 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
469 | KEEMBAY_MUX(0x5, "I2S0_M5"), | |
470 | KEEMBAY_MUX(0x6, "SLVDS1_M6"), | |
471 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
472 | KEEMBAY_PIN_DESC(37, "GPIO37", | |
473 | KEEMBAY_MUX(0x0, "SD0_M0"), | |
474 | KEEMBAY_MUX(0x1, "SPI3_M1"), | |
475 | KEEMBAY_MUX(0x2, "I2C1_M2"), | |
476 | KEEMBAY_MUX(0x3, "DEBUG_M3"), | |
477 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
478 | KEEMBAY_MUX(0x5, "I2S0_M5"), | |
479 | KEEMBAY_MUX(0x6, "SLVDS1_M6"), | |
480 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
481 | KEEMBAY_PIN_DESC(38, "GPIO38", | |
482 | KEEMBAY_MUX(0x0, "I3C1_M0"), | |
483 | KEEMBAY_MUX(0x1, "SPI3_M1"), | |
484 | KEEMBAY_MUX(0x2, "UART3_M2"), | |
485 | KEEMBAY_MUX(0x3, "DEBUG_M3"), | |
486 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
487 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
488 | KEEMBAY_MUX(0x6, "I2C2_M6"), | |
489 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
490 | KEEMBAY_PIN_DESC(39, "GPIO39", | |
491 | KEEMBAY_MUX(0x0, "I3C1_M0"), | |
492 | KEEMBAY_MUX(0x1, "SPI3_M1"), | |
493 | KEEMBAY_MUX(0x2, "UART3_M2"), | |
494 | KEEMBAY_MUX(0x3, "DEBUG_M3"), | |
495 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
496 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
497 | KEEMBAY_MUX(0x6, "I2C2_M6"), | |
498 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
499 | KEEMBAY_PIN_DESC(40, "GPIO40", | |
500 | KEEMBAY_MUX(0x0, "I2S2_M0"), | |
501 | KEEMBAY_MUX(0x1, "SPI3_M1"), | |
502 | KEEMBAY_MUX(0x2, "UART3_M2"), | |
503 | KEEMBAY_MUX(0x3, "DEBUG_M3"), | |
504 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
505 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
506 | KEEMBAY_MUX(0x6, "I2C3_M6"), | |
507 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
508 | KEEMBAY_PIN_DESC(41, "GPIO41", | |
509 | KEEMBAY_MUX(0x0, "ETH_M0"), | |
510 | KEEMBAY_MUX(0x1, "SPI3_M1"), | |
511 | KEEMBAY_MUX(0x2, "SPI3_M2"), | |
512 | KEEMBAY_MUX(0x3, "DEBUG_M3"), | |
513 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
514 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
515 | KEEMBAY_MUX(0x6, "I2C3_M6"), | |
516 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
517 | KEEMBAY_PIN_DESC(42, "GPIO42", | |
518 | KEEMBAY_MUX(0x0, "ETH_M0"), | |
519 | KEEMBAY_MUX(0x1, "SD1_M1"), | |
520 | KEEMBAY_MUX(0x2, "SPI3_M2"), | |
521 | KEEMBAY_MUX(0x3, "CPR_M3"), | |
522 | KEEMBAY_MUX(0x4, "CAM_M4"), | |
523 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
524 | KEEMBAY_MUX(0x6, "I2C4_M6"), | |
525 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
526 | KEEMBAY_PIN_DESC(43, "GPIO43", | |
527 | KEEMBAY_MUX(0x0, "ETH_M0"), | |
528 | KEEMBAY_MUX(0x1, "SD1_M1"), | |
529 | KEEMBAY_MUX(0x2, "SPI3_M2"), | |
530 | KEEMBAY_MUX(0x3, "CPR_M3"), | |
531 | KEEMBAY_MUX(0x4, "I2S0_M4"), | |
532 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
533 | KEEMBAY_MUX(0x6, "I2C4_M6"), | |
534 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
535 | KEEMBAY_PIN_DESC(44, "GPIO44", | |
536 | KEEMBAY_MUX(0x0, "ETH_M0"), | |
537 | KEEMBAY_MUX(0x1, "SD1_M1"), | |
538 | KEEMBAY_MUX(0x2, "SPI0_M2"), | |
539 | KEEMBAY_MUX(0x3, "CPR_M3"), | |
540 | KEEMBAY_MUX(0x4, "I2S0_M4"), | |
541 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
542 | KEEMBAY_MUX(0x6, "CAM_M6"), | |
543 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
544 | KEEMBAY_PIN_DESC(45, "GPIO45", | |
545 | KEEMBAY_MUX(0x0, "ETH_M0"), | |
546 | KEEMBAY_MUX(0x1, "SD1_M1"), | |
547 | KEEMBAY_MUX(0x2, "SPI0_M2"), | |
548 | KEEMBAY_MUX(0x3, "CPR_M3"), | |
549 | KEEMBAY_MUX(0x4, "I2S0_M4"), | |
550 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
551 | KEEMBAY_MUX(0x6, "CAM_M6"), | |
552 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
553 | KEEMBAY_PIN_DESC(46, "GPIO46", | |
554 | KEEMBAY_MUX(0x0, "ETH_M0"), | |
555 | KEEMBAY_MUX(0x1, "SD1_M1"), | |
556 | KEEMBAY_MUX(0x2, "SPI0_M2"), | |
557 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
558 | KEEMBAY_MUX(0x4, "I2S0_M4"), | |
559 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
560 | KEEMBAY_MUX(0x6, "CAM_M6"), | |
561 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
562 | KEEMBAY_PIN_DESC(47, "GPIO47", | |
563 | KEEMBAY_MUX(0x0, "ETH_M0"), | |
564 | KEEMBAY_MUX(0x1, "SD1_M1"), | |
565 | KEEMBAY_MUX(0x2, "SPI0_M2"), | |
566 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
567 | KEEMBAY_MUX(0x4, "I2S0_M4"), | |
568 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
569 | KEEMBAY_MUX(0x6, "CAM_M6"), | |
570 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
571 | KEEMBAY_PIN_DESC(48, "GPIO48", | |
572 | KEEMBAY_MUX(0x0, "ETH_M0"), | |
573 | KEEMBAY_MUX(0x1, "SPI2_M1"), | |
574 | KEEMBAY_MUX(0x2, "UART2_M2"), | |
575 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
576 | KEEMBAY_MUX(0x4, "I2S0_M4"), | |
577 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
578 | KEEMBAY_MUX(0x6, "CAM_M6"), | |
579 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
580 | KEEMBAY_PIN_DESC(49, "GPIO49", | |
581 | KEEMBAY_MUX(0x0, "ETH_M0"), | |
582 | KEEMBAY_MUX(0x1, "SPI2_M1"), | |
583 | KEEMBAY_MUX(0x2, "UART2_M2"), | |
584 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
585 | KEEMBAY_MUX(0x4, "I2S1_M4"), | |
586 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
587 | KEEMBAY_MUX(0x6, "CAM_M6"), | |
588 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
589 | KEEMBAY_PIN_DESC(50, "GPIO50", | |
590 | KEEMBAY_MUX(0x0, "ETH_M0"), | |
591 | KEEMBAY_MUX(0x1, "SPI2_M1"), | |
592 | KEEMBAY_MUX(0x2, "UART2_M2"), | |
593 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
594 | KEEMBAY_MUX(0x4, "I2S1_M4"), | |
595 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
596 | KEEMBAY_MUX(0x6, "CAM_M6"), | |
597 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
598 | KEEMBAY_PIN_DESC(51, "GPIO51", | |
599 | KEEMBAY_MUX(0x0, "ETH_M0"), | |
600 | KEEMBAY_MUX(0x1, "SPI2_M1"), | |
601 | KEEMBAY_MUX(0x2, "UART2_M2"), | |
602 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
603 | KEEMBAY_MUX(0x4, "I2S1_M4"), | |
604 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
605 | KEEMBAY_MUX(0x6, "CAM_M6"), | |
606 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
607 | KEEMBAY_PIN_DESC(52, "GPIO52", | |
608 | KEEMBAY_MUX(0x0, "ETH_M0"), | |
609 | KEEMBAY_MUX(0x1, "SPI2_M1"), | |
610 | KEEMBAY_MUX(0x2, "SD0_M2"), | |
611 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
612 | KEEMBAY_MUX(0x4, "I2S1_M4"), | |
613 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
614 | KEEMBAY_MUX(0x6, "CAM_M6"), | |
615 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
616 | KEEMBAY_PIN_DESC(53, "GPIO53", | |
617 | KEEMBAY_MUX(0x0, "ETH_M0"), | |
618 | KEEMBAY_MUX(0x1, "SPI2_M1"), | |
619 | KEEMBAY_MUX(0x2, "SD0_M2"), | |
620 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
621 | KEEMBAY_MUX(0x4, "I2S2_M4"), | |
622 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
623 | KEEMBAY_MUX(0x6, "CAM_M6"), | |
624 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
625 | KEEMBAY_PIN_DESC(54, "GPIO54", | |
626 | KEEMBAY_MUX(0x0, "ETH_M0"), | |
627 | KEEMBAY_MUX(0x1, "SPI2_M1"), | |
628 | KEEMBAY_MUX(0x2, "SD0_M2"), | |
629 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
630 | KEEMBAY_MUX(0x4, "I2S2_M4"), | |
631 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
632 | KEEMBAY_MUX(0x6, "CAM_M6"), | |
633 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
634 | KEEMBAY_PIN_DESC(55, "GPIO55", | |
635 | KEEMBAY_MUX(0x0, "ETH_M0"), | |
636 | KEEMBAY_MUX(0x1, "SPI2_M1"), | |
637 | KEEMBAY_MUX(0x2, "SD1_M2"), | |
638 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
639 | KEEMBAY_MUX(0x4, "I2S2_M4"), | |
640 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
641 | KEEMBAY_MUX(0x6, "CAM_M6"), | |
642 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
643 | KEEMBAY_PIN_DESC(56, "GPIO56", | |
644 | KEEMBAY_MUX(0x0, "ETH_M0"), | |
645 | KEEMBAY_MUX(0x1, "SPI2_M1"), | |
646 | KEEMBAY_MUX(0x2, "SD1_M2"), | |
647 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
648 | KEEMBAY_MUX(0x4, "I2S2_M4"), | |
649 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
650 | KEEMBAY_MUX(0x6, "CAM_M6"), | |
651 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
652 | KEEMBAY_PIN_DESC(57, "GPIO57", | |
653 | KEEMBAY_MUX(0x0, "SPI1_M0"), | |
654 | KEEMBAY_MUX(0x1, "I2S1_M1"), | |
655 | KEEMBAY_MUX(0x2, "SD1_M2"), | |
656 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
657 | KEEMBAY_MUX(0x4, "UART0_M4"), | |
658 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
659 | KEEMBAY_MUX(0x6, "CAM_M6"), | |
660 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
661 | KEEMBAY_PIN_DESC(58, "GPIO58", | |
662 | KEEMBAY_MUX(0x0, "SPI1_M0"), | |
663 | KEEMBAY_MUX(0x1, "ETH_M1"), | |
664 | KEEMBAY_MUX(0x2, "SD0_M2"), | |
665 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
666 | KEEMBAY_MUX(0x4, "UART0_M4"), | |
667 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
668 | KEEMBAY_MUX(0x6, "CAM_M6"), | |
669 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
670 | KEEMBAY_PIN_DESC(59, "GPIO59", | |
671 | KEEMBAY_MUX(0x0, "SPI1_M0"), | |
672 | KEEMBAY_MUX(0x1, "ETH_M1"), | |
673 | KEEMBAY_MUX(0x2, "SD0_M2"), | |
674 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
675 | KEEMBAY_MUX(0x4, "UART0_M4"), | |
676 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
677 | KEEMBAY_MUX(0x6, "CAM_M6"), | |
678 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
679 | KEEMBAY_PIN_DESC(60, "GPIO60", | |
680 | KEEMBAY_MUX(0x0, "SPI1_M0"), | |
681 | KEEMBAY_MUX(0x1, "ETH_M1"), | |
682 | KEEMBAY_MUX(0x2, "I3C1_M2"), | |
683 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
684 | KEEMBAY_MUX(0x4, "UART0_M4"), | |
685 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
686 | KEEMBAY_MUX(0x6, "CAM_M6"), | |
687 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
688 | KEEMBAY_PIN_DESC(61, "GPIO61", | |
689 | KEEMBAY_MUX(0x0, "SPI1_M0"), | |
690 | KEEMBAY_MUX(0x1, "ETH_M1"), | |
691 | KEEMBAY_MUX(0x2, "SD0_M2"), | |
692 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
693 | KEEMBAY_MUX(0x4, "UART1_M4"), | |
694 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
695 | KEEMBAY_MUX(0x6, "CAM_M6"), | |
696 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
697 | KEEMBAY_PIN_DESC(62, "GPIO62", | |
698 | KEEMBAY_MUX(0x0, "SPI1_M0"), | |
699 | KEEMBAY_MUX(0x1, "ETH_M1"), | |
700 | KEEMBAY_MUX(0x2, "SD1_M2"), | |
701 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
702 | KEEMBAY_MUX(0x4, "UART1_M4"), | |
703 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
704 | KEEMBAY_MUX(0x6, "CAM_M6"), | |
705 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
706 | KEEMBAY_PIN_DESC(63, "GPIO63", | |
707 | KEEMBAY_MUX(0x0, "I2S1_M0"), | |
708 | KEEMBAY_MUX(0x1, "SPI1_M1"), | |
709 | KEEMBAY_MUX(0x2, "SD1_M2"), | |
710 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
711 | KEEMBAY_MUX(0x4, "UART1_M4"), | |
712 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
713 | KEEMBAY_MUX(0x6, "CAM_M6"), | |
714 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
715 | KEEMBAY_PIN_DESC(64, "GPIO64", | |
716 | KEEMBAY_MUX(0x0, "I2S2_M0"), | |
717 | KEEMBAY_MUX(0x1, "SPI1_M1"), | |
718 | KEEMBAY_MUX(0x2, "ETH_M2"), | |
719 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
720 | KEEMBAY_MUX(0x4, "UART1_M4"), | |
721 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
722 | KEEMBAY_MUX(0x6, "CAM_M6"), | |
723 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
724 | KEEMBAY_PIN_DESC(65, "GPIO65", | |
725 | KEEMBAY_MUX(0x0, "I3C0_M0"), | |
726 | KEEMBAY_MUX(0x1, "SPI1_M1"), | |
727 | KEEMBAY_MUX(0x2, "SD1_M2"), | |
728 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
729 | KEEMBAY_MUX(0x4, "SPI0_M4"), | |
730 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
731 | KEEMBAY_MUX(0x6, "CAM_M6"), | |
732 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
733 | KEEMBAY_PIN_DESC(66, "GPIO66", | |
734 | KEEMBAY_MUX(0x0, "I3C0_M0"), | |
735 | KEEMBAY_MUX(0x1, "ETH_M1"), | |
736 | KEEMBAY_MUX(0x2, "I2C0_M2"), | |
737 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
738 | KEEMBAY_MUX(0x4, "SPI0_M4"), | |
739 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
740 | KEEMBAY_MUX(0x6, "CAM_M6"), | |
741 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
742 | KEEMBAY_PIN_DESC(67, "GPIO67", | |
743 | KEEMBAY_MUX(0x0, "I3C1_M0"), | |
744 | KEEMBAY_MUX(0x1, "ETH_M1"), | |
745 | KEEMBAY_MUX(0x2, "I2C0_M2"), | |
746 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
747 | KEEMBAY_MUX(0x4, "SPI0_M4"), | |
748 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
749 | KEEMBAY_MUX(0x6, "I2S3_M6"), | |
750 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
751 | KEEMBAY_PIN_DESC(68, "GPIO68", | |
752 | KEEMBAY_MUX(0x0, "I3C1_M0"), | |
753 | KEEMBAY_MUX(0x1, "ETH_M1"), | |
754 | KEEMBAY_MUX(0x2, "I2C1_M2"), | |
755 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
756 | KEEMBAY_MUX(0x4, "SPI0_M4"), | |
757 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
758 | KEEMBAY_MUX(0x6, "I2S3_M6"), | |
759 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
760 | KEEMBAY_PIN_DESC(69, "GPIO69", | |
761 | KEEMBAY_MUX(0x0, "I3C2_M0"), | |
762 | KEEMBAY_MUX(0x1, "ETH_M1"), | |
763 | KEEMBAY_MUX(0x2, "I2C1_M2"), | |
764 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
765 | KEEMBAY_MUX(0x4, "SPI0_M4"), | |
766 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
767 | KEEMBAY_MUX(0x6, "I2S3_M6"), | |
768 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
769 | KEEMBAY_PIN_DESC(70, "GPIO70", | |
770 | KEEMBAY_MUX(0x0, "I3C2_M0"), | |
771 | KEEMBAY_MUX(0x1, "ETH_M1"), | |
772 | KEEMBAY_MUX(0x2, "SPI0_M2"), | |
773 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
774 | KEEMBAY_MUX(0x4, "SD0_M4"), | |
775 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
776 | KEEMBAY_MUX(0x6, "I2S3_M6"), | |
777 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
778 | KEEMBAY_PIN_DESC(71, "GPIO71", | |
779 | KEEMBAY_MUX(0x0, "I3C0_M0"), | |
780 | KEEMBAY_MUX(0x1, "ETH_M1"), | |
781 | KEEMBAY_MUX(0x2, "SLVDS1_M2"), | |
782 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
783 | KEEMBAY_MUX(0x4, "SD0_M4"), | |
784 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
785 | KEEMBAY_MUX(0x6, "I2S3_M6"), | |
786 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
787 | KEEMBAY_PIN_DESC(72, "GPIO72", | |
788 | KEEMBAY_MUX(0x0, "I3C1_M0"), | |
789 | KEEMBAY_MUX(0x1, "ETH_M1"), | |
790 | KEEMBAY_MUX(0x2, "SLVDS1_M2"), | |
791 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
792 | KEEMBAY_MUX(0x4, "SD0_M4"), | |
793 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
794 | KEEMBAY_MUX(0x6, "UART2_M6"), | |
795 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
796 | KEEMBAY_PIN_DESC(73, "GPIO73", | |
797 | KEEMBAY_MUX(0x0, "I3C2_M0"), | |
798 | KEEMBAY_MUX(0x1, "ETH_M1"), | |
799 | KEEMBAY_MUX(0x2, "SLVDS1_M2"), | |
800 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
801 | KEEMBAY_MUX(0x4, "SD0_M4"), | |
802 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
803 | KEEMBAY_MUX(0x6, "UART2_M6"), | |
804 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
805 | KEEMBAY_PIN_DESC(74, "GPIO74", | |
806 | KEEMBAY_MUX(0x0, "I3C0_M0"), | |
807 | KEEMBAY_MUX(0x1, "ETH_M1"), | |
808 | KEEMBAY_MUX(0x2, "SLVDS1_M2"), | |
809 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
810 | KEEMBAY_MUX(0x4, "SD0_M4"), | |
811 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
812 | KEEMBAY_MUX(0x6, "UART2_M6"), | |
813 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
814 | KEEMBAY_PIN_DESC(75, "GPIO75", | |
815 | KEEMBAY_MUX(0x0, "I3C0_M0"), | |
816 | KEEMBAY_MUX(0x1, "ETH_M1"), | |
817 | KEEMBAY_MUX(0x2, "SLVDS1_M2"), | |
818 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
819 | KEEMBAY_MUX(0x4, "SD0_M4"), | |
820 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
821 | KEEMBAY_MUX(0x6, "UART2_M6"), | |
822 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
823 | KEEMBAY_PIN_DESC(76, "GPIO76", | |
824 | KEEMBAY_MUX(0x0, "I2C2_M0"), | |
825 | KEEMBAY_MUX(0x1, "I3C0_M1"), | |
826 | KEEMBAY_MUX(0x2, "SLVDS1_M2"), | |
827 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
828 | KEEMBAY_MUX(0x4, "ETH_M4"), | |
829 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
830 | KEEMBAY_MUX(0x6, "UART3_M6"), | |
831 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
832 | KEEMBAY_PIN_DESC(77, "GPIO77", | |
833 | KEEMBAY_MUX(0x0, "PCIE_M0"), | |
834 | KEEMBAY_MUX(0x1, "I3C1_M1"), | |
835 | KEEMBAY_MUX(0x2, "SLVDS1_M2"), | |
836 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
837 | KEEMBAY_MUX(0x4, "I3C2_M4"), | |
838 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
839 | KEEMBAY_MUX(0x6, "UART3_M6"), | |
840 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
841 | KEEMBAY_PIN_DESC(78, "GPIO78", | |
842 | KEEMBAY_MUX(0x0, "PCIE_M0"), | |
843 | KEEMBAY_MUX(0x1, "I3C2_M1"), | |
844 | KEEMBAY_MUX(0x2, "SLVDS1_M2"), | |
845 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
846 | KEEMBAY_MUX(0x4, "I3C2_M4"), | |
847 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
848 | KEEMBAY_MUX(0x6, "UART3_M6"), | |
849 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
850 | KEEMBAY_PIN_DESC(79, "GPIO79", | |
851 | KEEMBAY_MUX(0x0, "PCIE_M0"), | |
852 | KEEMBAY_MUX(0x1, "I2C2_M1"), | |
853 | KEEMBAY_MUX(0x2, "SLVDS1_M2"), | |
854 | KEEMBAY_MUX(0x3, "TPIU_M3"), | |
855 | KEEMBAY_MUX(0x4, "I3C2_M4"), | |
856 | KEEMBAY_MUX(0x5, "LCD_M5"), | |
857 | KEEMBAY_MUX(0x6, "UART3_M6"), | |
858 | KEEMBAY_MUX(0x7, "GPIO_M7")), | |
859 | }; | |
860 | ||
861 | static inline u32 keembay_read_reg(void __iomem *base, unsigned int pin) | |
862 | { | |
863 | return readl(base + KEEMBAY_GPIO_REG_OFFSET(pin)); | |
864 | } | |
865 | ||
866 | static inline u32 keembay_read_gpio_reg(void __iomem *base, unsigned int pin) | |
867 | { | |
868 | return keembay_read_reg(base, pin / KEEMBAY_GPIO_MAX_PER_REG); | |
869 | } | |
870 | ||
871 | static inline u32 keembay_read_pin(void __iomem *base, unsigned int pin) | |
872 | { | |
873 | u32 val = keembay_read_gpio_reg(base, pin); | |
874 | ||
875 | return !!(val & BIT(pin % KEEMBAY_GPIO_MAX_PER_REG)); | |
876 | } | |
877 | ||
878 | static inline void keembay_write_reg(u32 val, void __iomem *base, unsigned int pin) | |
879 | { | |
880 | writel(val, base + KEEMBAY_GPIO_REG_OFFSET(pin)); | |
881 | } | |
882 | ||
883 | static inline void keembay_write_gpio_reg(u32 val, void __iomem *base, unsigned int pin) | |
884 | { | |
885 | keembay_write_reg(val, base, pin / KEEMBAY_GPIO_MAX_PER_REG); | |
886 | } | |
887 | ||
888 | static void keembay_gpio_invert(struct keembay_pinctrl *kpc, unsigned int pin) | |
889 | { | |
890 | unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
891 | ||
892 | /* | |
893 | * This IP doesn't support the falling edge and low level interrupt | |
894 | * trigger. Invert API is used to mimic the falling edge and low | |
895 | * level support | |
896 | */ | |
897 | ||
898 | val |= FIELD_PREP(KEEMBAY_GPIO_MODE_INV_MASK, KEEMBAY_GPIO_MODE_INV_VAL); | |
899 | keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
900 | } | |
901 | ||
902 | static void keembay_gpio_restore_default(struct keembay_pinctrl *kpc, unsigned int pin) | |
903 | { | |
904 | unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
905 | ||
906 | val &= FIELD_PREP(KEEMBAY_GPIO_MODE_INV_MASK, 0); | |
907 | keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
908 | } | |
909 | ||
910 | static int keembay_request_gpio(struct pinctrl_dev *pctldev, | |
911 | struct pinctrl_gpio_range *range, unsigned int pin) | |
912 | { | |
913 | struct keembay_pinctrl *kpc = pinctrl_dev_get_drvdata(pctldev); | |
914 | unsigned int val; | |
915 | ||
916 | if (pin >= kpc->npins) | |
917 | return -EINVAL; | |
918 | ||
919 | val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
920 | val = FIELD_GET(KEEMBAY_GPIO_MODE_SELECT_MASK, val); | |
921 | ||
922 | /* As per Pin Mux Map, Modes 0 to 6 are for peripherals */ | |
923 | if (val != KEEMBAY_GPIO_MODE_DEFAULT) | |
924 | return -EBUSY; | |
925 | ||
926 | return 0; | |
927 | } | |
928 | ||
929 | static int keembay_set_mux(struct pinctrl_dev *pctldev, unsigned int fun_sel, | |
930 | unsigned int grp_sel) | |
931 | { | |
932 | struct keembay_pinctrl *kpc = pinctrl_dev_get_drvdata(pctldev); | |
933 | struct function_desc *func; | |
934 | struct group_desc *grp; | |
935 | unsigned int val; | |
936 | u8 pin_mode; | |
937 | int pin; | |
938 | ||
939 | grp = pinctrl_generic_get_group(pctldev, grp_sel); | |
940 | if (!grp) | |
941 | return -EINVAL; | |
942 | ||
943 | func = pinmux_generic_get_function(pctldev, fun_sel); | |
944 | if (!func) | |
945 | return -EINVAL; | |
946 | ||
947 | /* Change modes for pins in the selected group */ | |
948 | pin = *grp->pins; | |
949 | pin_mode = *(u8 *)(func->data); | |
950 | ||
951 | val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
952 | val = u32_replace_bits(val, pin_mode, KEEMBAY_GPIO_MODE_SELECT_MASK); | |
953 | keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
954 | ||
955 | return 0; | |
956 | } | |
957 | ||
958 | static u32 keembay_pinconf_get_pull(struct keembay_pinctrl *kpc, unsigned int pin) | |
959 | { | |
960 | unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
961 | ||
962 | return FIELD_GET(KEEMBAY_GPIO_MODE_PULLUP_MASK, val); | |
963 | } | |
964 | ||
965 | static int keembay_pinconf_set_pull(struct keembay_pinctrl *kpc, unsigned int pin, | |
966 | unsigned int pull) | |
967 | { | |
968 | unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
969 | ||
970 | val = u32_replace_bits(val, pull, KEEMBAY_GPIO_MODE_PULLUP_MASK); | |
971 | keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
972 | ||
973 | return 0; | |
974 | } | |
975 | ||
976 | static int keembay_pinconf_get_drive(struct keembay_pinctrl *kpc, unsigned int pin) | |
977 | { | |
978 | unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
979 | ||
980 | val = FIELD_GET(KEEMBAY_GPIO_MODE_DRIVE_MASK, val) * 4; | |
981 | if (val) | |
982 | return val; | |
983 | ||
984 | return KEEMBAY_GPIO_MIN_STRENGTH; | |
985 | } | |
986 | ||
987 | static int keembay_pinconf_set_drive(struct keembay_pinctrl *kpc, unsigned int pin, | |
988 | unsigned int drive) | |
989 | { | |
990 | unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
991 | unsigned int strength = clamp_val(drive, KEEMBAY_GPIO_MIN_STRENGTH, | |
992 | KEEMBAY_GPIO_MAX_STRENGTH) / 4; | |
993 | ||
994 | val = u32_replace_bits(val, strength, KEEMBAY_GPIO_MODE_DRIVE_MASK); | |
995 | keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
996 | ||
997 | return 0; | |
998 | } | |
999 | ||
1000 | static int keembay_pinconf_get_slew_rate(struct keembay_pinctrl *kpc, unsigned int pin) | |
1001 | { | |
1002 | unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
1003 | ||
1004 | return !!(val & KEEMBAY_GPIO_MODE_SLEW_RATE); | |
1005 | } | |
1006 | ||
1007 | static int keembay_pinconf_set_slew_rate(struct keembay_pinctrl *kpc, unsigned int pin, | |
1008 | unsigned int slew_rate) | |
1009 | { | |
1010 | unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
1011 | ||
1012 | if (slew_rate) | |
1013 | val |= KEEMBAY_GPIO_MODE_SLEW_RATE; | |
1014 | else | |
1015 | val &= ~KEEMBAY_GPIO_MODE_SLEW_RATE; | |
1016 | ||
1017 | keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
1018 | ||
1019 | return 0; | |
1020 | } | |
1021 | ||
1022 | static int keembay_pinconf_get_schmitt(struct keembay_pinctrl *kpc, unsigned int pin) | |
1023 | { | |
1024 | unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
1025 | ||
1026 | return !!(val & KEEMBAY_GPIO_MODE_SCHMITT_EN); | |
1027 | } | |
1028 | ||
1029 | static int keembay_pinconf_set_schmitt(struct keembay_pinctrl *kpc, unsigned int pin, | |
1030 | unsigned int schmitt_en) | |
1031 | { | |
1032 | unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
1033 | ||
1034 | if (schmitt_en) | |
1035 | val |= KEEMBAY_GPIO_MODE_SCHMITT_EN; | |
1036 | else | |
1037 | val &= ~KEEMBAY_GPIO_MODE_SCHMITT_EN; | |
1038 | ||
1039 | keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
1040 | ||
1041 | return 0; | |
1042 | } | |
1043 | ||
1044 | static int keembay_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, | |
1045 | unsigned long *cfg) | |
1046 | { | |
1047 | struct keembay_pinctrl *kpc = pinctrl_dev_get_drvdata(pctldev); | |
1048 | unsigned int param = pinconf_to_config_param(*cfg); | |
1049 | unsigned int val; | |
1050 | ||
1051 | if (pin >= kpc->npins) | |
1052 | return -EINVAL; | |
1053 | ||
1054 | switch (param) { | |
1055 | case PIN_CONFIG_BIAS_DISABLE: | |
1056 | if (keembay_pinconf_get_pull(kpc, pin) != KEEMBAY_GPIO_DISABLE) | |
1057 | return -EINVAL; | |
1058 | break; | |
1059 | ||
1060 | case PIN_CONFIG_BIAS_PULL_UP: | |
1061 | if (keembay_pinconf_get_pull(kpc, pin) != KEEMBAY_GPIO_PULL_UP) | |
1062 | return -EINVAL; | |
1063 | break; | |
1064 | ||
1065 | case PIN_CONFIG_BIAS_PULL_DOWN: | |
1066 | if (keembay_pinconf_get_pull(kpc, pin) != KEEMBAY_GPIO_PULL_DOWN) | |
1067 | return -EINVAL; | |
1068 | break; | |
1069 | ||
1070 | case PIN_CONFIG_BIAS_BUS_HOLD: | |
1071 | if (keembay_pinconf_get_pull(kpc, pin) != KEEMBAY_GPIO_BUS_HOLD) | |
1072 | return -EINVAL; | |
1073 | break; | |
1074 | ||
1075 | case PIN_CONFIG_INPUT_SCHMITT_ENABLE: | |
1076 | if (!keembay_pinconf_get_schmitt(kpc, pin)) | |
1077 | return -EINVAL; | |
1078 | break; | |
1079 | ||
1080 | case PIN_CONFIG_SLEW_RATE: | |
1081 | val = keembay_pinconf_get_slew_rate(kpc, pin); | |
1082 | *cfg = pinconf_to_config_packed(param, val); | |
1083 | break; | |
1084 | ||
1085 | case PIN_CONFIG_DRIVE_STRENGTH: | |
1086 | val = keembay_pinconf_get_drive(kpc, pin); | |
1087 | *cfg = pinconf_to_config_packed(param, val); | |
1088 | break; | |
1089 | ||
1090 | default: | |
1091 | return -ENOTSUPP; | |
1092 | } | |
1093 | ||
1094 | return 0; | |
1095 | } | |
1096 | ||
1097 | static int keembay_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, | |
1098 | unsigned long *cfg, unsigned int num_configs) | |
1099 | { | |
1100 | struct keembay_pinctrl *kpc = pinctrl_dev_get_drvdata(pctldev); | |
1101 | enum pin_config_param param; | |
1102 | unsigned int arg, i; | |
1103 | int ret = 0; | |
1104 | ||
1105 | if (pin >= kpc->npins) | |
1106 | return -EINVAL; | |
1107 | ||
1108 | for (i = 0; i < num_configs; i++) { | |
1109 | param = pinconf_to_config_param(cfg[i]); | |
1110 | arg = pinconf_to_config_argument(cfg[i]); | |
1111 | ||
1112 | switch (param) { | |
1113 | case PIN_CONFIG_BIAS_DISABLE: | |
1114 | ret = keembay_pinconf_set_pull(kpc, pin, KEEMBAY_GPIO_DISABLE); | |
1115 | break; | |
1116 | ||
1117 | case PIN_CONFIG_BIAS_PULL_UP: | |
1118 | ret = keembay_pinconf_set_pull(kpc, pin, KEEMBAY_GPIO_PULL_UP); | |
1119 | break; | |
1120 | ||
1121 | case PIN_CONFIG_BIAS_PULL_DOWN: | |
1122 | ret = keembay_pinconf_set_pull(kpc, pin, KEEMBAY_GPIO_PULL_DOWN); | |
1123 | break; | |
1124 | ||
1125 | case PIN_CONFIG_BIAS_BUS_HOLD: | |
1126 | ret = keembay_pinconf_set_pull(kpc, pin, KEEMBAY_GPIO_BUS_HOLD); | |
1127 | break; | |
1128 | ||
1129 | case PIN_CONFIG_INPUT_SCHMITT_ENABLE: | |
1130 | ret = keembay_pinconf_set_schmitt(kpc, pin, arg); | |
1131 | break; | |
1132 | ||
1133 | case PIN_CONFIG_SLEW_RATE: | |
1134 | ret = keembay_pinconf_set_slew_rate(kpc, pin, arg); | |
1135 | break; | |
1136 | ||
1137 | case PIN_CONFIG_DRIVE_STRENGTH: | |
1138 | ret = keembay_pinconf_set_drive(kpc, pin, arg); | |
1139 | break; | |
1140 | ||
1141 | default: | |
1142 | return -ENOTSUPP; | |
1143 | } | |
1144 | if (ret) | |
1145 | return ret; | |
1146 | } | |
1147 | return ret; | |
1148 | } | |
1149 | ||
1150 | static const struct pinctrl_ops keembay_pctlops = { | |
1151 | .get_groups_count = pinctrl_generic_get_group_count, | |
1152 | .get_group_name = pinctrl_generic_get_group_name, | |
1153 | .get_group_pins = pinctrl_generic_get_group_pins, | |
1154 | .dt_node_to_map = pinconf_generic_dt_node_to_map_all, | |
1155 | .dt_free_map = pinconf_generic_dt_free_map, | |
1156 | }; | |
1157 | ||
1158 | static const struct pinmux_ops keembay_pmxops = { | |
1159 | .get_functions_count = pinmux_generic_get_function_count, | |
1160 | .get_function_name = pinmux_generic_get_function_name, | |
1161 | .get_function_groups = pinmux_generic_get_function_groups, | |
1162 | .gpio_request_enable = keembay_request_gpio, | |
1163 | .set_mux = keembay_set_mux, | |
1164 | }; | |
1165 | ||
1166 | static const struct pinconf_ops keembay_confops = { | |
1167 | .is_generic = true, | |
1168 | .pin_config_get = keembay_pinconf_get, | |
1169 | .pin_config_set = keembay_pinconf_set, | |
1170 | }; | |
1171 | ||
1172 | static struct pinctrl_desc keembay_pinctrl_desc = { | |
1173 | .name = "keembay-pinmux", | |
1174 | .pctlops = &keembay_pctlops, | |
1175 | .pmxops = &keembay_pmxops, | |
1176 | .confops = &keembay_confops, | |
1177 | .owner = THIS_MODULE, | |
1178 | }; | |
1179 | ||
1180 | static int keembay_gpio_get(struct gpio_chip *gc, unsigned int pin) | |
1181 | { | |
1182 | struct keembay_pinctrl *kpc = gpiochip_get_data(gc); | |
1183 | unsigned int val, offset; | |
1184 | ||
1185 | val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
1186 | offset = (val & KEEMBAY_GPIO_MODE_DIR) ? KEEMBAY_GPIO_DATA_IN : KEEMBAY_GPIO_DATA_OUT; | |
1187 | ||
1188 | return keembay_read_pin(kpc->base0 + offset, pin); | |
1189 | } | |
1190 | ||
1191 | static void keembay_gpio_set(struct gpio_chip *gc, unsigned int pin, int val) | |
1192 | { | |
1193 | struct keembay_pinctrl *kpc = gpiochip_get_data(gc); | |
1194 | unsigned int reg_val; | |
1195 | ||
1196 | reg_val = keembay_read_gpio_reg(kpc->base0 + KEEMBAY_GPIO_DATA_OUT, pin); | |
1197 | if (val) | |
1198 | keembay_write_gpio_reg(reg_val | BIT(pin % KEEMBAY_GPIO_MAX_PER_REG), | |
1199 | kpc->base0 + KEEMBAY_GPIO_DATA_HIGH, pin); | |
1200 | else | |
1201 | keembay_write_gpio_reg(~reg_val | BIT(pin % KEEMBAY_GPIO_MAX_PER_REG), | |
1202 | kpc->base0 + KEEMBAY_GPIO_DATA_LOW, pin); | |
1203 | } | |
1204 | ||
1205 | static int keembay_gpio_get_direction(struct gpio_chip *gc, unsigned int pin) | |
1206 | { | |
1207 | struct keembay_pinctrl *kpc = gpiochip_get_data(gc); | |
1208 | unsigned int val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
1209 | ||
1210 | return !!(val & KEEMBAY_GPIO_MODE_DIR); | |
1211 | } | |
1212 | ||
1213 | static int keembay_gpio_set_direction_in(struct gpio_chip *gc, unsigned int pin) | |
1214 | { | |
1215 | struct keembay_pinctrl *kpc = gpiochip_get_data(gc); | |
1216 | unsigned int val; | |
1217 | ||
1218 | val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
1219 | val |= KEEMBAY_GPIO_MODE_DIR; | |
1220 | keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
1221 | ||
1222 | return 0; | |
1223 | } | |
1224 | ||
1225 | static int keembay_gpio_set_direction_out(struct gpio_chip *gc, | |
1226 | unsigned int pin, int value) | |
1227 | { | |
1228 | struct keembay_pinctrl *kpc = gpiochip_get_data(gc); | |
1229 | unsigned int val; | |
1230 | ||
1231 | val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
1232 | val &= ~KEEMBAY_GPIO_MODE_DIR; | |
1233 | keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_MODE, pin); | |
1234 | keembay_gpio_set(gc, pin, value); | |
1235 | ||
1236 | return 0; | |
1237 | } | |
1238 | ||
1239 | static void keembay_gpio_irq_handler(struct irq_desc *desc) | |
1240 | { | |
1241 | struct gpio_chip *gc = irq_desc_get_handler_data(desc); | |
1242 | unsigned int kmb_irq = irq_desc_get_irq(desc); | |
1243 | unsigned long reg, clump = 0, bit = 0; | |
1244 | struct irq_chip *parent_chip; | |
1245 | struct keembay_pinctrl *kpc; | |
1246 | unsigned int src, pin, val; | |
1247 | ||
1248 | /* Identify GPIO interrupt number from GIC interrupt number */ | |
1249 | for (src = 0; src < KEEMBAY_GPIO_NUM_IRQ; src++) { | |
1250 | if (kmb_irq == gc->irq.parents[src]) | |
1251 | break; | |
1252 | } | |
1253 | ||
1254 | if (src == KEEMBAY_GPIO_NUM_IRQ) | |
1255 | return; | |
1256 | ||
1257 | parent_chip = irq_desc_get_chip(desc); | |
1258 | kpc = gpiochip_get_data(gc); | |
1259 | ||
1260 | chained_irq_enter(parent_chip, desc); | |
1261 | reg = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_INT_CFG, src); | |
1262 | ||
1263 | /* | |
1264 | * Each Interrupt line can be shared by up to 4 GPIO pins. Enable bit | |
1265 | * and input values were checked to identify the source of the | |
1266 | * Interrupt. The checked enable bit positions are 7, 15, 23 and 31. | |
1267 | */ | |
1268 | for_each_set_clump8(bit, clump, ®, BITS_PER_TYPE(typeof(reg))) { | |
1269 | pin = clump & ~KEEMBAY_GPIO_IRQ_ENABLE; | |
1270 | val = keembay_read_pin(kpc->base0 + KEEMBAY_GPIO_DATA_IN, pin); | |
1271 | kmb_irq = irq_linear_revmap(gc->irq.domain, pin); | |
1272 | ||
1273 | /* Checks if the interrupt is enabled */ | |
1274 | if (val && (clump & KEEMBAY_GPIO_IRQ_ENABLE)) | |
1275 | generic_handle_irq(kmb_irq); | |
1276 | } | |
1277 | chained_irq_exit(parent_chip, desc); | |
1278 | } | |
1279 | ||
1280 | static void keembay_gpio_clear_irq(struct irq_data *data, unsigned long pos, | |
1281 | u32 src, irq_hw_number_t pin) | |
1282 | { | |
1283 | struct gpio_chip *gc = irq_data_get_irq_chip_data(data); | |
1284 | struct keembay_pinctrl *kpc = gpiochip_get_data(gc); | |
1285 | unsigned long trig = irqd_get_trigger_type(data); | |
1286 | struct keembay_gpio_irq *irq = &kpc->irq[src]; | |
1287 | unsigned long val; | |
1288 | ||
1289 | /* Check if the value of pos/KEEMBAY_GPIO_NUM_IRQ is in valid range. */ | |
1290 | if ((pos / KEEMBAY_GPIO_NUM_IRQ) >= KEEMBAY_GPIO_MAX_PER_IRQ) | |
1291 | return; | |
1292 | ||
1293 | /* Retains val register as it handles other interrupts as well. */ | |
1294 | val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_INT_CFG, src); | |
1295 | ||
1296 | bitmap_set_value8(&val, 0, pos); | |
1297 | keembay_write_reg(val, kpc->base1 + KEEMBAY_GPIO_INT_CFG, src); | |
1298 | ||
1299 | irq->num_share--; | |
1300 | irq->pins[pos / KEEMBAY_GPIO_NUM_IRQ] = 0; | |
1301 | ||
1302 | if (trig & IRQ_TYPE_LEVEL_MASK) | |
1303 | keembay_gpio_restore_default(kpc, pin); | |
1304 | ||
1305 | if (irq->trigger == IRQ_TYPE_LEVEL_HIGH) | |
1306 | kpc->max_gpios_level_type++; | |
1307 | else if (irq->trigger == IRQ_TYPE_EDGE_RISING) | |
1308 | kpc->max_gpios_edge_type++; | |
1309 | } | |
1310 | ||
1311 | static int keembay_find_free_slot(struct keembay_pinctrl *kpc, unsigned int src) | |
1312 | { | |
1313 | unsigned long val = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_INT_CFG, src); | |
1314 | ||
1315 | return bitmap_find_free_region(&val, KEEMBAY_GPIO_MAX_PER_REG, 3) / KEEMBAY_GPIO_NUM_IRQ; | |
1316 | } | |
1317 | ||
1318 | static int keembay_find_free_src(struct keembay_pinctrl *kpc, unsigned int trig) | |
1319 | { | |
1320 | int src, type = 0; | |
1321 | ||
1322 | if (trig & IRQ_TYPE_LEVEL_MASK) | |
1323 | type = IRQ_TYPE_LEVEL_HIGH; | |
1324 | else if (trig & IRQ_TYPE_EDGE_BOTH) | |
1325 | type = IRQ_TYPE_EDGE_RISING; | |
1326 | ||
1327 | for (src = 0; src < KEEMBAY_GPIO_NUM_IRQ; src++) { | |
1328 | if (kpc->irq[src].trigger != type) | |
1329 | continue; | |
1330 | ||
1331 | if (!keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_INT_CFG, src) || | |
1332 | kpc->irq[src].num_share < KEEMBAY_GPIO_MAX_PER_IRQ) | |
1333 | return src; | |
1334 | } | |
1335 | ||
1336 | return -EBUSY; | |
1337 | } | |
1338 | ||
1339 | static void keembay_gpio_set_irq(struct keembay_pinctrl *kpc, int src, | |
1340 | int slot, irq_hw_number_t pin) | |
1341 | { | |
1342 | unsigned long val = pin | KEEMBAY_GPIO_IRQ_ENABLE; | |
1343 | struct keembay_gpio_irq *irq = &kpc->irq[src]; | |
1344 | unsigned long flags, reg; | |
1345 | ||
1346 | raw_spin_lock_irqsave(&kpc->lock, flags); | |
1347 | reg = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_INT_CFG, src); | |
1348 | bitmap_set_value8(®, val, slot * 8); | |
1349 | keembay_write_reg(reg, kpc->base1 + KEEMBAY_GPIO_INT_CFG, src); | |
1350 | raw_spin_unlock_irqrestore(&kpc->lock, flags); | |
1351 | ||
1352 | if (irq->trigger == IRQ_TYPE_LEVEL_HIGH) | |
1353 | kpc->max_gpios_level_type--; | |
1354 | else if (irq->trigger == IRQ_TYPE_EDGE_RISING) | |
1355 | kpc->max_gpios_edge_type--; | |
1356 | ||
1357 | irq->source = src; | |
1358 | irq->pins[slot] = pin; | |
1359 | irq->num_share++; | |
1360 | } | |
1361 | ||
1362 | static void keembay_gpio_irq_enable(struct irq_data *data) | |
1363 | { | |
1364 | struct gpio_chip *gc = irq_data_get_irq_chip_data(data); | |
1365 | struct keembay_pinctrl *kpc = gpiochip_get_data(gc); | |
1366 | unsigned int trig = irqd_get_trigger_type(data); | |
1367 | irq_hw_number_t pin = irqd_to_hwirq(data); | |
1368 | int src, slot; | |
1369 | ||
1370 | /* Check which Interrupt source and slot is available */ | |
1371 | src = keembay_find_free_src(kpc, trig); | |
1372 | slot = keembay_find_free_slot(kpc, src); | |
1373 | ||
1374 | if (src < 0 || slot < 0) | |
1375 | return; | |
1376 | ||
1377 | if (trig & KEEMBAY_GPIO_SENSE_LOW) | |
1378 | keembay_gpio_invert(kpc, pin); | |
1379 | ||
1380 | keembay_gpio_set_irq(kpc, src, slot, pin); | |
1381 | } | |
1382 | ||
1383 | static void keembay_gpio_irq_ack(struct irq_data *data) | |
1384 | { | |
1385 | /* | |
1386 | * The keembay_gpio_irq_ack function is needed to handle_edge_irq. | |
1387 | * IRQ ack is not possible from the SOC perspective. The IP by itself | |
1388 | * is used for handling interrupts which do not come in short-time and | |
1389 | * not used as protocol or communication interrupts. All the interrupts | |
1390 | * are threaded IRQ interrupts. But this function is expected to be | |
1391 | * present as the gpio IP is registered with irq framework. Otherwise | |
1392 | * handle_edge_irq() fails. | |
1393 | */ | |
1394 | } | |
1395 | ||
1396 | static void keembay_gpio_irq_disable(struct irq_data *data) | |
1397 | { | |
1398 | struct gpio_chip *gc = irq_data_get_irq_chip_data(data); | |
1399 | struct keembay_pinctrl *kpc = gpiochip_get_data(gc); | |
1400 | irq_hw_number_t pin = irqd_to_hwirq(data); | |
1401 | unsigned long reg, clump = 0, pos = 0; | |
1402 | unsigned int src; | |
1403 | ||
1404 | for (src = 0; src < KEEMBAY_GPIO_NUM_IRQ; src++) { | |
1405 | reg = keembay_read_reg(kpc->base1 + KEEMBAY_GPIO_INT_CFG, src); | |
1406 | for_each_set_clump8(pos, clump, ®, BITS_PER_TYPE(typeof(reg))) { | |
1407 | if ((clump & ~KEEMBAY_GPIO_IRQ_ENABLE) == pin) { | |
1408 | keembay_gpio_clear_irq(data, pos, src, pin); | |
1409 | return; | |
1410 | } | |
1411 | } | |
1412 | } | |
1413 | } | |
1414 | ||
1415 | static int keembay_gpio_irq_set_type(struct irq_data *data, unsigned int type) | |
1416 | { | |
1417 | struct gpio_chip *gc = irq_data_get_irq_chip_data(data); | |
1418 | struct keembay_pinctrl *kpc = gpiochip_get_data(gc); | |
1419 | ||
1420 | /* Change EDGE_BOTH as EDGE_RISING in order to claim the IRQ for power button */ | |
1421 | if (!kpc->max_gpios_edge_type && (type & IRQ_TYPE_EDGE_BOTH)) | |
1422 | type = IRQ_TYPE_EDGE_RISING; | |
1423 | ||
1424 | if (!kpc->max_gpios_level_type && (type & IRQ_TYPE_LEVEL_MASK)) | |
1425 | type = IRQ_TYPE_NONE; | |
1426 | ||
1427 | if (type & IRQ_TYPE_EDGE_BOTH) | |
1428 | irq_set_handler_locked(data, handle_edge_irq); | |
1429 | else if (type & IRQ_TYPE_LEVEL_MASK) | |
1430 | irq_set_handler_locked(data, handle_level_irq); | |
1431 | else | |
1432 | return -EINVAL; | |
1433 | ||
1434 | return 0; | |
1435 | } | |
1436 | ||
1437 | static int keembay_gpio_add_pin_ranges(struct gpio_chip *chip) | |
1438 | { | |
1439 | struct keembay_pinctrl *kpc = gpiochip_get_data(chip); | |
1440 | int ret; | |
1441 | ||
1442 | ret = gpiochip_add_pin_range(chip, dev_name(kpc->dev), 0, 0, chip->ngpio); | |
1443 | if (ret) | |
1444 | dev_err_probe(kpc->dev, ret, "failed to add GPIO pin range\n"); | |
1445 | return ret; | |
1446 | } | |
1447 | ||
1448 | static struct irq_chip keembay_gpio_irqchip = { | |
1449 | .name = "keembay-gpio", | |
1450 | .irq_enable = keembay_gpio_irq_enable, | |
1451 | .irq_disable = keembay_gpio_irq_disable, | |
1452 | .irq_set_type = keembay_gpio_irq_set_type, | |
1453 | .irq_ack = keembay_gpio_irq_ack, | |
1454 | }; | |
1455 | ||
1456 | static int keembay_gpiochip_probe(struct keembay_pinctrl *kpc, | |
1457 | struct platform_device *pdev) | |
1458 | { | |
1459 | unsigned int i, level_line = 0, edge_line = 0; | |
1460 | struct gpio_chip *gc = &kpc->chip; | |
1461 | struct gpio_irq_chip *girq; | |
1462 | ||
1463 | /* Setup GPIO IRQ chip */ | |
1464 | girq = &kpc->chip.irq; | |
1465 | girq->chip = &keembay_gpio_irqchip; | |
1466 | girq->parent_handler = keembay_gpio_irq_handler; | |
1467 | girq->num_parents = KEEMBAY_GPIO_NUM_IRQ; | |
1468 | girq->parents = devm_kcalloc(kpc->dev, girq->num_parents, | |
1469 | sizeof(*girq->parents), GFP_KERNEL); | |
1470 | ||
1471 | if (!girq->parents) | |
1472 | return -ENOMEM; | |
1473 | ||
1474 | /* Setup GPIO chip */ | |
1475 | gc->label = dev_name(kpc->dev); | |
1476 | gc->parent = kpc->dev; | |
1477 | gc->request = gpiochip_generic_request; | |
1478 | gc->free = gpiochip_generic_free; | |
1479 | gc->get_direction = keembay_gpio_get_direction; | |
1480 | gc->direction_input = keembay_gpio_set_direction_in; | |
1481 | gc->direction_output = keembay_gpio_set_direction_out; | |
1482 | gc->get = keembay_gpio_get; | |
1483 | gc->set = keembay_gpio_set; | |
1484 | gc->set_config = gpiochip_generic_config; | |
1485 | gc->base = -1; | |
1486 | gc->ngpio = kpc->npins; | |
1487 | gc->add_pin_ranges = keembay_gpio_add_pin_ranges; | |
1488 | ||
1489 | for (i = 0; i < KEEMBAY_GPIO_NUM_IRQ; i++) { | |
1490 | struct keembay_gpio_irq *kmb_irq = &kpc->irq[i]; | |
1491 | int irq; | |
1492 | ||
1493 | irq = platform_get_irq_optional(pdev, i); | |
1494 | if (irq <= 0) | |
1495 | continue; | |
1496 | ||
1497 | girq->parents[i] = irq; | |
1498 | kmb_irq->line = girq->parents[i]; | |
1499 | kmb_irq->source = i; | |
1500 | kmb_irq->trigger = irq_get_trigger_type(girq->parents[i]); | |
1501 | kmb_irq->num_share = 0; | |
1502 | ||
1503 | if (kmb_irq->trigger == IRQ_TYPE_LEVEL_HIGH) | |
1504 | level_line++; | |
1505 | else | |
1506 | edge_line++; | |
1507 | } | |
1508 | ||
1509 | kpc->max_gpios_level_type = level_line * KEEMBAY_GPIO_MAX_PER_IRQ; | |
1510 | kpc->max_gpios_edge_type = edge_line * KEEMBAY_GPIO_MAX_PER_IRQ; | |
1511 | ||
1512 | girq->default_type = IRQ_TYPE_NONE; | |
1513 | girq->handler = handle_bad_irq; | |
1514 | ||
1515 | return devm_gpiochip_add_data(kpc->dev, gc, kpc); | |
1516 | } | |
1517 | ||
1518 | static int keembay_build_groups(struct keembay_pinctrl *kpc) | |
1519 | { | |
1520 | struct group_desc *grp; | |
1521 | unsigned int i; | |
1522 | ||
1523 | kpc->ngroups = kpc->npins; | |
1524 | grp = devm_kcalloc(kpc->dev, kpc->ngroups, sizeof(*grp), GFP_KERNEL); | |
1525 | if (!grp) | |
1526 | return -ENOMEM; | |
1527 | ||
1528 | /* Each pin is categorised as one group */ | |
1529 | for (i = 0; i < kpc->ngroups; i++) { | |
1530 | const struct pinctrl_pin_desc *pdesc = keembay_pins + i; | |
1531 | struct group_desc *kmb_grp = grp + i; | |
1532 | ||
1533 | kmb_grp->name = pdesc->name; | |
1534 | kmb_grp->pins = (int *)&pdesc->number; | |
1535 | pinctrl_generic_add_group(kpc->pctrl, kmb_grp->name, | |
1536 | kmb_grp->pins, 1, NULL); | |
1537 | } | |
1538 | ||
1539 | return 0; | |
1540 | } | |
1541 | ||
1542 | static int keembay_pinctrl_reg(struct keembay_pinctrl *kpc, struct device *dev) | |
1543 | { | |
1544 | int ret; | |
1545 | ||
1546 | keembay_pinctrl_desc.pins = keembay_pins; | |
1547 | ret = of_property_read_u32(dev->of_node, "ngpios", &kpc->npins); | |
1548 | if (ret < 0) | |
1549 | return ret; | |
1550 | keembay_pinctrl_desc.npins = kpc->npins; | |
1551 | ||
1552 | kpc->pctrl = devm_pinctrl_register(kpc->dev, &keembay_pinctrl_desc, kpc); | |
1553 | ||
1554 | return PTR_ERR_OR_ZERO(kpc->pctrl); | |
1555 | } | |
1556 | ||
1557 | static int keembay_add_functions(struct keembay_pinctrl *kpc, | |
c26c4bfc | 1558 | struct function_desc *functions) |
ffd4e739 LS |
1559 | { |
1560 | unsigned int i; | |
1561 | ||
1562 | /* Assign the groups for each function */ | |
c26c4bfc RM |
1563 | for (i = 0; i < kpc->nfuncs; i++) { |
1564 | struct function_desc *func = &functions[i]; | |
1565 | const char **group_names; | |
1566 | unsigned int grp_idx = 0; | |
1567 | int j; | |
1568 | ||
1569 | group_names = devm_kcalloc(kpc->dev, func->num_group_names, | |
1570 | sizeof(*group_names), GFP_KERNEL); | |
1571 | if (!group_names) | |
1572 | return -ENOMEM; | |
1573 | ||
1574 | for (j = 0; j < kpc->npins; j++) { | |
1575 | const struct pinctrl_pin_desc *pdesc = &keembay_pins[j]; | |
1576 | struct keembay_mux_desc *mux; | |
1577 | ||
1578 | for (mux = pdesc->drv_data; mux->name; mux++) { | |
1579 | if (!strcmp(mux->name, func->name)) | |
1580 | group_names[grp_idx++] = pdesc->name; | |
ffd4e739 | 1581 | } |
ffd4e739 | 1582 | } |
c26c4bfc RM |
1583 | |
1584 | func->group_names = group_names; | |
ffd4e739 LS |
1585 | } |
1586 | ||
1587 | /* Add all functions */ | |
1588 | for (i = 0; i < kpc->nfuncs; i++) { | |
1589 | pinmux_generic_add_function(kpc->pctrl, | |
c26c4bfc RM |
1590 | functions[i].name, |
1591 | functions[i].group_names, | |
1592 | functions[i].num_group_names, | |
1593 | functions[i].data); | |
ffd4e739 LS |
1594 | } |
1595 | ||
1596 | return 0; | |
1597 | } | |
1598 | ||
1599 | static int keembay_build_functions(struct keembay_pinctrl *kpc) | |
1600 | { | |
1601 | struct function_desc *keembay_funcs, *new_funcs; | |
1602 | int i; | |
1603 | ||
5d067499 RM |
1604 | /* |
1605 | * Allocate maximum possible number of functions. Assume every pin | |
1606 | * being part of 8 (hw maximum) globally unique muxes. | |
1607 | */ | |
ffd4e739 LS |
1608 | kpc->nfuncs = 0; |
1609 | keembay_funcs = kcalloc(kpc->npins * 8, sizeof(*keembay_funcs), GFP_KERNEL); | |
1610 | if (!keembay_funcs) | |
1611 | return -ENOMEM; | |
1612 | ||
5d067499 | 1613 | /* Setup 1 function for each unique mux */ |
ffd4e739 LS |
1614 | for (i = 0; i < kpc->npins; i++) { |
1615 | const struct pinctrl_pin_desc *pdesc = keembay_pins + i; | |
5d067499 | 1616 | struct keembay_mux_desc *mux; |
ffd4e739 | 1617 | |
5d067499 RM |
1618 | for (mux = pdesc->drv_data; mux->name; mux++) { |
1619 | struct function_desc *fdesc; | |
ffd4e739 | 1620 | |
5d067499 RM |
1621 | /* Check if we already have function for this mux */ |
1622 | for (fdesc = keembay_funcs; fdesc->name; fdesc++) { | |
ffd4e739 LS |
1623 | if (!strcmp(mux->name, fdesc->name)) { |
1624 | fdesc->num_group_names++; | |
1625 | break; | |
1626 | } | |
ffd4e739 LS |
1627 | } |
1628 | ||
5d067499 | 1629 | /* Setup new function for this mux we didn't see before */ |
ffd4e739 LS |
1630 | if (!fdesc->name) { |
1631 | fdesc->name = mux->name; | |
1632 | fdesc->num_group_names = 1; | |
1633 | fdesc->data = &mux->mode; | |
1634 | kpc->nfuncs++; | |
1635 | } | |
ffd4e739 LS |
1636 | } |
1637 | } | |
1638 | ||
1639 | /* Reallocate memory based on actual number of functions */ | |
1640 | new_funcs = krealloc(keembay_funcs, kpc->nfuncs * sizeof(*new_funcs), GFP_KERNEL); | |
1641 | if (!new_funcs) { | |
1642 | kfree(keembay_funcs); | |
1643 | return -ENOMEM; | |
1644 | } | |
1645 | ||
1646 | return keembay_add_functions(kpc, new_funcs); | |
1647 | } | |
1648 | ||
1649 | static const struct keembay_pin_soc keembay_data = { | |
1650 | .pins = keembay_pins, | |
1651 | }; | |
1652 | ||
1653 | static const struct of_device_id keembay_pinctrl_match[] = { | |
1654 | { .compatible = "intel,keembay-pinctrl", .data = &keembay_data }, | |
1655 | { } | |
1656 | }; | |
1657 | MODULE_DEVICE_TABLE(of, keembay_pinctrl_match); | |
1658 | ||
1659 | static int keembay_pinctrl_probe(struct platform_device *pdev) | |
1660 | { | |
1661 | struct device *dev = &pdev->dev; | |
1662 | struct keembay_pinctrl *kpc; | |
1663 | int ret; | |
1664 | ||
1665 | kpc = devm_kzalloc(dev, sizeof(*kpc), GFP_KERNEL); | |
1666 | if (!kpc) | |
1667 | return -ENOMEM; | |
1668 | ||
1669 | kpc->dev = dev; | |
1670 | kpc->soc = device_get_match_data(dev); | |
1671 | ||
1672 | kpc->base0 = devm_platform_ioremap_resource(pdev, 0); | |
1673 | if (IS_ERR(kpc->base0)) | |
1674 | return PTR_ERR(kpc->base0); | |
1675 | ||
1676 | kpc->base1 = devm_platform_ioremap_resource(pdev, 1); | |
1677 | if (IS_ERR(kpc->base1)) | |
1678 | return PTR_ERR(kpc->base1); | |
1679 | ||
1680 | raw_spin_lock_init(&kpc->lock); | |
1681 | ||
1682 | ret = keembay_pinctrl_reg(kpc, dev); | |
1683 | if (ret) | |
1684 | return ret; | |
1685 | ||
1686 | ret = keembay_build_groups(kpc); | |
1687 | if (ret) | |
1688 | return ret; | |
1689 | ||
1690 | ret = keembay_build_functions(kpc); | |
1691 | if (ret) | |
1692 | return ret; | |
1693 | ||
1694 | ret = keembay_gpiochip_probe(kpc, pdev); | |
1695 | if (ret) | |
1696 | return ret; | |
1697 | ||
1698 | platform_set_drvdata(pdev, kpc); | |
1699 | ||
1700 | return 0; | |
1701 | } | |
1702 | ||
1703 | static struct platform_driver keembay_pinctrl_driver = { | |
1704 | .probe = keembay_pinctrl_probe, | |
1705 | .driver = { | |
1706 | .name = "keembay-pinctrl", | |
1707 | .of_match_table = keembay_pinctrl_match, | |
1708 | }, | |
1709 | }; | |
1710 | module_platform_driver(keembay_pinctrl_driver); | |
1711 | ||
1712 | MODULE_AUTHOR("Muhammad Husaini Zulkifli <muhammad.husaini.zulkifli@intel.com>"); | |
1713 | MODULE_AUTHOR("Vijayakannan Ayyathurai <vijayakannan.ayyathurai@intel.com>"); | |
1714 | MODULE_AUTHOR("Lakshmi Sowjanya D <lakshmi.sowjanya.d@intel.com>"); | |
1715 | MODULE_DESCRIPTION("Intel Keem Bay SoC pinctrl/GPIO driver"); | |
1716 | MODULE_LICENSE("GPL"); |