diff --git a/arch/arm/src/am335x/am335x_edid.c b/arch/arm/src/am335x/am335x_edid.c index 6e774e5f763..fd4d226e80a 100644 --- a/arch/arm/src/am335x/am335x_edid.c +++ b/arch/arm/src/am335x/am335x_edid.c @@ -380,7 +380,7 @@ void am335x_lcd_edid(FAR const uint8_t *edid, size_t edid_len, if (videomode == NULL) { - videomode = videomode_lookup("640x480x60"); + videomode = videomode_lookup_by_name("640x480x60"); DEBUGASSERT(videomode != NULL); } diff --git a/configs/beaglebone-black/src/am335x_lcd.c b/configs/beaglebone-black/src/am335x_lcd.c index b01145defde..905aa1510ab 100644 --- a/configs/beaglebone-black/src/am335x_lcd.c +++ b/configs/beaglebone-black/src/am335x_lcd.c @@ -152,7 +152,7 @@ int up_fbinitialize(int display) #else /* Lookup the video mode corresponding to the default video mode */ - videomode = videomode_lookup(CONFIG_BEAGLEBONE_VIDEOMODE); + videomode = videomode_lookup_by_name(CONFIG_BEAGLEBONE_VIDEOMODE); if (videomode == NULL) { lcderr("ERROR: Videomode \"%s\" is not supported.\n", diff --git a/include/nuttx/video/videomode.h b/include/nuttx/video/videomode.h index 87e0aa62ed6..04dd1818c8c 100644 --- a/include/nuttx/video/videomode.h +++ b/include/nuttx/video/videomode.h @@ -133,7 +133,39 @@ void sort_videomodes(FAR struct videomode_s *modes, * ****************************************************************************/ -FAR const struct videomode_s *videomode_lookup(FAR const char *name); +FAR const struct videomode_s *videomode_lookup_by_name(FAR const char *name); + +/**************************************************************************** + * Name: videomode_lookup_by_dotclock + * + * Description: + * Find the video mode in a look-up table with the matching width and + * height and the closest dot clock that does not exceed the requested + * dot clock. + * + ****************************************************************************/ + +#if 0 /* Not used */ +FAR const struct videomode_s * + videomode_lookup_by_dotclock(uint16_t width, uint16_t height, + uint32_t dotclock); +#endif + +/**************************************************************************** + * Name: videomode_lookup_by_refresh + * + * Description: + * Find the video mode in a look-up table with the matching width and + * height and the closest refresh rate that does not exceed the requested + * rate. + * + ****************************************************************************/ + +#if 0 /* Not used */ +FAR const struct videomode_s * + videomode_lookup_by_refresh(uint16_t width, uint16_t height, + uint16_t refresh); +#endif /**************************************************************************** * Name: videomode_dump diff --git a/video/videomode/edid_parse.c b/video/videomode/edid_parse.c index f84b10ead99..7bc21467b85 100644 --- a/video/videomode/edid_parse.c +++ b/video/videomode/edid_parse.c @@ -50,6 +50,7 @@ #include #include +#include #include /**************************************************************************** @@ -174,7 +175,7 @@ static bool edid_std_timing(FAR const uint8_t *stdtim, /* First try to lookup the mode as a DMT timing */ snprintf(name, sizeof(name), "%dx%dx%d", x, y, f); - if ((lookup = videomode_lookup(name)) != NULL) + if ((lookup = videomode_lookup_by_name(name)) != NULL) { *mode = *lookup; } @@ -532,7 +533,7 @@ int edid_parse(FAR const uint8_t *data, FAR struct edid_info_s *edid) { if (estmodes & (1 << i)) { - mode = videomode_lookup(g_edid_modes[i]); + mode = videomode_lookup_by_name(g_edid_modes[i]); if (mode != NULL) { edid->edid_modes[edid->edid_nmodes] = *mode; diff --git a/video/videomode/videomode_lookup.c b/video/videomode/videomode_lookup.c index 3e9cfcbd09a..441ff394035 100644 --- a/video/videomode/videomode_lookup.c +++ b/video/videomode/videomode_lookup.c @@ -45,6 +45,7 @@ #include #include +#include #include @@ -176,14 +177,15 @@ static const int g_nvideomodes = 46; ****************************************************************************/ /**************************************************************************** - * Name: edid_mode_lookup + * Name: videomode_lookup_by_name * * Description: - * Find the video mode in a look-up table + * Find the video mode in a look-up table by the name assigned to the + * video mode. * ****************************************************************************/ -FAR const struct videomode_s *edid_mode_lookup(FAR const char *name) +FAR const struct videomode_s *videomode_lookup_by_name(FAR const char *name) { int i; @@ -197,3 +199,122 @@ FAR const struct videomode_s *edid_mode_lookup(FAR const char *name) return NULL; } + +/**************************************************************************** + * Name: videomode_lookup_by_dotclock + * + * Description: + * Find the video mode in a look-up table with the matching width and + * height and the closest dot clock that does not exceed the requested + * dot clock. + * + ****************************************************************************/ + +#if 0 /* Not used */ +FAR const struct videomode_s * + videomode_lookup_by_dotclock(uint16_t width, uint16_t height, + uint32_t dotclock) +{ + FAR const struct videomode_s *curr; + FAR const struct videomode_s *best = NULL; + int i; + + lcdinfo("Looking for %u x %u at up to %lu kHz\n", + width, height, (unsigned long)dotclock); + + for (i = 0; i < g_nvideomodes; i++) + { + curr = &g_videomodes[i]; + + if (curr->hdisplay == width && curr->vdisplay == height && + curr->dotclock <= dotclock) + { + if (best != NULL) + { + if (curr->dotclock > best->dotclock) + { + best = curr; + } + } + } + else + { + best = curr; + } + } + + if (best != NULL) + { + lcdinfo("Found %s\n", best->name); + } + + return best; +} +#endif + +/**************************************************************************** + * Name: videomode_lookup_by_refresh + * + * Description: + * Find the video mode in a look-up table with the matching width and + * height and the closest refrsh rate that does not exceed the requested + * rate. + * + ****************************************************************************/ + +#if 0 /* Not used */ +FAR const struct videomode_s * + videomode_lookup_by_refresh(uint16_t width, uint16_t height, + uint16_t refresh) +{ + FAR const struct videomode_s *curr; + FAR const struct videomode_s *best = NULL; + uint32_t mref; + int closest = 1000; + int diff; + int i; + + lcdinfo("Looking for %u x %u at up to %u Hz\n", + width, height, refresh); + + for (i = 0; i < g_nvideomodes; i++) + { + curr = &g_videomodes[i]; + + if (curr->hdisplay == width && curr->vdisplay == height) + { + mref = curr->dotclock * 1000 / (curr->htotal * curr->vtotal); + diff = mref - (uint32_t)refresh; + if (diff < 0) + { + diff = -diff; + } + + lcdinfo("%s in %lu Hz, diff %d\n", + curr->name, (unsigned long)mref, diff); + + if (best != NULL) + { + if (diff < closest) + { + best = curr; + closest = diff; + } + } + else + { + best = curr; + closest = diff; + } + } + } + + if (best != NULL) + { + lcdinfo("Found %s %lu\n", + best->name, (unsigned long)best->dotclock); + } + + return best; +} +#endif