Lines Matching +full:port +full:- +full:pin
4 * SPDX-License-Identifier: Apache-2.0
55 * Pin direction as well as other pin properties are set using
87 /** Input values for each pin */
89 /** Output values for each pin */
91 /** Interrupt status for each pin */
95 /** Is interrupt enabled for each pin */
97 /** Singly-linked list of callbacks associated with the controller */
108 * @param port The emulated GPIO device pointer
115 get_pins_with_flags(const struct device *port, gpio_port_pins_t mask, in get_pins_with_flags() argument
121 (struct gpio_emul_data *)port->data; in get_pins_with_flags()
123 (const struct gpio_emul_config *)port->config; in get_pins_with_flags()
125 for (i = 0; i < config->num_pins; ++i) { in get_pins_with_flags()
126 if ((drv_data->flags[i] & mask) == flags) { in get_pins_with_flags()
139 * @param port The emulated GPIO device pointer
143 static inline gpio_port_pins_t get_input_pins(const struct device *port) in get_input_pins() argument
145 return get_pins_with_flags(port, GPIO_INPUT, GPIO_INPUT); in get_input_pins()
153 * @param port The emulated GPIO device pointer
157 static inline gpio_port_pins_t get_output_pins(const struct device *port) in get_output_pins() argument
159 return get_pins_with_flags(port, GPIO_OUTPUT, GPIO_OUTPUT); in get_output_pins()
163 * Check if @p port has capabilities specified in @p caps
165 * @param port The emulated GPIO device pointer
170 static inline bool gpio_emul_config_has_caps(const struct device *port, in gpio_emul_config_has_caps() argument
174 (const struct gpio_emul_config *)port->config; in gpio_emul_config_has_caps()
176 return (caps & config->interrupt_caps) == caps; in gpio_emul_config_has_caps()
180 * GPIO backend API (for setting input pin values)
182 static void gpio_emul_gen_interrupt_bits(const struct device *port, in gpio_emul_gen_interrupt_bits() argument
193 (struct gpio_emul_data *)port->data; in gpio_emul_gen_interrupt_bits()
195 (const struct gpio_emul_config *)port->config; in gpio_emul_gen_interrupt_bits()
197 for (i = 0, *interrupts = 0; mask && i < config->num_pins; in gpio_emul_gen_interrupt_bits()
206 switch (drv_data->flags[i] & GPIO_EMUL_INT_BITMASK) { in gpio_emul_gen_interrupt_bits()
208 if (gpio_emul_config_has_caps(port, GPIO_EMUL_INT_CAP_EDGE_RISING)) { in gpio_emul_gen_interrupt_bits()
210 drv_data->interrupts |= BIT(i); in gpio_emul_gen_interrupt_bits()
211 *interrupts |= (BIT(i) & drv_data->enabled_interrupts); in gpio_emul_gen_interrupt_bits()
216 if (gpio_emul_config_has_caps(port, GPIO_EMUL_INT_CAP_EDGE_FALLING)) { in gpio_emul_gen_interrupt_bits()
218 drv_data->interrupts |= BIT(i); in gpio_emul_gen_interrupt_bits()
219 *interrupts |= (BIT(i) & drv_data->enabled_interrupts); in gpio_emul_gen_interrupt_bits()
224 if (gpio_emul_config_has_caps(port, in gpio_emul_gen_interrupt_bits()
227 drv_data->interrupts |= BIT(i); in gpio_emul_gen_interrupt_bits()
228 *interrupts |= (BIT(i) & drv_data->enabled_interrupts); in gpio_emul_gen_interrupt_bits()
233 if (gpio_emul_config_has_caps(port, GPIO_EMUL_INT_CAP_LEVEL_LOW)) { in gpio_emul_gen_interrupt_bits()
235 drv_data->interrupts |= BIT(i); in gpio_emul_gen_interrupt_bits()
236 *interrupts |= (BIT(i) & drv_data->enabled_interrupts); in gpio_emul_gen_interrupt_bits()
241 if (gpio_emul_config_has_caps(port, GPIO_EMUL_INT_CAP_LEVEL_HIGH)) { in gpio_emul_gen_interrupt_bits()
243 drv_data->interrupts |= BIT(i); in gpio_emul_gen_interrupt_bits()
244 *interrupts |= (BIT(i) & drv_data->enabled_interrupts); in gpio_emul_gen_interrupt_bits()
253 drv_data->flags[i] & GPIO_EMUL_INT_BITMASK); in gpio_emul_gen_interrupt_bits()
260 * @brief Trigger possible interrupt events after an input pin has changed
266 * @param port The emulated GPIO port
268 * @param prev_values Previous pin values
269 * @param values Current pin values
271 static void gpio_emul_pend_interrupt(const struct device *port, gpio_port_pins_t mask, in gpio_emul_pend_interrupt() argument
277 (struct gpio_emul_data *)port->data; in gpio_emul_pend_interrupt()
280 key = k_spin_lock(&drv_data->lock); in gpio_emul_pend_interrupt()
281 gpio_emul_gen_interrupt_bits(port, mask, prev_values, values, in gpio_emul_pend_interrupt()
284 k_spin_unlock(&drv_data->lock, key); in gpio_emul_pend_interrupt()
285 gpio_fire_callbacks(&drv_data->callbacks, port, interrupts); in gpio_emul_pend_interrupt()
286 key = k_spin_lock(&drv_data->lock); in gpio_emul_pend_interrupt()
288 drv_data->interrupts &= ~interrupts; in gpio_emul_pend_interrupt()
289 gpio_emul_gen_interrupt_bits(port, mask, prev_values, values, in gpio_emul_pend_interrupt()
293 k_spin_unlock(&drv_data->lock, key); in gpio_emul_pend_interrupt()
296 int gpio_emul_input_set_masked_int(const struct device *port, in gpio_emul_input_set_masked_int() argument
303 (struct gpio_emul_data *)port->data; in gpio_emul_input_set_masked_int()
305 (const struct gpio_emul_config *)port->config; in gpio_emul_input_set_masked_int()
311 if (~config->common.port_pin_mask & mask) { in gpio_emul_input_set_masked_int()
312 LOG_ERR("Pin not supported port_pin_mask=%x mask=%x", in gpio_emul_input_set_masked_int()
313 config->common.port_pin_mask, mask); in gpio_emul_input_set_masked_int()
314 return -EINVAL; in gpio_emul_input_set_masked_int()
317 input_mask = get_input_pins(port); in gpio_emul_input_set_masked_int()
319 LOG_ERR("Not input pin input_mask=%x mask=%x", input_mask, in gpio_emul_input_set_masked_int()
321 return -EINVAL; in gpio_emul_input_set_masked_int()
324 prev_values = drv_data->input_vals; in gpio_emul_input_set_masked_int()
325 drv_data->input_vals &= ~mask; in gpio_emul_input_set_masked_int()
326 drv_data->input_vals |= values & mask; in gpio_emul_input_set_masked_int()
332 int gpio_emul_input_set_masked(const struct device *port, gpio_port_pins_t mask, in gpio_emul_input_set_masked() argument
335 struct gpio_emul_data *drv_data = (struct gpio_emul_data *)port->data; in gpio_emul_input_set_masked()
341 key = k_spin_lock(&drv_data->lock); in gpio_emul_input_set_masked()
342 prev_input_values = drv_data->input_vals; in gpio_emul_input_set_masked()
343 rv = gpio_emul_input_set_masked_int(port, mask, values); in gpio_emul_input_set_masked()
344 input_values = drv_data->input_vals; in gpio_emul_input_set_masked()
345 k_spin_unlock(&drv_data->lock, key); in gpio_emul_input_set_masked()
350 gpio_emul_pend_interrupt(port, mask, prev_input_values, input_values); in gpio_emul_input_set_masked()
355 int gpio_emul_output_get_masked(const struct device *port, gpio_port_pins_t mask, in gpio_emul_output_get_masked() argument
359 (struct gpio_emul_data *)port->data; in gpio_emul_output_get_masked()
361 (const struct gpio_emul_config *)port->config; in gpio_emul_output_get_masked()
368 if (~config->common.port_pin_mask & mask) { in gpio_emul_output_get_masked()
369 return -EINVAL; in gpio_emul_output_get_masked()
372 key = k_spin_lock(&drv_data->lock); in gpio_emul_output_get_masked()
373 *values = drv_data->output_vals & get_output_pins(port); in gpio_emul_output_get_masked()
374 k_spin_unlock(&drv_data->lock, key); in gpio_emul_output_get_masked()
380 int gpio_emul_flags_get(const struct device *port, gpio_pin_t pin, gpio_flags_t *flags) in gpio_emul_flags_get() argument
383 (struct gpio_emul_data *)port->data; in gpio_emul_flags_get()
385 (const struct gpio_emul_config *)port->config; in gpio_emul_flags_get()
389 return -EINVAL; in gpio_emul_flags_get()
392 if ((config->common.port_pin_mask & BIT(pin)) == 0) { in gpio_emul_flags_get()
393 return -EINVAL; in gpio_emul_flags_get()
396 key = k_spin_lock(&drv_data->lock); in gpio_emul_flags_get()
397 *flags = drv_data->flags[pin]; in gpio_emul_flags_get()
398 k_spin_unlock(&drv_data->lock, key); in gpio_emul_flags_get()
409 static int gpio_emul_pin_configure(const struct device *port, gpio_pin_t pin, in gpio_emul_pin_configure() argument
413 (struct gpio_emul_data *)port->data; in gpio_emul_pin_configure()
415 (const struct gpio_emul_config *)port->config; in gpio_emul_pin_configure()
420 return -ENOTSUP; in gpio_emul_pin_configure()
424 return -ENOTSUP; in gpio_emul_pin_configure()
427 if ((config->common.port_pin_mask & BIT(pin)) == 0) { in gpio_emul_pin_configure()
428 return -EINVAL; in gpio_emul_pin_configure()
431 key = k_spin_lock(&drv_data->lock); in gpio_emul_pin_configure()
432 drv_data->flags[pin] = flags; in gpio_emul_pin_configure()
435 drv_data->output_vals &= ~BIT(pin); in gpio_emul_pin_configure()
437 /* for push-pull mode to generate interrupts */ in gpio_emul_pin_configure()
439 port, BIT(pin), drv_data->output_vals); in gpio_emul_pin_configure()
443 drv_data->output_vals |= BIT(pin); in gpio_emul_pin_configure()
445 /* for push-pull mode to generate interrupts */ in gpio_emul_pin_configure()
447 port, BIT(pin), drv_data->output_vals); in gpio_emul_pin_configure()
453 rv = gpio_emul_input_set_masked_int(port, BIT(pin), BIT(pin)); in gpio_emul_pin_configure()
457 port, BIT(pin), 0); in gpio_emul_pin_configure()
462 k_spin_unlock(&drv_data->lock, key); in gpio_emul_pin_configure()
463 gpio_fire_callbacks(&drv_data->callbacks, port, BIT(pin)); in gpio_emul_pin_configure()
464 /* GPIO pin configuration changed so clear the pending interrupt. */ in gpio_emul_pin_configure()
465 drv_data->interrupts &= ~((gpio_port_pins_t)BIT(pin)); in gpio_emul_pin_configure()
471 static int gpio_emul_pin_get_config(const struct device *port, gpio_pin_t pin, in gpio_emul_pin_get_config() argument
475 (struct gpio_emul_data *)port->data; in gpio_emul_pin_get_config()
478 key = k_spin_lock(&drv_data->lock); in gpio_emul_pin_get_config()
480 *out_flags = drv_data->flags[pin] & in gpio_emul_pin_get_config()
483 if (drv_data->flags[pin] & GPIO_OUTPUT) { in gpio_emul_pin_get_config()
484 if (drv_data->output_vals & BIT(pin)) { in gpio_emul_pin_get_config()
491 k_spin_unlock(&drv_data->lock, key); in gpio_emul_pin_get_config()
497 static int gpio_emul_port_get_raw(const struct device *port, gpio_port_value_t *values) in gpio_emul_port_get_raw() argument
500 (struct gpio_emul_data *)port->data; in gpio_emul_port_get_raw()
504 return -EINVAL; in gpio_emul_port_get_raw()
507 key = k_spin_lock(&drv_data->lock); in gpio_emul_port_get_raw()
508 *values = drv_data->input_vals & get_input_pins(port); in gpio_emul_port_get_raw()
509 k_spin_unlock(&drv_data->lock, key); in gpio_emul_port_get_raw()
514 static int gpio_emul_port_set_masked_raw(const struct device *port, in gpio_emul_port_set_masked_raw() argument
524 (struct gpio_emul_data *)port->data; in gpio_emul_port_set_masked_raw()
528 key = k_spin_lock(&drv_data->lock); in gpio_emul_port_set_masked_raw()
529 output_mask = get_output_pins(port); in gpio_emul_port_set_masked_raw()
531 prev_values = drv_data->output_vals; in gpio_emul_port_set_masked_raw()
534 drv_data->output_vals &= ~mask; in gpio_emul_port_set_masked_raw()
535 drv_data->output_vals |= values; in gpio_emul_port_set_masked_raw()
536 /* in push-pull, set input values & fire interrupts */ in gpio_emul_port_set_masked_raw()
537 prev_input_values = drv_data->input_vals; in gpio_emul_port_set_masked_raw()
538 input_mask = mask & get_input_pins(port); in gpio_emul_port_set_masked_raw()
539 rv = gpio_emul_input_set_masked_int(port, input_mask, in gpio_emul_port_set_masked_raw()
540 drv_data->output_vals); in gpio_emul_port_set_masked_raw()
541 input_values = drv_data->input_vals; in gpio_emul_port_set_masked_raw()
542 k_spin_unlock(&drv_data->lock, key); in gpio_emul_port_set_masked_raw()
544 gpio_emul_pend_interrupt(port, input_mask, prev_input_values, input_values); in gpio_emul_port_set_masked_raw()
546 /* for output-wiring, so the user can take action based on output */ in gpio_emul_port_set_masked_raw()
548 gpio_fire_callbacks(&drv_data->callbacks, port, mask & ~get_input_pins(port)); in gpio_emul_port_set_masked_raw()
554 static int gpio_emul_port_set_bits_raw(const struct device *port, in gpio_emul_port_set_bits_raw() argument
558 (struct gpio_emul_data *)port->data; in gpio_emul_port_set_bits_raw()
565 key = k_spin_lock(&drv_data->lock); in gpio_emul_port_set_bits_raw()
566 pins &= get_output_pins(port); in gpio_emul_port_set_bits_raw()
567 drv_data->output_vals |= pins; in gpio_emul_port_set_bits_raw()
568 prev_input_values = drv_data->input_vals; in gpio_emul_port_set_bits_raw()
569 input_mask = pins & get_input_pins(port); in gpio_emul_port_set_bits_raw()
570 rv = gpio_emul_input_set_masked_int(port, input_mask, in gpio_emul_port_set_bits_raw()
571 drv_data->output_vals); in gpio_emul_port_set_bits_raw()
572 input_values = drv_data->input_vals; in gpio_emul_port_set_bits_raw()
573 k_spin_unlock(&drv_data->lock, key); in gpio_emul_port_set_bits_raw()
575 gpio_emul_pend_interrupt(port, input_mask, prev_input_values, input_values); in gpio_emul_port_set_bits_raw()
576 /* for output-wiring, so the user can take action based on output */ in gpio_emul_port_set_bits_raw()
577 gpio_fire_callbacks(&drv_data->callbacks, port, pins & ~get_input_pins(port)); in gpio_emul_port_set_bits_raw()
582 static int gpio_emul_port_clear_bits_raw(const struct device *port, in gpio_emul_port_clear_bits_raw() argument
586 (struct gpio_emul_data *)port->data; in gpio_emul_port_clear_bits_raw()
593 key = k_spin_lock(&drv_data->lock); in gpio_emul_port_clear_bits_raw()
594 pins &= get_output_pins(port); in gpio_emul_port_clear_bits_raw()
595 drv_data->output_vals &= ~pins; in gpio_emul_port_clear_bits_raw()
596 prev_input_values = drv_data->input_vals; in gpio_emul_port_clear_bits_raw()
597 input_mask = pins & get_input_pins(port); in gpio_emul_port_clear_bits_raw()
598 rv = gpio_emul_input_set_masked_int(port, input_mask, drv_data->output_vals); in gpio_emul_port_clear_bits_raw()
599 input_values = drv_data->input_vals; in gpio_emul_port_clear_bits_raw()
600 k_spin_unlock(&drv_data->lock, key); in gpio_emul_port_clear_bits_raw()
602 gpio_emul_pend_interrupt(port, input_mask, prev_input_values, input_values); in gpio_emul_port_clear_bits_raw()
603 /* for output-wiring, so the user can take action based on output */ in gpio_emul_port_clear_bits_raw()
604 gpio_fire_callbacks(&drv_data->callbacks, port, pins & ~get_input_pins(port)); in gpio_emul_port_clear_bits_raw()
609 static int gpio_emul_port_toggle_bits(const struct device *port, gpio_port_pins_t pins) in gpio_emul_port_toggle_bits() argument
612 (struct gpio_emul_data *)port->data; in gpio_emul_port_toggle_bits()
616 key = k_spin_lock(&drv_data->lock); in gpio_emul_port_toggle_bits()
617 drv_data->output_vals ^= (pins & get_output_pins(port)); in gpio_emul_port_toggle_bits()
618 /* in push-pull, set input values but do not fire interrupts (yet) */ in gpio_emul_port_toggle_bits()
619 rv = gpio_emul_input_set_masked_int(port, pins & get_input_pins(port), in gpio_emul_port_toggle_bits()
620 drv_data->output_vals); in gpio_emul_port_toggle_bits()
621 k_spin_unlock(&drv_data->lock, key); in gpio_emul_port_toggle_bits()
623 /* for output-wiring, so the user can take action based on output */ in gpio_emul_port_toggle_bits()
624 gpio_fire_callbacks(&drv_data->callbacks, port, pins); in gpio_emul_port_toggle_bits()
629 static bool gpio_emul_level_trigger_supported(const struct device *port, in gpio_emul_level_trigger_supported() argument
634 return gpio_emul_config_has_caps(port, GPIO_EMUL_INT_CAP_LEVEL_LOW); in gpio_emul_level_trigger_supported()
636 return gpio_emul_config_has_caps(port, GPIO_EMUL_INT_CAP_LEVEL_HIGH); in gpio_emul_level_trigger_supported()
638 return gpio_emul_config_has_caps(port, GPIO_EMUL_INT_CAP_LEVEL_LOW in gpio_emul_level_trigger_supported()
645 static bool gpio_emul_edge_trigger_supported(const struct device *port, in gpio_emul_edge_trigger_supported() argument
650 return gpio_emul_config_has_caps(port, GPIO_EMUL_INT_CAP_EDGE_FALLING); in gpio_emul_edge_trigger_supported()
652 return gpio_emul_config_has_caps(port, GPIO_EMUL_INT_CAP_EDGE_RISING); in gpio_emul_edge_trigger_supported()
654 return gpio_emul_config_has_caps(port, GPIO_EMUL_INT_CAP_EDGE_FALLING in gpio_emul_edge_trigger_supported()
661 static int gpio_emul_pin_interrupt_configure(const struct device *port, gpio_pin_t pin, argument
667 (struct gpio_emul_data *)port->data;
669 (const struct gpio_emul_config *)port->config;
672 if ((BIT(pin) & config->common.port_pin_mask) == 0) {
673 return -EINVAL;
687 return -EINVAL;
692 if (!gpio_emul_level_trigger_supported(port, trig)) {
693 return -ENOTSUP;
698 if (!gpio_emul_edge_trigger_supported(port, trig)) {
699 return -ENOTSUP;
703 key = k_spin_lock(&drv_data->lock);
711 drv_data->interrupts &= ~((gpio_port_pins_t)BIT(pin));
714 drv_data->interrupts &= ~((gpio_port_pins_t)BIT(pin));
719 drv_data->flags[pin] &= ~GPIO_EMUL_INT_BITMASK;
720 drv_data->flags[pin] |= GPIO_INT_DISABLE;
725 drv_data->enabled_interrupts &= ~((gpio_port_pins_t)BIT(pin));
729 drv_data->flags[pin] &= ~GPIO_EMUL_INT_BITMASK;
730 drv_data->flags[pin] |= (mode | trig);
735 drv_data->enabled_interrupts |= BIT(pin);
738 ret = -EINVAL;
745 k_spin_unlock(&drv_data->lock, key);
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));
756 static int gpio_emul_manage_callback(const struct device *port, argument
760 (struct gpio_emul_data *)port->data;
762 return gpio_manage_callback(&drv_data->callbacks, cb, set);
768 (struct gpio_emul_data *)dev->data;
770 return drv_data->interrupts;
774 static int gpio_emul_port_get_direction(const struct device *port, gpio_port_pins_t map, argument
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;
783 map &= config->common.port_pin_mask;
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);
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);
828 (struct gpio_emul_data *)dev->data;
830 sys_slist_init(&drv_data->callbacks);