]> git.karo-electronics.de Git - linux-beck.git/commitdiff
[media] adv7842: support YCrCb analog input, receive CEA formats as RGB on VGA input
authorHans Verkuil <hans.verkuil@cisco.com>
Fri, 20 Dec 2013 08:44:27 +0000 (05:44 -0300)
committerMauro Carvalho Chehab <m.chehab@samsung.com>
Tue, 7 Jan 2014 08:28:26 +0000 (06:28 -0200)
Added support for YCrCb analog input.

If input is ADV7842_MODE_RGB and RGB quantization range is set to
V4L2_DV_RGB_RANGE_AUTO, then video with CEA timings will be received
as RGB. For ADV7842_MODE_COMP, automatic CSC mode will be selected.

See table 48 on page 281 in "ADV7842 Hardware Manual, Rev. 0, January 2011"
for details.

Make sure that when switching inputs the RGB quantization range is
updated as well.

Also updated the platform_data in ezkit to ensure that what was the old
default value is now explicitly specified, so the behavior for that board
is unchanged.

Signed-off-by: Mats Randgaard <matrandg@cisco.com>
Signed-off-by: Martin Bugge <marbugge@cisco.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Cc: Scott Jiang <scott.jiang.linux@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
arch/blackfin/mach-bf609/boards/ezkit.c
drivers/media/i2c/adv7842.c
include/media/adv7842.h

index 82beedd953f648849852acf15f50e789f6c04684..28bdd8ba3a8628236e50beb4121eeebbdfc1da1e 100644 (file)
@@ -1025,7 +1025,6 @@ static struct adv7842_platform_data adv7842_data = {
        .ain_sel = ADV7842_AIN10_11_12_NC_SYNC_4_1,
        .prim_mode = ADV7842_PRIM_MODE_SDP,
        .vid_std_select = ADV7842_SDP_VID_STD_CVBS_SD_4x1,
-       .inp_color_space = ADV7842_INP_COLOR_SPACE_AUTO,
        .i2c_sdp_io = 0x40,
        .i2c_sdp = 0x41,
        .i2c_cp = 0x42,
index 05d65a8341974924494890bf407e434a75f8b2d6..23f3c1f5f010aafe4e190573fcaf511ef78a52de 100644 (file)
@@ -1034,34 +1034,60 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd)
 {
        struct adv7842_state *state = to_state(sd);
 
+       v4l2_dbg(2, debug, sd, "%s: rgb_quantization_range = %d\n",
+                      __func__, state->rgb_quantization_range);
+
        switch (state->rgb_quantization_range) {
        case V4L2_DV_RGB_RANGE_AUTO:
-               /* automatic */
-               if (is_digital_input(sd) && !(hdmi_read(sd, 0x05) & 0x80)) {
-                       /* receiving DVI-D signal */
-
-                       /* ADV7842 selects RGB limited range regardless of
-                          input format (CE/IT) in automatic mode */
-                       if (state->timings.bt.standards & V4L2_DV_BT_STD_CEA861) {
-                               /* RGB limited range (16-235) */
-                               io_write_and_or(sd, 0x02, 0x0f, 0x00);
-
-                       } else {
-                               /* RGB full range (0-255) */
-                               io_write_and_or(sd, 0x02, 0x0f, 0x10);
-                       }
-               } else {
-                       /* receiving HDMI or analog signal, set automode */
+               if (state->mode == ADV7842_MODE_RGB) {
+                       /* Receiving analog RGB signal
+                        * Set RGB full range (0-255) */
+                       io_write_and_or(sd, 0x02, 0x0f, 0x10);
+                       break;
+               }
+
+               if (state->mode == ADV7842_MODE_COMP) {
+                       /* Receiving analog YPbPr signal
+                        * Set automode */
+                       io_write_and_or(sd, 0x02, 0x0f, 0xf0);
+                       break;
+               }
+
+               if (hdmi_read(sd, 0x05) & 0x80) {
+                       /* Receiving HDMI signal
+                        * Set automode */
                        io_write_and_or(sd, 0x02, 0x0f, 0xf0);
+                       break;
+               }
+
+               /* Receiving DVI-D signal
+                * ADV7842 selects RGB limited range regardless of
+                * input format (CE/IT) in automatic mode */
+               if (state->timings.bt.standards & V4L2_DV_BT_STD_CEA861) {
+                       /* RGB limited range (16-235) */
+                       io_write_and_or(sd, 0x02, 0x0f, 0x00);
+               } else {
+                       /* RGB full range (0-255) */
+                       io_write_and_or(sd, 0x02, 0x0f, 0x10);
                }
                break;
        case V4L2_DV_RGB_RANGE_LIMITED:
-               /* RGB limited range (16-235) */
-               io_write_and_or(sd, 0x02, 0x0f, 0x00);
+               if (state->mode == ADV7842_MODE_COMP) {
+                       /* YCrCb limited range (16-235) */
+                       io_write_and_or(sd, 0x02, 0x0f, 0x20);
+               } else {
+                       /* RGB limited range (16-235) */
+                       io_write_and_or(sd, 0x02, 0x0f, 0x00);
+               }
                break;
        case V4L2_DV_RGB_RANGE_FULL:
-               /* RGB full range (0-255) */
-               io_write_and_or(sd, 0x02, 0x0f, 0x10);
+               if (state->mode == ADV7842_MODE_COMP) {
+                       /* YCrCb full range (0-255) */
+                       io_write_and_or(sd, 0x02, 0x0f, 0x60);
+               } else {
+                       /* RGB full range (0-255) */
+                       io_write_and_or(sd, 0x02, 0x0f, 0x10);
+               }
                break;
        }
 }
@@ -1299,7 +1325,7 @@ static int adv7842_dv_timings_cap(struct v4l2_subdev *sd,
 }
 
 /* Fill the optional fields .standards and .flags in struct v4l2_dv_timings
-   if the format is listed in adv7604_timings[] */
+   if the format is listed in adv7842_timings[] */
 static void adv7842_fill_optional_dv_timings_fields(struct v4l2_subdev *sd,
                struct v4l2_dv_timings *timings)
 {
@@ -1442,6 +1468,8 @@ static int adv7842_g_dv_timings(struct v4l2_subdev *sd,
 static void enable_input(struct v4l2_subdev *sd)
 {
        struct adv7842_state *state = to_state(sd);
+
+       set_rgb_quantization_range(sd);
        switch (state->mode) {
        case ADV7842_MODE_SDP:
        case ADV7842_MODE_COMP:
@@ -1586,6 +1614,13 @@ static void select_input(struct v4l2_subdev *sd,
 
                afe_write(sd, 0x00, 0x00); /* power up ADC */
                afe_write(sd, 0xc8, 0x00); /* phase control */
+               if (state->mode == ADV7842_MODE_COMP) {
+                       /* force to YCrCb */
+                       io_write_and_or(sd, 0x02, 0x0f, 0x60);
+               } else {
+                       /* force to RGB */
+                       io_write_and_or(sd, 0x02, 0x0f, 0x10);
+               }
 
                /* set ADI recommended settings for digitizer */
                /* "ADV7842 Register Settings Recommendations
@@ -1681,19 +1716,19 @@ static int adv7842_s_routing(struct v4l2_subdev *sd,
 
        switch (input) {
        case ADV7842_SELECT_HDMI_PORT_A:
-               /* TODO select HDMI_COMP or HDMI_GR */
                state->mode = ADV7842_MODE_HDMI;
                state->vid_std_select = ADV7842_HDMI_COMP_VID_STD_HD_1250P;
                state->hdmi_port_a = true;
                break;
        case ADV7842_SELECT_HDMI_PORT_B:
-               /* TODO select HDMI_COMP or HDMI_GR */
                state->mode = ADV7842_MODE_HDMI;
                state->vid_std_select = ADV7842_HDMI_COMP_VID_STD_HD_1250P;
                state->hdmi_port_a = false;
                break;
        case ADV7842_SELECT_VGA_COMP:
-               v4l2_info(sd, "%s: VGA component: todo\n", __func__);
+               state->mode = ADV7842_MODE_COMP;
+               state->vid_std_select = ADV7842_RGB_VID_STD_AUTO_GRAPH_MODE;
+               break;
        case ADV7842_SELECT_VGA_RGB:
                state->mode = ADV7842_MODE_RGB;
                state->vid_std_select = ADV7842_RGB_VID_STD_AUTO_GRAPH_MODE;
@@ -2112,7 +2147,7 @@ static int adv7842_cp_log_status(struct v4l2_subdev *sd)
        static const char * const input_color_space_txt[16] = {
                "RGB limited range (16-235)", "RGB full range (0-255)",
                "YCbCr Bt.601 (16-235)", "YCbCr Bt.709 (16-235)",
-               "XvYCC Bt.601", "XvYCC Bt.709",
+               "xvYCC Bt.601", "xvYCC Bt.709",
                "YCbCr Bt.601 (0-255)", "YCbCr Bt.709 (0-255)",
                "invalid", "invalid", "invalid", "invalid", "invalid",
                "invalid", "invalid", "automatic"
@@ -2341,9 +2376,10 @@ static int adv7842_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm)
 
 /* ----------------------------------------------------------------------- */
 
-static int adv7842_core_init(struct v4l2_subdev *sd,
-               const struct adv7842_platform_data *pdata)
+static int adv7842_core_init(struct v4l2_subdev *sd)
 {
+       struct adv7842_state *state = to_state(sd);
+       struct adv7842_platform_data *pdata = &state->pdata;
        hdmi_write(sd, 0x48,
                   (pdata->disable_pwrdnb ? 0x80 : 0) |
                   (pdata->disable_cable_det_rst ? 0x40 : 0));
@@ -2356,7 +2392,7 @@ static int adv7842_core_init(struct v4l2_subdev *sd,
 
        /* video format */
        io_write(sd, 0x02,
-                pdata->inp_color_space << 4 |
+                0xf0 |
                 pdata->alt_gamma << 3 |
                 pdata->op_656_range << 2 |
                 pdata->rgb_out << 1 |
@@ -2570,7 +2606,7 @@ static int adv7842_command_ram_test(struct v4l2_subdev *sd)
        adv7842_rewrite_i2c_addresses(sd, pdata);
 
        /* and re-init chip and state */
-       adv7842_core_init(sd, pdata);
+       adv7842_core_init(sd);
 
        disable_input(sd);
 
index c023f88475da3ce29b9e90b9f5abf875dbd12057..f4e9d0d68c13cab07b302964d9faf7bd7c92fb28 100644 (file)
@@ -163,9 +163,6 @@ struct adv7842_platform_data {
        /* Video standard */
        enum adv7842_vid_std_select vid_std_select;
 
-       /* Input Color Space */
-       enum adv7842_inp_color_space inp_color_space;
-
        /* Select output format */
        enum adv7842_op_format_sel op_format_sel;