Skip to content

Commit

Permalink
tegra-cec support. closes #636
Browse files Browse the repository at this point in the history
The original implementation was done by https://github.com/BuzzBumbleBee/libcec
  • Loading branch information
anishsane authored and opdenkamp committed Feb 13, 2025
1 parent 6854c1f commit 97fe495
Show file tree
Hide file tree
Showing 13 changed files with 722 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ AssemblyInfo.cs
AssemblyInfo.cpp

*~
tags
cscope.*

/support/private

Expand Down
3 changes: 2 additions & 1 deletion include/cectypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -887,7 +887,8 @@ typedef enum cec_adapter_type
ADAPTERTYPE_EXYNOS = 0x300,
ADAPTERTYPE_LINUX = 0x400,
ADAPTERTYPE_AOCEC = 0x500,
ADAPTERTYPE_IMX = 0x600
ADAPTERTYPE_IMX = 0x600,
ADAPTERTYPE_TEGRA = 0x700
} cec_adapter_type;

/** force exporting through swig */
Expand Down
2 changes: 2 additions & 0 deletions src/libcec/CECTypeUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,8 @@ namespace CEC
return "i.MX";
case ADAPTERTYPE_LINUX:
return "Linux";
case ADAPTERTYPE_TEGRA:
return "Tegra";
default:
return "unknown";
}
Expand Down
30 changes: 29 additions & 1 deletion src/libcec/adapter/AdapterFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@
#include "IMX/IMXCECAdapterCommunication.h"
#endif

#if defined(HAVE_TEGRA_API)
#include "Tegra/TegraCECAdapterDetection.h"
#include "Tegra/TegraCECAdapterCommunication.h"
#include "Tegra/TegraCECDev.h"
#endif

using namespace CEC;

int8_t CAdapterFactory::FindAdapters(cec_adapter *deviceList, uint8_t iBufSize, const char *strDevicePath /* = NULL */)
Expand Down Expand Up @@ -178,7 +184,24 @@ int8_t CAdapterFactory::DetectAdapters(cec_adapter_descriptor *deviceList, uint8
}
#endif

#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_EXYNOS_API) && !defined(HAVE_LINUX_API) && !defined(HAVE_AOCEC_API) && !defined(HAVE_IMX_API)
#if defined(HAVE_TEGRA_API)
if (iAdaptersFound < iBufSize && TegraCECAdapterDetection::FindAdapter() &&
(!strDevicePath || !strcmp(strDevicePath, CEC_TDA995x_VIRTUAL_COM)))
{
snprintf(deviceList[iAdaptersFound].strComPath, sizeof(deviceList[iAdaptersFound].strComPath), TEGRA_CEC_DEV_PATH);
snprintf(deviceList[iAdaptersFound].strComName, sizeof(deviceList[iAdaptersFound].strComName), TEGRA_CEC_DEV_PATH);
deviceList[iAdaptersFound].iVendorId = TEGRA_ADAPTER_VID;
deviceList[iAdaptersFound].iProductId = TEGRA_ADAPTER_PID;
deviceList[iAdaptersFound].adapterType = ADAPTERTYPE_TEGRA;
iAdaptersFound++;
}
#endif

// #if defined(HAVE_TEGRA_API)
// iAdaptersFound++;
// #endif

#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_EXYNOS_API) && !defined(HAVE_LINUX_API) && !defined(HAVE_AOCEC_API) && !defined(HAVE_IMX_API) && !defined(HAVE_TEGRA_API)
#error "libCEC doesn't have support for any type of adapter. please check your build system or configuration"
#endif

Expand All @@ -192,6 +215,11 @@ IAdapterCommunication *CAdapterFactory::GetInstance(const char *strPort, uint16_
return new CTDA995xCECAdapterCommunication(m_lib->m_cec);
#endif

#if defined(HAVE_TEGRA_API)
if (!strcmp(strPort, TEGRA_CEC_DEV_PATH))
return new TegraCECAdapterCommunication(m_lib->m_cec);
#endif

#if defined(HAVE_EXYNOS_API)
if (!strcmp(strPort, CEC_EXYNOS_VIRTUAL_COM))
return new CExynosCECAdapterCommunication(m_lib->m_cec);
Expand Down
134 changes: 134 additions & 0 deletions src/libcec/adapter/Tegra/AdapterMessageQueue.h
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
* http://www.pulse-eight.com/
* http://www.pulse-eight.net/
*/

#include "p8-platform/threads/mutex.h"

namespace CEC
{
using namespace P8PLATFORM;

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 */
P8PLATFORM::CCondition<bool> m_condition; /**< the condition to wait on */
P8PLATFORM::CMutex m_mutex; /**< mutex for changes to this class */
uint32_t m_hash;
uint32_t m_retval;
bool m_bSucceeded;
};

};
Loading

0 comments on commit 97fe495

Please sign in to comment.