os: move synaptics_dsx touch driver to imx repo

Ref genodelabs/genode#5252
This commit is contained in:
Stefan Kalkowski 2024-06-19 13:55:09 +02:00 committed by Norman Feske
parent 6162eae9e0
commit 86386548c0
4 changed files with 0 additions and 396 deletions

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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 &current = 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); }

View File

@ -1,5 +0,0 @@
TARGET = imx8_synaptics_touch
REQUIRES = arm_v8
SRC_CC = main.cc
LIBS = base
INC_DIR += $(PRG_DIR)