diff options
author | Victor Ryabukhin <vryabukhin@nvidia.com> | 2011-08-19 15:55:50 +0900 |
---|---|---|
committer | Annamaria Pyreddy <apyreddy@nvidia.com> | 2011-08-24 15:05:12 -0700 |
commit | f092fc6c56675bc1cf3396bb6a0b439d8a13d3e8 (patch) | |
tree | f62c597399942fcd708a48e14ec3bbd0d7360f48 | |
parent | 914df2dea16b54acdf362784ebe414d961748360 (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.c | 15 | ||||
-rw-r--r-- | drivers/video/tegra/dc/edid.h | 2 | ||||
-rw-r--r-- | drivers/video/tegra/dc/hdmi.c | 21 |
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; |