mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-24 11:16:51 +00:00
libcec: repaired detection of logical address; prevent that amlogic adapter hangs on close
This commit is contained in:
parent
14b0ed1abe
commit
4344e2a16b
@ -1,36 +1,7 @@
|
||||
diff -Nur -x .cproject -x .project -x .settings libcec-3.0.1/include/cectypes.h libcec-3.0.1-with-amlogic-adapter/include/cectypes.h
|
||||
--- libcec-3.0.1/include/cectypes.h 2016-02-21 01:11:20.791177759 +0100
|
||||
+++ libcec-3.0.1-with-amlogic-adapter/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 -x .cproject -x .project -x .settings libcec-3.0.1/README.md libcec-3.0.1-with-amlogic-adapter/README.md
|
||||
--- libcec-3.0.1/README.md 2015-07-03 19:20:49.000000000 +0200
|
||||
+++ libcec-3.0.1-with-amlogic-adapter/README.md 2016-02-10 12:03:54.517523977 +0100
|
||||
diff --git a/README.md b/README.md
|
||||
index dfaf4d6..0dffdcf 100644
|
||||
--- a/README.md
|
||||
+++ b/README.md
|
||||
@@ -58,6 +58,12 @@
|
||||
cmake -DHAVE_EXYNOS_API=1 ..
|
||||
```
|
||||
@ -44,9 +15,54 @@ diff -Nur -x .cproject -x .project -x .settings libcec-3.0.1/README.md libcec-3.
|
||||
## TDA995x ##
|
||||
To compile in support for TDA995x devices, you have to pass the argument -DHAVE_TDA995X_API=1 to cmake:
|
||||
```
|
||||
diff -Nur -x .cproject -x .project -x .settings libcec-3.0.1/src/libcec/adapter/AdapterFactory.cpp libcec-3.0.1-with-amlogic-adapter/src/libcec/adapter/AdapterFactory.cpp
|
||||
--- libcec-3.0.1/src/libcec/adapter/AdapterFactory.cpp 2016-02-21 01:11:12.579266950 +0100
|
||||
+++ libcec-3.0.1-with-amlogic-adapter/src/libcec/adapter/AdapterFactory.cpp 2016-02-10 12:41:44.252060917 +0100
|
||||
diff --git a/include/cectypes.h b/include/cectypes.h
|
||||
index e28c8df..c0b9476 100644
|
||||
--- a/include/cectypes.h
|
||||
+++ b/include/cectypes.h
|
||||
@@ -318,6 +318,15 @@ namespace CEC {
|
||||
*/
|
||||
#define CEC_IMX_VIRTUAL_COM "i.MX"
|
||||
|
||||
+/*!
|
||||
+ * 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
|
||||
@@ -889,7 +898,8 @@ typedef enum cec_adapter_type
|
||||
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 --git a/src/libcec/CMakeLists.txt b/src/libcec/CMakeLists.txt
|
||||
index a494533..e94b094 100644
|
||||
--- a/src/libcec/CMakeLists.txt
|
||||
+++ b/src/libcec/CMakeLists.txt
|
||||
@@ -87,6 +87,9 @@ set(CEC_HEADERS devices/CECRecordingDevice.h
|
||||
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 --git a/src/libcec/adapter/AdapterFactory.cpp b/src/libcec/adapter/AdapterFactory.cpp
|
||||
index 92e378b..55703b9 100644
|
||||
--- a/src/libcec/adapter/AdapterFactory.cpp
|
||||
+++ b/src/libcec/adapter/AdapterFactory.cpp
|
||||
@@ -63,6 +63,11 @@
|
||||
#include "IMX/IMXCECAdapterCommunication.h"
|
||||
#endif
|
||||
@ -59,7 +75,16 @@ diff -Nur -x .cproject -x .project -x .settings libcec-3.0.1/src/libcec/adapter/
|
||||
using namespace CEC;
|
||||
|
||||
int8_t CAdapterFactory::FindAdapters(cec_adapter *deviceList, uint8_t iBufSize, const char *strDevicePath /* = NULL */)
|
||||
@@ -131,6 +136,18 @@
|
||||
@@ -131,8 +136,6 @@ int8_t CAdapterFactory::DetectAdapters(cec_adapter_descriptor *deviceList, uint8
|
||||
}
|
||||
#endif
|
||||
|
||||
-
|
||||
-
|
||||
#if defined(HAVE_IMX_API)
|
||||
if (iAdaptersFound < iBufSize && CIMXCECAdapterDetection::FindAdapter() &&
|
||||
(!strDevicePath || !strcmp(strDevicePath, CEC_IMX_VIRTUAL_COM)))
|
||||
@@ -146,8 +149,20 @@ int8_t CAdapterFactory::DetectAdapters(cec_adapter_descriptor *deviceList, uint8
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -74,12 +99,15 @@ diff -Nur -x .cproject -x .project -x .settings libcec-3.0.1/src/libcec/adapter/
|
||||
+ iAdaptersFound++;
|
||||
+ }
|
||||
+#endif
|
||||
|
||||
-#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_IMX_API)
|
||||
+
|
||||
+#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_IMX_API) && !defined(HAVE_AMLOGIC_API)
|
||||
#error "libCEC doesn't have support for any type of adapter. please check your build system or configuration"
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(HAVE_IMX_API)
|
||||
@@ -166,6 +183,11 @@
|
||||
return new CExynosCECAdapterCommunication(m_lib->m_cec);
|
||||
@@ -176,11 +191,16 @@ IAdapterCommunication *CAdapterFactory::GetInstance(const char *strPort, uint16_
|
||||
return new CIMXCECAdapterCommunication(m_lib->m_cec);
|
||||
#endif
|
||||
|
||||
+#if defined(HAVE_AMLOGIC_API)
|
||||
@ -87,22 +115,68 @@ diff -Nur -x .cproject -x .project -x .settings libcec-3.0.1/src/libcec/adapter/
|
||||
+ 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 @@
|
||||
#if defined(HAVE_P8_USB)
|
||||
return new CUSBCECAdapterCommunication(m_lib->m_cec, strPort, iBaudRate);
|
||||
#endif
|
||||
|
||||
-#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_EXYNOS_API) && !defined(HAVE_IMX_API)
|
||||
+#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_EXYNOS_API) && !defined(HAVE_IMX_API) && !defined(HAVE_AMLOGIC_API)
|
||||
+#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_EXYNOS_API) && !defined(HAVE_IMX_API) && !defined(HAVE_AMLOGIC_API)
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
diff -Nur -x .cproject -x .project -x .settings libcec-3.0.1/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.cpp libcec-3.0.1-with-amlogic-adapter/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.cpp
|
||||
--- libcec-3.0.1/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.cpp 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ libcec-3.0.1-with-amlogic-adapter/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.cpp 2016-02-28 12:31:26.771045268 +0100
|
||||
@@ -0,0 +1,298 @@
|
||||
diff --git a/src/libcec/adapter/Amlogic/AmlogicCEC.h b/src/libcec/adapter/Amlogic/AmlogicCEC.h
|
||||
new file mode 100644
|
||||
index 0000000..7b86982
|
||||
--- /dev/null
|
||||
+++ b/src/libcec/adapter/Amlogic/AmlogicCEC.h
|
||||
@@ -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 --git a/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.cpp b/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.cpp
|
||||
new file mode 100644
|
||||
index 0000000..5aeddda
|
||||
--- /dev/null
|
||||
+++ b/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.cpp
|
||||
@@ -0,0 +1,305 @@
|
||||
+/*
|
||||
+ * This file is part of the libCEC(R) library.
|
||||
+ *
|
||||
@ -346,6 +420,7 @@ diff -Nur -x .cproject -x .project -x .settings libcec-3.0.1/src/libcec/adapter/
|
||||
+ uint32_t size;
|
||||
+ fd_set rfds;
|
||||
+ cec_logical_address initiator, destination;
|
||||
+ struct timeval tv;
|
||||
+
|
||||
+ if (!IsOpen())
|
||||
+ return 0;
|
||||
@ -362,8 +437,15 @@ diff -Nur -x .cproject -x .project -x .settings libcec-3.0.1/src/libcec/adapter/
|
||||
+ FD_ZERO(&rfds);
|
||||
+ FD_SET(fd, &rfds);
|
||||
+
|
||||
+ if (select(fd + 1, &rfds, NULL, NULL, NULL) >= 0 )
|
||||
+ tv.tv_sec = 1;
|
||||
+ tv.tv_usec = 0;
|
||||
+
|
||||
+ if (select(fd + 1, &rfds, NULL, NULL, &tv) >= 0 )
|
||||
+ {
|
||||
+
|
||||
+ if (!FD_ISSET(fd, &rfds))
|
||||
+ continue;
|
||||
+
|
||||
+ size = read(fd, buffer, CEC_MAX_FRAME_SIZE);
|
||||
+
|
||||
+ if (size > 0)
|
||||
@ -394,16 +476,17 @@ diff -Nur -x .cproject -x .project -x .settings libcec-3.0.1/src/libcec/adapter/
|
||||
+ m_callback->OnCommandReceived(cmd);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#endif // HAVE_AMLOGIC_API
|
||||
diff -Nur -x .cproject -x .project -x .settings libcec-3.0.1/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.h libcec-3.0.1-with-amlogic-adapter/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.h
|
||||
--- libcec-3.0.1/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.h 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ libcec-3.0.1-with-amlogic-adapter/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.h 2016-02-28 12:16:30.985474428 +0100
|
||||
diff --git a/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.h b/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.h
|
||||
new file mode 100644
|
||||
index 0000000..0e99cf8
|
||||
--- /dev/null
|
||||
+++ b/src/libcec/adapter/Amlogic/AmlogicCECAdapterCommunication.h
|
||||
@@ -0,0 +1,105 @@
|
||||
+#pragma once
|
||||
+/*
|
||||
@ -510,9 +593,11 @@ diff -Nur -x .cproject -x .project -x .settings libcec-3.0.1/src/libcec/adapter/
|
||||
+ };
|
||||
+};
|
||||
+#endif
|
||||
diff -Nur -x .cproject -x .project -x .settings libcec-3.0.1/src/libcec/adapter/Amlogic/AmlogicCECAdapterDetection.cpp libcec-3.0.1-with-amlogic-adapter/src/libcec/adapter/Amlogic/AmlogicCECAdapterDetection.cpp
|
||||
--- libcec-3.0.1/src/libcec/adapter/Amlogic/AmlogicCECAdapterDetection.cpp 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ libcec-3.0.1-with-amlogic-adapter/src/libcec/adapter/Amlogic/AmlogicCECAdapterDetection.cpp 2016-02-10 11:57:58.445532459 +0100
|
||||
diff --git a/src/libcec/adapter/Amlogic/AmlogicCECAdapterDetection.cpp b/src/libcec/adapter/Amlogic/AmlogicCECAdapterDetection.cpp
|
||||
new file mode 100644
|
||||
index 0000000..2247346
|
||||
--- /dev/null
|
||||
+++ b/src/libcec/adapter/Amlogic/AmlogicCECAdapterDetection.cpp
|
||||
@@ -0,0 +1,50 @@
|
||||
+/*
|
||||
+ * This file is part of the libCEC(R) library.
|
||||
@ -564,9 +649,11 @@ diff -Nur -x .cproject -x .project -x .settings libcec-3.0.1/src/libcec/adapter/
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
diff -Nur -x .cproject -x .project -x .settings libcec-3.0.1/src/libcec/adapter/Amlogic/AmlogicCECAdapterDetection.h libcec-3.0.1-with-amlogic-adapter/src/libcec/adapter/Amlogic/AmlogicCECAdapterDetection.h
|
||||
--- libcec-3.0.1/src/libcec/adapter/Amlogic/AmlogicCECAdapterDetection.h 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ libcec-3.0.1-with-amlogic-adapter/src/libcec/adapter/Amlogic/AmlogicCECAdapterDetection.h 2016-02-10 11:57:58.445532459 +0100
|
||||
diff --git a/src/libcec/adapter/Amlogic/AmlogicCECAdapterDetection.h b/src/libcec/adapter/Amlogic/AmlogicCECAdapterDetection.h
|
||||
new file mode 100644
|
||||
index 0000000..8a7418d
|
||||
--- /dev/null
|
||||
+++ b/src/libcec/adapter/Amlogic/AmlogicCECAdapterDetection.h
|
||||
@@ -0,0 +1,46 @@
|
||||
+#pragma once
|
||||
+/*
|
||||
@ -614,54 +701,10 @@ diff -Nur -x .cproject -x .project -x .settings libcec-3.0.1/src/libcec/adapter/
|
||||
+ static bool FindAdapter(void);
|
||||
+ };
|
||||
+}
|
||||
diff -Nur -x .cproject -x .project -x .settings libcec-3.0.1/src/libcec/adapter/Amlogic/AmlogicCEC.h libcec-3.0.1-with-amlogic-adapter/src/libcec/adapter/Amlogic/AmlogicCEC.h
|
||||
--- libcec-3.0.1/src/libcec/adapter/Amlogic/AmlogicCEC.h 1970-01-01 01:00:00.000000000 +0100
|
||||
+++ libcec-3.0.1-with-amlogic-adapter/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 -x .cproject -x .project -x .settings libcec-3.0.1/src/libcec/cmake/CheckPlatformSupport.cmake libcec-3.0.1-with-amlogic-adapter/src/libcec/cmake/CheckPlatformSupport.cmake
|
||||
--- libcec-3.0.1/src/libcec/cmake/CheckPlatformSupport.cmake 2016-02-21 01:11:12.579266950 +0100
|
||||
+++ libcec-3.0.1-with-amlogic-adapter/src/libcec/cmake/CheckPlatformSupport.cmake 2016-02-10 13:18:20.847385373 +0100
|
||||
diff --git a/src/libcec/cmake/CheckPlatformSupport.cmake b/src/libcec/cmake/CheckPlatformSupport.cmake
|
||||
index dc5bc25..64003d9 100644
|
||||
--- a/src/libcec/cmake/CheckPlatformSupport.cmake
|
||||
+++ b/src/libcec/cmake/CheckPlatformSupport.cmake
|
||||
@@ -11,6 +11,7 @@
|
||||
# HAVE_IMX_API 1 if i.MX is supported
|
||||
# HAVE_TDA995X_API 1 if TDA995X is supported
|
||||
@ -670,7 +713,7 @@ diff -Nur -x .cproject -x .project -x .settings libcec-3.0.1/src/libcec/cmake/Ch
|
||||
# HAVE_P8_USB_DETECT 1 if Pulse-Eight devices can be auto-detected
|
||||
#
|
||||
|
||||
@@ -129,6 +130,18 @@
|
||||
@@ -142,6 +143,18 @@ else()
|
||||
else()
|
||||
set(HAVE_EXYNOS_API 0)
|
||||
endif()
|
||||
@ -689,11 +732,12 @@ diff -Nur -x .cproject -x .project -x .settings libcec-3.0.1/src/libcec/cmake/Ch
|
||||
endif()
|
||||
|
||||
# rt
|
||||
diff -Nur -x .cproject -x .project -x .settings libcec-3.0.1/src/libcec/cmake/DisplayPlatformSupport.cmake libcec-3.0.1-with-amlogic-adapter/src/libcec/cmake/DisplayPlatformSupport.cmake
|
||||
--- libcec-3.0.1/src/libcec/cmake/DisplayPlatformSupport.cmake 2016-02-21 01:11:12.579266950 +0100
|
||||
+++ libcec-3.0.1-with-amlogic-adapter/src/libcec/cmake/DisplayPlatformSupport.cmake 2016-02-10 12:47:10.380408360 +0100
|
||||
@@ -50,6 +50,12 @@
|
||||
message(STATUS "Exynos support: no")
|
||||
diff --git a/src/libcec/cmake/DisplayPlatformSupport.cmake b/src/libcec/cmake/DisplayPlatformSupport.cmake
|
||||
index 4e24def..1890cac 100644
|
||||
--- a/src/libcec/cmake/DisplayPlatformSupport.cmake
|
||||
+++ b/src/libcec/cmake/DisplayPlatformSupport.cmake
|
||||
@@ -50,6 +50,12 @@ else()
|
||||
message(STATUS "DRM support: no")
|
||||
endif()
|
||||
|
||||
+if (HAVE_AMLOGIC_API)
|
||||
@ -705,23 +749,11 @@ diff -Nur -x .cproject -x .project -x .settings libcec-3.0.1/src/libcec/cmake/Di
|
||||
if (HAVE_PYTHON)
|
||||
message(STATUS "Python support: version ${PYTHONLIBS_VERSION_STRING} (${PYTHON_VERSION})")
|
||||
else()
|
||||
diff -Nur -x .cproject -x .project -x .settings libcec-3.0.1/src/libcec/CMakeLists.txt libcec-3.0.1-with-amlogic-adapter/src/libcec/CMakeLists.txt
|
||||
--- libcec-3.0.1/src/libcec/CMakeLists.txt 2015-07-03 19:20:49.000000000 +0200
|
||||
+++ libcec-3.0.1-with-amlogic-adapter/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 -x .cproject -x .project -x .settings libcec-3.0.1/src/libcec/env.h.in libcec-3.0.1-with-amlogic-adapter/src/libcec/env.h.in
|
||||
--- libcec-3.0.1/src/libcec/env.h.in 2016-02-21 01:11:12.579266950 +0100
|
||||
+++ libcec-3.0.1-with-amlogic-adapter/src/libcec/env.h.in 2016-02-10 11:57:58.449532413 +0100
|
||||
@@ -69,6 +69,9 @@
|
||||
diff --git a/src/libcec/env.h.in b/src/libcec/env.h.in
|
||||
index 384f1c7..c3f00bc 100644
|
||||
--- a/src/libcec/env.h.in
|
||||
+++ b/src/libcec/env.h.in
|
||||
@@ -75,6 +75,9 @@
|
||||
/* Define to 1 for Exynos support */
|
||||
#cmakedefine HAVE_EXYNOS_API @HAVE_EXYNOS_API@
|
||||
|
||||
|
@ -55,10 +55,10 @@ index 7a944cd..f74ec1f 100755
|
||||
#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..bd31aaa
|
||||
index 0000000..a3556b3
|
||||
--- /dev/null
|
||||
+++ b/drivers/amlogic/hdmi/hdmi_tx/amlogic_cec.c
|
||||
@@ -0,0 +1,596 @@
|
||||
@@ -0,0 +1,671 @@
|
||||
+/* linux/drivers/amlogic/hdmi/hdmi_tx/amlogic_cec.c
|
||||
+ *
|
||||
+ * Copyright (c) 2016 Gerald Dachs
|
||||
@ -84,6 +84,7 @@ index 0000000..bd31aaa
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/atomic.h>
|
||||
+#include <linux/semaphore.h>
|
||||
+
|
||||
+#include <asm/uaccess.h>
|
||||
+#include <asm/delay.h>
|
||||
@ -127,6 +128,8 @@ index 0000000..bd31aaa
|
||||
+/* CEC Tx buffer size */
|
||||
+#define CEC_TX_BUFF_SIZE 16
|
||||
+
|
||||
+static DEFINE_SEMAPHORE(init_mutex);
|
||||
+
|
||||
+struct cec_rx_list {
|
||||
+ u8 buffer[CEC_RX_BUFF_SIZE];
|
||||
+ unsigned char size;
|
||||
@ -226,7 +229,7 @@ index 0000000..bd31aaa
|
||||
+ rx_msg_status = amlogic_cec_read_reg(CEC_RX_MSG_STATUS);
|
||||
+ rx_num_msg = amlogic_cec_read_reg(CEC_RX_NUM_MSG);
|
||||
+
|
||||
+ amlogic_cec_log_dbg("amlogic_cec_read_hw: enter: CEC_RX_MSG_STATUS %d, CEC_RX_NUM_MSG %d\n", rx_msg_status, rx_num_msg);
|
||||
+ amlogic_cec_log_dbg("rx_msg_status: %d, rx_num_msg: %d\n", rx_msg_status, rx_num_msg);
|
||||
+
|
||||
+ valid_msg = (RX_DONE == rx_msg_status) && (1 == rx_num_msg);
|
||||
+
|
||||
@ -248,7 +251,7 @@ index 0000000..bd31aaa
|
||||
+#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
|
||||
+ aml_write_reg32(P_AO_CEC_INTR_CLR, aml_read_reg32(P_AO_CEC_INTR_CLR) | (1 << 2));
|
||||
+#endif
|
||||
+ amlogic_cec_write_reg(CEC_RX_MSG_CMD, RX_ACK_NEXT);
|
||||
+ amlogic_cec_write_reg(CEC_RX_MSG_CMD, valid_msg ? RX_ACK_NEXT : RX_ACK_CURRENT);
|
||||
+ amlogic_cec_write_reg(CEC_RX_MSG_CMD, RX_NO_OP);
|
||||
+
|
||||
+ return ret;
|
||||
@ -290,45 +293,89 @@ index 0000000..bd31aaa
|
||||
+ if (hdmitx_device->hdmi_info.vsdb_phy_addr.valid == 0)
|
||||
+ {
|
||||
+ amlogic_cec_log_dbg("no valid cec physical address\n");
|
||||
+ if (aml_read_reg32(P_AO_DEBUG_REG1))
|
||||
+ if (aml_read_reg32(P_AO_DEBUG_REG1) & 0xffff)
|
||||
+ {
|
||||
+ amlogic_cec_log_dbg("use last physical address\n");
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ aml_write_reg32(P_AO_DEBUG_REG1, 0x1000);
|
||||
+ aml_write_reg32(P_AO_DEBUG_REG1, (aml_read_reg32(P_AO_DEBUG_REG1) & (0xf << 16)) | 0x1000);
|
||||
+ amlogic_cec_log_dbg("use default physical address\n");
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ aml_write_reg32(P_AO_DEBUG_REG1, cec_phy_addr);
|
||||
+ amlogic_cec_log_dbg("physical address:0x%x\n", aml_read_reg32(P_AO_DEBUG_REG1));
|
||||
+
|
||||
+ if ((hdmitx_device->cec_init_ready != 0) && (hdmitx_device->hpd_state != 0))
|
||||
+ {
|
||||
+ if ((entry = kmalloc(sizeof(struct cec_rx_list), GFP_ATOMIC)) == NULL)
|
||||
+ if (cec_global_info.my_node_index)
|
||||
+ {
|
||||
+ // prevent write operations
|
||||
+ if (down_interruptible(&init_mutex))
|
||||
+ {
|
||||
+ amlogic_cec_log_dbg("can't alloc cec_rx_list\n");
|
||||
+ printk(KERN_ERR "[amlogic] ##### cec node init interrupted! #####\n");
|
||||
+ return;
|
||||
+ }
|
||||
+ else
|
||||
+ hdmitx_device->cec_init_ready = 0;
|
||||
+ spin_lock_irqsave(&cec_rx_struct.lock, spin_flags);
|
||||
+
|
||||
+ amlogic_cec_log_dbg("start reset\n");
|
||||
+#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
|
||||
+ aml_write_reg32(P_HDMI_CTRL_PORT, aml_read_reg32(P_HDMI_CTRL_PORT)|(1<<16));
|
||||
+ hdmi_wr_reg(OTHER_BASE_ADDR+HDMI_OTHER_CTRL0, 0xc); //[3]cec_creg_sw_rst [2]cec_sys_sw_rst
|
||||
+
|
||||
+#if 0
|
||||
+ hdmi_wr_reg(CEC0_BASE_ADDR+CEC_TX_CLEAR_BUF, 0x1);
|
||||
+ hdmi_wr_reg(CEC0_BASE_ADDR+CEC_RX_CLEAR_BUF, 0x1);
|
||||
+
|
||||
+ hdmi_wr_reg(CEC0_BASE_ADDR+CEC_TX_CLEAR_BUF, 0x0);
|
||||
+ hdmi_wr_reg(CEC0_BASE_ADDR+CEC_RX_CLEAR_BUF, 0x0);
|
||||
+#endif
|
||||
+
|
||||
+ hdmi_wr_reg(OTHER_BASE_ADDR+HDMI_OTHER_CTRL0, 0x0);
|
||||
+ aml_write_reg32(P_HDMI_CTRL_PORT, aml_read_reg32(P_HDMI_CTRL_PORT)&(~(1<<16)));
|
||||
+ hdmi_wr_reg(CEC0_BASE_ADDR+CEC_CLOCK_DIV_H, 0x00 );
|
||||
+ hdmi_wr_reg(CEC0_BASE_ADDR+CEC_CLOCK_DIV_L, 0xf0 );
|
||||
+
|
||||
+#endif
|
||||
+#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
|
||||
+ // regain rx interrupts
|
||||
+ cec_enable_irq();
|
||||
+#endif
|
||||
+ spin_unlock_irqrestore(&cec_rx_struct.lock, spin_flags);
|
||||
+
|
||||
+ hdmitx_device->cec_init_ready = 1;
|
||||
+
|
||||
+ up(&init_mutex);
|
||||
+ amlogic_cec_log_dbg("stop reset\n");
|
||||
+ }
|
||||
+
|
||||
+ if ((aml_read_reg32(P_AO_DEBUG_REG1) & 0xffff) != cec_phy_addr)
|
||||
+ {
|
||||
+ aml_write_reg32(P_AO_DEBUG_REG1, (aml_read_reg32(P_AO_DEBUG_REG1) & (0xf << 16)) | cec_phy_addr);
|
||||
+ amlogic_cec_log_dbg("physical address:0x%x\n", aml_read_reg32(P_AO_DEBUG_REG1) & 0xffff);
|
||||
+
|
||||
+ if ((hdmitx_device->cec_init_ready != 0) && (hdmitx_device->hpd_state != 0))
|
||||
+ {
|
||||
+ // let the libCEC ask for new physical Address
|
||||
+ entry->buffer[0] = 0xff;
|
||||
+ entry->size = 1;
|
||||
+ INIT_LIST_HEAD(&entry->list);
|
||||
+ if ((entry = kmalloc(sizeof(struct cec_rx_list), GFP_ATOMIC)) == NULL)
|
||||
+ {
|
||||
+ amlogic_cec_log_dbg("can't alloc cec_rx_list\n");
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ // let the libCEC ask for new physical Address
|
||||
+ entry->buffer[0] = 0xff;
|
||||
+ entry->size = 1;
|
||||
+ 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);
|
||||
+ 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);
|
||||
+
|
||||
+ amlogic_cec_log_dbg("trigger libCEC\n");
|
||||
+ wake_up_interruptible(&cec_rx_struct.waitq);
|
||||
+ amlogic_cec_log_dbg("trigger libCEC\n");
|
||||
+ wake_up_interruptible(&cec_rx_struct.waitq);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ amlogic_cec_log_dbg("cec node init: cec features ok !\n");
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t amlogic_cec_irq_handler(int irq, void *dummy)
|
||||
@ -338,7 +385,9 @@ index 0000000..bd31aaa
|
||||
+ unsigned int tx_msg_state;
|
||||
+ unsigned int rx_msg_state;
|
||||
+
|
||||
+#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
|
||||
+ udelay(100); //Delay execution a little. This fixes an issue when HDMI CEC stops working after a while.
|
||||
+#endif
|
||||
+
|
||||
+ tx_msg_state = amlogic_cec_read_reg(CEC_TX_MSG_STATUS);
|
||||
+ rx_msg_state = amlogic_cec_read_reg(CEC_RX_MSG_STATUS);
|
||||
@ -356,9 +405,6 @@ index 0000000..bd31aaa
|
||||
+ case TX_DONE :
|
||||
+ amlogic_cec_set_tx_state(STATE_DONE);
|
||||
+ break;
|
||||
+ default :
|
||||
+ amlogic_cec_log_dbg("unexpected ts message state: 0x%x", tx_msg_state);
|
||||
+ break;
|
||||
+ }
|
||||
+ wake_up_interruptible(&cec_tx_struct.waitq);
|
||||
+ }
|
||||
@ -372,16 +418,18 @@ index 0000000..bd31aaa
|
||||
+ return IRQ_HANDLED;
|
||||
+ }
|
||||
+
|
||||
+ INIT_LIST_HEAD(&entry->list);
|
||||
+
|
||||
+ spin_lock_irqsave(&cec_rx_struct.lock, spin_flags);
|
||||
+
|
||||
+ if ((-1) == amlogic_cec_read_hw(entry->buffer, &entry->size))
|
||||
+ {
|
||||
+ kfree(entry);
|
||||
+ amlogic_cec_log_dbg("amlogic_cec_irq_handler: nothing to read\n");
|
||||
+ spin_unlock_irqrestore(&cec_rx_struct.lock, spin_flags);
|
||||
+ 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);
|
||||
@ -432,21 +480,17 @@ index 0000000..bd31aaa
|
||||
+ 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
|
||||
+ amlogic_cec_write_reg(CEC_LOGICAL_ADDR0, (0x1 << 4) | 0xf);
|
||||
+
|
||||
+ hdmitx_device->cec_init_ready = 1;
|
||||
+
|
||||
+ }
|
||||
@ -463,6 +507,8 @@ index 0000000..bd31aaa
|
||||
+ free_irq(INT_AO_CEC, (void *)hdmitx_device);
|
||||
+#endif
|
||||
+
|
||||
+ amlogic_cec_write_reg(CEC_LOGICAL_ADDR0, (0x1 << 4) | 0xf);
|
||||
+
|
||||
+ atomic_dec(&hdmi_on);
|
||||
+
|
||||
+ return 0;
|
||||
@ -520,6 +566,7 @@ index 0000000..bd31aaa
|
||||
+static ssize_t amlogic_cec_write(struct file *file, const char __user *buffer,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ int retval = count;
|
||||
+ char data[CEC_TX_BUFF_SIZE];
|
||||
+
|
||||
+ /* check data size */
|
||||
@ -534,9 +581,8 @@ index 0000000..bd31aaa
|
||||
+
|
||||
+ amlogic_cec_set_tx_state(STATE_TX);
|
||||
+
|
||||
+ // just for the case that the first write starts
|
||||
+ // before the end of amlogic_cec_delayed_init()
|
||||
+ if (wait_event_interruptible(cec_tx_struct.waitq, hdmitx_device->cec_init_ready == 1))
|
||||
+ // don't write if cec_node_init() is in progress
|
||||
+ if (down_interruptible(&init_mutex))
|
||||
+ {
|
||||
+ amlogic_cec_log_dbg("error during wait on state change\n");
|
||||
+ printk(KERN_ERR "[amlogic] ##### cec write error! #####\n");
|
||||
@ -552,22 +598,27 @@ index 0000000..bd31aaa
|
||||
+ printk(KERN_ERR "[amlogic] ##### cec write error! #####\n");
|
||||
+ amlogic_cec_write_reg(CEC_TX_MSG_CMD, TX_ABORT); // stop cec tx for hw retry.
|
||||
+ amlogic_cec_write_reg(CEC_TX_MSG_CMD, TX_NO_OP);
|
||||
+ return -ERESTARTSYS;
|
||||
+ retval = -ERESTARTSYS;
|
||||
+ goto error_exit;
|
||||
+ }
|
||||
+
|
||||
+ if (atomic_read(&cec_tx_struct.state) != STATE_DONE)
|
||||
+ {
|
||||
+ printk(KERN_ERR "[amlogic] ##### cec write error! #####\n");
|
||||
+ return -1;
|
||||
+ retval = -1;
|
||||
+ }
|
||||
+
|
||||
+ return count;
|
||||
+error_exit:
|
||||
+ up(&init_mutex);
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+static long amlogic_cec_ioctl(struct file *file, unsigned int cmd,
|
||||
+ unsigned long arg)
|
||||
+{
|
||||
+ unsigned char logical_addr;
|
||||
+ unsigned int reg;
|
||||
+
|
||||
+ switch(cmd) {
|
||||
+ case CEC_IOC_SETLADDR:
|
||||
@ -578,12 +629,21 @@ index 0000000..bd31aaa
|
||||
+ }
|
||||
+
|
||||
+ amlogic_cec_write_reg(CEC_LOGICAL_ADDR0, (0x1 << 4) | logical_addr);
|
||||
+ cec_global_info.my_node_index = logical_addr;
|
||||
+ /*
|
||||
+ * use DEBUG_REG1 bit 16 ~ 31 to save logic address.
|
||||
+ * So uboot can use this logic address directly
|
||||
+ */
|
||||
+ reg = (aml_read_reg32(P_AO_DEBUG_REG1) & 0xffff);
|
||||
+ reg |= ((unsigned int)logical_addr) << 16;
|
||||
+ aml_write_reg32(P_AO_DEBUG_REG1, reg);
|
||||
+
|
||||
+ amlogic_cec_log_dbg("amlogic_cec_ioctl: Set logical address: %d\n", logical_addr);
|
||||
+ return 0;
|
||||
+
|
||||
+ case CEC_IOC_GETPADDR:
|
||||
+ amlogic_cec_log_dbg("amlogic_cec_ioctl: return physical address 0x%x\n", aml_read_reg32(P_AO_DEBUG_REG1));
|
||||
+ return aml_read_reg32(P_AO_DEBUG_REG1);
|
||||
+ amlogic_cec_log_dbg("amlogic_cec_ioctl: return physical address 0x%x\n", aml_read_reg32(P_AO_DEBUG_REG1) & 0xffff);
|
||||
+ return aml_read_reg32(P_AO_DEBUG_REG1) & 0xffff;
|
||||
+ }
|
||||
+
|
||||
+ return -EINVAL;
|
||||
@ -618,13 +678,23 @@ index 0000000..bd31aaa
|
||||
+
|
||||
+static int amlogic_cec_init(void)
|
||||
+{
|
||||
+ int retval = 0;
|
||||
+ extern hdmitx_dev_t * get_hdmitx_device(void);
|
||||
+
|
||||
+ if (down_interruptible(&init_mutex))
|
||||
+ {
|
||||
+ return -ERESTARTSYS;
|
||||
+ }
|
||||
+
|
||||
+ INIT_LIST_HEAD(&cec_rx_struct.list);
|
||||
+
|
||||
+ printk("%s, Version: %s\n", banner, VERSION);
|
||||
+
|
||||
+ hdmitx_device = get_hdmitx_device();
|
||||
+ amlogic_cec_log_dbg("CEC init\n");
|
||||
+
|
||||
+ amlogic_cec_write_reg(CEC_LOGICAL_ADDR0, (0x1 << 4) | 0xf);
|
||||
+
|
||||
+#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 );
|
||||
@ -641,10 +711,15 @@ index 0000000..bd31aaa
|
||||
+ if (misc_register(&cec_misc_device))
|
||||
+ {
|
||||
+ printk(KERN_WARNING " Couldn't register device 10, %d.\n", CEC_MINOR);
|
||||
+ return -EBUSY;
|
||||
+ retval = -EBUSY;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+ // release initial lock on init_mutex
|
||||
+ up(&init_mutex);
|
||||
+
|
||||
+ amlogic_cec_log_dbg("CEC init finished: %d\n", retval);
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+static void amlogic_cec_exit(void)
|
||||
|
@ -55,10 +55,10 @@ index 7a944cd..f74ec1f 100755
|
||||
#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..bd31aaa
|
||||
index 0000000..a3556b3
|
||||
--- /dev/null
|
||||
+++ b/drivers/amlogic/hdmi/hdmi_tx/amlogic_cec.c
|
||||
@@ -0,0 +1,596 @@
|
||||
@@ -0,0 +1,671 @@
|
||||
+/* linux/drivers/amlogic/hdmi/hdmi_tx/amlogic_cec.c
|
||||
+ *
|
||||
+ * Copyright (c) 2016 Gerald Dachs
|
||||
@ -84,6 +84,7 @@ index 0000000..bd31aaa
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/atomic.h>
|
||||
+#include <linux/semaphore.h>
|
||||
+
|
||||
+#include <asm/uaccess.h>
|
||||
+#include <asm/delay.h>
|
||||
@ -127,6 +128,8 @@ index 0000000..bd31aaa
|
||||
+/* CEC Tx buffer size */
|
||||
+#define CEC_TX_BUFF_SIZE 16
|
||||
+
|
||||
+static DEFINE_SEMAPHORE(init_mutex);
|
||||
+
|
||||
+struct cec_rx_list {
|
||||
+ u8 buffer[CEC_RX_BUFF_SIZE];
|
||||
+ unsigned char size;
|
||||
@ -226,7 +229,7 @@ index 0000000..bd31aaa
|
||||
+ rx_msg_status = amlogic_cec_read_reg(CEC_RX_MSG_STATUS);
|
||||
+ rx_num_msg = amlogic_cec_read_reg(CEC_RX_NUM_MSG);
|
||||
+
|
||||
+ amlogic_cec_log_dbg("amlogic_cec_read_hw: enter: CEC_RX_MSG_STATUS %d, CEC_RX_NUM_MSG %d\n", rx_msg_status, rx_num_msg);
|
||||
+ amlogic_cec_log_dbg("rx_msg_status: %d, rx_num_msg: %d\n", rx_msg_status, rx_num_msg);
|
||||
+
|
||||
+ valid_msg = (RX_DONE == rx_msg_status) && (1 == rx_num_msg);
|
||||
+
|
||||
@ -248,7 +251,7 @@ index 0000000..bd31aaa
|
||||
+#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
|
||||
+ aml_write_reg32(P_AO_CEC_INTR_CLR, aml_read_reg32(P_AO_CEC_INTR_CLR) | (1 << 2));
|
||||
+#endif
|
||||
+ amlogic_cec_write_reg(CEC_RX_MSG_CMD, RX_ACK_NEXT);
|
||||
+ amlogic_cec_write_reg(CEC_RX_MSG_CMD, valid_msg ? RX_ACK_NEXT : RX_ACK_CURRENT);
|
||||
+ amlogic_cec_write_reg(CEC_RX_MSG_CMD, RX_NO_OP);
|
||||
+
|
||||
+ return ret;
|
||||
@ -290,45 +293,89 @@ index 0000000..bd31aaa
|
||||
+ if (hdmitx_device->hdmi_info.vsdb_phy_addr.valid == 0)
|
||||
+ {
|
||||
+ amlogic_cec_log_dbg("no valid cec physical address\n");
|
||||
+ if (aml_read_reg32(P_AO_DEBUG_REG1))
|
||||
+ if (aml_read_reg32(P_AO_DEBUG_REG1) & 0xffff)
|
||||
+ {
|
||||
+ amlogic_cec_log_dbg("use last physical address\n");
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ aml_write_reg32(P_AO_DEBUG_REG1, 0x1000);
|
||||
+ aml_write_reg32(P_AO_DEBUG_REG1, (aml_read_reg32(P_AO_DEBUG_REG1) & (0xf << 16)) | 0x1000);
|
||||
+ amlogic_cec_log_dbg("use default physical address\n");
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ aml_write_reg32(P_AO_DEBUG_REG1, cec_phy_addr);
|
||||
+ amlogic_cec_log_dbg("physical address:0x%x\n", aml_read_reg32(P_AO_DEBUG_REG1));
|
||||
+
|
||||
+ if ((hdmitx_device->cec_init_ready != 0) && (hdmitx_device->hpd_state != 0))
|
||||
+ {
|
||||
+ if ((entry = kmalloc(sizeof(struct cec_rx_list), GFP_ATOMIC)) == NULL)
|
||||
+ if (cec_global_info.my_node_index)
|
||||
+ {
|
||||
+ // prevent write operations
|
||||
+ if (down_interruptible(&init_mutex))
|
||||
+ {
|
||||
+ amlogic_cec_log_dbg("can't alloc cec_rx_list\n");
|
||||
+ printk(KERN_ERR "[amlogic] ##### cec node init interrupted! #####\n");
|
||||
+ return;
|
||||
+ }
|
||||
+ else
|
||||
+ hdmitx_device->cec_init_ready = 0;
|
||||
+ spin_lock_irqsave(&cec_rx_struct.lock, spin_flags);
|
||||
+
|
||||
+ amlogic_cec_log_dbg("start reset\n");
|
||||
+#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
|
||||
+ aml_write_reg32(P_HDMI_CTRL_PORT, aml_read_reg32(P_HDMI_CTRL_PORT)|(1<<16));
|
||||
+ hdmi_wr_reg(OTHER_BASE_ADDR+HDMI_OTHER_CTRL0, 0xc); //[3]cec_creg_sw_rst [2]cec_sys_sw_rst
|
||||
+
|
||||
+#if 0
|
||||
+ hdmi_wr_reg(CEC0_BASE_ADDR+CEC_TX_CLEAR_BUF, 0x1);
|
||||
+ hdmi_wr_reg(CEC0_BASE_ADDR+CEC_RX_CLEAR_BUF, 0x1);
|
||||
+
|
||||
+ hdmi_wr_reg(CEC0_BASE_ADDR+CEC_TX_CLEAR_BUF, 0x0);
|
||||
+ hdmi_wr_reg(CEC0_BASE_ADDR+CEC_RX_CLEAR_BUF, 0x0);
|
||||
+#endif
|
||||
+
|
||||
+ hdmi_wr_reg(OTHER_BASE_ADDR+HDMI_OTHER_CTRL0, 0x0);
|
||||
+ aml_write_reg32(P_HDMI_CTRL_PORT, aml_read_reg32(P_HDMI_CTRL_PORT)&(~(1<<16)));
|
||||
+ hdmi_wr_reg(CEC0_BASE_ADDR+CEC_CLOCK_DIV_H, 0x00 );
|
||||
+ hdmi_wr_reg(CEC0_BASE_ADDR+CEC_CLOCK_DIV_L, 0xf0 );
|
||||
+
|
||||
+#endif
|
||||
+#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
|
||||
+ // regain rx interrupts
|
||||
+ cec_enable_irq();
|
||||
+#endif
|
||||
+ spin_unlock_irqrestore(&cec_rx_struct.lock, spin_flags);
|
||||
+
|
||||
+ hdmitx_device->cec_init_ready = 1;
|
||||
+
|
||||
+ up(&init_mutex);
|
||||
+ amlogic_cec_log_dbg("stop reset\n");
|
||||
+ }
|
||||
+
|
||||
+ if ((aml_read_reg32(P_AO_DEBUG_REG1) & 0xffff) != cec_phy_addr)
|
||||
+ {
|
||||
+ aml_write_reg32(P_AO_DEBUG_REG1, (aml_read_reg32(P_AO_DEBUG_REG1) & (0xf << 16)) | cec_phy_addr);
|
||||
+ amlogic_cec_log_dbg("physical address:0x%x\n", aml_read_reg32(P_AO_DEBUG_REG1) & 0xffff);
|
||||
+
|
||||
+ if ((hdmitx_device->cec_init_ready != 0) && (hdmitx_device->hpd_state != 0))
|
||||
+ {
|
||||
+ // let the libCEC ask for new physical Address
|
||||
+ entry->buffer[0] = 0xff;
|
||||
+ entry->size = 1;
|
||||
+ INIT_LIST_HEAD(&entry->list);
|
||||
+ if ((entry = kmalloc(sizeof(struct cec_rx_list), GFP_ATOMIC)) == NULL)
|
||||
+ {
|
||||
+ amlogic_cec_log_dbg("can't alloc cec_rx_list\n");
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ // let the libCEC ask for new physical Address
|
||||
+ entry->buffer[0] = 0xff;
|
||||
+ entry->size = 1;
|
||||
+ 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);
|
||||
+ 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);
|
||||
+
|
||||
+ amlogic_cec_log_dbg("trigger libCEC\n");
|
||||
+ wake_up_interruptible(&cec_rx_struct.waitq);
|
||||
+ amlogic_cec_log_dbg("trigger libCEC\n");
|
||||
+ wake_up_interruptible(&cec_rx_struct.waitq);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ amlogic_cec_log_dbg("cec node init: cec features ok !\n");
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t amlogic_cec_irq_handler(int irq, void *dummy)
|
||||
@ -338,7 +385,9 @@ index 0000000..bd31aaa
|
||||
+ unsigned int tx_msg_state;
|
||||
+ unsigned int rx_msg_state;
|
||||
+
|
||||
+#if MESON_CPU_TYPE == MESON_CPU_TYPE_MESON6
|
||||
+ udelay(100); //Delay execution a little. This fixes an issue when HDMI CEC stops working after a while.
|
||||
+#endif
|
||||
+
|
||||
+ tx_msg_state = amlogic_cec_read_reg(CEC_TX_MSG_STATUS);
|
||||
+ rx_msg_state = amlogic_cec_read_reg(CEC_RX_MSG_STATUS);
|
||||
@ -356,9 +405,6 @@ index 0000000..bd31aaa
|
||||
+ case TX_DONE :
|
||||
+ amlogic_cec_set_tx_state(STATE_DONE);
|
||||
+ break;
|
||||
+ default :
|
||||
+ amlogic_cec_log_dbg("unexpected ts message state: 0x%x", tx_msg_state);
|
||||
+ break;
|
||||
+ }
|
||||
+ wake_up_interruptible(&cec_tx_struct.waitq);
|
||||
+ }
|
||||
@ -372,16 +418,18 @@ index 0000000..bd31aaa
|
||||
+ return IRQ_HANDLED;
|
||||
+ }
|
||||
+
|
||||
+ INIT_LIST_HEAD(&entry->list);
|
||||
+
|
||||
+ spin_lock_irqsave(&cec_rx_struct.lock, spin_flags);
|
||||
+
|
||||
+ if ((-1) == amlogic_cec_read_hw(entry->buffer, &entry->size))
|
||||
+ {
|
||||
+ kfree(entry);
|
||||
+ amlogic_cec_log_dbg("amlogic_cec_irq_handler: nothing to read\n");
|
||||
+ spin_unlock_irqrestore(&cec_rx_struct.lock, spin_flags);
|
||||
+ 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);
|
||||
@ -432,21 +480,17 @@ index 0000000..bd31aaa
|
||||
+ 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
|
||||
+ amlogic_cec_write_reg(CEC_LOGICAL_ADDR0, (0x1 << 4) | 0xf);
|
||||
+
|
||||
+ hdmitx_device->cec_init_ready = 1;
|
||||
+
|
||||
+ }
|
||||
@ -463,6 +507,8 @@ index 0000000..bd31aaa
|
||||
+ free_irq(INT_AO_CEC, (void *)hdmitx_device);
|
||||
+#endif
|
||||
+
|
||||
+ amlogic_cec_write_reg(CEC_LOGICAL_ADDR0, (0x1 << 4) | 0xf);
|
||||
+
|
||||
+ atomic_dec(&hdmi_on);
|
||||
+
|
||||
+ return 0;
|
||||
@ -520,6 +566,7 @@ index 0000000..bd31aaa
|
||||
+static ssize_t amlogic_cec_write(struct file *file, const char __user *buffer,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ int retval = count;
|
||||
+ char data[CEC_TX_BUFF_SIZE];
|
||||
+
|
||||
+ /* check data size */
|
||||
@ -534,9 +581,8 @@ index 0000000..bd31aaa
|
||||
+
|
||||
+ amlogic_cec_set_tx_state(STATE_TX);
|
||||
+
|
||||
+ // just for the case that the first write starts
|
||||
+ // before the end of amlogic_cec_delayed_init()
|
||||
+ if (wait_event_interruptible(cec_tx_struct.waitq, hdmitx_device->cec_init_ready == 1))
|
||||
+ // don't write if cec_node_init() is in progress
|
||||
+ if (down_interruptible(&init_mutex))
|
||||
+ {
|
||||
+ amlogic_cec_log_dbg("error during wait on state change\n");
|
||||
+ printk(KERN_ERR "[amlogic] ##### cec write error! #####\n");
|
||||
@ -552,22 +598,27 @@ index 0000000..bd31aaa
|
||||
+ printk(KERN_ERR "[amlogic] ##### cec write error! #####\n");
|
||||
+ amlogic_cec_write_reg(CEC_TX_MSG_CMD, TX_ABORT); // stop cec tx for hw retry.
|
||||
+ amlogic_cec_write_reg(CEC_TX_MSG_CMD, TX_NO_OP);
|
||||
+ return -ERESTARTSYS;
|
||||
+ retval = -ERESTARTSYS;
|
||||
+ goto error_exit;
|
||||
+ }
|
||||
+
|
||||
+ if (atomic_read(&cec_tx_struct.state) != STATE_DONE)
|
||||
+ {
|
||||
+ printk(KERN_ERR "[amlogic] ##### cec write error! #####\n");
|
||||
+ return -1;
|
||||
+ retval = -1;
|
||||
+ }
|
||||
+
|
||||
+ return count;
|
||||
+error_exit:
|
||||
+ up(&init_mutex);
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+static long amlogic_cec_ioctl(struct file *file, unsigned int cmd,
|
||||
+ unsigned long arg)
|
||||
+{
|
||||
+ unsigned char logical_addr;
|
||||
+ unsigned int reg;
|
||||
+
|
||||
+ switch(cmd) {
|
||||
+ case CEC_IOC_SETLADDR:
|
||||
@ -578,12 +629,21 @@ index 0000000..bd31aaa
|
||||
+ }
|
||||
+
|
||||
+ amlogic_cec_write_reg(CEC_LOGICAL_ADDR0, (0x1 << 4) | logical_addr);
|
||||
+ cec_global_info.my_node_index = logical_addr;
|
||||
+ /*
|
||||
+ * use DEBUG_REG1 bit 16 ~ 31 to save logic address.
|
||||
+ * So uboot can use this logic address directly
|
||||
+ */
|
||||
+ reg = (aml_read_reg32(P_AO_DEBUG_REG1) & 0xffff);
|
||||
+ reg |= ((unsigned int)logical_addr) << 16;
|
||||
+ aml_write_reg32(P_AO_DEBUG_REG1, reg);
|
||||
+
|
||||
+ amlogic_cec_log_dbg("amlogic_cec_ioctl: Set logical address: %d\n", logical_addr);
|
||||
+ return 0;
|
||||
+
|
||||
+ case CEC_IOC_GETPADDR:
|
||||
+ amlogic_cec_log_dbg("amlogic_cec_ioctl: return physical address 0x%x\n", aml_read_reg32(P_AO_DEBUG_REG1));
|
||||
+ return aml_read_reg32(P_AO_DEBUG_REG1);
|
||||
+ amlogic_cec_log_dbg("amlogic_cec_ioctl: return physical address 0x%x\n", aml_read_reg32(P_AO_DEBUG_REG1) & 0xffff);
|
||||
+ return aml_read_reg32(P_AO_DEBUG_REG1) & 0xffff;
|
||||
+ }
|
||||
+
|
||||
+ return -EINVAL;
|
||||
@ -618,13 +678,23 @@ index 0000000..bd31aaa
|
||||
+
|
||||
+static int amlogic_cec_init(void)
|
||||
+{
|
||||
+ int retval = 0;
|
||||
+ extern hdmitx_dev_t * get_hdmitx_device(void);
|
||||
+
|
||||
+ if (down_interruptible(&init_mutex))
|
||||
+ {
|
||||
+ return -ERESTARTSYS;
|
||||
+ }
|
||||
+
|
||||
+ INIT_LIST_HEAD(&cec_rx_struct.list);
|
||||
+
|
||||
+ printk("%s, Version: %s\n", banner, VERSION);
|
||||
+
|
||||
+ hdmitx_device = get_hdmitx_device();
|
||||
+ amlogic_cec_log_dbg("CEC init\n");
|
||||
+
|
||||
+ amlogic_cec_write_reg(CEC_LOGICAL_ADDR0, (0x1 << 4) | 0xf);
|
||||
+
|
||||
+#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 );
|
||||
@ -641,10 +711,15 @@ index 0000000..bd31aaa
|
||||
+ if (misc_register(&cec_misc_device))
|
||||
+ {
|
||||
+ printk(KERN_WARNING " Couldn't register device 10, %d.\n", CEC_MINOR);
|
||||
+ return -EBUSY;
|
||||
+ retval = -EBUSY;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+ // release initial lock on init_mutex
|
||||
+ up(&init_mutex);
|
||||
+
|
||||
+ amlogic_cec_log_dbg("CEC init finished: %d\n", retval);
|
||||
+
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+static void amlogic_cec_exit(void)
|
||||
|
Loading…
x
Reference in New Issue
Block a user