#include <linux/of_platform.h>
#include "sde_kms.h"
+#include "sde_connector.h"
#include "msm_drv.h"
#include "sde_hdmi.h"
connector = sde_hdmi->ctrl.ctrl->connector;
drm_helper_hpd_irq_event(connector->dev);
+
+ sde_hdmi_notify_clients(connector, connector->status);
}
static void _sde_hdmi_connector_irq(struct sde_hdmi *sde_hdmi)
return rc;
}
+void sde_hdmi_notify_clients(struct drm_connector *connector,
+ enum drm_connector_status status)
+{
+ struct sde_connector *c_conn = to_sde_connector(connector);
+ struct sde_hdmi *display = (struct sde_hdmi *)c_conn->display;
+ int state = (status == connector_status_connected) ?
+ EXT_DISPLAY_CABLE_CONNECT : EXT_DISPLAY_CABLE_DISCONNECT;
+
+ if (display && display->ext_audio_data.intf_ops.hpd) {
+ struct hdmi *hdmi = display->ctrl.ctrl;
+ u32 flags = MSM_EXT_DISP_HPD_VIDEO;
+
+ if (hdmi->hdmi_mode)
+ flags |= MSM_EXT_DISP_HPD_AUDIO;
+
+ display->ext_audio_data.intf_ops.hpd(display->ext_pdev,
+ display->ext_audio_data.type, state, flags);
+ }
+}
+
+void sde_hdmi_ack_state(struct drm_connector *connector,
+ enum drm_connector_status status)
+{
+ struct sde_connector *c_conn = to_sde_connector(connector);
+ struct sde_hdmi *display = (struct sde_hdmi *)c_conn->display;
+
+ if (display) {
+ struct hdmi *hdmi = display->ctrl.ctrl;
+
+ if (hdmi->hdmi_mode && display->ext_audio_data.intf_ops.notify)
+ display->ext_audio_data.intf_ops.notify(
+ display->ext_pdev, status);
+ }
+}
+
void sde_hdmi_set_mode(struct hdmi *hdmi, bool power_on)
{
uint32_t ctrl = 0;
* Return: error code.
*/
int sde_hdmi_config_avmute(struct hdmi *hdmi, bool set);
+
+/**
+ * sde_hdmi_notify_clients() - notify hdmi clients of the connection status.
+ * @connector: Handle to the drm_connector.
+ * @status: connection status.
+ *
+ * Return: void.
+ */
+void sde_hdmi_notify_clients(struct drm_connector *connector,
+ enum drm_connector_status status);
+
+/**
+ * sde_hdmi_ack_state() - acknowledge the connection status.
+ * @connector: Handle to the drm_connector.
+ * @status: connection status.
+ *
+ * Return: void.
+ */
+void sde_hdmi_ack_state(struct drm_connector *connector,
+ enum drm_connector_status status);
+
#else /*#ifdef CONFIG_DRM_SDE_HDMI*/
static inline u32 sde_hdmi_get_num_of_displays(void)
#include "drm_edid.h"
#include "sde_kms.h"
+#include "sde_connector.h"
#include "sde_hdmi.h"
#include "hdmi.h"
if (hdmi->hdcp_ctrl && hdmi->is_hdcp_supported)
hdmi_hdcp_ctrl_on(hdmi->hdcp_ctrl);
+
+ sde_hdmi_ack_state(hdmi->connector, EXT_DISPLAY_CABLE_CONNECT);
+}
+
+static void sde_hdmi_force_update_audio(struct drm_connector *connector,
+ enum drm_connector_status status)
+{
+ struct sde_connector *c_conn = to_sde_connector(connector);
+ struct sde_hdmi *display = (struct sde_hdmi *)c_conn->display;
+
+ if (display && display->non_pluggable) {
+ display->ext_audio_data.intf_ops.hpd(display->ext_pdev,
+ display->ext_audio_data.type,
+ status,
+ MSM_EXT_DISP_HPD_AUDIO);
+ }
}
static void _sde_hdmi_bridge_enable(struct drm_bridge *bridge)
{
+ struct sde_hdmi_bridge *sde_hdmi_bridge = to_hdmi_bridge(bridge);
+ struct hdmi *hdmi = sde_hdmi_bridge->hdmi;
+
+ /* force update audio ops when there's no HPD event */
+ sde_hdmi_force_update_audio(hdmi->connector,
+ EXT_DISPLAY_CABLE_CONNECT);
}
static void _sde_hdmi_bridge_disable(struct drm_bridge *bridge)
{
+ struct sde_hdmi_bridge *sde_hdmi_bridge = to_hdmi_bridge(bridge);
+ struct hdmi *hdmi = sde_hdmi_bridge->hdmi;
+
+ /* force update audio ops when there's no HPD event */
+ sde_hdmi_force_update_audio(hdmi->connector,
+ EXT_DISPLAY_CABLE_DISCONNECT);
}
static void _sde_hdmi_bridge_post_disable(struct drm_bridge *bridge)
_sde_hdmi_bridge_power_off(bridge);
hdmi->power_on = false;
}
+
+ sde_hdmi_ack_state(hdmi->connector, EXT_DISPLAY_CABLE_DISCONNECT);
}
static void _sde_hdmi_bridge_set_avi_infoframe(struct hdmi *hdmi,