diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2006-03-30 19:50:34 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-04-02 04:56:06 -0300 |
commit | 0020d3ef915fc01a0184bc96eeb3c240bded5d8e (patch) | |
tree | 89685985691405ae3c407b699a1f8cefa19425ce /drivers/media/video/msp3400-kthreads.c | |
parent | 9bc7400a9d01b1fe05c7f0200e7384e17794f6e4 (diff) | |
download | linux-0020d3ef915fc01a0184bc96eeb3c240bded5d8e.tar.gz linux-0020d3ef915fc01a0184bc96eeb3c240bded5d8e.tar.xz |
V4L/DVB (3693): Fix msp3400c and bttv stereo/mono/bilingual detection/handling
- msp3400c did not detect the second carrier, thus being always mono.
- properly mute the msp3400c while detecting the carrier.
- fix checks on the presence of scart2/3 inputs and scart 2 output.
- implement proper audio mode fallbacks for msp3400c/d, identical to the
way msp3400g works.
- MODE_STEREO no longer produces dual languages when set for a bilingual
transmission, instead it falls back to LANG1. Use LANG1_LANG2 to hear
both languages of a bilingual transmission. This is much more intuitive
for the user and is in accordance with the preferred usage in the v4l2
specification.
- bttv tried to implement v4l2 calls with v4l1 calls to the i2c devices,
completely mangling the audmode/rxsubchans handling. v4l2 calls now do
v4l2 calls to the i2c devices.
- fixed broken i2c_vidiocschan in bttv.
- add start/end lines to LOG_STATUS.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/msp3400-kthreads.c')
-rw-r--r-- | drivers/media/video/msp3400-kthreads.c | 71 |
1 files changed, 39 insertions, 32 deletions
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c index 1a4564a7e92f..926095c6d826 100644 --- a/drivers/media/video/msp3400-kthreads.c +++ b/drivers/media/video/msp3400-kthreads.c @@ -170,7 +170,7 @@ static void msp_set_source(struct i2c_client *client, u16 src) msp_write_dsp(client, 0x000a, src); msp_write_dsp(client, 0x000b, src); msp_write_dsp(client, 0x000c, src); - if (state->has_scart23_in_scart2_out) + if (state->has_scart2_out) msp_write_dsp(client, 0x0041, src); } @@ -240,15 +240,22 @@ static void msp3400c_set_audmode(struct i2c_client *client) return; } - /* If no second language is available, switch to the first language */ - if ((audmode == V4L2_TUNER_MODE_LANG2 || - audmode == V4L2_TUNER_MODE_LANG1_LANG2) && - !(state->rxsubchans & V4L2_TUNER_SUB_LANG2)) - audmode = V4L2_TUNER_MODE_LANG1; - /* switch to stereo for stereo transmission, otherwise - keep first language */ - if (audmode == V4L2_TUNER_MODE_LANG1 && - (state->rxsubchans & V4L2_TUNER_SUB_STEREO)) + /* Note: for the C and D revs no NTSC stereo + SAP is possible as + the hardware does not support SAP. So the rxsubchans combination + of STEREO | LANG2 does not occur. */ + + /* switch to mono if only mono is available */ + if (state->rxsubchans == V4L2_TUNER_SUB_MONO) + audmode = V4L2_TUNER_MODE_MONO; + /* if bilingual */ + else if (state->rxsubchans & V4L2_TUNER_SUB_LANG2) { + /* and mono or stereo, then fallback to lang1 */ + if (audmode == V4L2_TUNER_MODE_MONO || + audmode == V4L2_TUNER_MODE_STEREO) + audmode = V4L2_TUNER_MODE_LANG1; + } + /* if stereo, and audmode is not mono, then switch to stereo */ + else if (audmode != V4L2_TUNER_MODE_MONO) audmode = V4L2_TUNER_MODE_STEREO; /* switch demodulator */ @@ -308,6 +315,7 @@ static void msp3400c_set_audmode(struct i2c_client *client) } /* switch audio */ + v4l_dbg(1, msp_debug, client, "set audmode %d\n", audmode); switch (audmode) { case V4L2_TUNER_MODE_STEREO: case V4L2_TUNER_MODE_LANG1_LANG2: @@ -476,8 +484,9 @@ int msp3400c_thread(void *data) continue; } - /* mute */ - msp_set_mute(client); + /* put into sane state (and mute) */ + msp_reset(client); + msp3400c_set_mode(client, MSP_MODE_AM_DETECT); val1 = val2 = 0; max1 = max2 = -1; @@ -560,7 +569,6 @@ int msp3400c_thread(void *data) /* B/G NICAM */ state->second = msp3400c_carrier_detect_55[max2].cdo; msp3400c_set_mode(client, MSP_MODE_FM_NICAM1); - msp3400c_set_carrier(client, state->second, state->main); state->nicam_on = 1; state->watch_stereo = 1; } else { @@ -571,7 +579,6 @@ int msp3400c_thread(void *data) /* PAL I NICAM */ state->second = MSP_CARRIER(6.552); msp3400c_set_mode(client, MSP_MODE_FM_NICAM2); - msp3400c_set_carrier(client, state->second, state->main); state->nicam_on = 1; state->watch_stereo = 1; break; @@ -585,13 +592,11 @@ int msp3400c_thread(void *data) /* L NICAM or AM-mono */ state->second = msp3400c_carrier_detect_65[max2].cdo; msp3400c_set_mode(client, MSP_MODE_AM_NICAM); - msp3400c_set_carrier(client, state->second, state->main); state->watch_stereo = 1; } else if (max2 == 0 && state->has_nicam) { /* D/K NICAM */ state->second = msp3400c_carrier_detect_65[max2].cdo; msp3400c_set_mode(client, MSP_MODE_FM_NICAM1); - msp3400c_set_carrier(client, state->second, state->main); state->nicam_on = 1; state->watch_stereo = 1; } else { @@ -603,13 +608,15 @@ int msp3400c_thread(void *data) no_second: state->second = msp3400c_carrier_detect_main[max1].cdo; msp3400c_set_mode(client, MSP_MODE_FM_TERRA); - msp3400c_set_carrier(client, state->second, state->main); state->rxsubchans = V4L2_TUNER_SUB_MONO; break; } + msp3400c_set_carrier(client, state->second, state->main); - /* unmute */ + /* unmute, restore misc registers */ msp_set_audio(client); + + msp_write_dsp(client, 0x13, state->acb); msp3400c_set_audmode(client); if (msp_debug) @@ -617,12 +624,12 @@ int msp3400c_thread(void *data) /* monitor tv audio mode, the first time don't wait so long to get a quick stereo/bilingual result */ - if (msp_sleep(state, 1000)) - goto restart; + count = 20; while (state->watch_stereo) { watch_stereo(client); - if (msp_sleep(state, 5000)) + if (msp_sleep(state, count ? 200 : 5000)) goto restart; + if (count) count--; } } v4l_dbg(1, msp_debug, client, "thread: exit\n"); @@ -634,7 +641,7 @@ int msp3410d_thread(void *data) { struct i2c_client *client = data; struct msp_state *state = i2c_get_clientdata(client); - int val, i, std; + int val, i, std, count; v4l_dbg(1, msp_debug, client, "msp3410 daemon started\n"); @@ -775,12 +782,12 @@ int msp3410d_thread(void *data) /* monitor tv audio mode, the first time don't wait so long to get a quick stereo/bilingual result */ - if (msp_sleep(state, 1000)) - goto restart; + count = 20; while (state->watch_stereo) { watch_stereo(client); - if (msp_sleep(state, 5000)) + if (msp_sleep(state, count ? 200 : 5000)) goto restart; + if (count) count--; } } v4l_dbg(1, msp_debug, client, "thread: exit\n"); @@ -837,20 +844,20 @@ static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in) source = 0; /* mono only */ matrix = 0x30; break; - case V4L2_TUNER_MODE_LANG1: - source = 3; /* stereo or A */ - matrix = 0x00; - break; case V4L2_TUNER_MODE_LANG2: source = 4; /* stereo or B */ matrix = 0x10; break; - case V4L2_TUNER_MODE_STEREO: case V4L2_TUNER_MODE_LANG1_LANG2: - default: source = 1; /* stereo or A|B */ matrix = 0x20; break; + case V4L2_TUNER_MODE_STEREO: + case V4L2_TUNER_MODE_LANG1: + default: + source = 3; /* stereo or A */ + matrix = 0x00; + break; } if (in == MSP_DSP_OUT_TUNER) @@ -877,7 +884,7 @@ static void msp34xxg_set_sources(struct i2c_client *client) msp34xxg_set_source(client, 0x000c, (in >> 4) & 0xf); msp34xxg_set_source(client, 0x0009, (in >> 8) & 0xf); msp34xxg_set_source(client, 0x000a, (in >> 12) & 0xf); - if (state->has_scart23_in_scart2_out) + if (state->has_scart2_out) msp34xxg_set_source(client, 0x0041, (in >> 16) & 0xf); msp34xxg_set_source(client, 0x000b, (in >> 20) & 0xf); } |