1 /*
2  * Copyright (c) 2020 Friedt Professional Engineering Services, Inc
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT zephyr_gpio_emul
8 
9 #include <zephyr/device.h>
10 #include <zephyr/drivers/gpio.h>
11 #include <zephyr/drivers/gpio/gpio_emul.h>
12 #include <errno.h>
13 #include <zephyr/kernel.h>
14 #include <zephyr/pm/device.h>
15 
16 #include <zephyr/drivers/gpio/gpio_utils.h>
17 
18 #define LOG_LEVEL CONFIG_GPIO_LOG_LEVEL
19 #include <zephyr/logging/log.h>
20 LOG_MODULE_REGISTER(gpio_emul);
21 
22 #define GPIO_EMUL_INT_BITMASK						\
23 	(GPIO_INT_DISABLE | GPIO_INT_ENABLE | GPIO_INT_LEVELS_LOGICAL |	\
24 	 GPIO_INT_EDGE | GPIO_INT_LOW_0 | GPIO_INT_HIGH_1)
25 
26 /**
27  * @brief GPIO Emulator interrupt capabilities
28  *
29  * These enumerations are used as a bitmask and allow the GPIO Emulator to
30  * model GPIO interrupt controllers with varying interrupt trigger support.
31  *
32  * For example, some controllers to not support level interrupts,
33  * some controllers do not support rising and falling edge simultaneously,
34  * etc.
35  *
36  * This primarily affects the behaviour of @ref gpio_pin_interrupt_configure.
37  */
38 enum gpio_emul_interrupt_cap {
39 	GPIO_EMUL_INT_CAP_EDGE_RISING = 1,
40 	GPIO_EMUL_INT_CAP_EDGE_FALLING = 2,
41 	GPIO_EMUL_INT_CAP_LEVEL_HIGH = 16,
42 	GPIO_EMUL_INT_CAP_LEVEL_LOW = 32,
43 };
44 
45 /**
46  * @brief Emulated GPIO controller configuration data
47  *
48  * This structure contains all of the state for a given emulated GPIO
49  * controller as well as all of the pins associated with it.
50  *
51  * The @a flags member is a pointer to an array which is @a num_pins in size.
52  *
53  * @a num_pins must be in the range [1, @ref GPIO_MAX_PINS_PER_PORT].
54  *
55  * Pin direction as well as other pin properties are set using
56  * specific bits in @a flags. For more details, see @ref gpio_interface.
57  *
58  * Changes are synchronized using @ref gpio_emul_data.mu.
59  */
60 struct gpio_emul_config {
61 	/** Common @ref gpio_driver_config */
62 	const struct gpio_driver_config common;
63 	/** Number of pins available in the given GPIO controller instance */
64 	const gpio_pin_t num_pins;
65 	/** Supported interrupts */
66 	const enum gpio_emul_interrupt_cap interrupt_caps;
67 };
68 
69 /**
70  * @brief Emulated GPIO controller data
71  *
72  * This structure contains data structures used by a emulated GPIO
73  * controller.
74  *
75  * If the application wishes to specify a "wiring" for the emulated
76  * GPIO, then a @ref gpio_callback_handler_t should be registered using
77  * @ref gpio_add_callback.
78  *
79  * Changes are to @ref gpio_emul_data and @ref gpio_emul_config are
80  * synchronized using @a k_spinlock.
81  */
82 struct gpio_emul_data {
83 	/** Common @ref gpio_driver_data */
84 	struct gpio_driver_data common;
85 	/** Pointer to an array of flags is @a num_pins in size */
86 	gpio_flags_t *flags;
87 	/** Input values for each pin */
88 	gpio_port_value_t input_vals;
89 	/** Output values for each pin */
90 	gpio_port_value_t output_vals;
91 	/** Interrupt status for each pin */
92 	gpio_port_pins_t interrupts;
93 	/** Spinlock to synchronize accesses to driver data and config */
94 	struct k_spinlock lock;
95 	/** Is interrupt enabled for each pin */
96 	gpio_port_pins_t enabled_interrupts;
97 	/** Singly-linked list of callbacks associated with the controller */
98 	sys_slist_t callbacks;
99 };
100 
101 /**
102  * @brief Obtain a mask of pins that match all of the provided @p flags
103  *
104  * Use this function to see which pins match the current GPIO configuration.
105  *
106  * The caller must ensure that @ref gpio_emul_data.lock is locked.
107  *
108  * @param port The emulated GPIO device pointer
109  * @param mask A mask of flags to match
110  * @param flags The flags to match
111  *
112  * @return a mask of the pins with matching @p flags
113  */
114 static gpio_port_pins_t
get_pins_with_flags(const struct device * port,gpio_port_pins_t mask,gpio_flags_t flags)115 get_pins_with_flags(const struct device *port, gpio_port_pins_t mask,
116 	gpio_flags_t flags)
117 {
118 	size_t i;
119 	gpio_port_pins_t matched = 0;
120 	struct gpio_emul_data *drv_data =
121 		(struct gpio_emul_data *)port->data;
122 	const struct gpio_emul_config *config =
123 		(const struct gpio_emul_config *)port->config;
124 
125 	for (i = 0; i < config->num_pins; ++i) {
126 		if ((drv_data->flags[i] & mask) == flags) {
127 			matched |= BIT(i);
128 		}
129 	}
130 
131 	return matched;
132 }
133 
134 /**
135  * @brief Obtain a mask of pins that are configured as @ref GPIO_INPUT
136  *
137  * The caller must ensure that @ref gpio_emul_data.lock is locked.
138  *
139  * @param port The emulated GPIO device pointer
140  *
141  * @return a mask of pins that are configured as @ref GPIO_INPUT
142  */
get_input_pins(const struct device * port)143 static inline gpio_port_pins_t get_input_pins(const struct device *port)
144 {
145 	return get_pins_with_flags(port, GPIO_INPUT, GPIO_INPUT);
146 }
147 
148 /**
149  * @brief Obtain a mask of pins that are configured as @ref GPIO_OUTPUT
150  *
151  * The caller must ensure that @ref gpio_emul_data.lock is locked.
152  *
153  * @param port The emulated GPIO device pointer
154  *
155  * @return a mask of pins that are configured as @ref GPIO_OUTPUT
156  */
get_output_pins(const struct device * port)157 static inline gpio_port_pins_t get_output_pins(const struct device *port)
158 {
159 	return get_pins_with_flags(port, GPIO_OUTPUT, GPIO_OUTPUT);
160 }
161 
162 /**
163  * Check if @p port has capabilities specified in @p caps
164  *
165  * @param port The emulated GPIO device pointer
166  * @param caps A bitmask of @ref gpio_emul_interrupt_cap
167  *
168  * @return true if all @p caps are present, otherwise false
169  */
gpio_emul_config_has_caps(const struct device * port,int caps)170 static inline bool gpio_emul_config_has_caps(const struct device *port,
171 		int caps) {
172 
173 	const struct gpio_emul_config *config =
174 		(const struct gpio_emul_config *)port->config;
175 
176 	return (caps & config->interrupt_caps) == caps;
177 }
178 
179 /*
180  * GPIO backend API (for setting input pin values)
181  */
gpio_emul_gen_interrupt_bits(const struct device * port,gpio_port_pins_t mask,gpio_port_value_t prev_values,gpio_port_value_t values,gpio_port_pins_t * interrupts,bool detect_edge)182 static void gpio_emul_gen_interrupt_bits(const struct device *port,
183 					gpio_port_pins_t mask,
184 					gpio_port_value_t prev_values,
185 					gpio_port_value_t values,
186 					gpio_port_pins_t *interrupts,
187 					bool detect_edge)
188 {
189 	size_t i;
190 	bool bit;
191 	bool prev_bit;
192 	struct gpio_emul_data *drv_data =
193 		(struct gpio_emul_data *)port->data;
194 	const struct gpio_emul_config *config =
195 		(const struct gpio_emul_config *)port->config;
196 
197 	for (i = 0, *interrupts = 0; mask && i < config->num_pins;
198 	     ++i, mask >>= 1, prev_values >>= 1, values >>= 1) {
199 		if ((mask & 1) == 0) {
200 			continue;
201 		}
202 
203 		prev_bit = ((prev_values & 1) != 0);
204 		bit = ((values & 1) != 0);
205 
206 		switch (drv_data->flags[i] & GPIO_EMUL_INT_BITMASK) {
207 		case GPIO_INT_EDGE_RISING:
208 			if (gpio_emul_config_has_caps(port, GPIO_EMUL_INT_CAP_EDGE_RISING)) {
209 				if (detect_edge && !prev_bit && bit) {
210 					drv_data->interrupts |= BIT(i);
211 					*interrupts |= (BIT(i) & drv_data->enabled_interrupts);
212 				}
213 			}
214 			break;
215 		case GPIO_INT_EDGE_FALLING:
216 			if (gpio_emul_config_has_caps(port, GPIO_EMUL_INT_CAP_EDGE_FALLING)) {
217 				if (detect_edge && prev_bit && !bit) {
218 					drv_data->interrupts |= BIT(i);
219 					*interrupts |= (BIT(i) & drv_data->enabled_interrupts);
220 				}
221 			}
222 			break;
223 		case GPIO_INT_EDGE_BOTH:
224 			if (gpio_emul_config_has_caps(port,
225 				GPIO_EMUL_INT_CAP_EDGE_RISING | GPIO_EMUL_INT_CAP_EDGE_FALLING)) {
226 				if (detect_edge && prev_bit != bit) {
227 					drv_data->interrupts |= BIT(i);
228 					*interrupts |= (BIT(i) & drv_data->enabled_interrupts);
229 				}
230 			}
231 			break;
232 		case GPIO_INT_LEVEL_LOW:
233 			if (gpio_emul_config_has_caps(port, GPIO_EMUL_INT_CAP_LEVEL_LOW)) {
234 				if (!bit) {
235 					drv_data->interrupts |= BIT(i);
236 					*interrupts |= (BIT(i) & drv_data->enabled_interrupts);
237 				}
238 			}
239 			break;
240 		case GPIO_INT_LEVEL_HIGH:
241 			if (gpio_emul_config_has_caps(port, GPIO_EMUL_INT_CAP_LEVEL_HIGH)) {
242 				if (bit) {
243 					drv_data->interrupts |= BIT(i);
244 					*interrupts |= (BIT(i) & drv_data->enabled_interrupts);
245 				}
246 			}
247 			break;
248 		case 0:
249 		case GPIO_INT_DISABLE:
250 			break;
251 		default:
252 			LOG_DBG("unhandled case %u",
253 				drv_data->flags[i] & GPIO_EMUL_INT_BITMASK);
254 			break;
255 		}
256 	}
257 }
258 
259 /**
260  * @brief Trigger possible interrupt events after an input pin has changed
261  *
262  * For more information, see @ref gpio_interface.
263  *
264  * The caller must ensure that @ref gpio_emul_data.lock is locked.
265  *
266  * @param port The emulated GPIO port
267  * @param mask The mask of pins that have changed
268  * @param prev_values Previous pin values
269  * @param values Current pin values
270  */
gpio_emul_pend_interrupt(const struct device * port,gpio_port_pins_t mask,gpio_port_value_t prev_values,gpio_port_value_t values)271 static void gpio_emul_pend_interrupt(const struct device *port, gpio_port_pins_t mask,
272 				    gpio_port_value_t prev_values,
273 				    gpio_port_value_t values)
274 {
275 	gpio_port_pins_t interrupts;
276 	struct gpio_emul_data *drv_data =
277 		(struct gpio_emul_data *)port->data;
278 	k_spinlock_key_t key;
279 
280 	key = k_spin_lock(&drv_data->lock);
281 	gpio_emul_gen_interrupt_bits(port, mask, prev_values, values,
282 		&interrupts, true);
283 	while (interrupts != 0) {
284 		k_spin_unlock(&drv_data->lock, key);
285 		gpio_fire_callbacks(&drv_data->callbacks, port, interrupts);
286 		key = k_spin_lock(&drv_data->lock);
287 		/* Clear handled interrupts */
288 		drv_data->interrupts &= ~interrupts;
289 		gpio_emul_gen_interrupt_bits(port, mask, prev_values, values,
290 			&interrupts, false);
291 	}
292 
293 	k_spin_unlock(&drv_data->lock, key);
294 }
295 
gpio_emul_input_set_masked_int(const struct device * port,gpio_port_pins_t mask,gpio_port_value_t values)296 int gpio_emul_input_set_masked_int(const struct device *port,
297 				   gpio_port_pins_t mask,
298 				   gpio_port_value_t values)
299 {
300 	gpio_port_pins_t input_mask;
301 	gpio_port_pins_t prev_values;
302 	struct gpio_emul_data *drv_data =
303 		(struct gpio_emul_data *)port->data;
304 	const struct gpio_emul_config *config =
305 		(const struct gpio_emul_config *)port->config;
306 
307 	if (mask == 0) {
308 		return 0;
309 	}
310 
311 	if (~config->common.port_pin_mask & mask) {
312 		LOG_ERR("Pin not supported port_pin_mask=%x mask=%x",
313 			config->common.port_pin_mask, mask);
314 		return -EINVAL;
315 	}
316 
317 	input_mask = get_input_pins(port);
318 	if (~input_mask & mask) {
319 		LOG_ERR("Not input pin input_mask=%x mask=%x", input_mask,
320 			mask);
321 		return -EINVAL;
322 	}
323 
324 	prev_values = drv_data->input_vals;
325 	drv_data->input_vals &= ~mask;
326 	drv_data->input_vals |= values & mask;
327 
328 	return 0;
329 }
330 
331 /* documented in drivers/gpio/gpio_emul.h */
gpio_emul_input_set_masked(const struct device * port,gpio_port_pins_t mask,gpio_port_value_t values)332 int gpio_emul_input_set_masked(const struct device *port, gpio_port_pins_t mask,
333 			      gpio_port_value_t values)
334 {
335 	struct gpio_emul_data *drv_data = (struct gpio_emul_data *)port->data;
336 	gpio_port_pins_t prev_input_values;
337 	gpio_port_pins_t input_values;
338 	k_spinlock_key_t key;
339 	int rv;
340 
341 	key = k_spin_lock(&drv_data->lock);
342 	prev_input_values = drv_data->input_vals;
343 	rv = gpio_emul_input_set_masked_int(port, mask, values);
344 	input_values = drv_data->input_vals;
345 	k_spin_unlock(&drv_data->lock, key);
346 	if (rv) {
347 		return rv;
348 	}
349 
350 	gpio_emul_pend_interrupt(port, mask, prev_input_values, input_values);
351 	return 0;
352 }
353 
354 /* documented in drivers/gpio/gpio_emul.h */
gpio_emul_output_get_masked(const struct device * port,gpio_port_pins_t mask,gpio_port_value_t * values)355 int gpio_emul_output_get_masked(const struct device *port, gpio_port_pins_t mask,
356 			       gpio_port_value_t *values)
357 {
358 	struct gpio_emul_data *drv_data =
359 		(struct gpio_emul_data *)port->data;
360 	const struct gpio_emul_config *config =
361 		(const struct gpio_emul_config *)port->config;
362 	k_spinlock_key_t key;
363 
364 	if (mask == 0) {
365 		return 0;
366 	}
367 
368 	if (~config->common.port_pin_mask & mask) {
369 		return -EINVAL;
370 	}
371 
372 	key = k_spin_lock(&drv_data->lock);
373 	*values = drv_data->output_vals & get_output_pins(port);
374 	k_spin_unlock(&drv_data->lock, key);
375 
376 	return 0;
377 }
378 
379 /* documented in drivers/gpio/gpio_emul.h */
gpio_emul_flags_get(const struct device * port,gpio_pin_t pin,gpio_flags_t * flags)380 int gpio_emul_flags_get(const struct device *port, gpio_pin_t pin, gpio_flags_t *flags)
381 {
382 	struct gpio_emul_data *drv_data =
383 		(struct gpio_emul_data *)port->data;
384 	const struct gpio_emul_config *config =
385 		(const struct gpio_emul_config *)port->config;
386 	k_spinlock_key_t key;
387 
388 	if (flags == NULL) {
389 		return -EINVAL;
390 	}
391 
392 	if ((config->common.port_pin_mask & BIT(pin)) == 0) {
393 		return -EINVAL;
394 	}
395 
396 	key = k_spin_lock(&drv_data->lock);
397 	*flags = drv_data->flags[pin];
398 	k_spin_unlock(&drv_data->lock, key);
399 
400 	return 0;
401 }
402 
403 /*
404  * GPIO Driver API
405  *
406  * API is documented at drivers/gpio.h
407  */
408 
gpio_emul_pin_configure(const struct device * port,gpio_pin_t pin,gpio_flags_t flags)409 static int gpio_emul_pin_configure(const struct device *port, gpio_pin_t pin,
410 				  gpio_flags_t flags)
411 {
412 	struct gpio_emul_data *drv_data =
413 		(struct gpio_emul_data *)port->data;
414 	const struct gpio_emul_config *config =
415 		(const struct gpio_emul_config *)port->config;
416 	k_spinlock_key_t key;
417 	int rv;
418 
419 	if (flags & GPIO_OPEN_DRAIN) {
420 		return -ENOTSUP;
421 	}
422 
423 	if (flags & GPIO_OPEN_SOURCE) {
424 		return -ENOTSUP;
425 	}
426 
427 	if ((config->common.port_pin_mask & BIT(pin)) == 0) {
428 		return -EINVAL;
429 	}
430 
431 	key = k_spin_lock(&drv_data->lock);
432 	drv_data->flags[pin] = flags;
433 	if (flags & GPIO_OUTPUT) {
434 		if (flags & GPIO_OUTPUT_INIT_LOW) {
435 			drv_data->output_vals &= ~BIT(pin);
436 			if (flags & GPIO_INPUT) {
437 				/* for push-pull mode to generate interrupts */
438 				rv = gpio_emul_input_set_masked_int(
439 					port, BIT(pin), drv_data->output_vals);
440 				__ASSERT_NO_MSG(rv == 0);
441 			}
442 		} else if (flags & GPIO_OUTPUT_INIT_HIGH) {
443 			drv_data->output_vals |= BIT(pin);
444 			if (flags & GPIO_INPUT) {
445 				/* for push-pull mode to generate interrupts */
446 				rv = gpio_emul_input_set_masked_int(
447 					port, BIT(pin), drv_data->output_vals);
448 				__ASSERT_NO_MSG(rv == 0);
449 			}
450 		}
451 	} else if (flags & GPIO_INPUT) {
452 		if (flags & GPIO_PULL_UP) {
453 			rv = gpio_emul_input_set_masked_int(port, BIT(pin), BIT(pin));
454 			__ASSERT_NO_MSG(rv == 0);
455 		} else if (flags & GPIO_PULL_DOWN) {
456 			rv = gpio_emul_input_set_masked_int(
457 				port, BIT(pin), 0);
458 			__ASSERT_NO_MSG(rv == 0);
459 		}
460 	}
461 
462 	k_spin_unlock(&drv_data->lock, key);
463 	gpio_fire_callbacks(&drv_data->callbacks, port, BIT(pin));
464 	/* GPIO pin configuration changed so clear the pending interrupt. */
465 	drv_data->interrupts &= ~((gpio_port_pins_t)BIT(pin));
466 
467 	return 0;
468 }
469 
470 #ifdef CONFIG_GPIO_GET_CONFIG
gpio_emul_pin_get_config(const struct device * port,gpio_pin_t pin,gpio_flags_t * out_flags)471 static int gpio_emul_pin_get_config(const struct device *port, gpio_pin_t pin,
472 				    gpio_flags_t *out_flags)
473 {
474 	struct gpio_emul_data *drv_data =
475 		(struct gpio_emul_data *)port->data;
476 	k_spinlock_key_t key;
477 
478 	key = k_spin_lock(&drv_data->lock);
479 
480 	*out_flags = drv_data->flags[pin] &
481 			~(GPIO_OUTPUT_INIT_LOW | GPIO_OUTPUT_INIT_HIGH
482 				| GPIO_OUTPUT_INIT_LOGICAL);
483 	if (drv_data->flags[pin] & GPIO_OUTPUT) {
484 		if (drv_data->output_vals & BIT(pin)) {
485 			*out_flags |= GPIO_OUTPUT_HIGH;
486 		} else {
487 			*out_flags |= GPIO_OUTPUT_LOW;
488 		}
489 	}
490 
491 	k_spin_unlock(&drv_data->lock, key);
492 
493 	return 0;
494 }
495 #endif
496 
gpio_emul_port_get_raw(const struct device * port,gpio_port_value_t * values)497 static int gpio_emul_port_get_raw(const struct device *port, gpio_port_value_t *values)
498 {
499 	struct gpio_emul_data *drv_data =
500 		(struct gpio_emul_data *)port->data;
501 	k_spinlock_key_t key;
502 
503 	if (values == NULL) {
504 		return -EINVAL;
505 	}
506 
507 	key = k_spin_lock(&drv_data->lock);
508 	*values = drv_data->input_vals & get_input_pins(port);
509 	k_spin_unlock(&drv_data->lock, key);
510 
511 	return 0;
512 }
513 
gpio_emul_port_set_masked_raw(const struct device * port,gpio_port_pins_t mask,gpio_port_value_t values)514 static int gpio_emul_port_set_masked_raw(const struct device *port,
515 					gpio_port_pins_t mask,
516 					gpio_port_value_t values)
517 {
518 	gpio_port_pins_t output_mask;
519 	gpio_port_pins_t prev_values;
520 	gpio_port_pins_t prev_input_values;
521 	gpio_port_pins_t input_values;
522 	gpio_port_pins_t input_mask;
523 	struct gpio_emul_data *drv_data =
524 		(struct gpio_emul_data *)port->data;
525 	k_spinlock_key_t key;
526 	int rv;
527 
528 	key = k_spin_lock(&drv_data->lock);
529 	output_mask = get_output_pins(port);
530 	mask &= output_mask;
531 	prev_values = drv_data->output_vals;
532 	prev_values &= output_mask;
533 	values &= mask;
534 	drv_data->output_vals &= ~mask;
535 	drv_data->output_vals |= values;
536 	/* in push-pull, set input values & fire interrupts */
537 	prev_input_values = drv_data->input_vals;
538 	input_mask = mask & get_input_pins(port);
539 	rv = gpio_emul_input_set_masked_int(port, input_mask,
540 		drv_data->output_vals);
541 	input_values = drv_data->input_vals;
542 	k_spin_unlock(&drv_data->lock, key);
543 	__ASSERT_NO_MSG(rv == 0);
544 	gpio_emul_pend_interrupt(port, input_mask, prev_input_values, input_values);
545 
546 	/* for output-wiring, so the user can take action based on output */
547 	if (prev_values ^ values) {
548 		gpio_fire_callbacks(&drv_data->callbacks, port, mask & ~get_input_pins(port));
549 	}
550 
551 	return 0;
552 }
553 
gpio_emul_port_set_bits_raw(const struct device * port,gpio_port_pins_t pins)554 static int gpio_emul_port_set_bits_raw(const struct device *port,
555 				      gpio_port_pins_t pins)
556 {
557 	struct gpio_emul_data *drv_data =
558 		(struct gpio_emul_data *)port->data;
559 	k_spinlock_key_t key;
560 	gpio_port_pins_t prev_input_values;
561 	gpio_port_pins_t input_values;
562 	gpio_port_pins_t input_mask;
563 	int rv;
564 
565 	key = k_spin_lock(&drv_data->lock);
566 	pins &= get_output_pins(port);
567 	drv_data->output_vals |= pins;
568 	prev_input_values = drv_data->input_vals;
569 	input_mask = pins & get_input_pins(port);
570 	rv = gpio_emul_input_set_masked_int(port, input_mask,
571 		drv_data->output_vals);
572 	input_values = drv_data->input_vals;
573 	k_spin_unlock(&drv_data->lock, key);
574 	__ASSERT_NO_MSG(rv == 0);
575 	gpio_emul_pend_interrupt(port, input_mask, prev_input_values, input_values);
576 	/* for output-wiring, so the user can take action based on output */
577 	gpio_fire_callbacks(&drv_data->callbacks, port, pins & ~get_input_pins(port));
578 
579 	return 0;
580 }
581 
gpio_emul_port_clear_bits_raw(const struct device * port,gpio_port_pins_t pins)582 static int gpio_emul_port_clear_bits_raw(const struct device *port,
583 					gpio_port_pins_t pins)
584 {
585 	struct gpio_emul_data *drv_data =
586 		(struct gpio_emul_data *)port->data;
587 	k_spinlock_key_t key;
588 	gpio_port_pins_t prev_input_values;
589 	gpio_port_pins_t input_values;
590 	gpio_port_pins_t input_mask;
591 	int rv;
592 
593 	key = k_spin_lock(&drv_data->lock);
594 	pins &= get_output_pins(port);
595 	drv_data->output_vals &= ~pins;
596 	prev_input_values = drv_data->input_vals;
597 	input_mask = pins & get_input_pins(port);
598 	rv = gpio_emul_input_set_masked_int(port, input_mask, drv_data->output_vals);
599 	input_values = drv_data->input_vals;
600 	k_spin_unlock(&drv_data->lock, key);
601 	__ASSERT_NO_MSG(rv == 0);
602 	gpio_emul_pend_interrupt(port, input_mask, prev_input_values, input_values);
603 	/* for output-wiring, so the user can take action based on output */
604 	gpio_fire_callbacks(&drv_data->callbacks, port, pins & ~get_input_pins(port));
605 
606 	return 0;
607 }
608 
gpio_emul_port_toggle_bits(const struct device * port,gpio_port_pins_t pins)609 static int gpio_emul_port_toggle_bits(const struct device *port, gpio_port_pins_t pins)
610 {
611 	struct gpio_emul_data *drv_data =
612 		(struct gpio_emul_data *)port->data;
613 	k_spinlock_key_t key;
614 	int rv;
615 
616 	key = k_spin_lock(&drv_data->lock);
617 	drv_data->output_vals ^= (pins & get_output_pins(port));
618 	/* in push-pull, set input values but do not fire interrupts (yet) */
619 	rv = gpio_emul_input_set_masked_int(port, pins & get_input_pins(port),
620 		drv_data->output_vals);
621 	k_spin_unlock(&drv_data->lock, key);
622 	__ASSERT_NO_MSG(rv == 0);
623 	/* for output-wiring, so the user can take action based on output */
624 	gpio_fire_callbacks(&drv_data->callbacks, port, pins);
625 
626 	return 0;
627 }
628 
gpio_emul_level_trigger_supported(const struct device * port,enum gpio_int_trig trig)629 static bool gpio_emul_level_trigger_supported(const struct device *port,
630 					     enum gpio_int_trig trig)
631 {
632 	switch (trig) {
633 	case GPIO_INT_TRIG_LOW:
634 		return gpio_emul_config_has_caps(port, GPIO_EMUL_INT_CAP_LEVEL_LOW);
635 	case GPIO_INT_TRIG_HIGH:
636 		return gpio_emul_config_has_caps(port, GPIO_EMUL_INT_CAP_LEVEL_HIGH);
637 	case GPIO_INT_TRIG_BOTH:
638 		return gpio_emul_config_has_caps(port, GPIO_EMUL_INT_CAP_LEVEL_LOW
639 			| GPIO_EMUL_INT_CAP_LEVEL_HIGH);
640 	default:
641 		return false;
642 	}
643 }
644 
gpio_emul_edge_trigger_supported(const struct device * port,enum gpio_int_trig trig)645 static bool gpio_emul_edge_trigger_supported(const struct device *port,
646 					    enum gpio_int_trig trig)
647 {
648 	switch (trig) {
649 	case GPIO_INT_TRIG_LOW:
650 		return gpio_emul_config_has_caps(port, GPIO_EMUL_INT_CAP_EDGE_FALLING);
651 	case GPIO_INT_TRIG_HIGH:
652 		return gpio_emul_config_has_caps(port, GPIO_EMUL_INT_CAP_EDGE_RISING);
653 	case GPIO_INT_TRIG_BOTH:
654 		return gpio_emul_config_has_caps(port, GPIO_EMUL_INT_CAP_EDGE_FALLING
655 			| GPIO_EMUL_INT_CAP_EDGE_RISING);
656 	default:
657 		return false;
658 	}
659 }
660 
gpio_emul_pin_interrupt_configure(const struct device * port,gpio_pin_t pin,enum gpio_int_mode mode,enum gpio_int_trig trig)661 static int gpio_emul_pin_interrupt_configure(const struct device *port, gpio_pin_t pin,
662 					    enum gpio_int_mode mode,
663 					    enum gpio_int_trig trig)
664 {
665 	int ret;
666 	struct gpio_emul_data *drv_data =
667 		(struct gpio_emul_data *)port->data;
668 	const struct gpio_emul_config *config =
669 		(const struct gpio_emul_config *)port->config;
670 	k_spinlock_key_t key;
671 
672 	if ((BIT(pin) & config->common.port_pin_mask) == 0) {
673 		return -EINVAL;
674 	}
675 
676 #ifdef CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT
677 	if (mode != GPIO_INT_MODE_DISABLED && !(mode & GPIO_INT_ENABLE_DISABLE_ONLY)) {
678 #else
679 	if (mode != GPIO_INT_MODE_DISABLED) {
680 #endif /* CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT */
681 		switch (trig) {
682 		case GPIO_INT_TRIG_LOW:
683 		case GPIO_INT_TRIG_HIGH:
684 		case GPIO_INT_TRIG_BOTH:
685 			break;
686 		default:
687 			return -EINVAL;
688 		}
689 	}
690 
691 	if (mode == GPIO_INT_MODE_LEVEL) {
692 		if (!gpio_emul_level_trigger_supported(port, trig)) {
693 			return -ENOTSUP;
694 		}
695 	}
696 
697 	if (mode == GPIO_INT_MODE_EDGE) {
698 		if (!gpio_emul_edge_trigger_supported(port, trig)) {
699 			return -ENOTSUP;
700 		}
701 	}
702 
703 	key = k_spin_lock(&drv_data->lock);
704 
705 #ifdef CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT
706 	/* According to the GPIO interrupt configuration flag documentation,
707 	 * changes to the interrupt trigger properties should clear pending
708 	 * interrupts.
709 	 */
710 	if (!(mode & GPIO_INT_ENABLE_DISABLE_ONLY)) {
711 		drv_data->interrupts &= ~((gpio_port_pins_t)BIT(pin));
712 	}
713 #else
714 	drv_data->interrupts &= ~((gpio_port_pins_t)BIT(pin));
715 #endif /* CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT */
716 
717 	switch (mode) {
718 	case GPIO_INT_MODE_DISABLED:
719 		drv_data->flags[pin] &= ~GPIO_EMUL_INT_BITMASK;
720 		drv_data->flags[pin] |= GPIO_INT_DISABLE;
721 #ifdef CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT
722 		__fallthrough;
723 	case GPIO_INT_MODE_DISABLE_ONLY:
724 #endif /* CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT */
725 		drv_data->enabled_interrupts &= ~((gpio_port_pins_t)BIT(pin));
726 		break;
727 	case GPIO_INT_MODE_LEVEL:
728 	case GPIO_INT_MODE_EDGE:
729 		drv_data->flags[pin] &= ~GPIO_EMUL_INT_BITMASK;
730 		drv_data->flags[pin] |= (mode | trig);
731 #ifdef CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT
732 		__fallthrough;
733 	case GPIO_INT_MODE_ENABLE_ONLY:
734 #endif /* CONFIG_GPIO_ENABLE_DISABLE_INTERRUPT */
735 		drv_data->enabled_interrupts |= BIT(pin);
736 		break;
737 	default:
738 		ret = -EINVAL;
739 		goto unlock;
740 	}
741 
742 	ret = 0;
743 
744 unlock:
745 	k_spin_unlock(&drv_data->lock, key);
746 
747 	/* Trigger callback if this pin has pending interrupt */
748 	if (BIT(pin) & (drv_data->interrupts & drv_data->enabled_interrupts)) {
749 		gpio_fire_callbacks(&drv_data->callbacks, port, BIT(pin));
750 		drv_data->interrupts &= ~((gpio_port_pins_t)BIT(pin));
751 	}
752 
753 	return ret;
754 }
755 
756 static int gpio_emul_manage_callback(const struct device *port,
757 				    struct gpio_callback *cb, bool set)
758 {
759 	struct gpio_emul_data *drv_data =
760 		(struct gpio_emul_data *)port->data;
761 
762 	return gpio_manage_callback(&drv_data->callbacks, cb, set);
763 }
764 
765 static gpio_port_pins_t gpio_emul_get_pending_int(const struct device *dev)
766 {
767 	struct gpio_emul_data *drv_data =
768 		(struct gpio_emul_data *)dev->data;
769 
770 	return drv_data->interrupts;
771 }
772 
773 #ifdef CONFIG_GPIO_GET_DIRECTION
774 static int gpio_emul_port_get_direction(const struct device *port, gpio_port_pins_t map,
775 					gpio_port_pins_t *inputs, gpio_port_pins_t *outputs)
776 {
777 	int i;
778 	gpio_port_pins_t ip = 0;
779 	gpio_port_pins_t op = 0;
780 	struct gpio_emul_data *const drv_data = (struct gpio_emul_data *)port->data;
781 	const struct gpio_emul_config *config = (const struct gpio_emul_config *)port->config;
782 
783 	map &= config->common.port_pin_mask;
784 
785 	if (inputs != NULL) {
786 		for (i = find_lsb_set(map) - 1; map;
787 		     map &= ~BIT(i), i = find_lsb_set(map) - 1) {
788 			ip |= !!(drv_data->flags[i] & GPIO_INPUT) * BIT(i);
789 		}
790 
791 		*inputs = ip;
792 	}
793 
794 	if (outputs != NULL) {
795 		for (i = find_lsb_set(map) - 1; map;
796 		     map &= ~BIT(i), i = find_lsb_set(map) - 1) {
797 			op |= !!(drv_data->flags[i] & GPIO_OUTPUT) * BIT(i);
798 		}
799 
800 		*outputs = op;
801 	}
802 
803 	return 0;
804 }
805 #endif /* CONFIG_GPIO_GET_DIRECTION */
806 
807 static const struct gpio_driver_api gpio_emul_driver = {
808 	.pin_configure = gpio_emul_pin_configure,
809 #ifdef CONFIG_GPIO_GET_CONFIG
810 	.pin_get_config = gpio_emul_pin_get_config,
811 #endif
812 	.port_get_raw = gpio_emul_port_get_raw,
813 	.port_set_masked_raw = gpio_emul_port_set_masked_raw,
814 	.port_set_bits_raw = gpio_emul_port_set_bits_raw,
815 	.port_clear_bits_raw = gpio_emul_port_clear_bits_raw,
816 	.port_toggle_bits = gpio_emul_port_toggle_bits,
817 	.pin_interrupt_configure = gpio_emul_pin_interrupt_configure,
818 	.manage_callback = gpio_emul_manage_callback,
819 	.get_pending_int = gpio_emul_get_pending_int,
820 #ifdef CONFIG_GPIO_GET_DIRECTION
821 	.port_get_direction = gpio_emul_port_get_direction,
822 #endif /* CONFIG_GPIO_GET_DIRECTION */
823 };
824 
825 static int gpio_emul_init(const struct device *dev)
826 {
827 	struct gpio_emul_data *drv_data =
828 		(struct gpio_emul_data *)dev->data;
829 
830 	sys_slist_init(&drv_data->callbacks);
831 	return 0;
832 }
833 
834 #ifdef CONFIG_PM_DEVICE
835 static int gpio_emul_pm_device_pm_action(const struct device *dev,
836 					 enum pm_device_action action)
837 {
838 	ARG_UNUSED(dev);
839 	ARG_UNUSED(action);
840 
841 	return 0;
842 }
843 #endif
844 
845 /*
846  * Device Initialization
847  */
848 
849 #define GPIO_EMUL_INT_CAPS(_num) (0					\
850 	+ DT_INST_PROP(_num, rising_edge)				\
851 		* GPIO_EMUL_INT_CAP_EDGE_RISING				\
852 	+ DT_INST_PROP(_num, falling_edge)				\
853 		* GPIO_EMUL_INT_CAP_EDGE_FALLING			\
854 	+ DT_INST_PROP(_num, high_level)				\
855 		* GPIO_EMUL_INT_CAP_LEVEL_HIGH				\
856 	+ DT_INST_PROP(_num, low_level)					\
857 		* GPIO_EMUL_INT_CAP_LEVEL_LOW				\
858 	)
859 
860 #define DEFINE_GPIO_EMUL(_num)						\
861 									\
862 	static gpio_flags_t						\
863 		gpio_emul_flags_##_num[DT_INST_PROP(_num, ngpios)];	\
864 									\
865 	static const struct gpio_emul_config gpio_emul_config_##_num = {\
866 		.common = {						\
867 			.port_pin_mask =				\
868 				GPIO_PORT_PIN_MASK_FROM_DT_INST(_num),	\
869 		},							\
870 		.num_pins = DT_INST_PROP(_num, ngpios),			\
871 		.interrupt_caps = GPIO_EMUL_INT_CAPS(_num)		\
872 	};								\
873 	BUILD_ASSERT(							\
874 		DT_INST_PROP(_num, ngpios) <= GPIO_MAX_PINS_PER_PORT,	\
875 		"Too many ngpios");					\
876 									\
877 	static struct gpio_emul_data gpio_emul_data_##_num = {		\
878 		.flags = gpio_emul_flags_##_num,			\
879 	};								\
880 									\
881 	PM_DEVICE_DT_INST_DEFINE(_num, gpio_emul_pm_device_pm_action);	\
882 									\
883 	DEVICE_DT_INST_DEFINE(_num, gpio_emul_init,			\
884 			    PM_DEVICE_DT_INST_GET(_num),		\
885 			    &gpio_emul_data_##_num,			\
886 			    &gpio_emul_config_##_num, POST_KERNEL,	\
887 			    CONFIG_GPIO_INIT_PRIORITY,			\
888 			    &gpio_emul_driver);
889 
890 DT_INST_FOREACH_STATUS_OKAY(DEFINE_GPIO_EMUL)
891