94 lines
2.3 KiB
C
94 lines
2.3 KiB
C
|
/*
|
||
|
* \brief EETI eGalaxy touchscreen driver
|
||
|
* \author Stefan Kalkowski
|
||
|
* \date 2013-03-15
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* Copyright (C) 2013 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.
|
||
|
*/
|
||
|
|
||
|
#ifndef _EGALAX_TS_H_
|
||
|
#define _EGALAX_TS_H_
|
||
|
|
||
|
/* Genode includes */
|
||
|
#include <drivers/board_base.h>
|
||
|
#include <os/attached_io_mem_dataspace.h>
|
||
|
#include <input/event_queue.h>
|
||
|
#include <input/event.h>
|
||
|
#include <input/keycodes.h>
|
||
|
|
||
|
/* local includes */
|
||
|
#include <i2c.h>
|
||
|
|
||
|
namespace Input {
|
||
|
class Touchscreen;
|
||
|
}
|
||
|
|
||
|
|
||
|
class Input::Touchscreen {
|
||
|
|
||
|
private:
|
||
|
|
||
|
enum I2c_addresses { I2C_ADDR = 0x4 };
|
||
|
enum Finger_state { PRESSED, RELEASED };
|
||
|
|
||
|
Genode::Attached_io_mem_dataspace _i2c_ds;
|
||
|
I2c::I2c _i2c;
|
||
|
Genode::uint8_t _buf[10];
|
||
|
Finger_state _state;
|
||
|
|
||
|
public:
|
||
|
|
||
|
Touchscreen() : _i2c_ds(Genode::Board_base::I2C_3_BASE,
|
||
|
Genode::Board_base::I2C_3_SIZE),
|
||
|
_i2c((Genode::addr_t)_i2c_ds.local_addr<void>(),
|
||
|
Genode::Board_base::I2C_3_IRQ),
|
||
|
_state(RELEASED)
|
||
|
{
|
||
|
/* ask for touchscreen firmware version */
|
||
|
Genode::uint8_t cmd[10] = { 0x03, 0x03, 0xa, 0x01, 0x41 };
|
||
|
_i2c.send(I2C_ADDR, cmd, sizeof(cmd));
|
||
|
}
|
||
|
|
||
|
void event(Event_queue &ev_queue)
|
||
|
{
|
||
|
_i2c.recv(I2C_ADDR, _buf, sizeof(_buf));
|
||
|
|
||
|
/* ignore all events except of multitouch*/
|
||
|
if (_buf[0] != 4)
|
||
|
return;
|
||
|
|
||
|
int x = (_buf[3] << 8) | _buf[2];
|
||
|
int y = (_buf[5] << 8) | _buf[4];
|
||
|
|
||
|
Genode::uint8_t state = _buf[1];
|
||
|
bool valid = state & (1 << 7);
|
||
|
int id = (state >> 2) & 0xf;
|
||
|
int down = state & 1;
|
||
|
|
||
|
if (!valid || id > 5)
|
||
|
return; /* invalid point */
|
||
|
|
||
|
x = 102400 / (3276700 / x);
|
||
|
y = 76800 / (3276700 / y);
|
||
|
|
||
|
/* motion event */
|
||
|
ev_queue.add(Input::Event(Input::Event::MOTION, 0, x, y, 0, 0));
|
||
|
|
||
|
/* button event */
|
||
|
if ((down && (_state == RELEASED)) ||
|
||
|
(!down && (_state == PRESSED))) {
|
||
|
ev_queue.add(Input::Event(down ? Input::Event::PRESS
|
||
|
: Input::Event::RELEASE,
|
||
|
Input::BTN_LEFT, 0, 0, 0, 0));
|
||
|
_state = down ? PRESSED : RELEASED;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
#endif /* _EGALAX_TS_H_ */
|