hdmi: support parse and modify colorimetry.
authorZheng Yang <zhengyang@rock-chips.com>
Tue, 14 Jul 2015 01:33:45 +0000 (09:33 +0800)
committerZheng Yang <zhengyang@rock-chips.com>
Tue, 14 Jul 2015 01:33:45 +0000 (09:33 +0800)
Signed-off-by: Zheng Yang <zhengyang@rock-chips.com>
drivers/video/rockchip/hdmi/rockchip-hdmi-core.c
drivers/video/rockchip/hdmi/rockchip-hdmi-edid.c
drivers/video/rockchip/hdmi/rockchip-hdmi-sysfs.c
drivers/video/rockchip/hdmi/rockchip-hdmi.h

index 1f36185f2d35583dd2e6c49c91f9bd103edcf86d..a28c04de5441af0e6a6d1e9452422b2dc262dbb0 100644 (file)
@@ -82,7 +82,7 @@ static void hdmi_wq_set_video(struct hdmi *hdmi)
        video.vic = hdmi->vic & HDMI_VIC_MASK;
        video.sink_hdmi = hdmi->edid.sink_hdmi;
        video.format_3d = hdmi->mode_3d;
-
+       video.colorimetry = hdmi->colorimetry;
        /* For DVI, output RGB */
        if (hdmi->edid.sink_hdmi == 0) {
                video.color_output = HDMI_COLOR_RGB_0_255;
@@ -481,6 +481,7 @@ struct hdmi *rockchip_hdmi_register(struct hdmi_property *property,
        }
        hdmi->colormode = HDMI_VIDEO_DEFAULT_COLORMODE;
        hdmi->colordepth = HDMI_DEPP_COLOR_AUTO;
+       hdmi->colorimetry = HDMI_COLORIMETRY_NO_DATA;
        hdmi->mode_3d = HDMI_3D_NONE;
        hdmi->audio.type = HDMI_AUDIO_DEFAULT_TYPE;
        hdmi->audio.channel = HDMI_AUDIO_DEFAULT_CHANNEL;
index e18e98663f50878cee82c6e48f42ccb964edc192..4673082416cd8c8e4e24bbd91cf72fc3ab53c3c5 100644 (file)
@@ -437,6 +437,7 @@ static int hdmi_edid_parse_extensions_cea(unsigned char *buf,
                        case 0x05:
                                EDBG("[CEA] Colorimetry Data Block\n");
                                EDBG("value is %02x\n", buf[cur_offset + 2]);
+                               pedid->colorimetry = buf[cur_offset + 2];
                                break;
                        case 0x0e:
                                EDBG("[CEA] YCBCR 4:2:0 Video Data Block\n");
index 914500897043359523415f71348f460fcf1f3fcd..066391aaab0e2733eea28b6904ff1b2c0bad4ea2 100644 (file)
@@ -218,6 +218,10 @@ static int hdmi_get_color(struct rk_display_device *device, char *buf)
                      "Supported Color Depth: %d\n", mode);
        i += snprintf(buf + i, PAGE_SIZE - i,
                      "Current Color Depth: %d\n", hdmi->colordepth);
+       i += snprintf(buf + i, PAGE_SIZE - i,
+                     "Supported Colorimetry: %d\n", hdmi->edid.colorimetry);
+       i += snprintf(buf + i, PAGE_SIZE - i,
+                     "Current Colorimetry: %d\n", hdmi->colorimetry);
        mutex_unlock(&hdmi->lock);
        return i;
 }
@@ -242,6 +246,13 @@ static int hdmi_set_color(struct rk_display_device *device,
                         hdmi->colordepth, value);
                if (hdmi->colordepth != value)
                        hdmi->colordepth = value;
+       } else if (!strncmp(buf, "colorimetry", 11)) {
+               if (sscanf(buf, "colorimetry=%d", &value) == -1)
+                       return -1;
+               pr_debug("current colorimetry is %d input colorimetry is %d\n",
+                        hdmi->colorimetry, value);
+               if (hdmi->colorimetry != value)
+                       hdmi->colorimetry = value;
        } else {
                pr_err("%s unkown event\n", __func__);
                return -1;
@@ -338,8 +349,8 @@ static int hdmi_show_sink_info(struct hdmi *hdmi, char *buf, int len)
                                         "\t%s\n", m->name);
        }
        lens += snprintf(buf + lens, PAGE_SIZE - lens,
-                        "Support video color mode:\n");
-       lens += snprintf(buf + lens, PAGE_SIZE - lens, "\tRGB");
+                        "Support video color mode:");
+       lens += snprintf(buf + lens, PAGE_SIZE - lens, " RGB");
        if (hdmi->edid.ycbcr420)
                lens += snprintf(buf + lens, PAGE_SIZE - lens,
                                 " YCbCr420");
@@ -350,8 +361,8 @@ static int hdmi_show_sink_info(struct hdmi *hdmi, char *buf, int len)
                lens += snprintf(buf + lens, PAGE_SIZE - lens,
                                 " YCbCr444");
        lens += snprintf(buf + lens, PAGE_SIZE - lens,
-                        "\nSupport video color depth:\n");
-       lens += snprintf(buf + lens, PAGE_SIZE - lens, "\t24bit");
+                        "\nSupport video color depth:");
+       lens += snprintf(buf + lens, PAGE_SIZE - lens, " 24bit");
        if (hdmi->edid.deepcolor & HDMI_DEEP_COLOR_30BITS)
                lens += snprintf(buf + lens, PAGE_SIZE - lens, " 30bit");
        if (hdmi->edid.deepcolor & HDMI_DEEP_COLOR_36BITS)
@@ -366,77 +377,113 @@ static int hdmi_show_sink_info(struct hdmi *hdmi, char *buf, int len)
                lens += snprintf(buf + lens, PAGE_SIZE - lens, " 420_36bit");
        if (hdmi->edid.deepcolor_420 & HDMI_DEEP_COLOR_48BITS)
                lens += snprintf(buf + lens, PAGE_SIZE - lens, " 420_48bit");
+       if (hdmi->edid.colorimetry) {
+               lens += snprintf(buf + lens, PAGE_SIZE - lens,
+                                "\nExtended Colorimetry:");
+               if (hdmi->edid.colorimetry &
+                   (1 << (HDMI_COLORIMETRY_EXTEND_XVYCC_601 - 3)))
+                       lens += snprintf(buf + lens, PAGE_SIZE - lens,
+                                        " xvYCC601");
+               if (hdmi->edid.colorimetry &
+                   (1 << (HDMI_COLORIMETRY_EXTEND_XVYCC_709 - 3)))
+                       lens += snprintf(buf + lens, PAGE_SIZE - lens,
+                                        " xvYCC709");
+               if (hdmi->edid.colorimetry &
+                   (1 << (HDMI_COLORIMETRY_EXTEND_SYCC_601 - 3)))
+                       lens += snprintf(buf + lens, PAGE_SIZE - lens,
+                                        " sYCC601");
+               if (hdmi->edid.colorimetry &
+                   (1 << (HDMI_COLORIMETRY_EXTEND_ADOBE_YCC601 - 3)))
+                       lens += snprintf(buf + lens, PAGE_SIZE - lens,
+                                        " AdobeYCC601");
+               if (hdmi->edid.colorimetry &
+                   (1 << (HDMI_COLORIMETRY_EXTEND_ADOBE_RGB - 3)))
+                       lens += snprintf(buf + lens, PAGE_SIZE - lens,
+                                        " AdobeRGB");
+               if (hdmi->edid.colorimetry &
+                   (1 << (HDMI_COLORIMETRY_EXTEND_BT_2020_YCC_C - 3)))
+                       lens += snprintf(buf + lens, PAGE_SIZE - lens,
+                                        " BT2020cYCC");
+               if (hdmi->edid.colorimetry &
+                   (1 << (HDMI_COLORIMETRY_EXTEND_BT_2020_YCC - 3)))
+                       lens += snprintf(buf + lens, PAGE_SIZE - lens,
+                                        " BT2020YCC");
+               if (hdmi->edid.colorimetry &
+                   (1 << (HDMI_COLORIMETRY_EXTEND_BT_2020_RGB - 3)))
+                       lens += snprintf(buf + lens, PAGE_SIZE - lens,
+                                        " BT2020RGB");
+       }
        lens += snprintf(buf + lens, PAGE_SIZE - lens,
-                        "\nSupport audio type:\n");
+                        "\nSupport audio type:");
        for (i = 0; i < hdmi->edid.audio_num; i++) {
                audio = &(hdmi->edid.audio[i]);
                switch (audio->type) {
                case HDMI_AUDIO_LPCM:
                        lens += snprintf(buf + lens, PAGE_SIZE - lens,
-                               "\tLPCM\n");
+                               " LPCM\n");
                        break;
                case HDMI_AUDIO_AC3:
                        lens += snprintf(buf + lens, PAGE_SIZE - lens,
-                                        "\tAC3\n");
+                                        " AC3");
                        break;
                case HDMI_AUDIO_MPEG1:
                        lens += snprintf(buf + lens, PAGE_SIZE - lens,
-                                        "\tMPEG1\n");
+                                        " MPEG1");
                        break;
                case HDMI_AUDIO_MP3:
                        lens += snprintf(buf + lens, PAGE_SIZE - lens,
-                                        "\tMP3\n");
+                                        " MP3");
                        break;
                case HDMI_AUDIO_MPEG2:
                        lens += snprintf(buf + lens, PAGE_SIZE - lens,
-                                        "\tMPEG2\n");
+                                        " MPEG2");
                        break;
                case HDMI_AUDIO_AAC_LC:
                        lens += snprintf(buf + lens, PAGE_SIZE - lens,
-                                        "\tAAC\n");
+                                        " AAC");
                        break;
                case HDMI_AUDIO_DTS:
                        lens += snprintf(buf + lens, PAGE_SIZE - lens,
-                                        "\tDTS\n");
+                                        " DTS");
                        break;
                case HDMI_AUDIO_ATARC:
                        lens += snprintf(buf + lens, PAGE_SIZE - lens,
-                                        "\tATARC\n");
+                                        " ATARC");
                        break;
                case HDMI_AUDIO_DSD:
                        lens += snprintf(buf + lens, PAGE_SIZE - lens,
-                                        "\tDSD\n");
+                                        " DSD");
                        break;
                case HDMI_AUDIO_E_AC3:
                        lens += snprintf(buf + lens, PAGE_SIZE - lens,
-                                        "\tE-AC3\n");
+                                        " E-AC3");
                        break;
                case HDMI_AUDIO_DTS_HD:
                        lens += snprintf(buf + lens, PAGE_SIZE - lens,
-                                        "\tDTS-HD\n");
+                                        " DTS-HD");
                        break;
                case HDMI_AUDIO_MLP:
                        lens += snprintf(buf + lens, PAGE_SIZE - lens,
-                                        "\tMLP\n");
+                                        " MLP");
                        break;
                case HDMI_AUDIO_DST:
                        lens += snprintf(buf + lens, PAGE_SIZE - lens,
-                                        "\tDST\n");
+                                        " DST");
                        break;
                case HDMI_AUDIO_WMA_PRO:
                        lens += snprintf(buf + lens, PAGE_SIZE - lens,
-                                        "\tWMP-PRO\n");
+                                        " WMP-PRO");
                        break;
                default:
                        lens += snprintf(buf + lens, PAGE_SIZE - lens,
-                                        "\tUnkown\n");
+                                        " Unkown");
                        break;
                }
                lens += snprintf(buf + lens, PAGE_SIZE - lens,
                                 "Support max audio channel is %d\n",
                                 audio->channel);
                lens += snprintf(buf + lens, PAGE_SIZE - lens,
-                                "Support audio sample rate:\n\t");
+                                "Support audio sample rate:");
                if (audio->rate & HDMI_AUDIO_FS_32000)
                        lens += snprintf(buf + lens, PAGE_SIZE - lens,
                                         " 32000");
@@ -459,7 +506,7 @@ static int hdmi_show_sink_info(struct hdmi *hdmi, char *buf, int len)
                        lens += snprintf(buf + lens, PAGE_SIZE - lens,
                                         " 192000");
                lens += snprintf(buf + lens, PAGE_SIZE - lens,
-                                "\nSupport audio word lenght:\n\t");
+                                "\nSupport audio word lenght:");
                if (audio->rate & HDMI_AUDIO_WORD_LENGTH_16bit)
                        lens += snprintf(buf + lens, PAGE_SIZE - lens,
                                         " 16bit");
index db9b651f8c2b53dd54877f618071eb3d74232612..86830682a88bfbff9e981ef144794454fd4e946f 100644 (file)
@@ -170,6 +170,20 @@ enum hdmi_deep_color {
        HDMI_DEEP_COLOR_48BITS = 0x8,
 };
 
+enum hdmi_colorimetry {
+       HDMI_COLORIMETRY_NO_DATA = 0,
+       HDMI_COLORIMETRY_SMTPE_170M,
+       HDMI_COLORIMETRY_ITU709,
+       HDMI_COLORIMETRY_EXTEND_XVYCC_601,
+       HDMI_COLORIMETRY_EXTEND_XVYCC_709,
+       HDMI_COLORIMETRY_EXTEND_SYCC_601,
+       HDMI_COLORIMETRY_EXTEND_ADOBE_YCC601,
+       HDMI_COLORIMETRY_EXTEND_ADOBE_RGB,
+       HDMI_COLORIMETRY_EXTEND_BT_2020_YCC_C, /*constant luminance*/
+       HDMI_COLORIMETRY_EXTEND_BT_2020_YCC,
+       HDMI_COLORIMETRY_EXTEND_BT_2020_RGB,
+};
+
 /* HDMI Audio source */
 enum {
        HDMI_AUDIO_SRC_IIS = 0,
@@ -251,6 +265,7 @@ struct hdmi_video {
        unsigned int color_input;       /* Input video color mode*/
        unsigned int color_output;      /* Output video color mode*/
        unsigned int color_output_depth;/* Output video Color Depth*/
+       unsigned int colorimetry;       /* Output Colorimetry */
        unsigned int sink_hdmi;         /* Output signal is DVI or HDMI*/
        unsigned int format_3d;         /* Output 3D mode*/
 };
@@ -291,6 +306,7 @@ struct hdmi_edid {
        unsigned char dual_view;
        unsigned char osd_disparity_3d;
 
+       unsigned int colorimetry;
        struct fb_monspecs      *specs; /*Device spec*/
        struct list_head modelist;      /*Device supported display mode list*/
        unsigned char baseaudio_support;
@@ -380,9 +396,10 @@ struct hdmi {
                           2 means mute audio,
                           1 means mute display;
                           0 is unmute*/
-       int colordepth;                 /* Ouput color depth*/
-       int colormode;                  /* Ouput color mode*/
+       int colordepth;                 /* Output color depth*/
+       int colormode;                  /* Output color mode*/
        int colormode_input;            /* Input color mode*/
+       int colorimetry;                /* Output colorimetry */
        struct hdmi_edid edid;          /* EDID information*/
        int enable;                     /* Enable flag*/
        int sleep;                      /* Sleep flag*/