rk hdmi: add node to get TV audio&video info
authorhjc <hjc@rock-chips.com>
Mon, 22 Sep 2014 03:13:11 +0000 (11:13 +0800)
committerhjc <hjc@rock-chips.com>
Mon, 22 Sep 2014 03:13:42 +0000 (11:13 +0800)
drivers/video/rockchip/display-sys.c
drivers/video/rockchip/hdmi/rk_hdmi.h
drivers/video/rockchip/hdmi/rk_hdmi_sysfs.c
drivers/video/rockchip/hdmi/rk_hdmi_task.c
include/linux/display-sys.h

index 3f8e6b85bb6bb81be12f076f70613cb334d2f00e..3097ace6ea7565ec07832c892fb390d96cb6c989 100755 (executable)
@@ -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
 };
 
index b8c15be418929a387f78e98cebca7e5c213e3df6..d962ff83f33d21298da2de93a461a01fa0c8c733 100755 (executable)
@@ -331,6 +331,7 @@ struct hdmi {
        struct switch_dev switch_hdmi;
 #endif
 
+       struct mutex lock;
        struct workqueue_struct *workqueue;
        struct delayed_work delay_work;
 
index 767490d900dc3ce53ef7990c89bf3a0ff06d95bc..9ab7a1a96437cbce35feea9280865a5ad19f29b8 100755 (executable)
@@ -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
index 26fffd4399106de080331cf55e28f32b94ccb2c7..0728b04125b01edd54fab4e29c05e0ebe8202211 100755 (executable)
@@ -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;
 }
 
index 8edee472a5e55892861519408769b6dc948ed336..ce89ff7adedcb53d2923797139b2af30c46dd90d 100755 (executable)
@@ -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 {