Index: linux/drivers/sound/pxa-i2s_spitz.c
===================================================================
--- linux/drivers/sound/pxa-i2s_spitz.c	(revision 41)
+++ linux/drivers/sound/pxa-i2s_spitz.c	(revision 42)
@@ -34,6 +34,7 @@
 #include <linux/poll.h>
 #include <linux/sound.h>
 #include <linux/soundcard.h>
+#include <linux/proc_fs.h>
 
 #include <asm/mach/arch.h>
 #include <asm/hardware.h>
@@ -105,7 +106,7 @@
 #define AUDIO_DATA	0x00
 
 
-enum { CORGI_HP_AUDIO=0, CORGI_HP_BUZZER, CORGI_HP_SOUNDER, CORGI_HP_HP, CORGI_HP_BOTH, CORGI_HP_MIC, CORGI_HP_HEADSET};
+enum { CORGI_HP_AUDIO=0, CORGI_HP_BUZZER=1, CORGI_HP_SOUNDER=2, CORGI_HP_HP=3, CORGI_HP_BOTH=4, CORGI_HP_MIC=5, CORGI_HP_HEADSET=6};
 
 #define AUDIO_BUFFER_SETUP_NOCLEAR	1
 //#undef AUDIO_BUFFER_SETUP_NOCLEAR
@@ -132,6 +133,8 @@
 static int isPXAI2SReady = 0;
 static int isChkHPstatus = 0;
 int sharp_HPstatus = HPJACK_STATE_UNDETECT;
+int sharp_HPmanualOverride = 0;
+int corgi_ManualOverrideStatus = HPJACK_STATE_NONE;
 
 static int corgi_intmode = 0;
 static int corgi_intmode_speed = 0;
@@ -161,7 +164,12 @@
 static int CorgiSetFreq(int);
 static int mixer_ioctl( struct inode *, struct file *,unsigned int, unsigned long);
 static void corgi_hp_mode(int mode);
+static int corgi_setstatus(int HPstatus);
 static void corgi_intmode_mix(unsigned char *,int);
+static void updateBass();
+static void updateTreble();
+static void update3D();
+static void updateR5();
 #ifdef CONFIG_PM
 static int CorgiPMCallBack(struct pm_dev *,pm_request_t, void *);
 #endif
@@ -236,8 +244,19 @@
   int gain_right;
 
   int bass;		/* tone (not support) */
+  int bass_cutoff_high;
+  int bass_boost;
+  
   int treble;
-
+  int treble_cutoff_low;
+  
+  int s3d_upper_cutoff_low;
+  int s3d_lower_cutoff_high;
+  int s3d_depth;
+  int s3d_enabled;
+  
+  int dac_6db_attenuation;
+  
   /* device independ */
   int gain_shift;	/* input gain shift */
   int gain;		/* input gain */
@@ -2078,7 +2097,7 @@
     return;
   }
 
-  if( sharp_HPstatus < 0 ){ // get current status
+  if( sharp_HPstatus == HPJACK_STATE_UNDETECT ){ // get current status
     if (GPLR(GPIO_HP_IN) & GPIO_bit(GPIO_HP_IN)) {
       if (!(GPLR(GPIO_AK_INT) & GPIO_bit(GPIO_AK_INT))) {
 	sharp_HPstatus = HPJACK_STATE_REMOCON;
@@ -2136,6 +2155,31 @@
 	CorgiUpdateVolume();
 }
 
+static int corgi_setstatus(int HPstatus)
+{
+	audio_state_t  *audio_state = &pxa_audio_state;
+
+	if ( sharp_HPmanualOverride ) {
+		sharp_HPstatus = corgi_ManualOverrideStatus;
+	} else {		
+		sharp_HPstatus = HPstatus;
+	}
+	
+	// sound is not playing , so HP/SP be disabled.
+	if ( !audio_state->wr_ref && !audio_state->rd_ref ) return 0;
+
+	if( audio_state->rd_ref ){
+		// mic mode
+		corgi_hp_mode((audio_state->wr_ref)?
+				  CORGI_HP_HEADSET:CORGI_HP_MIC);
+	}else{
+		corgi_hp_mode((sharp_HPstatus == HPJACK_STATE_NONE)?
+				  CORGI_HP_SOUNDER : CORGI_HP_HP);
+	}
+	
+	return 1;
+}
+
 // for judge remocon
 #define REMOTE_CONTROL_PHONE	8
 int get_remocon_raw(void);
@@ -2219,22 +2263,13 @@
 	  break;
 	}
 	printk("new hp status=%d\n",sharp_HPstatus);
-
-	// sound is not playing , so HP/SP be disabled.
-	if ( !audio_state->wr_ref && !audio_state->rd_ref ) continue;
-
-	if( audio_state->rd_ref ){
-		// mic mode
-		corgi_hp_mode((audio_state->wr_ref)?
-				  CORGI_HP_HEADSET:CORGI_HP_MIC);
-	}else{
-		corgi_hp_mode((sharp_HPstatus == HPJACK_STATE_NONE)?
-				  CORGI_HP_SOUNDER : CORGI_HP_HP);
-	}
+	if ( !corgi_setstatus(sharp_HPstatus) ) 
+		continue;
+	
+	// the continue above is important, in case we add something here...
   }
 }
 
-
 static void corgi_init_thread(void)
 {
   SOUND_SETTINGS settings;
@@ -2963,7 +2998,20 @@
   sound.gain_left = 40;
   sound.gain_right = 40;
 
-
+  sound.bass_boost = 0;
+  sound.bass_cutoff_high = 0;
+  sound.bass = 0;
+  
+  sound.treble_cutoff_low = 0;
+  sound.treble = 0;
+  
+  sound.s3d_upper_cutoff_low = 0;
+  sound.s3d_lower_cutoff_high = 0;
+  sound.s3d_depth = 0;
+  sound.s3d_enabled = 0;
+  
+  sound.dac_6db_attenuation = 0;
+  
   // Change Format
   (*sound.mach.setFormat)(sound.format);
 
@@ -3082,6 +3130,347 @@
 }
 #endif
 
+static ssize_t write_integer_param(const char *buf, size_t nbytes, int *dst, int lower_limit, int upper_limit, void (*callback)(void))
+{
+	int param = -1;
+	sscanf(buf, "%d", &param);
+	
+	if (param != -1) {
+		*dst = (param > upper_limit ? upper_limit : (param < lower_limit ? lower_limit : param));
+		if (callback)
+			(*callback)();
+	}
+	
+	return nbytes;
+}
+
+static ssize_t read_integer_param(struct file *file, char *buf, size_t nbytes, loff_t *ppos, int value)
+{
+	char outputbuf[16];
+	int count;
+	
+	if (*ppos > 0) /* Assume reading completed in previous read*/
+		return 0;
+	
+	count = sprintf(outputbuf, "%d\n", value);
+	count++;
+	*ppos += count;
+	
+	if (count > nbytes)/* Assume output can be read at one time */
+		return -EINVAL;
+	
+	if (copy_to_user(buf, outputbuf, count + 1))
+		return -EFAULT;
+	
+	return count;
+}
+
+static ssize_t headphone_autodetect_read_params(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
+{
+	return read_integer_param(file, buf, nbytes, ppos, (sharp_HPmanualOverride == 1 ? 0 : 1));
+}
+
+static ssize_t headphone_autodetect_write_params(struct file *file, const char *buf, size_t nbytes, loff_t *ppos)
+{
+	unsigned int param = -1;
+	sscanf(buf, "%d", &param);
+	
+	if (param != -1) {
+		sharp_HPmanualOverride = (param == 0 ? 1 : 0);
+
+		if ( sharp_HPmanualOverride ) {
+			corgi_setstatus(corgi_ManualOverrideStatus);
+		} else {
+			// reset state, so it will be detected next time 
+			// we call corgi_hp_mode with CORGI_HP_AUDIO
+			sharp_HPstatus = HPJACK_STATE_UNDETECT;
+			corgi_hp_mode(CORGI_HP_AUDIO);
+		}	
+	}
+	
+	return nbytes;
+}
+
+static struct file_operations proc_headphone_autodetect_params_operations = {
+	read: headphone_autodetect_read_params,
+	write: headphone_autodetect_write_params
+};
+
+static ssize_t headphone_state_read_params(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
+{
+	return read_integer_param(file, buf, nbytes, ppos, (sharp_HPmanualOverride ? corgi_ManualOverrideStatus: sharp_HPstatus));
+}
+
+static ssize_t headphone_state_write_params(struct file *file, const char *buf, size_t nbytes, loff_t *ppos)
+{
+	unsigned int param = -1;
+	sscanf(buf, "%u", &param);
+	
+	if (param != -1) {
+		corgi_ManualOverrideStatus = (param ? 1 : 0);
+
+		if (sharp_HPmanualOverride)
+			corgi_setstatus(corgi_ManualOverrideStatus);
+	}
+	
+	return nbytes;
+}
+
+static struct file_operations proc_headphone_state_params_operations = {
+	read: headphone_state_read_params,
+	write: headphone_state_write_params
+};
+
+/* Bass */
+
+static void updateBass()
+{
+	unsigned short bassRegContent = 0;
+	bassRegContent = (sound.bass_boost & 0x1) << 7 | (sound.bass_cutoff_high & 0x1) << 6 | ((15 - sound.bass) & 0xF);
+	wm8750_set_reg_directly(WM8750_BassCtl_ADR, bassRegContent);
+}
+
+static ssize_t adaptive_bass_boost_read_params(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
+{
+	return read_integer_param(file, buf, nbytes, ppos, sound.bass_boost);
+}
+
+static ssize_t adaptive_bass_boost_write_params(struct file *file, const char *buf, size_t nbytes, loff_t *ppos)
+{
+	return write_integer_param(buf, nbytes, &sound.bass_boost, 0, 1, &updateBass);
+}
+
+static struct file_operations proc_pde_adaptive_bass_boost_params_operations = {
+	read: adaptive_bass_boost_read_params,
+	write: adaptive_bass_boost_write_params		
+};
+
+static ssize_t bass_cutoff_high_read_params(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
+{
+	return read_integer_param(file, buf, nbytes, ppos, sound.bass_cutoff_high);
+}
+
+static ssize_t bass_cutoff_high_write_params(struct file *file, const char *buf, size_t nbytes, loff_t *ppos)
+{
+	return write_integer_param(buf, nbytes, &sound.bass_cutoff_high, 0, 1, &updateBass);
+}
+
+static struct file_operations proc_pde_bass_cutoff_high_params_operations = {
+	read: bass_cutoff_high_read_params,
+	write: bass_cutoff_high_write_params		
+};
+
+static ssize_t bass_intensity_read_params(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
+{
+	return read_integer_param(file, buf, nbytes, ppos, sound.bass);
+}
+
+static ssize_t bass_intensity_write_params(struct file *file, const char *buf, size_t nbytes, loff_t *ppos)
+{
+	return write_integer_param(buf, nbytes, &sound.bass, 0, 15, &updateBass);
+}
+
+static struct file_operations proc_pde_bass_intensity_params_operations = {
+	read: bass_intensity_read_params,
+	write: bass_intensity_write_params		
+};
+
+/* Treble */
+
+static void updateTreble()
+{
+	unsigned short trebleRegContent = 0;
+	trebleRegContent = (sound.treble_cutoff_low & 0x1) << 6 | ((15 - sound.treble) & 0xF);
+	wm8750_set_reg_directly(WM8750_TrebleCtl_ADR, trebleRegContent);
+}
+
+static ssize_t treble_cutoff_low_read_params(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
+{
+	return read_integer_param(file, buf, nbytes, ppos, sound.treble_cutoff_low);
+}
+
+static ssize_t treble_cutoff_low_write_params(struct file *file, const char *buf, size_t nbytes, loff_t *ppos)
+{
+	return write_integer_param(buf, nbytes, &sound.treble_cutoff_low, 0, 1, &updateTreble);
+}
+
+static struct file_operations proc_pde_treble_cutoff_low_params_operations = {
+	read: treble_cutoff_low_read_params,
+	write: treble_cutoff_low_write_params		
+};
+
+static ssize_t treble_intensity_read_params(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
+{
+	return read_integer_param(file, buf, nbytes, ppos, sound.treble);
+}
+
+static ssize_t treble_intensity_write_params(struct file *file, const char *buf, size_t nbytes, loff_t *ppos)
+{
+	return write_integer_param(buf, nbytes, &sound.treble, 0, 15, &updateTreble);
+}
+
+static struct file_operations proc_pde_treble_intensity_params_operations = {
+	read: treble_intensity_read_params,
+	write: treble_intensity_write_params		
+};
+
+/* 3D stereo enhancement */
+
+static void update3D()
+{
+	unsigned short s3dRegContent = 0;
+	s3dRegContent = 0x80 | // MODE3D = 1 -> selected for playback
+					 (sound.s3d_upper_cutoff_low & 0x1) << 6 | 
+	 				 (sound.s3d_lower_cutoff_high & 0x1) << 5 |
+					 (sound.s3d_depth & 0xF) << 1 |
+					 (sound.s3d_enabled & 0x1);
+	wm8750_set_reg_directly(WM8750_3DCtl_ADR, s3dRegContent);
+}
+
+static ssize_t s3denh_upper_cutoff_low_read_params(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
+{
+	return read_integer_param(file, buf, nbytes, ppos, sound.s3d_upper_cutoff_low);
+}
+
+static ssize_t s3denh_upper_cutoff_low_write_params(struct file *file, const char *buf, size_t nbytes, loff_t *ppos)
+{
+	return write_integer_param(buf, nbytes, &sound.s3d_upper_cutoff_low, 0, 1, &update3D);
+}
+
+static struct file_operations proc_pde_s3denh_upper_cutoff_low_params_operations = {
+	read: s3denh_upper_cutoff_low_read_params,
+	write: s3denh_upper_cutoff_low_write_params		
+};
+
+static ssize_t s3denh_lower_cutoff_high_read_params(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
+{
+	return read_integer_param(file, buf, nbytes, ppos, sound.s3d_lower_cutoff_high);
+}
+
+static ssize_t s3denh_lower_cutoff_high_write_params(struct file *file, const char *buf, size_t nbytes, loff_t *ppos)
+{
+	return write_integer_param(buf, nbytes, &sound.s3d_lower_cutoff_high, 0, 1, &update3D);
+}
+
+static struct file_operations proc_pde_s3denh_lower_cutoff_high_params_operations = {
+	read: s3denh_lower_cutoff_high_read_params,
+	write: s3denh_lower_cutoff_high_write_params		
+};
+
+static ssize_t s3denh_depth_read_params(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
+{
+	return read_integer_param(file, buf, nbytes, ppos, sound.s3d_depth);
+}
+
+static ssize_t s3denh_depth_write_params(struct file *file, const char *buf, size_t nbytes, loff_t *ppos)
+{
+	return write_integer_param(buf, nbytes, &sound.s3d_depth, 0, 15, &update3D);
+}
+
+static struct file_operations proc_pde_s3denh_depth_params_operations = {
+	read: s3denh_depth_read_params,
+	write: s3denh_depth_write_params		
+};
+
+static ssize_t s3denh_enabled_read_params(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
+{
+	return read_integer_param(file, buf, nbytes, ppos, sound.s3d_enabled);
+}
+
+static ssize_t s3denh_enabled_write_params(struct file *file, const char *buf, size_t nbytes, loff_t *ppos)
+{
+	return write_integer_param(buf, nbytes, &sound.s3d_enabled, 0, 1, &update3D);
+}
+
+static struct file_operations proc_pde_s3denh_enabled_params_operations = {
+	read: s3denh_enabled_read_params,
+	write: s3denh_enabled_write_params		
+};
+
+
+static void updateR5()
+{
+	wm8750_set_6db_attenuation(sound.dac_6db_attenuation);
+}
+
+static ssize_t dac_6db_attenuation_read_params(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
+{
+	return read_integer_param(file, buf, nbytes, ppos, sound.dac_6db_attenuation);
+}
+
+static ssize_t dac_6db_attenuation_write_params(struct file *file, const char *buf, size_t nbytes, loff_t *ppos)
+{
+	return write_integer_param(buf, nbytes, &sound.dac_6db_attenuation, 0, 1, &updateR5);
+}
+
+static struct file_operations proc_pde_dac_6db_attenuation_params_operations = {
+	read: dac_6db_attenuation_read_params,
+	write: dac_6db_attenuation_write_params		
+};
+
+
+static struct proc_dir_entry * proc_createassoc(char *filename, struct file_operations *fops)
+{
+	struct proc_dir_entry *result = NULL;
+	result = create_proc_entry(filename, 0, NULL);
+	if (result)
+		result->proc_fops = fops;
+	
+	return result;
+}
+
+static int proc_init()
+{
+	struct proc_dir_entry *pde_driver_wm8750 = proc_mkdir("driver/wm8750", NULL);
+	if (pde_driver_wm8750 == NULL) {
+		printk(KERN_ERR "proc: can't create /proc/driver/wm8750\n");
+		return -ENOMEM;
+	}
+	
+	/* Headphone settings */
+	
+	proc_createassoc("driver/wm8750/headphone_autodetect", &proc_headphone_autodetect_params_operations);
+	proc_createassoc("driver/wm8750/headphone_state", &proc_headphone_state_params_operations);
+	
+	/* Bass */
+	
+	proc_createassoc("driver/wm8750/bass_adaptive_boost", &proc_pde_adaptive_bass_boost_params_operations);
+	proc_createassoc("driver/wm8750/bass_cutoff_high", &proc_pde_bass_cutoff_high_params_operations);
+	proc_createassoc("driver/wm8750/bass_intensity", &proc_pde_bass_intensity_params_operations);
+	
+	/* Treble */
+	
+	proc_createassoc("driver/wm8750/treble_cutoff_low", &proc_pde_treble_cutoff_low_params_operations);
+	proc_createassoc("driver/wm8750/treble_intensity", &proc_pde_treble_intensity_params_operations);
+	
+	/* 3D stereo enhancement */
+	
+	proc_createassoc("driver/wm8750/s3denh_upper_cutoff_low", &proc_pde_s3denh_upper_cutoff_low_params_operations);
+	proc_createassoc("driver/wm8750/s3denh_lower_cutoff_high", &proc_pde_s3denh_lower_cutoff_high_params_operations);
+	proc_createassoc("driver/wm8750/s3denh_depth", &proc_pde_s3denh_depth_params_operations);
+	proc_createassoc("driver/wm8750/s3denh_enabled", &proc_pde_s3denh_enabled_params_operations);
+	
+	/* Misc */
+	
+	proc_createassoc("driver/wm8750/dac_6db_attenuation", &proc_pde_dac_6db_attenuation_params_operations);
+}
+
+void proc_cleanup()
+{
+	remove_proc_entry("driver/wm8750/dac_6db_attenuation", NULL);
+	remove_proc_entry("driver/wm8750/s3denh_enabled", NULL);
+	remove_proc_entry("driver/wm8750/s3denh_depth", NULL);
+	remove_proc_entry("driver/wm8750/s3denh_lower_cutoff_high", NULL);
+	remove_proc_entry("driver/wm8750/s3denh_upper_cutoff_low", NULL);
+	remove_proc_entry("driver/wm8750/treble_intensity", NULL);
+	remove_proc_entry("driver/wm8750/treble_cutoff_low", NULL);
+	remove_proc_entry("driver/wm8750/bass_intensity", NULL);
+	remove_proc_entry("driver/wm8750/bass_cutoff_high", NULL);
+	remove_proc_entry("driver/wm8750/bass_adaptive_boost", NULL);
+	remove_proc_entry("driver/wm8750/headphone_state", NULL);
+	remove_proc_entry("driver/wm8750/headphone_autodetect", NULL);
+	remove_proc_entry("driver/wm8750", NULL);	
+}
 
 /*** Config & Setup *********************************************************/
 static int __init pxa_i2s_init(void)
@@ -3100,7 +3489,9 @@
 
 	/* Set up /dev/mixer. */
 	mixer_init();
-
+	
+	/* Set up /proc/driver/sound/... */
+	proc_init();
 
 #ifdef CONFIG_PM
 	pxa_sound_pm_dev = pm_register(PM_SYS_DEV, 0, CorgiPMCallBack);
@@ -3111,6 +3502,8 @@
 
 static void __exit pxa_i2s_exit(void)
 {
+  proc_cleanup();
+	
   // FIXME : release buffer
 
   if ( pxa_audio_state.dev_dsp >= 0 ) 
Index: linux/drivers/sound/spitz_wm8750.c
===================================================================
--- linux/drivers/sound/spitz_wm8750.c	(revision 41)
+++ linux/drivers/sound/spitz_wm8750.c	(revision 42)
@@ -66,6 +66,7 @@
   int		used;		//used: open(1) close(0)
   int		mode;		//Sound mode
   int		agc;		//Agc: on(1) off(0)
+  int	 	att6db;		//6db attenuation: on(1) off(0)
 } wm8750_stat_t;
 
 static wm8750_stat_t wm8750_stat;
@@ -245,6 +246,9 @@
 	wm8750_i2c_write(WM8750_PwrMgmt1_ADR, 
 				( SET_VMID(VREF_STOP) | EN_VREF ));
 	mdelay(1);
+	wm8750_i2c_write(WM8750_3DCtl_ADR, 0x80);  // set 3D enhance to playback mode, not enabled yet.
+	WM8750Regs[WM8750_3DCtl_ADR] = 0x80;
+	mdelay(1);
 	wm8750_i2c_write(WM8750_PwrMgmt2_ADR, 
 		( EN_DACL | EN_DACR ));
 	wm8750_i2c_write(WM8750_PwrMgmt1_ADR, 
@@ -475,6 +479,12 @@
 
 	wm8750_set_linein_vol_shadowreg(WM8750_LeftInputVolume_ADR, setting->input.left);
 	wm8750_set_linein_vol_shadowreg(WM8750_RightInputVolume_ADR, setting->input.right);
+	
+	if (wm8750_stat.att6db)	
+		WM8750Regs[WM8750_AdcDacCtl_ADR] |= DPC_DAC_6DBATT_ON;
+	else
+		WM8750Regs[WM8750_AdcDacCtl_ADR] &= DPC_DAC_6DBATT_MASK;
+
 	return ret;
 }
 
@@ -769,6 +779,24 @@
 	return err;
 }
 
+int wm8750_set_reg_directly(unsigned char adr, unsigned short value)
+{
+	int err;
+	
+	err = wm8750_i2c_open();
+	if ( err ) {
+		WM8750_DBGPRINT(DBG_ALWAYS, "can not open i2c device\n");
+		return err;
+	}
+
+	WM8750Regs[adr] = value;
+	wm8750_i2c_write(adr, value);
+	
+	wm8750_i2c_close();
+
+	return err;	
+}
+
 int wm8750_set_freq(int freq)
 {
 	return 0;
@@ -774,10 +802,22 @@
 	return 0;
 }
 
+void wm8750_set_6db_attenuation(int set_state)
+{
+	wm8750_stat.att6db = !!set_state; 
+		
+	if (set_state)	
+		WM8750Regs[WM8750_AdcDacCtl_ADR] |= DPC_DAC_6DBATT_ON;
+	else
+		WM8750Regs[WM8750_AdcDacCtl_ADR] &= DPC_DAC_6DBATT_MASK;
+
+	wm8750_set_reg_directly(WM8750_AdcDacCtl_ADR, WM8750Regs[WM8750_AdcDacCtl_ADR]);
+}
+
 static void WM8750_set_DAC_MUTE(int set_state)
 {
 	if (set_state){	// MUTE ON
-		WM8750Regs[WM8750_AdcDacCtl_ADR] |= DPC_DAC_MUTE_OFF;
+		WM8750Regs[WM8750_AdcDacCtl_ADR] |= DPC_DAC_MUTE_ON;
 	}else{
 		WM8750Regs[WM8750_AdcDacCtl_ADR] &= DPC_DAC_MUTE_MASK;
 	}
@@ -783,7 +823,6 @@
 	}
 	wm8750_i2c_write(WM8750_AdcDacCtl_ADR,
 					WM8750Regs[WM8750_AdcDacCtl_ADR]);
-	return;
 }
 
 static void WM8750_set_HP_SP(int set_state)
@@ -891,6 +930,8 @@
 	wm8750_i2c_write(WM8750_PwrMgmt1_ADR,WM8750Regs[WM8750_PwrMgmt1_ADR]);
 	wm8750_i2c_write(WM8750_PwrMgmt2_ADR, WM8750Regs[WM8750_PwrMgmt2_ADR]);
 
+	WM8750_set_DAC_MUTE(0);
+	
 	for(i=0;i<WM8750_REG_NUM;i++) {
 		if (((i < 32) && ((1 << i) & WM8750_REG_MASK1)) ||
 			((i >= 32) && ((1 << (i - 32)) & WM8750_REG_MASK2)))
Index: linux/include/asm-arm/arch-pxa/spitz_wm8750.h
===================================================================
--- linux/include/asm-arm/arch-pxa/spitz_wm8750.h	(revision 41)
+++ linux/include/asm-arm/arch-pxa/spitz_wm8750.h	(revision 42)
@@ -125,6 +125,9 @@
 #define NGAT_ON					( 1 )
 
 // Digital Audio path ctrl register
+#define DPC_DAC_6DBATT_ON		( 1U << 7 )
+#define DPC_DAC_6DBATT_OFF		( 0U )
+#define DPC_DAC_6DBATT_MASK	(~ ( 1U << 7 ) )
 #define DPC_DAC_MUTE_ON			( 1U << 3 )
 #define DPC_DAC_MUTE_OFF		( 0U )
 #define DPC_DAC_MUTE_MASK		(~ ( 1U << 3 ) )
@@ -244,6 +247,8 @@
 void wm8750_set_volume_reg(int,unsigned char);
 int wm8750_set_output_volume(int,int);
 int wm8750_set_input_volume(int,int);
+void wm8750_set_6db_attenuation(int);
+int wm8750_set_reg_directly(unsigned char, unsigned short);
 int wm8750_set_mic_gain_boost(int);
 int wm8750_resume(void);
 
