From: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
To: linux-fbdev@vger.kernel.org
Subject: [PATCH] fbdev: add a function to parse further EDID Detailed Timing
Date: Fri, 20 Aug 2010 06:48:36 +0000 [thread overview]
Message-ID: <Pine.LNX.4.64.1008200847020.6103@axis700.grange> (raw)
Currently a function is available to parse the first EDID Detailed Timing
Descriptor (DTD) block. However, EDID can contain up to four DTDs. Add a
function to parse further DTDs.
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
drivers/video/fbmon.c | 74 ++++++++++++++++++++++++++++++++++++------------
include/linux/fb.h | 2 +
2 files changed, 57 insertions(+), 19 deletions(-)
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 563a98b..03de586 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -866,6 +866,29 @@ static void get_monspecs(unsigned char *edid, struct fb_monspecs *specs)
}
}
+static void fb_edid_to_var(unsigned char *block, struct fb_var_screeninfo *var)
+{
+ var->xres = var->xres_virtual = H_ACTIVE;
+ var->yres = var->yres_virtual = V_ACTIVE;
+ var->height = var->width = 0;
+ var->right_margin = H_SYNC_OFFSET;
+ var->left_margin = (H_ACTIVE + H_BLANKING) -
+ (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH);
+ var->upper_margin = V_BLANKING - V_SYNC_OFFSET -
+ V_SYNC_WIDTH;
+ var->lower_margin = V_SYNC_OFFSET;
+ var->hsync_len = H_SYNC_WIDTH;
+ var->vsync_len = V_SYNC_WIDTH;
+ var->pixclock = PIXEL_CLOCK;
+ var->pixclock /= 1000;
+ var->pixclock = KHZ2PICOS(var->pixclock);
+
+ if (HSYNC_POSITIVE)
+ var->sync |= FB_SYNC_HOR_HIGH_ACT;
+ if (VSYNC_POSITIVE)
+ var->sync |= FB_SYNC_VERT_HIGH_ACT;
+}
+
int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var)
{
int i;
@@ -884,31 +907,38 @@ int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var)
for (i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) {
if (edid_is_timing_block(block)) {
- var->xres = var->xres_virtual = H_ACTIVE;
- var->yres = var->yres_virtual = V_ACTIVE;
- var->height = var->width = 0;
- var->right_margin = H_SYNC_OFFSET;
- var->left_margin = (H_ACTIVE + H_BLANKING) -
- (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH);
- var->upper_margin = V_BLANKING - V_SYNC_OFFSET -
- V_SYNC_WIDTH;
- var->lower_margin = V_SYNC_OFFSET;
- var->hsync_len = H_SYNC_WIDTH;
- var->vsync_len = V_SYNC_WIDTH;
- var->pixclock = PIXEL_CLOCK;
- var->pixclock /= 1000;
- var->pixclock = KHZ2PICOS(var->pixclock);
-
- if (HSYNC_POSITIVE)
- var->sync |= FB_SYNC_HOR_HIGH_ACT;
- if (VSYNC_POSITIVE)
- var->sync |= FB_SYNC_VERT_HIGH_ACT;
+ fb_edid_to_var(block, var);
return 0;
}
}
return 1;
}
+int fb_parse_edid_index(unsigned char *edid, struct fb_var_screeninfo *var,
+ unsigned int idx)
+{
+ unsigned char *block;
+
+ if (edid = NULL || var = NULL || idx > 3)
+ return 1;
+
+ if (!(edid_checksum(edid)))
+ return 1;
+
+ if (!(edid_check_header(edid)))
+ return 1;
+
+ block = edid + DETAILED_TIMING_DESCRIPTIONS_START +
+ idx * DETAILED_TIMING_DESCRIPTION_SIZE;
+
+ if (edid_is_timing_block(block)) {
+ fb_edid_to_var(block, var);
+ return 0;
+ }
+
+ return 1;
+}
+
void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
{
unsigned char *block;
@@ -1285,6 +1315,11 @@ int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var)
{
return 1;
}
+int fb_parse_edid_index(unsigned char *edid, struct fb_var_screeninfo *var,
+ unsigned int idx)
+{
+ return 1;
+}
void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
{
specs = NULL;
@@ -1395,6 +1430,7 @@ const unsigned char *fb_firmware_edid(struct device *device)
EXPORT_SYMBOL(fb_firmware_edid);
EXPORT_SYMBOL(fb_parse_edid);
+EXPORT_SYMBOL(fb_parse_edid_index);
EXPORT_SYMBOL(fb_edid_to_monspecs);
EXPORT_SYMBOL(fb_get_mode);
EXPORT_SYMBOL(fb_validate_mode);
diff --git a/include/linux/fb.h b/include/linux/fb.h
index f0268de..3649c47 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -1083,6 +1083,8 @@ extern int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var,
extern int fb_validate_mode(const struct fb_var_screeninfo *var,
struct fb_info *info);
extern int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var);
+extern int fb_parse_edid_index(unsigned char *edid, struct fb_var_screeninfo *var,
+ unsigned int idx);
extern const unsigned char *fb_firmware_edid(struct device *device);
extern void fb_edid_to_monspecs(unsigned char *edid,
struct fb_monspecs *specs);
--
1.7.2
next reply other threads:[~2010-08-20 6:48 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-08-20 6:48 Guennadi Liakhovetski [this message]
2010-08-20 7:23 ` [PATCH] fbdev: add a function to parse further EDID Detailed Erik Gilling
2010-10-20 15:12 ` Guennadi Liakhovetski
2010-10-20 23:19 ` Andrew Morton
2010-10-20 23:56 ` Dave Airlie
2010-10-21 8:26 ` Geert Uytterhoeven
2010-10-21 8:47 ` Dave Airlie
2010-10-21 14:08 ` Guennadi Liakhovetski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Pine.LNX.4.64.1008200847020.6103@axis700.grange \
--to=g.liakhovetski@gmx.de \
--cc=linux-fbdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox