OMAP: DSS2: HDMI: implement detect()
authorTomi Valkeinen <tomi.valkeinen@ti.com>
Mon, 29 Aug 2011 15:10:20 +0000 (18:10 +0300)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Fri, 30 Sep 2011 13:16:47 +0000 (16:16 +0300)
Implement detect() by checking the hot plug detect status.

The implementation is not very good, as it always turns on the HDMI
output to get the detection working. HDMI driver needs improvements so
that we could enable only core parts of it.

Cc: Mythri P K <mythripk@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
drivers/video/omap2/dss/dss.h
drivers/video/omap2/dss/dss_features.c
drivers/video/omap2/dss/hdmi.c
drivers/video/omap2/dss/hdmi_panel.c
drivers/video/omap2/dss/ti_hdmi.h
drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c

index 2e7799c82960ea42c9019da377b57533582a026e..f58c302b730d3a6c7da22c1415ded6754b7e928f 100644 (file)
@@ -495,6 +495,7 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev);
 int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
                                        struct omap_video_timings *timings);
 int omapdss_hdmi_read_edid(u8 *buf, int len);
+bool omapdss_hdmi_detect(void);
 int hdmi_panel_init(void);
 void hdmi_panel_exit(void);
 
index 076f399a91533362fa3b09df993008afe7e56605..ab4166590a74961e6a16f232ff51136abdd5353e 100644 (file)
@@ -440,6 +440,7 @@ static const struct ti_hdmi_ip_ops omap4_hdmi_functions = {
        .phy_enable             =       ti_hdmi_4xxx_phy_enable,
        .phy_disable            =       ti_hdmi_4xxx_phy_disable,
        .read_edid              =       ti_hdmi_4xxx_read_edid,
+       .detect                 =       ti_hdmi_4xxx_detect,
        .pll_enable             =       ti_hdmi_4xxx_pll_enable,
        .pll_disable            =       ti_hdmi_4xxx_pll_disable,
        .video_enable           =       ti_hdmi_4xxx_wp_video_start,
index fb85ce5a8ab41af52b6ca1f9d9c7fc6684d04b58..7818670026622877ab957a291eb01ec195ea970e 100644 (file)
@@ -449,6 +449,23 @@ int omapdss_hdmi_read_edid(u8 *buf, int len)
        return r;
 }
 
+bool omapdss_hdmi_detect(void)
+{
+       int r;
+
+       mutex_lock(&hdmi.lock);
+
+       r = hdmi_runtime_get();
+       BUG_ON(r);
+
+       r = hdmi.ip_data.ops->detect(&hdmi.ip_data);
+
+       hdmi_runtime_put();
+       mutex_unlock(&hdmi.lock);
+
+       return r == 1;
+}
+
 int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
 {
        int r = 0;
index 71aa8134f4fbe9d1290d5b2249777f5d65e92ef9..533d5dc634d256374a22b9a2da8a8eb0453f9a34 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/mutex.h>
 #include <linux/module.h>
 #include <video/omapdss.h>
+#include <linux/slab.h>
 
 #include "dss.h"
 
@@ -198,6 +199,29 @@ err:
        return r;
 }
 
+static bool hdmi_detect(struct omap_dss_device *dssdev)
+{
+       int r;
+
+       mutex_lock(&hdmi.hdmi_lock);
+
+       if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
+               r = omapdss_hdmi_display_enable(dssdev);
+               if (r)
+                       goto err;
+       }
+
+       r = omapdss_hdmi_detect();
+
+       if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
+                       dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
+               omapdss_hdmi_display_disable(dssdev);
+err:
+       mutex_unlock(&hdmi.hdmi_lock);
+
+       return r;
+}
+
 static struct omap_dss_driver hdmi_driver = {
        .probe          = hdmi_panel_probe,
        .remove         = hdmi_panel_remove,
@@ -209,6 +233,7 @@ static struct omap_dss_driver hdmi_driver = {
        .set_timings    = hdmi_set_timings,
        .check_timings  = hdmi_check_timings,
        .read_edid      = hdmi_read_edid,
+       .detect         = hdmi_detect,
        .driver                 = {
                .name   = "hdmi_panel",
                .owner  = THIS_MODULE,
index 390cd85b122f8e4d64bcdd50b601070d6e36e07e..d48603c8e23d631e5738f3a5596c4bd37f9bedd4 100644 (file)
@@ -94,6 +94,8 @@ struct ti_hdmi_ip_ops {
 
        int (*read_edid)(struct hdmi_ip_data *ip_data, u8 *edid, int len);
 
+       bool (*detect)(struct hdmi_ip_data *ip_data);
+
        int (*pll_enable)(struct hdmi_ip_data *ip_data);
 
        void (*pll_disable)(struct hdmi_ip_data *ip_data);
@@ -114,6 +116,7 @@ struct hdmi_ip_data {
 int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data);
 void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data);
 int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len);
+bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data);
 void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start);
 int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data);
 void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data);
index e9885dcc4122106503b503d4c7a73f894e96b8b2..da7fe50fc127bf3bd242d24f56444bd8509fbcd1 100644 (file)
@@ -416,6 +416,18 @@ int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data,
        return l;
 }
 
+bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data)
+{
+       int r;
+
+       void __iomem *base = hdmi_core_sys_base(ip_data);
+
+       /* HPD */
+       r = REG_GET(base, HDMI_CORE_SYS_SYS_STAT, 1, 1);
+
+       return r == 1;
+}
+
 static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
                        struct hdmi_core_infoframe_avi *avi_cfg,
                        struct hdmi_core_packet_enable_repeat *repeat_cfg)