hdmitx: add hpd extcon [1/1]

PD#SWPL-87506

Problem:
lack extcon

Solution:
add extcon

Verify:
sc2

Change-Id: Iad1c509cf0616e719697670cab13a0501b17e846
Signed-off-by: Wenjie Qiao <wenjie.qiao@amlogic.com>
This commit is contained in:
Wenjie Qiao
2022-10-10 14:21:03 +08:00
committed by gerrit autosubmit
parent db3d8ee5e0
commit e452ec2c5b
4 changed files with 91 additions and 4 deletions
@@ -46,6 +46,9 @@
#include <linux/amlogic/media/vout/hdmi_tx/hdmi_config.h>
#include <linux/amlogic/media/vout/hdmi_tx_ext.h>
#include <linux/amlogic/media/registers/cpu_version.h>
#include <linux/extcon.h>
#include <linux/extcon-provider.h>
#include "hw/tvenc_conf.h"
#include "hw/common.h"
#include "hw/hw_clk.h"
@@ -194,6 +197,13 @@ struct vout_device_s hdmitx_vdev = {
struct hdmi_config_platform_data *hdmi_pdata;
static struct extcon_dev *hdmitx_extcon_hdmi;
static const unsigned int hdmi_extcon_cable[] = {
EXTCON_DISP_HDMI,
EXTCON_NONE,
};
static struct hdmitx_uevent hdmi_events[] = {
{
.type = HDMITX_HPD_EVENT,
@@ -323,6 +333,7 @@ static void hdmitx_early_suspend(struct early_suspend *h)
hdmitx_edid_clear(hdev);
hdmitx_edid_ram_buffer_clear(hdev);
edidinfo_detach_to_vinfo(hdev);
hdmitx_set_uevent(HDMITX_HDCPPWR_EVENT, HDMI_SUSPEND);
hdmitx_set_uevent(HDMITX_AUDIO_EVENT, 0);
hdev->tx_hw.cntlconfig(&hdev->tx_hw, CONF_CLR_AVI_PACKET, 0);
@@ -396,6 +407,8 @@ static void hdmitx_late_resume(struct early_suspend *h)
if (info && drm_hdmitx_chk_mode_attr_sup(info->name,
suspend_fmt_attr))
setup_attr(suspend_fmt_attr);
extcon_set_state_sync(hdmitx_extcon_hdmi, EXTCON_DISP_HDMI,
hdev->tx_comm.hpd_state);
hdmitx_set_uevent(HDMITX_HPD_EVENT, hdev->tx_comm.hpd_state);
hdmitx_set_uevent(HDMITX_HDCPPWR_EVENT, HDMI_WAKEUP);
hdmitx_set_uevent(HDMITX_AUDIO_EVENT, hdev->tx_comm.hpd_state);
@@ -4172,7 +4185,8 @@ static ssize_t fake_plug_store(struct device *dev,
/*notify to drm hdmi*/
hdmitx_hpd_notify_unlocked(&hdev->tx_comm);
extcon_set_state_sync(hdmitx_extcon_hdmi, EXTCON_DISP_HDMI,
hdev->tx_comm.hpd_state);
hdmitx_set_uevent(HDMITX_HPD_EVENT, hdev->tx_comm.hpd_state);
return count;
@@ -5551,6 +5565,7 @@ static void hdmitx_hpd_plugin_handler(struct work_struct *work)
hdev->tx_comm.edid_parsing ?
hdev->tx_comm.edid_ptr : NULL);
extcon_set_state_sync(hdmitx_extcon_hdmi, EXTCON_DISP_HDMI, 1);
hdmitx_set_uevent(HDMITX_HPD_EVENT, 1);
/* audio uevent is used for android to
* register hdmi audio device, it should
@@ -5629,6 +5644,7 @@ static void hdmitx_hpd_plugout_handler(struct work_struct *work)
hdev->tx_comm.hpd_state = 0;
hdmitx_notify_hpd(hdev->tx_comm.hpd_state, NULL);
hdev->tx_hw.cntlmisc(&hdev->tx_hw, MISC_AVMUTE_OP, SET_AVMUTE);
extcon_set_state_sync(hdmitx_extcon_hdmi, EXTCON_DISP_HDMI, 0);
hdmitx_set_uevent(HDMITX_HPD_EVENT, 0);
hdmitx_set_uevent(HDMITX_AUDIO_EVENT, 0);
mutex_unlock(&hdmimode_mutex);
@@ -5660,6 +5676,7 @@ static void hdmitx_hpd_plugout_handler(struct work_struct *work)
hdev->tx_comm.hpd_state = 0;
hdmitx_notify_hpd(hdev->tx_comm.hpd_state, NULL);
extcon_set_state_sync(hdmitx_extcon_hdmi, EXTCON_DISP_HDMI, 0);
hdmitx_set_uevent(HDMITX_HPD_EVENT, 0);
hdmitx_set_uevent(HDMITX_AUDIO_EVENT, 0);
mutex_unlock(&hdmimode_mutex);
@@ -5926,6 +5943,30 @@ void hdmitx_hdcp_status(int hdmi_authenticated)
hdmi_authenticated);
}
/* for compliance with p/q/r/s/t, need both extcon and hdmi_event
* there're mixed android/kernel combination, P/Q
* only listen to extcon; while R/S only listen to uevent
* t need listen to extcon(only hdmi hpd) and uevent
*/
static int hdmitx_extcon_register(struct platform_device *pdev, struct device *dev)
{
int ret;
/*hdmitx extcon hdmi*/
hdmitx_extcon_hdmi = devm_extcon_dev_allocate(&pdev->dev, hdmi_extcon_cable);
if (IS_ERR(hdmitx_extcon_hdmi)) {
pr_info("%s[%d] hdmitx_extcon_hdmi allocated failed\n", __func__, __LINE__);
if (PTR_ERR(hdmitx_extcon_hdmi) != -ENODEV)
return PTR_ERR(hdmitx_extcon_hdmi);
hdmitx_extcon_hdmi = NULL;
}
ret = devm_extcon_dev_register(&pdev->dev, hdmitx_extcon_hdmi);
if (ret < 0)
pr_info("%s[%d] hdmitx_extcon_hdmi register failed\n", __func__, __LINE__);
return 0;
}
static void hdmitx_init_parameters(struct hdmitx_info *info)
{
memset(info, 0, sizeof(struct hdmitx_info));
@@ -6421,11 +6462,14 @@ static int amhdmitx_probe(struct platform_device *pdev)
aout_register_client(&hdmitx_notifier_nb_a);
#endif
spin_lock_init(&hdev->edid_spinlock);
hdmitx_extcon_register(pdev, dev);
/* update fmt_attr */
hdmitx_fmt_attr(hdev);
hdev->tx_comm.hpd_state = !!hdev->tx_hw.cntlmisc(&hdev->tx_hw, MISC_HPD_GPI_ST, 0);
hdmitx_notify_hpd(hdev->tx_comm.hpd_state, NULL);
hdmitx_set_uevent(HDMITX_HDCPPWR_EVENT, HDMI_WAKEUP);
INIT_WORK(&hdev->work_hdr, hdr_work_func);
+42 -1
View File
@@ -46,6 +46,9 @@
#include <linux/amlogic/media/vout/hdmi_tx21/hdmi_config.h>
#include <linux/amlogic/media/vout/hdmi_tx_ext.h>
#include <linux/amlogic/media/vrr/vrr.h>
#include <linux/extcon.h>
#include <linux/extcon-provider.h>
#include "hdmi_tx_ext.h"
#include "hdmi_tx.h"
@@ -161,6 +164,13 @@ static struct vout_device_s hdmitx_vdev = {
.video_mute = hdmitx21_video_mute_op,
};
static struct extcon_dev *hdmitx_extcon_hdmi;
static const unsigned int hdmi_extcon_cable[] = {
EXTCON_DISP_HDMI,
EXTCON_NONE,
};
static struct hdmitx_uevent hdmi_events[] = {
{
.type = HDMITX_HPD_EVENT,
@@ -329,6 +339,8 @@ static void hdmitx_late_resume(struct early_suspend *h)
hdev->tx_hw.cntlconfig(&hdev->tx_hw, CONF_AUDIO_MUTE_OP, AUDIO_MUTE);
/* set_disp_mode_auto(); */
extcon_set_state_sync(hdmitx_extcon_hdmi, EXTCON_DISP_HDMI,
hdev->tx_comm.hpd_state);
hdmitx21_set_uevent(HDMITX_HPD_EVENT, hdev->tx_comm.hpd_state);
hdmitx21_set_uevent(HDMITX_HDCPPWR_EVENT, HDMI_WAKEUP);
hdmitx21_set_uevent(HDMITX_AUDIO_EVENT, hdev->tx_comm.hpd_state);
@@ -3264,6 +3276,8 @@ static ssize_t fake_plug_store(struct device *dev,
/*notify to drm hdmi*/
hdmitx_hpd_notify_unlocked(&hdev->tx_comm);
extcon_set_state_sync(hdmitx_extcon_hdmi, EXTCON_DISP_HDMI,
hdev->tx_comm.hpd_state);
hdmitx21_set_uevent(HDMITX_HPD_EVENT, hdev->tx_comm.hpd_state);
return count;
@@ -4025,6 +4039,7 @@ static void hdmitx_hpd_plugin_handler(struct work_struct *work)
/*notify to drm hdmi*/
hdmitx_hpd_notify_unlocked(&hdev->tx_comm);
extcon_set_state_sync(hdmitx_extcon_hdmi, EXTCON_DISP_HDMI, 1);
hdmitx21_set_uevent(HDMITX_HPD_EVENT, 1);
hdmitx21_set_uevent(HDMITX_AUDIO_EVENT, 1);
/* Should be started at end of output */
@@ -4098,6 +4113,7 @@ static void hdmitx_hpd_plugout_handler(struct work_struct *work)
hdmitx_notify_hpd(hdev->tx_comm.hpd_state, NULL);
}
hdev->tx_hw.cntlmisc(&hdev->tx_hw, MISC_AVMUTE_OP, SET_AVMUTE);
extcon_set_state_sync(hdmitx_extcon_hdmi, EXTCON_DISP_HDMI, 0);
hdmitx21_set_uevent(HDMITX_HPD_EVENT, 0);
hdmitx21_set_uevent(HDMITX_AUDIO_EVENT, 0);
mutex_unlock(&hdev->tx_comm.setclk_mutex);
@@ -4128,6 +4144,7 @@ static void hdmitx_hpd_plugout_handler(struct work_struct *work)
/*notify to drm hdmi*/
hdmitx_hpd_notify_unlocked(&hdev->tx_comm);
extcon_set_state_sync(hdmitx_extcon_hdmi, EXTCON_DISP_HDMI, 0);
hdmitx21_set_uevent(HDMITX_HPD_EVENT, 0);
hdmitx21_set_uevent(HDMITX_AUDIO_EVENT, 0);
@@ -4326,6 +4343,30 @@ void hdmitx21_hdcp_status(int hdmi_authenticated)
hdmitx21_set_uevent(HDMITX_HDCP_EVENT, hdmi_authenticated);
}
/* for compliance with p/q/r/s/t, need both extcon and hdmi_event
* there're mixed combination, P/Q only listen to extcon;
* while R/S only listen to uevent
* t need listen to extcon(only hdmi hpd) and uevent
*/
static int hdmitx_extcon_register(struct platform_device *pdev, struct device *dev)
{
int ret;
/*hdmitx extcon hdmi*/
hdmitx_extcon_hdmi = devm_extcon_dev_allocate(&pdev->dev, hdmi_extcon_cable);
if (IS_ERR(hdmitx_extcon_hdmi)) {
pr_info("%s[%d] hdmitx_extcon_hdmi allocated failed\n", __func__, __LINE__);
if (PTR_ERR(hdmitx_extcon_hdmi) != -ENODEV)
return PTR_ERR(hdmitx_extcon_hdmi);
hdmitx_extcon_hdmi = NULL;
}
ret = devm_extcon_dev_register(&pdev->dev, hdmitx_extcon_hdmi);
if (ret < 0)
pr_info("%s[%d] hdmitx_extcon_hdmi register failed\n", __func__, __LINE__);
return 0;
}
static void hdmitx_init_parameters(struct hdmitx_info *info)
{
memset(info, 0, sizeof(struct hdmitx_info));
@@ -4744,7 +4785,7 @@ static int amhdmitx_probe(struct platform_device *pdev)
}
aout_register_client(&hdmitx_notifier_nb_a);
#endif
hdmitx_extcon_register(pdev, dev);
/* update fmt_attr */
hdmitx21_fmt_attr(hdev);
@@ -33,6 +33,7 @@
"V03.00.01.00.01.03.04 [20220803] [BUG] echo 1 > /sys/class/display/bist lead to panic\n" \
"V03.00.01.00.01.03.05 [20220913] [BUG] add DDC reset before do EDID transaction\n" \
"V03.00.01.00.01.03.06 [20220915] [BUG] Don't reset variables when parse a new block\n" \
"V03.00.01.00.01.03.07 [20220926] [BUG] enable null packt for special TV\n"
"V03.00.01.00.01.03.07 [20220926] [BUG] enable null packt for special TV\n" \
"V03.00.01.00.01.03.08 [20221012] [NEW] add hdmi hpd extcon\n"
#endif // __HDMI20_VERSION_H__
@@ -36,6 +36,7 @@
"V03.00.00.00.03.03.06 [20220829] [NEWF] support avi content type\n" \
"V03.00.00.00.03.03.07 [20220913] [BUGFIX] add DDC reset before do EDID transaction\n" \
"V03.00.00.00.03.03.08 [20220919] [BUG] y422 mapping and Enable the dither\n" \
"V03.00.00.00.03.03.09 [20220915] [BUG] Don't reset variables when parse a new block\n"
"V03.00.00.00.03.03.09 [20220915] [BUG] Don't reset variables when parse a new block\n" \
"V03.00.00.00.03.03.10 [20221012] [NEW] add hdmi hpd extcon\n"
#endif // __HDMI21_VERSION_H__