diff options
author | Andreas Sandberg <andreas.sandberg@arm.com> | 2018-04-09 22:24:31 +0000 |
---|---|---|
committer | Andreas Sandberg <andreas.sandberg@arm.com> | 2018-04-17 11:19:44 +0000 |
commit | 68f99c93808ac4d8e12e39c87acec89d422fd8b4 (patch) | |
tree | 9222c9d26c87d1ec419a7398f65250abe56f343f | |
parent | 7789e9aa75ba82a0bc52dc8b2b44fa9b16234173 (diff) | |
download | gem5-68f99c93808ac4d8e12e39c87acec89d422fd8b4.tar.xz |
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>
-rw-r--r-- | src/dev/ps2/touchkit.cc | 84 | ||||
-rw-r--r-- | src/dev/ps2/touchkit.hh | 19 |
2 files changed, 82 insertions, 21 deletions
diff --git a/src/dev/ps2/touchkit.cc b/src/dev/ps2/touchkit.cc index fd81c5758..819b06c5d 100644 --- a/src/dev/ps2/touchkit.cc +++ b/src/dev/ps2/touchkit.cc @@ -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,33 +141,61 @@ 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: %#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("Unknown byte received: %d\n", data[0]); + 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) { // If the driver hasn't initialized the device yet, no need to try and send // 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 diff --git a/src/dev/ps2/touchkit.hh b/src/dev/ps2/touchkit.hh index fa1bc52a4..dc98a78fa 100644 --- a/src/dev/ps2/touchkit.hh +++ b/src/dev/ps2/touchkit.hh @@ -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__ |