Add video_off_hdmi option to power down HDMI on idle timeout (#1110)

When video_off_hdmi=1 is set in MiSTer.ini, the ADV7513 HDMI
transmitter is powered down via I2C when the video_off timeout
expires, allowing the connected monitor to enter sleep mode.
HDMI is restored when user activity is detected (OSD opens).
This commit is contained in:
Timothy Redaelli
2026-03-08 20:05:58 +01:00
committed by GitHub
parent 74ac680640
commit 6b21918ce2
6 changed files with 23 additions and 0 deletions

View File

@@ -33,6 +33,7 @@ fb_terminal=1 ; 1 - enabled (default), 0 - disabled
osd_timeout=30 ; 5-3600 timeout (in seconds) for OSD to disappear in Menu core. 0 - never timeout.
; Background picture will get darker after double timeout
video_off=0 ; output black frame in Menu core after timeout (is seconds). Valid only if osd_timout is non zero.
video_off_hdmi=0 ; 1 - power down HDMI on video_off timeout (TV can sleep), 0 - keep HDMI active
osd_rotate=0 ; Display OSD menu rotated, 0 - no rotation, 1 - rotate right (+90°), 2 - rotate left (-90°)
vga_sog=0 ; 1 - enable sync on green (needs analog I/O board v6.0 or newer).
lookahead=2 ; 0 - off, 13 - scroll list up to 3 items ahead of cursor near top/bottom

View File

@@ -109,6 +109,7 @@ static const ini_var_t ini_vars[] =
{ "VRR_MAX_FRAMERATE", (void *)(&(cfg.vrr_max_framerate)), UINT8, 0, 255 },
{ "VRR_VESA_FRAMERATE", (void *)(&(cfg.vrr_vesa_framerate)), UINT8, 0, 255 },
{ "VIDEO_OFF", (void*)(&(cfg.video_off)), INT16, 0, 3600 },
{ "VIDEO_OFF_HDMI", (void*)(&(cfg.video_off_hdmi)), UINT8, 0, 1 },
{ "PLAYER_1_CONTROLLER", (void*)(&(cfg.player_controller[0])), STRINGARR, sizeof(cfg.player_controller[0]) / sizeof(cfg.player_controller[0][0]), sizeof(cfg.player_controller[0][0]) },
{ "PLAYER_2_CONTROLLER", (void*)(&(cfg.player_controller[1])), STRINGARR, sizeof(cfg.player_controller[0]) / sizeof(cfg.player_controller[0][0]), sizeof(cfg.player_controller[0][0]) },
{ "PLAYER_3_CONTROLLER", (void*)(&(cfg.player_controller[2])), STRINGARR, sizeof(cfg.player_controller[0]) / sizeof(cfg.player_controller[0][0]), sizeof(cfg.player_controller[0][0]) },

1
cfg.h
View File

@@ -82,6 +82,7 @@ typedef struct {
uint8_t vrr_max_framerate;
uint8_t vrr_vesa_framerate;
uint16_t video_off;
uint8_t video_off_hdmi;
uint8_t disable_autofire;
uint8_t video_brightness;
uint8_t video_contrast;

View File

@@ -1239,6 +1239,7 @@ void HandleUI(void)
{
off_timeout = 0;
video_menu_bg(user_io_status_get("[3:1]"), 3);
if (cfg.video_off_hdmi) video_hdmi_power(0);
}
if (c || menustate != MENU_FILE_SELECT2)
@@ -1248,6 +1249,7 @@ void HandleUI(void)
{
c = 0;
menu_visible = 1;
if (cfg.video_off_hdmi) video_hdmi_power(1);
video_menu_bg(user_io_status_get("[3:1]"));
OsdMenuCtl(1);
}

View File

@@ -1562,6 +1562,23 @@ static void hdmi_config_init()
hdmi_config_set_csc();
}
void video_hdmi_power(int on)
{
// ADV7513 power-down control. 0 = power on, 1 = power down.
int fd = i2c_open(0x39, 0);
if (fd >= 0)
{
uint8_t val = on ? 0x00 : 0x40;
int res = i2c_smbus_write_byte_data(fd, 0x41, val);
if (res < 0) printf("i2c: write error (41 %02X): %d\n", val, res);
i2c_close(fd);
}
else
{
printf("*** ADV7513 not found on i2c bus! HDMI won't be available!\n");
}
}
static void hdmi_config_set_hdr()
{
// Grab desired nits values

View File

@@ -68,6 +68,7 @@ int video_bg_has_picture();
int video_chvt(int num);
void video_cmd(char *cmd);
void video_mode_cmd(char *cmd);
void video_hdmi_power(int on);
void video_core_description(char *str, size_t len);
void video_scaler_description(char *str, size_t len);