From 8bc3b7344c700ccd0969e3b6b0ee9262c6700825 Mon Sep 17 00:00:00 2001 From: Joachim Damm Date: Sun, 19 Jun 2016 22:43:43 +0200 Subject: [PATCH] H3 cec driver wait for free cec line and fix wrong array size --- drivers/video/sunxi/disp2/hdmi/aw/hdmi_cec.c | 37 +++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/drivers/video/sunxi/disp2/hdmi/aw/hdmi_cec.c b/drivers/video/sunxi/disp2/hdmi/aw/hdmi_cec.c index b407caf..09db0aa 100644 --- a/drivers/video/sunxi/disp2/hdmi/aw/hdmi_cec.c +++ b/drivers/video/sunxi/disp2/hdmi/aw/hdmi_cec.c @@ -99,14 +99,14 @@ static u8 cec_l_addr_l = 0, cec_l_addr_h = 0; static wait_queue_head_t hdmi_cec_queue; static wait_queue_head_t tx_cec_queue; -static int tx_reg[15] = {HDMI_CEC_TX_DATA0, HDMI_CEC_TX_DATA1, HDMI_CEC_TX_DATA2,\ +static int tx_reg[16] = {HDMI_CEC_TX_DATA0, HDMI_CEC_TX_DATA1, HDMI_CEC_TX_DATA2,\ HDMI_CEC_TX_DATA3, HDMI_CEC_TX_DATA4, HDMI_CEC_TX_DATA5,\ HDMI_CEC_TX_DATA6, HDMI_CEC_TX_DATA7, HDMI_CEC_TX_DATA8,\ HDMI_CEC_TX_DATA9, HDMI_CEC_TX_DATA10, HDMI_CEC_TX_DATA11,\ HDMI_CEC_TX_DATA12, HDMI_CEC_TX_DATA13, HDMI_CEC_TX_DATA14,\ HDMI_CEC_TX_DATA15}; -static int rx_reg[15] = {HDMI_CEC_RX_DATA0, HDMI_CEC_RX_DATA1, HDMI_CEC_RX_DATA2,\ +static int rx_reg[16] = {HDMI_CEC_RX_DATA0, HDMI_CEC_RX_DATA1, HDMI_CEC_RX_DATA2,\ HDMI_CEC_RX_DATA3, HDMI_CEC_RX_DATA4, HDMI_CEC_RX_DATA5,\ HDMI_CEC_RX_DATA6, HDMI_CEC_RX_DATA7, HDMI_CEC_RX_DATA8,\ HDMI_CEC_RX_DATA9, HDMI_CEC_RX_DATA10, HDMI_CEC_RX_DATA11,\ @@ -462,7 +462,7 @@ void hdmi_cec_handle(u16 cec_stat) hdmi_cec_data.send_error++; if (hdmi_cec_data.send_error < 2) { hdmi_cec_data.msg_resend = true; - schedule_delayed_work(&hdmi_cec_data.hdmi_cec_resend, msecs_to_jiffies(400)); + schedule_delayed_work(&hdmi_cec_data.hdmi_cec_resend, msecs_to_jiffies(20)); } else { hdmi_cec_data.tx_answer = cec_stat; wake_up(&tx_cec_queue); @@ -484,6 +484,23 @@ static void hdmi_cec_worker(struct work_struct *work) hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0); } +static int hdmi_wait_free_cecline(void) +{ + u32 count_timeout = 0; + + while (count_hi < 5) + { + count_timeout++; + usleep_range(2000,2200); + // no change in time, timeout + if (count_timeout > 500) + { + return -1; + } + } + return 0; +} + static void hdmi_cec_resender(struct work_struct *work) { u8 val; @@ -491,6 +508,8 @@ static void hdmi_cec_resender(struct work_struct *work) hdmi_cec_data.msg_resend = false; mutex_unlock(&hdmi_cec_data.lock); + /* FIXME : check return value */ + hdmi_wait_free_cecline(); /* Enable Sending */ hdmi_writel(0x00, 0x1003c); @@ -567,6 +586,13 @@ static ssize_t hdmi_cec_write(struct file *file, const char __user *buf, if (!open_count) return -ENODEV; + /* wait for free line */ + ret = hdmi_wait_free_cecline(); + if (ret < 0) { + pr_err("[CEC] no free cec line detected.\n"); + ret = -ERESTARTSYS; + goto tx_out; + } mutex_lock(&hdmi_cec_data.lock); if (false == hdmi_cec_data.cec_state) { mutex_unlock(&hdmi_cec_data.lock); @@ -592,7 +618,6 @@ static ssize_t hdmi_cec_write(struct file *file, const char __user *buf, for (i = 0; i < msg_len; i++) hdmi_writeb(msg[i], tx_reg[i]); - /* FIXME : wait for free line */ /* Enable Sending */ hdmi_writel(0x00, 0x1003c); @@ -646,7 +671,7 @@ static void hdmi_stop_device(void) } /*! - * @brief IO ctrl function for vpu file operation + * @brief IO ctrl function for cec file operation * @param cmd IO ctrl command * @return 0 on success or negative error code on error */ @@ -720,7 +745,7 @@ static long hdmi_cec_ioctl(struct file *filp, u_int cmd, } /*! - * @brief Release function for vpu file operation + * @brief Release function for cec file operation * @return 0 on success or negative error code on error */ static int hdmi_cec_release(struct inode *inode, struct file *filp)