diff -Naur libcec-2.2.0/configure.ac libcec-2.2.0.patch/configure.ac --- libcec-2.2.0/configure.ac 2014-11-01 01:51:37.000000000 +0100 +++ libcec-2.2.0.patch/configure.ac 2014-11-10 23:14:45.210162950 +0100 @@ -100,6 +100,14 @@ esac fi +## i.MX6 support +AC_ARG_ENABLE([imx6], + [AS_HELP_STRING([--enable-imx6], + [enable support for freescale i.MX6 (default is no)])], + [use_imx6=$enableval], + [use_imx6=no]) + + ## add the top dir and include to the include path, so we can include config.h and cec.h CPPFLAGS="$CPPFLAGS -I\$(abs_top_srcdir)/src -I\$(abs_top_srcdir)/include" @@ -306,6 +314,17 @@ fi +## mark i.MX6 support as available +if test "x$use_imx6" != "xno"; then + AC_DEFINE([HAVE_IMX_API],[1],[Define to 1 to include i.MX6 support]) + AM_CONDITIONAL(USE_IMX_API, true) + features="$features\n i.MX6 support :\t\t\tyes" + LIB_INFO="$LIB_INFO 'i.MX6'" +else + AM_CONDITIONAL(USE_IMX_API, false) + features="$features\n i.MX6 support :\t\t\tno" +fi + ## check if our build system is complete AC_CHECK_HEADER(algorithm,,AC_MSG_ERROR($msg_required_header_missing)) AC_CHECK_HEADER(ctype.h,,AC_MSG_ERROR($msg_required_header_missing)) diff -Naur libcec-2.2.0/include/cectypes.h libcec-2.2.0.patch/include/cectypes.h --- libcec-2.2.0/include/cectypes.h 2014-10-28 16:20:50.000000000 +0100 +++ libcec-2.2.0.patch/include/cectypes.h 2014-11-10 23:21:37.347945493 +0100 @@ -307,6 +307,17 @@ #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 2 @@ -888,7 +899,8 @@ ADAPTERTYPE_P8_DAUGHTERBOARD = 0x2, ADAPTERTYPE_RPI = 0x100, ADAPTERTYPE_TDA995x = 0x200, - ADAPTERTYPE_EXYNOS = 0x300 + ADAPTERTYPE_EXYNOS = 0x300, + ADAPTERTYPE_IMX = 0x400 } cec_adapter_type; typedef struct cec_menu_language diff -Naur libcec-2.2.0/src/lib/adapter/AdapterFactory.cpp libcec-2.2.0.patch/src/lib/adapter/AdapterFactory.cpp --- libcec-2.2.0/src/lib/adapter/AdapterFactory.cpp 2014-10-28 16:20:50.000000000 +0100 +++ libcec-2.2.0.patch/src/lib/adapter/AdapterFactory.cpp 2014-11-10 23:18:08.761485552 +0100 @@ -57,6 +57,11 @@ #include "Exynos/ExynosCECAdapterCommunication.h" #endif +#if defined(HAVE_IMX_API) +#include "IMX/IMXCECAdapterDetection.h" +#include "IMX/IMXCECAdapterCommunication.h" +#endif + using namespace std; using namespace CEC; @@ -127,7 +132,22 @@ #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 @@ 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 -Naur libcec-2.2.0/src/lib/adapter/IMX/AdapterMessageQueue.h libcec-2.2.0.patch/src/lib/adapter/IMX/AdapterMessageQueue.h --- libcec-2.2.0/src/lib/adapter/IMX/AdapterMessageQueue.h 1970-01-01 01:00:00.000000000 +0100 +++ libcec-2.2.0.patch/src/lib/adapter/IMX/AdapterMessageQueue.h 2014-11-10 23:14:45.214162390 +0100 @@ -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 "lib/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 -Naur libcec-2.2.0/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp libcec-2.2.0.patch/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp --- libcec-2.2.0/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp 1970-01-01 01:00:00.000000000 +0100 +++ libcec-2.2.0.patch/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp 2014-11-10 23:14:45.217161982 +0100 @@ -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 "lib/CECTypeUtils.h" +#include "lib/LibCEC.h" +#include "lib/platform/sockets/cdevsocket.h" +#include "lib/platform/util/StdString.h" +#include "lib/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 -Naur libcec-2.2.0/src/lib/adapter/IMX/IMXCECAdapterCommunication.h libcec-2.2.0.patch/src/lib/adapter/IMX/IMXCECAdapterCommunication.h --- libcec-2.2.0/src/lib/adapter/IMX/IMXCECAdapterCommunication.h 1970-01-01 01:00:00.000000000 +0100 +++ libcec-2.2.0.patch/src/lib/adapter/IMX/IMXCECAdapterCommunication.h 2014-11-10 23:14:45.217161982 +0100 @@ -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 "lib/platform/threads/mutex.h" +#include "lib/platform/threads/threads.h" +#include "lib/platform/sockets/socket.h" +#include "lib/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 -Naur libcec-2.2.0/src/lib/adapter/IMX/IMXCECAdapterDetection.cpp libcec-2.2.0.patch/src/lib/adapter/IMX/IMXCECAdapterDetection.cpp --- libcec-2.2.0/src/lib/adapter/IMX/IMXCECAdapterDetection.cpp 1970-01-01 01:00:00.000000000 +0100 +++ libcec-2.2.0.patch/src/lib/adapter/IMX/IMXCECAdapterDetection.cpp 2014-11-10 23:14:45.215162253 +0100 @@ -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 -Naur libcec-2.2.0/src/lib/adapter/IMX/IMXCECAdapterDetection.h libcec-2.2.0.patch/src/lib/adapter/IMX/IMXCECAdapterDetection.h --- libcec-2.2.0/src/lib/adapter/IMX/IMXCECAdapterDetection.h 1970-01-01 01:00:00.000000000 +0100 +++ libcec-2.2.0.patch/src/lib/adapter/IMX/IMXCECAdapterDetection.h 2014-11-10 23:14:45.215162253 +0100 @@ -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 -Naur libcec-2.2.0/src/lib/CECTypeUtils.h libcec-2.2.0.patch/src/lib/CECTypeUtils.h --- libcec-2.2.0/src/lib/CECTypeUtils.h 2014-10-28 16:20:50.000000000 +0100 +++ libcec-2.2.0.patch/src/lib/CECTypeUtils.h 2014-11-10 23:14:45.212162668 +0100 @@ -877,6 +877,8 @@ return "Raspberry Pi"; case ADAPTERTYPE_TDA995x: return "TDA995x"; + case ADAPTERTYPE_IMX: + return "i.MX"; default: return "unknown"; } diff -Naur libcec-2.2.0/src/lib/Makefile.am libcec-2.2.0.patch/src/lib/Makefile.am --- libcec-2.2.0/src/lib/Makefile.am 2014-10-28 16:20:50.000000000 +0100 +++ libcec-2.2.0.patch/src/lib/Makefile.am 2014-11-10 23:20:02.597700521 +0100 @@ -63,6 +63,12 @@ adapter/TDA995x/TDA995xCECAdapterCommunication.cpp endif +## i.MX6 support +if USE_IMX_API +libcec_la_SOURCES += adapter/IMX/IMXCECAdapterDetection.cpp \ + adapter/IMX/IMXCECAdapterCommunication.cpp +endif + ## Exynos support if USE_EXYNOS_API libcec_la_SOURCES += adapter/Exynos/ExynosCECAdapterDetection.cpp \