V4L/DVB (4006): Stop/start microcontroller when changing sampling frequency

Stop/start microcontroller when changing sampling frequency to prevent 
tinny audio.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c
index f035f2b..b67ad4d 100644
--- a/drivers/media/video/cx25840/cx25840-audio.c
+++ b/drivers/media/video/cx25840/cx25840-audio.c
@@ -181,13 +181,15 @@
 	} else {
 		/* Set Path1 to Analog Demod Main Channel */
 		cx25840_write4(client, 0x8d0, 0x7038061f);
+	}
 
+	set_audclk_freq(client, state->audclk_freq);
+
+	if (state->aud_input != CX25840_AUDIO_SERIAL) {
 		/* When the microcontroller detects the
 		 * audio format, it will unmute the lines */
 		cx25840_and_or(client, 0x803, ~0x10, 0x10);
 	}
-
-	set_audclk_freq(client, state->audclk_freq);
 }
 
 static int get_volume(struct i2c_client *client)
@@ -311,11 +313,21 @@
 
 int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg)
 {
+	struct cx25840_state *state = i2c_get_clientdata(client);
 	struct v4l2_control *ctrl = arg;
+	int retval;
 
 	switch (cmd) {
 	case VIDIOC_INT_AUDIO_CLOCK_FREQ:
-		return set_audclk_freq(client, *(u32 *)arg);
+		if (state->aud_input != CX25840_AUDIO_SERIAL) {
+			cx25840_and_or(client, 0x803, ~0x10, 0);
+			cx25840_write(client, 0x8d3, 0x1f);
+		}
+		retval = set_audclk_freq(client, *(u32 *)arg);
+		if (state->aud_input != CX25840_AUDIO_SERIAL) {
+			cx25840_and_or(client, 0x803, ~0x10, 0x10);
+		}
+		return retval;
 
 	case VIDIOC_G_CTRL:
 		switch (ctrl->id) {