From 69476fe4edbb562283a74ff29add0557fbdc96e1 Mon Sep 17 00:00:00 2001 From: Evoke Zhang Date: Wed, 12 Apr 2017 14:07:31 +0800 Subject: [PATCH] PD#138714: vout: add tvout mode monitor for box add sysfs node /sys/class/display/mode_flag, change mode_flag to 0 to stop monitor tvout mode. Change-Id: Ibb3ab599c94e0beece83895605f9cc779b6dc09a Signed-off-by: Evoke Zhang --- drivers/amlogic/media/vout/vout_serve/vout_serve.c | 134 ++++++++++++++++++++- 1 file changed, 132 insertions(+), 2 deletions(-) diff --git a/drivers/amlogic/media/vout/vout_serve/vout_serve.c b/drivers/amlogic/media/vout/vout_serve/vout_serve.c index dee9b74..4048ce1 100644 --- a/drivers/amlogic/media/vout/vout_serve/vout_serve.c +++ b/drivers/amlogic/media/vout/vout_serve/vout_serve.c @@ -36,6 +36,9 @@ /* Amlogic Headers */ #include +#ifdef CONFIG_AMLOGIC_HDMITX +#include +#endif /* Local Headers */ #include "vout_serve.h" @@ -49,9 +52,8 @@ static int early_suspend_flag; static int early_resume_flag; #endif - #define VOUT_CLASS_NAME "display" -#define MAX_NUMBER_PARA 10 +#define MAX_NUMBER_PARA 10 static struct class *vout_class; static DEFINE_MUTEX(vout_mutex); @@ -63,6 +65,14 @@ static char vout_axis[64] __nosavedata; static u32 vout_init_vmode = VMODE_INIT_NULL; static int uboot_display; +static char hdmimode[64]; +static char cvbsmode[64]; +static enum vmode_e last_vmode = VMODE_MAX; +static int tvout_monitor_flag = 1; + +static struct delayed_work tvout_mode_work; +static DEFINE_MUTEX(tvout_mode_lock); + void update_vout_mode(char *name) { snprintf(vout_mode, 60, "%s", name); @@ -126,6 +136,7 @@ static int set_vout_init_mode(void) vout_mode_uboot); return -1; } + last_vmode = vout_init_vmode; if (uboot_display) vmode = vout_init_vmode | VMODE_INIT_BIT_MASK; @@ -329,6 +340,33 @@ static ssize_t vout_vinfo_show(struct class *class, return len; } +static ssize_t vout_mode_flag_show(struct class *class, + struct class_attribute *attr, char *buf) +{ + int ret = 0; + + ret = sprintf(buf, "%d\n", tvout_monitor_flag); + + return ret; +} + +static ssize_t vout_mode_flag_store(struct class *class, + struct class_attribute *attr, const char *buf, size_t count) +{ + int ret = 0; + + ret = kstrtoint(buf, 10, &tvout_monitor_flag); + if (ret == 1) { + VOUTPR("%s: tvout_monitor_flag = %d\n", + __func__, tvout_monitor_flag); + } else { + VOUTPR("%s: invalid data\n", __func__); + return -EINVAL; + } + + return count; +} + static struct class_attribute vout_class_attrs[] = { __ATTR(mode, 0644, vout_mode_show, vout_mode_store), #ifdef CONFIG_AMLOGIC_FB @@ -337,6 +375,7 @@ static struct class_attribute vout_class_attrs[] = { __ATTR(fr_policy, 0644, vout_fr_policy_show, vout_fr_policy_store), __ATTR(vinfo, 0644, vout_vinfo_show, NULL), + __ATTR(mode_flag, 0644, vout_mode_flag_show, vout_mode_flag_store), }; static int vout_create_attr(void) @@ -484,6 +523,75 @@ static void aml_vout_late_resume(struct early_suspend *h) } #endif +/* ***************************************************** */ +/* hdmi/cvbs output mode monitor */ +/* ***************************************************** */ +static int refresh_tvout_mode(void) +{ + enum vmode_e cur_vmode = VMODE_MAX; + char *cur_mode_str; + int hdp_state = 0; + + if (tvout_monitor_flag == 0) + return 0; + +#ifdef CONFIG_AMLOGIC_HDMITX + hdp_state = get_hpd_state(); +#endif + if (hdp_state) { + cur_vmode = validate_vmode(hdmimode); + cur_mode_str = hdmimode; + } else { + cur_vmode = validate_vmode(cvbsmode); + cur_mode_str = cvbsmode; + } + if (cur_vmode >= VMODE_MAX) { + VOUTERR("%s: no matched cur_mode: %s\n", + __func__, cur_mode_str); + return -1; + } + + /* not box platform */ + if ((cur_vmode != VMODE_HDMI) && (cur_vmode != VMODE_CVBS)) + return -1; + + if (cur_vmode != last_vmode) { + VOUTPR("%s: mode chang\n", __func__); + if (set_vout_mode(cur_mode_str) == 0) + strcpy(vout_mode, cur_mode_str); + last_vmode = cur_vmode; + } + + return 0; +} + +static void aml_tvout_mode_work(struct work_struct *work) +{ + mutex_lock(&tvout_mode_lock); + refresh_tvout_mode(); + mutex_unlock(&tvout_mode_lock); + + if (tvout_monitor_flag) + schedule_delayed_work(&tvout_mode_work, 1*HZ/2); +} + +static void aml_tvout_mode_monitor(void) +{ + if ((vout_init_vmode != VMODE_HDMI) && (vout_init_vmode != VMODE_CVBS)) + return; + + VOUTPR("%s\n", __func__); + last_vmode = vout_init_vmode; + tvout_monitor_flag = 1; + INIT_DELAYED_WORK(&tvout_mode_work, aml_tvout_mode_work); + + mutex_lock(&tvout_mode_lock); + refresh_tvout_mode(); + mutex_unlock(&tvout_mode_lock); + + schedule_delayed_work(&tvout_mode_work, 1*HZ/2); +} + /***************************************************************** ** ** vout driver interface @@ -510,6 +618,8 @@ static int aml_vout_probe(struct platform_device *pdev) else VOUTERR("create vout attribute FAILED\n"); + aml_tvout_mode_monitor(); + VOUTPR("%s OK\n", __func__); return ret; } @@ -653,6 +763,26 @@ static int __init get_vout_init_mode(char *str) } __setup("vout=", get_vout_init_mode); +static int __init get_hdmi_mode(char *str) +{ + strcpy(hdmimode, str); + + VOUTPR("get hdmimode: %s\n", str); + return 1; +} +__setup("hdmimode=", get_hdmi_mode); + +static int __init get_cvbs_mode(char *str) +{ + if ((strncmp("480", str, 3) == 0) || (strncmp("576", str, 3) == 0)) + strcpy(cvbsmode, str); + else if (strncmp("nocvbs", str, 6) == 0) + strcpy(cvbsmode, "invalid"); + VOUTPR("get cvbsmode: %s\n", str); + return 1; +} +__setup("cvbsmode=", get_cvbs_mode); + MODULE_AUTHOR("Platform-BJ "); MODULE_DESCRIPTION("VOUT Server Module"); MODULE_LICENSE("GPL"); -- 2.7.4