mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-24 11:16:51 +00:00
Merge pull request #4712 from gdachs/new-amlogic-cec-driver
New amlogic cec driver
This commit is contained in:
commit
4bfc99d612
@ -43,6 +43,12 @@ else
|
||||
EXTRA_CMAKE_OPTS="-DHAVE_IMX_API=0"
|
||||
fi
|
||||
|
||||
if [ "$KODIPLAYER_DRIVER" = "libamcodec" ]; then
|
||||
EXTRA_CMAKE_OPTS="-DHAVE_AMLOGIC_API=1"
|
||||
else
|
||||
EXTRA_CMAKE_OPTS="-DHAVE_AMLOGIC_API=0"
|
||||
fi
|
||||
|
||||
configure_target() {
|
||||
if [ "$KODIPLAYER_DRIVER" = "bcm2835-driver" ]; then
|
||||
export CXXFLAGS="$CXXFLAGS \
|
||||
|
694
packages/devel/libcec/patches/libcec-03-amlogic-support.patch
Normal file
694
packages/devel/libcec/patches/libcec-03-amlogic-support.patch
Normal file
@ -0,0 +1,694 @@
|
||||
diff -Nur a/include/cectypes.h b/include/cectypes.h
|
||||
--- a/include/cectypes.h 2016-02-10 11:50:03.658878388 +0100
|
||||
+++ b/include/cectypes.h 2016-02-10 13:45:19.057046951 +0100
|
||||
@@ -320,6 +320,16 @@
|
||||
|
||||
|
||||
/*!
|
||||
+ * the path to use for the Amlogic HDMI CEC device
|
||||
+ */
|
||||
+#define CEC_AMLOGIC_PATH "/dev/AmlogicCEC"
|
||||
+
|
||||
+/*!
|
||||
+ * the name of the virtual COM port to use for the AMLOGIC' CEC wire
|
||||
+ */
|
||||
+#define CEC_AMLOGIC_VIRTUAL_COM "Amlogic"
|
||||
+
|
||||
+/*!
|
||||
* Mimimum client version
|
||||
*/
|
||||
#define CEC_MIN_LIB_VERSION 3
|
||||
@@ -888,7 +898,8 @@
|
||||
ADAPTERTYPE_RPI = 0x100,
|
||||
ADAPTERTYPE_TDA995x = 0x200,
|
||||
ADAPTERTYPE_EXYNOS = 0x300,
|
||||
- ADAPTERTYPE_IMX = 0x400
|
||||
+ ADAPTERTYPE_IMX = 0x400,
|
||||
+ ADAPTERTYPE_AMLOGIC = 0x500
|
||||
} cec_adapter_type;
|
||||
|
||||
/** force exporting through swig */
|
||||
diff -Nur a/README.md b/README.md
|
||||
--- a/README.md 2015-07-03 19:20:49.000000000 +0200
|
||||
+++ b/README.md 2016-02-10 12:03:54.517523977 +0100
|
||||
@@ -58,6 +58,12 @@
|
||||
cmake -DHAVE_EXYNOS_API=1 ..
|
||||
```
|
||||
|
||||
+### Amlogic
|
||||
+To compile in support for Amlogic devices, you have to pass the argument -DHAVE_AMLOGIC_API=1 to cmake:
|
||||
+```
|
||||
+cmake -DHAVE_AMLOGIC_API=1 ..
|
||||
+```
|
||||
+
|
||||
## TDA995x ##
|
||||
To compile in support for TDA995x devices, you have to pass the argument -DHAVE_TDA995X_API=1 to cmake:
|
||||
```
|
||||
diff -Nur a/src/libcec/adapter/AdapterFactory.cpp b/src/libcec/adapter/AdapterFactory.cpp
|
||||
--- a/src/libcec/adapter/AdapterFactory.cpp 2016-02-10 11:49:46.887067255 +0100
|
||||
+++ b/src/libcec/adapter/AdapterFactory.cpp 2016-02-10 12:41:44.252060917 +0100
|
||||
@@ -63,6 +63,11 @@
|
||||
#include "IMX/IMXCECAdapterCommunication.h"
|
||||
#endif
|
||||
|
||||
+#if defined(HAVE_AMLOGIC_API)
|
||||
+#include "Amlogic/AmlogicCECAdapterDetection.h"
|
||||
+#include "Amlogic/AmlogicCECAdapterCommunication.h"
|
||||
+#endif
|
||||
+
|
||||
using namespace CEC;
|
||||
|
||||
int8_t CAdapterFactory::FindAdapters(cec_adapter *deviceList, uint8_t iBufSize, const char *strDevicePath /* = NULL */)
|
||||
@@ -131,6 +136,18 @@
|
||||
}
|
||||
#endif
|
||||
|
||||
+#if defined(HAVE_AMLOGIC_API)
|
||||
+ if (iAdaptersFound < iBufSize && CAmlogicCECAdapterDetection::FindAdapter())
|
||||
+ {
|
||||
+ snprintf(deviceList[iAdaptersFound].strComPath, sizeof(deviceList[iAdaptersFound].strComPath), CEC_AMLOGIC_PATH);
|
||||
+ snprintf(deviceList[iAdaptersFound].strComName, sizeof(deviceList[iAdaptersFound].strComName), CEC_AMLOGIC_VIRTUAL_COM);
|
||||
+ deviceList[iAdaptersFound].iVendorId = 0;
|
||||
+ deviceList[iAdaptersFound].iProductId = 0;
|
||||
+ deviceList[iAdaptersFound].adapterType = ADAPTERTYPE_AMLOGIC;
|
||||
+ iAdaptersFound++;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
|
||||
|
||||
#if defined(HAVE_IMX_API)
|
||||
@@ -166,6 +183,11 @@
|
||||
return new CExynosCECAdapterCommunication(m_lib->m_cec);
|
||||
#endif
|
||||
|
||||
+#if defined(HAVE_AMLOGIC_API)
|
||||
+ if (!strcmp(strPort, CEC_AMLOGIC_VIRTUAL_COM))
|
||||
+ return new CAmlogicCECAdapterCommunication(m_lib->m_cec);
|
||||
+#endif
|
||||
+
|
||||
#if defined(HAVE_RPI_API)
|
||||
if (!strcmp(strPort, CEC_RPI_VIRTUAL_COM))
|
||||
return new CRPiCECAdapterCommunication(m_lib->m_cec);
|
||||
@@ -180,7 +202,7 @@
|
||||
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)
|
||||
+#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)
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
diff -Nur a/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.cpp b/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.cpp
|
||||
--- a/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.cpp 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ b/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.cpp 2016-02-10 13:54:51.298457229 +0100
|
||||
@@ -0,0 +1,259 @@
|
||||
+/*
|
||||
+ * This file is part of the libCEC(R) library.
|
||||
+ *
|
||||
+ * libCEC Amlogic Code Copyright (C) 2016 Gerald Dachs
|
||||
+ * based heavily on:
|
||||
+ * libCEC Exynos Code Copyright (C) 2014 Valentin Manea
|
||||
+ * libCEC(R) is Copyright (C) 2011-2015 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 <license@pulse-eight.com>
|
||||
+ * http://www.pulse-eight.com/
|
||||
+ * http://www.pulse-eight.net/
|
||||
+ */
|
||||
+
|
||||
+#include "env.h"
|
||||
+#include <fcntl.h>
|
||||
+#include <sys/ioctl.h>
|
||||
+
|
||||
+
|
||||
+#if defined(HAVE_AMLOGIC_API)
|
||||
+#include "AmlogicCEC.h"
|
||||
+#include "AmlogicCECAdapterCommunication.h"
|
||||
+
|
||||
+#include "CECTypeUtils.h"
|
||||
+#include "LibCEC.h"
|
||||
+#include <platform/util/buffer.h>
|
||||
+
|
||||
+using namespace CEC;
|
||||
+using namespace PLATFORM;
|
||||
+
|
||||
+#define LIB_CEC m_callback->GetLib()
|
||||
+
|
||||
+
|
||||
+CAmlogicCECAdapterCommunication::CAmlogicCECAdapterCommunication(IAdapterCommunicationCallback *callback) :
|
||||
+ IAdapterCommunication(callback),
|
||||
+ m_bLogicalAddressChanged(false)
|
||||
+{
|
||||
+ CLockObject lock(m_mutex);
|
||||
+
|
||||
+ m_logicalAddresses.Clear();
|
||||
+ m_fd = INVALID_SOCKET_VALUE;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+CAmlogicCECAdapterCommunication::~CAmlogicCECAdapterCommunication(void)
|
||||
+{
|
||||
+ Close();
|
||||
+}
|
||||
+
|
||||
+
|
||||
+bool CAmlogicCECAdapterCommunication::IsOpen(void)
|
||||
+{
|
||||
+ return IsInitialised() && m_fd != INVALID_SOCKET_VALUE;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+bool CAmlogicCECAdapterCommunication::Open(uint32_t UNUSED(iTimeoutMs), bool UNUSED(bSkipChecks), bool bStartListening)
|
||||
+{
|
||||
+ if (m_fd != INVALID_SOCKET_VALUE)
|
||||
+ close(m_fd);
|
||||
+
|
||||
+ if ((m_fd = open(CEC_AMLOGIC_PATH, O_RDWR)) > 0)
|
||||
+ {
|
||||
+ if (!bStartListening || CreateThread()) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ close(m_fd);
|
||||
+ }
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+void CAmlogicCECAdapterCommunication::Close(void)
|
||||
+{
|
||||
+ StopThread(0);
|
||||
+
|
||||
+ close(m_fd);
|
||||
+ m_fd = INVALID_SOCKET_VALUE;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+std::string CAmlogicCECAdapterCommunication::GetError(void) const
|
||||
+{
|
||||
+ std::string strError(m_strError);
|
||||
+ return strError;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+cec_adapter_message_state CAmlogicCECAdapterCommunication::Write(
|
||||
+ const cec_command &data, bool &UNUSED(bRetry), uint8_t UNUSED(iLineTimeout), bool UNUSED(bIsReply))
|
||||
+{
|
||||
+ uint8_t buffer[CEC_MAX_FRAME_SIZE];
|
||||
+ int32_t size = 1;
|
||||
+ cec_adapter_message_state rc = ADAPTER_MESSAGE_STATE_ERROR;
|
||||
+
|
||||
+ if (!IsOpen())
|
||||
+ return rc;
|
||||
+
|
||||
+ if ((size_t)data.parameters.size + data.opcode_set > sizeof(buffer))
|
||||
+ {
|
||||
+ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: data size too large !", __func__);
|
||||
+ return ADAPTER_MESSAGE_STATE_ERROR;
|
||||
+ }
|
||||
+
|
||||
+ buffer[0] = (data.initiator << 4) | (data.destination & 0x0f);
|
||||
+
|
||||
+ if (data.opcode_set)
|
||||
+ {
|
||||
+ buffer[1] = data.opcode;
|
||||
+ size++;
|
||||
+
|
||||
+ memcpy(&buffer[size], data.parameters.data, data.parameters.size);
|
||||
+ size += data.parameters.size;
|
||||
+ }
|
||||
+
|
||||
+ if (write(m_fd, (void *)buffer, size) == size)
|
||||
+ {
|
||||
+ rc = ADAPTER_MESSAGE_STATE_SENT_ACKED;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: write failed !", __func__);
|
||||
+ }
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+uint16_t CAmlogicCECAdapterCommunication::GetFirmwareVersion(void)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+cec_vendor_id CAmlogicCECAdapterCommunication::GetVendorId(void)
|
||||
+{
|
||||
+ return cec_vendor_id(CEC_VENDOR_UNKNOWN);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+uint16_t CAmlogicCECAdapterCommunication::GetPhysicalAddress(void)
|
||||
+{
|
||||
+ int phys_addr = CEC_DEFAULT_PADDR;
|
||||
+
|
||||
+ CLockObject lock(m_mutex);
|
||||
+
|
||||
+ if (!IsOpen())
|
||||
+ return (uint16_t)phys_addr;
|
||||
+
|
||||
+ if ((phys_addr = ioctl(m_fd, CEC_IOC_GETPADDR)) < 0)
|
||||
+ {
|
||||
+ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: IOCTL GetPhysicalAddr failed !", __func__);
|
||||
+ phys_addr = CEC_DEFAULT_PADDR;
|
||||
+ }
|
||||
+ return (uint16_t)phys_addr;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+cec_logical_addresses CAmlogicCECAdapterCommunication::GetLogicalAddresses(void)
|
||||
+{
|
||||
+ return m_logicalAddresses;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+bool CAmlogicCECAdapterCommunication::SetLogicalAddresses(const cec_logical_addresses &addresses)
|
||||
+{
|
||||
+ unsigned int log_addr = addresses.primary;
|
||||
+ CLockObject lock(m_mutex);
|
||||
+
|
||||
+ if (!IsOpen())
|
||||
+ return false;
|
||||
+
|
||||
+ if (ioctl(m_fd, CEC_IOC_SETLADDR, &log_addr))
|
||||
+ {
|
||||
+ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: IOCTL SetLogicalAddr failed !", __func__);
|
||||
+ return false;
|
||||
+ }
|
||||
+ m_logicalAddresses = addresses;
|
||||
+ m_bLogicalAddressChanged = true;
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+void CAmlogicCECAdapterCommunication::HandleLogicalAddressLost(cec_logical_address UNUSED(oldAddress))
|
||||
+{
|
||||
+ unsigned int log_addr = CECDEVICE_BROADCAST;
|
||||
+ if (ioctl(m_fd, CEC_IOC_SETLADDR, &log_addr))
|
||||
+ {
|
||||
+ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: IOCTL SetLogicalAddr failed !", __func__);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
+void *CAmlogicCECAdapterCommunication::Process(void)
|
||||
+{
|
||||
+ uint8_t buffer[CEC_MAX_FRAME_SIZE];
|
||||
+ uint32_t size;
|
||||
+ fd_set rfds;
|
||||
+ cec_logical_address initiator, destination;
|
||||
+
|
||||
+ if (!IsOpen())
|
||||
+ return 0;
|
||||
+
|
||||
+ FD_ZERO(&rfds);
|
||||
+ FD_SET(m_fd, &rfds);
|
||||
+
|
||||
+ while (!IsStopped())
|
||||
+ {
|
||||
+ if (select(m_fd + 1, &rfds, NULL, NULL, NULL) >= 0 )
|
||||
+ {
|
||||
+ size = read(m_fd, buffer, CEC_MAX_FRAME_SIZE);
|
||||
+
|
||||
+ if (size > 0)
|
||||
+ {
|
||||
+ initiator = cec_logical_address(buffer[0] >> 4);
|
||||
+ destination = cec_logical_address(buffer[0] & 0x0f);
|
||||
+
|
||||
+ cec_command cmd;
|
||||
+
|
||||
+ cec_command::Format(
|
||||
+ cmd, initiator, destination,
|
||||
+ ( size > 1 ) ? cec_opcode(buffer[1]) : CEC_OPCODE_NONE);
|
||||
+
|
||||
+ for( uint8_t i = 2; i < size; i++ )
|
||||
+ cmd.parameters.PushBack(buffer[i]);
|
||||
+
|
||||
+ if (!IsStopped())
|
||||
+ m_callback->OnCommandReceived(cmd);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#endif // HAVE_AMLOGIC_API
|
||||
diff -Nur a/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.h b/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.h
|
||||
--- a/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.h 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ b/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.h 2016-02-10 13:49:16.546310466 +0100
|
||||
@@ -0,0 +1,105 @@
|
||||
+#pragma once
|
||||
+/*
|
||||
+ * This file is part of the libCEC(R) library.
|
||||
+ *
|
||||
+ * libCEC Amlogic Code Copyright (C) 2016 Gerald Dachs
|
||||
+ * based heavily on:
|
||||
+ * libCEC Exynos Code Copyright (C) 2014 Valentin Manea
|
||||
+ * libCEC(R) is Copyright (C) 2011-2015 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 <license@pulse-eight.com>
|
||||
+ * http://www.pulse-eight.com/
|
||||
+ * http://www.pulse-eight.net/
|
||||
+ */
|
||||
+
|
||||
+#include "env.h"
|
||||
+
|
||||
+#if defined(HAVE_AMLOGIC_API)
|
||||
+
|
||||
+#include <platform/threads/mutex.h>
|
||||
+#include <platform/threads/threads.h>
|
||||
+#include "../AdapterCommunication.h"
|
||||
+#include <map>
|
||||
+
|
||||
+namespace CEC
|
||||
+{
|
||||
+ class CAmlogicCECAdapterCommunication : public IAdapterCommunication, public PLATFORM::CThread
|
||||
+ {
|
||||
+ public:
|
||||
+ /*!
|
||||
+ * @brief Create a new Exynos HDMI CEC communication handler.
|
||||
+ * @param callback The callback to use for incoming CEC commands.
|
||||
+ */
|
||||
+ CAmlogicCECAdapterCommunication(IAdapterCommunicationCallback *callback);
|
||||
+ virtual ~CAmlogicCECAdapterCommunication(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("AMLOGIC"); }
|
||||
+ 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_AMLOGIC; }
|
||||
+ uint16_t GetAdapterVendorId(void) const { return 1; }
|
||||
+ uint16_t GetAdapterProductId(void) const { return 1; }
|
||||
+ void HandleLogicalAddressLost(cec_logical_address oldAddress);
|
||||
+ void SetActiveSource(bool UNUSED(bSetTo), bool UNUSED(bClientUnregistered)) {}
|
||||
+ ///}
|
||||
+
|
||||
+ /** @name PLATFORM::CThread implementation */
|
||||
+ ///{
|
||||
+ void *Process(void);
|
||||
+ ///}
|
||||
+
|
||||
+ private:
|
||||
+ bool IsInitialised(void) const { return 1; };
|
||||
+
|
||||
+ std::string m_strError; /**< current error message */
|
||||
+
|
||||
+ bool m_bLogicalAddressChanged;
|
||||
+ cec_logical_addresses m_logicalAddresses;
|
||||
+
|
||||
+ PLATFORM::CMutex m_mutex;
|
||||
+ int m_fd;
|
||||
+ };
|
||||
+};
|
||||
+#endif
|
||||
diff -Nur a/src/libcec/adapter/Amlogic/AmlogicCECAdapterDetection.cpp b/src/libcec/adapter/Amlogic/AmlogicCECAdapterDetection.cpp
|
||||
--- a/src/libcec/adapter/Amlogic/AmlogicCECAdapterDetection.cpp 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ b/src/libcec/adapter/Amlogic/AmlogicCECAdapterDetection.cpp 2016-02-10 11:57:58.445532459 +0100
|
||||
@@ -0,0 +1,50 @@
|
||||
+/*
|
||||
+ * This file is part of the libCEC(R) library.
|
||||
+ *
|
||||
+ * libCEC Amlogic Code Copyright (C) 2016 Gerald Dachs
|
||||
+ * based heavily on:
|
||||
+ * libCEC Exynos Code Copyright (C) 2014 Valentin Manea
|
||||
+ * libCEC(R) is Copyright (C) 2011-2015 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 <license@pulse-eight.com>
|
||||
+ * http://www.pulse-eight.com/
|
||||
+ * http://www.pulse-eight.net/
|
||||
+ */
|
||||
+
|
||||
+#include "env.h"
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+#if defined(HAVE_AMLOGIC_API)
|
||||
+#include "AmlogicCECAdapterDetection.h"
|
||||
+#include "AmlogicCEC.h"
|
||||
+
|
||||
+using namespace CEC;
|
||||
+
|
||||
+bool CAmlogicCECAdapterDetection::FindAdapter(void)
|
||||
+{
|
||||
+ return access(CEC_AMLOGIC_PATH, 0) == 0;
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
diff -Nur a/src/libcec/adapter/Amlogic/AmlogicCECAdapterDetection.h b/src/libcec/adapter/Amlogic/AmlogicCECAdapterDetection.h
|
||||
--- a/src/libcec/adapter/Amlogic/AmlogicCECAdapterDetection.h 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ b/src/libcec/adapter/Amlogic/AmlogicCECAdapterDetection.h 2016-02-10 11:57:58.445532459 +0100
|
||||
@@ -0,0 +1,46 @@
|
||||
+#pragma once
|
||||
+/*
|
||||
+ * This file is part of the libCEC(R) library.
|
||||
+ *
|
||||
+ * libCEC Amlogic Code Copyright (C) 2016 Gerald Dachs
|
||||
+ * based heavily on:
|
||||
+ * libCEC Exynos Code Copyright (C) 2014 Valentin Manea
|
||||
+ * libCEC(R) is Copyright (C) 2011-2015 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 <license@pulse-eight.com>
|
||||
+ * http://www.pulse-eight.com/
|
||||
+ * http://www.pulse-eight.net/
|
||||
+ */
|
||||
+
|
||||
+#include "env.h"
|
||||
+
|
||||
+namespace CEC
|
||||
+{
|
||||
+ class CAmlogicCECAdapterDetection
|
||||
+ {
|
||||
+ public:
|
||||
+ static bool FindAdapter(void);
|
||||
+ };
|
||||
+}
|
||||
diff -Nur a/src/libcec/adapter/Amlogic/AmlogicCEC.h b/src/libcec/adapter/Amlogic/AmlogicCEC.h
|
||||
--- a/src/libcec/adapter/Amlogic/AmlogicCEC.h 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ b/src/libcec/adapter/Amlogic/AmlogicCEC.h 2016-02-10 11:57:58.445532459 +0100
|
||||
@@ -0,0 +1,41 @@
|
||||
+#pragma once
|
||||
+/*
|
||||
+ * This file is part of the libCEC(R) library.
|
||||
+ *
|
||||
+ * libCEC Amlogic Code Copyright (C) 2016 Gerald Dachs
|
||||
+ * based heavily on:
|
||||
+ * libCEC Exynos Code Copyright (C) 2014 Valentin Manea
|
||||
+ * libCEC(R) is Copyright (C) 2011-2015 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 <license@pulse-eight.com>
|
||||
+ * http://www.pulse-eight.com/
|
||||
+ * http://www.pulse-eight.net/
|
||||
+ */
|
||||
+
|
||||
+
|
||||
+#define CEC_DEFAULT_PADDR 0x1000
|
||||
+#define CEC_IOC_SETLADDR _IOW('c', 0, unsigned int)
|
||||
+#define CEC_IOC_GETPADDR _IO('c', 1)
|
||||
+#define CEC_MAX_FRAME_SIZE 16
|
||||
diff -Nur a/src/libcec/cmake/CheckPlatformSupport.cmake b/src/libcec/cmake/CheckPlatformSupport.cmake
|
||||
--- a/src/libcec/cmake/CheckPlatformSupport.cmake 2016-02-10 11:49:46.891067210 +0100
|
||||
+++ b/src/libcec/cmake/CheckPlatformSupport.cmake 2016-02-10 13:18:20.847385373 +0100
|
||||
@@ -11,6 +11,7 @@
|
||||
# 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_AMLOGIC_API 1 if Amlogic is supported
|
||||
# HAVE_P8_USB_DETECT 1 if Pulse-Eight devices can be auto-detected
|
||||
#
|
||||
|
||||
@@ -129,6 +130,18 @@
|
||||
else()
|
||||
set(HAVE_EXYNOS_API 0)
|
||||
endif()
|
||||
+
|
||||
+ # Amlogic
|
||||
+ if (${HAVE_AMLOGIC_API})
|
||||
+ set(LIB_INFO "${LIB_INFO}, Amlogic")
|
||||
+ set(HAVE_AMLOGIC_API 1)
|
||||
+ set(CEC_SOURCES_ADAPTER_AMLOGIC adapter/Amlogic/AmlogicCECAdapterDetection.cpp
|
||||
+ adapter/Amlogic/AmlogicCECAdapterCommunication.cpp)
|
||||
+ source_group("Source Files\\adapter\\Amlogic" FILES ${CEC_SOURCES_ADAPTER_AMLOGIC})
|
||||
+ list(APPEND CEC_SOURCES ${CEC_SOURCES_ADAPTER_AMLOGIC})
|
||||
+ else()
|
||||
+ set(HAVE_AMLOGIC_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-02-10 11:49:46.891067210 +0100
|
||||
+++ b/src/libcec/cmake/DisplayPlatformSupport.cmake 2016-02-10 12:47:10.380408360 +0100
|
||||
@@ -50,6 +50,12 @@
|
||||
message(STATUS "Exynos support: no")
|
||||
endif()
|
||||
|
||||
+if (HAVE_AMLOGIC_API)
|
||||
+ message(STATUS "Amlogic support: yes")
|
||||
+else()
|
||||
+ message(STATUS "Amlogic 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 2015-07-03 19:20:49.000000000 +0200
|
||||
+++ b/src/libcec/CMakeLists.txt 2016-02-10 11:57:58.445532459 +0100
|
||||
@@ -83,6 +83,9 @@
|
||||
adapter/Exynos/ExynosCEC.h
|
||||
adapter/Exynos/ExynosCECAdapterDetection.h
|
||||
adapter/Exynos/ExynosCECAdapterCommunication.h
|
||||
+ adapter/Amlogic/AmlogicCEC.h
|
||||
+ adapter/Amlogic/AmlogicCECAdapterDetection.h
|
||||
+ adapter/Amlogic/AmlogicCECAdapterCommunication.h
|
||||
adapter/Pulse-Eight/USBCECAdapterMessageQueue.h
|
||||
adapter/Pulse-Eight/USBCECAdapterCommunication.h
|
||||
adapter/Pulse-Eight/USBCECAdapterCommands.h
|
||||
diff -Nur a/src/libcec/env.h.in b/src/libcec/env.h.in
|
||||
--- a/src/libcec/env.h.in 2016-02-10 11:49:46.891067210 +0100
|
||||
+++ b/src/libcec/env.h.in 2016-02-10 11:57:58.449532413 +0100
|
||||
@@ -69,6 +69,9 @@
|
||||
/* Define to 1 for Exynos support */
|
||||
#cmakedefine HAVE_EXYNOS_API @HAVE_EXYNOS_API@
|
||||
|
||||
+/* Define to 1 for Amlogic support */
|
||||
+#cmakedefine HAVE_AMLOGIC_API @HAVE_AMLOGIC_API@
|
||||
+
|
||||
/* Define to 1 for nVidia EDID parsing support (on selected models) */
|
||||
#cmakedefine HAVE_NVIDIA_EDID_PARSER @HAVE_NVIDIA_EDID_PARSER@
|
||||
|
@ -1223,6 +1223,7 @@ CONFIG_AMLOGIC_SYS_LED=y
|
||||
# CONFIG_AML_HDMI_TX_20 is not set
|
||||
CONFIG_AML_HDMI_TX=y
|
||||
# CONFIG_AML_HDMI_TX_HDCP is not set
|
||||
CONFIG_AML_HDMI_TX_NEW_CEC_DRIVER=y
|
||||
# CONFIG_TVIN is not set
|
||||
# CONFIG_AML_EXT_HDMIIN is not set
|
||||
# CONFIG_DEBUG_DRIVER is not set
|
||||
|
749
projects/WeTek_Core/patches/linux/080-amlogic-cec-driver.patch
Normal file
749
projects/WeTek_Core/patches/linux/080-amlogic-cec-driver.patch
Normal file
@ -0,0 +1,749 @@
|
||||
From 3bde21926d476a3fc0f4d37275f8fde11f09dade Mon Sep 17 00:00:00 2001
|
||||
From: Gerald Dachs <gda@dachsweb.de>
|
||||
Date: Wed, 3 Feb 2016 19:19:49 +0100
|
||||
Subject: [PATCH] New amlogic cec driver
|
||||
|
||||
---
|
||||
.../mach-mesong9bb/hdmi_tx_hw_20/hdmi_tx_cec_hw.c | 3 +-
|
||||
drivers/amlogic/hdmi/Kconfig | 8 +
|
||||
drivers/amlogic/hdmi/hdmi_tx/Makefile | 8 +-
|
||||
drivers/amlogic/hdmi/hdmi_tx/amlogic_cec.c | 534 +++++++++++++++++++++
|
||||
drivers/amlogic/hdmi/hdmi_tx/hdmi_tx.c | 11 +-
|
||||
drivers/amlogic/input/new_remote/remote_func.c | 6 +
|
||||
drivers/amlogic/input/remote/am_remote.c | 2 +
|
||||
7 files changed, 569 insertions(+), 3 deletions(-)
|
||||
create mode 100644 drivers/amlogic/hdmi/hdmi_tx/amlogic_cec.c
|
||||
|
||||
diff --git a/arch/arm/mach-mesong9bb/hdmi_tx_hw_20/hdmi_tx_cec_hw.c b/arch/arm/mach-mesong9bb/hdmi_tx_hw_20/hdmi_tx_cec_hw.c
|
||||
index a2a78bd..762feba 100644
|
||||
--- a/arch/arm/mach-mesong9bb/hdmi_tx_hw_20/hdmi_tx_cec_hw.c
|
||||
+++ b/arch/arm/mach-mesong9bb/hdmi_tx_hw_20/hdmi_tx_cec_hw.c
|
||||
@@ -996,6 +996,7 @@ void cec_tx_irq_handle(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
+#ifndef CONFIG_AML_HDMI_TX_NEW_CEC_DRIVER
|
||||
void cec_polling_online_dev(int log_addr, int *bool)
|
||||
{
|
||||
#ifdef AO_CEC
|
||||
@@ -1005,7 +1006,7 @@ void cec_polling_online_dev(int log_addr, int *bool)
|
||||
#endif
|
||||
hdmi_print(INF, CEC "CEC: poll online logic device: 0x%x BOOL: %d\n", log_addr, *bool);
|
||||
}
|
||||
-
|
||||
+#endif
|
||||
|
||||
// DELETE LATER, TEST ONLY
|
||||
void cec_test_(unsigned int cmd)
|
||||
diff --git a/drivers/amlogic/hdmi/Kconfig b/drivers/amlogic/hdmi/Kconfig
|
||||
index 71f6bf8..1bfc289 100755
|
||||
--- a/drivers/amlogic/hdmi/Kconfig
|
||||
+++ b/drivers/amlogic/hdmi/Kconfig
|
||||
@@ -24,4 +24,12 @@ config AML_HDMI_TX_HDCP
|
||||
hdmitx hdcp enable, it should be enalbe if board burned hdmitx hdcp keys
|
||||
endif
|
||||
|
||||
+if AML_HDMI_TX
|
||||
+config AML_HDMI_TX_NEW_CEC_DRIVER
|
||||
+ bool "HDMI new CEC driver"
|
||||
+ default n
|
||||
+ help
|
||||
+ hdmitx uses new CEC driver
|
||||
+endif
|
||||
+
|
||||
endmenu
|
||||
diff --git a/drivers/amlogic/hdmi/hdmi_tx/Makefile b/drivers/amlogic/hdmi/hdmi_tx/Makefile
|
||||
index 7a944cd..f74ec1f 100755
|
||||
--- a/drivers/amlogic/hdmi/hdmi_tx/Makefile
|
||||
+++ b/drivers/amlogic/hdmi/hdmi_tx/Makefile
|
||||
@@ -1,5 +1,11 @@
|
||||
obj-$(CONFIG_AML_HDMI_TX) += hdmitx.o
|
||||
|
||||
-hdmitx-objs := hdmi_tx.o hdmi_tx_cec.o hdmi_cec_key.o hdmi_tx_video.o hdmi_tx_audio.o hdmi_tx_edid.o hdmi_tx_audio.o hdmi_tx_hdcp.o hdmi_tx_compliance.o
|
||||
+hdmitx-objs := hdmi_tx.o hdmi_tx_video.o hdmi_tx_audio.o hdmi_tx_edid.o hdmi_tx_audio.o hdmi_tx_hdcp.o hdmi_tx_compliance.o
|
||||
+
|
||||
+ifdef CONFIG_AML_HDMI_TX_NEW_CEC_DRIVER
|
||||
+ hdmitx-objs += amlogic_cec.o
|
||||
+else
|
||||
+ hdmitx-objs += hdmi_tx_cec.o hdmi_cec_key.o
|
||||
+endif
|
||||
|
||||
#EXTRA_CFLAGS += -O2
|
||||
diff --git a/drivers/amlogic/hdmi/hdmi_tx/amlogic_cec.c b/drivers/amlogic/hdmi/hdmi_tx/amlogic_cec.c
|
||||
new file mode 100644
|
||||
index 0000000..61fb500
|
||||
--- /dev/null
|
||||
+++ b/drivers/amlogic/hdmi/hdmi_tx/amlogic_cec.c
|
||||
@@ -0,0 +1,534 @@
|
||||
+/* linux/drivers/amlogic/hdmi/hdmi_tx/amlogic_cec.c
|
||||
+ *
|
||||
+ * Copyright (c) 2016 Gerald Dachs
|
||||
+ *
|
||||
+ * CEC interface file for Amlogic
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+*/
|
||||
+
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/uaccess.h>
|
||||
+#include <linux/poll.h>
|
||||
+#include <linux/miscdevice.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/sched.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/export.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/cdev.h>
|
||||
+#include <linux/list.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/atomic.h>
|
||||
+
|
||||
+#include <asm/uaccess.h>
|
||||
+#include <asm/delay.h>
|
||||
+#include <mach/am_regs.h>
|
||||
+#include <mach/power_gate.h>
|
||||
+#include <linux/amlogic/tvin/tvin.h>
|
||||
+
|
||||
+#include <mach/gpio.h>
|
||||
+#include <linux/amlogic/hdmi_tx/hdmi_info_global.h>
|
||||
+#include <linux/amlogic/hdmi_tx/hdmi_tx_module.h>
|
||||
+#include <mach/hdmi_tx_reg.h>
|
||||
+#include <linux/amlogic/hdmi_tx/hdmi_tx_cec.h>
|
||||
+
|
||||
+#define CONFIG_TV_DEBUG
|
||||
+
|
||||
+MODULE_AUTHOR("Gerald Dachs");
|
||||
+MODULE_DESCRIPTION("Amlogic CEC driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+
|
||||
+#define CEC_IOC_MAGIC 'c'
|
||||
+#define CEC_IOC_SETLADDR _IOW(CEC_IOC_MAGIC, 0, unsigned int)
|
||||
+#define CEC_IOC_GETPADDR _IO(CEC_IOC_MAGIC, 1)
|
||||
+
|
||||
+#define VERSION "1.0" /* Driver version number */
|
||||
+#define CEC_MINOR 243 /* Major 10, Minor 242, /dev/cec */
|
||||
+
|
||||
+/* CEC Rx buffer size */
|
||||
+#define CEC_RX_BUFF_SIZE 16
|
||||
+/* CEC Tx buffer size */
|
||||
+#define CEC_TX_BUFF_SIZE 16
|
||||
+
|
||||
+#define DRV_NAME "amlogic_cec"
|
||||
+#ifndef tvout_dbg
|
||||
+#ifdef CONFIG_TV_DEBUG
|
||||
+#define tvout_dbg(fmt, ...) \
|
||||
+ printk(KERN_INFO "[%s] %s(): " fmt, \
|
||||
+ DRV_NAME, __func__, ##__VA_ARGS__)
|
||||
+#else
|
||||
+#define tvout_dbg(fmt, ...)
|
||||
+#endif
|
||||
+#endif
|
||||
+
|
||||
+static atomic_t hdmi_on = ATOMIC_INIT(0);
|
||||
+
|
||||
+bool cec_msg_dbg_en = 1;
|
||||
+cec_global_info_t cec_global_info;
|
||||
+
|
||||
+static hdmitx_dev_t* hdmitx_device = NULL;
|
||||
+static struct workqueue_struct *cec_workqueue = NULL;
|
||||
+
|
||||
+struct cec_rx_list {
|
||||
+ u8 buffer[CEC_RX_BUFF_SIZE];
|
||||
+ unsigned char size;
|
||||
+ struct list_head list;
|
||||
+};
|
||||
+
|
||||
+struct cec_rx_struct {
|
||||
+ spinlock_t lock;
|
||||
+ wait_queue_head_t waitq;
|
||||
+ atomic_t state;
|
||||
+ struct list_head list;
|
||||
+};
|
||||
+
|
||||
+enum cec_state {
|
||||
+ STATE_RX,
|
||||
+ STATE_TX,
|
||||
+ STATE_DONE,
|
||||
+ STATE_ERROR
|
||||
+};
|
||||
+
|
||||
+static char banner[] __initdata =
|
||||
+ "Amlogic CEC Driver, (c) 2016 Gerald Dachs\n";
|
||||
+
|
||||
+static struct cec_rx_struct cec_rx_struct;
|
||||
+
|
||||
+unsigned short cec_log_addr_to_dev_type(unsigned char log_addr)
|
||||
+{
|
||||
+ unsigned short us = CEC_UNREGISTERED_DEVICE_TYPE;
|
||||
+ if ((1 << log_addr) & CEC_DISPLAY_DEVICE)
|
||||
+ {
|
||||
+ us = CEC_DISPLAY_DEVICE_TYPE;
|
||||
+ }
|
||||
+ else if ((1 << log_addr) & CEC_RECORDING_DEVICE)
|
||||
+ {
|
||||
+ us = CEC_RECORDING_DEVICE_TYPE;
|
||||
+ }
|
||||
+ else if ((1 << log_addr) & CEC_PLAYBACK_DEVICE)
|
||||
+ {
|
||||
+ us = CEC_PLAYBACK_DEVICE_TYPE;
|
||||
+ }
|
||||
+ else if ((1 << log_addr) & CEC_TUNER_DEVICE)
|
||||
+ {
|
||||
+ us = CEC_TUNER_DEVICE_TYPE;
|
||||
+ }
|
||||
+ else if ((1 << log_addr) & CEC_AUDIO_SYSTEM_DEVICE)
|
||||
+ {
|
||||
+ us = CEC_AUDIO_SYSTEM_DEVICE_TYPE;
|
||||
+ }
|
||||
+
|
||||
+ return us;
|
||||
+}
|
||||
+
|
||||
+void cec_report_physical_address_smp(void)
|
||||
+{
|
||||
+ unsigned char msg[5];
|
||||
+ unsigned char index = cec_global_info.my_node_index;
|
||||
+ unsigned char phy_addr_ab = (aml_read_reg32(P_AO_DEBUG_REG1) >> 8) & 0xff;
|
||||
+ unsigned char phy_addr_cd = aml_read_reg32(P_AO_DEBUG_REG1) & 0xff;
|
||||
+
|
||||
+ tvout_dbg("cec_report_physical_address_smp: enter\n");
|
||||
+
|
||||
+ msg[0] = ((index & 0xf) << 4) | CEC_BROADCAST_ADDR;
|
||||
+ msg[1] = CEC_OC_REPORT_PHYSICAL_ADDRESS;
|
||||
+ msg[2] = phy_addr_ab;
|
||||
+ msg[3] = phy_addr_cd;
|
||||
+ msg[4] = cec_log_addr_to_dev_type(index);
|
||||
+
|
||||
+ cec_ll_tx(msg, 5);
|
||||
+
|
||||
+ tvout_dbg("cec_report_physical_address_smp: leave\n");
|
||||
+}
|
||||
+
|
||||
+void cec_node_init(hdmitx_dev_t* hdmitx_device)
|
||||
+{
|
||||
+ unsigned long cec_phy_addr;
|
||||
+
|
||||
+ tvout_dbg("cec node init: enter\n");
|
||||
+
|
||||
+ cec_phy_addr = (((hdmitx_device->hdmi_info.vsdb_phy_addr.a) & 0xf) << 12)
|
||||
+ | (((hdmitx_device->hdmi_info.vsdb_phy_addr.b) & 0xf) << 8)
|
||||
+ | (((hdmitx_device->hdmi_info.vsdb_phy_addr.c) & 0xf) << 4)
|
||||
+ | (((hdmitx_device->hdmi_info.vsdb_phy_addr.d) & 0xf) << 0);
|
||||
+
|
||||
+ // If VSDB is not valid,use last or default physical address.
|
||||
+ if (hdmitx_device->hdmi_info.vsdb_phy_addr.valid == 0)
|
||||
+ {
|
||||
+ tvout_dbg("no valid cec physical address\n");
|
||||
+ if (aml_read_reg32 (P_AO_DEBUG_REG1))
|
||||
+ {
|
||||
+ tvout_dbg("use last physical address\n");
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ aml_write_reg32 (P_AO_DEBUG_REG1, 0x1000);
|
||||
+ tvout_dbg("use default physical address\n");
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ aml_write_reg32 (P_AO_DEBUG_REG1, cec_phy_addr);
|
||||
+ }
|
||||
+ tvout_dbg("physical address:0x%x\n", aml_read_reg32(P_AO_DEBUG_REG1));
|
||||
+
|
||||
+ if (hdmitx_device->cec_init_ready != 0)
|
||||
+ {
|
||||
+ tvout_dbg("report physical address:0x%x\n", aml_read_reg32(P_AO_DEBUG_REG1));
|
||||
+ cec_report_physical_address_smp();
|
||||
+ }
|
||||
+ tvout_dbg("cec node init: cec features ok !\n");
|
||||
+}
|
||||
+
|
||||
+static void amlogic_cec_set_rx_state(enum cec_state state)
|
||||
+{
|
||||
+ atomic_set(&cec_rx_struct.state, state);
|
||||
+}
|
||||
+
|
||||
+static int amlogic_cec_open(struct inode *inode, struct file *file)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (atomic_read(&hdmi_on))
|
||||
+ {
|
||||
+ tvout_dbg("do not allow multiple open for tvout cec\n");
|
||||
+ ret = -EBUSY;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ atomic_inc(&hdmi_on);
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int amlogic_cec_release(struct inode *inode, struct file *file)
|
||||
+{
|
||||
+ atomic_dec(&hdmi_on);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static ssize_t amlogic_cec_read(struct file *file, char __user *buffer,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ ssize_t retval;
|
||||
+ unsigned long spin_flags;
|
||||
+ struct cec_rx_list* entry = NULL;
|
||||
+
|
||||
+ tvout_dbg("amlogic_cec_read: enter\n");
|
||||
+
|
||||
+ if (wait_event_interruptible(cec_rx_struct.waitq,
|
||||
+ atomic_read(&cec_rx_struct.state) == STATE_DONE))
|
||||
+ {
|
||||
+ tvout_dbg("error during wait on state change\n");
|
||||
+ return -ERESTARTSYS;
|
||||
+ }
|
||||
+
|
||||
+ spin_lock_irqsave(&cec_rx_struct.lock, spin_flags);
|
||||
+
|
||||
+ entry = list_first_entry_or_null(&cec_rx_struct.list, struct cec_rx_list, list);
|
||||
+
|
||||
+ if (entry == NULL || entry->size > count)
|
||||
+ {
|
||||
+ tvout_dbg("entry is NULL, or empty\n");
|
||||
+ retval = -1;
|
||||
+ goto error_exit;
|
||||
+ }
|
||||
+
|
||||
+ if (copy_to_user(buffer, entry->buffer, entry->size))
|
||||
+ {
|
||||
+ printk(KERN_ERR " copy_to_user() failed!\n");
|
||||
+
|
||||
+ retval = -EFAULT;
|
||||
+ goto error_exit;
|
||||
+ }
|
||||
+
|
||||
+ retval = entry->size;
|
||||
+
|
||||
+ amlogic_cec_set_rx_state(STATE_RX);
|
||||
+
|
||||
+error_exit:
|
||||
+ if (entry != NULL)
|
||||
+ {
|
||||
+ list_del(&entry->list);
|
||||
+ kfree(entry);
|
||||
+ }
|
||||
+
|
||||
+ spin_unlock_irqrestore(&cec_rx_struct.lock, spin_flags);
|
||||
+
|
||||
+ tvout_dbg("amlogic_cec_read: leave\n");
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+static ssize_t amlogic_cec_write(struct file *file, const char __user *buffer,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ char data[CEC_TX_BUFF_SIZE];
|
||||
+
|
||||
+ tvout_dbg("amlogic_cec_write: enter\n");
|
||||
+
|
||||
+ /* check data size */
|
||||
+ if (count > CEC_TX_BUFF_SIZE || count == 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (copy_from_user(data, buffer, count))
|
||||
+ {
|
||||
+ printk(KERN_ERR " copy_from_user() failed!\n");
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+
|
||||
+ ret = cec_ll_tx(data, count);
|
||||
+ if (ret != 1)
|
||||
+ {
|
||||
+ tvout_dbg("Message transmit failed, ret=%d\n", ret);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ tvout_dbg("amlogic_cec_write: leave\n");
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static long amlogic_cec_ioctl(struct file *file, unsigned int cmd,
|
||||
+ unsigned long arg)
|
||||
+{
|
||||
+ unsigned char logical_addr;
|
||||
+
|
||||
+ switch(cmd) {
|
||||
+ case CEC_IOC_SETLADDR:
|
||||
+ if (get_user(logical_addr, (unsigned char __user *)arg))
|
||||
+ {
|
||||
+ tvout_dbg("Failed to get logical addr from user\n");
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+
|
||||
+ cec_global_info.my_node_index = logical_addr;
|
||||
+#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
|
||||
+ hdmi_wr_reg(CEC0_BASE_ADDR+CEC_LOGICAL_ADDR0, (0x1 << 4) | logical_addr);
|
||||
+#endif
|
||||
+#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
|
||||
+ aocec_wr_reg(CEC_LOGICAL_ADDR0, (0x1 << 4) | logical_addr);
|
||||
+#endif
|
||||
+ tvout_dbg("Set logical address: %d\n", logical_addr);
|
||||
+ return 0;
|
||||
+
|
||||
+ case CEC_IOC_GETPADDR:
|
||||
+ return aml_read_reg32(P_AO_DEBUG_REG1);
|
||||
+ }
|
||||
+
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static u32 amlogic_cec_poll(struct file *file, poll_table *wait)
|
||||
+{
|
||||
+ poll_wait(file, &cec_rx_struct.waitq, wait);
|
||||
+
|
||||
+ if (atomic_read(&cec_rx_struct.state) == STATE_DONE)
|
||||
+ {
|
||||
+ return POLLIN | POLLRDNORM;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations cec_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .open = amlogic_cec_open,
|
||||
+ .release = amlogic_cec_release,
|
||||
+ .read = amlogic_cec_read,
|
||||
+ .write = amlogic_cec_write,
|
||||
+ .unlocked_ioctl = amlogic_cec_ioctl,
|
||||
+ .poll = amlogic_cec_poll,
|
||||
+};
|
||||
+
|
||||
+static struct miscdevice cec_misc_device = {
|
||||
+ .minor = CEC_MINOR,
|
||||
+ .name = "AmlogicCEC",
|
||||
+ .fops = &cec_fops,
|
||||
+};
|
||||
+
|
||||
+static irqreturn_t amlogic_cec_irq_handler(int irq, void *dummy)
|
||||
+{
|
||||
+ unsigned long spin_flags;
|
||||
+ struct cec_rx_list *entry;
|
||||
+#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
|
||||
+ unsigned int intr_stat = 0;
|
||||
+#endif
|
||||
+
|
||||
+ tvout_dbg("amlogic_cec_irq_handler: enter\n");
|
||||
+
|
||||
+ udelay(100); //Delay execution a little. This fixes an issue when HDMI CEC stops working after a while.
|
||||
+
|
||||
+#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
|
||||
+ tvout_dbg("cec TX status: rx: 0x%x; tx: 0x%x\n", hdmi_rd_reg(CEC0_BASE_ADDR+CEC_RX_MSG_STATUS), hdmi_rd_reg(CEC0_BASE_ADDR+CEC_TX_MSG_STATUS));
|
||||
+ if (hdmi_rd_reg(CEC0_BASE_ADDR+CEC_RX_MSG_STATUS) != RX_DONE)
|
||||
+ {
|
||||
+ return IRQ_HANDLED;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
|
||||
+ intr_stat = aml_read_reg32(P_AO_CEC_INTR_STAT);
|
||||
+ tvout_dbg("aocec irq %x\n", intr_stat);
|
||||
+ if (intr_stat & (1<<1))
|
||||
+ { // aocec tx intr
|
||||
+ tx_irq_handle();
|
||||
+ return IRQ_HANDLED;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ if ((entry = kmalloc(sizeof(struct cec_rx_list), GFP_ATOMIC)) == NULL)
|
||||
+ {
|
||||
+ tvout_dbg("can't alloc cec_rx_list\n");
|
||||
+ return IRQ_HANDLED;
|
||||
+ }
|
||||
+
|
||||
+ if ((-1) == cec_ll_rx(entry->buffer, &entry->size))
|
||||
+ {
|
||||
+ kfree(entry);
|
||||
+ tvout_dbg("amlogic_cec_irq_handler: nothing to read\n");
|
||||
+ return IRQ_HANDLED;
|
||||
+ }
|
||||
+
|
||||
+ INIT_LIST_HEAD(&entry->list);
|
||||
+
|
||||
+ spin_lock_irqsave(&cec_rx_struct.lock, spin_flags);
|
||||
+ list_add_tail(&entry->list, &cec_rx_struct.list);
|
||||
+ amlogic_cec_set_rx_state(STATE_DONE);
|
||||
+ spin_unlock_irqrestore(&cec_rx_struct.lock, spin_flags);
|
||||
+
|
||||
+ wake_up_interruptible(&cec_rx_struct.waitq);
|
||||
+
|
||||
+ tvout_dbg("amlogic_cec_irq_handler: leave\n");
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static void amlogic_cec_delayed_init(struct work_struct *work)
|
||||
+{
|
||||
+ hdmitx_dev_t* hdmitx_device = (hdmitx_dev_t*)container_of(work, hdmitx_dev_t, cec_work);
|
||||
+
|
||||
+ tvout_dbg("amlogic_cec_delayed_init: enter\n");
|
||||
+
|
||||
+ msleep_interruptible(15000);
|
||||
+
|
||||
+#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
|
||||
+ cec_gpi_init();
|
||||
+#endif
|
||||
+
|
||||
+#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
|
||||
+ aml_set_reg32_bits(P_PERIPHS_PIN_MUX_1, 1, 25, 1);
|
||||
+ // Clear CEC Int. state and set CEC Int. mask
|
||||
+ aml_write_reg32(P_SYS_CPU_0_IRQ_IN1_INTR_STAT_CLR, aml_read_reg32(P_SYS_CPU_0_IRQ_IN1_INTR_STAT_CLR) | (1 << 23)); // Clear the interrupt
|
||||
+ aml_write_reg32(P_SYS_CPU_0_IRQ_IN1_INTR_MASK, aml_read_reg32(P_SYS_CPU_0_IRQ_IN1_INTR_MASK) | (1 << 23)); // Enable the hdmi cec interrupt
|
||||
+
|
||||
+#endif
|
||||
+#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
|
||||
+#if 1 // Please match with H/W cec config
|
||||
+// GPIOAO_12
|
||||
+ aml_set_reg32_bits(P_AO_RTI_PIN_MUX_REG, 0, 14, 1); // bit[14]: AO_PWM_C pinmux //0xc8100014
|
||||
+ aml_set_reg32_bits(P_AO_RTI_PULL_UP_REG, 1, 12, 1); // bit[12]: enable AO_12 internal pull-up //0xc810002c
|
||||
+ aml_set_reg32_bits(P_AO_RTI_PIN_MUX_REG, 1, 17, 1); // bit[17]: AO_CEC pinmux //0xc8100014
|
||||
+ ao_cec_init();
|
||||
+#else
|
||||
+// GPIOH_3
|
||||
+ aml_set_reg32_bits(P_PAD_PULL_UP_EN_REG1, 0, 19, 1); // disable gpioh_3 internal pull-up
|
||||
+ aml_set_reg32_bits(P_PERIPHS_PIN_MUX_1, 1, 23, 1); // gpioh_3 cec pinmux
|
||||
+#endif
|
||||
+ cec_arbit_bit_time_set(3, 0x118, 0);
|
||||
+ cec_arbit_bit_time_set(5, 0x000, 0);
|
||||
+ cec_arbit_bit_time_set(7, 0x2aa, 0);
|
||||
+#endif
|
||||
+
|
||||
+ hdmitx_device->cec_init_ready = 1;
|
||||
+ cec_global_info.cec_flag.cec_init_flag = 0;
|
||||
+
|
||||
+ tvout_dbg("amlogic_cec_delayed_init: leave\n");
|
||||
+}
|
||||
+
|
||||
+static int amlogic_cec_init(void)
|
||||
+{
|
||||
+ extern hdmitx_dev_t * get_hdmitx_device(void);
|
||||
+ INIT_LIST_HEAD(&cec_rx_struct.list);
|
||||
+
|
||||
+ printk(banner);
|
||||
+
|
||||
+ hdmitx_device = get_hdmitx_device();
|
||||
+ tvout_dbg("CEC init\n");
|
||||
+ memset(&cec_global_info, 0, sizeof(cec_global_info_t));
|
||||
+
|
||||
+#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
|
||||
+ hdmi_wr_reg(CEC0_BASE_ADDR+CEC_CLOCK_DIV_H, 0x00 );
|
||||
+ hdmi_wr_reg(CEC0_BASE_ADDR+CEC_CLOCK_DIV_L, 0xf0 );
|
||||
+#endif
|
||||
+
|
||||
+ cec_global_info.cec_rx_msg_buf.rx_buf_size = sizeof(cec_global_info.cec_rx_msg_buf.cec_rx_message)/sizeof(cec_global_info.cec_rx_msg_buf.cec_rx_message[0]);
|
||||
+ cec_global_info.hdmitx_device = hdmitx_device;
|
||||
+
|
||||
+#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
|
||||
+ if (request_irq(INT_HDMI_CEC, &amlogic_cec_irq_handler,
|
||||
+ IRQF_SHARED, "amhdmitx-cec",(void *)hdmitx_device))
|
||||
+ {
|
||||
+ tvout_dbg("Can't register IRQ %d\n",INT_HDMI_CEC);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+#endif
|
||||
+#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
|
||||
+ if (request_irq(INT_AO_CEC, &amlogic_cec_irq_handler,
|
||||
+ IRQF_SHARED, "amhdmitx-aocec",(void *)hdmitx_device))
|
||||
+ {
|
||||
+ tvout_dbg("Can't register IRQ %d\n",INT_HDMI_CEC);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ init_waitqueue_head(&cec_rx_struct.waitq);
|
||||
+ spin_lock_init(&cec_rx_struct.lock);
|
||||
+
|
||||
+ if (misc_register(&cec_misc_device))
|
||||
+ {
|
||||
+ printk(KERN_WARNING " Couldn't register device 10, %d.\n", CEC_MINOR);
|
||||
+ return -EBUSY;
|
||||
+ }
|
||||
+
|
||||
+ cec_workqueue = create_workqueue("cec_work");
|
||||
+ if (cec_workqueue == NULL)
|
||||
+ {
|
||||
+ printk("create work queue failed\n");
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+ INIT_WORK(&hdmitx_device->cec_work, amlogic_cec_delayed_init);
|
||||
+ queue_work(cec_workqueue, &hdmitx_device->cec_work); // for init
|
||||
+
|
||||
+ tvout_dbg("hdmitx_device->cec_init_ready:0x%x\n", hdmitx_device->cec_init_ready);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void amlogic_cec_exit(void)
|
||||
+{
|
||||
+ if (cec_global_info.cec_flag.cec_init_flag == 1)
|
||||
+ {
|
||||
+
|
||||
+#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
|
||||
+ aml_write_reg32(P_SYS_CPU_0_IRQ_IN1_INTR_MASK, aml_read_reg32(P_SYS_CPU_0_IRQ_IN1_INTR_MASK) & ~(1 << 23)); // Disable the hdmi cec interrupt
|
||||
+ free_irq(INT_HDMI_CEC, (void *)hdmitx_device);
|
||||
+#endif
|
||||
+#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
|
||||
+ free_irq(INT_AO_CEC, (void *)hdmitx_device);
|
||||
+#endif
|
||||
+ cec_global_info.cec_flag.cec_init_flag = 0;
|
||||
+ }
|
||||
+
|
||||
+ misc_deregister(&cec_misc_device);
|
||||
+}
|
||||
+
|
||||
+module_init(amlogic_cec_init);
|
||||
+module_exit(amlogic_cec_exit);
|
||||
+
|
||||
diff --git a/drivers/amlogic/hdmi/hdmi_tx/hdmi_tx.c b/drivers/amlogic/hdmi/hdmi_tx/hdmi_tx.c
|
||||
index 3e043bc..69b3ffc 100755
|
||||
--- a/drivers/amlogic/hdmi/hdmi_tx/hdmi_tx.c
|
||||
+++ b/drivers/amlogic/hdmi/hdmi_tx/hdmi_tx.c
|
||||
@@ -542,6 +542,7 @@ static ssize_t store_disp_mode(struct device * dev, struct device_attribute *att
|
||||
return 16;
|
||||
}
|
||||
|
||||
+#ifndef CONFIG_AML_HDMI_TX_NEW_CEC_DRIVER
|
||||
/*cec attr*/
|
||||
static ssize_t show_cec(struct device * dev, struct device_attribute *attr, char * buf)
|
||||
{
|
||||
@@ -589,6 +590,7 @@ static ssize_t show_cec_lang_config(struct device * dev, struct device_attribute
|
||||
pos+=snprintf(buf+pos, PAGE_SIZE, "%x\n",cec_global_info.cec_node_info[cec_global_info.my_node_index].menu_lang);
|
||||
return pos;
|
||||
}
|
||||
+#endif
|
||||
|
||||
/*aud_mode attr*/
|
||||
static ssize_t show_aud_mode(struct device * dev, struct device_attribute *attr, char * buf)
|
||||
@@ -963,10 +965,12 @@ static DEVICE_ATTR(disp_cap_3d, S_IWUSR | S_IRUGO, show_disp_cap_3d, NULL);
|
||||
static DEVICE_ATTR(hdcp_ksv_info, S_IWUSR | S_IRUGO, show_hdcp_ksv_info, NULL);
|
||||
static DEVICE_ATTR(hpd_state, S_IWUSR | S_IRUGO, show_hpd_state, NULL);
|
||||
static DEVICE_ATTR(support_3d, S_IWUSR | S_IRUGO, show_support_3d, NULL);
|
||||
+#ifndef CONFIG_AML_HDMI_TX_NEW_CEC_DRIVER
|
||||
static DEVICE_ATTR(cec, S_IWUSR | S_IRUGO, show_cec, store_cec);
|
||||
static DEVICE_ATTR(cec_config, S_IWUSR | S_IRUGO | S_IWGRP, show_cec_config, store_cec_config);
|
||||
//static DEVICE_ATTR(cec_config, S_IWUGO | S_IRUGO , NULL, store_cec_config);
|
||||
static DEVICE_ATTR(cec_lang_config, S_IWUSR | S_IRUGO | S_IWGRP, show_cec_lang_config, store_cec_lang_config);
|
||||
+#endif
|
||||
|
||||
/*****************************
|
||||
* hdmitx display client interface
|
||||
@@ -1643,9 +1647,11 @@ static int amhdmitx_probe(struct platform_device *pdev)
|
||||
ret=device_create_file(hdmitx_dev, &dev_attr_hdcp_ksv_info);
|
||||
ret=device_create_file(hdmitx_dev, &dev_attr_hpd_state);
|
||||
ret=device_create_file(hdmitx_dev, &dev_attr_support_3d);
|
||||
+#ifndef CONFIG_AML_HDMI_TX_NEW_CEC_DRIVER
|
||||
ret=device_create_file(hdmitx_dev, &dev_attr_cec);
|
||||
ret=device_create_file(hdmitx_dev, &dev_attr_cec_config);
|
||||
ret=device_create_file(hdmitx_dev, &dev_attr_cec_lang_config);
|
||||
+#endif
|
||||
|
||||
if (hdmitx_dev == NULL) {
|
||||
hdmi_print(ERR, SYS "device_create create error\n");
|
||||
@@ -1732,7 +1738,9 @@ static int amhdmitx_probe(struct platform_device *pdev)
|
||||
}
|
||||
#endif
|
||||
switch_dev_register(&sdev);
|
||||
+#ifndef CONFIG_AML_HDMI_TX_NEW_CEC_DRIVER
|
||||
switch_dev_register(&lang_dev);
|
||||
+#endif
|
||||
|
||||
hdmitx_init_parameters(&hdmitx_device.hdmi_info);
|
||||
HDMITX_Meson_Init(&hdmitx_device);
|
||||
@@ -1771,8 +1779,9 @@ static int amhdmitx_remove(struct platform_device *pdev)
|
||||
device_remove_file(hdmitx_dev, &dev_attr_disp_cap_3d);
|
||||
device_remove_file(hdmitx_dev, &dev_attr_hpd_state);
|
||||
device_remove_file(hdmitx_dev, &dev_attr_support_3d);
|
||||
+#ifndef CONFIG_AML_HDMI_TX_NEW_CEC_DRIVER
|
||||
device_remove_file(hdmitx_dev, &dev_attr_cec);
|
||||
-
|
||||
+#endif
|
||||
cdev_del(&hdmitx_device.cdev);
|
||||
|
||||
device_destroy(hdmitx_class, hdmitx_id);
|
||||
diff --git a/drivers/amlogic/input/new_remote/remote_func.c b/drivers/amlogic/input/new_remote/remote_func.c
|
||||
index e36e272..807c255 100755
|
||||
--- a/drivers/amlogic/input/new_remote/remote_func.c
|
||||
+++ b/drivers/amlogic/input/new_remote/remote_func.c
|
||||
@@ -525,6 +525,7 @@ int remote_hw_reprot_key(struct remote *remote_data)
|
||||
mod_timer(&remote_data->timer, jiffies + msecs_to_jiffies(remote_data->release_delay[remote_data->map_num]+remote_data->repeat_delay[remote_data->map_num]));
|
||||
} else if((remote_data->frame_status & REPEARTFLAG) && remote_data->enable_repeat_falg) { //repeate key
|
||||
#ifdef CONFIG_AML_HDMI_TX
|
||||
+#ifndef CONFIG_AML_HDMI_TX_NEW_CEC_DRIVER
|
||||
extern int rc_long_press_pwr_key;
|
||||
if((remote_data->repeat_release_code == 0x1a) && (!cec_repeat)) {
|
||||
rc_long_press_pwr_key = 1;
|
||||
@@ -534,6 +535,7 @@ int remote_hw_reprot_key(struct remote *remote_data)
|
||||
cec_repeat--;
|
||||
|
||||
#endif
|
||||
+#endif
|
||||
if (remote_data->repeat_enable) {
|
||||
repeat_count++;
|
||||
if (remote_data->repeat_tick < jiffies) {
|
||||
@@ -618,6 +620,7 @@ int remote_hw_nec_rca_2in1_reprot_key(struct remote *remote_data)
|
||||
mod_timer(&remote_data->timer, jiffies + msecs_to_jiffies(remote_data->release_delay[remote_data->map_num]+remote_data->repeat_delay[remote_data->map_num]));
|
||||
} else if((remote_data->frame_status & REPEARTFLAG) && remote_data->enable_repeat_falg) { //repeate key
|
||||
#ifdef CONFIG_AML_HDMI_TX
|
||||
+#ifndef CONFIG_AML_HDMI_TX_NEW_CEC_DRIVER
|
||||
extern int rc_long_press_pwr_key;
|
||||
if((remote_data->repeat_release_code == 0x1a) && (!cec_repeat)) {
|
||||
rc_long_press_pwr_key = 1;
|
||||
@@ -627,6 +630,7 @@ int remote_hw_nec_rca_2in1_reprot_key(struct remote *remote_data)
|
||||
cec_repeat--;
|
||||
|
||||
#endif
|
||||
+#endif
|
||||
if (remote_data->repeat_enable) {
|
||||
repeat_count++;
|
||||
if (remote_data->repeat_tick < jiffies) {
|
||||
@@ -700,6 +704,7 @@ int remote_hw_nec_toshiba_2in1_reprot_key(struct remote *remote_data)
|
||||
mod_timer(&remote_data->timer, jiffies + msecs_to_jiffies(remote_data->release_delay[remote_data->map_num]+remote_data->repeat_delay[remote_data->map_num]));
|
||||
} else if((remote_data->frame_status & REPEARTFLAG) && remote_data->enable_repeat_falg) { //repeate key
|
||||
#ifdef CONFIG_AML_HDMI_TX
|
||||
+#ifndef CONFIG_AML_HDMI_TX_NEW_CEC_DRIVER
|
||||
extern int rc_long_press_pwr_key;
|
||||
if((remote_data->repeat_release_code == 0x1a) && (!cec_repeat)) {
|
||||
rc_long_press_pwr_key = 1;
|
||||
@@ -709,6 +714,7 @@ int remote_hw_nec_toshiba_2in1_reprot_key(struct remote *remote_data)
|
||||
cec_repeat--;
|
||||
|
||||
#endif
|
||||
+#endif
|
||||
if (remote_data->repeat_enable) {
|
||||
repeat_count++;
|
||||
if (remote_data->repeat_tick < jiffies) {
|
||||
diff --git a/drivers/amlogic/input/remote/am_remote.c b/drivers/amlogic/input/remote/am_remote.c
|
||||
index c824efb..01f0bfba 100755
|
||||
--- a/drivers/amlogic/input/remote/am_remote.c
|
||||
+++ b/drivers/amlogic/input/remote/am_remote.c
|
||||
@@ -390,6 +390,7 @@ static inline int remote_hw_reprot_key(struct remote *remote_data)
|
||||
}
|
||||
#ifdef CONFIG_AML_HDMI_TX
|
||||
#ifdef CONFIG_ARCH_MESON6
|
||||
+#ifndef CONFIG_AML_HDMI_TX_NEW_CEC_DRIVER
|
||||
//printk("last_scan_code:%x\n", last_scan_code);
|
||||
if((((scan_code >> 16) & 0xff) == 0x1a) && (!cec_repeat)) {
|
||||
extern int rc_long_press_pwr_key;
|
||||
@@ -401,6 +402,7 @@ static inline int remote_hw_reprot_key(struct remote *remote_data)
|
||||
cec_repeat--;
|
||||
#endif
|
||||
#endif
|
||||
+#endif
|
||||
if (remote_data->repeat_enable) {
|
||||
if ((remote_data->repeat_tick < jiffies)&&(repeat_flag == 1)) {
|
||||
remote_send_key(remote_data->input, (scan_code >> 16) & 0xff, 2);
|
@ -1232,6 +1232,7 @@ CONFIG_AM_HDMI_ONLY=y
|
||||
# CONFIG_AML_HDMI_TX_20 is not set
|
||||
CONFIG_AML_HDMI_TX=y
|
||||
# CONFIG_AML_HDMI_TX_HDCP is not set
|
||||
CONFIG_AML_HDMI_TX_NEW_CEC_DRIVER=y
|
||||
# CONFIG_TVIN is not set
|
||||
# CONFIG_AML_EXT_HDMIIN is not set
|
||||
# CONFIG_DEBUG_DRIVER is not set
|
||||
|
749
projects/WeTek_Play/patches/linux/080-amlogic-cec-driver.patch
Normal file
749
projects/WeTek_Play/patches/linux/080-amlogic-cec-driver.patch
Normal file
@ -0,0 +1,749 @@
|
||||
From 3bde21926d476a3fc0f4d37275f8fde11f09dade Mon Sep 17 00:00:00 2001
|
||||
From: Gerald Dachs <gda@dachsweb.de>
|
||||
Date: Wed, 3 Feb 2016 19:19:49 +0100
|
||||
Subject: [PATCH] New amlogic cec driver
|
||||
|
||||
---
|
||||
.../mach-mesong9bb/hdmi_tx_hw_20/hdmi_tx_cec_hw.c | 3 +-
|
||||
drivers/amlogic/hdmi/Kconfig | 8 +
|
||||
drivers/amlogic/hdmi/hdmi_tx/Makefile | 8 +-
|
||||
drivers/amlogic/hdmi/hdmi_tx/amlogic_cec.c | 534 +++++++++++++++++++++
|
||||
drivers/amlogic/hdmi/hdmi_tx/hdmi_tx.c | 11 +-
|
||||
drivers/amlogic/input/new_remote/remote_func.c | 6 +
|
||||
drivers/amlogic/input/remote/am_remote.c | 2 +
|
||||
7 files changed, 569 insertions(+), 3 deletions(-)
|
||||
create mode 100644 drivers/amlogic/hdmi/hdmi_tx/amlogic_cec.c
|
||||
|
||||
diff --git a/arch/arm/mach-mesong9bb/hdmi_tx_hw_20/hdmi_tx_cec_hw.c b/arch/arm/mach-mesong9bb/hdmi_tx_hw_20/hdmi_tx_cec_hw.c
|
||||
index a2a78bd..762feba 100644
|
||||
--- a/arch/arm/mach-mesong9bb/hdmi_tx_hw_20/hdmi_tx_cec_hw.c
|
||||
+++ b/arch/arm/mach-mesong9bb/hdmi_tx_hw_20/hdmi_tx_cec_hw.c
|
||||
@@ -996,6 +996,7 @@ void cec_tx_irq_handle(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
+#ifndef CONFIG_AML_HDMI_TX_NEW_CEC_DRIVER
|
||||
void cec_polling_online_dev(int log_addr, int *bool)
|
||||
{
|
||||
#ifdef AO_CEC
|
||||
@@ -1005,7 +1006,7 @@ void cec_polling_online_dev(int log_addr, int *bool)
|
||||
#endif
|
||||
hdmi_print(INF, CEC "CEC: poll online logic device: 0x%x BOOL: %d\n", log_addr, *bool);
|
||||
}
|
||||
-
|
||||
+#endif
|
||||
|
||||
// DELETE LATER, TEST ONLY
|
||||
void cec_test_(unsigned int cmd)
|
||||
diff --git a/drivers/amlogic/hdmi/Kconfig b/drivers/amlogic/hdmi/Kconfig
|
||||
index 71f6bf8..1bfc289 100755
|
||||
--- a/drivers/amlogic/hdmi/Kconfig
|
||||
+++ b/drivers/amlogic/hdmi/Kconfig
|
||||
@@ -24,4 +24,12 @@ config AML_HDMI_TX_HDCP
|
||||
hdmitx hdcp enable, it should be enalbe if board burned hdmitx hdcp keys
|
||||
endif
|
||||
|
||||
+if AML_HDMI_TX
|
||||
+config AML_HDMI_TX_NEW_CEC_DRIVER
|
||||
+ bool "HDMI new CEC driver"
|
||||
+ default n
|
||||
+ help
|
||||
+ hdmitx uses new CEC driver
|
||||
+endif
|
||||
+
|
||||
endmenu
|
||||
diff --git a/drivers/amlogic/hdmi/hdmi_tx/Makefile b/drivers/amlogic/hdmi/hdmi_tx/Makefile
|
||||
index 7a944cd..f74ec1f 100755
|
||||
--- a/drivers/amlogic/hdmi/hdmi_tx/Makefile
|
||||
+++ b/drivers/amlogic/hdmi/hdmi_tx/Makefile
|
||||
@@ -1,5 +1,11 @@
|
||||
obj-$(CONFIG_AML_HDMI_TX) += hdmitx.o
|
||||
|
||||
-hdmitx-objs := hdmi_tx.o hdmi_tx_cec.o hdmi_cec_key.o hdmi_tx_video.o hdmi_tx_audio.o hdmi_tx_edid.o hdmi_tx_audio.o hdmi_tx_hdcp.o hdmi_tx_compliance.o
|
||||
+hdmitx-objs := hdmi_tx.o hdmi_tx_video.o hdmi_tx_audio.o hdmi_tx_edid.o hdmi_tx_audio.o hdmi_tx_hdcp.o hdmi_tx_compliance.o
|
||||
+
|
||||
+ifdef CONFIG_AML_HDMI_TX_NEW_CEC_DRIVER
|
||||
+ hdmitx-objs += amlogic_cec.o
|
||||
+else
|
||||
+ hdmitx-objs += hdmi_tx_cec.o hdmi_cec_key.o
|
||||
+endif
|
||||
|
||||
#EXTRA_CFLAGS += -O2
|
||||
diff --git a/drivers/amlogic/hdmi/hdmi_tx/amlogic_cec.c b/drivers/amlogic/hdmi/hdmi_tx/amlogic_cec.c
|
||||
new file mode 100644
|
||||
index 0000000..61fb500
|
||||
--- /dev/null
|
||||
+++ b/drivers/amlogic/hdmi/hdmi_tx/amlogic_cec.c
|
||||
@@ -0,0 +1,534 @@
|
||||
+/* linux/drivers/amlogic/hdmi/hdmi_tx/amlogic_cec.c
|
||||
+ *
|
||||
+ * Copyright (c) 2016 Gerald Dachs
|
||||
+ *
|
||||
+ * CEC interface file for Amlogic
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+*/
|
||||
+
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/uaccess.h>
|
||||
+#include <linux/poll.h>
|
||||
+#include <linux/miscdevice.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/sched.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/export.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/cdev.h>
|
||||
+#include <linux/list.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/atomic.h>
|
||||
+
|
||||
+#include <asm/uaccess.h>
|
||||
+#include <asm/delay.h>
|
||||
+#include <mach/am_regs.h>
|
||||
+#include <mach/power_gate.h>
|
||||
+#include <linux/amlogic/tvin/tvin.h>
|
||||
+
|
||||
+#include <mach/gpio.h>
|
||||
+#include <linux/amlogic/hdmi_tx/hdmi_info_global.h>
|
||||
+#include <linux/amlogic/hdmi_tx/hdmi_tx_module.h>
|
||||
+#include <mach/hdmi_tx_reg.h>
|
||||
+#include <linux/amlogic/hdmi_tx/hdmi_tx_cec.h>
|
||||
+
|
||||
+#define CONFIG_TV_DEBUG
|
||||
+
|
||||
+MODULE_AUTHOR("Gerald Dachs");
|
||||
+MODULE_DESCRIPTION("Amlogic CEC driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+
|
||||
+#define CEC_IOC_MAGIC 'c'
|
||||
+#define CEC_IOC_SETLADDR _IOW(CEC_IOC_MAGIC, 0, unsigned int)
|
||||
+#define CEC_IOC_GETPADDR _IO(CEC_IOC_MAGIC, 1)
|
||||
+
|
||||
+#define VERSION "1.0" /* Driver version number */
|
||||
+#define CEC_MINOR 243 /* Major 10, Minor 242, /dev/cec */
|
||||
+
|
||||
+/* CEC Rx buffer size */
|
||||
+#define CEC_RX_BUFF_SIZE 16
|
||||
+/* CEC Tx buffer size */
|
||||
+#define CEC_TX_BUFF_SIZE 16
|
||||
+
|
||||
+#define DRV_NAME "amlogic_cec"
|
||||
+#ifndef tvout_dbg
|
||||
+#ifdef CONFIG_TV_DEBUG
|
||||
+#define tvout_dbg(fmt, ...) \
|
||||
+ printk(KERN_INFO "[%s] %s(): " fmt, \
|
||||
+ DRV_NAME, __func__, ##__VA_ARGS__)
|
||||
+#else
|
||||
+#define tvout_dbg(fmt, ...)
|
||||
+#endif
|
||||
+#endif
|
||||
+
|
||||
+static atomic_t hdmi_on = ATOMIC_INIT(0);
|
||||
+
|
||||
+bool cec_msg_dbg_en = 1;
|
||||
+cec_global_info_t cec_global_info;
|
||||
+
|
||||
+static hdmitx_dev_t* hdmitx_device = NULL;
|
||||
+static struct workqueue_struct *cec_workqueue = NULL;
|
||||
+
|
||||
+struct cec_rx_list {
|
||||
+ u8 buffer[CEC_RX_BUFF_SIZE];
|
||||
+ unsigned char size;
|
||||
+ struct list_head list;
|
||||
+};
|
||||
+
|
||||
+struct cec_rx_struct {
|
||||
+ spinlock_t lock;
|
||||
+ wait_queue_head_t waitq;
|
||||
+ atomic_t state;
|
||||
+ struct list_head list;
|
||||
+};
|
||||
+
|
||||
+enum cec_state {
|
||||
+ STATE_RX,
|
||||
+ STATE_TX,
|
||||
+ STATE_DONE,
|
||||
+ STATE_ERROR
|
||||
+};
|
||||
+
|
||||
+static char banner[] __initdata =
|
||||
+ "Amlogic CEC Driver, (c) 2016 Gerald Dachs\n";
|
||||
+
|
||||
+static struct cec_rx_struct cec_rx_struct;
|
||||
+
|
||||
+unsigned short cec_log_addr_to_dev_type(unsigned char log_addr)
|
||||
+{
|
||||
+ unsigned short us = CEC_UNREGISTERED_DEVICE_TYPE;
|
||||
+ if ((1 << log_addr) & CEC_DISPLAY_DEVICE)
|
||||
+ {
|
||||
+ us = CEC_DISPLAY_DEVICE_TYPE;
|
||||
+ }
|
||||
+ else if ((1 << log_addr) & CEC_RECORDING_DEVICE)
|
||||
+ {
|
||||
+ us = CEC_RECORDING_DEVICE_TYPE;
|
||||
+ }
|
||||
+ else if ((1 << log_addr) & CEC_PLAYBACK_DEVICE)
|
||||
+ {
|
||||
+ us = CEC_PLAYBACK_DEVICE_TYPE;
|
||||
+ }
|
||||
+ else if ((1 << log_addr) & CEC_TUNER_DEVICE)
|
||||
+ {
|
||||
+ us = CEC_TUNER_DEVICE_TYPE;
|
||||
+ }
|
||||
+ else if ((1 << log_addr) & CEC_AUDIO_SYSTEM_DEVICE)
|
||||
+ {
|
||||
+ us = CEC_AUDIO_SYSTEM_DEVICE_TYPE;
|
||||
+ }
|
||||
+
|
||||
+ return us;
|
||||
+}
|
||||
+
|
||||
+void cec_report_physical_address_smp(void)
|
||||
+{
|
||||
+ unsigned char msg[5];
|
||||
+ unsigned char index = cec_global_info.my_node_index;
|
||||
+ unsigned char phy_addr_ab = (aml_read_reg32(P_AO_DEBUG_REG1) >> 8) & 0xff;
|
||||
+ unsigned char phy_addr_cd = aml_read_reg32(P_AO_DEBUG_REG1) & 0xff;
|
||||
+
|
||||
+ tvout_dbg("cec_report_physical_address_smp: enter\n");
|
||||
+
|
||||
+ msg[0] = ((index & 0xf) << 4) | CEC_BROADCAST_ADDR;
|
||||
+ msg[1] = CEC_OC_REPORT_PHYSICAL_ADDRESS;
|
||||
+ msg[2] = phy_addr_ab;
|
||||
+ msg[3] = phy_addr_cd;
|
||||
+ msg[4] = cec_log_addr_to_dev_type(index);
|
||||
+
|
||||
+ cec_ll_tx(msg, 5);
|
||||
+
|
||||
+ tvout_dbg("cec_report_physical_address_smp: leave\n");
|
||||
+}
|
||||
+
|
||||
+void cec_node_init(hdmitx_dev_t* hdmitx_device)
|
||||
+{
|
||||
+ unsigned long cec_phy_addr;
|
||||
+
|
||||
+ tvout_dbg("cec node init: enter\n");
|
||||
+
|
||||
+ cec_phy_addr = (((hdmitx_device->hdmi_info.vsdb_phy_addr.a) & 0xf) << 12)
|
||||
+ | (((hdmitx_device->hdmi_info.vsdb_phy_addr.b) & 0xf) << 8)
|
||||
+ | (((hdmitx_device->hdmi_info.vsdb_phy_addr.c) & 0xf) << 4)
|
||||
+ | (((hdmitx_device->hdmi_info.vsdb_phy_addr.d) & 0xf) << 0);
|
||||
+
|
||||
+ // If VSDB is not valid,use last or default physical address.
|
||||
+ if (hdmitx_device->hdmi_info.vsdb_phy_addr.valid == 0)
|
||||
+ {
|
||||
+ tvout_dbg("no valid cec physical address\n");
|
||||
+ if (aml_read_reg32 (P_AO_DEBUG_REG1))
|
||||
+ {
|
||||
+ tvout_dbg("use last physical address\n");
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ aml_write_reg32 (P_AO_DEBUG_REG1, 0x1000);
|
||||
+ tvout_dbg("use default physical address\n");
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ aml_write_reg32 (P_AO_DEBUG_REG1, cec_phy_addr);
|
||||
+ }
|
||||
+ tvout_dbg("physical address:0x%x\n", aml_read_reg32(P_AO_DEBUG_REG1));
|
||||
+
|
||||
+ if (hdmitx_device->cec_init_ready != 0)
|
||||
+ {
|
||||
+ tvout_dbg("report physical address:0x%x\n", aml_read_reg32(P_AO_DEBUG_REG1));
|
||||
+ cec_report_physical_address_smp();
|
||||
+ }
|
||||
+ tvout_dbg("cec node init: cec features ok !\n");
|
||||
+}
|
||||
+
|
||||
+static void amlogic_cec_set_rx_state(enum cec_state state)
|
||||
+{
|
||||
+ atomic_set(&cec_rx_struct.state, state);
|
||||
+}
|
||||
+
|
||||
+static int amlogic_cec_open(struct inode *inode, struct file *file)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (atomic_read(&hdmi_on))
|
||||
+ {
|
||||
+ tvout_dbg("do not allow multiple open for tvout cec\n");
|
||||
+ ret = -EBUSY;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ atomic_inc(&hdmi_on);
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int amlogic_cec_release(struct inode *inode, struct file *file)
|
||||
+{
|
||||
+ atomic_dec(&hdmi_on);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static ssize_t amlogic_cec_read(struct file *file, char __user *buffer,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ ssize_t retval;
|
||||
+ unsigned long spin_flags;
|
||||
+ struct cec_rx_list* entry = NULL;
|
||||
+
|
||||
+ tvout_dbg("amlogic_cec_read: enter\n");
|
||||
+
|
||||
+ if (wait_event_interruptible(cec_rx_struct.waitq,
|
||||
+ atomic_read(&cec_rx_struct.state) == STATE_DONE))
|
||||
+ {
|
||||
+ tvout_dbg("error during wait on state change\n");
|
||||
+ return -ERESTARTSYS;
|
||||
+ }
|
||||
+
|
||||
+ spin_lock_irqsave(&cec_rx_struct.lock, spin_flags);
|
||||
+
|
||||
+ entry = list_first_entry_or_null(&cec_rx_struct.list, struct cec_rx_list, list);
|
||||
+
|
||||
+ if (entry == NULL || entry->size > count)
|
||||
+ {
|
||||
+ tvout_dbg("entry is NULL, or empty\n");
|
||||
+ retval = -1;
|
||||
+ goto error_exit;
|
||||
+ }
|
||||
+
|
||||
+ if (copy_to_user(buffer, entry->buffer, entry->size))
|
||||
+ {
|
||||
+ printk(KERN_ERR " copy_to_user() failed!\n");
|
||||
+
|
||||
+ retval = -EFAULT;
|
||||
+ goto error_exit;
|
||||
+ }
|
||||
+
|
||||
+ retval = entry->size;
|
||||
+
|
||||
+ amlogic_cec_set_rx_state(STATE_RX);
|
||||
+
|
||||
+error_exit:
|
||||
+ if (entry != NULL)
|
||||
+ {
|
||||
+ list_del(&entry->list);
|
||||
+ kfree(entry);
|
||||
+ }
|
||||
+
|
||||
+ spin_unlock_irqrestore(&cec_rx_struct.lock, spin_flags);
|
||||
+
|
||||
+ tvout_dbg("amlogic_cec_read: leave\n");
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+static ssize_t amlogic_cec_write(struct file *file, const char __user *buffer,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ char data[CEC_TX_BUFF_SIZE];
|
||||
+
|
||||
+ tvout_dbg("amlogic_cec_write: enter\n");
|
||||
+
|
||||
+ /* check data size */
|
||||
+ if (count > CEC_TX_BUFF_SIZE || count == 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (copy_from_user(data, buffer, count))
|
||||
+ {
|
||||
+ printk(KERN_ERR " copy_from_user() failed!\n");
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+
|
||||
+ ret = cec_ll_tx(data, count);
|
||||
+ if (ret != 1)
|
||||
+ {
|
||||
+ tvout_dbg("Message transmit failed, ret=%d\n", ret);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ tvout_dbg("amlogic_cec_write: leave\n");
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static long amlogic_cec_ioctl(struct file *file, unsigned int cmd,
|
||||
+ unsigned long arg)
|
||||
+{
|
||||
+ unsigned char logical_addr;
|
||||
+
|
||||
+ switch(cmd) {
|
||||
+ case CEC_IOC_SETLADDR:
|
||||
+ if (get_user(logical_addr, (unsigned char __user *)arg))
|
||||
+ {
|
||||
+ tvout_dbg("Failed to get logical addr from user\n");
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+
|
||||
+ cec_global_info.my_node_index = logical_addr;
|
||||
+#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
|
||||
+ hdmi_wr_reg(CEC0_BASE_ADDR+CEC_LOGICAL_ADDR0, (0x1 << 4) | logical_addr);
|
||||
+#endif
|
||||
+#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
|
||||
+ aocec_wr_reg(CEC_LOGICAL_ADDR0, (0x1 << 4) | logical_addr);
|
||||
+#endif
|
||||
+ tvout_dbg("Set logical address: %d\n", logical_addr);
|
||||
+ return 0;
|
||||
+
|
||||
+ case CEC_IOC_GETPADDR:
|
||||
+ return aml_read_reg32(P_AO_DEBUG_REG1);
|
||||
+ }
|
||||
+
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static u32 amlogic_cec_poll(struct file *file, poll_table *wait)
|
||||
+{
|
||||
+ poll_wait(file, &cec_rx_struct.waitq, wait);
|
||||
+
|
||||
+ if (atomic_read(&cec_rx_struct.state) == STATE_DONE)
|
||||
+ {
|
||||
+ return POLLIN | POLLRDNORM;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations cec_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .open = amlogic_cec_open,
|
||||
+ .release = amlogic_cec_release,
|
||||
+ .read = amlogic_cec_read,
|
||||
+ .write = amlogic_cec_write,
|
||||
+ .unlocked_ioctl = amlogic_cec_ioctl,
|
||||
+ .poll = amlogic_cec_poll,
|
||||
+};
|
||||
+
|
||||
+static struct miscdevice cec_misc_device = {
|
||||
+ .minor = CEC_MINOR,
|
||||
+ .name = "AmlogicCEC",
|
||||
+ .fops = &cec_fops,
|
||||
+};
|
||||
+
|
||||
+static irqreturn_t amlogic_cec_irq_handler(int irq, void *dummy)
|
||||
+{
|
||||
+ unsigned long spin_flags;
|
||||
+ struct cec_rx_list *entry;
|
||||
+#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
|
||||
+ unsigned int intr_stat = 0;
|
||||
+#endif
|
||||
+
|
||||
+ tvout_dbg("amlogic_cec_irq_handler: enter\n");
|
||||
+
|
||||
+ udelay(100); //Delay execution a little. This fixes an issue when HDMI CEC stops working after a while.
|
||||
+
|
||||
+#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
|
||||
+ tvout_dbg("cec TX status: rx: 0x%x; tx: 0x%x\n", hdmi_rd_reg(CEC0_BASE_ADDR+CEC_RX_MSG_STATUS), hdmi_rd_reg(CEC0_BASE_ADDR+CEC_TX_MSG_STATUS));
|
||||
+ if (hdmi_rd_reg(CEC0_BASE_ADDR+CEC_RX_MSG_STATUS) != RX_DONE)
|
||||
+ {
|
||||
+ return IRQ_HANDLED;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
|
||||
+ intr_stat = aml_read_reg32(P_AO_CEC_INTR_STAT);
|
||||
+ tvout_dbg("aocec irq %x\n", intr_stat);
|
||||
+ if (intr_stat & (1<<1))
|
||||
+ { // aocec tx intr
|
||||
+ tx_irq_handle();
|
||||
+ return IRQ_HANDLED;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ if ((entry = kmalloc(sizeof(struct cec_rx_list), GFP_ATOMIC)) == NULL)
|
||||
+ {
|
||||
+ tvout_dbg("can't alloc cec_rx_list\n");
|
||||
+ return IRQ_HANDLED;
|
||||
+ }
|
||||
+
|
||||
+ if ((-1) == cec_ll_rx(entry->buffer, &entry->size))
|
||||
+ {
|
||||
+ kfree(entry);
|
||||
+ tvout_dbg("amlogic_cec_irq_handler: nothing to read\n");
|
||||
+ return IRQ_HANDLED;
|
||||
+ }
|
||||
+
|
||||
+ INIT_LIST_HEAD(&entry->list);
|
||||
+
|
||||
+ spin_lock_irqsave(&cec_rx_struct.lock, spin_flags);
|
||||
+ list_add_tail(&entry->list, &cec_rx_struct.list);
|
||||
+ amlogic_cec_set_rx_state(STATE_DONE);
|
||||
+ spin_unlock_irqrestore(&cec_rx_struct.lock, spin_flags);
|
||||
+
|
||||
+ wake_up_interruptible(&cec_rx_struct.waitq);
|
||||
+
|
||||
+ tvout_dbg("amlogic_cec_irq_handler: leave\n");
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static void amlogic_cec_delayed_init(struct work_struct *work)
|
||||
+{
|
||||
+ hdmitx_dev_t* hdmitx_device = (hdmitx_dev_t*)container_of(work, hdmitx_dev_t, cec_work);
|
||||
+
|
||||
+ tvout_dbg("amlogic_cec_delayed_init: enter\n");
|
||||
+
|
||||
+ msleep_interruptible(15000);
|
||||
+
|
||||
+#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
|
||||
+ cec_gpi_init();
|
||||
+#endif
|
||||
+
|
||||
+#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
|
||||
+ aml_set_reg32_bits(P_PERIPHS_PIN_MUX_1, 1, 25, 1);
|
||||
+ // Clear CEC Int. state and set CEC Int. mask
|
||||
+ aml_write_reg32(P_SYS_CPU_0_IRQ_IN1_INTR_STAT_CLR, aml_read_reg32(P_SYS_CPU_0_IRQ_IN1_INTR_STAT_CLR) | (1 << 23)); // Clear the interrupt
|
||||
+ aml_write_reg32(P_SYS_CPU_0_IRQ_IN1_INTR_MASK, aml_read_reg32(P_SYS_CPU_0_IRQ_IN1_INTR_MASK) | (1 << 23)); // Enable the hdmi cec interrupt
|
||||
+
|
||||
+#endif
|
||||
+#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
|
||||
+#if 1 // Please match with H/W cec config
|
||||
+// GPIOAO_12
|
||||
+ aml_set_reg32_bits(P_AO_RTI_PIN_MUX_REG, 0, 14, 1); // bit[14]: AO_PWM_C pinmux //0xc8100014
|
||||
+ aml_set_reg32_bits(P_AO_RTI_PULL_UP_REG, 1, 12, 1); // bit[12]: enable AO_12 internal pull-up //0xc810002c
|
||||
+ aml_set_reg32_bits(P_AO_RTI_PIN_MUX_REG, 1, 17, 1); // bit[17]: AO_CEC pinmux //0xc8100014
|
||||
+ ao_cec_init();
|
||||
+#else
|
||||
+// GPIOH_3
|
||||
+ aml_set_reg32_bits(P_PAD_PULL_UP_EN_REG1, 0, 19, 1); // disable gpioh_3 internal pull-up
|
||||
+ aml_set_reg32_bits(P_PERIPHS_PIN_MUX_1, 1, 23, 1); // gpioh_3 cec pinmux
|
||||
+#endif
|
||||
+ cec_arbit_bit_time_set(3, 0x118, 0);
|
||||
+ cec_arbit_bit_time_set(5, 0x000, 0);
|
||||
+ cec_arbit_bit_time_set(7, 0x2aa, 0);
|
||||
+#endif
|
||||
+
|
||||
+ hdmitx_device->cec_init_ready = 1;
|
||||
+ cec_global_info.cec_flag.cec_init_flag = 0;
|
||||
+
|
||||
+ tvout_dbg("amlogic_cec_delayed_init: leave\n");
|
||||
+}
|
||||
+
|
||||
+static int amlogic_cec_init(void)
|
||||
+{
|
||||
+ extern hdmitx_dev_t * get_hdmitx_device(void);
|
||||
+ INIT_LIST_HEAD(&cec_rx_struct.list);
|
||||
+
|
||||
+ printk(banner);
|
||||
+
|
||||
+ hdmitx_device = get_hdmitx_device();
|
||||
+ tvout_dbg("CEC init\n");
|
||||
+ memset(&cec_global_info, 0, sizeof(cec_global_info_t));
|
||||
+
|
||||
+#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
|
||||
+ hdmi_wr_reg(CEC0_BASE_ADDR+CEC_CLOCK_DIV_H, 0x00 );
|
||||
+ hdmi_wr_reg(CEC0_BASE_ADDR+CEC_CLOCK_DIV_L, 0xf0 );
|
||||
+#endif
|
||||
+
|
||||
+ cec_global_info.cec_rx_msg_buf.rx_buf_size = sizeof(cec_global_info.cec_rx_msg_buf.cec_rx_message)/sizeof(cec_global_info.cec_rx_msg_buf.cec_rx_message[0]);
|
||||
+ cec_global_info.hdmitx_device = hdmitx_device;
|
||||
+
|
||||
+#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
|
||||
+ if (request_irq(INT_HDMI_CEC, &amlogic_cec_irq_handler,
|
||||
+ IRQF_SHARED, "amhdmitx-cec",(void *)hdmitx_device))
|
||||
+ {
|
||||
+ tvout_dbg("Can't register IRQ %d\n",INT_HDMI_CEC);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+#endif
|
||||
+#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
|
||||
+ if (request_irq(INT_AO_CEC, &amlogic_cec_irq_handler,
|
||||
+ IRQF_SHARED, "amhdmitx-aocec",(void *)hdmitx_device))
|
||||
+ {
|
||||
+ tvout_dbg("Can't register IRQ %d\n",INT_HDMI_CEC);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ init_waitqueue_head(&cec_rx_struct.waitq);
|
||||
+ spin_lock_init(&cec_rx_struct.lock);
|
||||
+
|
||||
+ if (misc_register(&cec_misc_device))
|
||||
+ {
|
||||
+ printk(KERN_WARNING " Couldn't register device 10, %d.\n", CEC_MINOR);
|
||||
+ return -EBUSY;
|
||||
+ }
|
||||
+
|
||||
+ cec_workqueue = create_workqueue("cec_work");
|
||||
+ if (cec_workqueue == NULL)
|
||||
+ {
|
||||
+ printk("create work queue failed\n");
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+ INIT_WORK(&hdmitx_device->cec_work, amlogic_cec_delayed_init);
|
||||
+ queue_work(cec_workqueue, &hdmitx_device->cec_work); // for init
|
||||
+
|
||||
+ tvout_dbg("hdmitx_device->cec_init_ready:0x%x\n", hdmitx_device->cec_init_ready);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void amlogic_cec_exit(void)
|
||||
+{
|
||||
+ if (cec_global_info.cec_flag.cec_init_flag == 1)
|
||||
+ {
|
||||
+
|
||||
+#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
|
||||
+ aml_write_reg32(P_SYS_CPU_0_IRQ_IN1_INTR_MASK, aml_read_reg32(P_SYS_CPU_0_IRQ_IN1_INTR_MASK) & ~(1 << 23)); // Disable the hdmi cec interrupt
|
||||
+ free_irq(INT_HDMI_CEC, (void *)hdmitx_device);
|
||||
+#endif
|
||||
+#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
|
||||
+ free_irq(INT_AO_CEC, (void *)hdmitx_device);
|
||||
+#endif
|
||||
+ cec_global_info.cec_flag.cec_init_flag = 0;
|
||||
+ }
|
||||
+
|
||||
+ misc_deregister(&cec_misc_device);
|
||||
+}
|
||||
+
|
||||
+module_init(amlogic_cec_init);
|
||||
+module_exit(amlogic_cec_exit);
|
||||
+
|
||||
diff --git a/drivers/amlogic/hdmi/hdmi_tx/hdmi_tx.c b/drivers/amlogic/hdmi/hdmi_tx/hdmi_tx.c
|
||||
index 3e043bc..69b3ffc 100755
|
||||
--- a/drivers/amlogic/hdmi/hdmi_tx/hdmi_tx.c
|
||||
+++ b/drivers/amlogic/hdmi/hdmi_tx/hdmi_tx.c
|
||||
@@ -542,6 +542,7 @@ static ssize_t store_disp_mode(struct device * dev, struct device_attribute *att
|
||||
return 16;
|
||||
}
|
||||
|
||||
+#ifndef CONFIG_AML_HDMI_TX_NEW_CEC_DRIVER
|
||||
/*cec attr*/
|
||||
static ssize_t show_cec(struct device * dev, struct device_attribute *attr, char * buf)
|
||||
{
|
||||
@@ -589,6 +590,7 @@ static ssize_t show_cec_lang_config(struct device * dev, struct device_attribute
|
||||
pos+=snprintf(buf+pos, PAGE_SIZE, "%x\n",cec_global_info.cec_node_info[cec_global_info.my_node_index].menu_lang);
|
||||
return pos;
|
||||
}
|
||||
+#endif
|
||||
|
||||
/*aud_mode attr*/
|
||||
static ssize_t show_aud_mode(struct device * dev, struct device_attribute *attr, char * buf)
|
||||
@@ -963,10 +965,12 @@ static DEVICE_ATTR(disp_cap_3d, S_IWUSR | S_IRUGO, show_disp_cap_3d, NULL);
|
||||
static DEVICE_ATTR(hdcp_ksv_info, S_IWUSR | S_IRUGO, show_hdcp_ksv_info, NULL);
|
||||
static DEVICE_ATTR(hpd_state, S_IWUSR | S_IRUGO, show_hpd_state, NULL);
|
||||
static DEVICE_ATTR(support_3d, S_IWUSR | S_IRUGO, show_support_3d, NULL);
|
||||
+#ifndef CONFIG_AML_HDMI_TX_NEW_CEC_DRIVER
|
||||
static DEVICE_ATTR(cec, S_IWUSR | S_IRUGO, show_cec, store_cec);
|
||||
static DEVICE_ATTR(cec_config, S_IWUSR | S_IRUGO | S_IWGRP, show_cec_config, store_cec_config);
|
||||
//static DEVICE_ATTR(cec_config, S_IWUGO | S_IRUGO , NULL, store_cec_config);
|
||||
static DEVICE_ATTR(cec_lang_config, S_IWUSR | S_IRUGO | S_IWGRP, show_cec_lang_config, store_cec_lang_config);
|
||||
+#endif
|
||||
|
||||
/*****************************
|
||||
* hdmitx display client interface
|
||||
@@ -1643,9 +1647,11 @@ static int amhdmitx_probe(struct platform_device *pdev)
|
||||
ret=device_create_file(hdmitx_dev, &dev_attr_hdcp_ksv_info);
|
||||
ret=device_create_file(hdmitx_dev, &dev_attr_hpd_state);
|
||||
ret=device_create_file(hdmitx_dev, &dev_attr_support_3d);
|
||||
+#ifndef CONFIG_AML_HDMI_TX_NEW_CEC_DRIVER
|
||||
ret=device_create_file(hdmitx_dev, &dev_attr_cec);
|
||||
ret=device_create_file(hdmitx_dev, &dev_attr_cec_config);
|
||||
ret=device_create_file(hdmitx_dev, &dev_attr_cec_lang_config);
|
||||
+#endif
|
||||
|
||||
if (hdmitx_dev == NULL) {
|
||||
hdmi_print(ERR, SYS "device_create create error\n");
|
||||
@@ -1732,7 +1738,9 @@ static int amhdmitx_probe(struct platform_device *pdev)
|
||||
}
|
||||
#endif
|
||||
switch_dev_register(&sdev);
|
||||
+#ifndef CONFIG_AML_HDMI_TX_NEW_CEC_DRIVER
|
||||
switch_dev_register(&lang_dev);
|
||||
+#endif
|
||||
|
||||
hdmitx_init_parameters(&hdmitx_device.hdmi_info);
|
||||
HDMITX_Meson_Init(&hdmitx_device);
|
||||
@@ -1771,8 +1779,9 @@ static int amhdmitx_remove(struct platform_device *pdev)
|
||||
device_remove_file(hdmitx_dev, &dev_attr_disp_cap_3d);
|
||||
device_remove_file(hdmitx_dev, &dev_attr_hpd_state);
|
||||
device_remove_file(hdmitx_dev, &dev_attr_support_3d);
|
||||
+#ifndef CONFIG_AML_HDMI_TX_NEW_CEC_DRIVER
|
||||
device_remove_file(hdmitx_dev, &dev_attr_cec);
|
||||
-
|
||||
+#endif
|
||||
cdev_del(&hdmitx_device.cdev);
|
||||
|
||||
device_destroy(hdmitx_class, hdmitx_id);
|
||||
diff --git a/drivers/amlogic/input/new_remote/remote_func.c b/drivers/amlogic/input/new_remote/remote_func.c
|
||||
index e36e272..807c255 100755
|
||||
--- a/drivers/amlogic/input/new_remote/remote_func.c
|
||||
+++ b/drivers/amlogic/input/new_remote/remote_func.c
|
||||
@@ -525,6 +525,7 @@ int remote_hw_reprot_key(struct remote *remote_data)
|
||||
mod_timer(&remote_data->timer, jiffies + msecs_to_jiffies(remote_data->release_delay[remote_data->map_num]+remote_data->repeat_delay[remote_data->map_num]));
|
||||
} else if((remote_data->frame_status & REPEARTFLAG) && remote_data->enable_repeat_falg) { //repeate key
|
||||
#ifdef CONFIG_AML_HDMI_TX
|
||||
+#ifndef CONFIG_AML_HDMI_TX_NEW_CEC_DRIVER
|
||||
extern int rc_long_press_pwr_key;
|
||||
if((remote_data->repeat_release_code == 0x1a) && (!cec_repeat)) {
|
||||
rc_long_press_pwr_key = 1;
|
||||
@@ -534,6 +535,7 @@ int remote_hw_reprot_key(struct remote *remote_data)
|
||||
cec_repeat--;
|
||||
|
||||
#endif
|
||||
+#endif
|
||||
if (remote_data->repeat_enable) {
|
||||
repeat_count++;
|
||||
if (remote_data->repeat_tick < jiffies) {
|
||||
@@ -618,6 +620,7 @@ int remote_hw_nec_rca_2in1_reprot_key(struct remote *remote_data)
|
||||
mod_timer(&remote_data->timer, jiffies + msecs_to_jiffies(remote_data->release_delay[remote_data->map_num]+remote_data->repeat_delay[remote_data->map_num]));
|
||||
} else if((remote_data->frame_status & REPEARTFLAG) && remote_data->enable_repeat_falg) { //repeate key
|
||||
#ifdef CONFIG_AML_HDMI_TX
|
||||
+#ifndef CONFIG_AML_HDMI_TX_NEW_CEC_DRIVER
|
||||
extern int rc_long_press_pwr_key;
|
||||
if((remote_data->repeat_release_code == 0x1a) && (!cec_repeat)) {
|
||||
rc_long_press_pwr_key = 1;
|
||||
@@ -627,6 +630,7 @@ int remote_hw_nec_rca_2in1_reprot_key(struct remote *remote_data)
|
||||
cec_repeat--;
|
||||
|
||||
#endif
|
||||
+#endif
|
||||
if (remote_data->repeat_enable) {
|
||||
repeat_count++;
|
||||
if (remote_data->repeat_tick < jiffies) {
|
||||
@@ -700,6 +704,7 @@ int remote_hw_nec_toshiba_2in1_reprot_key(struct remote *remote_data)
|
||||
mod_timer(&remote_data->timer, jiffies + msecs_to_jiffies(remote_data->release_delay[remote_data->map_num]+remote_data->repeat_delay[remote_data->map_num]));
|
||||
} else if((remote_data->frame_status & REPEARTFLAG) && remote_data->enable_repeat_falg) { //repeate key
|
||||
#ifdef CONFIG_AML_HDMI_TX
|
||||
+#ifndef CONFIG_AML_HDMI_TX_NEW_CEC_DRIVER
|
||||
extern int rc_long_press_pwr_key;
|
||||
if((remote_data->repeat_release_code == 0x1a) && (!cec_repeat)) {
|
||||
rc_long_press_pwr_key = 1;
|
||||
@@ -709,6 +714,7 @@ int remote_hw_nec_toshiba_2in1_reprot_key(struct remote *remote_data)
|
||||
cec_repeat--;
|
||||
|
||||
#endif
|
||||
+#endif
|
||||
if (remote_data->repeat_enable) {
|
||||
repeat_count++;
|
||||
if (remote_data->repeat_tick < jiffies) {
|
||||
diff --git a/drivers/amlogic/input/remote/am_remote.c b/drivers/amlogic/input/remote/am_remote.c
|
||||
index c824efb..01f0bfba 100755
|
||||
--- a/drivers/amlogic/input/remote/am_remote.c
|
||||
+++ b/drivers/amlogic/input/remote/am_remote.c
|
||||
@@ -390,6 +390,7 @@ static inline int remote_hw_reprot_key(struct remote *remote_data)
|
||||
}
|
||||
#ifdef CONFIG_AML_HDMI_TX
|
||||
#ifdef CONFIG_ARCH_MESON6
|
||||
+#ifndef CONFIG_AML_HDMI_TX_NEW_CEC_DRIVER
|
||||
//printk("last_scan_code:%x\n", last_scan_code);
|
||||
if((((scan_code >> 16) & 0xff) == 0x1a) && (!cec_repeat)) {
|
||||
extern int rc_long_press_pwr_key;
|
||||
@@ -401,6 +402,7 @@ static inline int remote_hw_reprot_key(struct remote *remote_data)
|
||||
cec_repeat--;
|
||||
#endif
|
||||
#endif
|
||||
+#endif
|
||||
if (remote_data->repeat_enable) {
|
||||
if ((remote_data->repeat_tick < jiffies)&&(repeat_flag == 1)) {
|
||||
remote_send_key(remote_data->input, (scan_code >> 16) & 0xff, 2);
|
Loading…
x
Reference in New Issue
Block a user