cec: store msg after bootup from st [1/2]

PD#SWPL-15856

Problem:
Device auto power off set off, after pressing the DVD
play button to wake up the TV, the TV cannot
automatically switch to the HDMI channel

Solution:
driver store msg during bootup st. after app task
restart, put these msg to cec hal.

Verify:
tl1

Change-Id: Ifdf5e9d3ed8fbea7142b4f4ed94130e0535f0766
Signed-off-by: Yong Qin <yong.qin@amlogic.com>
This commit is contained in:
Yong Qin
2019-11-13 09:54:19 +08:00
committed by Luke Go
parent bb1fca4a7f
commit 3e916617cd
2 changed files with 89 additions and 7 deletions

View File

@@ -131,6 +131,10 @@ struct ao_cec_dev {
struct vendor_info_data v_data;
struct cec_global_info_t cec_info;
struct cec_platform_data_s *plat_data;
unsigned int wakeup_st;
unsigned int msg_idx;
unsigned int msg_num;
struct st_rx_msg msgbuff[CEC_MSG_BUFF_MAX];
};
struct cec_msg_last {
@@ -165,6 +169,7 @@ static struct hrtimer start_bit_check;
static unsigned char rx_msg[MAX_MSG];
static unsigned char rx_len;
static unsigned int new_msg;
/*static bool wake_ok = 1;*/
static bool ee_cec;
static bool pin_status;
@@ -416,6 +421,26 @@ void cec_dbg_init(void)
stdbgflg.hal_cmd_bypass = 0;
}
void cec_store_msg_to_buff(unsigned char len, unsigned char *msg)
{
unsigned int i;
unsigned int msg_idx;
if (!cec_dev)
return;
if (cec_dev->wakeup_st && (len < MAX_MSG) &&
(cec_dev->msg_idx < CEC_MSG_BUFF_MAX)) {
msg_idx = cec_dev->msg_idx;
cec_dev->msgbuff[msg_idx].len = len;
for (i = 0; i < MAX_MSG; i++)
cec_dev->msgbuff[msg_idx].msg[i] = msg[i];
cec_dev->msg_idx++;
cec_dev->msg_num++;
CEC_INFO("save len %d, num %d\n", len, cec_dev->msg_idx);
}
}
void cecb_hw_reset(void)
{
/* cec disable */
@@ -602,8 +627,7 @@ void cecb_irq_handle(void)
if ((intr_cec & CEC_IRQ_RX_EOM) || lock) {
cecb_pick_msg(rx_msg, &rx_len);
CEC_INFO_L(L_2, "irqflg:RX_EOM\n");
/*complete(&cec_dev->rx_ok);*/
/*new_msg = 1;*/
cec_store_msg_to_buff(rx_len, rx_msg);
cec_new_msg_push();
dwork = &cec_dev->cec_work;
mod_delayed_work(cec_dev->cec_thread, dwork, 0);
@@ -1334,6 +1358,8 @@ int ceca_rx_irq_handle(unsigned char *msg, unsigned char *len)
msg[i] = aocec_rd_reg(CEC_RX_MSG_0_HEADER + i);
ret = rx_stat;
/* for resume, cec hal not ready */
cec_store_msg_to_buff(*len, msg);
/* ignore ping message */
if (cec_msg_dbg_en && *len > 1) {
@@ -2325,8 +2351,7 @@ static void ceca_tasklet_pro(unsigned long arg)
if ((-1) == ceca_rx_irq_handle(rx_msg, &rx_len))
return;
/*complete(&cec_dev->rx_ok);*/
/*new_msg = 1;*/
cec_store_msg_to_buff(rx_len, rx_msg);
cec_new_msg_push();
mod_delayed_work(cec_dev->cec_thread, dwork, 0);
}
@@ -2926,6 +2951,22 @@ static ssize_t hdmitx_cec_read(struct file *f, char __user *buf,
size_t size, loff_t *p)
{
int ret;
unsigned int idx;
unsigned int len = 0;
if (!cec_dev)
return 0;
if (cec_dev->msg_num) {
cec_dev->msg_num--;
idx = cec_dev->msg_idx;
len = cec_dev->msgbuff[idx].len;
cec_dev->msg_idx++;
if (copy_to_user(buf, &cec_dev->msgbuff[idx].msg[0], len))
return -EINVAL;
CEC_INFO("read msg from buff len=%d\n", len);
return len;
}
/*CEC_ERR("read msg start\n");*/
ret = wait_for_completion_timeout(&cec_dev->rx_ok, CEC_FRAME_DELAY);
@@ -2943,6 +2984,7 @@ static ssize_t hdmitx_cec_read(struct file *f, char __user *buf,
/*CEC_ERR("read msg end\n");*/
if (copy_to_user(buf, rx_msg, rx_len))
return -EINVAL;
CEC_INFO("read msg len=%d\n", rx_len);
return rx_len;
}
@@ -3436,9 +3478,14 @@ static void aocec_early_suspend(struct early_suspend *h)
static void aocec_late_resume(struct early_suspend *h)
{
if (!cec_dev)
return;
cec_dev->wakeup_st = 0;
cec_dev->msg_idx = 0;
cec_dev->cec_suspend = CEC_PW_POWER_ON;
CEC_ERR("%s, suspend sts:%d\n", __func__, cec_dev->cec_suspend);
}
#endif
@@ -4015,6 +4062,21 @@ static int aml_cec_remove(struct platform_device *pdev)
#ifdef CONFIG_PM
static int aml_cec_pm_prepare(struct device *dev)
{
unsigned int i, j;
if (IS_ERR_OR_NULL(cec_dev)) {
pr_info("%s cec_dev is null\n", __func__);
return 0;
}
/*initial msg buffer*/
cec_dev->wakeup_st = 0;
cec_dev->msg_idx = 0;
cec_dev->msg_num = 0;
for (i = 0; i < CEC_MSG_BUFF_MAX; i++) {
cec_dev->msgbuff[i].len = 0;
for (j = 0; j < MAX_MSG; j++)
cec_dev->msgbuff[i].msg[j] = 0;
}
//cec_dev->cec_suspend = CEC_DEEP_SUSPEND;
CEC_ERR("%s\n", __func__);
return 0;
@@ -4022,6 +4084,12 @@ static int aml_cec_pm_prepare(struct device *dev)
static void aml_cec_pm_complete(struct device *dev)
{
if (IS_ERR_OR_NULL(cec_dev))
return;
cec_dev->wakeup_st = 0;
cec_dev->msg_idx = 0;
if (get_resume_method() == CEC_WAKEUP) {
cec_key_report(0);
@@ -4067,7 +4135,11 @@ static int aml_cec_resume_noirq(struct device *dev)
cec_dev->cec_info.power_status = CEC_PW_TRANS_STANDBY_TO_ON;
cec_dev->cec_suspend = CEC_PW_TRANS_STANDBY_TO_ON;
/*initial msg buffer*/
cec_dev->msg_idx = 0;
cec_dev->msg_num = 0;
if (!is_pm_freeze_mode()) {
cec_clear_all_logical_addr(ee_cec);
scpi_get_wakeup_reason(&cec_dev->wakeup_reason);
CEC_ERR("wakeup_reason:0x%x\n", cec_dev->wakeup_reason);
@@ -4079,6 +4151,8 @@ static int aml_cec_resume_noirq(struct device *dev)
cec_dev->wakup_data.wk_port_id);
scpi_get_cec_val(SCPI_CMD_GET_CEC2, &temp);
CEC_ERR("cev val2: 0x%#x\n", temp);
/* disable all logical address */
/*cec_dev->cec_info.addr_enable = 0;*/
} else {
CEC_ERR("freeze mode\n");
}
@@ -4087,9 +4161,10 @@ static int aml_cec_resume_noirq(struct device *dev)
ret = pinctrl_pm_select_default_state(cec_dev->dbg_dev);
else
CEC_ERR("pinctrl default_state error\n");
cec_irq_enable(true);
cec_dev->cec_info.power_status = CEC_PW_POWER_ON;
cec_dev->cec_suspend = CEC_PW_POWER_ON;
cec_dev->wakeup_st = 1;
return 0;
}

View File

@@ -18,7 +18,7 @@
#ifndef __AO_CEC_H__
#define __AO_CEC_H__
#define CEC_DRIVER_VERSION "2019/11/15:add poll for andorid chk new msg\n"
#define CEC_DRIVER_VERSION "2019/11/12: store msg during bootup from st\n"
#define CEC_FRAME_DELAY msecs_to_jiffies(400)
#define CEC_DEV_NAME "cec"
@@ -83,6 +83,8 @@ enum cecbver {
#define ENABLE_ONE_CEC 1
#define ENABLE_TWO_CEC 2
#define CEC_MSG_BUFF_MAX 30
/*
#define CEC_FUNC_MASK 0
#define ONE_TOUCH_PLAY_MASK 1
@@ -518,6 +520,11 @@ struct dbgflg {
};
struct st_rx_msg {
unsigned char len;
unsigned char msg[16];
};
#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI
extern unsigned long hdmirx_rd_top(unsigned long addr);
extern void hdmirx_wr_top(unsigned long addr, unsigned long data);