diff options
| author | Venkata Prahlad Valluru <vvalluru@codeaurora.org> | 2020-03-06 12:13:55 +0530 |
|---|---|---|
| committer | Venkata Prahlad Valluru <vvalluru@codeaurora.org> | 2020-03-06 16:23:06 +0530 |
| commit | 80774a56dbc0e7f3aba6d9aa1f3742a42869bc4c (patch) | |
| tree | dc4cf16192cbeb04733a74275833d0da6d239bca | |
| parent | 1233c7c4b0c141ae19a2bd98b01cc389d4a149f5 (diff) | |
mdss: msm: hdmi: add CEC clear_logical_addr sysnode
When the logical address is cleared, CEC hal sets the logical
address to 15 but kernel cannot determine whether the logical
address is cleared or set to 15. To clearly detect that the
logical address is cleared, a new sysnode
"clear_logical_addr" is added.
If clear_logical_addr is set to 1, then kernel ignores
received CEC messages until it's reset to 0.
Change-Id: I517a3054c0816e774836767f3e0e47f92b395666
Signed-off-by: Venkata Prahlad Valluru <vvalluru@codeaurora.org>
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_cec_core.c | 40 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_cec_core.h | 3 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_hdmi_cec.c | 22 |
3 files changed, 63 insertions, 2 deletions
diff --git a/drivers/video/fbdev/msm/mdss_cec_core.c b/drivers/video/fbdev/msm/mdss_cec_core.c index 1d9950494d65..ab7a8056016a 100644 --- a/drivers/video/fbdev/msm/mdss_cec_core.c +++ b/drivers/video/fbdev/msm/mdss_cec_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2017, 2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -594,6 +594,41 @@ end: return ret; } +static ssize_t cec_wta_clear_logical_addr(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int clear_flag; + unsigned long flags; + ssize_t ret; + struct cec_ctl *ctl = cec_get_ctl(dev); + struct cec_ops *ops; + + if (!ctl) { + pr_err("Invalid ctl\n"); + ret = -EINVAL; + goto end; + } + + ops = ctl->init_data.ops; + + ret = kstrtoint(buf, 10, &clear_flag); + if (ret) { + pr_err("kstrtoint failed\n"); + goto end; + } + + ret = count; + + spin_lock_irqsave(&ctl->lock, flags); + if (ctl->enabled) { + if (ops && ops->clear_logical_addr) + ops->clear_logical_addr(ops->data, !!clear_flag); + } + spin_unlock_irqrestore(&ctl->lock, flags); +end: + return ret; +} + static ssize_t cec_rda_msg(struct device *dev, struct device_attribute *attr, char *buf) { @@ -703,6 +738,8 @@ static DEVICE_ATTR(enable_compliance, S_IRUGO | S_IWUSR, cec_rda_enable_compliance, cec_wta_enable_compliance); static DEVICE_ATTR(logical_addr, S_IRUSR | S_IWUSR, cec_rda_logical_addr, cec_wta_logical_addr); +static DEVICE_ATTR(clear_logical_addr, 0200, + NULL, cec_wta_clear_logical_addr); static DEVICE_ATTR(rd_msg, S_IRUGO, cec_rda_msg, NULL); static DEVICE_ATTR(wr_msg, S_IWUSR | S_IRUSR, NULL, cec_wta_msg); @@ -710,6 +747,7 @@ static struct attribute *cec_fs_attrs[] = { &dev_attr_enable.attr, &dev_attr_enable_compliance.attr, &dev_attr_logical_addr.attr, + &dev_attr_clear_logical_addr.attr, &dev_attr_rd_msg.attr, &dev_attr_wr_msg.attr, NULL, diff --git a/drivers/video/fbdev/msm/mdss_cec_core.h b/drivers/video/fbdev/msm/mdss_cec_core.h index 12b7677c5dee..481884a732d8 100644 --- a/drivers/video/fbdev/msm/mdss_cec_core.h +++ b/drivers/video/fbdev/msm/mdss_cec_core.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2016, 2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -67,6 +67,7 @@ struct cec_ops { int (*send_msg)(void *data, struct cec_msg *msg); void (*wt_logical_addr)(void *data, u8 addr); + void (*clear_logical_addr)(void *data, bool flag); void (*wakeup_en)(void *data, bool en); bool (*is_wakeup_en)(void *data); void (*device_suspend)(void *data, bool suspend); diff --git a/drivers/video/fbdev/msm/mdss_hdmi_cec.c b/drivers/video/fbdev/msm/mdss_hdmi_cec.c index 4efacfa86032..cafa4e207332 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_cec.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_cec.c @@ -37,6 +37,7 @@ struct hdmi_cec_ctrl { bool cec_enabled; bool cec_wakeup_en; bool cec_device_suspend; + bool cec_clear_logical_addr; u32 cec_msg_wr_status; struct cec_msg recv_msg; @@ -212,6 +213,13 @@ static int hdmi_cec_msg_read(struct hdmi_cec_ctrl *cec_ctrl) for (; i < MAX_OPERAND_SIZE; i++) msg->operand[i] = 0; + /* + * Clearing the logical address is used when the system doesn't + * need to process CEC command any more. + */ + if (cec_ctrl->cec_clear_logical_addr) + return -EINVAL; + DEV_DBG("%s: opcode 0x%x, wakup_en %d, device_suspend %d\n", __func__, msg->opcode, cec_ctrl->cec_wakeup_en, cec_ctrl->cec_device_suspend); @@ -379,6 +387,19 @@ static void hdmi_cec_write_logical_addr(void *input, u8 addr) DSS_REG_W(cec_ctrl->init_data.io, HDMI_CEC_ADDR, addr & 0xF); } +static void hdmi_cec_clear_logical_addr(void *input, bool clear_flag) +{ + struct hdmi_cec_ctrl *cec_ctrl = (struct hdmi_cec_ctrl *)input; + + if (!cec_ctrl || !cec_ctrl->init_data.io) { + DEV_ERR("%s: Invalid input\n", __func__); + return; + } + + if (cec_ctrl->cec_enabled) + cec_ctrl->cec_clear_logical_addr = clear_flag; +} + static int hdmi_cec_enable(void *input, bool enable) { int ret = 0; @@ -489,6 +510,7 @@ void *hdmi_cec_init(struct hdmi_cec_init_data *init_data) /* populate hardware specific operations to client */ ops->send_msg = hdmi_cec_msg_send; ops->wt_logical_addr = hdmi_cec_write_logical_addr; + ops->clear_logical_addr = hdmi_cec_clear_logical_addr; ops->enable = hdmi_cec_enable; ops->data = cec_ctrl; ops->wakeup_en = hdmi_cec_wakeup_en; |
