Commit c1738904 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

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: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent e078770a
...@@ -69,58 +69,6 @@ int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask, ...@@ -69,58 +69,6 @@ int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask,
or_value); or_value);
} }
int cx18_av_write_no_acfg(struct cx18 *cx, u16 addr, u8 value, int no_acfg_mask)
{
int retval;
u32 saved_reg[8] = {0};
if (no_acfg_mask & CXADEC_NO_ACFG_AFE) {
saved_reg[0] = cx18_av_read4(cx, CXADEC_CHIP_CTRL);
saved_reg[1] = cx18_av_read4(cx, CXADEC_AFE_CTRL);
}
if (no_acfg_mask & CXADEC_NO_ACFG_PLL) {
saved_reg[2] = cx18_av_read4(cx, CXADEC_PLL_CTRL1);
saved_reg[3] = cx18_av_read4(cx, CXADEC_VID_PLL_FRAC);
}
if (no_acfg_mask & CXADEC_NO_ACFG_VID) {
saved_reg[4] = cx18_av_read4(cx, CXADEC_HORIZ_TIM_CTRL);
saved_reg[5] = cx18_av_read4(cx, CXADEC_VERT_TIM_CTRL);
saved_reg[6] = cx18_av_read4(cx, CXADEC_SRC_COMB_CFG);
saved_reg[7] = cx18_av_read4(cx, CXADEC_CHROMA_VBIOFF_CFG);
}
retval = cx18_av_write(cx, addr, value);
if (no_acfg_mask & CXADEC_NO_ACFG_AFE) {
cx18_av_write4(cx, CXADEC_CHIP_CTRL, saved_reg[0]);
cx18_av_write4(cx, CXADEC_AFE_CTRL, saved_reg[1]);
}
if (no_acfg_mask & CXADEC_NO_ACFG_PLL) {
cx18_av_write4(cx, CXADEC_PLL_CTRL1, saved_reg[2]);
cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, saved_reg[3]);
}
if (no_acfg_mask & CXADEC_NO_ACFG_VID) {
cx18_av_write4(cx, CXADEC_HORIZ_TIM_CTRL, saved_reg[4]);
cx18_av_write4(cx, CXADEC_VERT_TIM_CTRL, saved_reg[5]);
cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, saved_reg[6]);
cx18_av_write4(cx, CXADEC_CHROMA_VBIOFF_CFG, saved_reg[7]);
}
return retval;
}
int cx18_av_and_or_no_acfg(struct cx18 *cx, u16 addr, unsigned and_mask,
u8 or_value, int no_acfg_mask)
{
return cx18_av_write_no_acfg(cx, addr,
(cx18_av_read(cx, addr) & and_mask) |
or_value, no_acfg_mask);
}
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, 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,16 +169,9 @@ static void input_change(struct cx18 *cx)
v4l2_std_id std = state->std; v4l2_std_id std = state->std;
/* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */ /* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */
if (std & V4L2_STD_SECAM) cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11);
cx18_av_write_no_acfg(cx, 0x402, 0, CXADEC_NO_ACFG_ALL); cx18_av_and_or(cx, 0x401, ~0x60, 0);
else { cx18_av_and_or(cx, 0x401, ~0x60, 0x60);
cx18_av_write_no_acfg(cx, 0x402, 0x04, CXADEC_NO_ACFG_ALL);
cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11);
}
cx18_av_and_or_no_acfg(cx, 0x401, ~0x60, 0,
CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID);
cx18_av_and_or_no_acfg(cx, 0x401, ~0x60, 0x60,
CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID);
if (std & V4L2_STD_525_60) { if (std & V4L2_STD_525_60) {
if (std == V4L2_STD_NTSC_M_JP) { 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,8 +257,7 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
cx18_av_write(cx, 0x103, reg); cx18_av_write(cx, 0x103, reg);
/* Set INPUT_MODE to Composite (0) or S-Video (1) */ /* Set INPUT_MODE to Composite (0) or S-Video (1) */
cx18_av_and_or_no_acfg(cx, 0x401, ~0x6, is_composite ? 0 : 0x02, cx18_av_and_or(cx, 0x401, ~0x6, is_composite ? 0 : 0x02);
CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID);
/* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
cx18_av_and_or(cx, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0); cx18_av_and_or(cx, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);
/* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */ /* 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,12 +313,12 @@ static int set_v4lstd(struct cx18 *cx)
This happens for example with the Yuan MPC622. */ This happens for example with the Yuan MPC622. */
if (fmt >= 4 && fmt < 8) { if (fmt >= 4 && fmt < 8) {
/* Set format to NTSC-M */ /* Set format to NTSC-M */
cx18_av_and_or_no_acfg(cx, 0x400, ~0xf, 1, CXADEC_NO_ACFG_AFE); cx18_av_and_or(cx, 0x400, ~0xf, 1);
/* Turn off LCOMB */ /* Turn off LCOMB */
cx18_av_and_or(cx, 0x47b, ~6, 0); cx18_av_and_or(cx, 0x47b, ~6, 0);
} }
cx18_av_and_or_no_acfg(cx, 0x400, ~0xf, fmt, CXADEC_NO_ACFG_AFE); cx18_av_and_or(cx, 0x400, ~0x2f, fmt | 0x20);
cx18_av_and_or_no_acfg(cx, 0x403, ~0x3, pal_m, CXADEC_NO_ACFG_ALL); cx18_av_and_or(cx, 0x403, ~0x3, pal_m);
cx18_av_vbi_setup(cx); cx18_av_vbi_setup(cx);
input_change(cx); input_change(cx);
return 0; return 0;
......
...@@ -295,24 +295,14 @@ struct cx18_av_state { ...@@ -295,24 +295,14 @@ struct cx18_av_state {
#define CXADEC_SELECT_AUDIO_STANDARD_FM 0xF9 /* FM radio */ #define CXADEC_SELECT_AUDIO_STANDARD_FM 0xF9 /* FM radio */
#define CXADEC_SELECT_AUDIO_STANDARD_AUTO 0xFF /* Auto detect */ #define CXADEC_SELECT_AUDIO_STANDARD_AUTO 0xFF /* Auto detect */
/* Flags on what to preserve on write to 0x400-0x403 with cx18_av_.*_no_acfg()*/
#define CXADEC_NO_ACFG_AFE 0x01 /* Preserve 0x100-0x107 */
#define CXADEC_NO_ACFG_PLL 0x02 /* Preserve 0x108-0x10f */
#define CXADEC_NO_ACFG_VID 0x04 /* Preserve 0x470-0x47f */
#define CXADEC_NO_ACFG_ALL 0x07
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
/* cx18_av-core.c */ /* cx18_av-core.c */
int cx18_av_write(struct cx18 *cx, u16 addr, u8 value); int cx18_av_write(struct cx18 *cx, u16 addr, u8 value);
int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value); int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value);
int cx18_av_write_no_acfg(struct cx18 *cx, u16 addr, u8 value,
int no_acfg_mask);
u8 cx18_av_read(struct cx18 *cx, u16 addr); u8 cx18_av_read(struct cx18 *cx, u16 addr);
u32 cx18_av_read4(struct cx18 *cx, u16 addr); u32 cx18_av_read4(struct cx18 *cx, u16 addr);
int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value); int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value);
int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value); int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value);
int cx18_av_and_or_no_acfg(struct cx18 *cx, u16 addr, unsigned mask, u8 value,
int no_acfg_mask);
int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg); int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg);
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
......
...@@ -108,18 +108,18 @@ void cx18_av_vbi_setup(struct cx18 *cx) ...@@ -108,18 +108,18 @@ void cx18_av_vbi_setup(struct cx18 *cx)
src_decimation = 0x21f; src_decimation = 0x21f;
luma_lpf = 2; luma_lpf = 2;
if (std & V4L2_STD_SECAM) { if (std & V4L2_STD_PAL) {
uv_lpf = 0;
comb = 0;
sc = 0x0a425f;
} else if (std == V4L2_STD_PAL_Nc) {
uv_lpf = 1; uv_lpf = 1;
comb = 0x20; comb = 0x20;
sc = 556453; sc = 0x0a8263;
} else { } else if (std == V4L2_STD_PAL_Nc) {
uv_lpf = 1; uv_lpf = 1;
comb = 0x20; comb = 0x20;
sc = 0x0a8263; sc = 0x087da5;
} else { /* SECAM */
uv_lpf = 0;
comb = 0;
sc = 0x0a425f;
} }
} else { } else {
hactive = 720; hactive = 720;
...@@ -127,25 +127,20 @@ void cx18_av_vbi_setup(struct cx18 *cx) ...@@ -127,25 +127,20 @@ void cx18_av_vbi_setup(struct cx18 *cx)
vactive = 487; vactive = 487;
luma_lpf = 1; luma_lpf = 1;
uv_lpf = 1; uv_lpf = 1;
vblank = 26;
vblank656 = 26;
src_decimation = 0x21f; src_decimation = 0x21f;
if (std == V4L2_STD_PAL_60) { if (std == V4L2_STD_PAL_60) {
vblank = 26;
vblank656 = 26;
burst = 0x5b; burst = 0x5b;
luma_lpf = 2; luma_lpf = 2;
comb = 0x20; comb = 0x20;
sc = 0x0a8263; sc = 0x0a8263;
} else if (std == V4L2_STD_PAL_M) { } else if (std == V4L2_STD_PAL_M) {
vblank = 20;
vblank656 = 24;
burst = 0x61; burst = 0x61;
comb = 0x20; comb = 0x20;
sc = 555452; sc = 555452;
} else { } else {
vblank = 26;
vblank656 = 26;
burst = 0x5b; burst = 0x5b;
comb = 0x66; comb = 0x66;
sc = 556063; sc = 556063;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment