mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-10 21:01:49 +00:00
acpica.run: add acpi_hid evaluation support
Evaluate acpi_hid report in acpi_event Showcase feature in acpica.run for FUJITSU FUJ02E3 and KEY_FN_F4.
This commit is contained in:
parent
1147f35972
commit
0a5741f076
@ -100,6 +100,7 @@ append config {
|
||||
<policy label="acpi_event -> acpi_ec" report="acpica -> acpi_ec"/>
|
||||
<policy label="acpi_event -> acpi_fixed" report="acpica -> acpi_fixed"/>
|
||||
<policy label="acpi_event -> acpi_lid" report="acpica -> acpi_lid"/>
|
||||
<policy label="acpi_event -> acpi_hid" report="acpica -> acpi_hid"/>
|
||||
</config>
|
||||
<route>
|
||||
<any-service> <parent/> </any-service>
|
||||
@ -176,15 +177,16 @@ append config {
|
||||
<config>
|
||||
<!-- example mapping - adapt to your target notebook !!! -->
|
||||
<!-- as="PRESS_RELEASE" is default if nothing specified -->
|
||||
<map acpi="ec" value="25" to_key="KEY_VENDOR"/>
|
||||
<map acpi="ec" value="20" to_key="KEY_BRIGHTNESSUP"/>
|
||||
<map acpi="ec" value="21" to_key="KEY_BRIGHTNESSDOWN"/>
|
||||
<map acpi="fixed" value="0" to_key="KEY_POWER" as="PRESS_RELEASE"/>
|
||||
<map acpi="lid" value="CLOSED" to_key="KEY_SLEEP" as="PRESS"/>
|
||||
<map acpi="lid" value="OPEN" to_key="KEY_SLEEP" as="RELEASE"/>
|
||||
<map acpi="ac" value="ONLINE" to_key="KEY_WAKEUP"/>
|
||||
<map acpi="ac" value="OFFLINE" to_key="KEY_SLEEP"/>
|
||||
<map acpi="battery" value="0" to_key="KEY_BATTERY"/>
|
||||
<map acpi="ec" value="25" to_key="KEY_VENDOR"/>
|
||||
<map acpi="ec" value="20" to_key="KEY_BRIGHTNESSUP"/>
|
||||
<map acpi="ec" value="21" to_key="KEY_BRIGHTNESSDOWN"/>
|
||||
<map acpi="fixed" value="0" to_key="KEY_POWER" as="PRESS_RELEASE"/>
|
||||
<map acpi="lid" value="CLOSED" to_key="KEY_SLEEP" as="PRESS"/>
|
||||
<map acpi="lid" value="OPEN" to_key="KEY_SLEEP" as="RELEASE"/>
|
||||
<map acpi="ac" value="ONLINE" to_key="KEY_WAKEUP"/>
|
||||
<map acpi="ac" value="OFFLINE" to_key="KEY_SLEEP"/>
|
||||
<map acpi="battery" value="0" to_key="KEY_BATTERY"/>
|
||||
<map acpi="hid" value="0x4000000" to_key="KEY_FN_F4"/>
|
||||
</config>
|
||||
<route>
|
||||
<service name="ROM" label="acpi_ac"> <child name="acpi_state"/> </service>
|
||||
@ -192,6 +194,7 @@ append config {
|
||||
<service name="ROM" label="acpi_ec"> <child name="acpi_state"/> </service>
|
||||
<service name="ROM" label="acpi_fixed"> <child name="acpi_state"/> </service>
|
||||
<service name="ROM" label="acpi_lid"> <child name="acpi_state"/> </service>
|
||||
<service name="ROM" label="acpi_hid"> <child name="acpi_state"/> </service>
|
||||
<service name="Event"> <child name="event_filter" label="acpi"/> </service>
|
||||
<any-service> <parent/> </any-service>
|
||||
</route>
|
||||
|
@ -23,15 +23,16 @@
|
||||
#include <event_session/connection.h>
|
||||
|
||||
namespace Transform {
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
struct Main;
|
||||
class Keys;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
class Transform::Keys : public Avl_node<Transform::Keys> {
|
||||
|
||||
class Transform::Keys : public Avl_node<Transform::Keys>
|
||||
{
|
||||
public:
|
||||
|
||||
enum Type { PRESS_RELEASE, PRESS, RELEASE };
|
||||
@ -39,15 +40,12 @@ class Transform::Keys : public Avl_node<Transform::Keys> {
|
||||
private:
|
||||
|
||||
const Input::Keycode _code;
|
||||
const long _acpi_value;
|
||||
unsigned long _acpi_count = 0;
|
||||
const uint64_t _acpi_value;
|
||||
uint64_t _acpi_count = 0;
|
||||
bool _first = true;
|
||||
Type _type;
|
||||
|
||||
static Avl_tree<Keys> _map_ec;
|
||||
static Avl_tree<Keys> _map_special;
|
||||
|
||||
Keys *_find_by_acpi_value(long acpi_value)
|
||||
Keys *_find_by_acpi_value(uint64_t acpi_value)
|
||||
{
|
||||
if (acpi_value == _acpi_value) return this;
|
||||
Keys *key = this->child(acpi_value > _acpi_value);
|
||||
@ -56,7 +54,7 @@ class Transform::Keys : public Avl_node<Transform::Keys> {
|
||||
|
||||
public:
|
||||
|
||||
Keys(Input::Keycode code, long acpi_value, Type type)
|
||||
Keys(Input::Keycode code, uint64_t acpi_value, Type type)
|
||||
: _code(code), _acpi_value(acpi_value), _type(type) { }
|
||||
|
||||
Input::Keycode key_code() const { return _code; }
|
||||
@ -65,10 +63,10 @@ class Transform::Keys : public Avl_node<Transform::Keys> {
|
||||
|
||||
Type type() const { return _type; }
|
||||
|
||||
unsigned long update_count(unsigned long acpi_count)
|
||||
uint64_t update_count(uint64_t acpi_count)
|
||||
{
|
||||
unsigned long diff = acpi_count > _acpi_count ?
|
||||
acpi_count - _acpi_count : 0;
|
||||
uint64_t diff = acpi_count > _acpi_count ?
|
||||
acpi_count - _acpi_count : 0;
|
||||
|
||||
/*
|
||||
* If we get the first time this ACPI event, than we don't
|
||||
@ -84,35 +82,19 @@ class Transform::Keys : public Avl_node<Transform::Keys> {
|
||||
return diff;
|
||||
}
|
||||
|
||||
static Keys * find_by_ec(long acpi_code)
|
||||
static Keys * find_by(Avl_tree<Keys> &map, uint64_t acpi_code)
|
||||
{
|
||||
Keys * head = _map_ec.first();
|
||||
Keys * head = map.first();
|
||||
if (!head)
|
||||
return head;
|
||||
|
||||
return head->_find_by_acpi_value(acpi_code);
|
||||
}
|
||||
|
||||
static Keys * find_by_fixed(long acpi_code)
|
||||
{
|
||||
Keys * head = _map_special.first();
|
||||
if (!head)
|
||||
return head;
|
||||
|
||||
return head->_find_by_acpi_value(acpi_code);
|
||||
}
|
||||
|
||||
static void insert_ec(Keys * key) { _map_ec.insert(key); }
|
||||
static void insert_special(Keys * key) { _map_special.insert(key); }
|
||||
};
|
||||
|
||||
|
||||
Genode::Avl_tree<Transform::Keys> Transform::Keys::_map_ec;
|
||||
Genode::Avl_tree<Transform::Keys> Transform::Keys::_map_special;
|
||||
|
||||
|
||||
struct Transform::Main {
|
||||
|
||||
struct Transform::Main
|
||||
{
|
||||
enum {
|
||||
ACPI_POWER_BUTTON, ACPI_LID_OPEN, ACPI_LID_CLOSED,
|
||||
ACPI_AC_ONLINE, ACPI_AC_OFFLINE, ACPI_BATTERY
|
||||
@ -126,15 +108,21 @@ struct Transform::Main {
|
||||
Attached_rom_dataspace _acpi_ec;
|
||||
Attached_rom_dataspace _acpi_fixed;
|
||||
Attached_rom_dataspace _acpi_lid;
|
||||
Attached_rom_dataspace _acpi_hid;
|
||||
|
||||
Signal_handler<Main> _dispatch_acpi_ac;
|
||||
Signal_handler<Main> _dispatch_acpi_battery;
|
||||
Signal_handler<Main> _dispatch_acpi_ec;
|
||||
Signal_handler<Main> _dispatch_acpi_fixed;
|
||||
Signal_handler<Main> _dispatch_acpi_lid;
|
||||
Signal_handler<Main> _dispatch_acpi_hid;
|
||||
|
||||
Event::Connection _event;
|
||||
|
||||
Avl_tree<Keys> _map_ec { };
|
||||
Avl_tree<Keys> _map_hid { };
|
||||
Avl_tree<Keys> _map_special { };
|
||||
|
||||
Main(Env &env)
|
||||
:
|
||||
_heap(env.ram(), env.rm()),
|
||||
@ -144,17 +132,19 @@ struct Transform::Main {
|
||||
_acpi_ec(env, "acpi_ec"),
|
||||
_acpi_fixed(env, "acpi_fixed"),
|
||||
_acpi_lid(env, "acpi_lid"),
|
||||
_acpi_hid(env, "acpi_hid"),
|
||||
_dispatch_acpi_ac(env.ep(), *this, &Main::check_acpi_ac),
|
||||
_dispatch_acpi_battery(env.ep(), *this, &Main::check_acpi_battery),
|
||||
_dispatch_acpi_ec(env.ep(), *this, &Main::check_acpi_ec),
|
||||
_dispatch_acpi_fixed(env.ep(), *this, &Main::check_acpi_fixed),
|
||||
_dispatch_acpi_lid(env.ep(), *this, &Main::check_acpi_lid),
|
||||
_dispatch_acpi_hid(env.ep(), *this, &Main::check_acpi_hid),
|
||||
_event(env)
|
||||
{
|
||||
Xml_node config(_config.local_addr<char>(), _config.size());
|
||||
config.for_each_sub_node("map", [&] (Xml_node map_node) {
|
||||
try {
|
||||
long acpi_value = 0;
|
||||
uint64_t acpi_value = 0;
|
||||
String<8> acpi_type;
|
||||
String<8> acpi_value_string;
|
||||
String<32> to_key;
|
||||
@ -211,24 +201,29 @@ struct Transform::Main {
|
||||
key_code = Input::Keycode::KEY_BRIGHTNESSUP;
|
||||
else if (to_key == "KEY_BRIGHTNESSDOWN")
|
||||
key_code = Input::Keycode::KEY_BRIGHTNESSDOWN;
|
||||
else if (to_key == "KEY_FN_F4")
|
||||
key_code = Input::Keycode::KEY_FN_F4;
|
||||
|
||||
if (key_code == Input::Keycode::KEY_UNKNOWN)
|
||||
throw 4;
|
||||
|
||||
if (acpi_type == "ec")
|
||||
Keys::insert_ec(new (_heap) Keys(key_code, acpi_value,
|
||||
press_release));
|
||||
_map_ec.insert(new (_heap) Keys(key_code, acpi_value,
|
||||
press_release));
|
||||
else if (acpi_type == "fixed")
|
||||
Keys::insert_special(new (_heap) Keys(key_code,
|
||||
ACPI_POWER_BUTTON,
|
||||
press_release));
|
||||
_map_special.insert(new (_heap) Keys(key_code,
|
||||
ACPI_POWER_BUTTON,
|
||||
press_release));
|
||||
else if (acpi_type == "lid" || acpi_type == "ac")
|
||||
Keys::insert_special(new (_heap) Keys(key_code, acpi_value,
|
||||
press_release));
|
||||
_map_special.insert(new (_heap) Keys(key_code, acpi_value,
|
||||
press_release));
|
||||
else if (acpi_type == "battery")
|
||||
Keys::insert_special(new (_heap) Keys(key_code,
|
||||
ACPI_BATTERY,
|
||||
press_release));
|
||||
_map_special.insert(new (_heap) Keys(key_code,
|
||||
ACPI_BATTERY,
|
||||
press_release));
|
||||
else if (acpi_type == "hid")
|
||||
_map_hid.insert(new (_heap) Keys(key_code, acpi_value,
|
||||
press_release));
|
||||
else
|
||||
throw 5;
|
||||
} catch (...) {
|
||||
@ -252,6 +247,7 @@ struct Transform::Main {
|
||||
_acpi_ec.sigh(_dispatch_acpi_ec);
|
||||
_acpi_fixed.sigh(_dispatch_acpi_fixed);
|
||||
_acpi_lid.sigh(_dispatch_acpi_lid);
|
||||
_acpi_hid.sigh(_dispatch_acpi_hid);
|
||||
|
||||
/* check for initial valid ACPI data */
|
||||
check_acpi_ac();
|
||||
@ -259,26 +255,28 @@ struct Transform::Main {
|
||||
check_acpi_ec();
|
||||
check_acpi_fixed();
|
||||
check_acpi_lid();
|
||||
check_acpi_hid();
|
||||
}
|
||||
|
||||
void check_acpi_ec()
|
||||
void _check_acpi(Attached_rom_dataspace &rom, Avl_tree<Keys> &map,
|
||||
char const * const name)
|
||||
{
|
||||
_acpi_ec.update();
|
||||
rom.update();
|
||||
|
||||
if (!_acpi_ec.valid()) return;
|
||||
if (!rom.valid()) return;
|
||||
|
||||
Xml_node ec_event(_acpi_ec.local_addr<char>(), _acpi_ec.size());
|
||||
Xml_node event(rom.local_addr<char>(), rom.size());
|
||||
|
||||
ec_event.for_each_sub_node("ec", [&] (Xml_node ec_node) {
|
||||
ec_node.for_each_sub_node("data", [&] (Xml_node data_node) {
|
||||
event.for_each_sub_node(name, [&] (Xml_node const &node) {
|
||||
node.for_each_sub_node("data", [&] (Xml_node const &data_node) {
|
||||
try {
|
||||
long acpi_value = 0;
|
||||
unsigned long acpi_count = 0;
|
||||
uint64_t acpi_value = 0;
|
||||
uint64_t acpi_count = 0;
|
||||
|
||||
data_node.attribute("value").value(acpi_value);
|
||||
data_node.attribute("count").value(acpi_count);
|
||||
|
||||
Keys * key = Keys::find_by_ec(acpi_value);
|
||||
Keys * key = Keys::find_by(map, acpi_value);
|
||||
if (!key)
|
||||
return;
|
||||
|
||||
@ -291,6 +289,10 @@ struct Transform::Main {
|
||||
});
|
||||
}
|
||||
|
||||
void check_acpi_ec() { _check_acpi(_acpi_ec, _map_ec, "ec"); }
|
||||
|
||||
void check_acpi_hid() { _check_acpi(_acpi_hid, _map_hid, "hid"); }
|
||||
|
||||
void submit_input(Keys * key)
|
||||
{
|
||||
_event.with_batch([&] (Event::Session_client::Batch &batch) {
|
||||
@ -319,12 +321,12 @@ struct Transform::Main {
|
||||
fixed_event.for_each_sub_node("power_button", [&] (Xml_node pw_node) {
|
||||
try {
|
||||
bool pressed = false;
|
||||
unsigned long acpi_count = 0;
|
||||
uint64_t acpi_count = 0;
|
||||
|
||||
pw_node.attribute("value").value(pressed);
|
||||
pw_node.attribute("count").value(acpi_count);
|
||||
|
||||
Keys * key = Keys::find_by_fixed(ACPI_POWER_BUTTON);
|
||||
Keys * key = Keys::find_by(_map_special, ACPI_POWER_BUTTON);
|
||||
if (!key)
|
||||
return;
|
||||
|
||||
@ -346,7 +348,7 @@ struct Transform::Main {
|
||||
Xml_node battery_node(_acpi_battery.local_addr<char>(),
|
||||
_acpi_battery.size());
|
||||
|
||||
submit_input(Keys::find_by_fixed(ACPI_BATTERY));
|
||||
submit_input(Keys::find_by(_map_special, ACPI_BATTERY));
|
||||
}
|
||||
|
||||
void check_acpi_ac()
|
||||
@ -376,8 +378,8 @@ struct Transform::Main {
|
||||
{
|
||||
xml_node.for_each_sub_node(sub_name, [&] (Xml_node node) {
|
||||
try {
|
||||
unsigned acpi_value = 0;
|
||||
unsigned long acpi_count = 0;
|
||||
uint64_t acpi_value = 0;
|
||||
uint64_t acpi_count = 0;
|
||||
|
||||
node.attribute("value").value(acpi_value);
|
||||
node.attribute("count").value(acpi_count);
|
||||
@ -386,9 +388,9 @@ struct Transform::Main {
|
||||
|
||||
Keys * key = nullptr;
|
||||
if (acpi_value == STATE_O)
|
||||
key = Keys::find_by_fixed(state_o);
|
||||
key = Keys::find_by(_map_special, state_o);
|
||||
if (acpi_value == STATE_C)
|
||||
key = Keys::find_by_fixed(state_c);
|
||||
key = Keys::find_by(_map_special, state_c);
|
||||
if (!key)
|
||||
return;
|
||||
|
||||
@ -406,10 +408,5 @@ struct Transform::Main {
|
||||
};
|
||||
|
||||
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
/* XXX execute constructors of global statics */
|
||||
env.exec_static_constructors();
|
||||
|
||||
static Transform::Main main(env);
|
||||
}
|
||||
void Component::construct(Genode::Env &env) {
|
||||
static Transform::Main main(env); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user