diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2012-10-16 05:40:45 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-11-21 14:43:49 -0500 |
commit | 6b0d5d344a78d43957a9f49c549b6f3aa2dc2082 (patch) | |
tree | d9be6a19a2cca3567ba3cb4ff5d28445acd066f9 /drivers/media/i2c | |
parent | 809396474f41fb6e7e676e298d79856c5e02d755 (diff) |
[media] adv7604: Replace prim_mode by mode
Changes the way the primary mode is handled:
- Remove it from platform_data since it doesn't belong there.
- Add a new mode enum for use with s_routing.
- Collapse the two HDMI modes into one HDMI mode: when setting up the
timings manually we do not need to select HDMI_COMP mode. That's only
needed when selecting a preset.
This patch prepares for the next step where we switch to using the presets
where available.
Signed-off-by: Mats Randgaard <mats.randgaard@cisco.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/i2c')
-rw-r--r-- | drivers/media/i2c/adv7604.c | 78 |
1 files changed, 29 insertions, 49 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 | ||
1206 | static void enable_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mode) | 1203 | static 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 | ||
1236 | static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mode) | 1234 | static 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 */ |