mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-07 19:34:56 +00:00
os: move synaptics_dsx touch driver to imx repo
Ref genodelabs/genode#5252
This commit is contained in:
parent
6162eae9e0
commit
86386548c0
@ -1,183 +0,0 @@
|
||||
/*
|
||||
* \brief Driver for the i.MX53 i2c controller
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2013-03-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _DRIVERS__INPUT__SPEC__IMX53__I2C_H_
|
||||
#define _DRIVERS__INPUT__SPEC__IMX53__I2C_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <platform_session/device.h>
|
||||
#include <timer_session/connection.h>
|
||||
|
||||
/* local includes */
|
||||
#include "irq_handler.h"
|
||||
|
||||
namespace I2c
|
||||
{
|
||||
class I2c;
|
||||
}
|
||||
|
||||
|
||||
class I2c::I2c : Platform::Device::Mmio<0x12>
|
||||
{
|
||||
private:
|
||||
|
||||
struct Address : public Register<0x0, 16>
|
||||
{
|
||||
struct Addr : Bitfield<1,7> {};
|
||||
};
|
||||
|
||||
struct Freq_divider : public Register<0x4, 16> {};
|
||||
|
||||
struct Control : public Register<0x8, 16>
|
||||
{
|
||||
struct Repeat_start : Bitfield<2,1> {};
|
||||
struct Tx_ack_enable : Bitfield<3,1> {};
|
||||
struct Tx_rx_select : Bitfield<4,1> {};
|
||||
struct Master_slave_select : Bitfield<5,1> {};
|
||||
struct Irq_enable : Bitfield<6,1> {};
|
||||
struct Enable : Bitfield<7,1> {};
|
||||
};
|
||||
|
||||
struct Status : public Register<0xc, 16>
|
||||
{
|
||||
struct Rcv_ack : Bitfield<0,1> {};
|
||||
struct Irq : Bitfield<1,1> {};
|
||||
struct Slave_rw : Bitfield<2,1> {};
|
||||
struct Arbitration_lost : Bitfield<4,1> {};
|
||||
struct Busy : Bitfield<5,1> {};
|
||||
struct Addressed_as_slave : Bitfield<6,1> {};
|
||||
struct Data_transfer : Bitfield<7,1> {};
|
||||
};
|
||||
|
||||
struct Data : public Register<0x10, 16> { };
|
||||
|
||||
|
||||
class No_ack : Genode::Exception {};
|
||||
|
||||
Irq_handler _irq_handler;
|
||||
|
||||
void _busy() { while (!read<Status::Busy>()); }
|
||||
|
||||
void _start()
|
||||
{
|
||||
/* clock enable */
|
||||
/* input root 90 is 25Mhz target is 400Khz, divide by 64 */
|
||||
write<Freq_divider>(0x2a);
|
||||
write<Status>(0);
|
||||
write<Control>(Control::Enable::bits(1));
|
||||
|
||||
while (!read<Control::Enable>()) { ; }
|
||||
|
||||
write<Control::Master_slave_select>(1);
|
||||
|
||||
_busy();
|
||||
|
||||
write<Control>(Control::Tx_rx_select::bits(1) |
|
||||
Control::Tx_ack_enable::bits(1) |
|
||||
Control::Irq_enable::bits(1) |
|
||||
Control::Master_slave_select::bits(1) |
|
||||
Control::Enable::bits(1));
|
||||
}
|
||||
|
||||
void _stop()
|
||||
{
|
||||
write<Control>(0);
|
||||
|
||||
/* clock disable */
|
||||
}
|
||||
|
||||
void _write(Genode::uint8_t value)
|
||||
{
|
||||
write<Data>(value);
|
||||
|
||||
do { _irq_handler.wait(); }
|
||||
while (!read<Status::Irq>());
|
||||
|
||||
write<Status::Irq>(0);
|
||||
_irq_handler.ack();
|
||||
|
||||
if (read<Status::Rcv_ack>()) throw No_ack();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
I2c(Genode::Env & env, Platform::Device & dev)
|
||||
: Platform::Device::Mmio<SIZE>(dev, {0}),
|
||||
_irq_handler(env, dev)
|
||||
{
|
||||
write<Control>(0);
|
||||
write<Status>(0);
|
||||
}
|
||||
|
||||
void send(Genode::uint8_t addr, const Genode::uint8_t *buf,
|
||||
Genode::size_t num)
|
||||
{
|
||||
while (true) {
|
||||
try {
|
||||
_start();
|
||||
|
||||
_write(addr << 1);
|
||||
for (Genode::size_t i = 0; i < num; i++)
|
||||
_write(buf[i]);
|
||||
_stop();
|
||||
return;
|
||||
} catch(No_ack) { }
|
||||
_stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void recv(Genode::uint8_t addr, Genode::uint8_t *buf,
|
||||
Genode::size_t num)
|
||||
{
|
||||
while (true) {
|
||||
try {
|
||||
_start();
|
||||
|
||||
_write((Genode::uint8_t)(addr << 1 | 1));
|
||||
|
||||
write<Control::Tx_rx_select>(0);
|
||||
if (num > 1)
|
||||
write<Control::Tx_ack_enable>(0);
|
||||
read<Data>(); /* dummy read */
|
||||
|
||||
for (Genode::size_t i = 0; i < num; i++) {
|
||||
|
||||
do { _irq_handler.wait(); }
|
||||
while (!read<Status::Irq>());
|
||||
|
||||
write<Status::Irq>(0);
|
||||
|
||||
if (i == num-1) {
|
||||
write<Control::Tx_rx_select>(0);
|
||||
write<Control::Master_slave_select>(0);
|
||||
while (read<Status::Busy>()) ;
|
||||
} else if (i == num-2) {
|
||||
write<Control::Tx_ack_enable>(1);
|
||||
}
|
||||
|
||||
buf[i] = (Genode::uint8_t)read<Data>();
|
||||
_irq_handler.ack();
|
||||
}
|
||||
|
||||
_stop();
|
||||
return;
|
||||
} catch(No_ack) {
|
||||
Genode::log("no ack");
|
||||
_stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _DRIVERS__INPUT__SPEC__IMX53__I2C_H_ */
|
@ -1,52 +0,0 @@
|
||||
/*
|
||||
* \brief Input-interrupt handler
|
||||
* \author Josef Soentgen
|
||||
* \date 2015-04-08
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _IRQ_HANDLER_H_
|
||||
#define _IRQ_HANDLER_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <platform_session/device.h>
|
||||
|
||||
class Irq_handler
|
||||
{
|
||||
private:
|
||||
|
||||
unsigned _sem_cnt = 1;
|
||||
|
||||
void _handle() { _sem_cnt = 0; }
|
||||
|
||||
Platform::Device::Irq _irq;
|
||||
Genode::Entrypoint & _ep;
|
||||
Genode::Io_signal_handler<Irq_handler> _handler { _ep, *this, &Irq_handler::_handle };
|
||||
|
||||
public:
|
||||
|
||||
Irq_handler(Genode::Env & env, Platform::Device & dev)
|
||||
:
|
||||
_irq(dev, { 0 }), _ep(env.ep())
|
||||
{
|
||||
_irq.sigh(_handler);
|
||||
_irq.ack();
|
||||
}
|
||||
|
||||
void wait()
|
||||
{
|
||||
_sem_cnt++;
|
||||
while (_sem_cnt > 0)
|
||||
_ep.wait_and_dispatch_one_io_signal();
|
||||
}
|
||||
|
||||
void ack() { _irq.ack(); }
|
||||
};
|
||||
|
||||
#endif /* _IRQ_HANDLER_H_ */
|
@ -1,156 +0,0 @@
|
||||
/**
|
||||
* \brief Synaptics DSX touch input
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2020-09-03
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2020 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/attached_dataspace.h>
|
||||
#include <base/component.h>
|
||||
#include <base/env.h>
|
||||
|
||||
#include <event_session/connection.h>
|
||||
#include <gpio_session/connection.h>
|
||||
#include <platform_session/device.h>
|
||||
#include <i2c.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
struct Finger_data
|
||||
{
|
||||
uint8_t status;
|
||||
uint8_t x_lsb;
|
||||
uint8_t x_msb;
|
||||
uint8_t y_lsb;
|
||||
uint8_t y_msb;
|
||||
uint8_t wx;
|
||||
uint8_t wy;
|
||||
|
||||
unsigned x() const
|
||||
{
|
||||
return 1080 - ((x_msb << 8) | x_lsb);
|
||||
}
|
||||
|
||||
unsigned y() const
|
||||
{
|
||||
return 1920 - ((y_msb << 8) | y_lsb);
|
||||
}
|
||||
|
||||
void dump() const
|
||||
{
|
||||
log("status: ", Hex(status),
|
||||
" x_lsb: ", x_lsb, " x_msb: ", x_msb,
|
||||
" y_lsb: ", y_lsb, " y_msb: ", y_msb,
|
||||
" wx: ", wx, " wy: ", wy,
|
||||
" x: ", x(),
|
||||
" y: ", y());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct Synaptics
|
||||
{
|
||||
enum { FINGERS = 5, I2C_ADDR = 0x20, };
|
||||
enum Gpio_irq { IRQ = 135 };
|
||||
|
||||
Genode::Env &env;
|
||||
I2c::I2c _i2c;
|
||||
Gpio::Connection _gpio { env, IRQ };
|
||||
Irq_session_client _irq { _gpio.irq_session(Gpio::Session::LOW_LEVEL) };
|
||||
Io_signal_handler<Synaptics> _irq_dispatcher { env.ep(), *this, &Synaptics::_handle_irq };
|
||||
Event::Connection _event { env };
|
||||
uint8_t _buf[10];
|
||||
bool _button[FINGERS] { };
|
||||
|
||||
void _handle_event(Event::Session_client::Batch &batch)
|
||||
{
|
||||
/* retrieve status */
|
||||
Finger_data fingers[FINGERS];
|
||||
_buf[0] = 6;
|
||||
_i2c.send(I2C_ADDR, _buf, 1);
|
||||
_i2c.recv(I2C_ADDR, (uint8_t *)fingers, sizeof(fingers));
|
||||
|
||||
for (unsigned i = 0; i < FINGERS; i++) {
|
||||
Finger_data ¤t = fingers[i];
|
||||
|
||||
Input::Touch_id id { i };
|
||||
|
||||
if (current.status == 0) {
|
||||
if (_button[i]) {
|
||||
batch.submit(Input::Release{Input::BTN_LEFT});
|
||||
batch.submit(Input::Touch_release{id});
|
||||
_button[i] = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
batch.submit(Input::Absolute_motion { (int)current.x(), (int)current.y() });
|
||||
batch.submit(Input::Touch { id, (float)current.x(), (float)current.y() });
|
||||
|
||||
if (_button[i] == false) {
|
||||
batch.submit(Input::Press { Input::BTN_LEFT });
|
||||
}
|
||||
_button[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
void _handle_irq()
|
||||
{
|
||||
/* read device IRQ */
|
||||
_buf[0] = 4;
|
||||
_i2c.send(I2C_ADDR, _buf, 1);
|
||||
_i2c.recv(I2C_ADDR, _buf, 2);
|
||||
|
||||
_event.with_batch([&] (Event::Session_client::Batch &batch) {
|
||||
_handle_event(batch);
|
||||
});
|
||||
|
||||
_irq.ack_irq();
|
||||
}
|
||||
|
||||
Synaptics(Env &env, Platform::Device & i2c_dev)
|
||||
: env(env), _i2c(env, i2c_dev)
|
||||
{
|
||||
|
||||
/* set page 0 */
|
||||
_buf[0] = 0xff;
|
||||
_buf[1] = 0;
|
||||
_i2c.send(I2C_ADDR, _buf, 2);
|
||||
|
||||
/* enable interrupt */
|
||||
_buf[0] = 0xf;
|
||||
_buf[1] = 0x16;
|
||||
_i2c.send(I2C_ADDR, _buf, 2);
|
||||
|
||||
/* set configured */
|
||||
_buf[0] = 0xe;
|
||||
_buf[1] = 0x84;
|
||||
_i2c.send(I2C_ADDR, _buf, 2);
|
||||
|
||||
/* GPIO touchscreen handling */
|
||||
_gpio.direction(Gpio::Session::IN);
|
||||
|
||||
_irq.sigh(_irq_dispatcher);
|
||||
_irq.ack_irq();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct Main
|
||||
{
|
||||
Genode::Env & _env;
|
||||
Platform::Connection _platform { _env };
|
||||
Platform::Device _device { _platform };
|
||||
Synaptics _synaptics { _env, _device };
|
||||
|
||||
Main(Env &env) : _env(env) { }
|
||||
};
|
||||
|
||||
void Component::construct(Genode::Env &env) { static Main main(env); }
|
@ -1,5 +0,0 @@
|
||||
TARGET = imx8_synaptics_touch
|
||||
REQUIRES = arm_v8
|
||||
SRC_CC = main.cc
|
||||
LIBS = base
|
||||
INC_DIR += $(PRG_DIR)
|
Loading…
x
Reference in New Issue
Block a user