rpi: register callback for HPD. re-read the physical address when we received VC_HDMI...
authorLars Op den Kamp <lars@opdenkamp.eu>
Mon, 25 Feb 2013 00:47:07 +0000 (01:47 +0100)
committerLars Op den Kamp <lars@opdenkamp.eu>
Mon, 25 Feb 2013 00:53:58 +0000 (01:53 +0100)
src/lib/CECProcessor.cpp
src/lib/CECProcessor.h
src/lib/adapter/AdapterCommunication.h
src/lib/adapter/RPi/RPiCECAdapterCommunication.cpp
src/lib/adapter/RPi/RPiCECAdapterCommunication.h

index 3be1c36cdb52c3996ce092302dd157797b6772dc..d9ef22c349285c58aa93247f605227625416dc2e 100644 (file)
@@ -988,6 +988,14 @@ void CCECProcessor::HandleLogicalAddressLost(cec_logical_address oldAddress)
   }
 }
 
+void CCECProcessor::HandlePhysicalAddressChanged(uint16_t iNewAddress)
+{
+  m_libcec->AddLog(CEC_LOG_NOTICE, "physical address changed to %04x", iNewAddress);
+  CCECClient* client = GetPrimaryClient();
+  if (client)
+    client->SetPhysicalAddress(iNewAddress);
+}
+
 uint16_t CCECProcessor::GetAdapterVendorId(void) const
 {
   return m_communication ? m_communication->GetAdapterVendorId() : 0;
index 69586a7cb8fd47f7f010223ad40eb58d5195b0a4..e57ddddd4063cacbde6ec59653361a25175a0483 100644 (file)
@@ -83,6 +83,7 @@ namespace CEC
 
       bool                  OnCommandReceived(const cec_command &command);
       void                  HandleLogicalAddressLost(cec_logical_address oldAddress);
+      void                  HandlePhysicalAddressChanged(uint16_t iNewAddress);
 
       CCECBusDevice *       GetDevice(cec_logical_address address) const;
       CCECAudioSystem *     GetAudioSystem(void) const;
index b1762b7a111db0755c03ede6922cf4e7ac785ae8..223e65fca4abf0ad3b67c0d904c7ed9fe403bc58 100644 (file)
@@ -81,6 +81,12 @@ namespace CEC
      */
     virtual void HandleLogicalAddressLost(cec_logical_address oldAddress) = 0;
 
+    /*!
+     * @brief Callback method for IAdapterCommunication, called when the physical address changed.
+     * @param iNewAddress The new physical address.
+     */
+    virtual void HandlePhysicalAddressChanged(uint16_t iNewAddress) = 0;
+
     virtual CLibCEC *GetLib(void) const = 0;
   };
 
index 1a2da3afad187ccf08251513311ee5436388fff4..f15b1c0baad3b1dd9f8404182f229992c064d122 100644 (file)
@@ -58,6 +58,13 @@ void rpi_cec_callback(void *callback_data, uint32_t p0, uint32_t p1, uint32_t p2
     static_cast<CRPiCECAdapterCommunication *>(callback_data)->OnDataReceived(p0, p1, p2, p3, p4);
 }
 
+// callback for the TV service
+void rpi_tv_callback(void *callback_data, uint32_t reason, uint32_t p0, uint32_t p1)
+{
+  if (callback_data)
+    static_cast<CRPiCECAdapterCommunication *>(callback_data)->OnTVServiceCallback(reason, p0, p1);
+}
+
 CRPiCECAdapterCommunication::CRPiCECAdapterCommunication(IAdapterCommunicationCallback *callback) :
     IAdapterCommunication(callback),
     m_logicalAddress(CECDEVICE_UNKNOWN),
@@ -107,6 +114,32 @@ bool CRPiCECAdapterCommunication::IsInitialised(void)
   return m_bInitialised;
 }
 
+void CRPiCECAdapterCommunication::OnTVServiceCallback(uint32_t reason, uint32_t UNUSED(p0), uint32_t UNUSED(p1))
+{
+  switch(reason)
+  {
+  case VC_HDMI_UNPLUGGED:
+  {
+    m_callback->HandlePhysicalAddressChanged(0x1000);
+    break;
+  }
+  case VC_HDMI_ATTACHED:
+  {
+    uint16_t iNewAddress = GetPhysicalAddress();
+    m_callback->HandlePhysicalAddressChanged(iNewAddress);
+    break;
+  }
+  case VC_HDMI_DVI:
+  case VC_HDMI_HDMI:
+  case VC_HDMI_HDCP_UNAUTH:
+  case VC_HDMI_HDCP_AUTH:
+  case VC_HDMI_HDCP_KEY_DOWNLOAD:
+  case VC_HDMI_HDCP_SRM_DOWNLOAD:
+  default:
+     break;
+  }
+}
+
 void CRPiCECAdapterCommunication::OnDataReceived(uint32_t header, uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3)
 {
   VC_CEC_NOTIFY_T reason = (VC_CEC_NOTIFY_T)CEC_CB_REASON(header);
@@ -260,7 +293,7 @@ int CRPiCECAdapterCommunication::InitHostCEC(void)
   return VCHIQ_SUCCESS;
 }
 
-bool CRPiCECAdapterCommunication::Open(uint32_t iTimeoutMs /* = CEC_DEFAULT_CONNECT_TIMEOUT */, bool UNUSED(bSkipChecks) /* = false */, bool bStartListening)
+bool CRPiCECAdapterCommunication::Open(uint32_t UNUSED(iTimeoutMs) /* = CEC_DEFAULT_CONNECT_TIMEOUT */, bool UNUSED(bSkipChecks) /* = false */, bool bStartListening)
 {
   Close();
 
@@ -272,8 +305,9 @@ bool CRPiCECAdapterCommunication::Open(uint32_t iTimeoutMs /* = CEC_DEFAULT_CONN
     // enable passive mode
     vc_cec_set_passive(true);
 
-    // register the callback
-    vc_cec_register_callback(((CECSERVICE_CALLBACK_T)rpi_cec_callback), (void*)this);
+    // register the callbacks
+    vc_cec_register_callback(rpi_cec_callback, (void*)this);
+    vc_tv_register_callback(rpi_tv_callback, (void*)this);
 
     // register LA "freeuse"
     if (RegisterLogicalAddress(CECDEVICE_FREEUSE))
@@ -315,6 +349,8 @@ void CRPiCECAdapterCommunication::Close(void)
     else
       return;
   }
+  vc_tv_unregister_callback(rpi_tv_callback);
+
   UnregisterLogicalAddress();
 
   // disable passive mode
index 9a0a9fd62f4e7a22966130893dd1f0716a5d0594..fa43894b3f6f10295afd7977add3ea3416bf6d42 100644 (file)
@@ -90,6 +90,7 @@ namespace CEC
 
     bool IsInitialised(void);
     void OnDataReceived(uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4);
+    void OnTVServiceCallback(uint32_t reason, uint32_t p0, uint32_t p1);
 
     static void InitHost(void);