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(addr: 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: 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, addr: 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: 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(base: 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, base: 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(base: kpc->base1 + KEEMBAY_GPIO_MODE, pin); |
905 | |
906 | val &= FIELD_PREP(KEEMBAY_GPIO_MODE_INV_MASK, 0); |
907 | keembay_write_reg(val, base: 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(base: 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, group_selector: grp_sel); |
940 | if (!grp) |
941 | return -EINVAL; |
942 | |
943 | func = pinmux_generic_get_function(pctldev, selector: 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(base: kpc->base1 + KEEMBAY_GPIO_MODE, pin); |
952 | val = u32_replace_bits(old: val, val: pin_mode, KEEMBAY_GPIO_MODE_SELECT_MASK); |
953 | keembay_write_reg(val, base: 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(base: 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(base: kpc->base1 + KEEMBAY_GPIO_MODE, pin); |
969 | |
970 | val = u32_replace_bits(old: val, val: pull, KEEMBAY_GPIO_MODE_PULLUP_MASK); |
971 | keembay_write_reg(val, base: 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(base: 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(base: 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(old: val, val: strength, KEEMBAY_GPIO_MODE_DRIVE_MASK); |
995 | keembay_write_reg(val, base: 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(base: 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(base: 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, base: 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(base: 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(base: 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, base: 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(config: *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, argument: 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, argument: 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(config: cfg[i]); |
1110 | arg = pinconf_to_config_argument(config: 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, schmitt_en: arg); |
1131 | break; |
1132 | |
1133 | case PIN_CONFIG_SLEW_RATE: |
1134 | ret = keembay_pinconf_set_slew_rate(kpc, pin, slew_rate: arg); |
1135 | break; |
1136 | |
1137 | case PIN_CONFIG_DRIVE_STRENGTH: |
1138 | ret = keembay_pinconf_set_drive(kpc, pin, drive: 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(base: 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(base: 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(base: kpc->base0 + KEEMBAY_GPIO_DATA_OUT, pin); |
1197 | if (val) |
1198 | keembay_write_gpio_reg(val: reg_val | BIT(pin % KEEMBAY_GPIO_MAX_PER_REG), |
1199 | base: kpc->base0 + KEEMBAY_GPIO_DATA_HIGH, pin); |
1200 | else |
1201 | keembay_write_gpio_reg(val: ~reg_val | BIT(pin % KEEMBAY_GPIO_MAX_PER_REG), |
1202 | base: 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(base: 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(base: kpc->base1 + KEEMBAY_GPIO_MODE, pin); |
1219 | val |= KEEMBAY_GPIO_MODE_DIR; |
1220 | keembay_write_reg(val, base: 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(base: kpc->base1 + KEEMBAY_GPIO_MODE, pin); |
1232 | val &= ~KEEMBAY_GPIO_MODE_DIR; |
1233 | keembay_write_reg(val, base: kpc->base1 + KEEMBAY_GPIO_MODE, pin); |
1234 | keembay_gpio_set(gc, pin, val: 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(chip: parent_chip, desc); |
1261 | reg = keembay_read_reg(base: kpc->base1 + KEEMBAY_GPIO_INT_CFG, pin: 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(base: kpc->base0 + KEEMBAY_GPIO_DATA_IN, pin); |
1271 | kmb_irq = irq_linear_revmap(domain: gc->irq.domain, hwirq: pin); |
1272 | |
1273 | /* Checks if the interrupt is enabled */ |
1274 | if (val && (clump & KEEMBAY_GPIO_IRQ_ENABLE)) |
1275 | generic_handle_irq(irq: kmb_irq); |
1276 | } |
1277 | chained_irq_exit(chip: 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(d: data); |
1284 | struct keembay_pinctrl *kpc = gpiochip_get_data(gc); |
1285 | unsigned long trig = irqd_get_trigger_type(d: 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(base: kpc->base1 + KEEMBAY_GPIO_INT_CFG, pin: src); |
1295 | |
1296 | bitmap_set_value8(map: &val, value: 0, start: pos); |
1297 | keembay_write_reg(val, base: kpc->base1 + KEEMBAY_GPIO_INT_CFG, pin: 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(base: kpc->base1 + KEEMBAY_GPIO_INT_CFG, pin: src); |
1314 | |
1315 | return bitmap_find_free_region(bitmap: &val, KEEMBAY_GPIO_MAX_PER_REG, order: 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(base: kpc->base1 + KEEMBAY_GPIO_INT_CFG, pin: 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(base: kpc->base1 + KEEMBAY_GPIO_INT_CFG, pin: src); |
1348 | bitmap_set_value8(map: ®, value: val, start: slot * 8); |
1349 | keembay_write_reg(val: reg, base: kpc->base1 + KEEMBAY_GPIO_INT_CFG, pin: 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(d: data); |
1365 | struct keembay_pinctrl *kpc = gpiochip_get_data(gc); |
1366 | unsigned int trig = irqd_get_trigger_type(d: data); |
1367 | irq_hw_number_t pin = irqd_to_hwirq(d: 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(d: data); |
1399 | struct keembay_pinctrl *kpc = gpiochip_get_data(gc); |
1400 | irq_hw_number_t pin = irqd_to_hwirq(d: 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(base: kpc->base1 + KEEMBAY_GPIO_INT_CFG, pin: 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(d: 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, handler: handle_edge_irq); |
1429 | else if (type & IRQ_TYPE_LEVEL_MASK) |
1430 | irq_set_handler_locked(data, handler: 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(gc: chip); |
1440 | int ret; |
1441 | |
1442 | ret = gpiochip_add_pin_range(gc: chip, pinctl_name: dev_name(dev: kpc->dev), gpio_offset: 0, pin_offset: 0, npins: chip->ngpio); |
1443 | if (ret) |
1444 | dev_err_probe(dev: kpc->dev, err: ret, fmt: "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(dev: kpc->dev, n: girq->num_parents, |
1469 | size: sizeof(*girq->parents), GFP_KERNEL); |
1470 | |
1471 | if (!girq->parents) |
1472 | return -ENOMEM; |
1473 | |
1474 | /* Setup GPIO chip */ |
1475 | gc->label = dev_name(dev: 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(irq: 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(dev: kpc->dev, n: kpc->ngroups, size: 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(pctldev: kpc->pctrl, name: kmb_grp->name, |
1536 | gpins: kmb_grp->pins, ngpins: 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(np: dev->of_node, propname: "ngpios" , out_value: &kpc->npins); |
1548 | if (ret < 0) |
1549 | return ret; |
1550 | keembay_pinctrl_desc.npins = kpc->npins; |
1551 | |
1552 | kpc->pctrl = devm_pinctrl_register(dev: kpc->dev, pctldesc: &keembay_pinctrl_desc, driver_data: kpc); |
1553 | |
1554 | return PTR_ERR_OR_ZERO(ptr: kpc->pctrl); |
1555 | } |
1556 | |
1557 | static int keembay_add_functions(struct keembay_pinctrl *kpc, |
1558 | struct function_desc *functions) |
1559 | { |
1560 | unsigned int i; |
1561 | |
1562 | /* Assign the groups for each function */ |
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(dev: kpc->dev, n: func->num_group_names, |
1570 | size: 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; |
1581 | } |
1582 | } |
1583 | |
1584 | func->group_names = group_names; |
1585 | } |
1586 | |
1587 | /* Add all functions */ |
1588 | for (i = 0; i < kpc->nfuncs; i++) { |
1589 | pinmux_generic_add_function(pctldev: kpc->pctrl, |
1590 | name: functions[i].name, |
1591 | groups: functions[i].group_names, |
1592 | num_groups: functions[i].num_group_names, |
1593 | data: functions[i].data); |
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 | |
1604 | /* |
1605 | * Allocate maximum possible number of functions. Assume every pin |
1606 | * being part of 8 (hw maximum) globally unique muxes. |
1607 | */ |
1608 | kpc->nfuncs = 0; |
1609 | keembay_funcs = kcalloc(n: kpc->npins * 8, size: sizeof(*keembay_funcs), GFP_KERNEL); |
1610 | if (!keembay_funcs) |
1611 | return -ENOMEM; |
1612 | |
1613 | /* Setup 1 function for each unique mux */ |
1614 | for (i = 0; i < kpc->npins; i++) { |
1615 | const struct pinctrl_pin_desc *pdesc = keembay_pins + i; |
1616 | struct keembay_mux_desc *mux; |
1617 | |
1618 | for (mux = pdesc->drv_data; mux->name; mux++) { |
1619 | struct function_desc *fdesc; |
1620 | |
1621 | /* Check if we already have function for this mux */ |
1622 | for (fdesc = keembay_funcs; fdesc->name; fdesc++) { |
1623 | if (!strcmp(mux->name, fdesc->name)) { |
1624 | fdesc->num_group_names++; |
1625 | break; |
1626 | } |
1627 | } |
1628 | |
1629 | /* Setup new function for this mux we didn't see before */ |
1630 | if (!fdesc->name) { |
1631 | fdesc->name = mux->name; |
1632 | fdesc->num_group_names = 1; |
1633 | fdesc->data = &mux->mode; |
1634 | kpc->nfuncs++; |
1635 | } |
1636 | } |
1637 | } |
1638 | |
1639 | /* Reallocate memory based on actual number of functions */ |
1640 | new_funcs = krealloc(objp: keembay_funcs, new_size: kpc->nfuncs * sizeof(*new_funcs), GFP_KERNEL); |
1641 | if (!new_funcs) { |
1642 | kfree(objp: keembay_funcs); |
1643 | return -ENOMEM; |
1644 | } |
1645 | |
1646 | return keembay_add_functions(kpc, functions: 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, size: 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, index: 0); |
1673 | if (IS_ERR(ptr: kpc->base0)) |
1674 | return PTR_ERR(ptr: kpc->base0); |
1675 | |
1676 | kpc->base1 = devm_platform_ioremap_resource(pdev, index: 1); |
1677 | if (IS_ERR(ptr: kpc->base1)) |
1678 | return PTR_ERR(ptr: 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, data: 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" ); |
1717 | |