ps2: Add proper touchscreen command handling

The touchscreen model used ad-hoc mechanisms to enable/disable the
device. Use standard PS/2 commands to activate/deactivate the
device. Add proper TouchKit command handling.

Change-Id: I0c5a2e2b47639f36ab3ee07e3e559f11afa54b9d
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/9768
Reviewed-by: Gabe Black <gabeblack@google.com>
This commit is contained in:
Andreas Sandberg
2018-04-09 22:24:31 +00:00
parent 7789e9aa75
commit 68f99c9380
2 changed files with 82 additions and 21 deletions

View File

@@ -54,7 +54,7 @@ const uint8_t PS2TouchKit::ID[] = {0x00};
PS2TouchKit::PS2TouchKit(const PS2TouchKitParams *p)
: PS2Device(p),
vnc(p->vnc),
driverInitialized(false)
enabled(false), touchKitEnabled(false)
{
if (vnc)
vnc->setMouse(this);
@@ -65,7 +65,8 @@ PS2TouchKit::serialize(CheckpointOut &cp) const
{
PS2Device::serialize(cp);
SERIALIZE_SCALAR(driverInitialized);
SERIALIZE_SCALAR(enabled);
SERIALIZE_SCALAR(touchKitEnabled);
}
void
@@ -73,7 +74,8 @@ PS2TouchKit::unserialize(CheckpointIn &cp)
{
PS2Device::unserialize(cp);
UNSERIALIZE_SCALAR(driverInitialized);
UNSERIALIZE_SCALAR(enabled);
UNSERIALIZE_SCALAR(touchKitEnabled);
}
bool
@@ -81,6 +83,9 @@ PS2TouchKit::recv(const std::vector<uint8_t> &data)
{
switch (data[0]) {
case Ps2::Ps2Reset:
DPRINTF(PS2, "Resetting device.\n");
enabled = false;
touchKitEnabled = false;
sendAck();
send(Ps2::SelfTestPass);
return true;
@@ -107,9 +112,24 @@ PS2TouchKit::recv(const std::vector<uint8_t> &data)
case Ps2::SetScaling1_1:
case Ps2::SetScaling1_2:
sendAck();
return true;
case Ps2::Disable:
DPRINTF(PS2, "Disabling device.\n");
enabled = false;
sendAck();
return true;
case Ps2::Enable:
DPRINTF(PS2, "Enabling device.\n");
enabled = true;
sendAck();
return true;
case Ps2::SetDefaults:
DPRINTF(PS2, "Setting defaults and disabling device.\n");
enabled = false;
sendAck();
return true;
@@ -121,25 +141,53 @@ PS2TouchKit::recv(const std::vector<uint8_t> &data)
return true;
case Ps2::TouchKitId:
sendAck();
if (data.size() == 1) {
send(Ps2::TouchKitId);
send(1);
send('A');
return false;
} else if (data.size() == 3) {
driverInitialized = true;
return true;
} else {
return false;
}
return recvTouchKit(data);
default:
panic("Unknown byte received: %d\n", data[0]);
panic("Unknown byte received: %#x\n", data[0]);
}
}
bool
PS2TouchKit::recvTouchKit(const std::vector<uint8_t> &data)
{
// Ack all incoming bytes
sendAck();
// Packet format is: 0x0A SIZE CMD DATA
assert(data[0] == Ps2::TouchKitId);
if (data.size() < 3 || data.size() - 2 < data[1])
return false;
const uint8_t len = data[1];
const uint8_t cmd = data[2];
// We have received at least one TouchKit diagnostic
// command. Enabled TouchKit reports.
touchKitEnabled = true;
switch (cmd) {
case TouchKitActive:
warn_if(len != 1, "Unexpected activate packet length: %u\n", len);
sendTouchKit('A');
return true;
default:
panic("Unimplemented touchscreen command: %#x\n", cmd);
}
}
void
PS2TouchKit::sendTouchKit(const uint8_t *data, size_t size)
{
send(Ps2::TouchKitId);
send(size);
for (int i = 0; i < size; ++i)
send(data[i]);
}
void
PS2TouchKit::mouseAt(uint16_t x, uint16_t y, uint8_t buttons)
{
@@ -147,7 +195,7 @@ PS2TouchKit::mouseAt(uint16_t x, uint16_t y, uint8_t buttons)
// it anything. Similarly we can get vnc mouse events orders of magnitude
// faster than m5 can process them. Only queue up two sets mouse movements
// and don't add more until those are processed.
if (!driverInitialized || sendPending() > 10)
if (!enabled || !touchKitEnabled || sendPending() > 10)
return;
// Convert screen coordinates to touchpad coordinates

View File

@@ -50,6 +50,12 @@ class PS2TouchKit : public PS2Device, public VncMouse
protected:
static const uint8_t ID[];
enum TKCommands {
TouchKitActive = 'A',
TouchKitFWRev = 'D',
TouchKitCtrlType = 'E',
};
public:
PS2TouchKit(const PS2TouchKitParams *p);
@@ -63,14 +69,21 @@ class PS2TouchKit : public PS2Device, public VncMouse
void mouseAt(uint16_t x, uint16_t y, uint8_t buttons) override;
protected:
bool recvTouchKit(const std::vector<uint8_t> &data);
void sendTouchKit(const uint8_t *data, size_t size);
void sendTouchKit(uint8_t data) { sendTouchKit(&data, 1); }
/** The vnc server we're connected to (if any) */
VncInput *const vnc;
/** Is the device enabled? */
bool enabled;
/**
* Has the driver been initialized in TouchKit mode? The model
* suppresses touch event generation until this is true.
* Has the driver enabled TouchKit mode? The model suppresses
* touch event generation until this is true.
*/
bool driverInitialized;
bool touchKitEnabled;
};
#endif // __DEV_PS2_TOUCHKIT_HH__