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