aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/i2c/adv7842.c
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2013-12-20 03:44:27 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-01-07 03:28:26 -0500
commit69e9ba6f31e6ff93eecdbf6fbeff8e5320fd2155 (patch)
tree65853db64dcf314c21f10a1a24a205162313eb88 /drivers/media/i2c/adv7842.c
parent32dbc8d4d5b2307ade65a28679e904c84f64764e (diff)
[media] adv7842: support YCrCb analog input, receive CEA formats as RGB on VGA input
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>
Diffstat (limited to 'drivers/media/i2c/adv7842.c')
-rw-r--r--drivers/media/i2c/adv7842.c94
1 files changed, 65 insertions, 29 deletions
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
index 05d65a834197..23f3c1f5f010 100644
--- a/drivers/media/i2c/adv7842.c
+++ b/drivers/media/i2c/adv7842.c
@@ -1034,34 +1034,60 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd)
1034{ 1034{
1035 struct adv7842_state *state = to_state(sd); 1035 struct adv7842_state *state = to_state(sd);
1036 1036
1037 v4l2_dbg(2, debug, sd, "%s: rgb_quantization_range = %d\n",
1038 __func__, state->rgb_quantization_range);
1039
1037 switch (state->rgb_quantization_range) { 1040 switch (state->rgb_quantization_range) {
1038 case V4L2_DV_RGB_RANGE_AUTO: 1041 case V4L2_DV_RGB_RANGE_AUTO:
1039 /* automatic */ 1042 if (state->mode == ADV7842_MODE_RGB) {
1040 if (is_digital_input(sd) && !(hdmi_read(sd, 0x05) & 0x80)) { 1043 /* Receiving analog RGB signal
1041 /* receiving DVI-D signal */ 1044 * Set RGB full range (0-255) */
1042 1045 io_write_and_or(sd, 0x02, 0x0f, 0x10);
1043 /* ADV7842 selects RGB limited range regardless of 1046 break;
1044 input format (CE/IT) in automatic mode */ 1047 }
1045 if (state->timings.bt.standards & V4L2_DV_BT_STD_CEA861) { 1048
1046 /* RGB limited range (16-235) */ 1049 if (state->mode == ADV7842_MODE_COMP) {
1047 io_write_and_or(sd, 0x02, 0x0f, 0x00); 1050 /* Receiving analog YPbPr signal
1048 1051 * Set automode */
1049 } else { 1052 io_write_and_or(sd, 0x02, 0x0f, 0xf0);
1050 /* RGB full range (0-255) */ 1053 break;
1051 io_write_and_or(sd, 0x02, 0x0f, 0x10); 1054 }
1052 } 1055
1053 } else { 1056 if (hdmi_read(sd, 0x05) & 0x80) {
1054 /* receiving HDMI or analog signal, set automode */ 1057 /* Receiving HDMI signal
1058 * Set automode */
1055 io_write_and_or(sd, 0x02, 0x0f, 0xf0); 1059 io_write_and_or(sd, 0x02, 0x0f, 0xf0);
1060 break;
1061 }
1062
1063 /* Receiving DVI-D signal
1064 * ADV7842 selects RGB limited range regardless of
1065 * input format (CE/IT) in automatic mode */
1066 if (state->timings.bt.standards & V4L2_DV_BT_STD_CEA861) {
1067 /* RGB limited range (16-235) */
1068 io_write_and_or(sd, 0x02, 0x0f, 0x00);
1069 } else {
1070 /* RGB full range (0-255) */
1071 io_write_and_or(sd, 0x02, 0x0f, 0x10);
1056 } 1072 }
1057 break; 1073 break;
1058 case V4L2_DV_RGB_RANGE_LIMITED: 1074 case V4L2_DV_RGB_RANGE_LIMITED:
1059 /* RGB limited range (16-235) */ 1075 if (state->mode == ADV7842_MODE_COMP) {
1060 io_write_and_or(sd, 0x02, 0x0f, 0x00); 1076 /* YCrCb limited range (16-235) */
1077 io_write_and_or(sd, 0x02, 0x0f, 0x20);
1078 } else {
1079 /* RGB limited range (16-235) */
1080 io_write_and_or(sd, 0x02, 0x0f, 0x00);
1081 }
1061 break; 1082 break;
1062 case V4L2_DV_RGB_RANGE_FULL: 1083 case V4L2_DV_RGB_RANGE_FULL:
1063 /* RGB full range (0-255) */ 1084 if (state->mode == ADV7842_MODE_COMP) {
1064 io_write_and_or(sd, 0x02, 0x0f, 0x10); 1085 /* YCrCb full range (0-255) */
1086 io_write_and_or(sd, 0x02, 0x0f, 0x60);
1087 } else {
1088 /* RGB full range (0-255) */
1089 io_write_and_or(sd, 0x02, 0x0f, 0x10);
1090 }
1065 break; 1091 break;
1066 } 1092 }
1067} 1093}
@@ -1299,7 +1325,7 @@ static int adv7842_dv_timings_cap(struct v4l2_subdev *sd,
1299} 1325}
1300 1326
1301/* Fill the optional fields .standards and .flags in struct v4l2_dv_timings 1327/* Fill the optional fields .standards and .flags in struct v4l2_dv_timings
1302 if the format is listed in adv7604_timings[] */ 1328 if the format is listed in adv7842_timings[] */
1303static void adv7842_fill_optional_dv_timings_fields(struct v4l2_subdev *sd, 1329static void adv7842_fill_optional_dv_timings_fields(struct v4l2_subdev *sd,
1304 struct v4l2_dv_timings *timings) 1330 struct v4l2_dv_timings *timings)
1305{ 1331{
@@ -1442,6 +1468,8 @@ static int adv7842_g_dv_timings(struct v4l2_subdev *sd,
1442static void enable_input(struct v4l2_subdev *sd) 1468static void enable_input(struct v4l2_subdev *sd)
1443{ 1469{
1444 struct adv7842_state *state = to_state(sd); 1470 struct adv7842_state *state = to_state(sd);
1471
1472 set_rgb_quantization_range(sd);
1445 switch (state->mode) { 1473 switch (state->mode) {
1446 case ADV7842_MODE_SDP: 1474 case ADV7842_MODE_SDP:
1447 case ADV7842_MODE_COMP: 1475 case ADV7842_MODE_COMP:
@@ -1586,6 +1614,13 @@ static void select_input(struct v4l2_subdev *sd,
1586 1614
1587 afe_write(sd, 0x00, 0x00); /* power up ADC */ 1615 afe_write(sd, 0x00, 0x00); /* power up ADC */
1588 afe_write(sd, 0xc8, 0x00); /* phase control */ 1616 afe_write(sd, 0xc8, 0x00); /* phase control */
1617 if (state->mode == ADV7842_MODE_COMP) {
1618 /* force to YCrCb */
1619 io_write_and_or(sd, 0x02, 0x0f, 0x60);
1620 } else {
1621 /* force to RGB */
1622 io_write_and_or(sd, 0x02, 0x0f, 0x10);
1623 }
1589 1624
1590 /* set ADI recommended settings for digitizer */ 1625 /* set ADI recommended settings for digitizer */
1591 /* "ADV7842 Register Settings Recommendations 1626 /* "ADV7842 Register Settings Recommendations
@@ -1681,19 +1716,19 @@ static int adv7842_s_routing(struct v4l2_subdev *sd,
1681 1716
1682 switch (input) { 1717 switch (input) {
1683 case ADV7842_SELECT_HDMI_PORT_A: 1718 case ADV7842_SELECT_HDMI_PORT_A:
1684 /* TODO select HDMI_COMP or HDMI_GR */
1685 state->mode = ADV7842_MODE_HDMI; 1719 state->mode = ADV7842_MODE_HDMI;
1686 state->vid_std_select = ADV7842_HDMI_COMP_VID_STD_HD_1250P; 1720 state->vid_std_select = ADV7842_HDMI_COMP_VID_STD_HD_1250P;
1687 state->hdmi_port_a = true; 1721 state->hdmi_port_a = true;
1688 break; 1722 break;
1689 case ADV7842_SELECT_HDMI_PORT_B: 1723 case ADV7842_SELECT_HDMI_PORT_B:
1690 /* TODO select HDMI_COMP or HDMI_GR */
1691 state->mode = ADV7842_MODE_HDMI; 1724 state->mode = ADV7842_MODE_HDMI;
1692 state->vid_std_select = ADV7842_HDMI_COMP_VID_STD_HD_1250P; 1725 state->vid_std_select = ADV7842_HDMI_COMP_VID_STD_HD_1250P;
1693 state->hdmi_port_a = false; 1726 state->hdmi_port_a = false;
1694 break; 1727 break;
1695 case ADV7842_SELECT_VGA_COMP: 1728 case ADV7842_SELECT_VGA_COMP:
1696 v4l2_info(sd, "%s: VGA component: todo\n", __func__); 1729 state->mode = ADV7842_MODE_COMP;
1730 state->vid_std_select = ADV7842_RGB_VID_STD_AUTO_GRAPH_MODE;
1731 break;
1697 case ADV7842_SELECT_VGA_RGB: 1732 case ADV7842_SELECT_VGA_RGB:
1698 state->mode = ADV7842_MODE_RGB; 1733 state->mode = ADV7842_MODE_RGB;
1699 state->vid_std_select = ADV7842_RGB_VID_STD_AUTO_GRAPH_MODE; 1734 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)
2112 static const char * const input_color_space_txt[16] = { 2147 static const char * const input_color_space_txt[16] = {
2113 "RGB limited range (16-235)", "RGB full range (0-255)", 2148 "RGB limited range (16-235)", "RGB full range (0-255)",
2114 "YCbCr Bt.601 (16-235)", "YCbCr Bt.709 (16-235)", 2149 "YCbCr Bt.601 (16-235)", "YCbCr Bt.709 (16-235)",
2115 "XvYCC Bt.601", "XvYCC Bt.709", 2150 "xvYCC Bt.601", "xvYCC Bt.709",
2116 "YCbCr Bt.601 (0-255)", "YCbCr Bt.709 (0-255)", 2151 "YCbCr Bt.601 (0-255)", "YCbCr Bt.709 (0-255)",
2117 "invalid", "invalid", "invalid", "invalid", "invalid", 2152 "invalid", "invalid", "invalid", "invalid", "invalid",
2118 "invalid", "invalid", "automatic" 2153 "invalid", "invalid", "automatic"
@@ -2341,9 +2376,10 @@ static int adv7842_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm)
2341 2376
2342/* ----------------------------------------------------------------------- */ 2377/* ----------------------------------------------------------------------- */
2343 2378
2344static int adv7842_core_init(struct v4l2_subdev *sd, 2379static int adv7842_core_init(struct v4l2_subdev *sd)
2345 const struct adv7842_platform_data *pdata)
2346{ 2380{
2381 struct adv7842_state *state = to_state(sd);
2382 struct adv7842_platform_data *pdata = &state->pdata;
2347 hdmi_write(sd, 0x48, 2383 hdmi_write(sd, 0x48,
2348 (pdata->disable_pwrdnb ? 0x80 : 0) | 2384 (pdata->disable_pwrdnb ? 0x80 : 0) |
2349 (pdata->disable_cable_det_rst ? 0x40 : 0)); 2385 (pdata->disable_cable_det_rst ? 0x40 : 0));
@@ -2356,7 +2392,7 @@ static int adv7842_core_init(struct v4l2_subdev *sd,
2356 2392
2357 /* video format */ 2393 /* video format */
2358 io_write(sd, 0x02, 2394 io_write(sd, 0x02,
2359 pdata->inp_color_space << 4 | 2395 0xf0 |
2360 pdata->alt_gamma << 3 | 2396 pdata->alt_gamma << 3 |
2361 pdata->op_656_range << 2 | 2397 pdata->op_656_range << 2 |
2362 pdata->rgb_out << 1 | 2398 pdata->rgb_out << 1 |
@@ -2570,7 +2606,7 @@ static int adv7842_command_ram_test(struct v4l2_subdev *sd)
2570 adv7842_rewrite_i2c_addresses(sd, pdata); 2606 adv7842_rewrite_i2c_addresses(sd, pdata);
2571 2607
2572 /* and re-init chip and state */ 2608 /* and re-init chip and state */
2573 adv7842_core_init(sd, pdata); 2609 adv7842_core_init(sd);
2574 2610
2575 disable_input(sd); 2611 disable_input(sd);
2576 2612