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

V4L/DVB (3324): msp3400 audio handling bug fixes.

- Check capabilities for audio settings (volume, balance,
bass, treble, loudness, mute)
- added loudness support
- added missing VIDEO_AUDIO_BALANCE flags for v4l1 compatibility
- do not call msp_any_detect_stereo for non-autoselect chips to
retrieve the current stereo setting: that will temporarily mute
the sound. It is only needed when the stereo mode might be
changed, and for autoselect msp processors that do not periodically
need to update their stereo setting.
- do not wake up the thread if the standard did not change. Prevents
temporary audio drop-out if the standard is set to the same value.
- fix confused stereo detect code where V4L2_TUNER_SUB_STEREO and
V4L2_TUNER_MODE_STEREO values were used incorrectly.
- stereo mode reporting was broken (v4l2 value used to index a
string array expecting v4l1 mode values).
- do not set dsp register 0x30 in the 3410d thread: that register
does not exist for pre-'G' revision msp chips.
Signed-off-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@brturbo.com.br>
parent 1157020d
No related merge requests found
This diff is collapsed.
...@@ -209,24 +209,10 @@ void msp3400c_setmode(struct i2c_client *client, int type) ...@@ -209,24 +209,10 @@ void msp3400c_setmode(struct i2c_client *client, int type)
} }
} }
/* given a bitmask of VIDEO_SOUND_XXX returns the "best" in the bitmask */
static int msp3400c_best_video_sound(int rxsubchans)
{
if (rxsubchans & V4L2_TUNER_SUB_STEREO)
return V4L2_TUNER_MODE_STEREO;
if (rxsubchans & V4L2_TUNER_SUB_LANG1)
return V4L2_TUNER_MODE_LANG1;
if (rxsubchans & V4L2_TUNER_SUB_LANG2)
return V4L2_TUNER_MODE_LANG2;
return V4L2_TUNER_MODE_MONO;
}
/* turn on/off nicam + stereo */ /* turn on/off nicam + stereo */
void msp3400c_setstereo(struct i2c_client *client, int mode) void msp3400c_setstereo(struct i2c_client *client, int mode)
{ {
static char *strmode[] = { "0", "mono", "stereo", "3", static char *strmode[] = { "mono", "stereo", "lang2", "lang1" };
"lang1", "5", "6", "7", "lang2"
};
struct msp_state *state = i2c_get_clientdata(client); struct msp_state *state = i2c_get_clientdata(client);
int nicam = 0; /* channel source: FM/AM or nicam */ int nicam = 0; /* channel source: FM/AM or nicam */
int src = 0; int src = 0;
...@@ -244,7 +230,7 @@ void msp3400c_setstereo(struct i2c_client *client, int mode) ...@@ -244,7 +230,7 @@ void msp3400c_setstereo(struct i2c_client *client, int mode)
switch (state->mode) { switch (state->mode) {
case MSP_MODE_FM_TERRA: case MSP_MODE_FM_TERRA:
v4l_dbg(1, client, "FM setstereo: %s\n", strmode[mode]); v4l_dbg(1, client, "FM setstereo: %s\n", strmode[mode]);
msp3400c_setcarrier(client,state->second,state->main); msp3400c_setcarrier(client, state->second, state->main);
switch (mode) { switch (mode) {
case V4L2_TUNER_MODE_STEREO: case V4L2_TUNER_MODE_STEREO:
msp_write_dsp(client, 0x000e, 0x3001); msp_write_dsp(client, 0x000e, 0x3001);
...@@ -298,7 +284,7 @@ void msp3400c_setstereo(struct i2c_client *client, int mode) ...@@ -298,7 +284,7 @@ void msp3400c_setstereo(struct i2c_client *client, int mode)
} }
/* switch audio */ /* switch audio */
switch (msp3400c_best_video_sound(mode)) { switch (mode) {
case V4L2_TUNER_MODE_STEREO: case V4L2_TUNER_MODE_STEREO:
src = 0x0020 | nicam; src = 0x0020 | nicam;
break; break;
...@@ -330,6 +316,9 @@ void msp3400c_setstereo(struct i2c_client *client, int mode) ...@@ -330,6 +316,9 @@ void msp3400c_setstereo(struct i2c_client *client, int mode)
msp_write_dsp(client, 0x0009, src); msp_write_dsp(client, 0x0009, src);
msp_write_dsp(client, 0x000a, src); msp_write_dsp(client, 0x000a, src);
msp_write_dsp(client, 0x000b, src); msp_write_dsp(client, 0x000b, src);
msp_write_dsp(client, 0x000c, src);
if (state->has_scart23_in_scart2_out)
msp_write_dsp(client, 0x0041, src);
} }
} }
...@@ -455,9 +444,9 @@ static void watch_stereo(struct i2c_client *client) ...@@ -455,9 +444,9 @@ static void watch_stereo(struct i2c_client *client)
struct msp_state *state = i2c_get_clientdata(client); struct msp_state *state = i2c_get_clientdata(client);
if (autodetect_stereo(client)) { if (autodetect_stereo(client)) {
if (state->stereo & V4L2_TUNER_MODE_STEREO) if (state->rxsubchans & V4L2_TUNER_SUB_STEREO)
msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO); msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO);
else if (state->stereo & VIDEO_SOUND_LANG1) else if (state->rxsubchans & V4L2_TUNER_SUB_LANG1)
msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1); msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1);
else else
msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
...@@ -657,7 +646,7 @@ int msp3410d_thread(void *data) ...@@ -657,7 +646,7 @@ int msp3410d_thread(void *data)
{ {
struct i2c_client *client = data; struct i2c_client *client = data;
struct msp_state *state = i2c_get_clientdata(client); struct msp_state *state = i2c_get_clientdata(client);
int mode,val,i,std; int val, i, std;
v4l_dbg(1, client, "msp3410 daemon started\n"); v4l_dbg(1, client, "msp3410 daemon started\n");
...@@ -687,9 +676,10 @@ int msp3410d_thread(void *data) ...@@ -687,9 +676,10 @@ int msp3410d_thread(void *data)
goto restart; goto restart;
/* start autodetect */ /* start autodetect */
mode = msp_modus(client); std = 1;
std = (state->std & V4L2_STD_NTSC) ? 0x20 : 1; if (state->std & V4L2_STD_NTSC)
msp_write_dem(client, 0x30, mode); std = 0x20;
else
msp_write_dem(client, 0x20, std); msp_write_dem(client, 0x20, std);
state->watch_stereo = 0; state->watch_stereo = 0;
...@@ -703,7 +693,7 @@ int msp3410d_thread(void *data) ...@@ -703,7 +693,7 @@ int msp3410d_thread(void *data)
} else { } else {
/* triggered autodetect */ /* triggered autodetect */
for (;;) { for (;;) {
if (msp_sleep(state,100)) if (msp_sleep(state, 100))
goto restart; goto restart;
/* check results */ /* check results */
......
...@@ -63,6 +63,7 @@ struct msp_state { ...@@ -63,6 +63,7 @@ struct msp_state {
int has_ntsc_jp_d_k3; int has_ntsc_jp_d_k3;
int has_scart4; int has_scart4;
int has_scart23_in_scart2_out; int has_scart23_in_scart2_out;
int has_scart2_out_volume;
int has_subwoofer; int has_subwoofer;
int has_sound_processing; int has_sound_processing;
int has_virtual_dolby_surround; int has_virtual_dolby_surround;
...@@ -72,7 +73,6 @@ struct msp_state { ...@@ -72,7 +73,6 @@ struct msp_state {
int opmode; int opmode;
int mode; int mode;
v4l2_std_id std; v4l2_std_id std;
int stereo;
int nicam_on; int nicam_on;
int acb; int acb;
int in_scart; int in_scart;
...@@ -85,8 +85,8 @@ struct msp_state { ...@@ -85,8 +85,8 @@ struct msp_state {
int audmode; int audmode;
int rxsubchans; int rxsubchans;
int muted; int volume, muted;
int volume, balance; int balance, loudness;
int bass, treble; int bass, treble;
/* thread */ /* thread */
......
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