mirror of
https://github.com/LibreELEC/LibreELEC.tv
synced 2025-09-24 19:46:01 +07:00
1767 lines
63 KiB
Diff
1767 lines
63 KiB
Diff
From 714ce8ee2ba07fe88249b8033d875f58ed21a4ab Mon Sep 17 00:00:00 2001
|
|
From: Peter Vicman <peter.vicman@gmail.com>
|
|
Date: Thu, 12 Jan 2017 09:36:24 +0100
|
|
Subject: [PATCH] patch for libcec from xbian
|
|
|
|
libcec base: libcec-2fc92b5
|
|
libcec xbian:
|
|
https://github.com/xbianonpi/xbian-sources-libcec/tree/masterv4 e12f92586ccda4fe20814c93d5830ed3a33f3a4e
|
|
---
|
|
CMakeLists.txt | 6 +
|
|
debian/control | 7 +-
|
|
debian/libcec4-dev.install | 1 +
|
|
debian/libcec4.install | 2 +
|
|
include/cec.h | 2 +
|
|
include/cectypes.h | 47 ++-
|
|
src/cec-client/CMakeLists.txt | 4 +-
|
|
src/cecc-client/cecc-client.c | 2 +-
|
|
src/libcec/CECClient.cpp | 12 +-
|
|
src/libcec/CECClient.h | 1 +
|
|
src/libcec/CECProcessor.cpp | 6 +
|
|
src/libcec/CECProcessor.h | 1 +
|
|
src/libcec/CECTypeUtils.h | 2 +
|
|
src/libcec/CMakeLists.txt | 22 +-
|
|
src/libcec/LibCEC.cpp | 5 +
|
|
src/libcec/LibCEC.h | 1 +
|
|
src/libcec/adapter/AdapterFactory.cpp | 27 +-
|
|
.../adapter/IMX/IMXCECAdapterCommunication.cpp | 381 +++++++++++++++++++++
|
|
.../adapter/IMX/IMXCECAdapterCommunication.h | 139 ++++++++
|
|
src/libcec/adapter/IMX/IMXCECAdapterDetection.cpp | 42 +++
|
|
src/libcec/adapter/IMX/IMXCECAdapterDetection.h | 36 ++
|
|
src/libcec/adapter/IMX/IMXCECAdapterMessageQueue.h | 118 +++++++
|
|
src/libcec/adapter/IMX/mxc_hdmi-cec.h | 47 +++
|
|
src/libcec/cmake/CheckPlatformSupport.cmake | 49 ++-
|
|
src/libcec/cmake/DisplayPlatformSupport.cmake | 10 +-
|
|
src/libcec/cmake/LinkPlatformSupport.cmake | 7 +-
|
|
src/libcec/cmake/git-rev.sh | 2 +-
|
|
src/libcec/devices/CECBusDevice.cpp | 11 +-
|
|
src/libcec/devices/CECBusDevice.h | 2 +
|
|
src/libcec/env.h.in | 3 +
|
|
src/libcec/implementations/CECCommandHandler.cpp | 16 +-
|
|
src/libcec/implementations/CECCommandHandler.h | 7 +-
|
|
src/libcec/implementations/GRCommandHandler.cpp | 92 +++++
|
|
src/libcec/implementations/GRCommandHandler.h | 53 +++
|
|
34 files changed, 1102 insertions(+), 61 deletions(-)
|
|
create mode 100644 src/libcec/adapter/IMX/IMXCECAdapterCommunication.cpp
|
|
create mode 100644 src/libcec/adapter/IMX/IMXCECAdapterCommunication.h
|
|
create mode 100644 src/libcec/adapter/IMX/IMXCECAdapterDetection.cpp
|
|
create mode 100644 src/libcec/adapter/IMX/IMXCECAdapterDetection.h
|
|
create mode 100644 src/libcec/adapter/IMX/IMXCECAdapterMessageQueue.h
|
|
create mode 100644 src/libcec/adapter/IMX/mxc_hdmi-cec.h
|
|
create mode 100644 src/libcec/implementations/GRCommandHandler.cpp
|
|
create mode 100644 src/libcec/implementations/GRCommandHandler.h
|
|
|
|
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
|
index 4f01662..7c19dd5 100644
|
|
--- a/CMakeLists.txt
|
|
+++ b/CMakeLists.txt
|
|
@@ -5,6 +5,12 @@ set(LIBCEC_VERSION_MAJOR 4)
|
|
set(LIBCEC_VERSION_MINOR 0)
|
|
set(LIBCEC_VERSION_PATCH 1)
|
|
|
|
+find_program(CCACHE_FOUND ccache)
|
|
+if(CCACHE_FOUND)
|
|
+ set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
|
|
+ set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
|
|
+endif(CCACHE_FOUND)
|
|
+
|
|
# cec-client
|
|
add_subdirectory(src/cec-client)
|
|
add_dependencies(cec-client cec)
|
|
diff --git a/debian/control b/debian/control
|
|
index e05a063..1675c1b 100644
|
|
--- a/debian/control
|
|
+++ b/debian/control
|
|
@@ -20,6 +20,7 @@ Vcs-Browser: http://anonscm.debian.org/gitweb/?p=collab-maint/libcec.git
|
|
Package: libcec4-dev
|
|
Architecture: any
|
|
Section: libdevel
|
|
+Replaces: libcec-dev
|
|
Depends: libcec4 (= ${binary:Version}),
|
|
${misc:Depends}
|
|
Description: libCEC communication Library (development files)
|
|
@@ -30,6 +31,7 @@ Description: libCEC communication Library (development files)
|
|
Package: libcec4
|
|
Architecture: any
|
|
Multi-Arch: same
|
|
+Replaces: libcec3
|
|
Pre-Depends: ${misc:Pre-Depends}
|
|
Depends: ${shlibs:Depends}, ${misc:Depends}
|
|
Description: libCEC communication Library (shared library)
|
|
@@ -40,6 +42,7 @@ Description: libCEC communication Library (shared library)
|
|
Package: cec-utils
|
|
Architecture: any
|
|
Section: utils
|
|
+Replaces: xbian-package-cec
|
|
Depends: libcec4 (= ${binary:Version}),
|
|
${shlibs:Depends},
|
|
${misc:Depends}
|
|
@@ -60,6 +63,8 @@ Description: Python bindings for libCEC
|
|
|
|
Package: libcec
|
|
Architecture: any
|
|
-Depends: ${shlibs:Depends}, ${misc:Depends}, libcec4 (= ${binary:Version})
|
|
+Depends: ${shlibs:Depends}, ${misc:Depends}, libcec4 (= ${binary:Version}), python-libcec, cec-utils, libcec4-dev
|
|
+Provides: xbian-package-cec
|
|
+Breaks: xbian-package-cec (<<10.0)
|
|
Description: Meta package libCEC.
|
|
|
|
diff --git a/debian/libcec4-dev.install b/debian/libcec4-dev.install
|
|
index e5bbd96..15a3585 100644
|
|
--- a/debian/libcec4-dev.install
|
|
+++ b/debian/libcec4-dev.install
|
|
@@ -1,3 +1,4 @@
|
|
usr/include
|
|
usr/lib/pkgconfig
|
|
usr/lib/*/*.so
|
|
+usr/lib/p8-platform
|
|
diff --git a/debian/libcec4.install b/debian/libcec4.install
|
|
index ca5ebe3..ac5e50a 100644
|
|
--- a/debian/libcec4.install
|
|
+++ b/debian/libcec4.install
|
|
@@ -1 +1,3 @@
|
|
usr/lib/*/libcec.so.*
|
|
+usr/lib/libp*.a
|
|
+
|
|
diff --git a/include/cec.h b/include/cec.h
|
|
index 71450ae..b4a7d78 100644
|
|
--- a/include/cec.h
|
|
+++ b/include/cec.h
|
|
@@ -389,6 +389,8 @@ namespace CEC
|
|
*/
|
|
virtual uint16_t GetAdapterProductId(void) const = 0;
|
|
|
|
+ virtual bool TransmitSystemAudioModeRequest(void) = 0;
|
|
+
|
|
virtual const char* ToString(const cec_menu_state state) = 0;
|
|
virtual const char* ToString(const cec_version version) = 0;
|
|
virtual const char* ToString(const cec_power_status status) = 0;
|
|
diff --git a/include/cectypes.h b/include/cectypes.h
|
|
index 9c91842..9fa69fc 100644
|
|
--- a/include/cectypes.h
|
|
+++ b/include/cectypes.h
|
|
@@ -267,9 +267,19 @@ namespace CEC {
|
|
#define CEC_TDA995x_VIRTUAL_COM "CuBox"
|
|
|
|
/*!
|
|
+ * the path to use for the i.MX CEC wire
|
|
+ */
|
|
+#define CEC_IMX_PATH "/dev/mxc_hdmi_cec"
|
|
+
|
|
+/*!
|
|
+ * the name of the virtual COM port to use for the i.MX CEC wire
|
|
+ */
|
|
+#define CEC_IMX_VIRTUAL_COM "i.MX"
|
|
+
|
|
+/*!
|
|
* the path to use for the Exynos HDMI CEC device
|
|
*/
|
|
-#define CEC_EXYNOS_PATH "/dev/CEC"
|
|
+#define CEC_EXYNOS_PATH "/dev/CEC"
|
|
|
|
/*!
|
|
* the name of the virtual COM port to use for the EXYNOS' CEC wire
|
|
@@ -296,6 +306,8 @@ namespace CEC {
|
|
*/
|
|
#define CEC_MIN_LIB_VERSION 4
|
|
|
|
+#define CEC_LIB_VERSION_MAJOR 4
|
|
+
|
|
#define MSGSTART 0xFF
|
|
#define MSGEND 0xFE
|
|
#define MSGESC 0xFD
|
|
@@ -861,6 +873,7 @@ typedef enum cec_adapter_type
|
|
ADAPTERTYPE_RPI = 0x100,
|
|
ADAPTERTYPE_TDA995x = 0x200,
|
|
ADAPTERTYPE_EXYNOS = 0x300,
|
|
+ ADAPTERTYPE_IMX = 0x400,
|
|
ADAPTERTYPE_AOCEC = 0x500
|
|
} cec_adapter_type;
|
|
|
|
@@ -1245,7 +1258,7 @@ typedef struct cec_device_type_list
|
|
typedef struct cec_logical_addresses
|
|
{
|
|
cec_logical_address primary; /**< the primary logical address to use */
|
|
- int addresses[16]; /**< the list of addresses */
|
|
+ uint16_t addresses; /**< the list of addresses */
|
|
|
|
#ifdef __cplusplus
|
|
/*!
|
|
@@ -1254,8 +1267,7 @@ typedef struct cec_logical_addresses
|
|
void Clear(void)
|
|
{
|
|
primary = CECDEVICE_UNREGISTERED;
|
|
- for (unsigned int iPtr = 0; iPtr < 16; iPtr++)
|
|
- addresses[iPtr] = 0;
|
|
+ addresses = 0;
|
|
}
|
|
|
|
/*!
|
|
@@ -1263,7 +1275,7 @@ typedef struct cec_logical_addresses
|
|
*/
|
|
bool IsEmpty(void) const
|
|
{
|
|
- return primary == CECDEVICE_UNREGISTERED;
|
|
+ return primary == CECDEVICE_UNREGISTERED && addresses == 0;
|
|
}
|
|
|
|
/*!
|
|
@@ -1272,11 +1284,7 @@ typedef struct cec_logical_addresses
|
|
*/
|
|
uint16_t AckMask(void) const
|
|
{
|
|
- uint16_t mask = 0;
|
|
- for (unsigned int iPtr = 0; iPtr < 16; iPtr++)
|
|
- if (addresses[iPtr] == 1)
|
|
- mask |= 0x1 << iPtr;
|
|
- return mask;
|
|
+ return addresses;
|
|
}
|
|
|
|
/*!
|
|
@@ -1288,7 +1296,7 @@ typedef struct cec_logical_addresses
|
|
if (primary == CECDEVICE_UNREGISTERED)
|
|
primary = address;
|
|
|
|
- addresses[(int) address] = 1;
|
|
+ addresses |= (1 << (int) address);
|
|
}
|
|
|
|
/*!
|
|
@@ -1300,7 +1308,7 @@ typedef struct cec_logical_addresses
|
|
if (primary == address)
|
|
primary = CECDEVICE_UNREGISTERED;
|
|
|
|
- addresses[(int) address] = 0;
|
|
+ addresses &= ~(uint16_t)(1 << (int) address);
|
|
}
|
|
|
|
/*!
|
|
@@ -1308,7 +1316,7 @@ typedef struct cec_logical_addresses
|
|
* @param address The address to check.
|
|
* @return True when set, false otherwise.
|
|
*/
|
|
- bool IsSet(cec_logical_address address) const { return addresses[(int) address] == 1; }
|
|
+ bool IsSet(cec_logical_address address) const { return (addresses & (1 << (int) address)); }
|
|
|
|
/*!
|
|
* @brief Check whether an address is set in this list.
|
|
@@ -1317,18 +1325,9 @@ typedef struct cec_logical_addresses
|
|
*/
|
|
bool operator[](uint8_t pos) const { return pos < 16 ? IsSet((cec_logical_address) pos) : false; }
|
|
|
|
- bool operator==(const cec_logical_addresses &other) const
|
|
- {
|
|
- bool bEqual(true);
|
|
- for (uint8_t iPtr = 0; iPtr < 16; iPtr++)
|
|
- bEqual &= ((addresses[(int)iPtr] == 1) == other[iPtr]);
|
|
- return bEqual;
|
|
- }
|
|
+ bool operator==(const cec_logical_addresses &other) const { return addresses == other.addresses; }
|
|
|
|
- bool operator!=(const cec_logical_addresses &other) const
|
|
- {
|
|
- return !(*this == other);
|
|
- }
|
|
+ bool operator!=(const cec_logical_addresses &other) const { return !(*this == other); }
|
|
#endif
|
|
} cec_logical_addresses;
|
|
|
|
diff --git a/src/cec-client/CMakeLists.txt b/src/cec-client/CMakeLists.txt
|
|
index 2cb42bb..c708fdb 100644
|
|
--- a/src/cec-client/CMakeLists.txt
|
|
+++ b/src/cec-client/CMakeLists.txt
|
|
@@ -13,9 +13,9 @@ include(CheckLibraryExists)
|
|
include(CheckIncludeFiles)
|
|
include(CheckCXXCompilerFlag)
|
|
|
|
-check_cxx_compiler_flag("-std=c++11" SUPPORTS_CXX11)
|
|
+check_cxx_compiler_flag("-std=c++0x" SUPPORTS_CXX11)
|
|
if (SUPPORTS_CXX11)
|
|
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
|
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
|
endif()
|
|
|
|
find_package(p8-platform REQUIRED)
|
|
diff --git a/src/cecc-client/cecc-client.c b/src/cecc-client/cecc-client.c
|
|
index 3373109..914d4d4 100644
|
|
--- a/src/cecc-client/cecc-client.c
|
|
+++ b/src/cecc-client/cecc-client.c
|
|
@@ -337,7 +337,7 @@ static int cec_process_command_scan(const char* data)
|
|
activeSource = g_iface.get_active_source(g_iface.connection);
|
|
for (iPtr = 0; iPtr < 16; iPtr++)
|
|
{
|
|
- if (addresses.addresses[iPtr])
|
|
+ if (addresses.addresses & (1 << iPtr))
|
|
{
|
|
cec_menu_language lang;
|
|
cec_osd_name osdName;
|
|
diff --git a/src/libcec/CECClient.cpp b/src/libcec/CECClient.cpp
|
|
index b777faa..9f6e7c5 100644
|
|
--- a/src/libcec/CECClient.cpp
|
|
+++ b/src/libcec/CECClient.cpp
|
|
@@ -139,10 +139,6 @@ bool CCECClient::OnRegister(void)
|
|
// set the physical address
|
|
SetPhysicalAddress(m_configuration);
|
|
|
|
- // make the primary device the active source if the option is set
|
|
- if (m_configuration.bActivateSource == 1)
|
|
- GetPrimaryDevice()->ActivateSource(500);
|
|
-
|
|
return true;
|
|
}
|
|
|
|
@@ -350,12 +346,13 @@ bool CCECClient::AllocateLogicalAddresses(void)
|
|
if (address == CECDEVICE_UNKNOWN)
|
|
{
|
|
LIB_CEC->AddLog(CEC_LOG_ERROR, "%s - failed to allocate device '%d', type '%s'", __FUNCTION__, iPtr, ToString(m_configuration.deviceTypes.types[iPtr]));
|
|
- return false;
|
|
+ continue;
|
|
}
|
|
|
|
// display the registered LA
|
|
LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s - device '%d', type '%s', LA '%X'", __FUNCTION__, iPtr, ToString(m_configuration.deviceTypes.types[iPtr]), address);
|
|
m_configuration.logicalAddresses.Set(address);
|
|
+ break;
|
|
}
|
|
|
|
// persist the new configuration
|
|
@@ -1540,6 +1537,11 @@ bool CCECClient::IsLibCECActiveSource(void)
|
|
return bReturn;
|
|
}
|
|
|
|
+bool CCECClient::TransmitSystemAudioModeRequest(void)
|
|
+{
|
|
+ return m_processor ? m_processor->TransmitSystemAudioModeRequest(m_configuration.logicalAddresses.primary) : false;
|
|
+}
|
|
+
|
|
void CCECClient::SourceActivated(const cec_logical_address logicalAddress)
|
|
{
|
|
LIB_CEC->AddLog(CEC_LOG_NOTICE, ">> source activated: %s (%x)", ToString(logicalAddress), logicalAddress);
|
|
diff --git a/src/libcec/CECClient.h b/src/libcec/CECClient.h
|
|
index 49528ee..f02775c 100644
|
|
--- a/src/libcec/CECClient.h
|
|
+++ b/src/libcec/CECClient.h
|
|
@@ -298,6 +298,7 @@ namespace CEC
|
|
virtual void RescanActiveDevices(void);
|
|
virtual bool IsLibCECActiveSource(void);
|
|
bool AudioEnable(bool enable);
|
|
+ virtual bool TransmitSystemAudioModeRequest(void);
|
|
|
|
// configuration
|
|
virtual bool GetCurrentConfiguration(libcec_configuration &configuration);
|
|
diff --git a/src/libcec/CECProcessor.cpp b/src/libcec/CECProcessor.cpp
|
|
index 8ce46c5..e31e24a 100644
|
|
--- a/src/libcec/CECProcessor.cpp
|
|
+++ b/src/libcec/CECProcessor.cpp
|
|
@@ -712,6 +712,12 @@ bool CCECProcessor::TransmitPendingActiveSourceCommands(void)
|
|
return bReturn;
|
|
}
|
|
|
|
+bool CCECProcessor::TransmitSystemAudioModeRequest(cec_logical_address initiator)
|
|
+{
|
|
+ CCECBusDevice *device = m_busDevices->At(initiator);
|
|
+ return device && device->TransmitSystemAudioModeRequest(initiator);
|
|
+}
|
|
+
|
|
CCECTV *CCECProcessor::GetTV(void) const
|
|
{
|
|
return CCECBusDevice::AsTV(m_busDevices->At(CECDEVICE_TV));
|
|
diff --git a/src/libcec/CECProcessor.h b/src/libcec/CECProcessor.h
|
|
index 08917b9..1971dee 100644
|
|
--- a/src/libcec/CECProcessor.h
|
|
+++ b/src/libcec/CECProcessor.h
|
|
@@ -149,6 +149,7 @@ namespace CEC
|
|
bool GetDeviceInformation(const char *strPort, libcec_configuration *config, uint32_t iTimeoutMs = CEC_DEFAULT_CONNECT_TIMEOUT);
|
|
|
|
bool TransmitPendingActiveSourceCommands(void);
|
|
+ bool TransmitSystemAudioModeRequest(cec_logical_address initiator);
|
|
|
|
CCECDeviceMap *GetDevices(void) const { return m_busDevices; }
|
|
CLibCEC *GetLib(void) const { return m_libcec; }
|
|
diff --git a/src/libcec/CECTypeUtils.h b/src/libcec/CECTypeUtils.h
|
|
index 0d0cf17..f6c818a 100644
|
|
--- a/src/libcec/CECTypeUtils.h
|
|
+++ b/src/libcec/CECTypeUtils.h
|
|
@@ -766,6 +766,8 @@ namespace CEC
|
|
return "Raspberry Pi";
|
|
case ADAPTERTYPE_TDA995x:
|
|
return "TDA995x";
|
|
+ case ADAPTERTYPE_IMX:
|
|
+ return "i.MX";
|
|
default:
|
|
return "unknown";
|
|
}
|
|
diff --git a/src/libcec/CMakeLists.txt b/src/libcec/CMakeLists.txt
|
|
index d3eefa3..6a33abf 100644
|
|
--- a/src/libcec/CMakeLists.txt
|
|
+++ b/src/libcec/CMakeLists.txt
|
|
@@ -13,9 +13,9 @@ include(CheckIncludeFiles)
|
|
include(CheckCXXCompilerFlag)
|
|
include(../../cmake/UseMultiArch.cmake)
|
|
|
|
-check_cxx_compiler_flag("-std=c++11" SUPPORTS_CXX11)
|
|
+check_cxx_compiler_flag("-std=c++0x" SUPPORTS_CXX11)
|
|
if (SUPPORTS_CXX11)
|
|
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
|
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
|
endif()
|
|
|
|
find_package(p8-platform REQUIRED)
|
|
@@ -64,7 +64,8 @@ set(CEC_SOURCES_IMPLEMENTATIONS implementations/ANCommandHandler.cpp
|
|
implementations/RLCommandHandler.cpp
|
|
implementations/PHCommandHandler.cpp
|
|
implementations/RHCommandHandler.cpp
|
|
- implementations/AQCommandHandler.cpp)
|
|
+ implementations/AQCommandHandler.cpp
|
|
+ implementations/GRCommandHandler.cpp)
|
|
|
|
# /platform/*
|
|
set(CEC_SOURCES_PLATFORM platform/adl/adl-edid.cpp
|
|
@@ -124,6 +125,7 @@ set(CEC_HEADERS devices/CECRecordingDevice.h
|
|
implementations/RHCommandHandler.h
|
|
implementations/PHCommandHandler.h
|
|
implementations/AQCommandHandler.h
|
|
+ implementations/GRCommandHandler.h
|
|
CECProcessor.h)
|
|
source_group("Header Files" FILES ${CEC_HEADERS})
|
|
|
|
@@ -176,13 +178,17 @@ install(FILES ${PROJECT_SOURCE_DIR}/../../include/cec.h
|
|
DESTINATION include/libcec)
|
|
|
|
# libCEC target
|
|
-add_library(cec SHARED ${CEC_SOURCES})
|
|
-install(TARGETS cec
|
|
+add_library(cecobj OBJECT ${CEC_SOURCES})
|
|
+set_property(TARGET ${cecobj} PROPERTY POSITION_INDEPENDENT_CODE 1)
|
|
+add_library(cec SHARED $<TARGET_OBJECTS:cecobj>)
|
|
+add_library(cecstatic STATIC $<TARGET_OBJECTS:cecobj>)
|
|
+set_target_properties(cecstatic PROPERTIES OUTPUT_NAME cec)
|
|
+install(TARGETS cec cecstatic
|
|
DESTINATION ${LIB_DESTINATION})
|
|
-set_target_properties(cec PROPERTIES VERSION ${LIBCEC_VERSION_MAJOR}.${LIBCEC_VERSION_MINOR}.${LIBCEC_VERSION_PATCH}
|
|
+set_target_properties(cec cecstatic PROPERTIES VERSION ${LIBCEC_VERSION_MAJOR}.${LIBCEC_VERSION_MINOR}.${LIBCEC_VERSION_PATCH}
|
|
SOVERSION ${LIBCEC_VERSION_MAJOR})
|
|
-target_link_libraries(cec ${p8-platform_LIBRARIES})
|
|
-target_link_libraries(cec ${CMAKE_THREAD_LIBS_INIT})
|
|
+target_link_libraries(cec cecstatic ${p8-platform_LIBRARIES})
|
|
+target_link_libraries(cec cecstatic ${CMAKE_THREAD_LIBS_INIT})
|
|
|
|
include(cmake/LinkPlatformSupport.cmake)
|
|
include(cmake/DisplayPlatformSupport.cmake)
|
|
diff --git a/src/libcec/LibCEC.cpp b/src/libcec/LibCEC.cpp
|
|
index 8eedaa7..9562e06 100644
|
|
--- a/src/libcec/LibCEC.cpp
|
|
+++ b/src/libcec/LibCEC.cpp
|
|
@@ -624,3 +624,8 @@ bool CLibCEC::AudioEnable(bool enable)
|
|
m_client->AudioEnable(enable) :
|
|
false;
|
|
}
|
|
+
|
|
+bool CLibCEC::TransmitSystemAudioModeRequest(void)
|
|
+{
|
|
+ return m_client ? m_client->TransmitSystemAudioModeRequest() : false;
|
|
+}
|
|
diff --git a/src/libcec/LibCEC.h b/src/libcec/LibCEC.h
|
|
index 7155926..b9e393b 100644
|
|
--- a/src/libcec/LibCEC.h
|
|
+++ b/src/libcec/LibCEC.h
|
|
@@ -109,6 +109,7 @@ namespace CEC
|
|
bool PersistConfiguration(libcec_configuration *configuration);
|
|
void RescanActiveDevices(void);
|
|
bool IsLibCECActiveSource(void);
|
|
+ bool TransmitSystemAudioModeRequest(void);
|
|
|
|
const char* ToString(const cec_menu_state state) { return CCECTypeUtils::ToString(state); }
|
|
const char* ToString(const cec_version version) { return CCECTypeUtils::ToString(version); }
|
|
diff --git a/src/libcec/adapter/AdapterFactory.cpp b/src/libcec/adapter/AdapterFactory.cpp
|
|
index 91195ea..e2460ad 100644
|
|
--- a/src/libcec/adapter/AdapterFactory.cpp
|
|
+++ b/src/libcec/adapter/AdapterFactory.cpp
|
|
@@ -63,6 +63,11 @@
|
|
#include "AOCEC/AOCECAdapterCommunication.h"
|
|
#endif
|
|
|
|
+#if defined(HAVE_IMX_API)
|
|
+#include "IMX/IMXCECAdapterDetection.h"
|
|
+#include "IMX/IMXCECAdapterCommunication.h"
|
|
+#endif
|
|
+
|
|
using namespace CEC;
|
|
|
|
int8_t CAdapterFactory::FindAdapters(cec_adapter *deviceList, uint8_t iBufSize, const char *strDevicePath /* = NULL */)
|
|
@@ -143,8 +148,21 @@ int8_t CAdapterFactory::DetectAdapters(cec_adapter_descriptor *deviceList, uint8
|
|
}
|
|
#endif
|
|
|
|
+#if defined(HAVE_IMX_API)
|
|
+ if (iAdaptersFound < iBufSize && CIMXCECAdapterDetection::FindAdapter() &&
|
|
+ (!strDevicePath || !strcmp(strDevicePath, CEC_IMX_VIRTUAL_COM)))
|
|
+ {
|
|
+ snprintf(deviceList[iAdaptersFound].strComPath, sizeof(deviceList[iAdaptersFound].strComPath), CEC_IMX_PATH);
|
|
+ snprintf(deviceList[iAdaptersFound].strComName, sizeof(deviceList[iAdaptersFound].strComName), CEC_IMX_VIRTUAL_COM);
|
|
+ deviceList[iAdaptersFound].iVendorId = IMX_ADAPTER_VID;
|
|
+ deviceList[iAdaptersFound].iProductId = IMX_ADAPTER_PID;
|
|
+ deviceList[iAdaptersFound].adapterType = ADAPTERTYPE_IMX;
|
|
+ iAdaptersFound++;
|
|
+ }
|
|
+#endif
|
|
+
|
|
|
|
-#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_AOCEC_API)
|
|
+#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_AOCEC_API) && !defined(HAVE_IMX_API)
|
|
#error "libCEC doesn't have support for any type of adapter. please check your build system or configuration"
|
|
#endif
|
|
|
|
@@ -173,11 +191,16 @@ IAdapterCommunication *CAdapterFactory::GetInstance(const char *strPort, uint16_
|
|
return new CRPiCECAdapterCommunication(m_lib->m_cec);
|
|
#endif
|
|
|
|
+#if defined(HAVE_IMX_API)
|
|
+ if (!strcmp(strPort, CEC_IMX_VIRTUAL_COM))
|
|
+ return new CIMXCECAdapterCommunication(m_lib->m_cec);
|
|
+#endif
|
|
+
|
|
#if defined(HAVE_P8_USB)
|
|
return new CUSBCECAdapterCommunication(m_lib->m_cec, strPort, iBaudRate);
|
|
#endif
|
|
|
|
-#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_EXYNOS_API) && !defined(HAVE_AOCEC_API)
|
|
+#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_EXYNOS_API) && !defined(HAVE_AOCEC_API) && !defined(HAVE_IMX_API)
|
|
return NULL;
|
|
#endif
|
|
}
|
|
diff --git a/src/libcec/adapter/IMX/IMXCECAdapterCommunication.cpp b/src/libcec/adapter/IMX/IMXCECAdapterCommunication.cpp
|
|
new file mode 100644
|
|
index 0000000..212dd75
|
|
--- /dev/null
|
|
+++ b/src/libcec/adapter/IMX/IMXCECAdapterCommunication.cpp
|
|
@@ -0,0 +1,381 @@
|
|
+/*
|
|
+ * This file is part of the libCEC(R) library.
|
|
+ *
|
|
+ * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved.
|
|
+ * libCEC(R) is an original work, containing original code.
|
|
+ *
|
|
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
|
|
+ *
|
|
+ * IMX adpater port is Copyright (C) 2013 by Stephan Rafin
|
|
+ * Copyright (C) 2014 by Matus Kral
|
|
+ *
|
|
+ * You can redistribute this file and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
+ *
|
|
+ *
|
|
+ */
|
|
+
|
|
+#include "env.h"
|
|
+
|
|
+#if defined(HAVE_IMX_API)
|
|
+#include "IMXCECAdapterCommunication.h"
|
|
+
|
|
+#include "CECTypeUtils.h"
|
|
+#include "LibCEC.h"
|
|
+#include <p8-platform/sockets/cdevsocket.h>
|
|
+#include <p8-platform/util/StdString.h>
|
|
+#include <p8-platform/util/util.h>
|
|
+
|
|
+using namespace std;
|
|
+using namespace CEC;
|
|
+using namespace P8PLATFORM;
|
|
+
|
|
+#include "IMXCECAdapterMessageQueue.h"
|
|
+
|
|
+#define LIB_CEC m_callback->GetLib()
|
|
+
|
|
+// these are defined in nxp private header file
|
|
+#define CEC_MSG_SUCCESS 0x00 /*Message transmisson Succeed*/
|
|
+#define CEC_CSP_OFF_STATE 0x80 /*CSP in Off State*/
|
|
+#define CEC_BAD_REQ_SERVICE 0x81 /*Bad .req service*/
|
|
+#define CEC_MSG_FAIL_UNABLE_TO_ACCESS 0x82 /*Message transmisson failed: Unable to access CEC line*/
|
|
+#define CEC_MSG_FAIL_ARBITRATION_ERROR 0x83 /*Message transmisson failed: Arbitration error*/
|
|
+#define CEC_MSG_FAIL_BIT_TIMMING_ERROR 0x84 /*Message transmisson failed: Bit timming error*/
|
|
+#define CEC_MSG_FAIL_DEST_NOT_ACK 0x85 /*Message transmisson failed: Destination Address not aknowledged*/
|
|
+#define CEC_MSG_FAIL_DATA_NOT_ACK 0x86 /*Message transmisson failed: Databyte not acknowledged*/
|
|
+
|
|
+CIMXCECAdapterCommunication::CIMXCECAdapterCommunication(IAdapterCommunicationCallback *callback) :
|
|
+ IAdapterCommunication(callback),
|
|
+ m_PAReporter(NULL)
|
|
+{
|
|
+ CLockObject lock(m_mutex);
|
|
+
|
|
+ m_iNextMessage = 0;
|
|
+ m_logicalAddress = CECDEVICE_UNKNOWN;
|
|
+ m_bLogicalAddressRegistered = false;
|
|
+ m_bInitialised = false;
|
|
+ m_dev = new CCDevSocket(CEC_IMX_PATH);
|
|
+ m_physicalAddress = -1;
|
|
+}
|
|
+
|
|
+CIMXCECAdapterCommunication::~CIMXCECAdapterCommunication(void)
|
|
+{
|
|
+ Close();
|
|
+ SAFE_DELETE(m_PAReporter);
|
|
+ delete m_dev;
|
|
+ m_dev = 0;
|
|
+}
|
|
+
|
|
+bool CIMXCECAdapterCommunication::IsOpen(void)
|
|
+{
|
|
+ return IsInitialised() && m_dev->IsOpen();
|
|
+}
|
|
+
|
|
+bool CIMXCECAdapterCommunication::Open(uint32_t iTimeoutMs, bool UNUSED(bSkipChecks), bool bStartListening)
|
|
+{
|
|
+ if (m_dev->Open(iTimeoutMs))
|
|
+ {
|
|
+ if (!bStartListening || CreateThread()) {
|
|
+ if (m_dev->Ioctl(HDMICEC_IOC_STARTDEVICE, NULL) == 0) {
|
|
+ m_bInitialised = true;
|
|
+ RegisterLogicalAddress(CECDEVICE_BROADCAST);
|
|
+ return true;
|
|
+ }
|
|
+ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: Unable to start device\n", __func__);
|
|
+ }
|
|
+ m_dev->Close();
|
|
+ }
|
|
+
|
|
+ return false;
|
|
+}
|
|
+
|
|
+
|
|
+void CIMXCECAdapterCommunication::Close(void)
|
|
+{
|
|
+ m_bInitialised = false;
|
|
+ if (m_dev->Ioctl(HDMICEC_IOC_STOPDEVICE, NULL) != 0)
|
|
+ {
|
|
+ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: Unable to stop device\n", __func__);
|
|
+ }
|
|
+ StopThread(false);
|
|
+ m_dev->Close();
|
|
+}
|
|
+
|
|
+
|
|
+std::string CIMXCECAdapterCommunication::GetError(void) const
|
|
+{
|
|
+ std::string strError(m_strError);
|
|
+ return strError;
|
|
+}
|
|
+
|
|
+
|
|
+cec_adapter_message_state CIMXCECAdapterCommunication::Write(
|
|
+ const cec_command &data, bool &bRetry, uint8_t iLineTimeout, bool UNUSED(bIsReply))
|
|
+{
|
|
+ unsigned char message[MAX_MESSAGE_LEN];
|
|
+ CIMXCECAdapterMessageQueueEntry *entry;
|
|
+ int msg_len = 1;
|
|
+ cec_adapter_message_state rc = ADAPTER_MESSAGE_STATE_ERROR;
|
|
+
|
|
+ bRetry = true;
|
|
+ if ((size_t)data.parameters.size + data.opcode_set + 1 > sizeof(message))
|
|
+ {
|
|
+ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: data size too large !", __func__);
|
|
+ bRetry = false;
|
|
+ return rc;
|
|
+ }
|
|
+
|
|
+ message[0] = (data.initiator << 4) | (data.destination & 0x0f);
|
|
+ if (data.opcode_set)
|
|
+ {
|
|
+ message[1] = data.opcode;
|
|
+ msg_len++;
|
|
+ memcpy(&message[2], data.parameters.data, data.parameters.size);
|
|
+ msg_len+=data.parameters.size;
|
|
+ }
|
|
+
|
|
+ entry = new CIMXCECAdapterMessageQueueEntry(message[0], data.opcode);
|
|
+ m_messageMutex.Lock();
|
|
+ uint32_t msgKey = ++m_iNextMessage;
|
|
+ m_messages.insert(make_pair(msgKey, entry));
|
|
+ m_messageMutex.Unlock();
|
|
+
|
|
+ if (m_dev->Write(message, msg_len) > 0)
|
|
+ {
|
|
+ if (entry->Wait(data.transmit_timeout ? data.transmit_timeout : iLineTimeout *1000))
|
|
+ {
|
|
+ int status = entry->Result();
|
|
+
|
|
+ if (status == MESSAGE_TYPE_NOACK)
|
|
+ rc = ADAPTER_MESSAGE_STATE_SENT_NOT_ACKED;
|
|
+ else if (status == MESSAGE_TYPE_SEND_SUCCESS)
|
|
+ rc = ADAPTER_MESSAGE_STATE_SENT_ACKED;
|
|
+
|
|
+ bRetry = false;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ rc = ADAPTER_MESSAGE_STATE_WAITING_TO_BE_SENT;
|
|
+#ifdef CEC_DEBUGGING
|
|
+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s: command timed out !", __func__);
|
|
+#endif
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ Sleep(CEC_DEFAULT_TRANSMIT_RETRY_WAIT);
|
|
+#ifdef CEC_DEBUGGING
|
|
+ LIB_CEC->AddLog(CEC_LOG_WARNING, "%s: write failed !", __func__);
|
|
+#endif
|
|
+ }
|
|
+
|
|
+ m_messageMutex.Lock();
|
|
+ m_messages.erase(msgKey);
|
|
+ m_messageMutex.Unlock();
|
|
+
|
|
+ delete entry;
|
|
+
|
|
+ return rc;
|
|
+}
|
|
+
|
|
+
|
|
+uint16_t CIMXCECAdapterCommunication::GetFirmwareVersion(void)
|
|
+{
|
|
+ /* FIXME add ioctl ? */
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+cec_vendor_id CIMXCECAdapterCommunication::GetVendorId(void)
|
|
+{
|
|
+ return CEC_VENDOR_UNKNOWN;
|
|
+}
|
|
+
|
|
+
|
|
+uint16_t CIMXCECAdapterCommunication::GetPhysicalAddress(void)
|
|
+{
|
|
+ uint8_t phy_addr[4];
|
|
+ uint16_t pa_tmp;
|
|
+
|
|
+ if (m_dev->Ioctl(HDMICEC_IOC_GETPHYADDRESS, &phy_addr) != 0)
|
|
+ {
|
|
+ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: HDMICEC_IOC_GETPHYADDRESS failed !", __func__);
|
|
+ return CEC_INVALID_PHYSICAL_ADDRESS;
|
|
+ }
|
|
+
|
|
+ if ((pa_tmp = ((phy_addr[0] << 4 | phy_addr[1]) << 8) | (phy_addr[2] << 4 | phy_addr[3])))
|
|
+ m_physicalAddress = pa_tmp;
|
|
+
|
|
+ return m_physicalAddress;
|
|
+}
|
|
+
|
|
+
|
|
+cec_logical_addresses CIMXCECAdapterCommunication::GetLogicalAddresses(void)
|
|
+{
|
|
+ cec_logical_addresses addresses;
|
|
+ addresses.Clear();
|
|
+
|
|
+ CLockObject lock(m_mutex);
|
|
+ if (m_bLogicalAddressRegistered)
|
|
+ addresses.Set(m_logicalAddress);
|
|
+
|
|
+ return addresses;
|
|
+}
|
|
+
|
|
+void CIMXCECAdapterCommunication::HandleLogicalAddressLost(cec_logical_address UNUSED(oldAddress))
|
|
+{
|
|
+ UnregisterLogicalAddress();
|
|
+}
|
|
+
|
|
+bool CIMXCECAdapterCommunication::UnregisterLogicalAddress(void)
|
|
+{
|
|
+ {
|
|
+ CLockObject lock(m_mutex);
|
|
+ if (!m_bLogicalAddressRegistered)
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+#ifdef CEC_DEBUGGING
|
|
+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s - releasing previous logical address", __func__);
|
|
+#endif
|
|
+ return RegisterLogicalAddress(CECDEVICE_BROADCAST);
|
|
+}
|
|
+
|
|
+bool CIMXCECAdapterCommunication::RegisterLogicalAddress(const cec_logical_address address)
|
|
+{
|
|
+ {
|
|
+ CLockObject lock(m_mutex);
|
|
+ if ((m_logicalAddress == address && m_bLogicalAddressRegistered) ||
|
|
+ (m_logicalAddress == address && address == CECDEVICE_BROADCAST))
|
|
+ {
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+
|
|
+#ifdef CEC_DEBUGGING
|
|
+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s: %x to %x", __func__, m_logicalAddress, address);
|
|
+#endif
|
|
+
|
|
+ if (m_dev->Ioctl(HDMICEC_IOC_SETLOGICALADDRESS, (void *)address) != 0)
|
|
+ {
|
|
+ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: HDMICEC_IOC_SETLOGICALADDRESS failed !", __func__);
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ CLockObject lock(m_mutex);
|
|
+
|
|
+ m_logicalAddress = address;
|
|
+ m_bLogicalAddressRegistered = (address != CECDEVICE_BROADCAST) ? true : false;
|
|
+ return true;
|
|
+}
|
|
+
|
|
+bool CIMXCECAdapterCommunication::SetLogicalAddresses(const cec_logical_addresses &addresses)
|
|
+{
|
|
+ int log_addr = addresses.primary;
|
|
+
|
|
+ return RegisterLogicalAddress((cec_logical_address)log_addr);
|
|
+}
|
|
+
|
|
+
|
|
+void *CIMXCECAdapterCommunication::Process(void)
|
|
+{
|
|
+ bool bHandled;
|
|
+ hdmi_cec_event event;
|
|
+ int ret;
|
|
+
|
|
+ cec_logical_address initiator, destination;
|
|
+
|
|
+ while (!IsStopped())
|
|
+ {
|
|
+ if (IsInitialised() && (ret = m_dev->Read((char *)&event, sizeof(event), 0)) > 0)
|
|
+ {
|
|
+
|
|
+ initiator = cec_logical_address(event.msg[0] >> 4);
|
|
+ destination = cec_logical_address(event.msg[0] & 0x0f);
|
|
+
|
|
+ if (event.event_type == MESSAGE_TYPE_RECEIVE_SUCCESS)
|
|
+ {
|
|
+ cec_command cmd;
|
|
+
|
|
+ cec_command::Format(
|
|
+ cmd, initiator, destination,
|
|
+ ( event.msg_len > 1 ) ? cec_opcode(event.msg[1]) : CEC_OPCODE_NONE);
|
|
+
|
|
+ for( uint8_t i = 2; i < event.msg_len; i++ )
|
|
+ cmd.parameters.PushBack(event.msg[i]);
|
|
+
|
|
+ if (!IsStopped()) {
|
|
+ m_callback->OnCommandReceived(cmd);
|
|
+ }
|
|
+ }
|
|
+ else if (event.event_type == MESSAGE_TYPE_SEND_SUCCESS
|
|
+ || event.event_type == MESSAGE_TYPE_NOACK)
|
|
+ {
|
|
+ bHandled = false;
|
|
+
|
|
+ m_messageMutex.Lock();
|
|
+ for (map<uint32_t, CIMXCECAdapterMessageQueueEntry *>::iterator it = m_messages.begin();
|
|
+ !bHandled && it != m_messages.end(); it++)
|
|
+ {
|
|
+ bHandled = it->second->Received(event.event_type, event.msg[0], (cec_opcode)event.msg[1]);
|
|
+ }
|
|
+ m_messageMutex.Unlock();
|
|
+
|
|
+ if (!bHandled)
|
|
+ LIB_CEC->AddLog(CEC_LOG_WARNING, "%s: response not matched !", __func__);
|
|
+ }
|
|
+ else if (event.event_type == MESSAGE_TYPE_DISCONNECTED)
|
|
+ {
|
|
+ /* HDMI Hotplug event - disconnect */
|
|
+ }
|
|
+ else if (event.event_type == MESSAGE_TYPE_CONNECTED)
|
|
+ {
|
|
+ if (m_physicalAddress == 0xffff)
|
|
+ continue;
|
|
+ /* HDMI Hotplug event - connect */
|
|
+ uint16_t oldAddress = m_physicalAddress;
|
|
+
|
|
+ if (oldAddress != GetPhysicalAddress()) {
|
|
+ if (m_PAReporter)
|
|
+ while (m_PAReporter->IsRunning()) Sleep(5);
|
|
+ delete m_PAReporter;
|
|
+
|
|
+ m_PAReporter = new CCECPAChangedReporter(m_callback, m_physicalAddress);
|
|
+ m_PAReporter->CreateThread(false);
|
|
+ }
|
|
+#ifdef CEC_DEBUGGING
|
|
+ LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s: plugin event received", __func__);
|
|
+#endif
|
|
+ }
|
|
+ else
|
|
+ LIB_CEC->AddLog(CEC_LOG_WARNING, "%s: unhandled response received %d!", __func__, event.event_type);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+CCECPAChangedReporter::CCECPAChangedReporter(IAdapterCommunicationCallback *callback, uint16_t newPA) :
|
|
+ m_callback(callback),
|
|
+ m_newPA(newPA)
|
|
+{
|
|
+}
|
|
+
|
|
+void* CCECPAChangedReporter::Process(void)
|
|
+{
|
|
+ m_callback->HandlePhysicalAddressChanged(m_newPA);
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+#endif // HAVE_IMX_API
|
|
diff --git a/src/libcec/adapter/IMX/IMXCECAdapterCommunication.h b/src/libcec/adapter/IMX/IMXCECAdapterCommunication.h
|
|
new file mode 100644
|
|
index 0000000..2da38c1
|
|
--- /dev/null
|
|
+++ b/src/libcec/adapter/IMX/IMXCECAdapterCommunication.h
|
|
@@ -0,0 +1,139 @@
|
|
+#pragma once
|
|
+/*
|
|
+ * This file is part of the libCEC(R) library.
|
|
+ *
|
|
+ * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved.
|
|
+ * libCEC(R) is an original work, containing original code.
|
|
+ *
|
|
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
|
|
+ *
|
|
+ * IMX adpater port is Copyright (C) 2013 by Stephan Rafin
|
|
+ * Copyright (C) 2014 by Matus Kral
|
|
+ *
|
|
+ * You can redistribute this file and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
+ *
|
|
+ *
|
|
+ */
|
|
+
|
|
+#if defined(HAVE_IMX_API)
|
|
+
|
|
+#include "adapter/AdapterCommunication.h"
|
|
+#include <p8-platform/threads/mutex.h>
|
|
+#include <p8-platform/threads/threads.h>
|
|
+#include <p8-platform/sockets/socket.h>
|
|
+#include "adapter/IMX/mxc_hdmi-cec.h"
|
|
+#include <map>
|
|
+
|
|
+#define IMX_ADAPTER_VID 0x0471 /*FIXME TBD*/
|
|
+#define IMX_ADAPTER_PID 0x1001
|
|
+
|
|
+typedef struct hdmi_cec_event{
|
|
+ uint8_t event_type;
|
|
+ uint8_t msg_len;
|
|
+ uint8_t msg[MAX_MESSAGE_LEN];
|
|
+}hdmi_cec_event;
|
|
+
|
|
+
|
|
+namespace P8PLATFORM
|
|
+{
|
|
+ class CCDevSocket;
|
|
+};
|
|
+
|
|
+namespace CEC
|
|
+{
|
|
+ class CIMXCECAdapterMessageQueueEntry;
|
|
+
|
|
+ class CCECPAChangedReporter : public P8PLATFORM::CThread
|
|
+ {
|
|
+ public:
|
|
+ CCECPAChangedReporter(IAdapterCommunicationCallback *callback, uint16_t newPA);
|
|
+ void* Process(void);
|
|
+
|
|
+ private:
|
|
+ IAdapterCommunicationCallback *m_callback;
|
|
+ uint16_t m_newPA;
|
|
+ };
|
|
+
|
|
+ class CIMXCECAdapterCommunication : public IAdapterCommunication, public P8PLATFORM::CThread
|
|
+ {
|
|
+ public:
|
|
+ /*!
|
|
+ * @brief Create a new USB-CEC communication handler.
|
|
+ * @param callback The callback to use for incoming CEC commands.
|
|
+ */
|
|
+ CIMXCECAdapterCommunication(IAdapterCommunicationCallback *callback);
|
|
+ virtual ~CIMXCECAdapterCommunication(void);
|
|
+
|
|
+ /** @name IAdapterCommunication implementation */
|
|
+ ///{
|
|
+ bool Open(uint32_t iTimeoutMs = CEC_DEFAULT_CONNECT_TIMEOUT, bool bSkipChecks = false, bool bStartListening = true);
|
|
+ void Close(void);
|
|
+ bool IsOpen(void);
|
|
+ std::string GetError(void) const;
|
|
+ cec_adapter_message_state Write(const cec_command &data, bool &bRetry, uint8_t iLineTimeout, bool bIsReply);
|
|
+
|
|
+ bool SetLineTimeout(uint8_t UNUSED(iTimeout)) { return true; }
|
|
+ bool StartBootloader(void) { return false; }
|
|
+ bool SetLogicalAddresses(const cec_logical_addresses &addresses);
|
|
+ cec_logical_addresses GetLogicalAddresses(void);
|
|
+ bool PingAdapter(void) { return IsInitialised(); }
|
|
+ uint16_t GetFirmwareVersion(void);
|
|
+ uint32_t GetFirmwareBuildDate(void) { return 0; }
|
|
+ bool IsRunningLatestFirmware(void) { return true; }
|
|
+ bool PersistConfiguration(const libcec_configuration & UNUSED(configuration)) { return false; }
|
|
+ bool GetConfiguration(libcec_configuration & UNUSED(configuration)) { return false; }
|
|
+ std::string GetPortName(void) { return std::string("IMX"); }
|
|
+ uint16_t GetPhysicalAddress(void);
|
|
+ bool SetControlledMode(bool UNUSED(controlled)) { return true; }
|
|
+ cec_vendor_id GetVendorId(void);
|
|
+ void HandleLogicalAddressLost(cec_logical_address UNUSED(oldAddress));
|
|
+ bool SupportsSourceLogicalAddress(const cec_logical_address address) { return address > CECDEVICE_TV && address <= CECDEVICE_BROADCAST; }
|
|
+ cec_adapter_type GetAdapterType(void) { return ADAPTERTYPE_IMX; }
|
|
+ uint16_t GetAdapterVendorId(void) const { return IMX_ADAPTER_VID; }
|
|
+ uint16_t GetAdapterProductId(void) const { return IMX_ADAPTER_PID; }
|
|
+ void SetActiveSource(bool UNUSED(bSetTo), bool UNUSED(bClientUnregistered)) {}
|
|
+ ///}
|
|
+
|
|
+ /** @name PLATFORM::CThread implementation */
|
|
+ ///{
|
|
+ void *Process(void);
|
|
+ ///}
|
|
+
|
|
+ private:
|
|
+ bool IsInitialised(void) { return m_bInitialised; };
|
|
+ bool RegisterLogicalAddress(const cec_logical_address address);
|
|
+ bool UnregisterLogicalAddress(void);
|
|
+
|
|
+ std::string m_strError; /**< current error message */
|
|
+
|
|
+ cec_logical_address m_logicalAddress;
|
|
+ uint16_t m_physicalAddress;
|
|
+
|
|
+ P8PLATFORM::CMutex m_mutex;
|
|
+ P8PLATFORM::CCDevSocket *m_dev; /**< the device connection */
|
|
+
|
|
+ P8PLATFORM::CMutex m_messageMutex;
|
|
+ uint32_t m_iNextMessage;
|
|
+ std::map<uint32_t, CIMXCECAdapterMessageQueueEntry *> m_messages;
|
|
+
|
|
+ bool m_bLogicalAddressRegistered;
|
|
+ bool m_bInitialised;
|
|
+
|
|
+ CCECPAChangedReporter *m_PAReporter;
|
|
+ };
|
|
+
|
|
+};
|
|
+
|
|
+#endif
|
|
diff --git a/src/libcec/adapter/IMX/IMXCECAdapterDetection.cpp b/src/libcec/adapter/IMX/IMXCECAdapterDetection.cpp
|
|
new file mode 100644
|
|
index 0000000..6c93c45
|
|
--- /dev/null
|
|
+++ b/src/libcec/adapter/IMX/IMXCECAdapterDetection.cpp
|
|
@@ -0,0 +1,42 @@
|
|
+/*
|
|
+ * This file is part of the libCEC(R) library.
|
|
+ *
|
|
+ * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved.
|
|
+ * libCEC(R) is an original work, containing original code.
|
|
+ *
|
|
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
|
|
+ *
|
|
+ * IMX adpater port is Copyright (C) 2013 by Stephan Rafin
|
|
+ *
|
|
+ * You can redistribute this file and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
+ *
|
|
+ *
|
|
+ */
|
|
+
|
|
+#include "env.h"
|
|
+#include <stdio.h>
|
|
+
|
|
+#if defined(HAVE_IMX_API)
|
|
+#include "IMXCECAdapterDetection.h"
|
|
+
|
|
+
|
|
+using namespace CEC;
|
|
+
|
|
+bool CIMXCECAdapterDetection::FindAdapter(void)
|
|
+{
|
|
+ return access(CEC_IMX_PATH, 0) == 0;
|
|
+}
|
|
+
|
|
+#endif
|
|
diff --git a/src/libcec/adapter/IMX/IMXCECAdapterDetection.h b/src/libcec/adapter/IMX/IMXCECAdapterDetection.h
|
|
new file mode 100644
|
|
index 0000000..d54891d
|
|
--- /dev/null
|
|
+++ b/src/libcec/adapter/IMX/IMXCECAdapterDetection.h
|
|
@@ -0,0 +1,36 @@
|
|
+#pragma once
|
|
+/*
|
|
+ * This file is part of the libCEC(R) library.
|
|
+ *
|
|
+ * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved.
|
|
+ * libCEC(R) is an original work, containing original code.
|
|
+ *
|
|
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
|
|
+ *
|
|
+ * IMX adpater port is Copyright (C) 2013 by Stephan Rafin
|
|
+ *
|
|
+ * You can redistribute this file and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
+ *
|
|
+ *
|
|
+ */
|
|
+
|
|
+namespace CEC
|
|
+{
|
|
+ class CIMXCECAdapterDetection
|
|
+ {
|
|
+ public:
|
|
+ static bool FindAdapter(void);
|
|
+ };
|
|
+}
|
|
diff --git a/src/libcec/adapter/IMX/IMXCECAdapterMessageQueue.h b/src/libcec/adapter/IMX/IMXCECAdapterMessageQueue.h
|
|
new file mode 100644
|
|
index 0000000..e54c192
|
|
--- /dev/null
|
|
+++ b/src/libcec/adapter/IMX/IMXCECAdapterMessageQueue.h
|
|
@@ -0,0 +1,118 @@
|
|
+#pragma once
|
|
+/*
|
|
+ * This file is part of the libCEC(R) library.
|
|
+ *
|
|
+ * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved.
|
|
+ * libCEC(R) is an original work, containing original code.
|
|
+ *
|
|
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
|
|
+ *
|
|
+ * This program is dual-licensed; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
+ *
|
|
+ *
|
|
+ * Alternatively, you can license this library under a commercial license,
|
|
+ * please contact Pulse-Eight Licensing for more information.
|
|
+ *
|
|
+ * For more information contact:
|
|
+ * Pulse-Eight Licensing <license@pulse-eight.com>
|
|
+ * http://www.pulse-eight.com/
|
|
+ * http://www.pulse-eight.net/
|
|
+ */
|
|
+
|
|
+#include <p8-platform/threads/mutex.h>
|
|
+
|
|
+namespace CEC
|
|
+{
|
|
+ using namespace P8PLATFORM;
|
|
+
|
|
+ class CIMXCECAdapterMessageQueueEntry
|
|
+ {
|
|
+ public:
|
|
+ CIMXCECAdapterMessageQueueEntry(uint8_t addrs, cec_opcode opcode)
|
|
+ : m_bWaiting(true), m_retval((uint32_t)-1), m_bSucceeded(false)
|
|
+ {
|
|
+ m_opcode = opcode;
|
|
+ m_addrs = addrs;
|
|
+ }
|
|
+
|
|
+ virtual ~CIMXCECAdapterMessageQueueEntry(void) {}
|
|
+
|
|
+ /*!
|
|
+ * @brief Query result from worker thread
|
|
+ */
|
|
+ uint32_t Result() const
|
|
+ {
|
|
+ return m_retval;
|
|
+ }
|
|
+
|
|
+ /*!
|
|
+ * @brief Signal waiting threads
|
|
+ */
|
|
+ void Broadcast(void)
|
|
+ {
|
|
+ CLockObject lock(m_mutex);
|
|
+ m_condition.Broadcast();
|
|
+ }
|
|
+
|
|
+ /*!
|
|
+ * @brief Signal waiting thread(s) when message matches this entry
|
|
+ */
|
|
+ bool Received(int response, uint8_t addrs, cec_opcode opcode)
|
|
+ {
|
|
+ CLockObject lock(m_mutex);
|
|
+
|
|
+ if (!(m_addrs == addrs && m_opcode == opcode))
|
|
+ return false;
|
|
+
|
|
+ m_retval = response;
|
|
+ m_bSucceeded = true;
|
|
+ m_condition.Signal();
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ /*!
|
|
+ * @brief Wait for a response to this command.
|
|
+ * @param iTimeout The timeout to use while waiting.
|
|
+ * @return True when a response was received before the timeout passed, false otherwise.
|
|
+ */
|
|
+ bool Wait(uint32_t iTimeout)
|
|
+ {
|
|
+ CLockObject lock(m_mutex);
|
|
+
|
|
+ bool bReturn = m_bSucceeded ? true : m_condition.Wait(m_mutex, m_bSucceeded, iTimeout);
|
|
+ m_bWaiting = false;
|
|
+ return bReturn;
|
|
+ }
|
|
+
|
|
+ /*!
|
|
+ * @return True while a thread is waiting for a signal or isn't waiting yet, false otherwise.
|
|
+ */
|
|
+ bool IsWaiting(void)
|
|
+ {
|
|
+ CLockObject lock(m_mutex);
|
|
+ return m_bWaiting;
|
|
+ }
|
|
+
|
|
+ private:
|
|
+ bool m_bWaiting; /**< true while a thread is waiting or when it hasn't started waiting yet */
|
|
+ P8PLATFORM::CCondition<bool> m_condition; /**< the condition to wait on */
|
|
+ P8PLATFORM::CMutex m_mutex; /**< mutex for changes to this class */
|
|
+ int m_retval;
|
|
+ bool m_bSucceeded;
|
|
+ uint8_t m_addrs;
|
|
+ cec_opcode m_opcode;
|
|
+ };
|
|
+
|
|
+};
|
|
diff --git a/src/libcec/adapter/IMX/mxc_hdmi-cec.h b/src/libcec/adapter/IMX/mxc_hdmi-cec.h
|
|
new file mode 100644
|
|
index 0000000..bc5bbce
|
|
--- /dev/null
|
|
+++ b/src/libcec/adapter/IMX/mxc_hdmi-cec.h
|
|
@@ -0,0 +1,47 @@
|
|
+/*
|
|
+ * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * The code contained herein is licensed under the GNU General Public
|
|
+ * License. You may obtain a copy of the GNU General Public License
|
|
+ * Version 2 or later at the following locations:
|
|
+ *
|
|
+ * http://www.opensource.org/licenses/gpl-license.html
|
|
+ * http://www.gnu.org/copyleft/gpl.html
|
|
+ */
|
|
+#ifndef _HDMICEC_H_
|
|
+#define _HDMICEC_H_
|
|
+#include <linux/ioctl.h>
|
|
+
|
|
+/*
|
|
+ * Ioctl definitions
|
|
+ */
|
|
+
|
|
+/* Use 'k' as magic number */
|
|
+#define HDMICEC_IOC_MAGIC 'H'
|
|
+/*
|
|
+ * S means "Set" through a ptr,
|
|
+ * T means "Tell" directly with the argument value
|
|
+ * G means "Get": reply by setting through a pointer
|
|
+ * Q means "Query": response is on the return value
|
|
+ * X means "eXchange": G and S atomically
|
|
+ * H means "sHift": T and Q atomically
|
|
+ */
|
|
+#define HDMICEC_IOC_SETLOGICALADDRESS \
|
|
+ _IOW(HDMICEC_IOC_MAGIC, 1, unsigned char)
|
|
+#define HDMICEC_IOC_STARTDEVICE _IO(HDMICEC_IOC_MAGIC, 2)
|
|
+#define HDMICEC_IOC_STOPDEVICE _IO(HDMICEC_IOC_MAGIC, 3)
|
|
+#define HDMICEC_IOC_GETPHYADDRESS \
|
|
+ _IOR(HDMICEC_IOC_MAGIC, 4, unsigned char[4])
|
|
+
|
|
+#define MAX_MESSAGE_LEN 16
|
|
+
|
|
+#define MESSAGE_TYPE_RECEIVE_SUCCESS 1
|
|
+#define MESSAGE_TYPE_NOACK 2
|
|
+#define MESSAGE_TYPE_DISCONNECTED 3
|
|
+#define MESSAGE_TYPE_CONNECTED 4
|
|
+#define MESSAGE_TYPE_SEND_SUCCESS 5
|
|
+
|
|
+#endif /* !_HDMICEC_H_ */
|
|
+
|
|
diff --git a/src/libcec/cmake/CheckPlatformSupport.cmake b/src/libcec/cmake/CheckPlatformSupport.cmake
|
|
index 532f213..a89e404 100644
|
|
--- a/src/libcec/cmake/CheckPlatformSupport.cmake
|
|
+++ b/src/libcec/cmake/CheckPlatformSupport.cmake
|
|
@@ -91,24 +91,49 @@ else()
|
|
endif()
|
|
|
|
# xrandr
|
|
- check_include_files("X11/Xlib.h;X11/Xatom.h;X11/extensions/Xrandr.h" HAVE_RANDR_HEADERS)
|
|
- check_library_exists(Xrandr XRRGetScreenResources "" HAVE_RANDR_LIB)
|
|
- if (HAVE_RANDR_HEADERS AND HAVE_RANDR_LIB)
|
|
- set(LIB_INFO "${LIB_INFO}, randr")
|
|
- list(APPEND CEC_SOURCES_PLATFORM platform/X11/randr-edid.cpp)
|
|
- SET(HAVE_RANDR ON CACHE BOOL "xrandr supported" FORCE)
|
|
+ if (${HAVE_RANDR_API})
|
|
+ check_include_files("X11/Xlib.h;X11/Xatom.h;X11/extensions/Xrandr.h" HAVE_RANDR_HEADERS)
|
|
+ check_library_exists(Xrandr XRRGetScreenResources "" HAVE_RANDR_LIB)
|
|
+ if (HAVE_RANDR_HEADERS AND HAVE_RANDR_LIB)
|
|
+ set(LIB_INFO "${LIB_INFO}, randr")
|
|
+ list(APPEND CEC_SOURCES_PLATFORM platform/X11/randr-edid.cpp)
|
|
+ set(HAVE_RANDR 1)
|
|
+ else()
|
|
+ set(HAVE_RANDR 0)
|
|
+ endif()
|
|
+ else()
|
|
+ set(HAVE_RANDR 0)
|
|
endif()
|
|
|
|
+ # iMX6
|
|
+ if (${HAVE_IMX_API})
|
|
+ set(LIB_INFO "${LIB_INFO}, iMX6")
|
|
+ set(HAVE_IMX_API 1)
|
|
+ set(CEC_SOURCES_ADAPTER_IMX adapter/IMX/IMXCECAdapterDetection.cpp
|
|
+ adapter/IMX/IMXCECAdapterCommunication.cpp)
|
|
+ source_group("Source Files\\adapter\\iMX6" FILES ${CEC_SOURCES_ADAPTER_IMX})
|
|
+ list(APPEND CEC_SOURCES ${CEC_SOURCES_ADAPTER_IMX})
|
|
+ set(HAVE_RPI_API 0)
|
|
+ else()
|
|
+ set(HAVE_IMX_API 0)
|
|
+ set(HAVE_RPI_API 1)
|
|
+ endif()
|
|
+
|
|
# raspberry pi
|
|
- find_library(RPI_BCM_HOST bcm_host "${RPI_LIB_DIR}")
|
|
- check_library_exists(bcm_host bcm_host_init "${RPI_LIB_DIR}" HAVE_RPI_LIB)
|
|
- if (HAVE_RPI_LIB)
|
|
- SET(HAVE_RPI_API ON CACHE BOOL "raspberry pi supported" FORCE)
|
|
+ if (HAVE_RPI_API)
|
|
+ find_library(RPI_BCM_HOST bcm_host "${RPI_LIB_DIR}")
|
|
+ check_library_exists(bcm_host bcm_host_init "${RPI_LIB_DIR}" HAVE_RPI_API)
|
|
+ endif()
|
|
+ if (HAVE_RPI_API)
|
|
find_library(RPI_VCOS vcos "${RPI_LIB_DIR}")
|
|
find_library(RPI_VCHIQ_ARM vchiq_arm "${RPI_LIB_DIR}")
|
|
include_directories(${RPI_INCLUDE_DIR} ${RPI_INCLUDE_DIR}/interface/vcos/pthreads ${RPI_INCLUDE_DIR}/interface/vmcs_host/linux)
|
|
|
|
- set(LIB_INFO "${LIB_INFO}, RPi")
|
|
+ set(LIB_INFO "${LIB_INFO}, 'RPi'")
|
|
+ # find includes files on Raspberry Pi
|
|
+ include_directories(/opt/vc/include /opt/vc/include/interface/vcos/pthreads /opt/vc/include/interface/vmcs_host/linux)
|
|
+ list(APPEND CMAKE_REQUIRED_LIBRARIES "vcos")
|
|
+ list(APPEND CMAKE_REQUIRED_LIBRARIES "vchiq_arm")
|
|
set(CEC_SOURCES_ADAPTER_RPI adapter/RPi/RPiCECAdapterDetection.cpp
|
|
adapter/RPi/RPiCECAdapterCommunication.cpp
|
|
adapter/RPi/RPiCECAdapterMessageQueue.cpp)
|
|
@@ -148,6 +173,8 @@ else()
|
|
else()
|
|
set(HAVE_AOCEC_API 0)
|
|
endif()
|
|
+
|
|
+
|
|
endif()
|
|
|
|
# rt
|
|
diff --git a/src/libcec/cmake/DisplayPlatformSupport.cmake b/src/libcec/cmake/DisplayPlatformSupport.cmake
|
|
index 7ec10f5..2262638 100644
|
|
--- a/src/libcec/cmake/DisplayPlatformSupport.cmake
|
|
+++ b/src/libcec/cmake/DisplayPlatformSupport.cmake
|
|
@@ -45,9 +45,15 @@ else()
|
|
endif()
|
|
|
|
if (HAVE_AOCEC_API)
|
|
- message(STATUS "AOCEC support: yes")
|
|
+ message(STATUS "AOCEC support: yes")
|
|
else()
|
|
- message(STATUS "AOCEC support: no")
|
|
+ message(STATUS "AOCEC support: no")
|
|
+endif()
|
|
+
|
|
+if (HAVE_IMX_API)
|
|
+ message(STATUS "i.MX6 support: yes")
|
|
+else()
|
|
+ message(STATUS "i.MX6 support: no")
|
|
endif()
|
|
|
|
if (HAVE_PYTHON)
|
|
diff --git a/src/libcec/cmake/LinkPlatformSupport.cmake b/src/libcec/cmake/LinkPlatformSupport.cmake
|
|
index fc27353..b203f6f 100644
|
|
--- a/src/libcec/cmake/LinkPlatformSupport.cmake
|
|
+++ b/src/libcec/cmake/LinkPlatformSupport.cmake
|
|
@@ -28,7 +28,12 @@ endif()
|
|
|
|
# raspberry pi
|
|
if (HAVE_RPI_API)
|
|
- target_link_libraries(cec ${RPI_VCOS} ${RPI_VCHIQ_ARM} ${RPI_BCM_HOST})
|
|
+ find_library (VCOS vcos)
|
|
+ target_link_libraries(cec ${VCOS})
|
|
+ find_library (VCHIQ_ARM vchiq_arm)
|
|
+ target_link_libraries(cec ${VCHIP_ARM})
|
|
+ find_library (BCM_HOST bcm_host)
|
|
+ target_link_libraries(cec ${BCM_HOST})
|
|
endif()
|
|
|
|
# Apple
|
|
diff --git a/src/libcec/cmake/git-rev.sh b/src/libcec/cmake/git-rev.sh
|
|
index db682c1..15b6a23 100755
|
|
--- a/src/libcec/cmake/git-rev.sh
|
|
+++ b/src/libcec/cmake/git-rev.sh
|
|
@@ -2,7 +2,7 @@
|
|
|
|
## cmake doesn't read the variable when it doesn't end with a newline, and I haven't figured out how to have it add a newline directly...
|
|
if git rev-parse --git-dir > /dev/null 2>&1; then
|
|
- last_tag=`git describe --tags --abbrev=0`
|
|
+ last_tag=`git describe --tags --abbrev=0 --all`
|
|
last_hash=`git --no-pager log --abbrev=7 -n 1 --pretty=format:"%h"`
|
|
commits_since_tag=`git log ${last_tag}..HEAD --oneline | wc -l`
|
|
git_dirty=`git diff HEAD | wc -l`
|
|
diff --git a/src/libcec/devices/CECBusDevice.cpp b/src/libcec/devices/CECBusDevice.cpp
|
|
index 99f762c..be72b05 100644
|
|
--- a/src/libcec/devices/CECBusDevice.cpp
|
|
+++ b/src/libcec/devices/CECBusDevice.cpp
|
|
@@ -44,6 +44,7 @@
|
|
#include "implementations/RLCommandHandler.h"
|
|
#include "implementations/RHCommandHandler.h"
|
|
#include "implementations/AQCommandHandler.h"
|
|
+#include "implementations/GRCommandHandler.h"
|
|
#include "LibCEC.h"
|
|
#include "CECTypeUtils.h"
|
|
#include <p8-platform/util/timeutils.h>
|
|
@@ -217,6 +218,9 @@ bool CCECBusDevice::ReplaceHandler(bool bActivateSource /* = true */)
|
|
case CEC_VENDOR_SHARP2:
|
|
m_handler = new CAQCommandHandler(this, iTransmitTimeout, iTransmitWait, iTransmitRetries, iActiveSourcePending);
|
|
break;
|
|
+ case CEC_VENDOR_GRUNDIG:
|
|
+ m_handler = new CGRCommandHandler(this, iTransmitTimeout, iTransmitWait, iTransmitRetries, iActiveSourcePending);
|
|
+ break;
|
|
default:
|
|
m_handler = new CCECCommandHandler(this, iTransmitTimeout, iTransmitWait, iTransmitRetries, iActiveSourcePending);
|
|
break;
|
|
@@ -1263,7 +1267,7 @@ bool CCECBusDevice::PowerOn(const cec_logical_address initiator)
|
|
|
|
MarkBusy();
|
|
cec_power_status currentStatus;
|
|
- if (m_iLogicalAddress == CECDEVICE_TV ||
|
|
+ if ((m_iLogicalAddress == CECDEVICE_TV && !ImageViewOnSent()) ||
|
|
((currentStatus = GetPowerStatus(initiator, false)) != CEC_POWER_STATUS_IN_TRANSITION_STANDBY_TO_ON &&
|
|
currentStatus != CEC_POWER_STATUS_ON))
|
|
{
|
|
@@ -1498,3 +1502,8 @@ bool CCECBusDevice::TransmitMuteAudio(const cec_logical_address source)
|
|
return TransmitKeypress(source, CEC_USER_CONTROL_CODE_MUTE) &&
|
|
TransmitKeyRelease(source);
|
|
}
|
|
+
|
|
+bool CCECBusDevice::TransmitSystemAudioModeRequest(const cec_logical_address initiator)
|
|
+{
|
|
+ return m_handler->TransmitSystemAudioModeRequest(initiator, m_iPhysicalAddress, false);
|
|
+}
|
|
diff --git a/src/libcec/devices/CECBusDevice.h b/src/libcec/devices/CECBusDevice.h
|
|
index b8255aa..8493d48 100644
|
|
--- a/src/libcec/devices/CECBusDevice.h
|
|
+++ b/src/libcec/devices/CECBusDevice.h
|
|
@@ -199,6 +199,8 @@ namespace CEC
|
|
void SignalOpcode(cec_opcode opcode);
|
|
bool WaitForOpcode(cec_opcode opcode);
|
|
|
|
+ virtual bool TransmitSystemAudioModeRequest(const cec_logical_address initiator);
|
|
+
|
|
CCECAudioSystem * AsAudioSystem(void);
|
|
static CCECAudioSystem * AsAudioSystem(CCECBusDevice *device);
|
|
CCECPlaybackDevice * AsPlaybackDevice(void);
|
|
diff --git a/src/libcec/env.h.in b/src/libcec/env.h.in
|
|
index 0774a1c..14c7704 100644
|
|
--- a/src/libcec/env.h.in
|
|
+++ b/src/libcec/env.h.in
|
|
@@ -70,6 +70,9 @@
|
|
/* Define to 1 for Raspberry Pi support */
|
|
#cmakedefine HAVE_RPI_API @HAVE_RPI_API@
|
|
|
|
+/* Define to 1 for iMX6 support */
|
|
+#cmakedefine HAVE_IMX_API @HAVE_IMX_API@
|
|
+
|
|
/* Define to 1 for TDA995x support */
|
|
#cmakedefine HAVE_TDA995X_API @HAVE_TDA995X_API@
|
|
|
|
diff --git a/src/libcec/implementations/CECCommandHandler.cpp b/src/libcec/implementations/CECCommandHandler.cpp
|
|
index 71c2230..5a1e7a0 100644
|
|
--- a/src/libcec/implementations/CECCommandHandler.cpp
|
|
+++ b/src/libcec/implementations/CECCommandHandler.cpp
|
|
@@ -62,6 +62,7 @@ CCECCommandHandler::CCECCommandHandler(CCECBusDevice *busDevice,
|
|
m_iTransmitRetries(iTransmitRetries),
|
|
m_bHandlerInited(false),
|
|
m_bOPTSendDeckStatusUpdateOnActiveSource(false),
|
|
+ m_bOPTSendMenuStatusUpdateOnActiveSource(true),
|
|
m_vendorId(CEC_VENDOR_UNKNOWN),
|
|
m_iActiveSourcePending(iActiveSourcePending),
|
|
m_iPowerStatusRequested(0)
|
|
@@ -1133,6 +1134,19 @@ bool CCECCommandHandler::TransmitAudioStatus(const cec_logical_address iInitiato
|
|
return Transmit(command, false, bIsReply);
|
|
}
|
|
|
|
+bool CCECCommandHandler::TransmitSystemAudioModeRequest(const cec_logical_address iInitiator, uint16_t iPhysicalAddress, bool bIsReply)
|
|
+{
|
|
+ cec_command command;
|
|
+ cec_command::Format(command, iInitiator, CECDEVICE_AUDIOSYSTEM, CEC_OPCODE_SYSTEM_AUDIO_MODE_REQUEST);
|
|
+ command.parameters.PushBack((uint8_t) ((iPhysicalAddress >> 8) & 0xFF));
|
|
+ command.parameters.PushBack((uint8_t) (iPhysicalAddress & 0xFF));
|
|
+
|
|
+ if (Transmit(command, true, bIsReply))
|
|
+ return true;
|
|
+
|
|
+ return false;
|
|
+}
|
|
+
|
|
bool CCECCommandHandler::TransmitSetSystemAudioMode(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_system_audio_status state, bool bIsReply)
|
|
{
|
|
cec_command command;
|
|
@@ -1307,7 +1321,7 @@ bool CCECCommandHandler::ActivateSource(bool bTransmitDelayedCommandsOnly /* = f
|
|
if (!bActiveSourceFailed && bSourceSwitchAllowed)
|
|
{
|
|
bActiveSourceFailed = !m_busDevice->TransmitActiveSource(false);
|
|
- if (bTvPresent && !bActiveSourceFailed)
|
|
+ if (bTvPresent && !bActiveSourceFailed && SendMenuStatusUpdateOnActiveSource())
|
|
m_busDevice->TransmitMenuState(CECDEVICE_TV, false);
|
|
|
|
// update the deck status for playback devices
|
|
diff --git a/src/libcec/implementations/CECCommandHandler.h b/src/libcec/implementations/CECCommandHandler.h
|
|
index 8ff9a1e..eb52ed3 100644
|
|
--- a/src/libcec/implementations/CECCommandHandler.h
|
|
+++ b/src/libcec/implementations/CECCommandHandler.h
|
|
@@ -60,7 +60,9 @@ namespace CEC
|
|
virtual bool HandleCommand(const cec_command &command);
|
|
virtual cec_vendor_id GetVendorId(void) { return m_vendorId; };
|
|
virtual void SetVendorId(cec_vendor_id vendorId) { m_vendorId = vendorId; }
|
|
- static bool HasSpecificHandler(cec_vendor_id vendorId) { return vendorId == CEC_VENDOR_LG || vendorId == CEC_VENDOR_SAMSUNG || vendorId == CEC_VENDOR_PANASONIC || vendorId == CEC_VENDOR_PHILIPS || vendorId == CEC_VENDOR_SHARP || vendorId == CEC_VENDOR_SHARP2 || vendorId == CEC_VENDOR_TOSHIBA || vendorId == CEC_VENDOR_TOSHIBA2 || vendorId == CEC_VENDOR_ONKYO;}
|
|
+ static bool HasSpecificHandler(cec_vendor_id vendorId) { return vendorId == CEC_VENDOR_LG || vendorId == CEC_VENDOR_SAMSUNG || vendorId == CEC_VENDOR_PANASONIC || vendorId == CEC_VENDOR_PHILIPS
|
|
+ || vendorId == CEC_VENDOR_SHARP || vendorId == CEC_VENDOR_SHARP2 || vendorId == CEC_VENDOR_TOSHIBA || vendorId == CEC_VENDOR_TOSHIBA2 || vendorId == CEC_VENDOR_ONKYO
|
|
+ || vendorId == CEC_VENDOR_GRUNDIG; }
|
|
|
|
virtual bool InitHandler(void) { return true; }
|
|
virtual bool ActivateSource(bool bTransmitDelayedCommandsOnly = false);
|
|
@@ -89,6 +91,7 @@ namespace CEC
|
|
virtual bool TransmitPowerState(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_power_status state, bool bIsReply);
|
|
virtual bool TransmitVendorID(const cec_logical_address iInitiator, const cec_logical_address iDestination, uint64_t iVendorId, bool bIsReply);
|
|
virtual bool TransmitAudioStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, uint8_t state, bool bIsReply);
|
|
+ virtual bool TransmitSystemAudioModeRequest(const cec_logical_address iInitiator, uint16_t iPhysicalAddress, bool bIsReply);
|
|
virtual bool TransmitSetSystemAudioMode(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_system_audio_status state, bool bIsReply);
|
|
virtual bool TransmitSystemAudioModeStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_system_audio_status state, bool bIsReply);
|
|
virtual bool TransmitDeckStatus(const cec_logical_address iInitiator, const cec_logical_address iDestination, cec_deck_info state, bool bIsReply);
|
|
@@ -97,6 +100,7 @@ namespace CEC
|
|
virtual bool TransmitSystemAudioModeRequest(const cec_logical_address iInitiator, uint16_t iPhysicalAddress);
|
|
virtual bool TransmitSetStreamPath(uint16_t iStreamPath, bool bIsReply);
|
|
virtual bool SendDeckStatusUpdateOnActiveSource(void) const { return m_bOPTSendDeckStatusUpdateOnActiveSource; };
|
|
+ virtual bool SendMenuStatusUpdateOnActiveSource(void) const { return m_bOPTSendMenuStatusUpdateOnActiveSource; };
|
|
|
|
virtual void ScheduleActivateSource(uint64_t iDelay);
|
|
|
|
@@ -165,6 +169,7 @@ namespace CEC
|
|
int8_t m_iTransmitRetries;
|
|
bool m_bHandlerInited;
|
|
bool m_bOPTSendDeckStatusUpdateOnActiveSource;
|
|
+ bool m_bOPTSendMenuStatusUpdateOnActiveSource;
|
|
cec_vendor_id m_vendorId;
|
|
int64_t m_iActiveSourcePending;
|
|
P8PLATFORM::CMutex m_mutex;
|
|
diff --git a/src/libcec/implementations/GRCommandHandler.cpp b/src/libcec/implementations/GRCommandHandler.cpp
|
|
new file mode 100644
|
|
index 0000000..af49af9
|
|
--- /dev/null
|
|
+++ b/src/libcec/implementations/GRCommandHandler.cpp
|
|
@@ -0,0 +1,92 @@
|
|
+/*
|
|
+ * This file is part of the libCEC(R) library.
|
|
+ *
|
|
+ * libCEC(R) is Copyright (C) 2011-2015 Pulse-Eight Limited. All rights reserved.
|
|
+ * libCEC(R) is an original work, containing original code.
|
|
+ *
|
|
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
|
|
+ *
|
|
+ * This program is dual-licensed; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
+ * 02110-1301 USA
|
|
+ *
|
|
+ *
|
|
+ * Alternatively, you can license this library under a commercial license,
|
|
+ * please contact Pulse-Eight Licensing for more information.
|
|
+ *
|
|
+ * For more information contact:
|
|
+ * Pulse-Eight Licensing <license@pulse-eight.com>
|
|
+ * http://www.pulse-eight.com/
|
|
+ * http://www.pulse-eight.net/
|
|
+ */
|
|
+
|
|
+#include "env.h"
|
|
+#include "GRCommandHandler.h"
|
|
+
|
|
+#include "devices/CECBusDevice.h"
|
|
+#include "CECProcessor.h"
|
|
+#include "LibCEC.h"
|
|
+#include "CECClient.h"
|
|
+
|
|
+using namespace CEC;
|
|
+
|
|
+#define LIB_CEC m_busDevice->GetProcessor()->GetLib()
|
|
+#define ToString(p) LIB_CEC->ToString(p)
|
|
+
|
|
+CGRCommandHandler::CGRCommandHandler(CCECBusDevice *busDevice,
|
|
+ int32_t iTransmitTimeout /* = CEC_DEFAULT_TRANSMIT_TIMEOUT */,
|
|
+ int32_t iTransmitWait /* = CEC_DEFAULT_TRANSMIT_WAIT */,
|
|
+ int8_t iTransmitRetries /* = CEC_DEFAULT_TRANSMIT_RETRIES */,
|
|
+ int64_t iActiveSourcePending /* = 0 */) :
|
|
+ CCECCommandHandler(busDevice, iTransmitTimeout, iTransmitWait, iTransmitRetries, iActiveSourcePending)
|
|
+{
|
|
+ m_vendorId = CEC_VENDOR_GRUNDIG;
|
|
+ m_bOPTSendMenuStatusUpdateOnActiveSource = false;
|
|
+
|
|
+ m_busDevice->SetCecVersion(CEC_VERSION_1_3A);
|
|
+
|
|
+ /* Grundig devices return "" as language */
|
|
+ cec_menu_language lang;
|
|
+ snprintf(lang, 4, "eng");
|
|
+ m_busDevice->SetMenuLanguage(lang);
|
|
+}
|
|
+
|
|
+bool CGRCommandHandler::InitHandler(void)
|
|
+{
|
|
+ if (m_bHandlerInited)
|
|
+ return true;
|
|
+ m_bHandlerInited = true;
|
|
+
|
|
+ if (m_busDevice->GetLogicalAddress() != CECDEVICE_TV)
|
|
+ return true;
|
|
+
|
|
+ CCECBusDevice *primary = m_processor->GetPrimaryDevice();
|
|
+ if (primary && primary->GetLogicalAddress() != CECDEVICE_UNREGISTERED)
|
|
+ {
|
|
+ /* imitate Toshiba devices */
|
|
+ if (m_busDevice->GetLogicalAddress() != primary->GetLogicalAddress())
|
|
+ {
|
|
+ primary->SetVendorId(CEC_VENDOR_GRUNDIG);
|
|
+ primary->ReplaceHandler(false);
|
|
+ }
|
|
+
|
|
+ if (m_busDevice->GetLogicalAddress() == CECDEVICE_TV)
|
|
+ {
|
|
+ /* send the vendor id */
|
|
+ primary->TransmitVendorID(CECDEVICE_BROADCAST, false, false);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+}
|
|
diff --git a/src/libcec/implementations/GRCommandHandler.h b/src/libcec/implementations/GRCommandHandler.h
|
|
new file mode 100644
|
|
index 0000000..e01c7fc
|
|
--- /dev/null
|
|
+++ b/src/libcec/implementations/GRCommandHandler.h
|
|
@@ -0,0 +1,53 @@
|
|
+#pragma once
|
|
+/*
|
|
+ * This file is part of the libCEC(R) library.
|
|
+ *
|
|
+ * libCEC(R) is Copyright (C) 2011-2015 Pulse-Eight Limited. All rights reserved.
|
|
+ * libCEC(R) is an original work, containing original code.
|
|
+ *
|
|
+ * libCEC(R) is a trademark of Pulse-Eight Limited.
|
|
+ *
|
|
+ * This program is dual-licensed; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
+ * 02110-1301 USA
|
|
+ *
|
|
+ *
|
|
+ * Alternatively, you can license this library under a commercial license,
|
|
+ * please contact Pulse-Eight Licensing for more information.
|
|
+ *
|
|
+ * For more information contact:
|
|
+ * Pulse-Eight Licensing <license@pulse-eight.com>
|
|
+ * http://www.pulse-eight.com/
|
|
+ * http://www.pulse-eight.net/
|
|
+ */
|
|
+
|
|
+#include "env.h"
|
|
+#include "CECCommandHandler.h"
|
|
+#include "p8-platform/threads/threads.h"
|
|
+
|
|
+namespace CEC
|
|
+{
|
|
+ class CGRCommandHandler : public CCECCommandHandler
|
|
+ {
|
|
+ public:
|
|
+ CGRCommandHandler(CCECBusDevice *busDevice,
|
|
+ int32_t iTransmitTimeout = CEC_DEFAULT_TRANSMIT_TIMEOUT,
|
|
+ int32_t iTransmitWait = CEC_DEFAULT_TRANSMIT_WAIT,
|
|
+ int8_t iTransmitRetries = CEC_DEFAULT_TRANSMIT_RETRIES,
|
|
+ int64_t iActiveSourcePending = 0);
|
|
+
|
|
+ bool InitHandler(void);
|
|
+ virtual ~CGRCommandHandler(void) {};
|
|
+ };
|
|
+};
|
|
--
|
|
2.7.4
|
|
|