Re: [PATCH] fbdev: add a function to parse further EDID Detailed Timing Descriptors

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Guennadi,
    Not sure how you're using the edid but you can get all 4 DTDs by
calling fb_edid_to_monspecs() then calling fb_videomode_to_var() on
each of the entries in monspecs.modedb.  This is still lacking as
modern monitors/tvs can have multiple EDID blocks.  My recent patch
[1] is a proposal for addressing that.

Cheers,
    Erik

[1] http://marc.info/?l=linux-fbdev&m=128208740412602&w=2

On Thu, Aug 19, 2010 at 11:48 PM, Guennadi Liakhovetski
<g.liakhovetski@xxxxxx> wrote:
> 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@xxxxxx>
> ---
>  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
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Video for Linux]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Tourism]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux