mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 13:47:56 +00:00
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.
This commit is contained in:
parent
85f98d7038
commit
b03059b933
@ -25,6 +25,13 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
void lx_emul_pin_control(char const *pin_name, bool enabled);
|
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
|
* Request interrupt backed by an IRQ session
|
||||||
*/
|
*/
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/registry.h>
|
#include <base/registry.h>
|
||||||
#include <pin_control_session/connection.h>
|
#include <pin_control_session/connection.h>
|
||||||
|
#include <pin_state_session/connection.h>
|
||||||
#include <irq_session/connection.h>
|
#include <irq_session/connection.h>
|
||||||
|
|
||||||
#include <lx_emul/pin.h>
|
#include <lx_emul/pin.h>
|
||||||
@ -75,10 +76,13 @@ namespace {
|
|||||||
Name const name;
|
Name const name;
|
||||||
|
|
||||||
Constructible<Pin_control::Connection> _control { };
|
Constructible<Pin_control::Connection> _control { };
|
||||||
|
Constructible<Pin_state::Connection> _state { };
|
||||||
Constructible<Irq_connection> _irq { };
|
Constructible<Irq_connection> _irq { };
|
||||||
|
|
||||||
Io_signal_handler<Pin> _irq_handler { _env.ep(), *this, &Pin::_handle_irq };
|
Io_signal_handler<Pin> _irq_handler { _env.ep(), *this, &Pin::_handle_irq };
|
||||||
|
|
||||||
|
enum class Direction { IN, OUT } _direction { Direction::IN };
|
||||||
|
|
||||||
void _handle_irq()
|
void _handle_irq()
|
||||||
{
|
{
|
||||||
_pin_irq_handler.handle_pin_irq(_irq_info);
|
_pin_irq_handler.handle_pin_irq(_irq_info);
|
||||||
@ -100,6 +104,25 @@ namespace {
|
|||||||
_control.construct(_env, name.string());
|
_control.construct(_env, name.string());
|
||||||
|
|
||||||
_control->state(enabled);
|
_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)
|
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,
|
extern "C" void lx_emul_pin_irq_unmask(unsigned gic_irq, unsigned pin_irq,
|
||||||
char const *pin_name)
|
char const *pin_name)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user