Lines Matching +full:ouput +full:- +full:only
2 * STM32L4x5 GPIO (General Purpose Input/Ouput)
4 * Copyright (c) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
5 * Copyright (c) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
7 * SPDX-License-Identifier: GPL-2.0-or-later
10 * See the COPYING file in the top-level directory.
15 * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs.
16 * https://www.st.com/en/microcontrollers-microprocessors/stm32l4x5/documentation.html
24 #include "hw/qdev-clock.h"
25 #include "hw/qdev-properties.h"
51 return extract32(s->pupdr, 2 * pin, 2) == 1; in is_pull_up()
56 return extract32(s->pupdr, 2 * pin, 2) == 2; in is_pull_down()
61 return extract32(s->moder, 2 * pin, 2) == 1; in is_output()
66 return extract32(s->otyper, pin, 1) == 1; in is_open_drain()
71 return extract32(s->otyper, pin, 1) == 0; in is_push_pull()
78 s->moder = s->moder_reset; in stm32l4x5_gpio_reset_hold()
79 s->otyper = 0x00000000; in stm32l4x5_gpio_reset_hold()
80 s->ospeedr = s->ospeedr_reset; in stm32l4x5_gpio_reset_hold()
81 s->pupdr = s->pupdr_reset; in stm32l4x5_gpio_reset_hold()
82 s->idr = 0x00000000; in stm32l4x5_gpio_reset_hold()
83 s->odr = 0x00000000; in stm32l4x5_gpio_reset_hold()
84 s->lckr = 0x00000000; in stm32l4x5_gpio_reset_hold()
85 s->afrl = 0x00000000; in stm32l4x5_gpio_reset_hold()
86 s->afrh = 0x00000000; in stm32l4x5_gpio_reset_hold()
87 s->ascr = 0x00000000; in stm32l4x5_gpio_reset_hold()
89 s->disconnected_pins = 0xFFFF; in stm32l4x5_gpio_reset_hold()
90 s->pins_connected_high = 0x0000; in stm32l4x5_gpio_reset_hold()
99 * except if level is 0 and the output is open-drain. in stm32l4x5_gpio_set()
100 * This way there will be no short-circuit prone situations. in stm32l4x5_gpio_set()
108 s->disconnected_pins &= ~(1 << line); in stm32l4x5_gpio_set()
110 s->pins_connected_high |= (1 << line); in stm32l4x5_gpio_set()
112 s->pins_connected_high &= ~(1 << line); in stm32l4x5_gpio_set()
114 trace_stm32l4x5_gpio_pins(s->name, s->disconnected_pins, in stm32l4x5_gpio_set()
115 s->pins_connected_high); in stm32l4x5_gpio_set()
123 uint32_t new_idr = s->odr; in update_gpio_idr()
124 uint32_t old_idr = s->idr; in update_gpio_idr()
131 } else if (!(s->odr & (1 << i))) { in update_gpio_idr()
132 /* open-drain ODR 0 */ in update_gpio_idr()
134 /* open-drain ODR 1 */ in update_gpio_idr()
135 } else if (!(s->disconnected_pins & (1 << i)) && in update_gpio_idr()
136 !(s->pins_connected_high & (1 << i))) { in update_gpio_idr()
137 /* open-drain ODR 1 with pin connected low */ in update_gpio_idr()
140 /* open-drain ODR 1 with unactive pin */ in update_gpio_idr()
148 * The only case left is for open-drain ODR 1 in update_gpio_idr()
149 * with unactive pin without pull-up or pull-down : in update_gpio_idr()
153 } else if (!(s->disconnected_pins & (1 << i))) { in update_gpio_idr()
154 if (s->pins_connected_high & (1 << i)) { in update_gpio_idr()
166 /* pull-up */ in update_gpio_idr()
170 /* pull-down */ in update_gpio_idr()
175 * The only case left is for a disconnected pin in update_gpio_idr()
176 * without pull-up or pull-down : in update_gpio_idr()
182 s->idr = (old_idr & ~new_idr_mask) | (new_idr & new_idr_mask); in update_gpio_idr()
183 trace_stm32l4x5_gpio_update_idr(s->name, old_idr, s->idr); in update_gpio_idr()
190 qemu_irq_raise(s->pin[i]); in update_gpio_idr()
192 qemu_irq_lower(s->pin[i]); in update_gpio_idr()
200 * mode and externally driven (except pins in open-drain
208 if (!(s->disconnected_pins & (1 << i)) && is_output(s, i)) { in get_gpio_pinmask_to_disconnect()
209 /* if either push-pull or high level */ in get_gpio_pinmask_to_disconnect()
210 if (is_push_pull(s, i) || s->pins_connected_high & (1 << i)) { in get_gpio_pinmask_to_disconnect()
226 s->disconnected_pins |= lines; in disconnect_gpio_pins()
227 trace_stm32l4x5_gpio_pins(s->name, s->disconnected_pins, in disconnect_gpio_pins()
228 s->pins_connected_high); in disconnect_gpio_pins()
253 uint32_t clock_freq_hz = clock_get_hz(s->clk); in clock_freq_get()
263 trace_stm32l4x5_gpio_write(s->name, addr, val64); in stm32l4x5_gpio_write()
267 s->moder = value; in stm32l4x5_gpio_write()
275 s->otyper = value & ~RESERVED_BITS_MASK; in stm32l4x5_gpio_write()
283 s->ospeedr = value; in stm32l4x5_gpio_write()
286 s->pupdr = value; in stm32l4x5_gpio_write()
291 "%s: GPIO->IDR is read-only\n", in stm32l4x5_gpio_write()
295 s->odr = value & ~RESERVED_BITS_MASK; in stm32l4x5_gpio_write()
302 s->odr &= ~bits_to_reset; in stm32l4x5_gpio_write()
303 s->odr |= bits_to_set; in stm32l4x5_gpio_write()
311 s->lckr = value & ~RESERVED_BITS_MASK; in stm32l4x5_gpio_write()
317 s->afrl = value; in stm32l4x5_gpio_write()
323 s->afrh = value; in stm32l4x5_gpio_write()
327 s->odr &= ~bits_to_reset; in stm32l4x5_gpio_write()
335 s->ascr = value & ~RESERVED_BITS_MASK; in stm32l4x5_gpio_write()
348 trace_stm32l4x5_gpio_read(s->name, addr); in stm32l4x5_gpio_read()
352 return s->moder; in stm32l4x5_gpio_read()
354 return s->otyper; in stm32l4x5_gpio_read()
356 return s->ospeedr; in stm32l4x5_gpio_read()
358 return s->pupdr; in stm32l4x5_gpio_read()
360 return s->idr; in stm32l4x5_gpio_read()
362 return s->odr; in stm32l4x5_gpio_read()
366 return s->lckr; in stm32l4x5_gpio_read()
368 return s->afrl; in stm32l4x5_gpio_read()
370 return s->afrh; in stm32l4x5_gpio_read()
374 return s->ascr; in stm32l4x5_gpio_read()
402 memory_region_init_io(&s->mmio, obj, &stm32l4x5_gpio_ops, s, in stm32l4x5_gpio_init()
405 sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); in stm32l4x5_gpio_init()
407 qdev_init_gpio_out(DEVICE(obj), s->pin, GPIO_NUM_PINS); in stm32l4x5_gpio_init()
410 s->clk = qdev_init_clock_in(DEVICE(s), "clk", NULL, s, 0); in stm32l4x5_gpio_init()
412 object_property_add(obj, "disconnected-pins", "uint16", in stm32l4x5_gpio_init()
414 NULL, &s->disconnected_pins); in stm32l4x5_gpio_init()
415 object_property_add(obj, "clock-freq-hz", "uint32", in stm32l4x5_gpio_init()
422 if (!clock_has_source(s->clk)) { in stm32l4x5_gpio_realize()
452 DEFINE_PROP_UINT32("mode-reset", Stm32l4x5GpioState, moder_reset, 0),
453 DEFINE_PROP_UINT32("ospeed-reset", Stm32l4x5GpioState, ospeedr_reset, 0),
454 DEFINE_PROP_UINT32("pupd-reset", Stm32l4x5GpioState, pupdr_reset, 0),
464 dc->vmsd = &vmstate_stm32l4x5_gpio; in stm32l4x5_gpio_class_init()
465 dc->realize = stm32l4x5_gpio_realize; in stm32l4x5_gpio_class_init()
466 rc->phases.hold = stm32l4x5_gpio_reset_hold; in stm32l4x5_gpio_class_init()