From a7f3315333c1a79259a763c6542a6cd71855b357 Mon Sep 17 00:00:00 2001 From: Stefan Saraev Date: Thu, 7 May 2015 11:35:04 +0300 Subject: [PATCH] imx support note. I am NOT the author of the patch. just rebased it --- include/cectypes.h | 14 +- src/libcec/CECTypeUtils.h | 2 + src/libcec/adapter/AdapterFactory.cpp | 29 +- src/libcec/adapter/IMX/AdapterMessageQueue.h | 134 +++++++++ .../adapter/IMX/IMXCECAdapterCommunication.cpp | 328 +++++++++++++++++++++ .../adapter/IMX/IMXCECAdapterCommunication.h | 119 ++++++++ src/libcec/adapter/IMX/IMXCECAdapterDetection.cpp | 42 +++ src/libcec/adapter/IMX/IMXCECAdapterDetection.h | 36 +++ src/libcec/cmake/CheckPlatformSupport.cmake | 10 + src/libcec/cmake/DisplayPlatformSupport.cmake | 6 + src/libcec/env.h.in | 3 + 11 files changed, 720 insertions(+), 3 deletions(-) create mode 100644 src/libcec/adapter/IMX/AdapterMessageQueue.h 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 diff --git a/include/cectypes.h b/include/cectypes.h index acff259..0cfee8c 100644 --- a/include/cectypes.h +++ b/include/cectypes.h @@ -309,6 +309,17 @@ namespace CEC { #define CEC_EXYNOS_VIRTUAL_COM "Exynos" /*! + * 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" + + +/*! * Mimimum client version */ #define CEC_MIN_LIB_VERSION 3 @@ -876,7 +887,8 @@ typedef enum cec_adapter_type ADAPTERTYPE_P8_DAUGHTERBOARD = 0x2, ADAPTERTYPE_RPI = 0x100, ADAPTERTYPE_TDA995x = 0x200, - ADAPTERTYPE_EXYNOS = 0x300 + ADAPTERTYPE_EXYNOS = 0x300, + ADAPTERTYPE_IMX = 0x400 } cec_adapter_type; /** force exporting through swig */ diff --git a/src/libcec/CECTypeUtils.h b/src/libcec/CECTypeUtils.h index fd8046a..48cb215 100644 --- a/src/libcec/CECTypeUtils.h +++ b/src/libcec/CECTypeUtils.h @@ -765,6 +765,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/adapter/AdapterFactory.cpp b/src/libcec/adapter/AdapterFactory.cpp index da05725..92e378b 100644 --- a/src/libcec/adapter/AdapterFactory.cpp +++ b/src/libcec/adapter/AdapterFactory.cpp @@ -58,6 +58,11 @@ #include "Exynos/ExynosCECAdapterCommunication.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 */) @@ -127,7 +132,22 @@ int8_t CAdapterFactory::DetectAdapters(cec_adapter_descriptor *deviceList, uint8 #endif -#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) + +#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_IMX_API) #error "libCEC doesn't have support for any type of adapter. please check your build system or configuration" #endif @@ -151,11 +171,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) +#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_EXYNOS_API) && !defined(HAVE_IMX_API) return NULL; #endif } diff --git a/src/libcec/adapter/IMX/AdapterMessageQueue.h b/src/libcec/adapter/IMX/AdapterMessageQueue.h new file mode 100644 index 0000000..af6742c --- /dev/null +++ b/src/libcec/adapter/IMX/AdapterMessageQueue.h @@ -0,0 +1,134 @@ +#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 + * http://www.pulse-eight.com/ + * http://www.pulse-eight.net/ + */ + +#include "platform/threads/mutex.h" + +namespace CEC +{ + using namespace PLATFORM; + + class CAdapterMessageQueueEntry + { + public: + CAdapterMessageQueueEntry(const cec_command &command) + : 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); + } + + virtual ~CAdapterMessageQueueEntry(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 CheckMatch(uint32_t opcode, cec_logical_address initiator, + cec_logical_address destination, uint32_t response) + { + uint32_t hash = hashValue(opcode, initiator, destination); + + if (hash == m_hash) + { + CLockObject lock(m_mutex); + + m_retval = response; + m_bSucceeded = true; + m_condition.Signal(); + return true; + } + + return false; + } + + /*! + * @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; + } + + /*! + * @return Hash value for given cec_command + */ + static uint32_t hashValue(uint32_t opcode, + cec_logical_address initiator, + cec_logical_address destination) + { + return 1 | ((uint32_t)initiator << 8) | + ((uint32_t)destination << 16) | ((uint32_t)opcode << 16); + } + + private: + bool m_bWaiting; /**< true while a thread is waiting or when it hasn't started waiting yet */ + PLATFORM::CCondition m_condition; /**< the condition to wait on */ + PLATFORM::CMutex m_mutex; /**< mutex for changes to this class */ + uint32_t m_hash; + uint32_t m_retval; + bool m_bSucceeded; + }; + +}; diff --git a/src/libcec/adapter/IMX/IMXCECAdapterCommunication.cpp b/src/libcec/adapter/IMX/IMXCECAdapterCommunication.cpp new file mode 100644 index 0000000..2daa8cb --- /dev/null +++ b/src/libcec/adapter/IMX/IMXCECAdapterCommunication.cpp @@ -0,0 +1,328 @@ +/* + * 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" + +#if defined(HAVE_IMX_API) +#include "IMXCECAdapterCommunication.h" + +#include "CECTypeUtils.h" +#include "LibCEC.h" +#include "platform/sockets/cdevsocket.h" +#include "platform/util/StdString.h" +#include "platform/util/buffer.h" + +/* + * Ioctl definitions from kernel header + */ +#define HDMICEC_IOC_MAGIC 'H' +#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_CEC_MESSAGE_LEN 17 + +#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 + +typedef struct hdmi_cec_event{ + int event_type; + int msg_len; + unsigned char msg[MAX_CEC_MESSAGE_LEN]; +}hdmi_cec_event; + + +using namespace std; +using namespace CEC; +using namespace PLATFORM; + +#include "AdapterMessageQueue.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_bLogicalAddressChanged(false)*/ +{ + CLockObject lock(m_mutex); + + m_iNextMessage = 0; + //m_logicalAddresses.Clear(); + m_logicalAddress = CECDEVICE_UNKNOWN; + m_bLogicalAddressRegistered = false; + m_bInitialised = false; + m_dev = new CCDevSocket(CEC_IMX_PATH); +} + +CIMXCECAdapterCommunication::~CIMXCECAdapterCommunication(void) +{ + Close(); + + CLockObject lock(m_mutex); + 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; + return true; + } + LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: Unable to start device\n", __func__); + } + m_dev->Close(); + } + + return false; +} + + +void CIMXCECAdapterCommunication::Close(void) +{ + StopThread(0); + + CLockObject lock(m_mutex); + if (!m_bInitialised) { + return; + } + if (m_dev->Ioctl(HDMICEC_IOC_STOPDEVICE, NULL) != 0) { + LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: Unable to stop device\n", __func__); + } + m_dev->Close(); + m_bInitialised = false; +} + + +std::string CIMXCECAdapterCommunication::GetError(void) const +{ + std::string strError(m_strError); + return strError; +} + + +cec_adapter_message_state CIMXCECAdapterCommunication::Write( + const cec_command &data, bool &UNUSED(bRetry), uint8_t UNUSED(iLineTimeout), bool UNUSED(bIsReply)) +{ + //cec_frame frame; + unsigned char message[MAX_CEC_MESSAGE_LEN]; + int msg_len = 1; + cec_adapter_message_state rc = ADAPTER_MESSAGE_STATE_ERROR; + + if ((size_t)data.parameters.size + data.opcode_set + 1 > sizeof(message)) + { + LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: data size too large !", __func__); + return ADAPTER_MESSAGE_STATE_ERROR; + } + + 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; + } + + if (m_dev->Write(message, msg_len) == msg_len) + { + rc = ADAPTER_MESSAGE_STATE_SENT_ACKED; + } + else + LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: sent command error !", __func__); + + 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) +{ + uint32_t info; + uint16_t phy_addr; + + if (m_dev->Ioctl(HDMICEC_IOC_GETPHYADDRESS, &info) != 0) + { + LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: HDMICEC_IOC_GETPHYADDRESS failed !", __func__); + return CEC_INVALID_PHYSICAL_ADDRESS; + } + /* Rebuild 16 bit raw value from fsl 32 bits value */ + phy_addr = ((info & 0x0f) << 12) | (info & 0x0f00) | + ((info & 0x0f0000) >> 12) | ((info & 0x0f000000) >> 24); + + return phy_addr; +} + + +cec_logical_addresses CIMXCECAdapterCommunication::GetLogicalAddresses(void) +{ + cec_logical_addresses addresses; + addresses.Clear(); + + CLockObject lock(m_mutex); + if ((m_logicalAddress & (CECDEVICE_UNKNOWN | CECDEVICE_UNREGISTERED)) == 0) + 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; + + if (m_dev->Ioctl(HDMICEC_IOC_SETLOGICALADDRESS, (void *)CECDEVICE_BROADCAST) != 0) + { + LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: HDMICEC_IOC_SETLOGICALADDRESS failed !", __func__); + return false; + } + + m_logicalAddress = CECDEVICE_UNKNOWN; + m_bLogicalAddressRegistered = false; + return true; +} + +bool CIMXCECAdapterCommunication::RegisterLogicalAddress(const cec_logical_address address) +{ + CLockObject lock(m_mutex); + + if (m_logicalAddress == address && m_bLogicalAddressRegistered) + { + return true; + } + + if (m_dev->Ioctl(HDMICEC_IOC_SETLOGICALADDRESS, (void *)address) != 0) + { + LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: HDMICEC_IOC_SETLOGICALADDRESS failed !", __func__); + return false; + } + + m_logicalAddress = address; + m_bLogicalAddressRegistered = true; + 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; + + uint32_t opcode, status; + cec_logical_address initiator, destination; + + while (!IsStopped()) + { + ret = m_dev->Read((char *)&event, sizeof(event), 5000); + if (ret > 0) + { + + initiator = cec_logical_address(event.msg[0] >> 4); + destination = cec_logical_address(event.msg[0] & 0x0f); + + //LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s: Read data : type : %d initiator %d dest %d", __func__, event.event_type, initiator, destination); + if (event.event_type == MESSAGE_TYPE_RECEIVE_SUCCESS) + /* Message received */ + { + 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); + } + + if (event.event_type == MESSAGE_TYPE_CONNECTED) + /* HDMI has just been reconnected - Notify phy address*/ + { + uint16_t iNewAddress = GetPhysicalAddress(); + m_callback->HandlePhysicalAddressChanged(iNewAddress); + } + /* We are not interested in other events */ + } /*else { + LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s: Read returned %d", __func__, ret); + }*/ + + } + + return 0; +} + +#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..9e899a3 --- /dev/null +++ b/src/libcec/adapter/IMX/IMXCECAdapterCommunication.h @@ -0,0 +1,119 @@ +#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. + * + * + */ + +#if defined(HAVE_IMX_API) + +#include "platform/threads/mutex.h" +#include "platform/threads/threads.h" +#include "platform/sockets/socket.h" +#include "adapter/AdapterCommunication.h" +#include + +#define IMX_ADAPTER_VID 0x0471 /*FIXME TBD*/ +#define IMX_ADAPTER_PID 0x1001 + + + +namespace PLATFORM +{ + class CCDevSocket; +}; + + +namespace CEC +{ + class CAdapterMessageQueueEntry; + + class CIMXCECAdapterCommunication : public IAdapterCommunication, public PLATFORM::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); + 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 HandleLogicalAddressLost(cec_logical_address UNUSED(oldAddress)); + void SetActiveSource(bool UNUSED(bSetTo), bool UNUSED(bClientUnregistered)) {} + bool RegisterLogicalAddress(const cec_logical_address address); + ///} + + /** @name PLATFORM::CThread implementation */ + ///{ + void *Process(void); + ///} + + private: + bool IsInitialised(void) const { return m_bInitialised; }; + bool UnregisterLogicalAddress(void); + + std::string m_strError; /**< current error message */ + + //cec_logical_addresses m_logicalAddresses; + cec_logical_address m_logicalAddress; + + PLATFORM::CMutex m_mutex; + PLATFORM::CCDevSocket *m_dev; /**< the device connection */ + bool m_bLogicalAddressRegistered; + bool m_bInitialised; + + PLATFORM::CMutex m_messageMutex; + uint32_t m_iNextMessage; + std::map m_messages; + }; + +}; + +#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 + +#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/cmake/CheckPlatformSupport.cmake b/src/libcec/cmake/CheckPlatformSupport.cmake index 828cdb2..8b47795 100644 --- a/src/libcec/cmake/CheckPlatformSupport.cmake +++ b/src/libcec/cmake/CheckPlatformSupport.cmake @@ -8,6 +8,7 @@ # HAVE_RANDR 1 if xrandr is supported # HAVE_LIBUDEV 1 if udev is supported # HAVE_RPI_API 1 if Raspberry Pi is supported +# HAVE_IMX_API 1 if i.MX is supported # HAVE_TDA995X_API 1 if TDA995X is supported # HAVE_EXYNOS_API 1 if Exynos is supported # HAVE_P8_USB_DETECT 1 if Pulse-Eight devices can be auto-detected @@ -87,6 +88,15 @@ else() list(APPEND CEC_SOURCES ${CEC_SOURCES_ADAPTER_RPI}) endif() + # i.MX + if (HAVE_IMX_API) + set(LIB_INFO "${LIB_INFO}, 'IMX'") + set(CEC_SOURCES_ADAPTER_IMX adapter/IMX/IMXCECAdapterDetection.cpp + adapter/IMX/IMXCECAdapterCommunication.cpp) + source_group("Source Files\\adapter\\IMX" FILES ${CEC_SOURCES_ADAPTER_IMX}) + list(APPEND CEC_SOURCES ${CEC_SOURCES_ADAPTER_IMX}) + endif() + # TDA995x check_include_files("tda998x_ioctl.h;comps/tmdlHdmiCEC/inc/tmdlHdmiCEC_Types.h" HAVE_TDA995X_API) if (HAVE_TDA995X_API) diff --git a/src/libcec/cmake/DisplayPlatformSupport.cmake b/src/libcec/cmake/DisplayPlatformSupport.cmake index feee111..0309c56 100644 --- a/src/libcec/cmake/DisplayPlatformSupport.cmake +++ b/src/libcec/cmake/DisplayPlatformSupport.cmake @@ -32,6 +32,12 @@ else() message(STATUS "Raspberry Pi support: no") endif() +if (HAVE_IMX_API) + message(STATUS "i.MX support: yes") +else() + message(STATUS "i.MX support: no") +endif() + if (HAVE_TDA995X_API) message(STATUS "TDA995x support: yes") else() diff --git a/src/libcec/env.h.in b/src/libcec/env.h.in index a1a1f26..f90e729 100644 --- a/src/libcec/env.h.in +++ b/src/libcec/env.h.in @@ -60,6 +60,9 @@ /* Define to 1 for Raspberry Pi support */ #cmakedefine HAVE_RPI_API @HAVE_RPI_API@ +/* Define to 1 for IMX support */ +#cmakedefine HAVE_IMX_API @HAVE_IMX_API@ + /* Define to 1 for TDA995x support */ #cmakedefine HAVE_TDA995X_API @HAVE_TDA995X_API@ -- 2.1.4