From 49ba42d414995d3b3f746d19cbb84ca18fc42897 Mon Sep 17 00:00:00 2001 From: Lars Op den Kamp Date: Mon, 25 Feb 2013 01:47:07 +0100 Subject: [PATCH] rpi: register callback for HPD. re-read the physical address when we received VC_HDMI_ATTACHED. issue #109 --- src/lib/CECProcessor.cpp | 8 ++++ src/lib/CECProcessor.h | 1 + src/lib/adapter/AdapterCommunication.h | 6 +++ .../RPi/RPiCECAdapterCommunication.cpp | 42 +++++++++++++++++-- .../adapter/RPi/RPiCECAdapterCommunication.h | 1 + 5 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/lib/CECProcessor.cpp b/src/lib/CECProcessor.cpp index 3be1c36..d9ef22c 100644 --- a/src/lib/CECProcessor.cpp +++ b/src/lib/CECProcessor.cpp @@ -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; diff --git a/src/lib/CECProcessor.h b/src/lib/CECProcessor.h index 69586a7..e57dddd 100644 --- a/src/lib/CECProcessor.h +++ b/src/lib/CECProcessor.h @@ -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; diff --git a/src/lib/adapter/AdapterCommunication.h b/src/lib/adapter/AdapterCommunication.h index b1762b7..223e65f 100644 --- a/src/lib/adapter/AdapterCommunication.h +++ b/src/lib/adapter/AdapterCommunication.h @@ -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; }; diff --git a/src/lib/adapter/RPi/RPiCECAdapterCommunication.cpp b/src/lib/adapter/RPi/RPiCECAdapterCommunication.cpp index 1a2da3a..f15b1c0 100644 --- a/src/lib/adapter/RPi/RPiCECAdapterCommunication.cpp +++ b/src/lib/adapter/RPi/RPiCECAdapterCommunication.cpp @@ -58,6 +58,13 @@ void rpi_cec_callback(void *callback_data, uint32_t p0, uint32_t p1, uint32_t p2 static_cast(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(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 diff --git a/src/lib/adapter/RPi/RPiCECAdapterCommunication.h b/src/lib/adapter/RPi/RPiCECAdapterCommunication.h index 9a0a9fd..fa43894 100644 --- a/src/lib/adapter/RPi/RPiCECAdapterCommunication.h +++ b/src/lib/adapter/RPi/RPiCECAdapterCommunication.h @@ -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); -- 2.34.1