From: hang cheng Date: Sat, 8 May 2021 10:16:59 +0000 (+0800) Subject: hdmirx: add hdmi plug & cec rx msg uevent [1/1] X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=d5cf6ee9a94135ca5eece22db7ff6b77f813a3ee;p=GitHub%2FLineageOS%2FG12%2Fandroid_kernel_amlogic_linux-4.9.git hdmirx: add hdmi plug & cec rx msg uevent [1/1] PD#SWPL-47310 Problem: 1.need hdmi plug uevent to check connection status 2.need cec rx msg uevent instead of poll 3.hdmitx hdcp result for uevent is wrong Solution: 1.add hdmitx/rx hotplug & cec rx msg uevent 2.correct hdcp result for drm uevent Verify: ab311 Change-Id: I60bc0e869770965df676ff22801ee1ff7981916b Signed-off-by: hang cheng --- diff --git a/drivers/amlogic/cec/hdmi_ao_cec.c b/drivers/amlogic/cec/hdmi_ao_cec.c index 5e034488ad5e..2d10717db4da 100644 --- a/drivers/amlogic/cec/hdmi_ao_cec.c +++ b/drivers/amlogic/cec/hdmi_ao_cec.c @@ -45,11 +45,16 @@ #include #include #include +#ifdef CONFIG_AMLOGIC_HDMITX #include +#endif #include #include #include #include +#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI +#include "../media/vin/tvin/hdmirx/hdmi_rx_drv_ext.h" +#endif #ifdef CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND static struct early_suspend aocec_suspend_handler; @@ -259,6 +264,27 @@ unsigned int read_clock(unsigned int addr) return data; } +static struct cec_uevent cec_events[] = { + { + .type = HDMI_PLUG_EVENT, + .env = "hdmi_conn=", + }, + { + .type = CEC_RX_MSG, + .env = "cec_rx_msg=", + }, + { + /* end of cec_events[] */ + .type = CEC_NONE_EVENT, + } +}; + +static int hdmitx_notify_callback(struct notifier_block *block, + unsigned long cmd, void *para); +static struct notifier_block hdmitx_notifier_nb = { + .notifier_call = hdmitx_notify_callback +}; + unsigned int waiting_aocec_free(unsigned int r) { unsigned int cnt = 0; @@ -3578,6 +3604,9 @@ void cec_new_msg_push(void) complete(&cec_dev->rx_ok); new_msg = 1; wake_up(&cec_msg_wait_queue); + /* uevent to notify cec msg received */ + queue_delayed_work(cec_dev->cec_rx_event_wq, + &cec_dev->work_cec_rx, 0); } } @@ -3926,6 +3955,111 @@ static void cec_get_wakeup_data(void) *((unsigned int *)&cec_dev->wakup_data)); } +int cec_set_uevent(enum cec_event_type type, unsigned int val) +{ + char env[MAX_UEVENT_LEN]; + struct cec_uevent *event = cec_events; + char *envp[2]; + int ret = -1; + + /* hdmi_plug/cec_rx uevent may concurrent, need mutex */ + mutex_lock(&cec_dev->cec_uevent_mutex); + for (event = cec_events; event->type != CEC_NONE_EVENT; event++) { + if (type == event->type) + break; + } + if (event->type == CEC_NONE_EVENT) { + CEC_ERR("[%s] unsupported event:0x%x\n", __func__, type); + mutex_unlock(&cec_dev->cec_uevent_mutex); + return ret; + } + if (event->state == val) { + CEC_INFO("[%s] state not chg:0x%x\n", __func__, val); + mutex_unlock(&cec_dev->cec_uevent_mutex); + return ret; + } + event->state = val; + memset(env, 0, sizeof(env)); + envp[0] = env; + envp[1] = NULL; + snprintf(env, MAX_UEVENT_LEN, "%s%x", event->env, val); + + ret = kobject_uevent_env(&cec_dev->dbg_dev->kobj, KOBJ_CHANGE, envp); + CEC_INFO("[%s] %s %d\n", __func__, env, ret); + mutex_unlock(&cec_dev->cec_uevent_mutex); + + return ret; +} +EXPORT_SYMBOL(cec_set_uevent); + +/* handler for both hdmitx & rx */ +static void cec_hdmi_plug_handler(struct work_struct *work) +{ + /* struct ao_cec_dev *pcec_dev = */ + /* container_of((struct delayed_work *)work, */ + /* struct ao_cec_dev, work_hdmitx_plug); */ + unsigned int tmp = 0; + +#ifdef CONFIG_AMLOGIC_HDMITX + tmp |= (cec_dev->tx_dev->hpd_state << 4); +#endif +#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI + tmp |= (hdmirx_get_connect_info() & 0xF); +#endif + + cec_set_uevent(HDMI_PLUG_EVENT, tmp); +} + +static void cec_rx_uevent_handler(struct work_struct *work) +{ + /* struct ao_cec_dev *pcec_dev = */ + /* container_of((struct delayed_work *)work, */ + /* struct ao_cec_dev, work_cec_rx); */ + /* notify framework to read cec msg */ + cec_set_uevent(CEC_RX_MSG, 1); + /* clear notify */ + cec_set_uevent(CEC_RX_MSG, 0); +} + +static int hdmitx_notify_callback(struct notifier_block *block, + unsigned long cmd, void *para) +{ + int ret = 0; + + switch (cmd) { +#ifdef CONFIG_AMLOGIC_HDMITX + case HDMITX_PLUG: + case HDMITX_UNPLUG: + CEC_INFO("[%s] event: %ld\n", __func__, cmd); + queue_delayed_work(cec_dev->hdmi_plug_wq, + &cec_dev->work_hdmi_plug, 0); + break; +#endif + default: + CEC_ERR("[%s] unsupported notify:%ld\n", __func__, cmd); + ret = -EINVAL; + break; + } + return ret; +} + +#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI +static int hdmirx_notify_callback(unsigned int pwr5v_sts) +{ + int ret = 0; + unsigned int tmp = 0; + +#ifdef CONFIG_AMLOGIC_HDMITX + tmp |= (cec_dev->tx_dev->hpd_state << 4); +#endif + tmp |= (pwr5v_sts & 0xF); + + queue_delayed_work(cec_dev->hdmi_plug_wq, &cec_dev->work_hdmi_plug, 0); + + return ret; +} +#endif + static int aml_cec_probe(struct platform_device *pdev) { struct device *cdev; @@ -3999,6 +4133,7 @@ static int aml_cec_probe(struct platform_device *pdev) init_completion(&cec_dev->tx_ok); mutex_init(&cec_dev->cec_tx_mutex); mutex_init(&cec_dev->cec_ioctl_mutex); + mutex_init(&cec_dev->cec_uevent_mutex); spin_lock_init(&cec_dev->cec_reg_lock); cec_dev->cec_info.remote_cec_dev = input_allocate_device(); if (!cec_dev->cec_info.remote_cec_dev) { @@ -4286,6 +4421,26 @@ static int aml_cec_probe(struct platform_device *pdev) ret = -EFAULT; goto tag_cec_threat_err; } + /* for hdmitx/rx plug uevent report */ + cec_dev->hdmi_plug_wq = + alloc_workqueue("cec_hdmi_plug", + WQ_HIGHPRI | WQ_CPU_INTENSIVE, 0); + if (!cec_dev->hdmi_plug_wq) { + CEC_INFO("create hdmi_plug_wq failed\n"); + ret = -EFAULT; + goto tag_hdmi_plug_wq_err; + } + INIT_DELAYED_WORK(&cec_dev->work_hdmi_plug, cec_hdmi_plug_handler); + /* for cec rx msg uevent report */ + cec_dev->cec_rx_event_wq = + alloc_workqueue("cec_rx_event", + WQ_HIGHPRI | WQ_CPU_INTENSIVE, 0); + if (!cec_dev->cec_rx_event_wq) { + CEC_INFO("create cec_rx_event_wq failed\n"); + ret = -EFAULT; + goto tag_cec_rx_event_wq_err; + } + INIT_DELAYED_WORK(&cec_dev->work_cec_rx, cec_rx_uevent_handler); /*freeze wakeup init*/ device_init_wakeup(&pdev->dev, 1); /*CEC_INFO("dev init wakeup\n");*/ @@ -4303,12 +4458,26 @@ static int aml_cec_probe(struct platform_device *pdev) queue_delayed_work(cec_dev->cec_thread, &cec_dev->cec_work, 0); tasklet_init(&ceca_tasklet, ceca_tasklet_pro, (unsigned long)cec_dev); +#ifdef CONFIG_AMLOGIC_HDMITX + hdmitx_event_notifier_regist(&hdmitx_notifier_nb); +#endif +#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI + register_cec_callback(hdmirx_notify_callback); +#endif cec_get_wakeup_reason(); cec_get_wakeup_data(); cec_irq_enable(true); cec_dev->probe_finish = true; return 0; +tag_cec_rx_event_wq_err: + destroy_workqueue(cec_dev->hdmi_plug_wq); +tag_hdmi_plug_wq_err: + destroy_workqueue(cec_dev->cec_thread); +tag_cec_threat_err: +#ifdef CONFIG_HAS_EARLYSUSPEND + unregister_early_suspend(&aocec_suspend_handler); +#endif tag_cec_msg_alloc_err: if (cec_dev->cec_num > ENABLE_ONE_CEC) { free_irq(cec_dev->irq_ceca, (void *)cec_dev); @@ -4322,10 +4491,7 @@ tag_cec_msg_alloc_err: tag_cec_reg_map_err: input_free_device(cec_dev->cec_info.remote_cec_dev); tag_cec_alloc_input_err: - destroy_workqueue(cec_dev->cec_thread); -tag_cec_threat_err: - device_destroy(&aocec_class, - MKDEV(cec_dev->cec_info.dev_no, 0)); + device_destroy(&aocec_class, MKDEV(cec_dev->cec_info.dev_no, 0)); tag_cec_device_create_err: unregister_chrdev(cec_dev->cec_info.dev_no, CEC_DEV_NAME); tag_cec_chr_reg_err: @@ -4355,6 +4521,20 @@ static int aml_cec_remove(struct platform_device *pdev) cancel_delayed_work_sync(&cec_dev->cec_work); destroy_workqueue(cec_dev->cec_thread); } +#ifdef CONFIG_AMLOGIC_HDMITX + hdmitx_event_notifier_unregist(&hdmitx_notifier_nb); +#endif +#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI + unregister_cec_callback(); +#endif + if (cec_dev->hdmi_plug_wq) { + cancel_delayed_work_sync(&cec_dev->work_hdmi_plug); + destroy_workqueue(cec_dev->hdmi_plug_wq); + } + if (cec_dev->cec_rx_event_wq) { + cancel_delayed_work_sync(&cec_dev->work_cec_rx); + destroy_workqueue(cec_dev->cec_rx_event_wq); + } input_unregister_device(cec_dev->cec_info.remote_cec_dev); unregister_chrdev(cec_dev->cec_info.dev_no, CEC_DEV_NAME); class_unregister(&aocec_class); diff --git a/drivers/amlogic/cec/hdmi_ao_cec.h b/drivers/amlogic/cec/hdmi_ao_cec.h index 3a956117d83c..d0ffba1276ba 100644 --- a/drivers/amlogic/cec/hdmi_ao_cec.h +++ b/drivers/amlogic/cec/hdmi_ao_cec.h @@ -19,7 +19,7 @@ #ifndef __AO_CEC_H__ #define __AO_CEC_H__ -#define CEC_DRIVER_VERSION "2021/01/19:phy addr error, defaut is 0xffff" +#define CEC_DRIVER_VERSION "2021/05/14: hdmi plug & cec rx msg uevent" #define CEC_DEV_NAME "cec" @@ -165,14 +165,19 @@ struct ao_cec_dev { void __iomem *clk_reg; struct hdmitx_dev *tx_dev; struct workqueue_struct *cec_thread; + struct workqueue_struct *hdmi_plug_wq; + struct workqueue_struct *cec_rx_event_wq; struct device *dbg_dev; const char *pin_name; struct delayed_work cec_work; + struct delayed_work work_hdmi_plug; + struct delayed_work work_cec_rx; struct completion rx_ok; struct completion tx_ok; spinlock_t cec_reg_lock;/*cec register access*/ struct mutex cec_tx_mutex;/*pretect tx cec msg*/ struct mutex cec_ioctl_mutex; + struct mutex cec_uevent_mutex; /* cec uevent */ struct cec_wakeup_t wakup_data; unsigned int wakeup_reason; #ifdef CONFIG_PM @@ -507,6 +512,20 @@ enum { CECB_STAT0_P2S_FBACK_RX_ERR = 6, }; +enum cec_event_type { + CEC_NONE_EVENT = 0, + HDMI_PLUG_EVENT = 1, + CEC_RX_MSG = 2 +}; + +#define MAX_UEVENT_LEN 64 + +struct cec_uevent { + enum cec_event_type type; + unsigned int state; + const char *env; +}; + /* cec ip irq flags bit discription */ #define EECEC_IRQ_TX_DONE BIT(16) #define EECEC_IRQ_RX_EOM BIT(17) diff --git a/drivers/amlogic/drm/meson_hdmi.c b/drivers/amlogic/drm/meson_hdmi.c index 06eea1a8ac2b..edd5bfffb1f9 100644 --- a/drivers/amlogic/drm/meson_hdmi.c +++ b/drivers/amlogic/drm/meson_hdmi.c @@ -1291,7 +1291,11 @@ static irqreturn_t am_hdmi_irq(int irq, void *dev_id) hdmi_tx_edid_proc((unsigned char *)edid); kfree(edid); } + hdmitx_dev->hpd_state = 1; + } else if (am_hdmi->hpd_flag == 2) { + hdmitx_dev->hpd_state = 0; } + hdmitx_notify_hpd(hdmitx_dev->hpd_state, NULL); drm_helper_hpd_irq_event(am_hdmi->connector.dev); return IRQ_HANDLED; } @@ -1457,6 +1461,10 @@ void am_hdmitx_hdcp_result(unsigned int *exe_type, *result_type = (unsigned int)am_hdmi_info.hdcp_result; } +void am_hdmitx_set_hdcp_mode(unsigned int user_type) +{ + am_hdmi_info.hdcp_user_type = user_type; +} static int am_meson_hdmi_probe(struct platform_device *pdev) { struct hdmitx_dev *hdmitx_dev; @@ -1468,6 +1476,7 @@ static int am_meson_hdmi_probe(struct platform_device *pdev) hdmitx_dev->hwop.am_hdmitx_hdcp_disable = am_hdmitx_hdcp_disable; hdmitx_dev->hwop.am_hdmitx_hdcp_enable = am_hdmitx_hdcp_enable; hdmitx_dev->hwop.am_hdmitx_hdcp_result = am_hdmitx_hdcp_result; + hdmitx_dev->hwop.am_hdmitx_set_hdcp_mode = am_hdmitx_set_hdcp_mode; return component_add(&pdev->dev, &am_meson_hdmi_ops); } diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h index 773f49a1f697..15173b93ac83 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h @@ -15,8 +15,8 @@ * */ -#ifndef _TVHDMI_H -#define _TVHDMI_H +#ifndef __HDMI_RX_DRV_H__ +#define __HDMI_RX_DRV_H__ #include #include @@ -32,7 +32,7 @@ //#include "hdmirx_repeater.h" //#include "hdmi_rx_pktinfo.h" #include "hdmi_rx_edid.h" - +#include "hdmi_rx_drv_ext.h" #define RX_VER0 "ver.2019/10/21" /* @@ -47,7 +47,7 @@ * * */ -#define RX_VER2 "ver.2019/11/18" +#define RX_VER2 "ver.2021/05/14" /*print type*/ #define LOG_EN 0x01 @@ -483,7 +483,6 @@ extern struct reg_map reg_maps[MAP_ADDR_MODULE_NUM]; extern bool downstream_repeat_support; extern void rx_tasklet_handler(unsigned long arg); extern void skip_frame(unsigned int cnt); -extern int cec_set_dev_info(uint8_t dev_idx); /* reg */ @@ -563,5 +562,4 @@ extern unsigned int *pd_fifo_buf; /* for other modules */ extern int External_Mute(int mute_flag); extern int rx_is_hdcp22_support(void); -extern int hdmirx_get_connect_info(void); #endif diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv_ext.h b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv_ext.h new file mode 100644 index 000000000000..f2005283df1c --- /dev/null +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv_ext.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2019 Amlogic, Inc. All rights reserved. + */ + +#ifndef __HDMI_RX_DRV_EXT_H__ +#define __HDMI_RX_DRV_EXT_H__ + +/* for CEC notify */ +typedef int (*cec_callback)(unsigned int pwr5v_sts); + +int hdmirx_get_connect_info(void); +int cec_set_dev_info(u8 dev_idx); +/* int hdmirx_set_cec_cfg(u32 cfg); */ +int register_cec_callback(cec_callback callback); +void unregister_cec_callback(void); + +#endif diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c index c6a5876e8dd7..aa3d837199df 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c @@ -45,6 +45,7 @@ #include "hdmi_rx_wrapper.h" #include "hdmi_rx_pktinfo.h" #include "hdmi_rx_edid.h" +#include "hdmi_rx_drv_ext.h" static int pll_unlock_cnt; static int pll_unlock_max = 30; @@ -208,6 +209,7 @@ static int esd_phy_rst_cnt; static int esd_phy_rst_max; static int cec_dev_info; struct rx_s rx; +static cec_callback cec_hdmirx5v_update; void hdmirx_init_params(void) { @@ -247,6 +249,19 @@ int cec_set_dev_info(uint8_t dev_idx) } EXPORT_SYMBOL(cec_set_dev_info); +int register_cec_callback(cec_callback callback) +{ + cec_hdmirx5v_update = callback; + return 0; +} +EXPORT_SYMBOL(register_cec_callback); + +void unregister_cec_callback(void) +{ + cec_hdmirx5v_update = NULL; +} +EXPORT_SYMBOL(unregister_cec_callback); + /* *func: irq tasklet *param: flag: @@ -1989,6 +2004,8 @@ void rx_5v_monitor(void) check_cnt = 0; pwr_sts = tmp_5v; rx.cur_5v_sts = (pwr_sts >> rx.port) & 1; + if (cec_hdmirx5v_update) + cec_hdmirx5v_update(pwr_sts); hotplug_wait_query(); rx_pr("hotplug-0x%x\n", pwr_sts); if (rx.cur_5v_sts == 0) { diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_hdcp.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_hdcp.c index 232e16bb88a6..19fea697ae6f 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_hdcp.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_hdcp.c @@ -203,15 +203,23 @@ static int hdmitx_hdcp_task(void *data) { static int auth_trigger; struct hdmitx_dev *hdev = (struct hdmitx_dev *)data; + unsigned int hdcp_mode; INIT_DELAYED_WORK(&hdev->work_do_hdcp, _hdcp_do_work); while (hdev->hpd_event != 0xff) { - hdmi_authenticated = hdev->hwop.cntlddc(hdev, - DDC_HDCP_GET_AUTH, 0); + if (hdev->drm_feature) { + if (hdev->hwop.am_hdmitx_hdcp_result) + hdev->hwop.am_hdmitx_hdcp_result(&hdcp_mode, + &hdmi_authenticated); + } else { + hdmi_authenticated = hdev->hwop.cntlddc(hdev, + DDC_HDCP_GET_AUTH, 0); + hdcp_mode = hdev->hdcp_mode; + } hdmitx_hdcp_status(hdmi_authenticated); if (auth_trigger != hdmi_authenticated) { auth_trigger = hdmi_authenticated; - pr_info("hdcptx: %d auth: %d\n", hdev->hdcp_mode, + pr_info("hdcptx: %d auth: %d\n", hdcp_mode, auth_trigger); } msleep_interruptible(200); diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main_drm.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main_drm.c index ac67a30ff007..88ee929e9ad4 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main_drm.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hdmi_tx_main_drm.c @@ -455,13 +455,15 @@ struct extcon_dev *hdmitx_extcon_cedst; * are remained the same. So, add hdr_status_pos and place it in the above 3 * functions to record the position. */ -static inline void hdmitx_notify_hpd(int hpd, void *p) +void hdmitx_notify_hpd(int hpd, void *p) { if (hpd) hdmitx_event_notify(HDMITX_PLUG, p); else hdmitx_event_notify(HDMITX_UNPLUG, NULL); } +EXPORT_SYMBOL(hdmitx_notify_hpd); + #if defined(CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND) && !defined(CONFIG_AMLOGIC_DRM) #include diff --git a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c index 8b0eb3da312a..1ce6e5a9b4ea 100644 --- a/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c +++ b/drivers/amlogic/media/vout/hdmitx/hdmi_tx_20/hw/hdmi_tx_hw.c @@ -3388,6 +3388,11 @@ static void hdmitx_debug(struct hdmitx_dev *hdev, const char *buf) } } else if (strncmp(tmpbuf, "stop_vsif", 9) == 0) { hdmitx_disable_packet(HDMI_PACKET_VEND); + } else if (strncmp(tmpbuf, "hdcp_mode", 9) == 0) { + ret = kstrtoul(tmpbuf + 9, 16, &value); + if ((value >= 0) && (value <= 3) && + hdev->hwop.am_hdmitx_set_hdcp_mode) + hdev->hwop.am_hdmitx_set_hdcp_mode(value); } } diff --git a/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h b/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h index 74046ebd891e..ec507f399edf 100644 --- a/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h +++ b/include/linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h @@ -387,6 +387,7 @@ struct hdmitx_dev { void (*am_hdmitx_hdcp_enable)(void); void (*am_hdmitx_hdcp_result)(unsigned int *exe_type, unsigned int *result_type); + void (*am_hdmitx_set_hdcp_mode)(unsigned int user_type); } hwop; struct { unsigned int hdcp14_en; @@ -798,6 +799,9 @@ int hdmitx_set_uevent(enum hdmitx_event type, int val); #ifdef CONFIG_AMLOGIC_HDMITX extern struct hdmitx_dev *get_hdmitx_device(void); extern int get_hpd_state(void); +#ifdef CONFIG_DRM_MESON_HDMI +void hdmitx_notify_hpd(int hpd, void *p); +#endif bool is_tv_changed(void); extern int hdmitx_event_notifier_regist(struct notifier_block *nb); extern int hdmitx_event_notifier_unregist(struct notifier_block *nb);