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>
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index 12a83ec..027c3d3 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -283,19 +283,6 @@
 		msp_write_dem(client, 0x40, state->i2s_mode);
 }
 
-void msp_set_mute(struct i2c_client *client)
-{
-	struct msp_state *state = i2c_get_clientdata(client);
-
-	v4l_dbg(1, msp_debug, client, "mute audio\n");
-	msp_write_dsp(client, 0x0000, 0);
-	msp_write_dsp(client, 0x0007, 1);
-	if (state->has_scart2_out_volume)
-		msp_write_dsp(client, 0x0040, 1);
-	if (state->has_headphones)
-		msp_write_dsp(client, 0x0006, 0);
-}
-
 void msp_set_audio(struct i2c_client *client)
 {
 	struct msp_state *state = i2c_get_clientdata(client);
@@ -347,7 +334,6 @@
 
 	if (NULL == state->kthread)
 		return;
-	msp_set_mute(client);
 	state->watch_stereo = 0;
 	state->restart = 1;
 	wake_up_interruptible(&state->wq);
@@ -375,19 +361,15 @@
 
 /* ------------------------------------------------------------------------ */
 
-static int msp_mode_v4l2_to_v4l1(int rxsubchans)
+static int msp_mode_v4l2_to_v4l1(int rxsubchans, int audmode)
 {
-	int mode = 0;
-
-	if (rxsubchans & V4L2_TUNER_SUB_STEREO)
-		mode |= VIDEO_SOUND_STEREO;
-	if (rxsubchans & V4L2_TUNER_SUB_LANG2)
-		mode |= VIDEO_SOUND_LANG2 | VIDEO_SOUND_STEREO;
-	if (rxsubchans & V4L2_TUNER_SUB_LANG1)
-		mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_STEREO;
-	if (mode == 0)
-		mode |= VIDEO_SOUND_MONO;
-	return mode;
+	if (rxsubchans == V4L2_TUNER_SUB_MONO)
+		return VIDEO_SOUND_MONO;
+	if (rxsubchans == V4L2_TUNER_SUB_STEREO)
+		return VIDEO_SOUND_STEREO;
+	if (audmode == V4L2_TUNER_MODE_LANG2)
+		return VIDEO_SOUND_LANG2;
+	return VIDEO_SOUND_LANG1;
 }
 
 static int msp_mode_v4l1_to_v4l2(int mode)
@@ -606,7 +588,7 @@
 			break;
 		if (state->opmode == OPMODE_AUTOSELECT)
 			msp_detect_stereo(client);
-		va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans);
+		va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans, state->audmode);
 		break;
 	}
 
@@ -621,7 +603,8 @@
 		state->treble = va->treble;
 		msp_set_audio(client);
 
-		if (va->mode != 0 && state->radio == 0) {
+		if (va->mode != 0 && state->radio == 0 &&
+		    state->audmode != msp_mode_v4l1_to_v4l2(va->mode)) {
 			state->audmode = msp_mode_v4l1_to_v4l2(va->mode);
 			msp_set_audmode(client);
 		}
@@ -727,6 +710,8 @@
 
 		if (state->radio)  /* TODO: add mono/stereo support for radio */
 			break;
+		if (state->audmode == vt->audmode)
+			break;
 		state->audmode = vt->audmode;
 		/* only set audmode */
 		msp_set_audmode(client);
@@ -888,7 +873,7 @@
 
 	memset(state, 0, sizeof(*state));
 	state->v4l2_std = V4L2_STD_NTSC;
-	state->audmode = V4L2_TUNER_MODE_LANG1;
+	state->audmode = V4L2_TUNER_MODE_STEREO;
 	state->volume = 58880;	/* 0db gain */
 	state->balance = 32768;	/* 0db gain */
 	state->bass = 32768;
@@ -932,13 +917,16 @@
 	state->has_radio = msp_revision >= 'G';
 	/* Has headphones output: not for stripped down products */
 	state->has_headphones = msp_prod_lo < 5;
+	/* Has scart2 input: not in stripped down products of the '3' family */
+	state->has_scart2 = msp_family >= 4 || msp_prod_lo < 7;
+	/* Has scart3 input: not in stripped down products of the '3' family */
+	state->has_scart3 = msp_family >= 4 || msp_prod_lo < 5;
 	/* Has scart4 input: not in pre D revisions, not in stripped D revs */
 	state->has_scart4 = msp_family >= 4 || (msp_revision >= 'D' && msp_prod_lo < 5);
-	/* Has scart2 and scart3 inputs and scart2 output: not in stripped
-	   down products of the '3' family */
-	state->has_scart23_in_scart2_out = msp_family >= 4 || msp_prod_lo < 5;
+	/* Has scart2 output: not in stripped down products of the '3' family */
+	state->has_scart2_out = msp_family >= 4 || msp_prod_lo < 5;
 	/* Has scart2 a volume control? Not in pre-D revisions. */
-	state->has_scart2_out_volume = msp_revision > 'C' && state->has_scart23_in_scart2_out;
+	state->has_scart2_out_volume = msp_revision > 'C' && state->has_scart2_out;
 	/* Has a configurable i2s out? */
 	state->has_i2s_conf = msp_revision >= 'G' && msp_prod_lo < 7;
 	/* Has subwoofer output: not in pre-D revs and not in stripped down products */