hdmi: modify debug string mode.
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / hdmi / rockchip-hdmi-core.c
index 4c65868f83977048231e011984079710ae3403cd..1f36185f2d35583dd2e6c49c91f9bd103edcf86d 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/delay.h>
+#include <sound/pcm_params.h>
 #include "rockchip-hdmi.h"
 #include "rockchip-hdmi-cec.h"
 
@@ -23,7 +24,7 @@ struct delayed_work *hdmi_submit_work(struct hdmi *hdmi,
 {
        struct hdmi_delayed_work *work;
 
-       DBG("%s event %04x delay %d", __func__, event, delay);
+       DBG("%s event %04x delay %d\n", __func__, event, delay);
 
        work = kmalloc(sizeof(*work), GFP_ATOMIC);
 
@@ -59,14 +60,14 @@ static void hdmi_send_uevent(struct hdmi *hdmi, int uevent)
 
 static inline void hdmi_wq_set_output(struct hdmi *hdmi, int mute)
 {
-       DBG("%s mute %d", __func__, mute);
+       DBG("%s mute %d\n", __func__, mute);
        if (hdmi->ops->setmute)
                hdmi->ops->setmute(hdmi, mute);
 }
 
 static inline void hdmi_wq_set_audio(struct hdmi *hdmi)
 {
-       DBG("%s", __func__);
+       DBG("%s\n", __func__);
        if (hdmi->ops->setaudio)
                hdmi->ops->setaudio(hdmi, &hdmi->audio);
 }
@@ -74,12 +75,14 @@ static inline void hdmi_wq_set_audio(struct hdmi *hdmi)
 static void hdmi_wq_set_video(struct hdmi *hdmi)
 {
        struct hdmi_video       video;
+       int     deepcolor;
 
-       DBG("%s", __func__);
+       DBG("%s\n", __func__);
 
        video.vic = hdmi->vic & HDMI_VIC_MASK;
        video.sink_hdmi = hdmi->edid.sink_hdmi;
        video.format_3d = hdmi->mode_3d;
+
        /* For DVI, output RGB */
        if (hdmi->edid.sink_hdmi == 0) {
                video.color_output = HDMI_COLOR_RGB_0_255;
@@ -95,16 +98,21 @@ static void hdmi_wq_set_video(struct hdmi *hdmi)
                        video.color_output = hdmi->colormode;
                }
        }
+       if (hdmi->vic & HDMI_VIDEO_YUV420) {
+               video.color_output = HDMI_COLOR_YCBCR420;
+               deepcolor = hdmi->edid.deepcolor_420;
+       } else {
+               deepcolor = hdmi->edid.deepcolor;
+       }
        if ((hdmi->property->feature & SUPPORT_DEEP_10BIT) &&
-           (hdmi->edid.deepcolor & HDMI_DEEP_COLOR_30BITS)) {
+           (deepcolor & HDMI_DEEP_COLOR_30BITS)) {
                if (hdmi->colordepth == HDMI_DEPP_COLOR_AUTO ||
                    hdmi->colordepth == 10)
                        video.color_output_depth = 10;
        } else {
                video.color_output_depth = 8;
        }
-       if (hdmi->vic & HDMI_VIDEO_YUV420)
-               video.color_output = HDMI_COLOR_YCBCR420;
+
        pr_info("hdmi output corlor mode is %d\n", video.color_output);
        video.color_input = HDMI_COLOR_RGB_0_255;
        if (hdmi->property->feature & SUPPORT_YCBCR_INPUT) {
@@ -129,7 +137,7 @@ static void hdmi_wq_parse_edid(struct hdmi *hdmi)
        if (hdmi == NULL)
                return;
 
-       DBG("%s", __func__);
+       DBG("%s\n", __func__);
 
        pedid = &(hdmi->edid);
        fb_destroy_modelist(&pedid->modelist);
@@ -213,7 +221,7 @@ out:
 
 static void hdmi_wq_insert(struct hdmi *hdmi)
 {
-       DBG("%s", __func__);
+       DBG("%s\n", __func__);
        if (hdmi->ops->insert)
                hdmi->ops->insert(hdmi);
        hdmi_wq_parse_edid(hdmi);
@@ -228,8 +236,7 @@ static void hdmi_wq_insert(struct hdmi *hdmi)
                #endif
                hdmi_wq_set_audio(hdmi);
                hdmi_wq_set_output(hdmi, hdmi->mute);
-               if (hdmi->ops->hdcp_cb)
-                       hdmi->ops->hdcp_cb(hdmi);
+               hdmi_submit_work(hdmi, HDMI_ENABLE_HDCP, 100, NULL);
                if (hdmi->ops->setcec)
                        hdmi->ops->setcec(hdmi);
        }
@@ -243,7 +250,7 @@ static void hdmi_wq_remove(struct hdmi *hdmi)
        struct rk_screen screen;
        int i;
 
-       DBG("%s", __func__);
+       DBG("%s\n", __func__);
        if (hdmi->ops->remove)
                hdmi->ops->remove(hdmi);
        if (hdmi->hotplug == HDMI_HPD_ACTIVED) {
@@ -253,10 +260,12 @@ static void hdmi_wq_remove(struct hdmi *hdmi)
        #ifdef CONFIG_SWITCH
        switch_set_state(&(hdmi->switchdev), 0);
        #endif
+       mutex_lock(&hdmi->ddev->lock);
        list_for_each_safe(pos, n, &hdmi->edid.modelist) {
                list_del(pos);
                kfree(pos);
        }
+       mutex_unlock(&hdmi->ddev->lock);
        for (i = 0; i < HDMI_MAX_EDID_BLOCK; i++)
                kfree(hdmi->edid.raw[i]);
        kfree(hdmi->edid.audio);
@@ -308,6 +317,10 @@ static void hdmi_work_queue(struct work_struct *work)
                break;
        case HDMI_DISABLE_CTL:
                if (hdmi->enable) {
+                       if (hdmi->hotplug == HDMI_HPD_ACTIVED)
+                               hdmi_wq_set_output(hdmi,
+                                                  HDMI_VIDEO_MUTE |
+                                                  HDMI_AUDIO_MUTE);
                        if (!hdmi->sleep) {
                                if (hdmi->ops->disable)
                                        hdmi->ops->disable(hdmi);
@@ -318,8 +331,10 @@ static void hdmi_work_queue(struct work_struct *work)
                break;
        case HDMI_SUSPEND_CTL:
                if (!hdmi->sleep) {
-                       hdmi_wq_set_output(hdmi,
-                                          HDMI_VIDEO_MUTE | HDMI_AUDIO_MUTE);
+                       if (hdmi->hotplug == HDMI_HPD_ACTIVED)
+                               hdmi_wq_set_output(hdmi,
+                                                  HDMI_VIDEO_MUTE |
+                                                  HDMI_AUDIO_MUTE);
                        if (hdmi->ops->disable)
                                hdmi->ops->disable(hdmi);
                        if (hdmi->enable)
@@ -330,7 +345,7 @@ static void hdmi_work_queue(struct work_struct *work)
        case HDMI_HPD_CHANGE:
                if (hdmi->ops->getstatus)
                        hpd = hdmi->ops->getstatus(hdmi);
-               DBG("hdmi_work_queue() - hpd is %d hotplug is %d",
+               DBG("hdmi_work_queue() - hpd is %d hotplug is %d\n",
                    hpd, hdmi->hotplug);
                if (hpd != hdmi->hotplug) {
                        if (hpd == HDMI_HPD_ACTIVED) {
@@ -400,6 +415,11 @@ static void hdmi_work_queue(struct work_struct *work)
                if (hdmi->hotplug == HDMI_HPD_ACTIVED && hdmi->ops->hdcp_cb)
                        hdmi->ops->hdcp_cb(hdmi);
                break;
+       case HDMI_HDCP_AUTH_2ND:
+               if (hdmi->hotplug == HDMI_HPD_ACTIVED &&
+                   hdmi->ops->hdcp_auth2nd)
+                       hdmi->ops->hdcp_auth2nd(hdmi);
+               break;
        default:
                pr_err("HDMI: hdmi_work_queue() unkown event\n");
                break;
@@ -433,7 +453,7 @@ struct hdmi *rockchip_hdmi_register(struct hdmi_property *property,
        if (i == HDMI_MAX_ID)
                return NULL;
 
-       DBG("hdmi_register() - video source %d display %d",
+       DBG("hdmi_register() - video source %d display %d\n",
            property->videosrc,  property->display);
 
        hdmi = kmalloc(sizeof(*hdmi), GFP_KERNEL);
@@ -470,12 +490,15 @@ struct hdmi *rockchip_hdmi_register(struct hdmi_property *property,
        hdmi->yscale = 100;
        hdmi_init_modelist(hdmi);
 
-#ifndef CONFIG_ARCH_RK29
        if (hdmi->property->videosrc == DISPLAY_SOURCE_LCDC0)
                hdmi->lcdc = rk_get_lcdc_drv("lcdc0");
        else
                hdmi->lcdc = rk_get_lcdc_drv("lcdc1");
-#endif
+
+       if (hdmi->lcdc->prop == EXTEND)
+               hdmi->property->display = DISPLAY_AUX;
+       else
+               hdmi->property->display = DISPLAY_MAIN;
        memset(name, 0, 32);
        sprintf(name, "hdmi-%s", hdmi->property->name);
        hdmi->workqueue = create_singlethread_workqueue(name);
@@ -576,11 +599,58 @@ int hdmi_config_audio(struct hdmi_audio   *audio)
                        continue;
                }*/
                memcpy(&hdmi->audio, audio, sizeof(struct hdmi_audio));
-               hdmi_submit_work(hdmi, HDMI_SET_AUDIO, 0, NULL);
+               if (hdmi->hotplug == HDMI_HPD_ACTIVED)
+                       hdmi_submit_work(hdmi, HDMI_SET_AUDIO, 0, NULL);
        }
        return 0;
 }
 
+int snd_config_hdmi_audio(struct snd_pcm_hw_params *params)
+{
+       struct hdmi_audio audio_cfg;
+       u32     rate;
+
+       switch (params_rate(params)) {
+       case 32000:
+               rate = HDMI_AUDIO_FS_32000;
+               break;
+       case 44100:
+               rate = HDMI_AUDIO_FS_44100;
+               break;
+       case 48000:
+               rate = HDMI_AUDIO_FS_48000;
+               break;
+       case 88200:
+               rate = HDMI_AUDIO_FS_88200;
+               break;
+       case 96000:
+               rate = HDMI_AUDIO_FS_96000;
+               break;
+       case 176400:
+               rate = HDMI_AUDIO_FS_176400;
+               break;
+       case 192000:
+               rate = HDMI_AUDIO_FS_192000;
+               break;
+       default:
+               pr_err("rate %d unsupport.\n", params_rate(params));
+               rate = HDMI_AUDIO_FS_44100;
+       }
+
+       audio_cfg.rate = rate;
+
+       if (HW_PARAMS_FLAG_NLPCM == params->flags)
+               audio_cfg.type = HDMI_AUDIO_NLPCM;
+       else
+               audio_cfg.type = HDMI_AUDIO_LPCM;
+
+       audio_cfg.channel = params_channels(params);
+       audio_cfg.word_length = HDMI_AUDIO_WORD_LENGTH_16bit;
+
+       return hdmi_config_audio(&audio_cfg);
+}
+EXPORT_SYMBOL(snd_config_hdmi_audio);
+
 void hdmi_audio_mute(int mute)
 {
        int i;