diff --git a/repos/gems/recipes/raw/drivers_managed-pc/drivers.config b/repos/gems/recipes/raw/drivers_managed-pc/drivers.config index 353c6dd6df..2b7436e7c7 100644 --- a/repos/gems/recipes/raw/drivers_managed-pc/drivers.config +++ b/repos/gems/recipes/raw/drivers_managed-pc/drivers.config @@ -151,10 +151,11 @@ - - - - + + + + + diff --git a/repos/libports/run/acpica.run b/repos/libports/run/acpica.run index fe2514d1fb..423d13b76b 100644 --- a/repos/libports/run/acpica.run +++ b/repos/libports/run/acpica.run @@ -152,6 +152,7 @@ append config { + diff --git a/repos/os/recipes/raw/drivers_interactive-pc/drivers.config b/repos/os/recipes/raw/drivers_interactive-pc/drivers.config index d311ec8bce..4bee1045c1 100644 --- a/repos/os/recipes/raw/drivers_interactive-pc/drivers.config +++ b/repos/os/recipes/raw/drivers_interactive-pc/drivers.config @@ -100,6 +100,7 @@ + diff --git a/repos/os/recipes/src/ps2_drv/used_apis b/repos/os/recipes/src/ps2_drv/used_apis index 2a424bf2d2..cb7d5b02c8 100644 --- a/repos/os/recipes/src/ps2_drv/used_apis +++ b/repos/os/recipes/src/ps2_drv/used_apis @@ -2,3 +2,4 @@ base os platform_session input_session +timer_session diff --git a/repos/os/run/input.run b/repos/os/run/input.run index 8c1feb7f30..ea4b9d3972 100644 --- a/repos/os/run/input.run +++ b/repos/os/run/input.run @@ -72,6 +72,7 @@ append_if [have_spec ps2] config { + } diff --git a/repos/os/src/drivers/input/spec/ps2/pbxa9/main.cc b/repos/os/src/drivers/input/spec/ps2/pbxa9/main.cc index 3497769bbb..0480421172 100644 --- a/repos/os/src/drivers/input/spec/ps2/pbxa9/main.cc +++ b/repos/os/src/drivers/input/spec/ps2/pbxa9/main.cc @@ -17,6 +17,7 @@ #include #include #include +#include /* local includes */ #include "ps2_keyboard.h" @@ -46,11 +47,13 @@ struct Ps2::Main Input::Session_component _session { _env, _env.ram() }; Input::Root_component _root { _env.ep().rpc_ep(), _session }; + Timer::Connection _timer { _env }; + Genode::Attached_rom_dataspace _config { _env, "config" }; Genode::Reconstructible _verbose { _config.xml() }; - Mouse _mouse { _pl050.aux_interface(), _session.event_queue(), *_verbose }; + Mouse _mouse { _pl050.aux_interface(), _session.event_queue(), _timer, *_verbose }; Keyboard _keyboard { _pl050.kbd_interface(), _session.event_queue(), false, *_verbose }; Irq_handler _mouse_irq { _env, PL050_MOUSE_IRQ, _pl050.aux_interface(), _mouse }; diff --git a/repos/os/src/drivers/input/spec/ps2/ps2_mouse.h b/repos/os/src/drivers/input/spec/ps2/ps2_mouse.h index 0e5f3718d9..ca2c218ae0 100644 --- a/repos/os/src/drivers/input/spec/ps2/ps2_mouse.h +++ b/repos/os/src/drivers/input/spec/ps2/ps2_mouse.h @@ -17,6 +17,7 @@ #include #include #include +#include #include "input_driver.h" @@ -77,6 +78,7 @@ class Ps2::Mouse : public Input_driver Type _type { PS2 }; + Timer::Connection &_timer; Verbose const &_verbose; bool _button_state[NUM_BUTTONS]; @@ -166,9 +168,9 @@ class Ps2::Mouse : public Input_driver public: Mouse(Serial_interface &aux, Input::Event_queue &ev_queue, - Verbose const &verbose) + Timer::Connection &timer, Verbose const &verbose) : - _aux(aux), _ev_queue(ev_queue), _verbose(verbose) + _aux(aux), _ev_queue(ev_queue), _timer(timer), _verbose(verbose) { for (unsigned i = 0; i < NUM_BUTTONS; ++i) _button_state[i] = false; @@ -180,6 +182,20 @@ class Ps2::Mouse : public Input_driver _aux.write(CMD_RESET); if (_aux.read() != RET_ACK) Genode::warning("could not reset mouse (missing ack)"); + + /* poll TIMEOUT_MS for reset results each SLEEP_MS */ + enum { TIMEOUT_MS = 700, SLEEP_MS = 10 }; + unsigned timeout_ms = 0; + do { + _timer.msleep(SLEEP_MS); + timeout_ms += SLEEP_MS; + } while (!_aux.data_read_ready() && timeout_ms < TIMEOUT_MS); + + if (!_aux.data_read_ready()) { + Genode::warning("could not reset mouse (no response)"); + return; + } + if (_aux.read() != 0xaa) Genode::warning("could not reset mouse (unexpected response)"); if (_aux.read() != 0x00) @@ -189,6 +205,13 @@ class Ps2::Mouse : public Input_driver if (_aux.read() != RET_ACK) Genode::warning("could not enable stream"); + /* + * Give the hardware some time to settle before probing extended + * mouse versions. Otherwise, current Lenovo trackpoints (X260, + * T470) stop working. + */ + _timer.msleep(5); + /* probe for protocol extensions */ if (_probe_exps2()) { _type = EXPS2; diff --git a/repos/os/src/drivers/input/spec/ps2/x86/main.cc b/repos/os/src/drivers/input/spec/ps2/x86/main.cc index 4ec76aa6d1..3960fa257d 100644 --- a/repos/os/src/drivers/input/spec/ps2/x86/main.cc +++ b/repos/os/src/drivers/input/spec/ps2/x86/main.cc @@ -20,6 +20,7 @@ #include #include #include +#include /* local includes */ #include "i8042.h" @@ -41,6 +42,8 @@ struct Ps2::Main Platform::Connection _platform { _env }; + Timer::Connection _timer { _env }; + Platform::Device_capability _ps2_device_cap() { return _platform.with_upgrade([&] () { @@ -61,7 +64,7 @@ struct Ps2::Main Keyboard _keyboard { _i8042.kbd_interface(), _session.event_queue(), _i8042.kbd_xlate(), *_verbose }; - Mouse _mouse { _i8042.aux_interface(), _session.event_queue(), *_verbose }; + Mouse _mouse { _i8042.aux_interface(), _session.event_queue(), _timer, *_verbose }; Irq_handler _keyboard_irq { _env.ep(), _keyboard, _device_ps2.irq(0) }; Irq_handler _mouse_irq { _env.ep(), _mouse, _device_ps2.irq(1) };