From b03059b933b5677327c6f4cb7fa113b637bdfa2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20S=C3=B6ntgen?= Date: Thu, 4 Aug 2022 11:12:04 +0200 Subject: [PATCH] dde_linux: allow GPIO state access To complement the GPIO support allow for setting and reading input pins. So far this is needed by drivers that attempt to perform I2C bit-banging via GPIO pins. Fixes #4624. --- repos/dde_linux/src/include/lx_emul/pin.h | 7 +++++ repos/dde_linux/src/lib/lx_emul/pin.cc | 35 +++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/repos/dde_linux/src/include/lx_emul/pin.h b/repos/dde_linux/src/include/lx_emul/pin.h index 74bb5dbb43..f5d554f66e 100644 --- a/repos/dde_linux/src/include/lx_emul/pin.h +++ b/repos/dde_linux/src/include/lx_emul/pin.h @@ -25,6 +25,13 @@ extern "C" { */ void lx_emul_pin_control(char const *pin_name, bool enabled); +/** + * Get input state of GPIO pin + * + * \pin_name GPIO name used as label for corresponding 'Pin_state' session + */ +int lx_emul_pin_sense(char const *pin_name); + /** * Request interrupt backed by an IRQ session */ diff --git a/repos/dde_linux/src/lib/lx_emul/pin.cc b/repos/dde_linux/src/lib/lx_emul/pin.cc index 7fb683dbfd..2a78f67975 100644 --- a/repos/dde_linux/src/lib/lx_emul/pin.cc +++ b/repos/dde_linux/src/lib/lx_emul/pin.cc @@ -14,6 +14,7 @@ /* Genode includes */ #include #include +#include #include #include @@ -75,10 +76,13 @@ namespace { Name const name; Constructible _control { }; + Constructible _state { }; Constructible _irq { }; Io_signal_handler _irq_handler { _env.ep(), *this, &Pin::_handle_irq }; + enum class Direction { IN, OUT } _direction { Direction::IN }; + void _handle_irq() { _pin_irq_handler.handle_pin_irq(_irq_info); @@ -100,6 +104,25 @@ namespace { _control.construct(_env, name.string()); _control->state(enabled); + _direction = Direction::OUT; + } + + bool sense() + { + if (_irq.constructed()) { + error("attempt to drive interrupt pin ", name, " as input"); + return false; + } + + if (_control.constructed() && (_direction == Direction::OUT)) { + _control->yield(); + _direction = Direction::IN; + } + + if (!_state.constructed()) + _state.construct(_env, name.string()); + + return _state->state(); } void associate_with_gic_and_unmask_irq(Irq_info irq_info) @@ -200,6 +223,18 @@ extern "C" void lx_emul_pin_control(char const *pin_name, bool enabled) } +extern "C" void lx_emul_backtrace(void); + + +extern "C" int lx_emul_pin_sense(char const *pin_name) +{ + bool result = false; + pins().with_pin(pin_name, [&] (Pin &pin) { + result = pin.sense(); }); + return result; +} + + extern "C" void lx_emul_pin_irq_unmask(unsigned gic_irq, unsigned pin_irq, char const *pin_name) {