aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/i2c/adv7604.c78
-rw-r--r--include/media/adv7604.h21
2 files changed, 39 insertions, 60 deletions
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index 75a8395b8992..74a18c0fc10d 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -53,8 +53,7 @@ MODULE_LICENSE("GPL");
53/* ADV7604 system clock frequency */ 53/* ADV7604 system clock frequency */
54#define ADV7604_fsc (28636360) 54#define ADV7604_fsc (28636360)
55 55
56#define DIGITAL_INPUT ((state->prim_mode == ADV7604_PRIM_MODE_HDMI_COMP) || \ 56#define DIGITAL_INPUT (state->mode == ADV7604_MODE_HDMI)
57 (state->prim_mode == ADV7604_PRIM_MODE_HDMI_GR))
58 57
59/* 58/*
60 ********************************************************************** 59 **********************************************************************
@@ -68,7 +67,7 @@ struct adv7604_state {
68 struct v4l2_subdev sd; 67 struct v4l2_subdev sd;
69 struct media_pad pad; 68 struct media_pad pad;
70 struct v4l2_ctrl_handler hdl; 69 struct v4l2_ctrl_handler hdl;
71 enum adv7604_prim_mode prim_mode; 70 enum adv7604_mode mode;
72 struct v4l2_dv_timings timings; 71 struct v4l2_dv_timings timings;
73 u8 edid[256]; 72 u8 edid[256];
74 unsigned edid_blocks; 73 unsigned edid_blocks;
@@ -738,12 +737,7 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd)
738 switch (state->rgb_quantization_range) { 737 switch (state->rgb_quantization_range) {
739 case V4L2_DV_RGB_RANGE_AUTO: 738 case V4L2_DV_RGB_RANGE_AUTO:
740 /* automatic */ 739 /* automatic */
741 if ((hdmi_read(sd, 0x05) & 0x80) || 740 if (DIGITAL_INPUT && !(hdmi_read(sd, 0x05) & 0x80)) {
742 (state->prim_mode == ADV7604_PRIM_MODE_COMP) ||
743 (state->prim_mode == ADV7604_PRIM_MODE_RGB)) {
744 /* receiving HDMI or analog signal */
745 io_write_and_or(sd, 0x02, 0x0f, 0xf0);
746 } else {
747 /* receiving DVI-D signal */ 741 /* receiving DVI-D signal */
748 742
749 /* ADV7604 selects RGB limited range regardless of 743 /* ADV7604 selects RGB limited range regardless of
@@ -756,6 +750,9 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd)
756 /* RGB full range (0-255) */ 750 /* RGB full range (0-255) */
757 io_write_and_or(sd, 0x02, 0x0f, 0x10); 751 io_write_and_or(sd, 0x02, 0x0f, 0x10);
758 } 752 }
753 } else {
754 /* receiving HDMI or analog signal, set automode */
755 io_write_and_or(sd, 0x02, 0x0f, 0xf0);
759 } 756 }
760 break; 757 break;
761 case V4L2_DV_RGB_RANGE_LIMITED: 758 case V4L2_DV_RGB_RANGE_LIMITED:
@@ -1203,24 +1200,25 @@ static int adv7604_g_dv_timings(struct v4l2_subdev *sd,
1203 return 0; 1200 return 0;
1204} 1201}
1205 1202
1206static void enable_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mode) 1203static void enable_input(struct v4l2_subdev *sd)
1207{ 1204{
1208 switch (prim_mode) { 1205 struct adv7604_state *state = to_state(sd);
1209 case ADV7604_PRIM_MODE_COMP: 1206
1210 case ADV7604_PRIM_MODE_RGB: 1207 switch (state->mode) {
1208 case ADV7604_MODE_COMP:
1209 case ADV7604_MODE_GR:
1211 /* enable */ 1210 /* enable */
1212 io_write(sd, 0x15, 0xb0); /* Disable Tristate of Pins (no audio) */ 1211 io_write(sd, 0x15, 0xb0); /* Disable Tristate of Pins (no audio) */
1213 break; 1212 break;
1214 case ADV7604_PRIM_MODE_HDMI_COMP: 1213 case ADV7604_MODE_HDMI:
1215 case ADV7604_PRIM_MODE_HDMI_GR:
1216 /* enable */ 1214 /* enable */
1217 hdmi_write(sd, 0x1a, 0x0a); /* Unmute audio */ 1215 hdmi_write(sd, 0x1a, 0x0a); /* Unmute audio */
1218 hdmi_write(sd, 0x01, 0x00); /* Enable HDMI clock terminators */ 1216 hdmi_write(sd, 0x01, 0x00); /* Enable HDMI clock terminators */
1219 io_write(sd, 0x15, 0xa0); /* Disable Tristate of Pins */ 1217 io_write(sd, 0x15, 0xa0); /* Disable Tristate of Pins */
1220 break; 1218 break;
1221 default: 1219 default:
1222 v4l2_err(sd, "%s: reserved primary mode 0x%0x\n", 1220 v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n",
1223 __func__, prim_mode); 1221 __func__, state->mode);
1224 break; 1222 break;
1225 } 1223 }
1226} 1224}
@@ -1233,11 +1231,13 @@ static void disable_input(struct v4l2_subdev *sd)
1233 hdmi_write(sd, 0x01, 0x78); /* Disable HDMI clock terminators */ 1231 hdmi_write(sd, 0x01, 0x78); /* Disable HDMI clock terminators */
1234} 1232}
1235 1233
1236static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mode) 1234static void select_input(struct v4l2_subdev *sd)
1237{ 1235{
1238 switch (prim_mode) { 1236 struct adv7604_state *state = to_state(sd);
1239 case ADV7604_PRIM_MODE_COMP: 1237
1240 case ADV7604_PRIM_MODE_RGB: 1238 switch (state->mode) {
1239 case ADV7604_MODE_COMP:
1240 case ADV7604_MODE_GR:
1241 /* set mode and select free run resolution */ 1241 /* set mode and select free run resolution */
1242 io_write(sd, 0x00, 0x07); /* video std */ 1242 io_write(sd, 0x00, 0x07); /* video std */
1243 io_write(sd, 0x01, 0x02); /* prim mode */ 1243 io_write(sd, 0x01, 0x02); /* prim mode */
@@ -1271,13 +1271,10 @@ static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mod
1271 cp_write(sd, 0x40, 0x5c); /* CP core pre-gain control. Graphics mode */ 1271 cp_write(sd, 0x40, 0x5c); /* CP core pre-gain control. Graphics mode */
1272 break; 1272 break;
1273 1273
1274 case ADV7604_PRIM_MODE_HDMI_COMP: 1274 case ADV7604_MODE_HDMI:
1275 case ADV7604_PRIM_MODE_HDMI_GR:
1276 /* set mode and select free run resolution */ 1275 /* set mode and select free run resolution */
1277 /* video std */ 1276 io_write(sd, 0x00, 0x02); /* video std */
1278 io_write(sd, 0x00, 1277 io_write(sd, 0x01, 0x06); /* prim mode */
1279 (prim_mode == ADV7604_PRIM_MODE_HDMI_GR) ? 0x02 : 0x1e);
1280 io_write(sd, 0x01, prim_mode); /* prim mode */
1281 /* disable embedded syncs for auto graphics mode */ 1278 /* disable embedded syncs for auto graphics mode */
1282 cp_write_and_or(sd, 0x81, 0xef, 0x00); 1279 cp_write_and_or(sd, 0x81, 0xef, 0x00);
1283 1280
@@ -1309,7 +1306,8 @@ static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mod
1309 1306
1310 break; 1307 break;
1311 default: 1308 default:
1312 v4l2_err(sd, "%s: reserved primary mode 0x%0x\n", __func__, prim_mode); 1309 v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n",
1310 __func__, state->mode);
1313 break; 1311 break;
1314 } 1312 }
1315} 1313}
@@ -1321,26 +1319,13 @@ static int adv7604_s_routing(struct v4l2_subdev *sd,
1321 1319
1322 v4l2_dbg(2, debug, sd, "%s: input %d", __func__, input); 1320 v4l2_dbg(2, debug, sd, "%s: input %d", __func__, input);
1323 1321
1324 switch (input) { 1322 state->mode = input;
1325 case 0:
1326 /* TODO select HDMI_COMP or HDMI_GR */
1327 state->prim_mode = ADV7604_PRIM_MODE_HDMI_COMP;
1328 break;
1329 case 1:
1330 state->prim_mode = ADV7604_PRIM_MODE_RGB;
1331 break;
1332 case 2:
1333 state->prim_mode = ADV7604_PRIM_MODE_COMP;
1334 break;
1335 default:
1336 return -EINVAL;
1337 }
1338 1323
1339 disable_input(sd); 1324 disable_input(sd);
1340 1325
1341 select_input(sd, state->prim_mode); 1326 select_input(sd);
1342 1327
1343 enable_input(sd, state->prim_mode); 1328 enable_input(sd);
1344 1329
1345 return 0; 1330 return 0;
1346} 1331}
@@ -1724,11 +1709,6 @@ static int adv7604_core_init(struct v4l2_subdev *sd)
1724 afe_write(sd, 0x02, pdata->ain_sel); /* Select analog input muxing mode */ 1709 afe_write(sd, 0x02, pdata->ain_sel); /* Select analog input muxing mode */
1725 io_write_and_or(sd, 0x30, ~(1 << 4), pdata->output_bus_lsb_to_msb << 4); 1710 io_write_and_or(sd, 0x30, ~(1 << 4), pdata->output_bus_lsb_to_msb << 4);
1726 1711
1727 state->prim_mode = pdata->prim_mode;
1728 select_input(sd, pdata->prim_mode);
1729
1730 enable_input(sd, pdata->prim_mode);
1731
1732 /* interrupts */ 1712 /* interrupts */
1733 io_write(sd, 0x40, 0xc2); /* Configure INT1 */ 1713 io_write(sd, 0x40, 0xc2); /* Configure INT1 */
1734 io_write(sd, 0x41, 0xd7); /* STDI irq for any change, disable INT2 */ 1714 io_write(sd, 0x41, 0xd7); /* STDI irq for any change, disable INT2 */
diff --git a/include/media/adv7604.h b/include/media/adv7604.h
index 171b957db743..dc004bc926c9 100644
--- a/include/media/adv7604.h
+++ b/include/media/adv7604.h
@@ -40,14 +40,6 @@ enum adv7604_op_ch_sel {
40 ADV7604_OP_CH_SEL_RBG = 5, 40 ADV7604_OP_CH_SEL_RBG = 5,
41}; 41};
42 42
43/* Primary mode (IO register 0x01, [3:0]) */
44enum adv7604_prim_mode {
45 ADV7604_PRIM_MODE_COMP = 1,
46 ADV7604_PRIM_MODE_RGB = 2,
47 ADV7604_PRIM_MODE_HDMI_COMP = 5,
48 ADV7604_PRIM_MODE_HDMI_GR = 6,
49};
50
51/* Input Color Space (IO register 0x02, [7:4]) */ 43/* Input Color Space (IO register 0x02, [7:4]) */
52enum adv7604_inp_color_space { 44enum adv7604_inp_color_space {
53 ADV7604_INP_COLOR_SPACE_LIM_RGB = 0, 45 ADV7604_INP_COLOR_SPACE_LIM_RGB = 0,
@@ -103,9 +95,6 @@ struct adv7604_platform_data {
103 /* Bus rotation and reordering */ 95 /* Bus rotation and reordering */
104 enum adv7604_op_ch_sel op_ch_sel; 96 enum adv7604_op_ch_sel op_ch_sel;
105 97
106 /* Primary mode */
107 enum adv7604_prim_mode prim_mode;
108
109 /* Select output format */ 98 /* Select output format */
110 enum adv7604_op_format_sel op_format_sel; 99 enum adv7604_op_format_sel op_format_sel;
111 100
@@ -142,6 +131,16 @@ struct adv7604_platform_data {
142 u8 i2c_vdp; 131 u8 i2c_vdp;
143}; 132};
144 133
134/*
135 * Mode of operation.
136 * This is used as the input argument of the s_routing video op.
137 */
138enum adv7604_mode {
139 ADV7604_MODE_COMP,
140 ADV7604_MODE_GR,
141 ADV7604_MODE_HDMI,
142};
143
145#define V4L2_CID_ADV_RX_ANALOG_SAMPLING_PHASE (V4L2_CID_DV_CLASS_BASE + 0x1000) 144#define V4L2_CID_ADV_RX_ANALOG_SAMPLING_PHASE (V4L2_CID_DV_CLASS_BASE + 0x1000)
146#define V4L2_CID_ADV_RX_FREE_RUN_COLOR_MANUAL (V4L2_CID_DV_CLASS_BASE + 0x1001) 145#define V4L2_CID_ADV_RX_FREE_RUN_COLOR_MANUAL (V4L2_CID_DV_CLASS_BASE + 0x1001)
147#define V4L2_CID_ADV_RX_FREE_RUN_COLOR (V4L2_CID_DV_CLASS_BASE + 0x1002) 146#define V4L2_CID_ADV_RX_FREE_RUN_COLOR (V4L2_CID_DV_CLASS_BASE + 0x1002)