summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Ryabukhin <vryabukhin@nvidia.com>2011-08-19 15:55:50 +0900
committerAnnamaria Pyreddy <apyreddy@nvidia.com>2011-08-24 15:05:12 -0700
commitf092fc6c56675bc1cf3396bb6a0b439d8a13d3e8 (patch)
treef62c597399942fcd708a48e14ec3bbd0d7360f48
parent914df2dea16b54acdf362784ebe414d961748360 (diff)
tegra: HDMI: add underscan capability exposure via sysfs
TVs/monitors which do not support underscan will crop HDMI picture. Underscan information might be needed in userspace to adjust HDMI resolution so that the picture will be shown correctly on such devices. Bug 854822 Change-Id: Ic9b8ac27853884558950a65e8c43452cbef68108 Reviewed-on: http://git-master/r/48063 Tested-by: Victor Ryabukhin <vryabukhin@nvidia.com> Reviewed-by: Alex Courbot <acourbot@nvidia.com> Reviewed-by: Victor Ryabukhin <vryabukhin@nvidia.com> Reviewed-by: Michael Frydrych <mfrydrych@nvidia.com> Reviewed-by: Jonathan Mayo <jmayo@nvidia.com> Reviewed-by: Sachin Nikam <snikam@nvidia.com> Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
-rw-r--r--drivers/video/tegra/dc/edid.c15
-rw-r--r--drivers/video/tegra/dc/edid.h2
-rw-r--r--drivers/video/tegra/dc/hdmi.c21
3 files changed, 37 insertions, 1 deletions
diff --git a/drivers/video/tegra/dc/edid.c b/drivers/video/tegra/dc/edid.c
index 0ac59d9c82a3..67bb2e5b2b2a 100644
--- a/drivers/video/tegra/dc/edid.c
+++ b/drivers/video/tegra/dc/edid.c
@@ -32,6 +32,7 @@ struct tegra_edid {
u8 *data;
unsigned len;
u8 support_stereo;
+ u8 support_underscan;
};
#if defined(DEBUG) || defined(CONFIG_DEBUG_FS)
@@ -171,6 +172,11 @@ int tegra_edid_parse_ext_block(u8 *raw, int idx, struct tegra_edid *edid)
ptr = &raw[4];
+ if (raw[3] & 0x80)
+ edid->support_underscan = 1;
+ else
+ edid->support_underscan = 0;
+
while (ptr < &raw[idx]) {
tmp = *ptr;
len = tmp & 0x1f;
@@ -244,6 +250,7 @@ int tegra_edid_get_monspecs(struct tegra_edid *edid, struct fb_monspecs *specs)
int extension_blocks;
edid->support_stereo = 0;
+ edid->support_underscan = 0;
ret = tegra_edid_read_block(edid, 0, edid->data);
if (ret)
@@ -285,6 +292,14 @@ int tegra_edid_get_monspecs(struct tegra_edid *edid, struct fb_monspecs *specs)
return 0;
}
+int tegra_edid_underscan_supported(struct tegra_edid *edid)
+{
+ if (!edid)
+ return 0;
+
+ return edid->support_underscan;
+}
+
struct tegra_edid *tegra_edid_create(int bus)
{
struct tegra_edid *edid;
diff --git a/drivers/video/tegra/dc/edid.h b/drivers/video/tegra/dc/edid.h
index 821da90a8b4f..027bb8439896 100644
--- a/drivers/video/tegra/dc/edid.h
+++ b/drivers/video/tegra/dc/edid.h
@@ -28,4 +28,6 @@ void tegra_edid_destroy(struct tegra_edid *edid);
int tegra_edid_get_monspecs(struct tegra_edid *edid, struct fb_monspecs *specs);
+int tegra_edid_underscan_supported(struct tegra_edid *edid);
+
#endif
diff --git a/drivers/video/tegra/dc/hdmi.c b/drivers/video/tegra/dc/hdmi.c
index ecf889cb4dd3..d935d5e4aee7 100644
--- a/drivers/video/tegra/dc/hdmi.c
+++ b/drivers/video/tegra/dc/hdmi.c
@@ -26,6 +26,7 @@
#include <linux/spinlock.h>
#include <linux/switch.h>
#include <linux/workqueue.h>
+#include <linux/device.h>
#include <mach/clk.h>
#include <mach/dc.h>
@@ -673,11 +674,26 @@ static void tegra_dc_hdmi_resume(struct tegra_dc *dc)
tegra_nvhdcp_resume(hdmi->nvhdcp);
}
+static ssize_t underscan_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct tegra_dc_hdmi_data *hdmi =
+ container_of(dev_get_drvdata(dev), struct tegra_dc_hdmi_data, hpd_switch);
+
+ if (hdmi->edid)
+ return sprintf(buf, "%d\n", tegra_edid_underscan_supported(hdmi->edid));
+ else
+ return 0;
+}
+
+static DEVICE_ATTR(underscan, S_IRUGO | S_IWUSR, underscan_show, NULL);
+
static int tegra_dc_hdmi_init(struct tegra_dc *dc)
{
struct tegra_dc_hdmi_data *hdmi;
struct resource *res;
struct resource *base_res;
+ int ret;
void __iomem *base;
struct clk *clk = NULL;
struct clk *disp1_clk = NULL;
@@ -768,7 +784,10 @@ static int tegra_dc_hdmi_init(struct tegra_dc *dc)
spin_lock_init(&hdmi->suspend_lock);
hdmi->hpd_switch.name = "hdmi";
- switch_dev_register(&hdmi->hpd_switch);
+ ret = switch_dev_register(&hdmi->hpd_switch);
+
+ if (!ret)
+ device_create_file(hdmi->hpd_switch.dev, &dev_attr_underscan);
dc->out->depth = 24;