From ddd6804ba90290b66ebff05b99752fcdd75fec45 Mon Sep 17 00:00:00 2001 From: Manish Patel Date: Sun, 11 Jan 2015 18:44:07 +0530 Subject: Fix audio routing issue between speaker and headphone Signed-off-by: Manish Patel --- sound/soc/codecs/vt1603.c | 103 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 91 insertions(+), 12 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/vt1603.c b/sound/soc/codecs/vt1603.c index eaa3d28e..3df20e54 100755 --- a/sound/soc/codecs/vt1603.c +++ b/sound/soc/codecs/vt1603.c @@ -160,43 +160,122 @@ static unsigned int vt1603_hw_read(struct snd_soc_codec *codec, /*----------------------IRQ handle Functions----------------------------*/ +static int vt1603_hp_power_up(struct snd_soc_codec *codec) +{ + u16 reg; + + /* disable mono mixing */ + reg = snd_soc_read(codec, VT1603_R0d); + reg &= ~BIT4; + snd_soc_write(codec, VT1603_R0d, reg); + + /* make sure DAC R channel is enable */ + reg = snd_soc_read(codec, VT1603_R62); + reg |= BIT4; + snd_soc_write(codec, VT1603_R62, reg); + + // set HP power up + reg = snd_soc_read(codec, VT1603_R68); + reg &= ~BIT4; + snd_soc_write(codec, VT1603_R68, reg); + + return 0; +} + +static int vt1603_classd_power_up(struct snd_soc_codec *codec) +{ + u16 reg; + + // set class-d power up + reg = snd_soc_read(codec, VT1603_R25); + reg |= BIT1; + snd_soc_write(codec, VT1603_R25, reg); + + return 0; +} + +static int vt1603_hp_power_off(struct snd_soc_codec *codec) +{ + u16 reg; + + // set HP power off + reg = snd_soc_read(codec, VT1603_R68); + reg |= BIT4; + snd_soc_write(codec, VT1603_R68, reg); + + return 0; +} + +static int vt1603_classd_power_off(struct snd_soc_codec *codec) +{ + u16 reg; + + // set class-d power off + reg = snd_soc_read(codec, VT1603_R25); + reg &= ~BIT1; + snd_soc_write(codec, VT1603_R25, reg); + + return 0; +} +static void vt1603_switch_to_hp(struct snd_soc_codec *codec) +{ + u16 reg; + + vt1603_classd_power_off(codec); + + if (codec->card->rtd->codec_dai->playback_active == 1) + vt1603_hp_power_up(codec); +} + +static void vt1603_switch_to_classd(struct snd_soc_codec *codec) +{ + u16 reg; + + vt1603_hp_power_off(codec); + + if (codec->card->rtd->codec_dai->playback_active == 1) + vt1603_classd_power_up(codec); +} + static void vt1603_set_switch_state(struct snd_soc_codec *codec) { - /* Just report hp state, don't switch hw device, app will handle it. */ - struct vt1603_priv *vt1603 = snd_soc_codec_get_drvdata(codec); unsigned int val = vt1603_hw_read(codec, VT1603_R21); if (vt1603_boardinfo.hp_level) { if (val & BIT1) { - val &= ~BIT1; - snd_soc_write(codec, VT1603_R21, val); if (!vt1603_boardinfo.ignore_hp_event) switch_set_state(&vt1603->hp_switch, 0); - pr_info("<<hp_switch, 1); + val |= BIT1; + snd_soc_write(codec, VT1603_R21, val); pr_info("<<hp_switch, 1); + val &= ~BIT1; + snd_soc_write(codec, VT1603_R21, val); pr_info("<<hp_switch, 0); - pr_info("<<