diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2008-06-27 14:33:02 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-07-20 06:15:04 -0400 |
commit | c1738904d6808a091d7d496b445d20671d513ad4 (patch) | |
tree | 30c61db23b8cd77fbbaf421c6de1c17c1de4b067 | |
parent | e078770a050aa686f895a965f54222c0f201feb3 (diff) |
V4L/DVB (8162): cx18: fix PAL/SECAM support
Reverted the 'Fix unintended auto configurations in cx18-av-core' patch,
instead disable the auto config completely.
Fix a bug in cx18_av_vbi_setup() where the standard tests were done
in the wrong order.
Tested with NTSC-M, PAL-BG, PAL-I, PAL-DK, PAL-M, PAL-Nc, SECAM-DK,
SECAM-L and SECAM-BG. The last one does not work at the moment due to
a tda9887.c bug.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r-- | drivers/media/video/cx18/cx18-av-core.c | 74 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-av-core.h | 10 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-av-vbi.c | 25 |
3 files changed, 17 insertions, 92 deletions
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c index faca43eb940f..cf98b2c445f4 100644 --- a/drivers/media/video/cx18/cx18-av-core.c +++ b/drivers/media/video/cx18/cx18-av-core.c | |||
@@ -69,58 +69,6 @@ int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask, | |||
69 | or_value); | 69 | or_value); |
70 | } | 70 | } |
71 | 71 | ||
72 | int cx18_av_write_no_acfg(struct cx18 *cx, u16 addr, u8 value, int no_acfg_mask) | ||
73 | { | ||
74 | int retval; | ||
75 | u32 saved_reg[8] = {0}; | ||
76 | |||
77 | if (no_acfg_mask & CXADEC_NO_ACFG_AFE) { | ||
78 | saved_reg[0] = cx18_av_read4(cx, CXADEC_CHIP_CTRL); | ||
79 | saved_reg[1] = cx18_av_read4(cx, CXADEC_AFE_CTRL); | ||
80 | } | ||
81 | |||
82 | if (no_acfg_mask & CXADEC_NO_ACFG_PLL) { | ||
83 | saved_reg[2] = cx18_av_read4(cx, CXADEC_PLL_CTRL1); | ||
84 | saved_reg[3] = cx18_av_read4(cx, CXADEC_VID_PLL_FRAC); | ||
85 | } | ||
86 | |||
87 | if (no_acfg_mask & CXADEC_NO_ACFG_VID) { | ||
88 | saved_reg[4] = cx18_av_read4(cx, CXADEC_HORIZ_TIM_CTRL); | ||
89 | saved_reg[5] = cx18_av_read4(cx, CXADEC_VERT_TIM_CTRL); | ||
90 | saved_reg[6] = cx18_av_read4(cx, CXADEC_SRC_COMB_CFG); | ||
91 | saved_reg[7] = cx18_av_read4(cx, CXADEC_CHROMA_VBIOFF_CFG); | ||
92 | } | ||
93 | |||
94 | retval = cx18_av_write(cx, addr, value); | ||
95 | |||
96 | if (no_acfg_mask & CXADEC_NO_ACFG_AFE) { | ||
97 | cx18_av_write4(cx, CXADEC_CHIP_CTRL, saved_reg[0]); | ||
98 | cx18_av_write4(cx, CXADEC_AFE_CTRL, saved_reg[1]); | ||
99 | } | ||
100 | |||
101 | if (no_acfg_mask & CXADEC_NO_ACFG_PLL) { | ||
102 | cx18_av_write4(cx, CXADEC_PLL_CTRL1, saved_reg[2]); | ||
103 | cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, saved_reg[3]); | ||
104 | } | ||
105 | |||
106 | if (no_acfg_mask & CXADEC_NO_ACFG_VID) { | ||
107 | cx18_av_write4(cx, CXADEC_HORIZ_TIM_CTRL, saved_reg[4]); | ||
108 | cx18_av_write4(cx, CXADEC_VERT_TIM_CTRL, saved_reg[5]); | ||
109 | cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, saved_reg[6]); | ||
110 | cx18_av_write4(cx, CXADEC_CHROMA_VBIOFF_CFG, saved_reg[7]); | ||
111 | } | ||
112 | |||
113 | return retval; | ||
114 | } | ||
115 | |||
116 | int cx18_av_and_or_no_acfg(struct cx18 *cx, u16 addr, unsigned and_mask, | ||
117 | u8 or_value, int no_acfg_mask) | ||
118 | { | ||
119 | return cx18_av_write_no_acfg(cx, addr, | ||
120 | (cx18_av_read(cx, addr) & and_mask) | | ||
121 | or_value, no_acfg_mask); | ||
122 | } | ||
123 | |||
124 | /* ----------------------------------------------------------------------- */ | 72 | /* ----------------------------------------------------------------------- */ |
125 | 73 | ||
126 | static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, | 74 | static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, |
@@ -221,16 +169,9 @@ static void input_change(struct cx18 *cx) | |||
221 | v4l2_std_id std = state->std; | 169 | v4l2_std_id std = state->std; |
222 | 170 | ||
223 | /* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */ | 171 | /* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */ |
224 | if (std & V4L2_STD_SECAM) | 172 | cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11); |
225 | cx18_av_write_no_acfg(cx, 0x402, 0, CXADEC_NO_ACFG_ALL); | 173 | cx18_av_and_or(cx, 0x401, ~0x60, 0); |
226 | else { | 174 | cx18_av_and_or(cx, 0x401, ~0x60, 0x60); |
227 | cx18_av_write_no_acfg(cx, 0x402, 0x04, CXADEC_NO_ACFG_ALL); | ||
228 | cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11); | ||
229 | } | ||
230 | cx18_av_and_or_no_acfg(cx, 0x401, ~0x60, 0, | ||
231 | CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID); | ||
232 | cx18_av_and_or_no_acfg(cx, 0x401, ~0x60, 0x60, | ||
233 | CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID); | ||
234 | 175 | ||
235 | if (std & V4L2_STD_525_60) { | 176 | if (std & V4L2_STD_525_60) { |
236 | if (std == V4L2_STD_NTSC_M_JP) { | 177 | if (std == V4L2_STD_NTSC_M_JP) { |
@@ -316,8 +257,7 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, | |||
316 | 257 | ||
317 | cx18_av_write(cx, 0x103, reg); | 258 | cx18_av_write(cx, 0x103, reg); |
318 | /* Set INPUT_MODE to Composite (0) or S-Video (1) */ | 259 | /* Set INPUT_MODE to Composite (0) or S-Video (1) */ |
319 | cx18_av_and_or_no_acfg(cx, 0x401, ~0x6, is_composite ? 0 : 0x02, | 260 | cx18_av_and_or(cx, 0x401, ~0x6, is_composite ? 0 : 0x02); |
320 | CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID); | ||
321 | /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ | 261 | /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ |
322 | cx18_av_and_or(cx, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0); | 262 | cx18_av_and_or(cx, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0); |
323 | /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */ | 263 | /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */ |
@@ -373,12 +313,12 @@ static int set_v4lstd(struct cx18 *cx) | |||
373 | This happens for example with the Yuan MPC622. */ | 313 | This happens for example with the Yuan MPC622. */ |
374 | if (fmt >= 4 && fmt < 8) { | 314 | if (fmt >= 4 && fmt < 8) { |
375 | /* Set format to NTSC-M */ | 315 | /* Set format to NTSC-M */ |
376 | cx18_av_and_or_no_acfg(cx, 0x400, ~0xf, 1, CXADEC_NO_ACFG_AFE); | 316 | cx18_av_and_or(cx, 0x400, ~0xf, 1); |
377 | /* Turn off LCOMB */ | 317 | /* Turn off LCOMB */ |
378 | cx18_av_and_or(cx, 0x47b, ~6, 0); | 318 | cx18_av_and_or(cx, 0x47b, ~6, 0); |
379 | } | 319 | } |
380 | cx18_av_and_or_no_acfg(cx, 0x400, ~0xf, fmt, CXADEC_NO_ACFG_AFE); | 320 | cx18_av_and_or(cx, 0x400, ~0x2f, fmt | 0x20); |
381 | cx18_av_and_or_no_acfg(cx, 0x403, ~0x3, pal_m, CXADEC_NO_ACFG_ALL); | 321 | cx18_av_and_or(cx, 0x403, ~0x3, pal_m); |
382 | cx18_av_vbi_setup(cx); | 322 | cx18_av_vbi_setup(cx); |
383 | input_change(cx); | 323 | input_change(cx); |
384 | return 0; | 324 | return 0; |
diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h index c172823ce1d8..39f3c9397158 100644 --- a/drivers/media/video/cx18/cx18-av-core.h +++ b/drivers/media/video/cx18/cx18-av-core.h | |||
@@ -295,24 +295,14 @@ struct cx18_av_state { | |||
295 | #define CXADEC_SELECT_AUDIO_STANDARD_FM 0xF9 /* FM radio */ | 295 | #define CXADEC_SELECT_AUDIO_STANDARD_FM 0xF9 /* FM radio */ |
296 | #define CXADEC_SELECT_AUDIO_STANDARD_AUTO 0xFF /* Auto detect */ | 296 | #define CXADEC_SELECT_AUDIO_STANDARD_AUTO 0xFF /* Auto detect */ |
297 | 297 | ||
298 | /* Flags on what to preserve on write to 0x400-0x403 with cx18_av_.*_no_acfg()*/ | ||
299 | #define CXADEC_NO_ACFG_AFE 0x01 /* Preserve 0x100-0x107 */ | ||
300 | #define CXADEC_NO_ACFG_PLL 0x02 /* Preserve 0x108-0x10f */ | ||
301 | #define CXADEC_NO_ACFG_VID 0x04 /* Preserve 0x470-0x47f */ | ||
302 | #define CXADEC_NO_ACFG_ALL 0x07 | ||
303 | |||
304 | /* ----------------------------------------------------------------------- */ | 298 | /* ----------------------------------------------------------------------- */ |
305 | /* cx18_av-core.c */ | 299 | /* cx18_av-core.c */ |
306 | int cx18_av_write(struct cx18 *cx, u16 addr, u8 value); | 300 | int cx18_av_write(struct cx18 *cx, u16 addr, u8 value); |
307 | int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value); | 301 | int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value); |
308 | int cx18_av_write_no_acfg(struct cx18 *cx, u16 addr, u8 value, | ||
309 | int no_acfg_mask); | ||
310 | u8 cx18_av_read(struct cx18 *cx, u16 addr); | 302 | u8 cx18_av_read(struct cx18 *cx, u16 addr); |
311 | u32 cx18_av_read4(struct cx18 *cx, u16 addr); | 303 | u32 cx18_av_read4(struct cx18 *cx, u16 addr); |
312 | int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value); | 304 | int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value); |
313 | int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value); | 305 | int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value); |
314 | int cx18_av_and_or_no_acfg(struct cx18 *cx, u16 addr, unsigned mask, u8 value, | ||
315 | int no_acfg_mask); | ||
316 | int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg); | 306 | int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg); |
317 | 307 | ||
318 | /* ----------------------------------------------------------------------- */ | 308 | /* ----------------------------------------------------------------------- */ |
diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c index d09f1daf4ebf..0c92f123686f 100644 --- a/drivers/media/video/cx18/cx18-av-vbi.c +++ b/drivers/media/video/cx18/cx18-av-vbi.c | |||
@@ -108,18 +108,18 @@ void cx18_av_vbi_setup(struct cx18 *cx) | |||
108 | src_decimation = 0x21f; | 108 | src_decimation = 0x21f; |
109 | 109 | ||
110 | luma_lpf = 2; | 110 | luma_lpf = 2; |
111 | if (std & V4L2_STD_SECAM) { | 111 | if (std & V4L2_STD_PAL) { |
112 | uv_lpf = 0; | ||
113 | comb = 0; | ||
114 | sc = 0x0a425f; | ||
115 | } else if (std == V4L2_STD_PAL_Nc) { | ||
116 | uv_lpf = 1; | 112 | uv_lpf = 1; |
117 | comb = 0x20; | 113 | comb = 0x20; |
118 | sc = 556453; | 114 | sc = 0x0a8263; |
119 | } else { | 115 | } else if (std == V4L2_STD_PAL_Nc) { |
120 | uv_lpf = 1; | 116 | uv_lpf = 1; |
121 | comb = 0x20; | 117 | comb = 0x20; |
122 | sc = 0x0a8263; | 118 | sc = 0x087da5; |
119 | } else { /* SECAM */ | ||
120 | uv_lpf = 0; | ||
121 | comb = 0; | ||
122 | sc = 0x0a425f; | ||
123 | } | 123 | } |
124 | } else { | 124 | } else { |
125 | hactive = 720; | 125 | hactive = 720; |
@@ -127,25 +127,20 @@ void cx18_av_vbi_setup(struct cx18 *cx) | |||
127 | vactive = 487; | 127 | vactive = 487; |
128 | luma_lpf = 1; | 128 | luma_lpf = 1; |
129 | uv_lpf = 1; | 129 | uv_lpf = 1; |
130 | vblank = 26; | ||
131 | vblank656 = 26; | ||
130 | 132 | ||
131 | src_decimation = 0x21f; | 133 | src_decimation = 0x21f; |
132 | if (std == V4L2_STD_PAL_60) { | 134 | if (std == V4L2_STD_PAL_60) { |
133 | vblank = 26; | ||
134 | vblank656 = 26; | ||
135 | burst = 0x5b; | 135 | burst = 0x5b; |
136 | luma_lpf = 2; | 136 | luma_lpf = 2; |
137 | comb = 0x20; | 137 | comb = 0x20; |
138 | sc = 0x0a8263; | 138 | sc = 0x0a8263; |
139 | } else if (std == V4L2_STD_PAL_M) { | 139 | } else if (std == V4L2_STD_PAL_M) { |
140 | vblank = 20; | ||
141 | vblank656 = 24; | ||
142 | burst = 0x61; | 140 | burst = 0x61; |
143 | comb = 0x20; | 141 | comb = 0x20; |
144 | |||
145 | sc = 555452; | 142 | sc = 555452; |
146 | } else { | 143 | } else { |
147 | vblank = 26; | ||
148 | vblank656 = 26; | ||
149 | burst = 0x5b; | 144 | burst = 0x5b; |
150 | comb = 0x66; | 145 | comb = 0x66; |
151 | sc = 556063; | 146 | sc = 556063; |