genode/dde_linux/src/drivers/usb/input/input_component.cc
Sebastian Sumpf 9f73476b37 New DDE-Linux-based USB driver
The new 'dde_linux' repository will host device drivers ported from the
Linux kernel. In contrast to the original 'linux_drivers' repository,
'dde_linux' does not contain any 3rd-party source code. To download the
Linux kernel source code and extract the drivers, execute the 'make
prepare' rule of the top-level Makefile. The initial version of the
'dde_linux' repository comes with an USB driver. The porting methodology
follows the path of the Intel GEM port. Instead of attempting to provide
a generic Linux environment that works across drivers, each driver comes
with a specially tailored DDE.

The DDE consists of Genode-specific implementations of Linux API
functions as declared in 'lx_emul.h'. Most of these functions are
dummies that must merely be provided to resolve dependencies at the
linking stage. They are called by unused code-paths.

As of now, the USB driver support UHCI, EHCI on the x86_32 platform. I
exposes USB HID devices and USB storage devices via Genode's input-session
and block-session respectively.

The USB driver is accompanied with two run scripts 'run/usb_hid.run' and
'run/usb_storage.run'.
2012-05-29 13:54:58 +02:00

78 lines
1.9 KiB
C++

/*
* \brief Linux 2.6 Input driver for USB HID
* \author Christian Helmuth
* \author Christian Prochaska
* \author Sebastian Sumpf
* \date 2011-07-15
*/
/*
* Copyright (C) 2011-2012 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <base/printf.h>
#include <base/rpc_server.h>
#include <input/component.h>
#include <os/ring_buffer.h>
#include <lx_emul.h>
#undef RELEASE
using namespace Genode;
/*********************
** Input component **
*********************/
typedef Ring_buffer<Input::Event, 512> Input_ring_buffer;
static Input_ring_buffer ev_queue;
namespace Input {
void event_handling(bool enable) { }
bool event_pending() { return !ev_queue.empty(); }
Event get_event() { return ev_queue.get(); }
}
/**
* Input event call-back function
*/
static void input_callback(enum input_event_type type,
unsigned keycode,
int absolute_x, int absolute_y,
int relative_x, int relative_y)
{
Input::Event::Type t = Input::Event::INVALID;
switch (type) {
case EVENT_TYPE_PRESS: t = Input::Event::PRESS; break;
case EVENT_TYPE_RELEASE: t = Input::Event::RELEASE; break;
case EVENT_TYPE_MOTION: t = Input::Event::MOTION; break;
case EVENT_TYPE_WHEEL: t = Input::Event::WHEEL; break;
}
try {
ev_queue.add(Input::Event(t, keycode,
absolute_x, absolute_y,
relative_x, relative_y));
} catch (Input_ring_buffer::Overflow) {
PWRN("input ring buffer overflow");
}
}
void start_input_service(void *ep)
{
Rpc_entrypoint *e = static_cast<Rpc_entrypoint *>(ep);
static Input::Root input_root(e, env()->heap());
env()->parent()->announce(e->manage(&input_root));
genode_input_register(input_callback);
}