drm: bridge: dw-hdmi: using extcon instead of switch

Switch is no longer available in kernel 4.19, so
we use extcon instead.

the hdmi connect status node:

/sys/class/extcon/extconX/state

HDMI=0:
	hdmi is disconnected
HDMI=1:
	hdmi is connected

Change-Id: I806d8fd5b9b4b36f15aa6aec275fad2ecf122e91
Signed-off-by: Algea Cao <algea.cao@rock-chips.com>
This commit is contained in:
Algea Cao
2019-11-06 11:06:59 +08:00
parent dc38189e70
commit 3187deef82

View File

@@ -9,6 +9,8 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/extcon.h>
#include <linux/extcon-provider.h>
#include <linux/hdmi.h>
#include <linux/irq.h>
#include <linux/module.h>
@@ -49,6 +51,11 @@
#define HDMI14_MAX_TMDSCLK 340000000
static const unsigned int dw_hdmi_cable[] = {
EXTCON_DISP_HDMI,
EXTCON_NONE,
};
enum hdmi_datamap {
RGB444_8B = 0x01,
RGB444_10B = 0x03,
@@ -256,6 +263,8 @@ struct dw_hdmi {
unsigned int audio_n;
bool audio_enable;
struct extcon_dev *extcon;
unsigned int reg_shift;
struct regmap *regm;
void (*enable_audio)(struct dw_hdmi *hdmi);
@@ -334,6 +343,8 @@ static void repo_hpd_event(struct work_struct *p_work)
drm_helper_hpd_irq_event(hdmi->bridge.dev);
drm_bridge_hpd_notify(&hdmi->bridge, status);
}
extcon_set_state_sync(hdmi->extcon, EXTCON_DISP_HDMI, hdmi->hpd_state);
}
static bool check_hdmi_irq(struct dw_hdmi *hdmi, int intr_stat,
@@ -2715,6 +2726,16 @@ static void dw_hdmi_connector_force(struct drm_connector *connector)
connector);
mutex_lock(&hdmi->mutex);
if (!hdmi->disabled && hdmi->force != connector->force) {
if (connector->force == DRM_FORCE_OFF)
extcon_set_state_sync(hdmi->extcon, EXTCON_DISP_HDMI,
false);
else if (connector->force == DRM_FORCE_ON)
extcon_set_state_sync(hdmi->extcon, EXTCON_DISP_HDMI,
true);
}
hdmi->force = connector->force;
dw_hdmi_update_power(hdmi);
dw_hdmi_update_phy_mask(hdmi);
@@ -3650,6 +3671,8 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
mutex_init(&hdmi->cec_notifier_mutex);
spin_lock_init(&hdmi->audio_lock);
dev_set_name(dev, "hdmi");
ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
if (ddc_node) {
hdmi->ddc = of_get_i2c_adapter_by_node(ddc_node);
@@ -3874,6 +3897,29 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
hdmi->cec = platform_device_register_full(&pdevinfo);
}
hdmi->extcon = devm_extcon_dev_allocate(hdmi->dev, dw_hdmi_cable);
if (IS_ERR(hdmi->extcon)) {
ret = PTR_ERR(hdmi->extcon);
dev_err(hdmi->dev, "allocate extcon failed: %d\n", ret);
goto err_iahb;
}
ret = devm_extcon_dev_register(hdmi->dev, hdmi->extcon);
if (ret) {
dev_err(hdmi->dev, "failed to register extcon: %d\n",
ret);
goto err_iahb;
}
ret = extcon_set_property_capability(hdmi->extcon, EXTCON_DISP_HDMI,
EXTCON_PROP_DISP_HPD);
if (ret) {
dev_err(hdmi->dev,
"failed to set USB property capability: %d\n",
ret);
goto err_iahb;
}
drm_bridge_add(&hdmi->bridge);
dw_hdmi_register_debugfs(dev, hdmi);