mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-24 11:16:51 +00:00
projects/Cuboxi: added patches from wolfgar and mk1. fixing CEC on Cuboxi
This commit is contained in:
parent
04950dea4c
commit
9e09602b50
@ -52,7 +52,7 @@ else
|
||||
fi
|
||||
|
||||
if [ "$XBMCPLAYER_DRIVER" = "libfslvpuwrap" ]; then
|
||||
PKG_CONFIGURE_OPTS_TARGET="$PKG_CONFIGURE_OPTS_TARGET --disable-imx6"
|
||||
PKG_CONFIGURE_OPTS_TARGET="$PKG_CONFIGURE_OPTS_TARGET --enable-imx6"
|
||||
else
|
||||
PKG_CONFIGURE_OPTS_TARGET="$PKG_CONFIGURE_OPTS_TARGET --disable-imx6"
|
||||
fi
|
||||
|
214
projects/Cuboxi/patches/libcec/libcec-02-mk1-cec-fix.patch
Normal file
214
projects/Cuboxi/patches/libcec/libcec-02-mk1-cec-fix.patch
Normal file
@ -0,0 +1,214 @@
|
||||
From d821a5f9b03a436950570ee9d7741452248f72e8 Mon Sep 17 00:00:00 2001
|
||||
From: wolfgar <stephan.rafin@laposte.net>
|
||||
Date: Wed, 23 Apr 2014 03:16:04 +0200
|
||||
Subject: [PATCH 1/2] Fix physical address retrieval and notify new address
|
||||
after unplug/plug
|
||||
|
||||
---
|
||||
src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp | 13 ++++++++++++-
|
||||
1 file changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp b/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp
|
||||
index 54e5662..a226a70 100644
|
||||
--- a/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp
|
||||
+++ b/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp
|
||||
@@ -189,14 +189,18 @@ cec_vendor_id CIMXCECAdapterCommunication::GetVendorId(void)
|
||||
uint16_t CIMXCECAdapterCommunication::GetPhysicalAddress(void)
|
||||
{
|
||||
uint32_t info;
|
||||
+ uint16_t phy_addr;
|
||||
|
||||
if (m_dev->Ioctl(HDMICEC_IOC_GETPHYADDRESS, &info) != 0)
|
||||
{
|
||||
LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: HDMICEC_IOC_GETPHYADDRESS failed !", __func__);
|
||||
return CEC_INVALID_PHYSICAL_ADDRESS;
|
||||
}
|
||||
+ /* Rebuild 16 bit raw value from fsl 32 bits value */
|
||||
+ phy_addr = ((info & 0x0f) << 12) | (info & 0x0f00) |
|
||||
+ ((info & 0x0f0000) >> 12) | ((info & 0x0f000000) >> 24);
|
||||
|
||||
- return info;
|
||||
+ return phy_addr;
|
||||
}
|
||||
|
||||
|
||||
@@ -266,6 +270,13 @@ void *CIMXCECAdapterCommunication::Process(void)
|
||||
if (!IsStopped())
|
||||
m_callback->OnCommandReceived(cmd);
|
||||
}
|
||||
+
|
||||
+ if (event.event_type == MESSAGE_TYPE_CONNECTED)
|
||||
+ /* HDMI has just been reconnected - Notify phy address*/
|
||||
+ {
|
||||
+ uint16_t iNewAddress = GetPhysicalAddress();
|
||||
+ m_callback->HandlePhysicalAddressChanged(iNewAddress);
|
||||
+ }
|
||||
/* We are not interested in other events */
|
||||
} /*else {
|
||||
LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s: Read returned %d", __func__, ret);
|
||||
--
|
||||
1.7.9.5
|
||||
|
||||
|
||||
From 42c3c07a79b8155635851c2eed9558b221b89047 Mon Sep 17 00:00:00 2001
|
||||
From: wolfgar <stephan.rafin@laposte.net>
|
||||
Date: Sat, 26 Apr 2014 01:48:06 +0200
|
||||
Subject: [PATCH 2/2] Grab enhancements from mk01 commit
|
||||
https://github.com/mk01/libcec/commit/40ac7550fe22a9fed665eec0aec1882498f838d6#diff-f2ea3f151edca2fc91b2f3cea1159c9bR336
|
||||
|
||||
---
|
||||
src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp | 58 ++++++++++++++++----
|
||||
src/lib/adapter/IMX/IMXCECAdapterCommunication.h | 9 ++-
|
||||
2 files changed, 55 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp b/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp
|
||||
index a226a70..1f70989 100644
|
||||
--- a/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp
|
||||
+++ b/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp
|
||||
@@ -88,6 +88,8 @@ CIMXCECAdapterCommunication::CIMXCECAdapterCommunication(IAdapterCommunicationCa
|
||||
m_iNextMessage = 0;
|
||||
//m_logicalAddresses.Clear();
|
||||
m_logicalAddress = CECDEVICE_UNKNOWN;
|
||||
+ m_bLogicalAddressRegistered = false;
|
||||
+ m_bInitialised = false;
|
||||
m_dev = new CCDevSocket(CEC_IMX_PATH);
|
||||
}
|
||||
|
||||
@@ -110,10 +112,11 @@ bool CIMXCECAdapterCommunication::Open(uint32_t iTimeoutMs, bool UNUSED(bSkipChe
|
||||
if (m_dev->Open(iTimeoutMs))
|
||||
{
|
||||
if (!bStartListening || CreateThread()) {
|
||||
- if (m_dev->Ioctl(HDMICEC_IOC_STARTDEVICE, NULL) != 0) {
|
||||
- LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: Unable to start device\n", __func__);
|
||||
+ if (m_dev->Ioctl(HDMICEC_IOC_STARTDEVICE, NULL) == 0) {
|
||||
+ m_bInitialised = true;
|
||||
+ return true;
|
||||
}
|
||||
- return true;
|
||||
+ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: Unable to start device\n", __func__);
|
||||
}
|
||||
m_dev->Close();
|
||||
}
|
||||
@@ -125,10 +128,16 @@ bool CIMXCECAdapterCommunication::Open(uint32_t iTimeoutMs, bool UNUSED(bSkipChe
|
||||
void CIMXCECAdapterCommunication::Close(void)
|
||||
{
|
||||
StopThread(0);
|
||||
+
|
||||
+ CLockObject lock(m_mutex);
|
||||
+ if (!m_bInitialised) {
|
||||
+ return;
|
||||
+ }
|
||||
if (m_dev->Ioctl(HDMICEC_IOC_STOPDEVICE, NULL) != 0) {
|
||||
LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: Unable to stop device\n", __func__);
|
||||
}
|
||||
m_dev->Close();
|
||||
+ m_bInitialised = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -210,31 +219,60 @@ cec_logical_addresses CIMXCECAdapterCommunication::GetLogicalAddresses(void)
|
||||
addresses.Clear();
|
||||
|
||||
CLockObject lock(m_mutex);
|
||||
- if ( m_logicalAddress != CECDEVICE_UNKNOWN)
|
||||
+ if ((m_logicalAddress & (CECDEVICE_UNKNOWN | CECDEVICE_UNREGISTERED)) == 0)
|
||||
addresses.Set(m_logicalAddress);
|
||||
|
||||
return addresses;
|
||||
}
|
||||
|
||||
+void CIMXCECAdapterCommunication::HandleLogicalAddressLost(cec_logical_address UNUSED(oldAddress))
|
||||
+{
|
||||
+ UnregisterLogicalAddress();
|
||||
+}
|
||||
|
||||
-bool CIMXCECAdapterCommunication::SetLogicalAddresses(const cec_logical_addresses &addresses)
|
||||
+bool CIMXCECAdapterCommunication::UnregisterLogicalAddress(void)
|
||||
{
|
||||
- int log_addr = addresses.primary;
|
||||
+ CLockObject lock(m_mutex);
|
||||
+ if (!m_bLogicalAddressRegistered)
|
||||
+ return true;
|
||||
+
|
||||
+ if (m_dev->Ioctl(HDMICEC_IOC_SETLOGICALADDRESS, (void *)CECDEVICE_BROADCAST) != 0)
|
||||
+ {
|
||||
+ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: HDMICEC_IOC_SETLOGICALADDRESS failed !", __func__);
|
||||
+ return false;
|
||||
+ }
|
||||
|
||||
+ m_logicalAddress = CECDEVICE_UNKNOWN;
|
||||
+ m_bLogicalAddressRegistered = false;
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+bool CIMXCECAdapterCommunication::RegisterLogicalAddress(const cec_logical_address address)
|
||||
+{
|
||||
CLockObject lock(m_mutex);
|
||||
- if (m_logicalAddress == log_addr)
|
||||
- return true;
|
||||
|
||||
- if (m_dev->Ioctl(HDMICEC_IOC_SETLOGICALADDRESS, (void *)log_addr) != 0)
|
||||
+ if (m_logicalAddress == address && m_bLogicalAddressRegistered)
|
||||
+ {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ if (m_dev->Ioctl(HDMICEC_IOC_SETLOGICALADDRESS, (void *)address) != 0)
|
||||
{
|
||||
LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: HDMICEC_IOC_SETLOGICALADDRESS failed !", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
- m_logicalAddress = (cec_logical_address)log_addr;
|
||||
+ m_logicalAddress = address;
|
||||
+ m_bLogicalAddressRegistered = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
+bool CIMXCECAdapterCommunication::SetLogicalAddresses(const cec_logical_addresses &addresses)
|
||||
+{
|
||||
+ int log_addr = addresses.primary;
|
||||
+
|
||||
+ return RegisterLogicalAddress((cec_logical_address)log_addr);
|
||||
+}
|
||||
|
||||
void *CIMXCECAdapterCommunication::Process(void)
|
||||
{
|
||||
diff --git a/src/lib/adapter/IMX/IMXCECAdapterCommunication.h b/src/lib/adapter/IMX/IMXCECAdapterCommunication.h
|
||||
index 910dd39..ce5c4cb 100644
|
||||
--- a/src/lib/adapter/IMX/IMXCECAdapterCommunication.h
|
||||
+++ b/src/lib/adapter/IMX/IMXCECAdapterCommunication.h
|
||||
@@ -85,7 +85,9 @@ namespace CEC
|
||||
cec_adapter_type GetAdapterType(void) { return ADAPTERTYPE_IMX; }
|
||||
uint16_t GetAdapterVendorId(void) const { return IMX_ADAPTER_VID; }
|
||||
uint16_t GetAdapterProductId(void) const { return IMX_ADAPTER_PID; }
|
||||
+ void HandleLogicalAddressLost(cec_logical_address UNUSED(oldAddress));
|
||||
void SetActiveSource(bool UNUSED(bSetTo), bool UNUSED(bClientUnregistered)) {}
|
||||
+ bool RegisterLogicalAddress(const cec_logical_address address);
|
||||
///}
|
||||
|
||||
/** @name PLATFORM::CThread implementation */
|
||||
@@ -94,7 +96,8 @@ namespace CEC
|
||||
///}
|
||||
|
||||
private:
|
||||
- bool IsInitialised(void) const { return m_dev != 0; };
|
||||
+ bool IsInitialised(void) const { return m_bInitialised; };
|
||||
+ bool UnregisterLogicalAddress(void);
|
||||
|
||||
std::string m_strError; /**< current error message */
|
||||
|
||||
@@ -103,7 +106,9 @@ namespace CEC
|
||||
|
||||
PLATFORM::CMutex m_mutex;
|
||||
PLATFORM::CCDevSocket *m_dev; /**< the device connection */
|
||||
-
|
||||
+ bool m_bLogicalAddressRegistered;
|
||||
+ bool m_bInitialised;
|
||||
+
|
||||
PLATFORM::CMutex m_messageMutex;
|
||||
uint32_t m_iNextMessage;
|
||||
std::map<uint32_t, CAdapterMessageQueueEntry *> m_messages;
|
||||
--
|
||||
1.7.9.5
|
||||
|
731
projects/Cuboxi/patches/linux/linux-999.99.22-hdmi-cec.patch
Normal file
731
projects/Cuboxi/patches/linux/linux-999.99.22-hdmi-cec.patch
Normal file
@ -0,0 +1,731 @@
|
||||
From 74fc2e85c080b0ddc2a4b2565eda97c55300303d Mon Sep 17 00:00:00 2001
|
||||
From: wolfgar <stephan.rafin@laposte.net>
|
||||
Date: Sat, 26 Apr 2014 16:50:32 +0200
|
||||
Subject: [PATCH] Merge all CEC driver changes to 3.10 This commit pushes all
|
||||
changes I did in the 3.0.35 kernel to improve/fix its
|
||||
behavior with libcec port for imx6
|
||||
|
||||
It also fixes CEC clock handling in case of FB mode change event
|
||||
and of HDMI cable disconnection
|
||||
---
|
||||
drivers/mxc/hdmi-cec/mxc_hdmi-cec.c | 327 +++++++++++++++--------------------
|
||||
drivers/video/mxc/mxc_hdmi.c | 14 +-
|
||||
2 files changed, 147 insertions(+), 194 deletions(-)
|
||||
|
||||
diff --git a/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c b/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c
|
||||
index d0113ee..3a8aff4 100644
|
||||
--- a/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c
|
||||
+++ b/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c
|
||||
@@ -55,6 +55,8 @@
|
||||
#define MESSAGE_TYPE_CONNECTED 4
|
||||
#define MESSAGE_TYPE_SEND_SUCCESS 5
|
||||
|
||||
+#define CEC_TX_INPROGRESS -1
|
||||
+#define CEC_TX_AVAIL 0
|
||||
|
||||
struct hdmi_cec_priv {
|
||||
int receive_error;
|
||||
@@ -63,7 +65,9 @@ struct hdmi_cec_priv {
|
||||
bool cec_state;
|
||||
u8 last_msg[MAX_MESSAGE_LEN];
|
||||
u8 msg_len;
|
||||
- u8 latest_cec_stat;
|
||||
+ int tx_answer;
|
||||
+ u16 latest_cec_stat;
|
||||
+ u8 link_status;
|
||||
spinlock_t irq_lock;
|
||||
struct delayed_work hdmi_cec_work;
|
||||
struct mutex lock;
|
||||
@@ -76,6 +80,7 @@ struct hdmi_cec_event {
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
+
|
||||
static LIST_HEAD(head);
|
||||
|
||||
static int hdmi_cec_major;
|
||||
@@ -84,11 +89,14 @@ static struct hdmi_cec_priv hdmi_cec_data;
|
||||
static u8 open_count;
|
||||
|
||||
static wait_queue_head_t hdmi_cec_queue;
|
||||
+static wait_queue_head_t tx_cec_queue;
|
||||
+
|
||||
static irqreturn_t mxc_hdmi_cec_isr(int irq, void *data)
|
||||
{
|
||||
struct hdmi_cec_priv *hdmi_cec = data;
|
||||
- u8 cec_stat = 0;
|
||||
+ u16 cec_stat = 0;
|
||||
unsigned long flags;
|
||||
+ u8 phy_stat0;
|
||||
|
||||
spin_lock_irqsave(&hdmi_cec->irq_lock, flags);
|
||||
|
||||
@@ -96,16 +104,24 @@ static irqreturn_t mxc_hdmi_cec_isr(int irq, void *data)
|
||||
|
||||
cec_stat = hdmi_readb(HDMI_IH_CEC_STAT0);
|
||||
hdmi_writeb(cec_stat, HDMI_IH_CEC_STAT0);
|
||||
-
|
||||
+ phy_stat0 = hdmi_readb(HDMI_PHY_STAT0) & 0x02;
|
||||
+ if (hdmi_cec->link_status ^ phy_stat0) {
|
||||
+ /* HPD value changed */
|
||||
+ hdmi_cec->link_status = phy_stat0;
|
||||
+ if (hdmi_cec->link_status)
|
||||
+ cec_stat |= 0x80; /* Connected */
|
||||
+ else
|
||||
+ cec_stat |= 0x100; /* Disconnected */
|
||||
+ }
|
||||
if ((cec_stat & (HDMI_IH_CEC_STAT0_ERROR_INIT | \
|
||||
HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | \
|
||||
- HDMI_IH_CEC_STAT0_DONE)) == 0) {
|
||||
+ HDMI_IH_CEC_STAT0_DONE | 0x180)) == 0) {
|
||||
spin_unlock_irqrestore(&hdmi_cec->irq_lock, flags);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
-
|
||||
pr_debug("HDMI CEC interrupt received\n");
|
||||
- hdmi_cec->latest_cec_stat = cec_stat;
|
||||
+ /* FIXME : there is a race with latest_cec_stat */
|
||||
+ hdmi_cec->latest_cec_stat = cec_stat ;
|
||||
|
||||
schedule_delayed_work(&(hdmi_cec->hdmi_cec_work), msecs_to_jiffies(20));
|
||||
|
||||
@@ -118,115 +134,70 @@ void mxc_hdmi_cec_handle(u16 cec_stat)
|
||||
{
|
||||
u8 val = 0, i = 0;
|
||||
struct hdmi_cec_event *event = NULL;
|
||||
-
|
||||
- /* The current transmission is successful (for initiator only). */
|
||||
+ /*The current transmission is successful (for initiator only).*/
|
||||
if (!open_count)
|
||||
return;
|
||||
|
||||
if (cec_stat & HDMI_IH_CEC_STAT0_DONE) {
|
||||
-
|
||||
- event = vmalloc(sizeof(struct hdmi_cec_event));
|
||||
- if (NULL == event) {
|
||||
- pr_err("%s: Not enough memory!\n", __func__);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- memset(event, 0, sizeof(struct hdmi_cec_event));
|
||||
- event->event_type = MESSAGE_TYPE_SEND_SUCCESS;
|
||||
-
|
||||
- mutex_lock(&hdmi_cec_data.lock);
|
||||
- list_add_tail(&event->list, &head);
|
||||
- mutex_unlock(&hdmi_cec_data.lock);
|
||||
-
|
||||
- wake_up(&hdmi_cec_queue);
|
||||
+ hdmi_cec_data.tx_answer = cec_stat;
|
||||
+ wake_up(&tx_cec_queue);
|
||||
}
|
||||
-
|
||||
- /* EOM is detected so that the received data is ready
|
||||
- * in the receiver data buffer
|
||||
- */
|
||||
+ /*EOM is detected so that the received data is ready in the receiver data buffer*/
|
||||
if (cec_stat & HDMI_IH_CEC_STAT0_EOM) {
|
||||
-
|
||||
hdmi_writeb(0x02, HDMI_IH_CEC_STAT0);
|
||||
-
|
||||
event = vmalloc(sizeof(struct hdmi_cec_event));
|
||||
if (NULL == event) {
|
||||
pr_err("%s: Not enough memory!\n", __func__);
|
||||
return;
|
||||
}
|
||||
memset(event, 0, sizeof(struct hdmi_cec_event));
|
||||
-
|
||||
event->msg_len = hdmi_readb(HDMI_CEC_RX_CNT);
|
||||
if (!event->msg_len) {
|
||||
pr_err("%s: Invalid CEC message length!\n", __func__);
|
||||
return;
|
||||
}
|
||||
event->event_type = MESSAGE_TYPE_RECEIVE_SUCCESS;
|
||||
-
|
||||
for (i = 0; i < event->msg_len; i++)
|
||||
event->msg[i] = hdmi_readb(HDMI_CEC_RX_DATA0+i);
|
||||
hdmi_writeb(0x0, HDMI_CEC_LOCK);
|
||||
-
|
||||
mutex_lock(&hdmi_cec_data.lock);
|
||||
list_add_tail(&event->list, &head);
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
-
|
||||
wake_up(&hdmi_cec_queue);
|
||||
}
|
||||
-
|
||||
- /* An error is detected on cec line (for initiator only). */
|
||||
+ /*An error is detected on cec line (for initiator only). */
|
||||
if (cec_stat & HDMI_IH_CEC_STAT0_ERROR_INIT) {
|
||||
-
|
||||
mutex_lock(&hdmi_cec_data.lock);
|
||||
hdmi_cec_data.send_error++;
|
||||
- if (hdmi_cec_data.send_error > 5) {
|
||||
- pr_err("%s:Re-transmission is attempted more than 5 times!\n",
|
||||
- __func__);
|
||||
+ if (hdmi_cec_data.send_error > 2) {
|
||||
+ pr_err("%s:Re-transmission is attempted more than 2 times!\n", __func__);
|
||||
hdmi_cec_data.send_error = 0;
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
+ hdmi_cec_data.tx_answer = cec_stat;
|
||||
+ wake_up(&tx_cec_queue);
|
||||
return;
|
||||
}
|
||||
-
|
||||
- for (i = 0; i < hdmi_cec_data.msg_len; i++) {
|
||||
- hdmi_writeb(hdmi_cec_data.last_msg[i],
|
||||
- HDMI_CEC_TX_DATA0 + i);
|
||||
- }
|
||||
+ for (i = 0; i < hdmi_cec_data.msg_len; i++)
|
||||
+ hdmi_writeb(hdmi_cec_data.last_msg[i], HDMI_CEC_TX_DATA0+i);
|
||||
hdmi_writeb(hdmi_cec_data.msg_len, HDMI_CEC_TX_CNT);
|
||||
-
|
||||
val = hdmi_readb(HDMI_CEC_CTRL);
|
||||
val |= 0x01;
|
||||
hdmi_writeb(val, HDMI_CEC_CTRL);
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
}
|
||||
-
|
||||
- /* A frame is not acknowledged in a directly addressed message.
|
||||
- * Or a frame is negatively acknowledged in
|
||||
- * a broadcast message (for initiator only).
|
||||
- */
|
||||
+ /*A frame is not acknowledged in a directly addressed message. Or a frame is negatively acknowledged in
|
||||
+ a broadcast message (for initiator only).*/
|
||||
if (cec_stat & HDMI_IH_CEC_STAT0_NACK) {
|
||||
- event = vmalloc(sizeof(struct hdmi_cec_event));
|
||||
- if (NULL == event) {
|
||||
- pr_err("%s: Not enough memory\n", __func__);
|
||||
- return;
|
||||
- }
|
||||
- memset(event, 0, sizeof(struct hdmi_cec_event));
|
||||
- event->event_type = MESSAGE_TYPE_NOACK;
|
||||
-
|
||||
- mutex_lock(&hdmi_cec_data.lock);
|
||||
- list_add_tail(&event->list, &head);
|
||||
- mutex_unlock(&hdmi_cec_data.lock);
|
||||
-
|
||||
- wake_up(&hdmi_cec_queue);
|
||||
+ hdmi_cec_data.tx_answer = cec_stat;
|
||||
+ wake_up(&tx_cec_queue);
|
||||
}
|
||||
-
|
||||
- /* An error is notified by a follower.
|
||||
- * Abnormal logic data bit error (for follower).
|
||||
- */
|
||||
+ /*An error is notified by a follower. Abnormal logic data bit error (for follower).*/
|
||||
if (cec_stat & HDMI_IH_CEC_STAT0_ERROR_FOLL) {
|
||||
hdmi_cec_data.receive_error++;
|
||||
}
|
||||
-
|
||||
- /* HDMI cable connected */
|
||||
+ /*HDMI cable connected*/
|
||||
if (cec_stat & 0x80) {
|
||||
+ pr_info("HDMI link connected\n");
|
||||
event = vmalloc(sizeof(struct hdmi_cec_event));
|
||||
if (NULL == event) {
|
||||
pr_err("%s: Not enough memory\n", __func__);
|
||||
@@ -234,16 +205,14 @@ void mxc_hdmi_cec_handle(u16 cec_stat)
|
||||
}
|
||||
memset(event, 0, sizeof(struct hdmi_cec_event));
|
||||
event->event_type = MESSAGE_TYPE_CONNECTED;
|
||||
-
|
||||
mutex_lock(&hdmi_cec_data.lock);
|
||||
list_add_tail(&event->list, &head);
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
-
|
||||
wake_up(&hdmi_cec_queue);
|
||||
}
|
||||
-
|
||||
- /* HDMI cable disconnected */
|
||||
+ /*HDMI cable disconnected*/
|
||||
if (cec_stat & 0x100) {
|
||||
+ pr_info("HDMI link disconnected\n");
|
||||
event = vmalloc(sizeof(struct hdmi_cec_event));
|
||||
if (NULL == event) {
|
||||
pr_err("%s: Not enough memory!\n", __func__);
|
||||
@@ -251,30 +220,24 @@ void mxc_hdmi_cec_handle(u16 cec_stat)
|
||||
}
|
||||
memset(event, 0, sizeof(struct hdmi_cec_event));
|
||||
event->event_type = MESSAGE_TYPE_DISCONNECTED;
|
||||
-
|
||||
mutex_lock(&hdmi_cec_data.lock);
|
||||
list_add_tail(&event->list, &head);
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
-
|
||||
wake_up(&hdmi_cec_queue);
|
||||
}
|
||||
-
|
||||
return;
|
||||
}
|
||||
EXPORT_SYMBOL(mxc_hdmi_cec_handle);
|
||||
-
|
||||
static void mxc_hdmi_cec_worker(struct work_struct *work)
|
||||
{
|
||||
u8 val;
|
||||
-
|
||||
mxc_hdmi_cec_handle(hdmi_cec_data.latest_cec_stat);
|
||||
- val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL |
|
||||
- HDMI_IH_CEC_STAT0_ARB_LOST;
|
||||
+ val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL | HDMI_IH_CEC_STAT0_ARB_LOST;
|
||||
hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0);
|
||||
}
|
||||
|
||||
/*!
|
||||
- * @brief open function for vpu file operation
|
||||
+ * @brief open function for cec file operation
|
||||
*
|
||||
* @return 0 on success or negative error code on error
|
||||
*/
|
||||
@@ -285,13 +248,11 @@ static int hdmi_cec_open(struct inode *inode, struct file *filp)
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
-
|
||||
open_count = 1;
|
||||
filp->private_data = (void *)(&hdmi_cec_data);
|
||||
hdmi_cec_data.Logical_address = 15;
|
||||
hdmi_cec_data.cec_state = false;
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -299,36 +260,40 @@ static ssize_t hdmi_cec_read(struct file *file, char __user *buf, size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct hdmi_cec_event *event = NULL;
|
||||
-
|
||||
pr_debug("function : %s\n", __func__);
|
||||
+
|
||||
if (!open_count)
|
||||
return -ENODEV;
|
||||
-
|
||||
mutex_lock(&hdmi_cec_data.lock);
|
||||
if (false == hdmi_cec_data.cec_state) {
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
return -EACCES;
|
||||
}
|
||||
- mutex_unlock(&hdmi_cec_data.lock);
|
||||
|
||||
- /* delete from list */
|
||||
- mutex_lock(&hdmi_cec_data.lock);
|
||||
if (list_empty(&head)) {
|
||||
- mutex_unlock(&hdmi_cec_data.lock);
|
||||
- return -EACCES;
|
||||
+ if (file->f_flags & O_NONBLOCK) {
|
||||
+ mutex_unlock(&hdmi_cec_data.lock);
|
||||
+ return -EAGAIN;
|
||||
+ } else {
|
||||
+ do {
|
||||
+ mutex_unlock(&hdmi_cec_data.lock);
|
||||
+ if (wait_event_interruptible(hdmi_cec_queue, (!list_empty(&head))))
|
||||
+ return -ERESTARTSYS;
|
||||
+ mutex_lock(&hdmi_cec_data.lock);
|
||||
+ } while (list_empty(&head));
|
||||
+ }
|
||||
}
|
||||
+
|
||||
event = list_first_entry(&head, struct hdmi_cec_event, list);
|
||||
list_del(&event->list);
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
-
|
||||
if (copy_to_user(buf, event,
|
||||
- sizeof(struct hdmi_cec_event) - sizeof(struct list_head))) {
|
||||
+ sizeof(struct hdmi_cec_event) - sizeof(struct list_head))) {
|
||||
vfree(event);
|
||||
return -EFAULT;
|
||||
}
|
||||
vfree(event);
|
||||
-
|
||||
- return sizeof(struct hdmi_cec_event);
|
||||
+ return (sizeof(struct hdmi_cec_event) - sizeof(struct list_head));
|
||||
}
|
||||
|
||||
static ssize_t hdmi_cec_write(struct file *file, const char __user *buf,
|
||||
@@ -339,58 +304,77 @@ static ssize_t hdmi_cec_write(struct file *file, const char __user *buf,
|
||||
u8 msg_len = 0, val = 0;
|
||||
|
||||
pr_debug("function : %s\n", __func__);
|
||||
+
|
||||
if (!open_count)
|
||||
return -ENODEV;
|
||||
-
|
||||
mutex_lock(&hdmi_cec_data.lock);
|
||||
if (false == hdmi_cec_data.cec_state) {
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
return -EACCES;
|
||||
}
|
||||
+ /* Ensure that there is only one writer who is the only listener of tx_cec_queue */
|
||||
+ if (hdmi_cec_data.tx_answer != CEC_TX_AVAIL) {
|
||||
+ mutex_unlock(&hdmi_cec_data.lock);
|
||||
+ return -EBUSY;
|
||||
+ }
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
-
|
||||
if (count > MAX_MESSAGE_LEN)
|
||||
return -EINVAL;
|
||||
-
|
||||
- mutex_lock(&hdmi_cec_data.lock);
|
||||
- hdmi_cec_data.send_error = 0;
|
||||
memset(&msg, 0, MAX_MESSAGE_LEN);
|
||||
ret = copy_from_user(&msg, buf, count);
|
||||
- if (ret) {
|
||||
- ret = -EACCES;
|
||||
- goto end;
|
||||
- }
|
||||
-
|
||||
+ if (ret)
|
||||
+ return -EACCES;
|
||||
+ mutex_lock(&hdmi_cec_data.lock);
|
||||
+ hdmi_cec_data.send_error = 0;
|
||||
+ hdmi_cec_data.tx_answer = CEC_TX_INPROGRESS;
|
||||
msg_len = count;
|
||||
hdmi_writeb(msg_len, HDMI_CEC_TX_CNT);
|
||||
- for (i = 0; i < msg_len; i++) {
|
||||
+ for (i = 0; i < msg_len; i++)
|
||||
hdmi_writeb(msg[i], HDMI_CEC_TX_DATA0+i);
|
||||
- }
|
||||
-
|
||||
val = hdmi_readb(HDMI_CEC_CTRL);
|
||||
val |= 0x01;
|
||||
hdmi_writeb(val, HDMI_CEC_CTRL);
|
||||
memcpy(hdmi_cec_data.last_msg, msg, msg_len);
|
||||
hdmi_cec_data.msg_len = msg_len;
|
||||
+ mutex_unlock(&hdmi_cec_data.lock);
|
||||
|
||||
- i = 0;
|
||||
- val = hdmi_readb(HDMI_CEC_CTRL);
|
||||
- while ((val & 0x01) == 0x1) {
|
||||
- msleep(50);
|
||||
- i++;
|
||||
- if (i > 3) {
|
||||
- ret = -EIO;
|
||||
- goto end;
|
||||
- }
|
||||
- val = hdmi_readb(HDMI_CEC_CTRL);
|
||||
+ ret = wait_event_interruptible_timeout(tx_cec_queue, hdmi_cec_data.tx_answer != CEC_TX_INPROGRESS, HZ);
|
||||
+
|
||||
+ if (ret < 0) {
|
||||
+ ret = -ERESTARTSYS;
|
||||
+ goto tx_out;
|
||||
}
|
||||
|
||||
-end:
|
||||
- mutex_unlock(&hdmi_cec_data.lock);
|
||||
+ if (hdmi_cec_data.tx_answer & HDMI_IH_CEC_STAT0_DONE)
|
||||
+ /* msg correctly sent */
|
||||
+ ret = msg_len;
|
||||
+ else
|
||||
+ ret = -EIO;
|
||||
|
||||
+ tx_out:
|
||||
+ hdmi_cec_data.tx_answer = CEC_TX_AVAIL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
+
|
||||
+static void hdmi_stop_device(void)
|
||||
+{
|
||||
+ u8 val;
|
||||
+
|
||||
+ hdmi_writeb(0x10, HDMI_CEC_CTRL);
|
||||
+ val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL | HDMI_IH_CEC_STAT0_ERROR_INIT | HDMI_IH_CEC_STAT0_ARB_LOST | \
|
||||
+ HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | HDMI_IH_CEC_STAT0_DONE;
|
||||
+ hdmi_writeb(val, HDMI_CEC_MASK);
|
||||
+ hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0);
|
||||
+ hdmi_writeb(0x0, HDMI_CEC_POLARITY);
|
||||
+ val = hdmi_readb(HDMI_MC_CLKDIS);
|
||||
+ val |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
|
||||
+ hdmi_writeb(val, HDMI_MC_CLKDIS);
|
||||
+ mutex_lock(&hdmi_cec_data.lock);
|
||||
+ hdmi_cec_data.cec_state = false;
|
||||
+ mutex_unlock(&hdmi_cec_data.lock);
|
||||
+}
|
||||
+
|
||||
/*!
|
||||
* @brief IO ctrl function for vpu file operation
|
||||
* @param cmd IO ctrl command
|
||||
@@ -402,93 +386,59 @@ static long hdmi_cec_ioctl(struct file *filp, u_int cmd,
|
||||
int ret = 0, status = 0;
|
||||
u8 val = 0, msg = 0;
|
||||
struct mxc_edid_cfg hdmi_edid_cfg;
|
||||
-
|
||||
pr_debug("function : %s\n", __func__);
|
||||
if (!open_count)
|
||||
return -ENODEV;
|
||||
-
|
||||
switch (cmd) {
|
||||
case HDMICEC_IOC_SETLOGICALADDRESS:
|
||||
mutex_lock(&hdmi_cec_data.lock);
|
||||
if (false == hdmi_cec_data.cec_state) {
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
+ pr_err("Trying to set logical address while not started\n");
|
||||
return -EACCES;
|
||||
}
|
||||
-
|
||||
hdmi_cec_data.Logical_address = (u8)arg;
|
||||
-
|
||||
if (hdmi_cec_data.Logical_address <= 7) {
|
||||
val = 1 << hdmi_cec_data.Logical_address;
|
||||
hdmi_writeb(val, HDMI_CEC_ADDR_L);
|
||||
hdmi_writeb(0, HDMI_CEC_ADDR_H);
|
||||
- } else if (hdmi_cec_data.Logical_address > 7 &&
|
||||
- hdmi_cec_data.Logical_address <= 15) {
|
||||
+ } else if (hdmi_cec_data.Logical_address > 7 && hdmi_cec_data.Logical_address <= 15) {
|
||||
val = 1 << (hdmi_cec_data.Logical_address - 8);
|
||||
hdmi_writeb(val, HDMI_CEC_ADDR_H);
|
||||
hdmi_writeb(0, HDMI_CEC_ADDR_L);
|
||||
- } else {
|
||||
+ } else
|
||||
ret = -EINVAL;
|
||||
- }
|
||||
-
|
||||
- /* Send Polling message with same source
|
||||
- * and destination address
|
||||
- */
|
||||
+ /*Send Polling message with same source and destination address*/
|
||||
if (0 == ret && 15 != hdmi_cec_data.Logical_address) {
|
||||
- msg = (hdmi_cec_data.Logical_address << 4) |
|
||||
- hdmi_cec_data.Logical_address;
|
||||
+ msg = (hdmi_cec_data.Logical_address << 4)|hdmi_cec_data.Logical_address;
|
||||
hdmi_writeb(1, HDMI_CEC_TX_CNT);
|
||||
hdmi_writeb(msg, HDMI_CEC_TX_DATA0);
|
||||
-
|
||||
val = hdmi_readb(HDMI_CEC_CTRL);
|
||||
val |= 0x01;
|
||||
hdmi_writeb(val, HDMI_CEC_CTRL);
|
||||
}
|
||||
-
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
break;
|
||||
-
|
||||
case HDMICEC_IOC_STARTDEVICE:
|
||||
val = hdmi_readb(HDMI_MC_CLKDIS);
|
||||
val &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
|
||||
hdmi_writeb(val, HDMI_MC_CLKDIS);
|
||||
-
|
||||
hdmi_writeb(0x02, HDMI_CEC_CTRL);
|
||||
-
|
||||
- val = HDMI_IH_CEC_STAT0_ERROR_INIT | HDMI_IH_CEC_STAT0_NACK |
|
||||
- HDMI_IH_CEC_STAT0_EOM | HDMI_IH_CEC_STAT0_DONE;
|
||||
+ /* Force read unlock */
|
||||
+ hdmi_writeb(0x0, HDMI_CEC_LOCK);
|
||||
+ val = HDMI_IH_CEC_STAT0_ERROR_INIT | HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | HDMI_IH_CEC_STAT0_DONE;
|
||||
hdmi_writeb(val, HDMI_CEC_POLARITY);
|
||||
-
|
||||
- val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL |
|
||||
- HDMI_IH_CEC_STAT0_ARB_LOST;
|
||||
+ val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL | HDMI_IH_CEC_STAT0_ARB_LOST;
|
||||
hdmi_writeb(val, HDMI_CEC_MASK);
|
||||
hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0);
|
||||
-
|
||||
+ hdmi_cec_data.link_status = hdmi_readb(HDMI_PHY_STAT0) & 0x02;
|
||||
mutex_lock(&hdmi_cec_data.lock);
|
||||
hdmi_cec_data.cec_state = true;
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
break;
|
||||
-
|
||||
case HDMICEC_IOC_STOPDEVICE:
|
||||
- hdmi_writeb(0x10, HDMI_CEC_CTRL);
|
||||
-
|
||||
- val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL |
|
||||
- HDMI_IH_CEC_STAT0_ERROR_INIT | HDMI_IH_CEC_STAT0_ARB_LOST |
|
||||
- HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM |
|
||||
- HDMI_IH_CEC_STAT0_DONE;
|
||||
- hdmi_writeb(val, HDMI_CEC_MASK);
|
||||
- hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0);
|
||||
-
|
||||
- hdmi_writeb(0x0, HDMI_CEC_POLARITY);
|
||||
-
|
||||
- val = hdmi_readb(HDMI_MC_CLKDIS);
|
||||
- val |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
|
||||
- hdmi_writeb(val, HDMI_MC_CLKDIS);
|
||||
-
|
||||
- mutex_lock(&hdmi_cec_data.lock);
|
||||
- hdmi_cec_data.cec_state = false;
|
||||
- mutex_unlock(&hdmi_cec_data.lock);
|
||||
+ hdmi_stop_device();
|
||||
break;
|
||||
-
|
||||
case HDMICEC_IOC_GETPHYADDRESS:
|
||||
hdmi_get_edid_cfg(&hdmi_edid_cfg);
|
||||
status = copy_to_user((void __user *)arg,
|
||||
@@ -497,29 +447,25 @@ static long hdmi_cec_ioctl(struct file *filp, u_int cmd,
|
||||
if (status)
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
-
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
-
|
||||
- return ret;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
-* @brief Release function for vpu file operation
|
||||
-* @return 0 on success or negative error code on error
|
||||
-*/
|
||||
+ * @brief Release function for vpu file operation
|
||||
+ * @return 0 on success or negative error code on error
|
||||
+ */
|
||||
static int hdmi_cec_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
mutex_lock(&hdmi_cec_data.lock);
|
||||
-
|
||||
if (open_count) {
|
||||
open_count = 0;
|
||||
hdmi_cec_data.cec_state = false;
|
||||
hdmi_cec_data.Logical_address = 15;
|
||||
}
|
||||
-
|
||||
mutex_unlock(&hdmi_cec_data.lock);
|
||||
|
||||
return 0;
|
||||
@@ -531,20 +477,18 @@ static unsigned int hdmi_cec_poll(struct file *file, poll_table *wait)
|
||||
|
||||
pr_debug("function : %s\n", __func__);
|
||||
|
||||
- if (!open_count)
|
||||
- return -ENODEV;
|
||||
-
|
||||
- if (false == hdmi_cec_data.cec_state)
|
||||
- return -EACCES;
|
||||
-
|
||||
poll_wait(file, &hdmi_cec_queue, wait);
|
||||
|
||||
+ /* Always writable */
|
||||
+ mask = (POLLOUT | POLLWRNORM);
|
||||
+ mutex_lock(&hdmi_cec_data.lock);
|
||||
if (!list_empty(&head))
|
||||
- mask |= (POLLIN | POLLRDNORM);
|
||||
-
|
||||
+ mask |= (POLLIN | POLLRDNORM);
|
||||
+ mutex_unlock(&hdmi_cec_data.lock);
|
||||
return mask;
|
||||
}
|
||||
|
||||
+
|
||||
const struct file_operations hdmi_cec_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.read = hdmi_cec_read,
|
||||
@@ -563,20 +507,18 @@ static int hdmi_cec_dev_probe(struct platform_device *pdev)
|
||||
struct pinctrl *pinctrl;
|
||||
int irq = platform_get_irq(pdev, 0);
|
||||
|
||||
- hdmi_cec_major = register_chrdev(hdmi_cec_major,
|
||||
- "mxc_hdmi_cec", &hdmi_cec_fops);
|
||||
+ hdmi_cec_major = register_chrdev(hdmi_cec_major, "mxc_hdmi_cec", &hdmi_cec_fops);
|
||||
if (hdmi_cec_major < 0) {
|
||||
dev_err(&pdev->dev, "hdmi_cec: unable to get a major for HDMI CEC\n");
|
||||
err = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
-
|
||||
+
|
||||
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (unlikely(res == NULL)) {
|
||||
dev_err(&pdev->dev, "hdmi_cec:No HDMI irq line provided\n");
|
||||
goto err_out_chrdev;
|
||||
}
|
||||
-
|
||||
spin_lock_init(&hdmi_cec_data.irq_lock);
|
||||
|
||||
err = devm_request_irq(&pdev->dev, irq, mxc_hdmi_cec_isr, IRQF_SHARED,
|
||||
@@ -592,8 +534,8 @@ static int hdmi_cec_dev_probe(struct platform_device *pdev)
|
||||
goto err_out_chrdev;
|
||||
}
|
||||
|
||||
- temp_class = device_create(hdmi_cec_class, NULL,
|
||||
- MKDEV(hdmi_cec_major, 0), NULL, "mxc_hdmi_cec");
|
||||
+ temp_class = device_create(hdmi_cec_class, NULL, MKDEV(hdmi_cec_major, 0),
|
||||
+ NULL, "mxc_hdmi_cec");
|
||||
if (IS_ERR(temp_class)) {
|
||||
err = PTR_ERR(temp_class);
|
||||
goto err_out_class;
|
||||
@@ -606,15 +548,14 @@ static int hdmi_cec_dev_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
init_waitqueue_head(&hdmi_cec_queue);
|
||||
+ init_waitqueue_head(&tx_cec_queue);
|
||||
|
||||
INIT_LIST_HEAD(&head);
|
||||
|
||||
mutex_init(&hdmi_cec_data.lock);
|
||||
-
|
||||
hdmi_cec_data.Logical_address = 15;
|
||||
-
|
||||
+ hdmi_cec_data.tx_answer = CEC_TX_AVAIL;
|
||||
platform_set_drvdata(pdev, &hdmi_cec_data);
|
||||
-
|
||||
INIT_DELAYED_WORK(&hdmi_cec_data.hdmi_cec_work, mxc_hdmi_cec_worker);
|
||||
|
||||
dev_info(&pdev->dev, "HDMI CEC initialized\n");
|
||||
@@ -631,12 +572,14 @@ out:
|
||||
|
||||
static int hdmi_cec_dev_remove(struct platform_device *pdev)
|
||||
{
|
||||
+ if (hdmi_cec_data.cec_state)
|
||||
+ hdmi_stop_device();
|
||||
if (hdmi_cec_major > 0) {
|
||||
device_destroy(hdmi_cec_class, MKDEV(hdmi_cec_major, 0));
|
||||
class_destroy(hdmi_cec_class);
|
||||
unregister_chrdev(hdmi_cec_major, "mxc_hdmi_cec");
|
||||
hdmi_cec_major = 0;
|
||||
- }
|
||||
+}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -650,9 +593,9 @@ static struct platform_driver mxc_hdmi_cec_driver = {
|
||||
.probe = hdmi_cec_dev_probe,
|
||||
.remove = hdmi_cec_dev_remove,
|
||||
.driver = {
|
||||
- .name = "mxc_hdmi_cec",
|
||||
+ .name = "mxc_hdmi_cec",
|
||||
.of_match_table = imx_hdmi_cec_match,
|
||||
- },
|
||||
+ },
|
||||
};
|
||||
|
||||
module_platform_driver(mxc_hdmi_cec_driver);
|
||||
diff --git a/drivers/video/mxc/mxc_hdmi.c b/drivers/video/mxc/mxc_hdmi.c
|
||||
index 20c6d70..88d62ce 100644
|
||||
--- a/drivers/video/mxc/mxc_hdmi.c
|
||||
+++ b/drivers/video/mxc/mxc_hdmi.c
|
||||
@@ -1708,8 +1708,12 @@ static void mxc_hdmi_enable_video_path(struct mxc_hdmi *hdmi)
|
||||
hdmi_writeb(0x16, HDMI_FC_CH1PREAM);
|
||||
hdmi_writeb(0x21, HDMI_FC_CH2PREAM);
|
||||
|
||||
+ /* Save CEC clock */
|
||||
+ clkdis = hdmi_readb(HDMI_MC_CLKDIS) & HDMI_MC_CLKDIS_CECCLK_DISABLE;
|
||||
+ clkdis |= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
|
||||
+
|
||||
/* Enable pixel clock and tmds data path */
|
||||
- clkdis = 0x7F;
|
||||
+ clkdis = 0x7F & clkdis;
|
||||
clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
|
||||
hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
|
||||
|
||||
@@ -1990,10 +1994,16 @@ static void mxc_hdmi_power_off(struct mxc_dispdrv_handle *disp)
|
||||
|
||||
static void mxc_hdmi_cable_disconnected(struct mxc_hdmi *hdmi)
|
||||
{
|
||||
+ u8 clkdis;
|
||||
+
|
||||
dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
|
||||
|
||||
+ /* Save CEC clock */
|
||||
+ clkdis = hdmi_readb(HDMI_MC_CLKDIS) & HDMI_MC_CLKDIS_CECCLK_DISABLE;
|
||||
+ clkdis |= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
|
||||
+
|
||||
/* Disable All HDMI clock */
|
||||
- hdmi_writeb(0xff, HDMI_MC_CLKDIS);
|
||||
+ hdmi_writeb(0xff & clkdis, HDMI_MC_CLKDIS);
|
||||
|
||||
mxc_hdmi_phy_disable(hdmi);
|
||||
|
||||
--
|
||||
1.7.9.5
|
||||
|
Loading…
x
Reference in New Issue
Block a user