dev: -Wdeprecated-copy not available on all supported compilers
[gem5.git] / src / dev / ps2 / touchkit.cc
index 96dd2e9c70af5bf78cb38de0af596c9d457ed507..d772b2cb6807a47ab616bdd496c58458e78c481b 100644 (file)
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Authors: Ali Saidi
- *          William Wang
- *          Andreas Sandberg
  */
 
 #include "dev/ps2/touchkit.hh"
 
 #include "base/logging.hh"
+#include "base/trace.hh"
 #include "debug/PS2.hh"
-#include "dev/ps2.hh"
+#include "dev/ps2/types.hh"
 #include "params/PS2TouchKit.hh"
 
-const uint8_t PS2TouchKit::ID[] = {0x00};
-
-PS2TouchKit::PS2TouchKit(const PS2TouchKitParams *p)
+PS2TouchKit::PS2TouchKit(const PS2TouchKitParams &p)
     : PS2Device(p),
-      vnc(p->vnc),
-      ackNext(false),
-      driverInitialized(false)
+      vnc(p.vnc),
+      enabled(false), touchKitEnabled(false)
 {
     if (vnc)
         vnc->setMouse(this);
@@ -66,8 +60,8 @@ PS2TouchKit::serialize(CheckpointOut &cp) const
 {
     PS2Device::serialize(cp);
 
-    SERIALIZE_SCALAR(ackNext);
-    SERIALIZE_SCALAR(driverInitialized);
+    SERIALIZE_SCALAR(enabled);
+    SERIALIZE_SCALAR(touchKitEnabled);
 }
 
 void
@@ -75,76 +69,119 @@ PS2TouchKit::unserialize(CheckpointIn &cp)
 {
     PS2Device::unserialize(cp);
 
-    UNSERIALIZE_SCALAR(ackNext);
-    UNSERIALIZE_SCALAR(driverInitialized);
+    UNSERIALIZE_SCALAR(enabled);
+    UNSERIALIZE_SCALAR(touchKitEnabled);
 }
 
-void
-PS2TouchKit::recv(uint8_t data)
+bool
+PS2TouchKit::recv(const std::vector<uint8_t> &data)
 {
-    if (ackNext) {
-        ackNext--;
+    switch (data[0]) {
+      case Ps2::Reset:
+        DPRINTF(PS2, "Resetting device.\n");
+        enabled = false;
+        touchKitEnabled = false;
         sendAck();
-        return;
-    }
+        send(Ps2::SelfTestPass);
+        return true;
 
-    switch (data) {
-      case Ps2::Ps2Reset:
+      case Ps2::ReadID:
         sendAck();
-        send(Ps2::SelfTestPass);
-        break;
+        send(Ps2::Mouse::ID);
+        return true;
 
-      case Ps2::SetResolution:
-      case Ps2::SetRate:
-      case Ps2::SetStatusLed:
+      case Ps2::Disable:
+        DPRINTF(PS2, "Disabling device.\n");
+        enabled = false;
         sendAck();
-        ackNext = 1;
-        break;
+        return true;
 
-      case Ps2::ReadId:
+      case Ps2::Enable:
+        DPRINTF(PS2, "Enabling device.\n");
+        enabled = true;
         sendAck();
-        send((const uint8_t *)&ID, sizeof(ID));
-        break;
+        return true;
 
-      case Ps2::TpReadId:
-        // We're not a trackpoint device, this should make the probe
-        // go away
+      case Ps2::DefaultsAndDisable:
+        DPRINTF(PS2, "Setting defaults and disabling device.\n");
+        enabled = false;
         sendAck();
-        send(0);
-        send(0);
+        return true;
+
+      case Ps2::Mouse::Scale1to1:
+      case Ps2::Mouse::Scale2to1:
         sendAck();
-        break;
+        return true;
 
-      case Ps2::SetScaling1_1:
-      case Ps2::SetScaling1_2:
-      case Ps2::Disable:
-      case Ps2::Enable:
-      case Ps2::SetDefaults:
+      case Ps2::Mouse::SetResolution:
+      case Ps2::Mouse::SampleRate:
         sendAck();
-        break;
+        return data.size() == 2;
 
-      case Ps2::StatusRequest:
+      case Ps2::Mouse::GetStatus:
         sendAck();
         send(0);
         send(2); // default resolution
         send(100); // default sample rate
-        break;
+        return true;
 
-      case Ps2::TouchKitId:
-        ackNext = 2;
+      case TpReadId:
+        // We're not a trackpoint device, this should make the probe
+        // go away
+        sendAck();
+        send(0);
+        send(0);
         sendAck();
-        send(Ps2::TouchKitId);
-        send(1);
-        send('A');
+        return true;
+
+      case TouchKitDiag:
+        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] == TouchKitDiag);
+    if (data.size() < 3 || data.size() - 2 < data[1])
+        return false;
+
+    const uint8_t len = data[1];
+    const uint8_t cmd = data[2];
 
-        driverInitialized = true;
-        break;
+    // 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);
+        panic("Unimplemented touchscreen command: %#x\n", cmd);
     }
 }
 
+void
+PS2TouchKit::sendTouchKit(const uint8_t *data, size_t size)
+{
+    send(TouchKitDiag);
+    send(size);
+    for (int i = 0; i < size; ++i)
+        send(data[i]);
+}
+
+
 void
 PS2TouchKit::mouseAt(uint16_t x, uint16_t y, uint8_t buttons)
 {
@@ -152,7 +189,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
@@ -167,9 +204,3 @@ PS2TouchKit::mouseAt(uint16_t x, uint16_t y, uint8_t buttons)
 
     send(resp, sizeof(resp));
 }
-
-PS2TouchKit *
-PS2TouchKitParams::create()
-{
-    return new PS2TouchKit(this);
-}