input/ps2: poll for mouse-reset results

The PS/2 driver retries to get mouse-reset results for 700 ms, sleeping
after each attempt for 10 ms. So, the driver needs a Timer session now.

Fixes #2713
This commit is contained in:
Christian Helmuth 2018-08-17 17:26:30 +02:00
parent 25ee872703
commit 40a84e0c81
8 changed files with 42 additions and 8 deletions

View File

@ -151,10 +151,11 @@
<service name="Platform"> <child name="platform_drv"/> </service>
<service name="ROM" label="capslock"> <parent label="capslock"/> </service>
<service name="ROM" label="numlock"> <parent label="numlock"/> </service>
<service name="ROM"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="LOG"> <parent/> </service>
<service name="ROM"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="LOG"> <parent/> </service>
<service name="Timer"> <parent/> </service>
</route>
</start>

View File

@ -152,6 +152,7 @@ append config {
<config verbose_keyboard="no" verbose_mouse="no" verbose_scancodes="no"/>
<route>
<service name="Platform"> <child name="platform_drv"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>

View File

@ -100,6 +100,7 @@
<service name="PD"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="LOG"> <parent/> </service>
<service name="Timer"> <parent/> </service>
</route>
</start>

View File

@ -2,3 +2,4 @@ base
os
platform_session
input_session
timer_session

View File

@ -72,6 +72,7 @@ append_if [have_spec ps2] config {
<service name="IO_PORT"> <parent/> </service>
<service name="LOG"> <parent/> </service>
<service name="Platform"> <any-child/> </service>
<service name="Timer"> <child name="timer"/> </service>
</route>
</start>
<alias name="input_drv" child="ps2_drv"/>}

View File

@ -17,6 +17,7 @@
#include <drivers/defs/pbxa9.h>
#include <input/component.h>
#include <input/root.h>
#include <timer_session/connection.h>
/* 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> _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 };

View File

@ -17,6 +17,7 @@
#include <base/log.h>
#include <input/event_queue.h>
#include <input/keycodes.h>
#include <timer_session/connection.h>
#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;

View File

@ -20,6 +20,7 @@
#include <input/component.h>
#include <input/root.h>
#include <platform_session/connection.h>
#include <timer_session/connection.h>
/* 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) };