Message ID | 20190704135208.32104-2-narmstrong@baylibre.com |
---|---|
State | Accepted |
Commit | 1c1ed441b0d1d7d5fbf02cf89a390c04b18f8ba3 |
Delegated to: | Anatolij Gustschin |
Headers | show |
Series | video: add support for EDID timings validation | expand |
On 04/07/2019 15:52, Neil Armstrong wrote: > The original edid_get_timing() function returns the first valid timing, > but on some plaforms, we could only supports a subset of the listed > monitot's navite timing. > > Let's introduce a edid_get_timing_validate() adding a mode_valid callback > including a private cookie pointer. > > If the callback returns false, the current timing is discared and the next > one is checked. If no valid & supported timings are found, the function > would return an error. > > Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> > --- > common/edid.c | 22 +++++++++++++++++++--- > include/edid.h | 22 ++++++++++++++++++++++ > 2 files changed, 41 insertions(+), 3 deletions(-) > > diff --git a/common/edid.c b/common/edid.c > index 90d1167f6e..f244d26e04 100644 > --- a/common/edid.c > +++ b/common/edid.c > @@ -168,8 +168,12 @@ static bool cea_is_hdmi_vsdb_present(struct edid_cea861_info *info) > return false; > } > > -int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing, > - int *panel_bits_per_colourp) > +int edid_get_timing_validate(u8 *buf, int buf_size, > + struct display_timing *timing, > + int *panel_bits_per_colourp, > + bool (*mode_valid)(void *priv, > + const struct display_timing *timing), > + void *mode_valid_priv) > { > struct edid1_info *edid = (struct edid1_info *)buf; > bool timing_done; > @@ -193,7 +197,11 @@ int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing, > desc = &edid->monitor_details.descriptor[i]; > if (desc->zero_flag_1 != 0) { > decode_timing((u8 *)desc, timing); > - timing_done = true; > + if (mode_valid) > + timing_done = mode_valid(mode_valid_priv, > + timing); > + else > + timing_done = true; > break; the break is wrong, it should be : if (timing_done) break; I'll send a v2. Neil > } > } > @@ -225,6 +233,14 @@ int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing, > return 0; > } > > +int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing, > + int *panel_bits_per_colourp) > +{ > + return edid_get_timing_validate(buf, buf_size, timing, > + panel_bits_per_colourp, NULL, NULL); > +} > + > + > /** > * Snip the tailing whitespace/return of a string. > * > diff --git a/include/edid.h b/include/edid.h > index f05d2b82f2..2562733061 100644 > --- a/include/edid.h > +++ b/include/edid.h > @@ -306,6 +306,28 @@ int edid_get_ranges(struct edid1_info *edid, unsigned int *hmin, > > struct display_timing; > > +/** > + * edid_get_timing_validate() - Get basic digital display parameters with > + * mode selection callback > + * > + * @param buf Buffer containing EDID data > + * @param buf_size Size of buffer in bytes > + * @param timing Place to put preferring timing information > + * @param panel_bits_per_colourp Place to put the number of bits per > + * colour supported by the panel. This will be set to > + * -1 if not available > + * @param mode_valid Callback validating mode, returning true is mode is > + * supported, false otherwise. > + * @parem valid_priv Pointer to private data for mode_valid callback > + * @return 0 if timings are OK, -ve on error > + */ > +int edid_get_timing_validate(u8 *buf, int buf_size, > + struct display_timing *timing, > + int *panel_bits_per_colourp, > + bool (*mode_valid)(void *priv, > + const struct display_timing *timing), > + void *mode_valid_priv); > + > /** > * edid_get_timing() - Get basic digital display parameters > * >
diff --git a/common/edid.c b/common/edid.c index 90d1167f6e..f244d26e04 100644 --- a/common/edid.c +++ b/common/edid.c @@ -168,8 +168,12 @@ static bool cea_is_hdmi_vsdb_present(struct edid_cea861_info *info) return false; } -int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing, - int *panel_bits_per_colourp) +int edid_get_timing_validate(u8 *buf, int buf_size, + struct display_timing *timing, + int *panel_bits_per_colourp, + bool (*mode_valid)(void *priv, + const struct display_timing *timing), + void *mode_valid_priv) { struct edid1_info *edid = (struct edid1_info *)buf; bool timing_done; @@ -193,7 +197,11 @@ int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing, desc = &edid->monitor_details.descriptor[i]; if (desc->zero_flag_1 != 0) { decode_timing((u8 *)desc, timing); - timing_done = true; + if (mode_valid) + timing_done = mode_valid(mode_valid_priv, + timing); + else + timing_done = true; break; } } @@ -225,6 +233,14 @@ int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing, return 0; } +int edid_get_timing(u8 *buf, int buf_size, struct display_timing *timing, + int *panel_bits_per_colourp) +{ + return edid_get_timing_validate(buf, buf_size, timing, + panel_bits_per_colourp, NULL, NULL); +} + + /** * Snip the tailing whitespace/return of a string. * diff --git a/include/edid.h b/include/edid.h index f05d2b82f2..2562733061 100644 --- a/include/edid.h +++ b/include/edid.h @@ -306,6 +306,28 @@ int edid_get_ranges(struct edid1_info *edid, unsigned int *hmin, struct display_timing; +/** + * edid_get_timing_validate() - Get basic digital display parameters with + * mode selection callback + * + * @param buf Buffer containing EDID data + * @param buf_size Size of buffer in bytes + * @param timing Place to put preferring timing information + * @param panel_bits_per_colourp Place to put the number of bits per + * colour supported by the panel. This will be set to + * -1 if not available + * @param mode_valid Callback validating mode, returning true is mode is + * supported, false otherwise. + * @parem valid_priv Pointer to private data for mode_valid callback + * @return 0 if timings are OK, -ve on error + */ +int edid_get_timing_validate(u8 *buf, int buf_size, + struct display_timing *timing, + int *panel_bits_per_colourp, + bool (*mode_valid)(void *priv, + const struct display_timing *timing), + void *mode_valid_priv); + /** * edid_get_timing() - Get basic digital display parameters *
The original edid_get_timing() function returns the first valid timing, but on some plaforms, we could only supports a subset of the listed monitot's navite timing. Let's introduce a edid_get_timing_validate() adding a mode_valid callback including a private cookie pointer. If the callback returns false, the current timing is discared and the next one is checked. If no valid & supported timings are found, the function would return an error. Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> --- common/edid.c | 22 +++++++++++++++++++--- include/edid.h | 22 ++++++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-)