drm/msm: add CEC notifier support for HDMI driver

Add CEC notifier support which allows HDMI driver to
inform CEC driver with the new physical address. With
this information the CEC adapter driver does not need
to manually set the physical address from userspace.

CRs-Fixed: 2041335
Change-Id: I5b5707ad40ee381b5cd67f1e89f0d2397a9a7bb2
Signed-off-by: Ray Zhang <rayz@codeaurora.org>
This commit is contained in:
Ray Zhang 2017-05-11 18:23:40 +08:00 committed by Gerrit - the friendly Code Review server
parent 6baa8d9364
commit dd943e28df
2 changed files with 47 additions and 3 deletions

View file

@ -907,6 +907,17 @@ static void _sde_hdmi_hdp_disable(struct sde_hdmi *sde_hdmi)
}
}
static void _sde_hdmi_cec_update_phys_addr(struct sde_hdmi *display)
{
struct edid *edid = display->edid_ctrl->edid;
if (edid)
cec_notifier_set_phys_addr_from_edid(display->notifier, edid);
else
cec_notifier_set_phys_addr(display->notifier,
CEC_PHYS_ADDR_INVALID);
}
static void _sde_hdmi_hotplug_work(struct work_struct *work)
{
struct sde_hdmi *sde_hdmi =
@ -936,6 +947,7 @@ static void _sde_hdmi_hotplug_work(struct work_struct *work)
sde_free_edid((void **)&sde_hdmi->edid_ctrl);
drm_helper_hpd_irq_event(connector->dev);
_sde_hdmi_cec_update_phys_addr(sde_hdmi);
}
static void _sde_hdmi_connector_irq(struct sde_hdmi *sde_hdmi)
@ -1673,10 +1685,28 @@ int sde_hdmi_dev_deinit(struct sde_hdmi *display)
SDE_ERROR("Invalid params\n");
return -EINVAL;
}
return 0;
}
static int _sde_hdmi_cec_init(struct sde_hdmi *display)
{
struct platform_device *pdev = display->pdev;
display->notifier = cec_notifier_get(&pdev->dev);
if (!display->notifier) {
SDE_ERROR("CEC notifier get failed\n");
return -ENOMEM;
}
return 0;
}
static void _sde_hdmi_cec_deinit(struct sde_hdmi *display)
{
cec_notifier_set_phys_addr(display->notifier, CEC_PHYS_ADDR_INVALID);
cec_notifier_put(display->notifier);
}
static int sde_hdmi_bind(struct device *dev, struct device *master, void *data)
{
int rc = 0;
@ -1715,7 +1745,14 @@ static int sde_hdmi_bind(struct device *dev, struct device *master, void *data)
if (rc) {
SDE_ERROR("[%s]Ext Disp init failed, rc=%d\n",
display->name, rc);
goto error;
goto ext_error;
}
rc = _sde_hdmi_cec_init(display);
if (rc) {
SDE_ERROR("[%s]CEC init failed, rc=%d\n",
display->name, rc);
goto ext_error;
}
display->edid_ctrl = sde_edid_init();
@ -1723,7 +1760,7 @@ static int sde_hdmi_bind(struct device *dev, struct device *master, void *data)
SDE_ERROR("[%s]sde edid init failed\n",
display->name);
rc = -ENOMEM;
goto error;
goto cec_error;
}
display_ctrl = &display->ctrl;
@ -1732,7 +1769,10 @@ static int sde_hdmi_bind(struct device *dev, struct device *master, void *data)
mutex_unlock(&display->display_lock);
return rc;
error:
cec_error:
(void)_sde_hdmi_cec_deinit(display);
ext_error:
(void)_sde_hdmi_debugfs_deinit(display);
debug_error:
mutex_unlock(&display->display_lock);
@ -1758,6 +1798,7 @@ static void sde_hdmi_unbind(struct device *dev, struct device *master,
mutex_lock(&display->display_lock);
(void)_sde_hdmi_debugfs_deinit(display);
(void)sde_edid_deinit((void **)&display->edid_ctrl);
(void)_sde_hdmi_cec_deinit(display);
display->drm_dev = NULL;
mutex_unlock(&display->display_lock);
}

View file

@ -23,6 +23,7 @@
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
#include <media/cec-notifier.h>
#include "hdmi.h"
#include "sde_edid_parser.h"
@ -87,6 +88,7 @@ struct sde_hdmi_ctrl {
* @codec_ready: If audio codec is ready.
* @client_notify_pending: If there is client notification pending.
* @irq_domain: IRQ domain structure.
* @notifier: CEC notifider to convey physical address information.
* @root: Debug fs root entry.
*/
struct sde_hdmi {
@ -116,6 +118,7 @@ struct sde_hdmi {
bool client_notify_pending;
struct irq_domain *irq_domain;
struct cec_notifier *notifier;
/* DEBUG FS */
struct dentry *root;