rk hdmi: add node to get TV audio&video info
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / hdmi / rk_hdmi_sysfs.c
index a93c3211083918d7daa02c8668fc66cafc96b2f3..9ab7a1a96437cbce35feea9280865a5ad19f29b8 100755 (executable)
@@ -8,43 +8,40 @@ static int hdmi_get_enable(struct rk_display_device *device)
 {
        struct hdmi *hdmi = device->priv_data;
        int enable;
-       
+
        mutex_lock(&hdmi->enable_mutex);
        enable = hdmi->enable;
        mutex_unlock(&hdmi->enable_mutex);
-       
+
        return enable;
 }
 
 static int hdmi_set_enable(struct rk_display_device *device, int enable)
 {
        struct hdmi *hdmi = device->priv_data;
-       
+
        mutex_lock(&hdmi->enable_mutex);
-       if(hdmi->enable == enable) {
+       if (hdmi->enable == enable) {
                mutex_unlock(&hdmi->enable_mutex);
                return 0;
        }
        hdmi->enable = enable;
-       
-       if(hdmi->suspend ) {
+
+       if (hdmi->suspend) {
                mutex_unlock(&hdmi->enable_mutex);
                return 0;
        }
-       
-       if(enable == 0) {
-               if(hdmi->irq)
+
+       if (enable == 0) {
+               if (hdmi->irq)
                        disable_irq(hdmi->irq);
                mutex_unlock(&hdmi->enable_mutex);
                hdmi->command = HDMI_CONFIG_ENABLE;
                queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, 0);
-       }
-       else {
-               if(hdmi->irq)
+       } else {
+               if (hdmi->irq)
                        enable_irq(hdmi->irq);
-               #ifdef CONFIG_HDMI_RK610
-                       queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, 0);
-               #endif
+               queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, 0);
                mutex_unlock(&hdmi->enable_mutex);
        }
        return 0;
@@ -53,67 +50,76 @@ static int hdmi_set_enable(struct rk_display_device *device, int enable)
 static int hdmi_get_status(struct rk_display_device *device)
 {
        struct hdmi *hdmi = device->priv_data;
-       if(hdmi->hotplug == HDMI_HPD_ACTIVED)
+
+       if (hdmi->hotplug == HDMI_HPD_ACTIVED)
                return 1;
        else
                return 0;
 }
 
-static int hdmi_get_modelist(struct rk_display_device *device, struct list_head **modelist)
+static int hdmi_get_modelist(struct rk_display_device *device,
+                            struct list_head **modelist)
 {
        struct hdmi *hdmi = device->priv_data;
-       if(!hdmi->hotplug)
+
+       if (!hdmi->hotplug)
                return -1;
        *modelist = &hdmi->edid.modelist;
        return 0;
 }
 
-static int hdmi_set_mode(struct rk_display_device *device, struct fb_videomode *mode)
+static int hdmi_set_mode(struct rk_display_device *device,
+                        struct fb_videomode *mode)
 {
        struct hdmi *hdmi = device->priv_data;
        int vic = hdmi_videomode_to_vic(mode);
-       
-       if(!hdmi->hotplug)
-               return -1;
+
        hdmi->autoconfig = HDMI_DISABLE;
-       if(vic && hdmi->vic != vic)
-       {
+       if (vic && hdmi->vic != vic) {
                hdmi->vic = vic;
+               if (!hdmi->hotplug)
+                       return 0;
                hdmi->command = HDMI_CONFIG_VIDEO;
                init_completion(&hdmi->complete);
                hdmi->wait = 1;
                queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, 0);
                wait_for_completion_interruptible_timeout(&hdmi->complete,
-                                                               msecs_to_jiffies(10000));
+                                                         msecs_to_jiffies
+                                                         (10000));
        }
        return 0;
 }
 
-static int hdmi_get_mode(struct rk_display_device *device, struct fb_videomode *mode)
+static int hdmi_get_mode(struct rk_display_device *device,
+                        struct fb_videomode *mode)
 {
        struct hdmi *hdmi = device->priv_data;
        struct fb_videomode *vmode;
-       
-       if(!hdmi->hotplug)
+
+       if (!hdmi->hotplug)
                return -1;
-               
-       vmode = (struct fb_videomode*) hdmi_vic_to_videomode(hdmi->vic);
-       if(unlikely(vmode == NULL))
+
+       vmode = (struct fb_videomode *)hdmi_vic_to_videomode(hdmi->vic);
+       if (unlikely(vmode == NULL))
                return -1;
        *mode = *vmode;
        return 0;
 }
 
-static int hdmi_set_scale(struct rk_display_device *device, int direction, int value)
+static int hdmi_set_scale(struct rk_display_device *device, int direction,
+                         int value)
 {
        struct hdmi *hdmi = device->priv_data;
-       
-       if(!hdmi || value < 0 || value > 100)
+
+       if (!hdmi || value < 0 || value > 100)
                return -1;
-                       
-       if(direction == DISPLAY_SCALE_X)
+
+       if (!hdmi->hotplug)
+               return 0;
+
+       if (direction == DISPLAY_SCALE_X)
                hdmi->xscale = value;
-       else if(direction == DISPLAY_SCALE_Y)
+       else if (direction == DISPLAY_SCALE_Y)
                hdmi->yscale = value;
        else
                return -1;
@@ -124,17 +130,91 @@ static int hdmi_set_scale(struct rk_display_device *device, int direction, int v
 static int hdmi_get_scale(struct rk_display_device *device, int direction)
 {
        struct hdmi *hdmi = device->priv_data;
-       
-       if(!hdmi)
+
+       if (!hdmi)
                return -1;
-               
-       if(direction == DISPLAY_SCALE_X)
+
+       if (direction == DISPLAY_SCALE_X)
                return hdmi->xscale;
-       else if(direction == DISPLAY_SCALE_Y)
+       else if (direction == DISPLAY_SCALE_Y)
                return hdmi->yscale;
        else
                return -1;
 }
+static int hdmi_set_debug(struct rk_display_device *device, int cmd)
+{
+       struct hdmi *hdmi = device->priv_data;
+
+       if (!hdmi)
+               return -1;
+       if (hdmi->ops && hdmi->ops->hdmi_debug)
+               hdmi->ops->hdmi_debug(hdmi,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,
@@ -145,6 +225,9 @@ struct rk_display_ops hdmi_display_ops = {
        .getmode = hdmi_get_mode,
        .setscale = hdmi_set_scale,
        .getscale = hdmi_get_scale,
+       .setdebug = hdmi_set_debug,
+       .getedidaudioinfo = hdmi_get_edidaudioinfo,
+       .getmonspecs = hdmi_get_monspecs,
 };
 
 #if 1
@@ -153,11 +236,11 @@ static int hdmi_display_probe(struct rk_display_device *device, void *devdata)
        device->owner = THIS_MODULE;
        strcpy(device->type, "HDMI");
        device->priority = DISPLAY_PRIORITY_HDMI;
-//     device->name = kmalloc(strlen(name), GFP_KERNEL);
-//     if(device->name)
-//     {
-//             strcpy(device->name, name);
-//     }
+/*
+       device->name = kmalloc(strlen(name), GFP_KERNEL);
+       if(device->name)
+               strcpy(device->name, name);
+*/
        device->priv_data = devdata;
        device->ops = &hdmi_display_ops;
        return 1;
@@ -167,16 +250,23 @@ static struct rk_display_driver display_hdmi = {
        .probe = hdmi_display_probe,
 };
 
-static struct rk_display_device *display_device_hdmi = NULL;
+#ifdef CONFIG_DRM_ROCKCHIP
+extern void rk_drm_display_register(struct rk_display_ops *extend_ops,
+                                   void *displaydata, int type);
+#endif
 
 void hdmi_register_display_sysfs(struct hdmi *hdmi, struct device *parent)
 {
-       display_device_hdmi = rk_display_device_register(&display_hdmi, parent, hdmi);
+       hdmi->ddev =
+           rk_display_device_register(&display_hdmi, parent, hdmi);
+#ifdef CONFIG_DRM_ROCKCHIP
+       rk_drm_display_register(&hdmi_display_ops, hdmi, SCREEN_HDMI);
+#endif
 }
 
 void hdmi_unregister_display_sysfs(struct hdmi *hdmi)
 {
-       if(display_device_hdmi)
-               rk_display_device_unregister(display_device_hdmi);
+       if (hdmi->ddev)
+               rk_display_device_unregister(hdmi->ddev);
 }
 #endif