From d1c8b6180aea75bf2b25d4b1bb6c574edb36c635 Mon Sep 17 00:00:00 2001 From: hjc Date: Mon, 22 Sep 2014 11:13:11 +0800 Subject: [PATCH] rk hdmi: add node to get TV audio&video info --- drivers/video/rockchip/display-sys.c | 37 ++++++++++++ drivers/video/rockchip/hdmi/rk_hdmi.h | 1 + drivers/video/rockchip/hdmi/rk_hdmi_sysfs.c | 64 +++++++++++++++++++++ drivers/video/rockchip/hdmi/rk_hdmi_task.c | 1 + include/linux/display-sys.h | 2 + 5 files changed, 105 insertions(+) diff --git a/drivers/video/rockchip/display-sys.c b/drivers/video/rockchip/display-sys.c index 3f8e6b85bb6b..3097ace6ea75 100755 --- a/drivers/video/rockchip/display-sys.c +++ b/drivers/video/rockchip/display-sys.c @@ -210,6 +210,41 @@ static ssize_t display_store_debug(struct device *dev, return -EINVAL; } +static ssize_t display_show_sinkaudioinfo(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct rk_display_device *dsp = dev_get_drvdata(dev); + char audioinfo[200]; + int ret=0; + + if(dsp->ops && dsp->ops->getedidaudioinfo) { + ret = dsp->ops->getedidaudioinfo(dsp, audioinfo, 200); + if(!ret){ + return snprintf(buf, PAGE_SIZE, "%s\n", audioinfo); + } + } + return -EINVAL; +} + + + +static ssize_t display_show_monspecs(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct rk_display_device *dsp = dev_get_drvdata(dev); + struct fb_monspecs monspecs; + int ret = 0; + if(dsp->ops && dsp->ops->getmonspecs) { + ret = dsp->ops->getmonspecs(dsp,&monspecs); + if(!ret) { + memcpy(buf, &monspecs, sizeof(struct fb_monspecs)); + return sizeof(struct fb_monspecs);//snprintf(buf, PAGE_SIZE, "%s\n", monspecs.monitor); + } + } + return -EINVAL; +} + + static struct device_attribute display_attrs[] = { __ATTR(name, S_IRUGO, display_show_name, NULL), __ATTR(type, S_IRUGO, display_show_type, NULL), @@ -219,6 +254,8 @@ static struct device_attribute display_attrs[] = { __ATTR(mode, 0664, display_show_mode, display_store_mode), __ATTR(scale, 0664, display_show_scale, display_store_scale), __ATTR(debug, 0664, display_show_debug, display_store_debug), + __ATTR(audioinfo, S_IRUGO, display_show_sinkaudioinfo, NULL), + __ATTR(monspecs, S_IRUGO, display_show_monspecs, NULL), __ATTR_NULL }; diff --git a/drivers/video/rockchip/hdmi/rk_hdmi.h b/drivers/video/rockchip/hdmi/rk_hdmi.h index b8c15be41892..d962ff83f33d 100755 --- a/drivers/video/rockchip/hdmi/rk_hdmi.h +++ b/drivers/video/rockchip/hdmi/rk_hdmi.h @@ -331,6 +331,7 @@ struct hdmi { struct switch_dev switch_hdmi; #endif + struct mutex lock; struct workqueue_struct *workqueue; struct delayed_work delay_work; diff --git a/drivers/video/rockchip/hdmi/rk_hdmi_sysfs.c b/drivers/video/rockchip/hdmi/rk_hdmi_sysfs.c index 767490d900dc..9ab7a1a96437 100755 --- a/drivers/video/rockchip/hdmi/rk_hdmi_sysfs.c +++ b/drivers/video/rockchip/hdmi/rk_hdmi_sysfs.c @@ -152,8 +152,70 @@ static int hdmi_set_debug(struct rk_display_device *device, int cmd) return 0; } +//CEA 861-E: Audio Coding Type +//sync width enum hdmi_audio_type +static const char* const sAudioFormatStr[] = { + "", + "LPCM", //HDMI_AUDIO_LPCM = 1, + "AC3", //HDMI_AUDIO_AC3, + "MPEG1", //HDMI_AUDIO_MPEG1, + "MP3", //HDMI_AUDIO_MP3, + "MPEG2", //HDMI_AUDIO_MPEG2, + "AAC-LC", //HDMI_AUDIO_AAC_LC, //AAC + "DTS", //HDMI_AUDIO_DTS, + "ATARC", //HDMI_AUDIO_ATARC, + "DSD", //HDMI_AUDIO_DSD, //One bit Audio + "E-AC3", //HDMI_AUDIO_E_AC3, + "DTS-HD", //HDMI_AUDIO_DTS_HD, + "MLP", //HDMI_AUDIO_MLP, + "DST", //HDMI_AUDIO_DST, + "WMA-PRO", //HDMI_AUDIO_WMA_PRO +}; + +static int hdmi_get_edidaudioinfo(struct rk_display_device *device, char *audioinfo, int len) +{ + struct hdmi *hdmi = device->priv_data; + int i=0; + int size=0; + struct hdmi_audio *audio; + if(!hdmi) + return -1; + + memset(audioinfo, 0x00, len); + mutex_lock(&hdmi->lock); + //printk("hdmi:edid: audio_num: %d\n", hdmi->edid.audio_num); + for(i = 0; i < hdmi->edid.audio_num; i++) + { + audio = &(hdmi->edid.audio[i]); + if(audio->type<1 || audio->type>HDMI_AUDIO_WMA_PRO){ + printk("audio type: unsupported."); + continue; + } + size = strlen(sAudioFormatStr[audio->type]); + //printk("size: %d, type: %s\n", size, sAudioFormatStr[audio->type]); + memcpy(audioinfo, sAudioFormatStr[audio->type], size); + audioinfo[size]=','; + audioinfo += (size+1); + } + mutex_unlock(&hdmi->lock); + return 0; +} +static int hdmi_get_monspecs(struct rk_display_device *device, struct fb_monspecs *monspecs) +{ + struct hdmi *hdmi = device->priv_data; + + if (!hdmi) + return -1; + + mutex_lock(&hdmi->lock); + if(hdmi->edid.specs) + *monspecs = *(hdmi->edid.specs); + mutex_unlock(&hdmi->lock); + return 0; +} + struct rk_display_ops hdmi_display_ops = { .setenable = hdmi_set_enable, .getenable = hdmi_get_enable, @@ -164,6 +226,8 @@ struct rk_display_ops hdmi_display_ops = { .setscale = hdmi_set_scale, .getscale = hdmi_get_scale, .setdebug = hdmi_set_debug, + .getedidaudioinfo = hdmi_get_edidaudioinfo, + .getmonspecs = hdmi_get_monspecs, }; #if 1 diff --git a/drivers/video/rockchip/hdmi/rk_hdmi_task.c b/drivers/video/rockchip/hdmi/rk_hdmi_task.c index 26fffd439910..0728b04125b0 100755 --- a/drivers/video/rockchip/hdmi/rk_hdmi_task.c +++ b/drivers/video/rockchip/hdmi/rk_hdmi_task.c @@ -61,6 +61,7 @@ int hdmi_sys_init(struct hdmi *hdmi) memset(&hdmi->edid, 0, sizeof(struct hdmi_edid)); INIT_LIST_HEAD(&hdmi->edid.modelist); + mutex_init(&hdmi->lock); return 0; } diff --git a/include/linux/display-sys.h b/include/linux/display-sys.h index 8edee472a5e5..ce89ff7adedc 100755 --- a/include/linux/display-sys.h +++ b/include/linux/display-sys.h @@ -38,6 +38,8 @@ struct rk_display_ops { int (*setscale)(struct rk_display_device *, int, int); int (*getscale)(struct rk_display_device *, int); int (*setdebug)(struct rk_display_device *, int); + int (*getedidaudioinfo)(struct rk_display_device *, char *audioinfo, int len); + int (*getmonspecs)(struct rk_display_device *, struct fb_monspecs *monspecs); }; struct rk_display_device { -- 2.34.1