1 /*
2  * Copyright (c) 2019 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT microchip_xec_gpio
8 
9 #include <errno.h>
10 #include <zephyr/device.h>
11 #include <zephyr/irq.h>
12 #include <zephyr/drivers/gpio.h>
13 #include <zephyr/sys/sys_io.h>
14 #include <soc.h>
15 
16 #include <zephyr/drivers/gpio/gpio_utils.h>
17 
18 #define XEC_GPIO_EDGE_DLY_COUNT		4
19 
20 #define GPIO_IN_BASE(config) \
21 	((__IO uint32_t *)(GPIO_PARIN_BASE + (config->port_num << 2)))
22 
23 #define GPIO_OUT_BASE(config) \
24 	((__IO uint32_t *)(GPIO_PAROUT_BASE + (config->port_num << 2)))
25 
26 static const uint32_t valid_ctrl_masks[NUM_MCHP_GPIO_PORTS] = {
27 	(MCHP_GPIO_PORT_A_BITMAP),
28 	(MCHP_GPIO_PORT_B_BITMAP),
29 	(MCHP_GPIO_PORT_C_BITMAP),
30 	(MCHP_GPIO_PORT_D_BITMAP),
31 	(MCHP_GPIO_PORT_E_BITMAP),
32 	(MCHP_GPIO_PORT_F_BITMAP)
33 };
34 
35 struct gpio_xec_data {
36 	/* gpio_driver_data needs to be first */
37 	struct gpio_driver_data common;
38 	/* port ISR callback routine address */
39 	sys_slist_t callbacks;
40 };
41 
42 struct gpio_xec_config {
43 	/* gpio_driver_config needs to be first */
44 	struct gpio_driver_config common;
45 	__IO uint32_t *pcr1_base;
46 	uint8_t girq_id;
47 	uint32_t port_num;
48 	uint32_t flags;
49 };
50 
51 /*
52  * notes: The GPIO parallel output bits are read-only until the
53  * Alternate-Output-Disable (AOD) bit is set in the pin's control
54  * register. To preload a parallel output value to prevent certain
55  * classes of glitching for output pins we must:
56  * Set GPIO control AOD=1 with the pin direction set to input.
57  * Program the new pin value in the respective GPIO parallel output
58  * register.
59  * Program other GPIO control bits except direction.
60  * Last step set the GPIO control register direction bit to output.
61  */
gpio_xec_configure(const struct device * dev,gpio_pin_t pin,gpio_flags_t flags)62 static int gpio_xec_configure(const struct device *dev,
63 			      gpio_pin_t pin, gpio_flags_t flags)
64 {
65 	const struct gpio_xec_config *config = dev->config;
66 	__IO uint32_t *current_pcr1;
67 	uint32_t pcr1 = 0U;
68 	uint32_t mask = 0U;
69 
70 	/* Validate pin number range in terms of current port */
71 	if ((valid_ctrl_masks[config->port_num] & BIT(pin)) == 0U) {
72 		return -EINVAL;
73 	}
74 
75 	/* Don't support "open source" mode */
76 	if (((flags & GPIO_SINGLE_ENDED) != 0U) &&
77 	    ((flags & GPIO_LINE_OPEN_DRAIN) == 0U)) {
78 		return -ENOTSUP;
79 	}
80 
81 	/* The flags contain options that require touching registers in the
82 	 * PCRs for a given GPIO. There are no GPIO modules in Microchip SOCs!
83 	 * Keep direction as input until last.
84 	 * Clear input pad disable allowing input pad to operate.
85 	 * Clear Power gate to allow pads to operate.
86 	 */
87 	mask |= MCHP_GPIO_CTRL_DIR_MASK;
88 	mask |= MCHP_GPIO_CTRL_INPAD_DIS_MASK;
89 	mask |= MCHP_GPIO_CTRL_PWRG_MASK;
90 	mask |= MCHP_GPIO_CTRL_AOD_MASK;
91 
92 	current_pcr1 = config->pcr1_base + pin;
93 
94 	if (flags == GPIO_DISCONNECTED) {
95 		pcr1 |= MCHP_GPIO_CTRL_PWRG_OFF;
96 		*current_pcr1 = (*current_pcr1 & ~mask) | pcr1;
97 		return 0;
98 	}
99 
100 	pcr1 = MCHP_GPIO_CTRL_PWRG_VTR_IO;
101 
102 	/* Always enable input pad */
103 	if (*current_pcr1 & BIT(MCHP_GPIO_CTRL_INPAD_DIS_POS)) {
104 		*current_pcr1 &= ~BIT(MCHP_GPIO_CTRL_INPAD_DIS_POS);
105 	}
106 
107 	/* Figure out the pullup/pulldown configuration and keep it in the
108 	 * pcr1 variable
109 	 */
110 	mask |= MCHP_GPIO_CTRL_PUD_MASK;
111 
112 	if ((flags & GPIO_PULL_UP) != 0U) {
113 		/* Enable the pull and select the pullup resistor. */
114 		pcr1 |= MCHP_GPIO_CTRL_PUD_PU;
115 	} else if ((flags & GPIO_PULL_DOWN) != 0U) {
116 		/* Enable the pull and select the pulldown resistor */
117 		pcr1 |= MCHP_GPIO_CTRL_PUD_PD;
118 	}
119 
120 	/* Push-pull or open drain */
121 	mask |= MCHP_GPIO_CTRL_BUFT_MASK;
122 
123 	if ((flags & GPIO_OPEN_DRAIN) != 0U) {
124 		/* Open drain */
125 		pcr1 |= MCHP_GPIO_CTRL_BUFT_OPENDRAIN;
126 	} else {
127 		/* Push-pull */
128 		pcr1 |= MCHP_GPIO_CTRL_BUFT_PUSHPULL;
129 	}
130 
131 	if ((flags & GPIO_OUTPUT) != 0U) {
132 		mask |= MCHP_GPIO_CTRL_OUTV_HI;
133 		if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0U) {
134 			pcr1 |= BIT(MCHP_GPIO_CTRL_OUTVAL_POS);
135 		} else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0U) {
136 			pcr1 &= ~BIT(MCHP_GPIO_CTRL_OUTVAL_POS);
137 		} else { /* Copy current input state to output state */
138 			if ((*current_pcr1 & MCHP_GPIO_CTRL_PWRG_MASK) ==
139 			     MCHP_GPIO_CTRL_PWRG_OFF) {
140 				*current_pcr1 = (*current_pcr1 &
141 						 ~MCHP_GPIO_CTRL_PWRG_MASK) |
142 						 MCHP_GPIO_CTRL_PWRG_VTR_IO;
143 			}
144 			if (*current_pcr1 & BIT(MCHP_GPIO_CTRL_INPAD_VAL_POS)) {
145 				pcr1 |= BIT(MCHP_GPIO_CTRL_OUTVAL_POS);
146 			} else {
147 				pcr1 &= ~BIT(MCHP_GPIO_CTRL_OUTVAL_POS);
148 			}
149 		}
150 
151 		pcr1 |= MCHP_GPIO_CTRL_DIR_OUTPUT;
152 	}
153 
154 	*current_pcr1 = (*current_pcr1 & ~mask) | pcr1;
155 	/* Control output bit becomes ready only and parallel output r/w */
156 	*current_pcr1 = *current_pcr1 | BIT(MCHP_GPIO_CTRL_AOD_POS);
157 
158 	return 0;
159 }
160 
gpio_xec_pin_interrupt_configure(const struct device * dev,gpio_pin_t pin,enum gpio_int_mode mode,enum gpio_int_trig trig)161 static int gpio_xec_pin_interrupt_configure(const struct device *dev,
162 					    gpio_pin_t pin,
163 					    enum gpio_int_mode mode,
164 					    enum gpio_int_trig trig)
165 {
166 	const struct gpio_xec_config *config = dev->config;
167 	__IO uint32_t *current_pcr1;
168 	uint32_t pcr1 = 0U;
169 	uint32_t mask = 0U;
170 	uint32_t gpio_interrupt = 0U;
171 
172 	/* Validate pin number range in terms of current port */
173 	if ((valid_ctrl_masks[config->port_num] & BIT(pin)) == 0U) {
174 		return -EINVAL;
175 	}
176 
177 	/* Check if GPIO port supports interrupts */
178 	if ((mode != GPIO_INT_MODE_DISABLED) &&
179 	    ((config->flags & GPIO_INT_ENABLE) == 0U)) {
180 		return -ENOTSUP;
181 	}
182 
183 	/* Disable interrupt in the EC aggregator */
184 	MCHP_GIRQ_ENCLR(config->girq_id) = BIT(pin);
185 
186 	/* Assemble mask for level/edge triggered interrupts */
187 	mask |= MCHP_GPIO_CTRL_IDET_MASK;
188 
189 	if (mode == GPIO_INT_MODE_DISABLED) {
190 		/* Explicitly disable interrupts, otherwise the configuration
191 		 * results in level triggered/low interrupts
192 		 */
193 		pcr1 |= MCHP_GPIO_CTRL_IDET_DISABLE;
194 	} else {
195 		if (mode == GPIO_INT_MODE_LEVEL) {
196 			/* Enable level interrupts */
197 			if (trig == GPIO_INT_TRIG_HIGH) {
198 				gpio_interrupt = MCHP_GPIO_CTRL_IDET_LVL_HI;
199 			} else {
200 				gpio_interrupt = MCHP_GPIO_CTRL_IDET_LVL_LO;
201 			}
202 		} else {
203 			/* Enable edge interrupts */
204 			switch (trig) {
205 			case GPIO_INT_TRIG_LOW:
206 				gpio_interrupt = MCHP_GPIO_CTRL_IDET_FEDGE;
207 				break;
208 			case GPIO_INT_TRIG_HIGH:
209 				gpio_interrupt = MCHP_GPIO_CTRL_IDET_REDGE;
210 				break;
211 			case GPIO_INT_TRIG_BOTH:
212 				gpio_interrupt = MCHP_GPIO_CTRL_IDET_BEDGE;
213 				break;
214 			default:
215 				return -EINVAL;
216 			}
217 		}
218 
219 		pcr1 |= gpio_interrupt;
220 	}
221 
222 	/* Now write contents of pcr1 variable to the PCR1 register that
223 	 * corresponds to the GPIO being configured
224 	 */
225 	current_pcr1 = config->pcr1_base + pin;
226 	*current_pcr1 = (*current_pcr1 & ~mask) | pcr1;
227 	/* delay for HW to synchronize after it ungates its clock */
228 	for (int i = 0; i < XEC_GPIO_EDGE_DLY_COUNT; i++) {
229 		(void)*current_pcr1;
230 	}
231 
232 	if (mode != GPIO_INT_MODE_DISABLED) {
233 		/* We enable the interrupts in the EC aggregator so that the
234 		 * result can be forwarded to the ARM NVIC
235 		 */
236 		MCHP_GIRQ_SRC_CLR(config->girq_id, pin);
237 		MCHP_GIRQ_ENSET(config->girq_id) = BIT(pin);
238 	}
239 
240 	return 0;
241 }
242 
gpio_xec_port_set_masked_raw(const struct device * dev,uint32_t mask,uint32_t value)243 static int gpio_xec_port_set_masked_raw(const struct device *dev,
244 					uint32_t mask,
245 					uint32_t value)
246 {
247 	const struct gpio_xec_config *config = dev->config;
248 
249 	/* GPIO output registers are used for writing */
250 	__IO uint32_t *gpio_base = GPIO_OUT_BASE(config);
251 
252 	*gpio_base = (*gpio_base & ~mask) | (mask & value);
253 
254 	return 0;
255 }
256 
gpio_xec_port_set_bits_raw(const struct device * dev,uint32_t mask)257 static int gpio_xec_port_set_bits_raw(const struct device *dev, uint32_t mask)
258 {
259 	const struct gpio_xec_config *config = dev->config;
260 
261 	/* GPIO output registers are used for writing */
262 	__IO uint32_t *gpio_base = GPIO_OUT_BASE(config);
263 
264 	*gpio_base |= mask;
265 
266 	return 0;
267 }
268 
gpio_xec_port_clear_bits_raw(const struct device * dev,uint32_t mask)269 static int gpio_xec_port_clear_bits_raw(const struct device *dev,
270 					uint32_t mask)
271 {
272 	const struct gpio_xec_config *config = dev->config;
273 
274 	/* GPIO output registers are used for writing */
275 	__IO uint32_t *gpio_base = GPIO_OUT_BASE(config);
276 
277 	*gpio_base &= ~mask;
278 
279 	return 0;
280 }
281 
gpio_xec_port_toggle_bits(const struct device * dev,uint32_t mask)282 static int gpio_xec_port_toggle_bits(const struct device *dev, uint32_t mask)
283 {
284 	const struct gpio_xec_config *config = dev->config;
285 
286 	/* GPIO output registers are used for writing */
287 	__IO uint32_t *gpio_base = GPIO_OUT_BASE(config);
288 
289 	*gpio_base ^= mask;
290 
291 	return 0;
292 }
293 
gpio_xec_port_get_raw(const struct device * dev,uint32_t * value)294 static int gpio_xec_port_get_raw(const struct device *dev, uint32_t *value)
295 {
296 	const struct gpio_xec_config *config = dev->config;
297 
298 	/* GPIO input registers are used for reading */
299 	__IO uint32_t *gpio_base = GPIO_IN_BASE(config);
300 
301 	*value = *gpio_base;
302 
303 	return 0;
304 }
305 
gpio_xec_manage_callback(const struct device * dev,struct gpio_callback * callback,bool set)306 static int gpio_xec_manage_callback(const struct device *dev,
307 				    struct gpio_callback *callback, bool set)
308 {
309 	struct gpio_xec_data *data = dev->data;
310 
311 	gpio_manage_callback(&data->callbacks, callback, set);
312 
313 	return 0;
314 }
315 
gpio_gpio_xec_port_isr(const struct device * dev)316 static void gpio_gpio_xec_port_isr(const struct device *dev)
317 {
318 	const struct gpio_xec_config *config = dev->config;
319 	struct gpio_xec_data *data = dev->data;
320 	uint32_t girq_result;
321 
322 	/* Figure out which interrupts have been triggered from the EC
323 	 * aggregator result register
324 	 */
325 	girq_result = MCHP_GIRQ_RESULT(config->girq_id);
326 
327 	/* Clear source register in aggregator before firing callbacks */
328 	REG32(MCHP_GIRQ_SRC_ADDR(config->girq_id)) = girq_result;
329 
330 	gpio_fire_callbacks(&data->callbacks, dev, girq_result);
331 }
332 
333 static const struct gpio_driver_api gpio_xec_driver_api = {
334 	.pin_configure = gpio_xec_configure,
335 	.port_get_raw = gpio_xec_port_get_raw,
336 	.port_set_masked_raw = gpio_xec_port_set_masked_raw,
337 	.port_set_bits_raw = gpio_xec_port_set_bits_raw,
338 	.port_clear_bits_raw = gpio_xec_port_clear_bits_raw,
339 	.port_toggle_bits = gpio_xec_port_toggle_bits,
340 	.pin_interrupt_configure = gpio_xec_pin_interrupt_configure,
341 	.manage_callback = gpio_xec_manage_callback,
342 };
343 
344 #if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio_000_036), okay)
345 static int gpio_xec_port000_036_init(const struct device *dev);
346 
347 static const struct gpio_xec_config gpio_xec_port000_036_config = {
348 	.common = {
349 		.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_NODE(
350 			DT_NODELABEL(gpio_000_036)),
351 	},
352 	.pcr1_base = (uint32_t *) DT_REG_ADDR(DT_NODELABEL(gpio_000_036)),
353 	.port_num = MCHP_GPIO_000_036,
354 #if DT_IRQ_HAS_CELL(DT_NODELABEL(gpio_000_036), irq)
355 	.girq_id = MCHP_GIRQ11_ID,
356 	.flags = GPIO_INT_ENABLE,
357 #else
358 	.flags = 0,
359 #endif
360 };
361 
362 static struct gpio_xec_data gpio_xec_port000_036_data;
363 
364 DEVICE_DT_DEFINE(DT_NODELABEL(gpio_000_036),
365 		    gpio_xec_port000_036_init,
366 		    NULL,
367 		    &gpio_xec_port000_036_data, &gpio_xec_port000_036_config,
368 		    PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY,
369 		    &gpio_xec_driver_api);
370 
gpio_xec_port000_036_init(const struct device * dev)371 static int gpio_xec_port000_036_init(const struct device *dev)
372 {
373 #if DT_IRQ_HAS_CELL(DT_NODELABEL(gpio_000_036), irq)
374 	const struct gpio_xec_config *config = dev->config;
375 
376 	/* Turn on the block enable in the EC aggregator */
377 	MCHP_GIRQ_BLK_SETEN(config->girq_id);
378 
379 	IRQ_CONNECT(DT_IRQ(DT_NODELABEL(gpio_000_036), irq),
380 		    DT_IRQ(DT_NODELABEL(gpio_000_036), priority),
381 		    gpio_gpio_xec_port_isr,
382 		    DEVICE_DT_GET(DT_NODELABEL(gpio_000_036)), 0U);
383 
384 	irq_enable(DT_IRQ(DT_NODELABEL(gpio_000_036), irq));
385 #endif
386 	return 0;
387 }
388 #endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpio_000_036), okay) */
389 
390 #if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio_040_076), okay)
391 static int gpio_xec_port040_076_init(const struct device *dev);
392 
393 static const struct gpio_xec_config gpio_xec_port040_076_config = {
394 	.common = {
395 		.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_NODE(
396 			DT_NODELABEL(gpio_040_076)),
397 	},
398 	.pcr1_base = (uint32_t *) DT_REG_ADDR(DT_NODELABEL(gpio_040_076)),
399 	.port_num = MCHP_GPIO_040_076,
400 #if DT_IRQ_HAS_CELL(DT_NODELABEL(gpio_040_076), irq)
401 	.girq_id = MCHP_GIRQ10_ID,
402 	.flags = GPIO_INT_ENABLE,
403 #else
404 	.flags = 0,
405 #endif
406 };
407 
408 static struct gpio_xec_data gpio_xec_port040_076_data;
409 
410 DEVICE_DT_DEFINE(DT_NODELABEL(gpio_040_076),
411 		    gpio_xec_port040_076_init,
412 		    NULL,
413 		    &gpio_xec_port040_076_data, &gpio_xec_port040_076_config,
414 		    PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY,
415 		    &gpio_xec_driver_api);
416 
gpio_xec_port040_076_init(const struct device * dev)417 static int gpio_xec_port040_076_init(const struct device *dev)
418 {
419 #if DT_IRQ_HAS_CELL(DT_NODELABEL(gpio_040_076), irq)
420 	const struct gpio_xec_config *config = dev->config;
421 
422 	/* Turn on the block enable in the EC aggregator */
423 	MCHP_GIRQ_BLK_SETEN(config->girq_id);
424 
425 	IRQ_CONNECT(DT_IRQ(DT_NODELABEL(gpio_040_076), irq),
426 		    DT_IRQ(DT_NODELABEL(gpio_040_076), priority),
427 		    gpio_gpio_xec_port_isr,
428 		    DEVICE_DT_GET(DT_NODELABEL(gpio_040_076)), 0U);
429 
430 	irq_enable(DT_IRQ(DT_NODELABEL(gpio_040_076), irq));
431 #endif
432 	return 0;
433 }
434 #endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpio_040_076), okay) */
435 
436 #if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio_100_136), okay)
437 static int gpio_xec_port100_136_init(const struct device *dev);
438 
439 static const struct gpio_xec_config gpio_xec_port100_136_config = {
440 	.common = {
441 		.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_NODE(
442 			DT_NODELABEL(gpio_100_136)),
443 	},
444 	.pcr1_base = (uint32_t *) DT_REG_ADDR(DT_NODELABEL(gpio_100_136)),
445 	.port_num = MCHP_GPIO_100_136,
446 #if DT_IRQ_HAS_CELL(DT_NODELABEL(gpio_100_136), irq)
447 	.girq_id = MCHP_GIRQ09_ID,
448 	.flags = GPIO_INT_ENABLE,
449 #else
450 	.flags = 0,
451 #endif
452 };
453 
454 static struct gpio_xec_data gpio_xec_port100_136_data;
455 
456 DEVICE_DT_DEFINE(DT_NODELABEL(gpio_100_136),
457 		    gpio_xec_port100_136_init,
458 		    NULL,
459 		    &gpio_xec_port100_136_data, &gpio_xec_port100_136_config,
460 		    PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY,
461 		    &gpio_xec_driver_api);
462 
gpio_xec_port100_136_init(const struct device * dev)463 static int gpio_xec_port100_136_init(const struct device *dev)
464 {
465 #if DT_IRQ_HAS_CELL(DT_NODELABEL(gpio_100_136), irq)
466 	const struct gpio_xec_config *config = dev->config;
467 
468 	/* Turn on the block enable in the EC aggregator */
469 	MCHP_GIRQ_BLK_SETEN(config->girq_id);
470 
471 	IRQ_CONNECT(DT_IRQ(DT_NODELABEL(gpio_100_136), irq),
472 		    DT_IRQ(DT_NODELABEL(gpio_100_136), priority),
473 		    gpio_gpio_xec_port_isr,
474 		    DEVICE_DT_GET(DT_NODELABEL(gpio_100_136)), 0U);
475 
476 	irq_enable(DT_IRQ(DT_NODELABEL(gpio_100_136), irq));
477 #endif
478 	return 0;
479 }
480 #endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpio_100_136), okay) */
481 
482 #if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio_140_176), okay)
483 static int gpio_xec_port140_176_init(const struct device *dev);
484 
485 static const struct gpio_xec_config gpio_xec_port140_176_config = {
486 	.common = {
487 		.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_NODE(
488 			DT_NODELABEL(gpio_140_176)),
489 	},
490 	.pcr1_base = (uint32_t *) DT_REG_ADDR(DT_NODELABEL(gpio_140_176)),
491 	.port_num = MCHP_GPIO_140_176,
492 #if DT_IRQ_HAS_CELL(DT_NODELABEL(gpio_140_176), irq)
493 	.girq_id = MCHP_GIRQ08_ID,
494 	.flags = GPIO_INT_ENABLE,
495 #else
496 	.flags = 0,
497 #endif
498 };
499 
500 static struct gpio_xec_data gpio_xec_port140_176_data;
501 
502 DEVICE_DT_DEFINE(DT_NODELABEL(gpio_140_176),
503 		    gpio_xec_port140_176_init,
504 		    NULL,
505 		    &gpio_xec_port140_176_data, &gpio_xec_port140_176_config,
506 		    PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY,
507 		    &gpio_xec_driver_api);
508 
gpio_xec_port140_176_init(const struct device * dev)509 static int gpio_xec_port140_176_init(const struct device *dev)
510 {
511 #if DT_IRQ_HAS_CELL(DT_NODELABEL(gpio_140_176), irq)
512 	const struct gpio_xec_config *config = dev->config;
513 
514 	/* Turn on the block enable in the EC aggregator */
515 	MCHP_GIRQ_BLK_SETEN(config->girq_id);
516 
517 	IRQ_CONNECT(DT_IRQ(DT_NODELABEL(gpio_140_176), irq),
518 		    DT_IRQ(DT_NODELABEL(gpio_140_176), priority),
519 		    gpio_gpio_xec_port_isr,
520 		    DEVICE_DT_GET(DT_NODELABEL(gpio_140_176)), 0U);
521 
522 	irq_enable(DT_IRQ(DT_NODELABEL(gpio_140_176), irq));
523 #endif
524 	return 0;
525 }
526 #endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpio_140_176), okay) */
527 
528 #if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio_200_236), okay)
529 static int gpio_xec_port200_236_init(const struct device *dev);
530 
531 static const struct gpio_xec_config gpio_xec_port200_236_config = {
532 	.common = {
533 		.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_NODE(
534 			DT_NODELABEL(gpio_200_236)),
535 	},
536 	.pcr1_base = (uint32_t *) DT_REG_ADDR(DT_NODELABEL(gpio_200_236)),
537 	.port_num = MCHP_GPIO_200_236,
538 #if DT_IRQ_HAS_CELL(DT_NODELABEL(gpio_200_236), irq)
539 	.girq_id = MCHP_GIRQ12_ID,
540 	.flags = GPIO_INT_ENABLE,
541 #else
542 	.flags = 0,
543 #endif
544 };
545 
546 static struct gpio_xec_data gpio_xec_port200_236_data;
547 
548 DEVICE_DT_DEFINE(DT_NODELABEL(gpio_200_236),
549 		    gpio_xec_port200_236_init,
550 		    NULL,
551 		    &gpio_xec_port200_236_data, &gpio_xec_port200_236_config,
552 		    PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY,
553 		    &gpio_xec_driver_api);
554 
gpio_xec_port200_236_init(const struct device * dev)555 static int gpio_xec_port200_236_init(const struct device *dev)
556 {
557 #if DT_IRQ_HAS_CELL(DT_NODELABEL(gpio_200_236), irq)
558 	const struct gpio_xec_config *config = dev->config;
559 
560 	/* Turn on the block enable in the EC aggregator */
561 	MCHP_GIRQ_BLK_SETEN(config->girq_id);
562 
563 	IRQ_CONNECT(DT_IRQ(DT_NODELABEL(gpio_200_236), irq),
564 		    DT_IRQ(DT_NODELABEL(gpio_200_236), priority),
565 		    gpio_gpio_xec_port_isr,
566 		    DEVICE_DT_GET(DT_NODELABEL(gpio_200_236)), 0U);
567 
568 	irq_enable(DT_IRQ(DT_NODELABEL(gpio_200_236), irq));
569 #endif
570 	return 0;
571 }
572 #endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpio_200_236), okay) */
573 
574 #if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio_240_276), okay)
575 static int gpio_xec_port240_276_init(const struct device *dev);
576 
577 static const struct gpio_xec_config gpio_xec_port240_276_config = {
578 	.common = {
579 		.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_NODE(
580 			DT_NODELABEL(gpio_240_276)),
581 	},
582 	.pcr1_base = (uint32_t *) DT_REG_ADDR(DT_NODELABEL(gpio_240_276)),
583 	.port_num = MCHP_GPIO_240_276,
584 #if DT_IRQ_HAS_CELL(DT_NODELABEL(gpio_240_276), irq)
585 	.girq_id = MCHP_GIRQ26_ID,
586 	.flags = GPIO_INT_ENABLE,
587 #else
588 	.flags = 0,
589 #endif
590 };
591 
592 static struct gpio_xec_data gpio_xec_port240_276_data;
593 
594 DEVICE_DT_DEFINE(DT_NODELABEL(gpio_240_276),
595 		    gpio_xec_port240_276_init,
596 		    NULL,
597 		    &gpio_xec_port240_276_data, &gpio_xec_port240_276_config,
598 		    PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY,
599 		    &gpio_xec_driver_api);
600 
gpio_xec_port240_276_init(const struct device * dev)601 static int gpio_xec_port240_276_init(const struct device *dev)
602 {
603 #if DT_IRQ_HAS_CELL(DT_NODELABEL(gpio_240_276), irq)
604 	const struct gpio_xec_config *config = dev->config;
605 
606 	/* Turn on the block enable in the EC aggregator */
607 	MCHP_GIRQ_BLK_SETEN(config->girq_id);
608 
609 	IRQ_CONNECT(DT_IRQ(DT_NODELABEL(gpio_240_276), irq),
610 		    DT_IRQ(DT_NODELABEL(gpio_240_276), priority),
611 		    gpio_gpio_xec_port_isr,
612 		    DEVICE_DT_GET(DT_NODELABEL(gpio_240_276)), 0U);
613 
614 	irq_enable(DT_IRQ(DT_NODELABEL(gpio_240_276), irq));
615 #endif
616 	return 0;
617 }
618 #endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(gpio_240_276), okay) */
619