From 51b611bcf0c25eb55d3097ba5122e3549d578a17 Mon Sep 17 00:00:00 2001 From: warped-rudi Date: Wed, 26 Sep 2012 19:48:45 +0200 Subject: [PATCH] Add support for Solid-Run CuBox (TDA995x) --- README | 10 +-- configure.ac | 26 +++--- include/cectypes.h | 6 +- src/lib/CECTypeUtils.h | 4 +- src/lib/Makefile.am | 2 +- src/lib/adapter/AdapterFactory.cpp | 21 ++--- src/lib/adapter/CuBox/AdapterMessageQueue.h | 16 ++-- .../CuBox/NxpCECAdapterCommunication.cpp | 82 +++++-------------- .../CuBox/NxpCECAdapterCommunication.h | 8 +- .../adapter/CuBox/NxpCECAdapterDetection.cpp | 7 +- 10 files changed, 70 insertions(+), 112 deletions(-) diff --git a/README b/README index de118ea..9bf8786 100644 --- a/README +++ b/README @@ -103,15 +103,15 @@ for 'configure': === CuBox === =============================================================================== -Solid-Run's CuBox uses an HDMI tranceiver by NXP. The device driver for this, -which is based on an SDK by the chip vendor, is built into the kernel. The -following options for 'configure' have been introduced: +Solid-Run's CuBox uses a combined HDMI tranceiver / CEC controller by NXP. The +device driver for it is based on an SDK by the chip vendor and is compiled into +the Linux kernel. The following options for 'configure' have been introduced: To enable support for the CuBox: --enable-cubox -To specify the path for the NXP SDK: ---with-nxp-toolkit-path='path/to/linux/drivers/video/dovefb/nxp_hdmi' +To specify the path to the SDK part of the kernel driver: +--with-tda995x-toolkit-path='path/to/linux/drivers/video/dovefb/nxp_hdmi' If the toolkit path is not specified, it is assumed that a directory named 'nxp_hdmi' (or a link to it) exists in the top level of the source tree. diff --git a/configure.ac b/configure.ac index e0252c9..6206ce0 100644 --- a/configure.ac +++ b/configure.ac @@ -47,15 +47,15 @@ AC_ARG_ENABLE([optimisation], AC_ARG_ENABLE([cubox], [AS_HELP_STRING([--enable-cubox], [enable support for the CuBox (default is no)])], - [use_nxp=$enableval], - [use_nxp=no]) + [use_tda995x=$enableval], + [use_tda995x=no]) -## Optional path to the NXP dev toolkit -AC_ARG_WITH([nxp-toolkit-path], - [AS_HELP_STRING([--with-nxp-toolkit-path], - [location of the NXP HDMI toolkit (default is ./nxp_hdmi)])], - [NXP_CFLAGS="-I$withval/inc"], - [NXP_CFLAGS="-I\$(abs_top_srcdir)/nxp_hdmi/inc"]) +## Optional path to the tda995x dev toolkit +AC_ARG_WITH([tda995x-toolkit-path], + [AS_HELP_STRING([--with-tda995x-toolkit-path], + [location of the TDA995x driver toolkit (default is ./nxp_hdmi)])], + [TDA995X_CFLAGS="-I$withval/inc"], + [TDA995X_CFLAGS="-I\$(abs_top_srcdir)/nxp_hdmi/inc"]) ## Raspberry Pi support AC_ARG_ENABLE([rpi], @@ -250,14 +250,14 @@ else fi ## mark CuBox support as available -if test "x$use_nxp" != "xno"; then - AC_DEFINE([HAVE_NXP_API],[1],[Define to 1 to include CuBox support]) - AM_CONDITIONAL(USE_NXP_API, true) +if test "x$use_tda995x" != "xno"; then + AC_DEFINE([HAVE_TDA995X_API],[1],[Define to 1 to include CuBox support]) + AM_CONDITIONAL(USE_TDA995X_API, true) features="$features\n CuBox support :\t\t\tyes" LIB_INFO="$LIB_INFO 'CuBox'" - CPPFLAGS="$CPPFLAGS $NXP_CFLAGS" + CPPFLAGS="$CPPFLAGS $TDA995X_CFLAGS" else - AM_CONDITIONAL(USE_NXP_API, false) + AM_CONDITIONAL(USE_TDA995X_API, false) features="$features\n CuBox support :\t\t\tno" fi diff --git a/include/cectypes.h b/include/cectypes.h index 0687c72..a44bbea 100644 --- a/include/cectypes.h +++ b/include/cectypes.h @@ -117,8 +117,8 @@ namespace CEC { #define CEC_RPI_VIRTUAL_PATH "Raspberry Pi" #define CEC_RPI_VIRTUAL_COM "RPI" -#define CEC_NXP_PATH "/dev/hdmicec" -#define CEC_NXP_VIRTUAL_COM "NXP" +#define CEC_TDA995x_PATH "/dev/hdmicec" +#define CEC_TDA995x_VIRTUAL_COM "CuBox" #define CEC_MIN_LIB_VERSION 1 #define CEC_LIB_VERSION_MAJOR 1 @@ -656,7 +656,7 @@ typedef enum cec_adapter_type ADAPTERTYPE_P8_EXTERNAL = 0x1, ADAPTERTYPE_P8_DAUGHTERBOARD = 0x2, ADAPTERTYPE_RPI = 0x100, - ADAPTERTYPE_NXP = 0x101 + ADAPTERTYPE_TDA995x = 0x200 } cec_adapter_type; typedef struct cec_menu_language diff --git a/src/lib/CECTypeUtils.h b/src/lib/CECTypeUtils.h index 90b287a..548fc97 100644 --- a/src/lib/CECTypeUtils.h +++ b/src/lib/CECTypeUtils.h @@ -795,8 +795,8 @@ namespace CEC return "Pulse-Eight USB-CEC Daughterboard"; case ADAPTERTYPE_RPI: return "Raspberry Pi"; - case ADAPTERTYPE_NXP: - return "Cubox"; + case ADAPTERTYPE_TDA995x: + return "TDA995x"; default: return "unknown"; } diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index b4afcd1..b88b02b 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -51,7 +51,7 @@ libcec_la_SOURCES += adapter/RPi/RPiCECAdapterDetection.cpp \ endif ## CuBox (NXP) support -if USE_NXP_API +if USE_TDA995X_API libcec_la_SOURCES += adapter/CuBox/NxpCECAdapterDetection.cpp \ adapter/CuBox/NxpCECAdapterCommunication.cpp endif diff --git a/src/lib/adapter/AdapterFactory.cpp b/src/lib/adapter/AdapterFactory.cpp index 8ade6ee..d1dae84 100644 --- a/src/lib/adapter/AdapterFactory.cpp +++ b/src/lib/adapter/AdapterFactory.cpp @@ -47,7 +47,7 @@ #include "RPi/RPiCECAdapterCommunication.h" #endif -#if defined(HAVE_NXP_API) +#if defined(HAVE_TDA995X_API) #include "CuBox/NxpCECAdapterDetection.h" #include "CuBox/NxpCECAdapterCommunication.h" #endif @@ -80,15 +80,16 @@ int8_t CAdapterFactory::FindAdapters(cec_adapter *deviceList, uint8_t iBufSize, } #endif -#if defined(HAVE_NXP_API) - if (iAdaptersFound < iBufSize && CNxpCECAdapterDetection::FindAdapter()) +#if defined(HAVE_TDA995X_API) + if (iAdaptersFound < iBufSize && CNxpCECAdapterDetection::FindAdapter() && + (!strDevicePath || !strcmp(strDevicePath, CEC_TDA995x_VIRTUAL_COM))) { - snprintf(deviceList[iAdaptersFound].path, 1024, CEC_NXP_PATH); - snprintf(deviceList[iAdaptersFound++].comm, 1024, CEC_NXP_VIRTUAL_COM); + snprintf(deviceList[iAdaptersFound].path, 1024, CEC_TDA995x_PATH); + snprintf(deviceList[iAdaptersFound++].comm, 1024, CEC_TDA995x_VIRTUAL_COM); } #endif -#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_NXP_API) +#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) #error "libCEC doesn't have support for any type of adapter. please check your build system or configuration" #endif @@ -97,9 +98,9 @@ int8_t CAdapterFactory::FindAdapters(cec_adapter *deviceList, uint8_t iBufSize, IAdapterCommunication *CAdapterFactory::GetInstance(const char *strPort, uint16_t iBaudRate) { -#if defined(HAVE_NXP_API) - if (!strcmp(strPort, CEC_NXP_VIRTUAL_COM)) - return new CNxpCECAdapterCommunication(m_lib->m_cec, CEC_NXP_PATH); +#if defined(HAVE_TDA995X_API) + if (!strcmp(strPort, CEC_TDA995x_VIRTUAL_COM)) + return new CNxpCECAdapterCommunication(m_lib->m_cec); #endif #if defined(HAVE_RPI_API) @@ -111,7 +112,7 @@ IAdapterCommunication *CAdapterFactory::GetInstance(const char *strPort, uint16_ return new CUSBCECAdapterCommunication(m_lib->m_cec, strPort, iBaudRate); #endif -#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_NXP_API) +#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) return NULL; #endif } diff --git a/src/lib/adapter/CuBox/AdapterMessageQueue.h b/src/lib/adapter/CuBox/AdapterMessageQueue.h index 7904084..d17f344 100644 --- a/src/lib/adapter/CuBox/AdapterMessageQueue.h +++ b/src/lib/adapter/CuBox/AdapterMessageQueue.h @@ -44,8 +44,8 @@ namespace CEC : m_bWaiting(true), m_retval((uint32_t)-1), m_bSucceeded(false) { m_hash = hashValue( - uint32_t(command.opcode_set ? command.opcode : CEC_OPCODE_NONE), - command.initiator, command.destination); + uint32_t(command.opcode_set ? command.opcode : CEC_OPCODE_NONE), + command.initiator, command.destination); } virtual ~CAdapterMessageQueueEntry(void) {} @@ -71,7 +71,7 @@ namespace CEC * @brief Signal waiting thread(s) when message matches this entry */ bool CheckMatch(uint32_t opcode, cec_logical_address initiator, - cec_logical_address destination, uint32_t response) + cec_logical_address destination, uint32_t response) { uint32_t hash = hashValue(opcode, initiator, destination); @@ -79,10 +79,10 @@ namespace CEC { CLockObject lock(m_mutex); - m_retval = response; + m_retval = response; m_bSucceeded = true; m_condition.Signal(); - return true; + return true; } return false; @@ -96,8 +96,8 @@ namespace CEC 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; } @@ -115,8 +115,8 @@ namespace CEC * @return Hash value for given cec_command */ static uint32_t hashValue(uint32_t opcode, - cec_logical_address initiator, - cec_logical_address destination) + cec_logical_address initiator, + cec_logical_address destination) { return 1 | ((uint32_t)initiator << 8) | ((uint32_t)destination << 16) | ((uint32_t)opcode << 16); diff --git a/src/lib/adapter/CuBox/NxpCECAdapterCommunication.cpp b/src/lib/adapter/CuBox/NxpCECAdapterCommunication.cpp index 44912d2..e46f94e 100644 --- a/src/lib/adapter/CuBox/NxpCECAdapterCommunication.cpp +++ b/src/lib/adapter/CuBox/NxpCECAdapterCommunication.cpp @@ -32,7 +32,7 @@ #include "env.h" -#if defined(HAVE_NXP_API) +#if defined(HAVE_TDA995X_API) #include "NxpCECAdapterCommunication.h" #include "lib/CECTypeUtils.h" @@ -55,41 +55,31 @@ using namespace PLATFORM; #define LIB_CEC m_callback->GetLib() -#if 0 - #define TRACE(a) LIB_CEC->AddLog a -#else - #define TRACE(a) -#endif - // 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_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*/ +#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*/ -CNxpCECAdapterCommunication::CNxpCECAdapterCommunication(IAdapterCommunicationCallback *callback, const char *UNUSED(device)) : +CNxpCECAdapterCommunication::CNxpCECAdapterCommunication(IAdapterCommunicationCallback *callback) : IAdapterCommunication(callback), m_bLogicalAddressChanged(false) { - TRACE((CEC_LOG_DEBUG, "%s called", __func__)); - CLockObject lock(m_mutex); m_iNextMessage = 0; m_logicalAddresses.Clear(); - m_dev = new CCDevSocket(CEC_NXP_PATH); + m_dev = new CCDevSocket(CEC_TDA995x_PATH); } CNxpCECAdapterCommunication::~CNxpCECAdapterCommunication(void) { - TRACE((CEC_LOG_DEBUG, "%s called", __func__)); - Close(); CLockObject lock(m_mutex); @@ -104,10 +94,8 @@ bool CNxpCECAdapterCommunication::IsOpen(void) } -bool CNxpCECAdapterCommunication::Open(uint32_t iTimeoutMs, bool bSkipChecks, bool bStartListening) +bool CNxpCECAdapterCommunication::Open(uint32_t iTimeoutMs, bool UNUSED(bSkipChecks), bool bStartListening) { - TRACE((CEC_LOG_DEBUG, "%s called (%d,%d,%d)", __func__, iTimeoutMs, bSkipChecks, bStartListening)); - if (m_dev->Open(iTimeoutMs)) { unsigned char raw_mode = 0xff; @@ -131,7 +119,7 @@ bool CNxpCECAdapterCommunication::Open(uint32_t iTimeoutMs, bool bSkipChecks, bo else { LIB_CEC->AddLog(CEC_LOG_ERROR, - "%s: CEC_IOCTL_GET_RAW_MODE not supported. Please update your kernel.", __func__); + "%s: CEC_IOCTL_GET_RAW_MODE not supported. Please update your kernel.", __func__); } m_dev->Close(); @@ -143,8 +131,6 @@ bool CNxpCECAdapterCommunication::Open(uint32_t iTimeoutMs, bool bSkipChecks, bo void CNxpCECAdapterCommunication::Close(void) { - TRACE((CEC_LOG_DEBUG, "%s called", __func__)); - StopThread(0); unsigned char raw_mode = 0; @@ -167,11 +153,7 @@ cec_adapter_message_state CNxpCECAdapterCommunication::Write( cec_frame frame; CAdapterMessageQueueEntry *entry; cec_adapter_message_state rc = ADAPTER_MESSAGE_STATE_ERROR; - - TRACE((CEC_LOG_DEBUG, "%s: %x->%x, %d,%d,%d OPC%02x TMO%d LEN%d [%02x,%02x,%02x,%02x...]", __func__, - data.initiator, data.destination, data.ack, data.eom, data.opcode_set, data.opcode, data.transmit_timeout, - data.parameters.size, data.parameters.data[0], data.parameters.data[1],data.parameters.data[2],data.parameters.data[3])); - + if ((size_t)data.parameters.size + data.opcode_set > sizeof(frame.data)) { LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: data size too large !", __func__); @@ -211,8 +193,6 @@ cec_adapter_message_state CNxpCECAdapterCommunication::Write( rc = ADAPTER_MESSAGE_STATE_SENT_NOT_ACKED; else if (status == CEC_MSG_SUCCESS) rc = ADAPTER_MESSAGE_STATE_SENT_ACKED; - - TRACE((CEC_LOG_DEBUG, "%s: reply received (0x%02x)", __func__, status)); } else LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: command timed out !", __func__); @@ -237,10 +217,6 @@ uint16_t CNxpCECAdapterCommunication::GetFirmwareVersion(void) m_dev->Ioctl(CEC_IOCTL_GET_SW_VERSION, &vers); - TRACE((CEC_LOG_DEBUG, - "%s: %s comp: %08lX, major: %08lX, minor: %08lX", __func__, - m_dev->GetName().c_str(), vers.compatibilityNr, vers.majorVersionNr, vers.minorVersionNr)); - return (vers.majorVersionNr * 100) + vers.minorVersionNr; } @@ -255,8 +231,6 @@ cec_vendor_id CNxpCECAdapterCommunication::GetVendorId(void) return CEC_VENDOR_LG; } - TRACE((CEC_LOG_DEBUG, "%s: Vendor=%08x", __func__, info.VendorID)); - return cec_vendor_id(info.VendorID); } @@ -271,8 +245,6 @@ uint16_t CNxpCECAdapterCommunication::GetPhysicalAddress(void) return CEC_INVALID_PHYSICAL_ADDRESS; } - TRACE((CEC_LOG_DEBUG, "%s: PhysAddr=%x", __func__, info.PhysicalAddress)); - return info.PhysicalAddress; } @@ -304,16 +276,12 @@ cec_logical_addresses CNxpCECAdapterCommunication::GetLogicalAddresses(void) m_bLogicalAddressChanged = false; } - TRACE((CEC_LOG_DEBUG, "%s: LogAddr=%d", __func__, (int)m_logicalAddresses.primary)); - return m_logicalAddresses; } bool CNxpCECAdapterCommunication::SetLogicalAddresses(const cec_logical_addresses &addresses) { - TRACE((CEC_LOG_DEBUG, "%s: LogAddr=%d", __func__, addresses.primary)); - unsigned char log_addr = addresses.primary; if (m_dev->Ioctl(CEC_IOCTL_RX_ADDR, &log_addr) != 0) @@ -340,10 +308,8 @@ bool CNxpCECAdapterCommunication::SetLogicalAddresses(const cec_logical_addresse } -void CNxpCECAdapterCommunication::HandleLogicalAddressLost(cec_logical_address oldAddress) +void CNxpCECAdapterCommunication::HandleLogicalAddressLost(cec_logical_address UNUSED(oldAddress)) { - TRACE((CEC_LOG_DEBUG, "%s: LogAddr=%d", __func__, (int)oldAddress)); - unsigned char log_addr = CECDEVICE_BROADCAST; if (m_dev->Ioctl(CEC_IOCTL_RX_ADDR, &log_addr) != 0) @@ -367,19 +333,15 @@ void *CNxpCECAdapterCommunication::Process(void) initiator = cec_logical_address(frame.addr >> 4); destination = cec_logical_address(frame.addr & 0x0f); - TRACE((CEC_LOG_DEBUG, - "%s: frame received [%x->%x] (srvc=%d, len=%d)", - __func__, initiator, destination, frame.service, frame.size)); - if (frame.service == CEC_RX_PKT) { - cec_command cmd; + cec_command cmd; - cec_command::Format( - cmd, initiator, destination, + cec_command::Format( + cmd, initiator, destination, ( frame.size > 3 ) ? cec_opcode(frame.data[0]) : CEC_OPCODE_NONE); - for( uint8_t i = 1; i < frame.size-3; i++ ) + for( uint8_t i = 1; i < frame.size-3; i++ ) cmd.parameters.PushBack(frame.data[i]); m_callback->OnCommandReceived(cmd); @@ -387,15 +349,15 @@ void *CNxpCECAdapterCommunication::Process(void) else if (frame.service == CEC_ACK_PKT) { bHandled = false; - status = ( frame.size > 3 ) ? frame.data[0] : 255; + status = ( frame.size > 3 ) ? frame.data[0] : 255; opcode = ( frame.size > 4 ) ? frame.data[1] : (uint32_t)CEC_OPCODE_NONE; m_messageMutex.Lock(); for (map::iterator it = m_messages.begin(); - !bHandled && it != m_messages.end(); it++) - { + !bHandled && it != m_messages.end(); it++) + { bHandled = it->second->CheckMatch(opcode, initiator, destination, status); - } + } m_messageMutex.Unlock(); if (!bHandled) @@ -407,6 +369,4 @@ void *CNxpCECAdapterCommunication::Process(void) return 0; } - -#endif // HAVE_NXP_API - +#endif // HAVE_TDA995X_API diff --git a/src/lib/adapter/CuBox/NxpCECAdapterCommunication.h b/src/lib/adapter/CuBox/NxpCECAdapterCommunication.h index 9a06e16..066c032 100644 --- a/src/lib/adapter/CuBox/NxpCECAdapterCommunication.h +++ b/src/lib/adapter/CuBox/NxpCECAdapterCommunication.h @@ -31,7 +31,7 @@ * http://www.pulse-eight.net/ */ -#if defined(HAVE_NXP_API) +#if defined(HAVE_TDA995X_API) #include "lib/platform/threads/mutex.h" #include "lib/platform/threads/threads.h" @@ -57,7 +57,7 @@ namespace CEC * @brief Create a new USB-CEC communication handler. * @param callback The callback to use for incoming CEC commands. */ - CNxpCECAdapterCommunication(IAdapterCommunicationCallback *callback, const char *device); + CNxpCECAdapterCommunication(IAdapterCommunicationCallback *callback); virtual ~CNxpCECAdapterCommunication(void); /** @name IAdapterCommunication implementation */ @@ -83,7 +83,7 @@ namespace CEC bool SetControlledMode(bool UNUSED(controlled)) { return true; } cec_vendor_id GetVendorId(void); bool SupportsSourceLogicalAddress(const cec_logical_address address) { return address > CECDEVICE_TV && address <= CECDEVICE_BROADCAST; } - cec_adapter_type GetAdapterType(void) { return ADAPTERTYPE_NXP; } + cec_adapter_type GetAdapterType(void) { return ADAPTERTYPE_TDA995x; } void HandleLogicalAddressLost(cec_logical_address oldAddress); ///} @@ -101,7 +101,7 @@ namespace CEC cec_logical_addresses m_logicalAddresses; PLATFORM::CMutex m_mutex; - PLATFORM::CCDevSocket *m_dev; /**< the device connection */ + PLATFORM::CCDevSocket *m_dev; /**< the device connection */ PLATFORM::CMutex m_messageMutex; uint32_t m_iNextMessage; diff --git a/src/lib/adapter/CuBox/NxpCECAdapterDetection.cpp b/src/lib/adapter/CuBox/NxpCECAdapterDetection.cpp index c4d1327..b4b7495 100644 --- a/src/lib/adapter/CuBox/NxpCECAdapterDetection.cpp +++ b/src/lib/adapter/CuBox/NxpCECAdapterDetection.cpp @@ -33,7 +33,7 @@ #include "env.h" #include -#if defined(HAVE_NXP_API) +#if defined(HAVE_TDA995X_API) #include "NxpCECAdapterDetection.h" extern "C" { @@ -46,10 +46,7 @@ using namespace CEC; bool CNxpCECAdapterDetection::FindAdapter(void) { - /* NXP HDMI uses /dev/hdmicec and ioctl() communication */ - - return access(CEC_NXP_PATH, 0) == 0; + return access(CEC_TDA995x_PATH, 0) == 0; } #endif - -- 2.34.1