diff -Nur a/include/cectypes.h b/include/cectypes.h --- a/include/cectypes.h 2016-06-13 21:27:29.406425322 +0200 +++ b/include/cectypes.h 2016-06-13 21:31:55.586417939 +0200 @@ -330,6 +330,16 @@ #define CEC_AMLOGIC_VIRTUAL_COM "Amlogic" /*! + * the path to use for the Sunxi CEC device + */ +#define CEC_SUNXI_PATH "/dev/sunxi_hdmi_cec" + +/*! + * the name of the virtual COM port to use for the Sunxi CEC wire + */ +#define CEC_SUNXI_VIRTUAL_COM "Sunxi" + +/*! * Mimimum client version */ #define CEC_MIN_LIB_VERSION 3 @@ -899,7 +909,8 @@ ADAPTERTYPE_TDA995x = 0x200, ADAPTERTYPE_EXYNOS = 0x300, ADAPTERTYPE_IMX = 0x400, - ADAPTERTYPE_AMLOGIC = 0x500 + ADAPTERTYPE_AMLOGIC = 0x500, + ADAPTERTYPE_SUNXI = 0x600 } cec_adapter_type; /** force exporting through swig */ diff -Nur a/README.md b/README.md --- a/README.md 2016-06-13 21:27:29.406425322 +0200 +++ b/README.md 2016-06-13 21:39:13.943072447 +0200 @@ -70,6 +70,12 @@ cmake -DHAVE_TDA995X_API=1 .. ``` +### Sunxi +To compile in support for Sunxi devices, you have to pass the argument -DHAVE_SUNXI_LIB=1 to cmake: +``` +cmake -DHAVE_SUNXI_API=1 .. +``` + ## Apple OS X To compile libCEC on OS X, you'll need the following dependencies: diff -Nur a/src/libcec/adapter/AdapterFactory.cpp b/src/libcec/adapter/AdapterFactory.cpp --- a/src/libcec/adapter/AdapterFactory.cpp 2016-06-13 21:27:29.406425322 +0200 +++ b/src/libcec/adapter/AdapterFactory.cpp 2016-06-13 21:37:09.966409219 +0200 @@ -68,6 +68,11 @@ #include "Amlogic/AmlogicCECAdapterCommunication.h" #endif +#if defined(HAVE_SUNXI_API) +#include "Sunxi/SunxiCECAdapterDetection.h" +#include "Sunxi/SunxiCECAdapterCommunication.h" +#endif + using namespace CEC; int8_t CAdapterFactory::FindAdapters(cec_adapter *deviceList, uint8_t iBufSize, const char *strDevicePath /* = NULL */) @@ -163,8 +168,20 @@ } #endif +#if defined(HAVE_SUNXI_API) + if (iAdaptersFound < iBufSize && CSunxiCECAdapterDetection::FindAdapter() && + (!strDevicePath || !strcmp(strDevicePath, CEC_SUNXI_VIRTUAL_COM))) + { + snprintf(deviceList[iAdaptersFound].strComPath, sizeof(deviceList[iAdaptersFound].strComPath), CEC_SUNXI_PATH); + snprintf(deviceList[iAdaptersFound].strComName, sizeof(deviceList[iAdaptersFound].strComName), CEC_SUNXI_VIRTUAL_COM); + deviceList[iAdaptersFound].iVendorId = SUNXI_ADAPTER_VID; + deviceList[iAdaptersFound].iProductId = SUNXI_ADAPTER_PID; + deviceList[iAdaptersFound].adapterType = ADAPTERTYPE_SUNXI; + iAdaptersFound++; + } +#endif -#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_IMX_API) && !defined(HAVE_AMLOGIC_API) +#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_IMX_API) && !defined(HAVE_AMLOGIC_API) && !defined(HAVE_SUNXI_API) #error "libCEC doesn't have support for any type of adapter. please check your build system or configuration" #endif @@ -198,11 +215,16 @@ return new CAmlogicCECAdapterCommunication(m_lib->m_cec); #endif +#if defined(HAVE_SUNXI_API) + if (!strcmp(strPort, CEC_SUNXI_VIRTUAL_COM)) + return new CSunxiCECAdapterCommunication(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_IMX_API) && !defined(HAVE_AMLOGIC_API) +#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_EXYNOS_API) && !defined(HAVE_IMX_API) && !defined(HAVE_AMLOGIC_API) && !defined(HAVE_SUNXI_API) return NULL; #endif } diff -Nur a/src/libcec/adapter/Sunxi/AdapterMessageQueue.h b/src/libcec/adapter/Sunxi/AdapterMessageQueue.h --- a/src/libcec/adapter/Sunxi/AdapterMessageQueue.h 1970-01-01 01:00:00.000000000 +0100 +++ b/src/libcec/adapter/Sunxi/AdapterMessageQueue.h 2016-06-13 21:47:43.009724994 +0200 @@ -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 + +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 -Nur a/src/libcec/adapter/Sunxi/SunxiCECAdapterCommunication.cpp b/src/libcec/adapter/Sunxi/SunxiCECAdapterCommunication.cpp --- a/src/libcec/adapter/Sunxi/SunxiCECAdapterCommunication.cpp 1970-01-01 01:00:00.000000000 +0100 +++ b/src/libcec/adapter/Sunxi/SunxiCECAdapterCommunication.cpp 2016-06-13 21:47:00.099726185 +0200 @@ -0,0 +1,278 @@ +/* + * 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. + * + * Sunxi adpater port is Copyright (C) 2016 by Joachim Damm + * based on IMX adpater port 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_SUNXI_API) +#include "SunxiCECAdapterCommunication.h" + +#include "CECTypeUtils.h" +#include "LibCEC.h" +#include +#include +#include + +/* + * 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*/ + + +CSunxiCECAdapterCommunication::CSunxiCECAdapterCommunication(IAdapterCommunicationCallback *callback) : + IAdapterCommunication(callback)/*, + m_bLogicalAddressChanged(false)*/ +{ + CLockObject lock(m_mutex); + + m_iNextMessage = 0; + //m_logicalAddresses.Clear(); + m_logicalAddress = CECDEVICE_UNKNOWN; + m_dev = new CCDevSocket(CEC_SUNXI_PATH); + //m_dev = new CCDevSocket("/dev/sunxi_hdmi_cec"); +} + +CSunxiCECAdapterCommunication::~CSunxiCECAdapterCommunication(void) +{ + Close(); + + CLockObject lock(m_mutex); + delete m_dev; + m_dev = 0; +} + +bool CSunxiCECAdapterCommunication::IsOpen(void) +{ + return IsInitialised() && m_dev->IsOpen(); +} + +bool CSunxiCECAdapterCommunication::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) { + LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: Unable to start device\n", __func__); + } + return true; + } + m_dev->Close(); + } + + return false; +} + + +void CSunxiCECAdapterCommunication::Close(void) +{ + StopThread(0); + 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(); +} + + +std::string CSunxiCECAdapterCommunication::GetError(void) const +{ + std::string strError(m_strError); + return strError; +} + + +cec_adapter_message_state CSunxiCECAdapterCommunication::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 CSunxiCECAdapterCommunication::GetFirmwareVersion(void) +{ + /* FIXME add ioctl ? */ + return 0; +} + + +cec_vendor_id CSunxiCECAdapterCommunication::GetVendorId(void) +{ + return CEC_VENDOR_UNKNOWN; +} + + +uint16_t CSunxiCECAdapterCommunication::GetPhysicalAddress(void) +{ + uint32_t info; + + 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; + } + + return info; +} + + +cec_logical_addresses CSunxiCECAdapterCommunication::GetLogicalAddresses(void) +{ + cec_logical_addresses addresses; + addresses.Clear(); + + CLockObject lock(m_mutex); + if ( m_logicalAddress != CECDEVICE_UNKNOWN) + addresses.Set(m_logicalAddress); + + return addresses; +} + + +bool CSunxiCECAdapterCommunication::SetLogicalAddresses(const cec_logical_addresses &addresses) +{ + int log_addr = addresses.primary; + + CLockObject lock(m_mutex); + if (m_logicalAddress == log_addr) + return true; + + if (m_dev->Ioctl(HDMICEC_IOC_SETLOGICALADDRESS, (void *)log_addr) != 0) + { + LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: HDMICEC_IOC_SETLOGICALADDRESS failed !", __func__); + return false; + } + + m_logicalAddress = (cec_logical_address)log_addr; + return true; +} + + +void *CSunxiCECAdapterCommunication::Process(void) +{ + hdmi_cec_event event; + int ret; + 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); + } + /* We are not interested in other events */ + } /*else { + LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s: Read returned %d", __func__, ret); + }*/ + + } + + return 0; +} + +#endif // HAVE_SUNXI_API diff -Nur a/src/libcec/adapter/Sunxi/SunxiCECAdapterCommunication.h b/src/libcec/adapter/Sunxi/SunxiCECAdapterCommunication.h --- a/src/libcec/adapter/Sunxi/SunxiCECAdapterCommunication.h 1970-01-01 01:00:00.000000000 +0100 +++ b/src/libcec/adapter/Sunxi/SunxiCECAdapterCommunication.h 2016-06-13 22:58:00.642941346 +0200 @@ -0,0 +1,115 @@ +#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. + * + * Sunxi adpater port is Copyright (C) 2016 by Joachim Damm + * based on IMX adpater port 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_SUNXI_API) + +#include +#include +#include +#include "adapter/AdapterCommunication.h" +#include + +#define SUNXI_ADAPTER_VID 0x0471 /*FIXME TBD*/ +#define SUNXI_ADAPTER_PID 0x1002 + + + +namespace PLATFORM +{ + class CCDevSocket; +}; + + +namespace CEC +{ + class CAdapterMessageQueueEntry; + + class CSunxiCECAdapterCommunication : public IAdapterCommunication, public PLATFORM::CThread + { + public: + /*! + * @brief Create a new USB-CEC communication handler. + * @param callback The callback to use for incoming CEC commands. + */ + CSunxiCECAdapterCommunication(IAdapterCommunicationCallback *callback); + virtual ~CSunxiCECAdapterCommunication(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("Sunxi"); } + 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_SUNXI; } + uint16_t GetAdapterVendorId(void) const { return SUNXI_ADAPTER_VID; } + uint16_t GetAdapterProductId(void) const { return SUNXI_ADAPTER_PID; } + void SetActiveSource(bool UNUSED(bSetTo), bool UNUSED(bClientUnregistered)) {} + ///} + + /** @name PLATFORM::CThread implementation */ + ///{ + void *Process(void); + ///} + + private: + bool IsInitialised(void) const { return m_dev != 0; }; + + 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 */ + + PLATFORM::CMutex m_messageMutex; + uint32_t m_iNextMessage; + std::map m_messages; + }; + +}; + +#endif diff -Nur a/src/libcec/adapter/Sunxi/SunxiCECAdapterDetection.cpp b/src/libcec/adapter/Sunxi/SunxiCECAdapterDetection.cpp --- a/src/libcec/adapter/Sunxi/SunxiCECAdapterDetection.cpp 1970-01-01 01:00:00.000000000 +0100 +++ b/src/libcec/adapter/Sunxi/SunxiCECAdapterDetection.cpp 2016-06-13 21:28:56.213089581 +0200 @@ -0,0 +1,43 @@ +/* + * 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. + * + * Sunxi adpater port is Copyright (C) 2016 by Joachim Damm + * based on IMX adpater port 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_SUNXI_API) +#include "SunxiCECAdapterDetection.h" + + +using namespace CEC; + +bool CSunxiCECAdapterDetection::FindAdapter(void) +{ + return access(CEC_SUNXI_PATH, 0) == 0; +} + +#endif diff -Nur a/src/libcec/adapter/Sunxi/SunxiCECAdapterDetection.h b/src/libcec/adapter/Sunxi/SunxiCECAdapterDetection.h --- a/src/libcec/adapter/Sunxi/SunxiCECAdapterDetection.h 1970-01-01 01:00:00.000000000 +0100 +++ b/src/libcec/adapter/Sunxi/SunxiCECAdapterDetection.h 2016-06-13 21:28:56.213089581 +0200 @@ -0,0 +1,37 @@ +#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. + * + * Sunxi adpater port is Copyright (C) 2013 by Joachim Damm + * based on IMX adpater port 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 CSunxiCECAdapterDetection + { + public: + static bool FindAdapter(void); + }; +} diff -Nur a/src/libcec/CECTypeUtils.h b/src/libcec/CECTypeUtils.h --- a/src/libcec/CECTypeUtils.h 2016-06-13 21:27:29.386425322 +0200 +++ b/src/libcec/CECTypeUtils.h 2016-06-13 21:33:04.353082699 +0200 @@ -767,6 +767,8 @@ return "TDA995x"; case ADAPTERTYPE_IMX: return "i.MX"; + case ADAPTERTYPE_SUNXI: + return "Sunxi"; default: return "unknown"; } diff -Nur a/src/libcec/cmake/CheckPlatformSupport.cmake b/src/libcec/cmake/CheckPlatformSupport.cmake --- a/src/libcec/cmake/CheckPlatformSupport.cmake 2016-06-13 21:27:29.406425322 +0200 +++ b/src/libcec/cmake/CheckPlatformSupport.cmake 2016-06-13 22:49:15.126289255 +0200 @@ -142,6 +142,19 @@ else() set(HAVE_AMLOGIC_API 0) endif() + + # Sunxi + if (${HAVE_SUNXI_LIB}) + set(LIB_INFO "${LIB_INFO}, Sunxi") + set(HAVE_SUNXI_API 1) + set(CEC_SOURCES_ADAPTER_SUNXI adapter/Sunxi/SunxiCECAdapterDetection.cpp + adapter/Sunxi/SunxiCECAdapterCommunication.cpp) + source_group("Source Files\\adapter\\Sunxi" FILES ${CEC_SOURCES_ADAPTER_SUNXI}) + list(APPEND CEC_SOURCES ${CEC_SOURCES_ADAPTER_SUNXI}) + else() + set(HAVE_SUNXI_API 0) + endif() + endif() # rt diff -Nur a/src/libcec/cmake/DisplayPlatformSupport.cmake b/src/libcec/cmake/DisplayPlatformSupport.cmake --- a/src/libcec/cmake/DisplayPlatformSupport.cmake 2016-06-13 21:27:29.406425322 +0200 +++ b/src/libcec/cmake/DisplayPlatformSupport.cmake 2016-06-13 21:38:48.466406487 +0200 @@ -56,6 +56,12 @@ message(STATUS "Amlogic support: no") endif() +if (HAVE_SUNXI_API) + message(STATUS "Sunxi support: yes") +else() + message(STATUS "Sunxi support: no") +endif() + if (HAVE_PYTHON) message(STATUS "Python support: version ${PYTHONLIBS_VERSION_STRING} (${PYTHON_VERSION})") else() diff -Nur a/src/libcec/CMakeLists.txt b/src/libcec/CMakeLists.txt --- a/src/libcec/CMakeLists.txt 2016-06-13 21:27:29.406425322 +0200 +++ b/src/libcec/CMakeLists.txt 2016-06-13 21:28:56.209756247 +0200 @@ -99,6 +99,9 @@ adapter/RPi/RPiCECAdapterMessageQueue.h adapter/RPi/RPiCECAdapterCommunication.h adapter/RPi/RPiCECAdapterDetection.h + adapter/Sunxi/AdapterMessageQueue.h + adapter/Sunxi/SunxiCECAdapterCommunication.h + adapter/Sunxi/SunxiCECAdapterDetection.h CECInputBuffer.h platform/util/baudrate.h platform/util/edid.h diff -Nur a/src/libcec/env.h.in b/src/libcec/env.h.in --- a/src/libcec/env.h.in 2016-06-13 21:27:29.406425322 +0200 +++ b/src/libcec/env.h.in 2016-06-13 21:28:56.213089581 +0200 @@ -72,6 +72,9 @@ /* Define to 1 for Amlogic support */ #cmakedefine HAVE_AMLOGIC_API @HAVE_AMLOGIC_API@ +/* Define to 1 for Sunxi support */ +#cmakedefine HAVE_SUNXI_API @HAVE_SUNXI_API@ + /* Define to 1 for nVidia EDID parsing support (on selected models) */ #cmakedefine HAVE_NVIDIA_EDID_PARSER @HAVE_NVIDIA_EDID_PARSER@