--- v4l-dvb-7c0b887911cf/linux/drivers/media/video/cx18/cx18-av-audio.c	2010-04-05 22:56:43.000000000 -0400
+++ patched/linux/drivers/media/video/cx18/cx18-av-audio.c	2010-03-13 22:06:55.000000000 -0500
@@ -305,14 +305,14 @@
 	struct cx18_av_state *state = &cx->av_state;
 	u8 v;
 
+	/* assert soft reset */
+	v = cx18_av_read(cx, CXADEC_AUDIO_SOFT_RESET) | 0x01;
+	cx18_av_write_expect(cx, CXADEC_AUDIO_SOFT_RESET, v, v, 0x0f);
+
 	/* stop microcontroller */
 	v = cx18_av_read(cx, 0x803) & ~0x10;
 	cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
 
-	/* assert soft reset */
-	v = cx18_av_read(cx, 0x810) | 0x01;
-	cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
-
 	/* Mute everything to prevent the PFFT! */
 	cx18_av_write(cx, 0x8d3, 0x1f);
 
@@ -330,16 +330,17 @@
 
 	set_audclk_freq(cx, state->audclk_freq);
 
-	/* deassert soft reset */
-	v = cx18_av_read(cx, 0x810) & ~0x01;
-	cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
-
 	if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
+		/* start microcontroller */
 		/* When the microcontroller detects the
 		 * audio format, it will unmute the lines */
 		v = cx18_av_read(cx, 0x803) | 0x10;
 		cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
 	}
+
+	/* deassert soft reset */
+	v = cx18_av_read(cx, CXADEC_AUDIO_SOFT_RESET) & ~0x01;
+	cx18_av_write_expect(cx, CXADEC_AUDIO_SOFT_RESET, v, v, 0x0f);
 }
 
 static int get_volume(struct cx18 *cx)
@@ -449,12 +450,13 @@
 		 * changes to the mute register. */
 		v = cx18_av_read(cx, 0x803);
 		if (mute) {
-			/* disable microcontroller */
+			/* stop microcontroller */
 			v &= ~0x10;
 			cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
+			/* mute all of Path 1 */
 			cx18_av_write(cx, 0x8d3, 0x1f);
 		} else {
-			/* enable microcontroller */
+			/* start microcontroller */
 			v |= 0x10;
 			cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
 		}
@@ -471,22 +473,29 @@
 	int retval;
 	u8 v;
 
+	/* assert soft reset */
+	v = cx18_av_read(cx, CXADEC_AUDIO_SOFT_RESET) | 0x1;
+	cx18_av_write_expect(cx, CXADEC_AUDIO_SOFT_RESET, v, v, 0x0f);
+
 	if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
+		/* stop microcontroller */
 		v = cx18_av_read(cx, 0x803) & ~0x10;
 		cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
+		/* mute all of Path 1 */
 		cx18_av_write(cx, 0x8d3, 0x1f);
 	}
-	v = cx18_av_read(cx, 0x810) | 0x1;
-	cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
 
 	retval = set_audclk_freq(cx, freq);
 
-	v = cx18_av_read(cx, 0x810) & ~0x1;
-	cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
 	if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
+		/* start microcontroller */
 		v = cx18_av_read(cx, 0x803) | 0x10;
 		cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
 	}
+
+	/* deassert soft reset */
+	v = cx18_av_read(cx, CXADEC_AUDIO_SOFT_RESET) & ~0x1;
+	cx18_av_write_expect(cx, CXADEC_AUDIO_SOFT_RESET, v, v, 0x0f);
 	return retval;
 }
 
diff -u --recursive --new-file --exclude='.*' --exclude='*.[osa]' --exclude=System.map --exclude='*.orig' --exclude='*.lds' --exclude='*.symvers' --exclude='*.mod.c' --exclude='*.ko' v4l-dvb-7c0b887911cf/linux/drivers/media/video/cx18/cx18-av-core.c patched/linux/drivers/media/video/cx18/cx18-av-core.c
--- v4l-dvb-7c0b887911cf/linux/drivers/media/video/cx18/cx18-av-core.c	2010-04-05 22:56:43.000000000 -0400
+++ patched/linux/drivers/media/video/cx18/cx18-av-core.c	2010-04-10 17:10:13.618719139 -0400
@@ -525,6 +525,10 @@
 	cx18_av_and_or(cx, 0x401, ~0x60, 0);
 	cx18_av_and_or(cx, 0x401, ~0x60, 0x60);
 
+	/* assert soft reset of audio */
+	v = cx18_av_read(cx, CXADEC_AUDIO_SOFT_RESET) | 0x01;
+	cx18_av_write_expect(cx, CXADEC_AUDIO_SOFT_RESET, v, v, 0x0f);
+
 	if (std & V4L2_STD_525_60) {
 		if (std == V4L2_STD_NTSC_M_JP) {
 			/* Japan uses EIAJ audio standard */
@@ -549,14 +553,9 @@
 		cx18_av_write_expect(cx, 0x80b, 0x03, 0x03, 0x3f);
 	}
 
-	v = cx18_av_read(cx, 0x803);
-	if (v & 0x10) {
-		/* restart audio decoder microcontroller */
-		v &= ~0x10;
-		cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
-		v |= 0x10;
-		cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
-	}
+	/* deassert soft reset of audio */
+	v = cx18_av_read(cx, CXADEC_AUDIO_SOFT_RESET) & ~0x01;
+	cx18_av_write_expect(cx, CXADEC_AUDIO_SOFT_RESET, v, v, 0x0f);
 }
 
 static int cx18_av_s_frequency(struct v4l2_subdev *sd,
diff -u --recursive --new-file --exclude='.*' --exclude='*.[osa]' --exclude=System.map --exclude='*.orig' --exclude='*.lds' --exclude='*.symvers' --exclude='*.mod.c' --exclude='*.ko' v4l-dvb-7c0b887911cf/linux/drivers/media/video/cx18/cx18-av-core.h patched/linux/drivers/media/video/cx18/cx18-av-core.h
--- v4l-dvb-7c0b887911cf/linux/drivers/media/video/cx18/cx18-av-core.h	2010-04-05 22:56:43.000000000 -0400
+++ patched/linux/drivers/media/video/cx18/cx18-av-core.h	2010-04-10 17:09:26.532890773 -0400
@@ -246,6 +246,7 @@
 
 #define CXADEC_DW8051_INT          0x80C
 #define CXADEC_GENERAL_CTL         0x810
+#define CXADEC_AUDIO_SOFT_RESET    0x810  /* 0x810 or 0x9cc ??? */
 #define CXADEC_AAGC_CTL            0x814
 #define CXADEC_IF_SRC_CTL          0x818
 #define CXADEC_ANLOG_DEMOD_CTL     0x81C
diff -u --recursive --new-file --exclude='.*' --exclude='*.[osa]' --exclude=System.map --exclude='*.orig' --exclude='*.lds' --exclude='*.symvers' --exclude='*.mod.c' --exclude='*.ko' v4l-dvb-7c0b887911cf/linux/drivers/media/video/cx18/cx18-av-firmware.c patched/linux/drivers/media/video/cx18/cx18-av-firmware.c
--- v4l-dvb-7c0b887911cf/linux/drivers/media/video/cx18/cx18-av-firmware.c	2010-04-05 22:56:43.000000000 -0400
+++ patched/linux/drivers/media/video/cx18/cx18-av-firmware.c	2010-03-13 22:06:55.000000000 -0500
@@ -142,14 +142,20 @@
 		return -EIO;
 	}
 
+	/* Disable firmware upload, keeping the 8051 in reset */
 	cx18_av_write4_expect(cx, CXADEC_DL_CTL,
 				0x03000000 | fw->size, 0x03000000, 0x13000000);
 
 	CX18_INFO_DEV(sd, "loaded %s firmware (%d bytes)\n", FWFILE, size);
 
-	if (cx18_av_verifyfw(cx, fw) == 0)
+	if (cx18_av_verifyfw(cx, fw) == 0) {
+		/* deassert soft reset */
+		v = cx18_av_read4(cx, CXADEC_AUDIO_SOFT_RESET) & ~0x01;
+		cx18_av_write4_expect(cx, CXADEC_AUDIO_SOFT_RESET, v, v, 0x0f);
+		/* deassert 8051 reset */
 		cx18_av_write4_expect(cx, CXADEC_DL_CTL,
 				0x13000000 | fw->size, 0x13000000, 0x13000000);
+	}
 
 	/* Output to the 416 */
 	cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x78000);
