aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8994_herring.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8994_herring.c')
-rwxr-xr-xsound/soc/codecs/wm8994_herring.c3988
1 files changed, 3988 insertions, 0 deletions
diff --git a/sound/soc/codecs/wm8994_herring.c b/sound/soc/codecs/wm8994_herring.c
new file mode 100755
index 0000000..28e2320
--- /dev/null
+++ b/sound/soc/codecs/wm8994_herring.c
@@ -0,0 +1,3988 @@
+/*
+ * wm8994_crespo.c -- WM8994 ALSA Soc Audio driver related Aries
+ *
+ * Copyright (C) 2010 Samsung Electronics.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <plat/gpio-cfg.h>
+#include <plat/map-base.h>
+#include <mach/regs-clock.h>
+#include "wm8994_samsung.h"
+#include "../../../arch/arm/mach-s5pv210/herring.h"
+#ifdef CONFIG_SND_VOODOO
+#include "wm8994_voodoo.h"
+#endif
+
+/*
+ * Debug Feature
+ */
+#define SUBJECT "wm8994_crespo.c"
+
+/*
+ * Definitions of tunning volumes for wm8994
+ */
+
+struct gain_info_t cdma_playback_gain_table[PLAYBACK_GAIN_NUM] = {
+ { /* COMMON */
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_DAC1_LEFT_VOLUME, /* 610h */
+ .mask = WM8994_DAC1L_VOL_MASK,
+ .gain = WM8994_DAC1_VU | 0xC0
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_DAC1_RIGHT_VOLUME, /* 611h */
+ .mask = WM8994_DAC1R_VOL_MASK,
+ .gain = WM8994_DAC1_VU | 0xC0
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_AIF1_DAC1_LEFT_VOLUME, /* 402h */
+ .mask = WM8994_AIF1DAC1L_VOL_MASK,
+ .gain = WM8994_AIF1DAC1_VU | 0xC0
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_AIF1_DAC1_RIGHT_VOLUME, /* 403h */
+ .mask = WM8994_AIF1DAC1R_VOL_MASK,
+ .gain = WM8994_AIF1DAC1_VU | 0xC0
+ }, { /* RCV */
+ .mode = PLAYBACK_RCV,
+ .reg = WM8994_OUTPUT_MIXER_5, /* 31h */
+ .mask = WM8994_DACL_MIXOUTL_VOL_MASK,
+ .gain = 0x0 << WM8994_DACL_MIXOUTL_VOL_SHIFT
+ }, {
+ .mode = PLAYBACK_RCV,
+ .reg = WM8994_OUTPUT_MIXER_6, /* 32h */
+ .mask = WM8994_DACR_MIXOUTR_VOL_MASK,
+ .gain = 0x0 << WM8994_DACR_MIXOUTR_VOL_SHIFT
+ }, {
+ .mode = PLAYBACK_RCV,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x3D
+ }, {
+ .mode = PLAYBACK_RCV,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x3D
+ }, {
+ .mode = PLAYBACK_RCV,
+ .reg = WM8994_HPOUT2_VOLUME, /* 1Fh */
+ .mask = WM8994_HPOUT2_VOL_MASK,
+ .gain = 0x0 << WM8994_HPOUT2_VOL_SHIFT
+ }, { /* SPK */
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_SPKMIXL_ATTENUATION, /* 22h */
+ .mask = WM8994_SPKMIXL_VOL_MASK,
+ .gain = 0x0
+ }, {
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_SPKMIXR_ATTENUATION, /* 23h */
+ .mask = WM8994_SPKMIXR_VOL_MASK,
+ .gain = 0x0
+ }, {
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_SPEAKER_VOLUME_LEFT, /* 26h */
+ .mask = WM8994_SPKOUTL_VOL_MASK,
+ .gain = WM8994_SPKOUT_VU | 0x3E /* +5dB */
+ }, {
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_SPEAKER_VOLUME_RIGHT, /* 27h */
+ .mask = WM8994_SPKOUTR_VOL_MASK,
+ .gain = 0
+ }, {
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_CLASSD, /* 25h */
+ .mask = WM8994_SPKOUTL_BOOST_MASK,
+ .gain = 0x05 << WM8994_SPKOUTL_BOOST_SHIFT /* +7.5dB */
+ }, {
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_AIF1_DAC1_LEFT_VOLUME, /* 402h */
+ .mask = WM8994_AIF1DAC1L_VOL_MASK,
+ .gain = WM8994_AIF1DAC1_VU | 0xB8 /* -2.625dB */
+ }, {
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_AIF1_DAC1_RIGHT_VOLUME, /* 403h */
+ .mask = WM8994_AIF1DAC1R_VOL_MASK,
+ .gain = WM8994_AIF1DAC1_VU | 0xB8 /* -2.625dB */
+ }, { /* HP */
+ .mode = PLAYBACK_HP,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x31 /* -8dB */
+ }, {
+ .mode = PLAYBACK_HP,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x31 /* -8dB */
+ }, {
+ .mode = PLAYBACK_HP,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = PLAYBACK_HP,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, { /* SPK_HP */
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_SPKMIXL_ATTENUATION, /* 22h */
+ .mask = WM8994_SPKMIXL_VOL_MASK,
+ .gain = 0x0
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_SPKMIXR_ATTENUATION, /* 23h */
+ .mask = WM8994_SPKMIXR_VOL_MASK,
+ .gain = 0x0
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_SPEAKER_VOLUME_LEFT, /* 26h */
+ .mask = WM8994_SPKOUTL_VOL_MASK,
+ .gain = WM8994_SPKOUT_VU | 0x3E
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_SPEAKER_VOLUME_RIGHT, /* 27h */
+ .mask = WM8994_SPKOUTR_VOL_MASK,
+ .gain = 0x0
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_CLASSD, /* 25h */
+ .mask = WM8994_SPKOUTL_BOOST_MASK,
+ .gain = 0x5 << WM8994_SPKOUTL_BOOST_SHIFT
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x1E
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x1E
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, { /* RING_SPK */
+ .mode = PLAYBACK_RING_SPK,
+ .reg = WM8994_SPEAKER_VOLUME_LEFT, /* 26h */
+ .mask = WM8994_SPKOUTL_VOL_MASK,
+ .gain = WM8994_SPKOUT_VU | 0x3E
+ }, {
+ .mode = PLAYBACK_RING_SPK,
+ .reg = WM8994_CLASSD, /* 25h */
+ .mask = WM8994_SPKOUTL_BOOST_MASK,
+ .gain = 0x5 << WM8994_SPKOUTL_BOOST_SHIFT
+ }, { /* RING_HP */
+ .mode = PLAYBACK_RING_HP,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x34
+ }, {
+ .mode = PLAYBACK_RING_HP,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x34
+ }, {
+ .mode = PLAYBACK_RING_HP,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = PLAYBACK_RING_HP,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, { /* RING_SPK_HP */
+ .mode = PLAYBACK_RING_SPK_HP,
+ .reg = WM8994_SPEAKER_VOLUME_LEFT, /* 26h */
+ .mask = WM8994_SPKOUTL_VOL_MASK,
+ .gain = WM8994_SPKOUT_VU | 0x3E
+ }, {
+ .mode = PLAYBACK_RING_SPK_HP,
+ .reg = WM8994_CLASSD, /* 25h */
+ .mask = WM8994_SPKOUTL_BOOST_MASK,
+ .gain = 0x5 << WM8994_SPKOUTL_BOOST_SHIFT
+ }, {
+ .mode = PLAYBACK_RING_SPK_HP,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x1E
+ }, {
+ .mode = PLAYBACK_RING_SPK_HP,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x1E
+ }, { /* HP_NO_MIC */
+ .mode = PLAYBACK_HP_NO_MIC,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x36 /* -3dB */
+ }, {
+ .mode = PLAYBACK_HP_NO_MIC,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x36 /* -3dB */
+ }, {
+ .mode = PLAYBACK_HP_NO_MIC,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = PLAYBACK_HP_NO_MIC,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ },
+};
+
+struct gain_info_t cdma_voicecall_gain_table[VOICECALL_GAIN_NUM] = {
+ { /* COMMON */
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_DAC1_LEFT_VOLUME, /* 610h */
+ .mask = WM8994_DAC1L_VOL_MASK,
+ .gain = WM8994_DAC1_VU | 0xC0 /* 0dB */
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_DAC1_RIGHT_VOLUME, /* 611h */
+ .mask = WM8994_DAC1R_VOL_MASK,
+ .gain = WM8994_DAC1_VU | 0xC0 /* 0dB */
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_AIF1_DAC1_LEFT_VOLUME, /* 402h */
+ .mask = WM8994_AIF1DAC1L_VOL_MASK,
+ .gain = WM8994_AIF1DAC1_VU | 0xC0 /* 0dB */
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_AIF1_DAC1_RIGHT_VOLUME, /* 403h */
+ .mask = WM8994_AIF1DAC1R_VOL_MASK,
+ .gain = WM8994_AIF1DAC1_VU | 0xC0 /* 0dB */
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_DAC2_LEFT_VOLUME, /* 612h */
+ .mask = WM8994_DAC2L_VOL_MASK,
+ .gain = WM8994_DAC2_VU | 0xC0 /* 0dB */
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_DAC2_RIGHT_VOLUME, /* 613h */
+ .mask = WM8994_DAC2R_VOL_MASK,
+ .gain = WM8994_DAC2_VU | 0xC0 /* 0dB */
+ }, { /* RCV */
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x0C /* +15dB */
+ }, {
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_INPUT_MIXER_3, /* 29h */
+ .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK,
+ .gain = 0x10 /* +30dB */
+ }, {
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_OUTPUT_MIXER_5, /* 31h */
+ .mask = WM8994_DACL_MIXOUTL_VOL_MASK,
+ .gain = 0x0 << WM8994_DACL_MIXOUTL_VOL_SHIFT
+ }, {
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_OUTPUT_MIXER_6, /* 32h */
+ .mask = WM8994_DACR_MIXOUTR_VOL_MASK,
+ .gain = 0x0 << WM8994_DACR_MIXOUTR_VOL_SHIFT
+ }, {
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x3F
+ }, {
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x3F
+ }, {
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_HPOUT2_VOLUME, /* 1Fh */
+ .mask = WM8994_HPOUT2_VOL_MASK,
+ .gain = 0x0 << WM8994_HPOUT2_VOL_SHIFT
+ }, { /* SPK */
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_INPUT_MIXER_3, /* 29h */
+ .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK,
+ .gain = 0x10 /* Mic +7.5dB */
+ }, {
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x12 /* Mic +30dB */
+ }, {
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_SPKMIXL_ATTENUATION, /* 22h */
+ .mask = WM8994_SPKMIXL_VOL_MASK,
+ .gain = 0x0 /* Speaker +0dB */
+ }, {
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_SPKMIXR_ATTENUATION, /* 23h */
+ .mask = WM8994_SPKMIXR_VOL_MASK,
+ .gain = 0x0 /* Speaker +0dB */
+ }, {
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_SPEAKER_VOLUME_LEFT, /* 26h */
+ .mask = WM8994_SPKOUTL_VOL_MASK,
+ .gain = WM8994_SPKOUT_VU | 0x3F /* Left Speaker +3dB */
+ }, {
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_SPEAKER_VOLUME_RIGHT, /* 27h */
+ .mask = WM8994_SPKOUTR_VOL_MASK, /* Right Speaker -57dB */
+ .gain = 0x0
+ }, {
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_CLASSD, /* 25h */
+ .mask = WM8994_SPKOUTL_BOOST_MASK,
+ .gain = 0x7 << WM8994_SPKOUTL_BOOST_SHIFT /* Left spaker +12dB */
+ }, { /* HP */
+ .mode = VOICECALL_HP,
+ .reg = WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, /* 1Ah */
+ .mask = WM8994_IN1R_VOL_MASK,
+ .gain = WM8994_IN1R_VU | 0x1D
+ }, {
+ .mode = VOICECALL_HP,
+ .reg = WM8994_INPUT_MIXER_4, /* 2Ah */
+ .mask = WM8994_IN1R_MIXINR_VOL_MASK | WM8994_MIXOUTR_MIXINR_VOL_MASK,
+ .gain = 0x0
+ }, {
+ .mode = VOICECALL_HP,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = VOICECALL_HP,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = VOICECALL_HP,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x30
+ }, {
+ .mode = VOICECALL_HP,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x30
+ }, { /* HP_NO_MIC */
+ .mode = VOICECALL_HP_NO_MIC,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x12 /* +10.5dB */
+ }, {
+ .mode = VOICECALL_HP_NO_MIC,
+ .reg = WM8994_INPUT_MIXER_3, /* 29h */
+ .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK,
+ .gain = 0x10
+ }, {
+ .mode = VOICECALL_HP_NO_MIC,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = VOICECALL_HP_NO_MIC,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = VOICECALL_HP_NO_MIC,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x30
+ }, {
+ .mode = VOICECALL_HP_NO_MIC,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x30
+ }, { /* TTY_VCO */
+ .mode = VOICECALL_TTY_VCO,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x15 /* +10.5dB */
+ }, {
+ .mode = VOICECALL_TTY_VCO,
+ .reg = WM8994_INPUT_MIXER_3, /* 29h */
+ .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK,
+ .gain = 0x0
+ }, { /* TTY_HCO */
+ .mode = VOICECALL_TTY_HCO,
+ .reg = WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, /* 1Ah */
+ .mask = WM8994_IN1R_VOL_MASK,
+ .gain = WM8994_IN1R_VU | 0x13 /* +12dB */
+ }, {
+ .mode = VOICECALL_TTY_HCO,
+ .reg = WM8994_INPUT_MIXER_4, /* 2Ah */
+ .mask = WM8994_IN1R_MIXINR_VOL_MASK | WM8994_MIXOUTR_MIXINR_VOL_MASK,
+ .gain = 0x0
+ }, { /* TTY_FULL */
+ .mode = VOICECALL_TTY_FULL,
+ .reg = WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, /* 1Ah */
+ .mask = WM8994_IN1R_VOL_MASK,
+ .gain = WM8994_IN1R_VU | 0x13 /* +12dB */
+ }, {
+ .mode = VOICECALL_TTY_FULL,
+ .reg = WM8994_INPUT_MIXER_4, /* 2Ah */
+ .mask = WM8994_IN1R_MIXINR_VOL_MASK | WM8994_MIXOUTR_MIXINR_VOL_MASK,
+ .gain = 0x0
+ },
+};
+
+struct gain_info_t playback_gain_table[PLAYBACK_GAIN_NUM] = {
+ { /* COMMON */
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_DAC1_LEFT_VOLUME, /* 610h */
+ .mask = WM8994_DAC1L_VOL_MASK,
+ .gain = WM8994_DAC1_VU | 0xC0
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_DAC1_RIGHT_VOLUME, /* 611h */
+ .mask = WM8994_DAC1R_VOL_MASK,
+ .gain = WM8994_DAC1_VU | 0xC0
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_AIF1_DAC1_LEFT_VOLUME, /* 402h */
+ .mask = WM8994_AIF1DAC1L_VOL_MASK,
+ .gain = WM8994_AIF1DAC1_VU | 0xC0
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_AIF1_DAC1_RIGHT_VOLUME, /* 403h */
+ .mask = WM8994_AIF1DAC1R_VOL_MASK,
+ .gain = WM8994_AIF1DAC1_VU | 0xC0
+ }, { /* RCV */
+ .mode = PLAYBACK_RCV,
+ .reg = WM8994_OUTPUT_MIXER_5, /* 31h */
+ .mask = WM8994_DACL_MIXOUTL_VOL_MASK,
+ .gain = 0x0 << WM8994_DACL_MIXOUTL_VOL_SHIFT
+ }, {
+ .mode = PLAYBACK_RCV,
+ .reg = WM8994_OUTPUT_MIXER_6, /* 32h */
+ .mask = WM8994_DACR_MIXOUTR_VOL_MASK,
+ .gain = 0x0 << WM8994_DACR_MIXOUTR_VOL_SHIFT
+ }, {
+ .mode = PLAYBACK_RCV,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x3D
+ }, {
+ .mode = PLAYBACK_RCV,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x3D
+ }, {
+ .mode = PLAYBACK_RCV,
+ .reg = WM8994_HPOUT2_VOLUME, /* 1Fh */
+ .mask = WM8994_HPOUT2_VOL_MASK,
+ .gain = 0x0 << WM8994_HPOUT2_VOL_SHIFT
+ }, { /* SPK */
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_SPKMIXL_ATTENUATION, /* 22h */
+ .mask = WM8994_SPKMIXL_VOL_MASK,
+ .gain = 0x0
+ }, {
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_SPKMIXR_ATTENUATION, /* 23h */
+ .mask = WM8994_SPKMIXR_VOL_MASK,
+ .gain = 0x0
+ }, {
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_SPEAKER_VOLUME_LEFT, /* 26h */
+ .mask = WM8994_SPKOUTL_VOL_MASK,
+ .gain = WM8994_SPKOUT_VU | 0x3E /* +5dB */
+ }, {
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_SPEAKER_VOLUME_RIGHT, /* 27h */
+ .mask = WM8994_SPKOUTR_VOL_MASK,
+ .gain = 0
+ }, {
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_CLASSD, /* 25h */
+ .mask = WM8994_SPKOUTL_BOOST_MASK,
+ .gain = 0x05 << WM8994_SPKOUTL_BOOST_SHIFT /* +7.5dB */
+ }, {
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_AIF1_DAC1_LEFT_VOLUME, /* 402h */
+ .mask = WM8994_AIF1DAC1L_VOL_MASK,
+ .gain = WM8994_AIF1DAC1_VU | 0xB8 /* -2.625dB */
+ }, {
+ .mode = PLAYBACK_SPK,
+ .reg = WM8994_AIF1_DAC1_RIGHT_VOLUME, /* 403h */
+ .mask = WM8994_AIF1DAC1R_VOL_MASK,
+ .gain = WM8994_AIF1DAC1_VU | 0xB8 /* -2.625dB */
+ }, { /* HP */
+ .mode = PLAYBACK_HP,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x31 /* -8dB */
+ }, {
+ .mode = PLAYBACK_HP,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x31 /* -8dB */
+ }, {
+ .mode = PLAYBACK_HP,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = PLAYBACK_HP,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, { /* SPK_HP */
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_SPKMIXL_ATTENUATION, /* 22h */
+ .mask = WM8994_SPKMIXL_VOL_MASK,
+ .gain = 0x0
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_SPKMIXR_ATTENUATION, /* 23h */
+ .mask = WM8994_SPKMIXR_VOL_MASK,
+ .gain = 0x0
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_SPEAKER_VOLUME_LEFT, /* 26h */
+ .mask = WM8994_SPKOUTL_VOL_MASK,
+ .gain = WM8994_SPKOUT_VU | 0x3E
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_SPEAKER_VOLUME_RIGHT, /* 27h */
+ .mask = WM8994_SPKOUTR_VOL_MASK,
+ .gain = 0x0
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_CLASSD, /* 25h */
+ .mask = WM8994_SPKOUTL_BOOST_MASK,
+ .gain = 0x5 << WM8994_SPKOUTL_BOOST_SHIFT
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x1E
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x1E
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = PLAYBACK_SPK_HP,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, { /* RING_SPK */
+ .mode = PLAYBACK_RING_SPK,
+ .reg = WM8994_SPEAKER_VOLUME_LEFT, /* 26h */
+ .mask = WM8994_SPKOUTL_VOL_MASK,
+ .gain = WM8994_SPKOUT_VU | 0x3E
+ }, {
+ .mode = PLAYBACK_RING_SPK,
+ .reg = WM8994_CLASSD, /* 25h */
+ .mask = WM8994_SPKOUTL_BOOST_MASK,
+ .gain = 0x5 << WM8994_SPKOUTL_BOOST_SHIFT
+ }, { /* RING_HP */
+ .mode = PLAYBACK_RING_HP,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x34
+ }, {
+ .mode = PLAYBACK_RING_HP,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x34
+ }, {
+ .mode = PLAYBACK_RING_HP,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = PLAYBACK_RING_HP,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, { /* RING_SPK_HP */
+ .mode = PLAYBACK_RING_SPK_HP,
+ .reg = WM8994_SPEAKER_VOLUME_LEFT, /* 26h */
+ .mask = WM8994_SPKOUTL_VOL_MASK,
+ .gain = WM8994_SPKOUT_VU | 0x3E
+ }, {
+ .mode = PLAYBACK_RING_SPK_HP,
+ .reg = WM8994_CLASSD, /* 25h */
+ .mask = WM8994_SPKOUTL_BOOST_MASK,
+ .gain = 0x5 << WM8994_SPKOUTL_BOOST_SHIFT
+ }, {
+ .mode = PLAYBACK_RING_SPK_HP,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x1E
+ }, {
+ .mode = PLAYBACK_RING_SPK_HP,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x1E
+ }, { /* HP_NO_MIC */
+ .mode = PLAYBACK_HP_NO_MIC,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x36 /* -3dB */
+ }, {
+ .mode = PLAYBACK_HP_NO_MIC,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x36 /* -3dB */
+ }, {
+ .mode = PLAYBACK_HP_NO_MIC,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = PLAYBACK_HP_NO_MIC,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ },
+};
+
+struct gain_info_t voicecall_gain_table[VOICECALL_GAIN_NUM] = {
+ { /* COMMON */
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_DAC1_LEFT_VOLUME, /* 610h */
+ .mask = WM8994_DAC1L_VOL_MASK,
+ .gain = WM8994_DAC1_VU | 0xC0 /* 0dB */
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_DAC1_RIGHT_VOLUME, /* 611h */
+ .mask = WM8994_DAC1R_VOL_MASK,
+ .gain = WM8994_DAC1_VU | 0xC0 /* 0dB */
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_AIF1_DAC1_LEFT_VOLUME, /* 402h */
+ .mask = WM8994_AIF1DAC1L_VOL_MASK,
+ .gain = WM8994_AIF1DAC1_VU | 0xC0 /* 0dB */
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_AIF1_DAC1_RIGHT_VOLUME, /* 403h */
+ .mask = WM8994_AIF1DAC1R_VOL_MASK,
+ .gain = WM8994_AIF1DAC1_VU | 0xC0 /* 0dB */
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_DAC2_LEFT_VOLUME, /* 612h */
+ .mask = WM8994_DAC2L_VOL_MASK,
+ .gain = WM8994_DAC2_VU | 0xC0 /* 0dB */
+ }, {
+ .mode = COMMON_SET_BIT,
+ .reg = WM8994_DAC2_RIGHT_VOLUME, /* 613h */
+ .mask = WM8994_DAC2R_VOL_MASK,
+ .gain = WM8994_DAC2_VU | 0xC0 /* 0dB */
+ }, { /* RCV */
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x15 /* +15dB */
+ }, {
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_INPUT_MIXER_3, /* 29h */
+ .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK,
+ .gain = 0x10 /* +30dB */
+ }, {
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_OUTPUT_MIXER_5, /* 31h */
+ .mask = WM8994_DACL_MIXOUTL_VOL_MASK,
+ .gain = 0x0 << WM8994_DACL_MIXOUTL_VOL_SHIFT
+ }, {
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_OUTPUT_MIXER_6, /* 32h */
+ .mask = WM8994_DACR_MIXOUTR_VOL_MASK,
+ .gain = 0x0 << WM8994_DACR_MIXOUTR_VOL_SHIFT
+ }, {
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x3F
+ }, {
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x3F
+ }, {
+ .mode = VOICECALL_RCV,
+ .reg = WM8994_HPOUT2_VOLUME, /* 1Fh */
+ .mask = WM8994_HPOUT2_VOL_MASK,
+ .gain = 0x0 << WM8994_HPOUT2_VOL_SHIFT
+ }, { /* SPK */
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_INPUT_MIXER_3, /* 29h */
+ .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK,
+ .gain = 0x10 /* Mic +7.5dB */
+ }, {
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x12 /* Mic +30dB */
+ }, {
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_SPKMIXL_ATTENUATION, /* 22h */
+ .mask = WM8994_SPKMIXL_VOL_MASK,
+ .gain = 0x0 /* Speaker +0dB */
+ }, {
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_SPKMIXR_ATTENUATION, /* 23h */
+ .mask = WM8994_SPKMIXR_VOL_MASK,
+ .gain = 0x0 /* Speaker +0dB */
+ }, {
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_SPEAKER_VOLUME_LEFT, /* 26h */
+ .mask = WM8994_SPKOUTL_VOL_MASK,
+ .gain = WM8994_SPKOUT_VU | 0x3C /* Left Speaker +3dB */
+ }, {
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_SPEAKER_VOLUME_RIGHT, /* 27h */
+ .mask = WM8994_SPKOUTR_VOL_MASK, /* Right Speaker -57dB */
+ .gain = 0x0
+ }, {
+ .mode = VOICECALL_SPK,
+ .reg = WM8994_CLASSD, /* 25h */
+ .mask = WM8994_SPKOUTL_BOOST_MASK,
+ .gain = 0x7 << WM8994_SPKOUTL_BOOST_SHIFT /* Left spaker +12dB */
+ }, { /* HP */
+ .mode = VOICECALL_HP,
+ .reg = WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, /* 1Ah */
+ .mask = WM8994_IN1R_VOL_MASK,
+ .gain = WM8994_IN1R_VU | 0x1D
+ }, {
+ .mode = VOICECALL_HP,
+ .reg = WM8994_INPUT_MIXER_4, /* 2Ah */
+ .mask = WM8994_IN1R_MIXINR_VOL_MASK | WM8994_MIXOUTR_MIXINR_VOL_MASK,
+ .gain = 0x0
+ }, {
+ .mode = VOICECALL_HP,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = VOICECALL_HP,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = VOICECALL_HP,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x30
+ }, {
+ .mode = VOICECALL_HP,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x30
+ }, { /* HP_NO_MIC */
+ .mode = VOICECALL_HP_NO_MIC,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x12 /* +10.5dB */
+ }, {
+ .mode = VOICECALL_HP_NO_MIC,
+ .reg = WM8994_INPUT_MIXER_3, /* 29h */
+ .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK,
+ .gain = 0x10
+ }, {
+ .mode = VOICECALL_HP_NO_MIC,
+ .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */
+ .mask = WM8994_MIXOUTL_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = VOICECALL_HP_NO_MIC,
+ .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */
+ .mask = WM8994_MIXOUTR_VOL_MASK,
+ .gain = WM8994_MIXOUT_VU | 0x39
+ }, {
+ .mode = VOICECALL_HP_NO_MIC,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x30
+ }, {
+ .mode = VOICECALL_HP_NO_MIC,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x30
+ }, { /* TTY_VCO */
+ .mode = VOICECALL_TTY_VCO,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x15 /* +10.5dB */
+ }, {
+ .mode = VOICECALL_TTY_VCO,
+ .reg = WM8994_INPUT_MIXER_3, /* 29h */
+ .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK,
+ .gain = 0x0
+ }, { /* TTY_HCO */
+ .mode = VOICECALL_TTY_HCO,
+ .reg = WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, /* 1Ah */
+ .mask = WM8994_IN1R_VOL_MASK,
+ .gain = WM8994_IN1R_VU | 0x13 /* +12dB */
+ }, {
+ .mode = VOICECALL_TTY_HCO,
+ .reg = WM8994_INPUT_MIXER_4, /* 2Ah */
+ .mask = WM8994_IN1R_MIXINR_VOL_MASK | WM8994_MIXOUTR_MIXINR_VOL_MASK,
+ .gain = 0x0
+ }, { /* TTY_FULL */
+ .mode = VOICECALL_TTY_FULL,
+ .reg = WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, /* 1Ah */
+ .mask = WM8994_IN1R_VOL_MASK,
+ .gain = WM8994_IN1R_VU | 0x13 /* +12dB */
+ }, {
+ .mode = VOICECALL_TTY_FULL,
+ .reg = WM8994_INPUT_MIXER_4, /* 2Ah */
+ .mask = WM8994_IN1R_MIXINR_VOL_MASK | WM8994_MIXOUTR_MIXINR_VOL_MASK,
+ .gain = 0x0
+ },
+};
+
+struct gain_info_t recording_gain_table[RECORDING_GAIN_NUM] = {
+ { /* MAIN */
+ .mode = RECORDING_MAIN,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x12 /* +10.5dB */
+ }, {
+ .mode = RECORDING_MAIN,
+ .reg = WM8994_INPUT_MIXER_3, /* 29h */
+ .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK,
+ .gain = 0x10 /* +30dB */
+ }, {
+ .mode = RECORDING_MAIN,
+ .reg = WM8994_AIF1_ADC1_LEFT_VOLUME, /* 400h */
+ .mask = WM8994_AIF1ADC1L_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0 /* 0dB */
+ }, {
+ .mode = RECORDING_MAIN,
+ .reg = WM8994_AIF1_ADC1_RIGHT_VOLUME, /* 401h */
+ .mask = WM8994_AIF1ADC1R_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0 /* 0dB */
+ }, { /* HP */
+ .mode = RECORDING_HP,
+ .reg = WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, /* 1Ah */
+ .mask = WM8994_IN1R_VOL_MASK,
+ .gain = WM8994_IN1R_VU | 0x15
+ }, {
+ .mode = RECORDING_HP,
+ .reg = WM8994_INPUT_MIXER_4, /* 2Ah */
+ .mask = WM8994_IN1R_MIXINR_VOL_MASK | WM8994_MIXOUTR_MIXINR_VOL_MASK,
+ .gain = 0x10
+ }, {
+ .mode = RECORDING_HP,
+ .reg = WM8994_AIF1_ADC1_LEFT_VOLUME, /* 400h */
+ .mask = WM8994_AIF1ADC1L_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0
+ }, {
+ .mode = RECORDING_HP,
+ .reg = WM8994_AIF1_ADC1_RIGHT_VOLUME, /* 401h */
+ .mask = WM8994_AIF1ADC1R_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0
+ }, { /* RECOGNITION_MAIN */
+ .mode = RECORDING_REC_MAIN,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x0D /* +3dB */
+ }, {
+ .mode = RECORDING_REC_MAIN,
+ .reg = WM8994_INPUT_MIXER_3, /* 29h */
+ .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK,
+ .gain = 0x10 /* 30dB */
+ }, {
+ .mode = RECORDING_REC_MAIN,
+ .reg = WM8994_AIF1_ADC1_LEFT_VOLUME, /* 400h */
+ .mask = WM8994_AIF1ADC1L_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xc0 /* +0dB */
+ }, {
+ .mode = RECORDING_REC_MAIN,
+ .reg = WM8994_AIF1_ADC1_RIGHT_VOLUME, /* 401h */
+ .mask = WM8994_AIF1ADC1R_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xc0 /* +0dB */
+ }, { /* RECOGNITION_HP */
+ .mode = RECORDING_REC_HP,
+ .reg = WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, /* 1Ah */
+ .mask = WM8994_IN1R_VOL_MASK,
+ .gain = WM8994_IN1R_VU | 0x12 /* +10.5dB */
+ }, {
+ .mode = RECORDING_REC_HP,
+ .reg = WM8994_INPUT_MIXER_4, /* 2Ah */
+ .mask = WM8994_IN1R_MIXINR_VOL_MASK | WM8994_MIXOUTR_MIXINR_VOL_MASK,
+ .gain = 0x10 /* +30dB */
+ }, {
+ .mode = RECORDING_REC_HP,
+ .reg = WM8994_AIF1_ADC1_LEFT_VOLUME, /* 400h */
+ .mask = WM8994_AIF1ADC1L_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0
+ }, {
+ .mode = RECORDING_REC_HP,
+ .reg = WM8994_AIF1_ADC1_RIGHT_VOLUME, /* 401h */
+ .mask = WM8994_AIF1ADC1R_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0
+ }, { /* CAMCORDER_MAIN */
+ .mode = RECORDING_CAM_MAIN,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x17 /* +18dB */
+ }, {
+ .mode = RECORDING_CAM_MAIN,
+ .reg = WM8994_INPUT_MIXER_3, /* 29h */
+ .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK,
+ .gain = 0x10 /* 30dB */
+ }, {
+ .mode = RECORDING_CAM_MAIN,
+ .reg = WM8994_AIF1_ADC1_LEFT_VOLUME, /* 400h */
+ .mask = WM8994_AIF1ADC1L_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0 /* +0dB */
+ }, {
+ .mode = RECORDING_CAM_MAIN,
+ .reg = WM8994_AIF1_ADC1_RIGHT_VOLUME, /* 401h */
+ .mask = WM8994_AIF1ADC1R_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0 /* +0dB */
+ }, { /* CAMCORDER_HP */
+ .mode = RECORDING_CAM_HP,
+ .reg = WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, /* 1Ah */
+ .mask = WM8994_IN1R_VOL_MASK,
+ .gain = WM8994_IN1R_VU | 0x15 /* +15dB */
+ }, {
+ .mode = RECORDING_CAM_HP,
+ .reg = WM8994_INPUT_MIXER_4, /* 2Ah */
+ .mask = WM8994_IN1R_MIXINR_VOL_MASK | WM8994_MIXOUTR_MIXINR_VOL_MASK,
+ .gain = 0x10 /* +30dB */
+ }, {
+ .mode = RECORDING_CAM_HP,
+ .reg = WM8994_AIF1_ADC1_LEFT_VOLUME, /* 400h */
+ .mask = WM8994_AIF1ADC1L_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0
+ }, {
+ .mode = RECORDING_CAM_HP,
+ .reg = WM8994_AIF1_ADC1_RIGHT_VOLUME, /* 401h */
+ .mask = WM8994_AIF1ADC1R_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0
+ }, { /* VOICE COMMUNICATION MAIN */
+ .mode = RECORDING_VC_MAIN,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x12 /* +10.5dB */
+ }, {
+ .mode = RECORDING_VC_MAIN,
+ .reg = WM8994_INPUT_MIXER_3, /* 29h */
+ .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK,
+ .gain = 0x10 /* +30dB */
+ }, {
+ .mode = RECORDING_VC_MAIN,
+ .reg = WM8994_AIF1_ADC1_LEFT_VOLUME, /* 400h */
+ .mask = WM8994_AIF1ADC1L_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0 /* 0dB */
+ }, {
+ .mode = RECORDING_VC_MAIN,
+ .reg = WM8994_AIF1_ADC1_RIGHT_VOLUME, /* 401h */
+ .mask = WM8994_AIF1ADC1R_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0 /* 0dB */
+ }, { /* VOICE COMMUNICATION HP */
+ .mode = RECORDING_VC_HP,
+ .reg = WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, /* 1Ah */
+ .mask = WM8994_IN1R_VOL_MASK,
+ .gain = WM8994_IN1R_VU | 0x15
+ }, {
+ .mode = RECORDING_VC_HP,
+ .reg = WM8994_INPUT_MIXER_4, /* 2Ah */
+ .mask = WM8994_IN1R_MIXINR_VOL_MASK | WM8994_MIXOUTR_MIXINR_VOL_MASK,
+ .gain = 0x10
+ }, {
+ .mode = RECORDING_VC_HP,
+ .reg = WM8994_AIF1_ADC1_LEFT_VOLUME, /* 400h */
+ .mask = WM8994_AIF1ADC1L_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0
+ }, {
+ .mode = RECORDING_VC_HP,
+ .reg = WM8994_AIF1_ADC1_RIGHT_VOLUME, /* 401h */
+ .mask = WM8994_AIF1ADC1R_VOL_MASK,
+ .gain = WM8994_AIF1ADC1_VU | 0xC0
+ }
+};
+
+struct gain_info_t gain_code_table[GAIN_CODE_NUM] = {
+ /* Playback */
+ {/* HP */
+ .mode = PLAYBACK_HP | PLAYBACK_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x31 /* -8dB */
+ }, {
+ .mode = PLAYBACK_HP | PLAYBACK_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x31 /* -8dB */
+ }, {/* HP_NO_MIC */
+ .mode = PLAYBACK_HP_NO_MIC | PLAYBACK_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x31 /* -8dB */
+ }, {
+ .mode = PLAYBACK_HP_NO_MIC | PLAYBACK_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x31 /* -8dB */
+ }, {/* Voicecall RCV */
+ .mode = VOICECALL_RCV | VOICECALL_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x14 /* +13.5dB */
+ }, {/* SPK */
+ .mode = VOICECALL_SPK | VOICECALL_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x0D /* +3dB */
+ }, {
+ .mode = VOICECALL_SPK | VOICECALL_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_SPEAKER_VOLUME_LEFT, /* 26h */
+ .mask = WM8994_SPKOUTL_VOL_MASK,
+ .gain = WM8994_SPKOUT_VU | 0x3A /* +1dB */
+ }, {/* HP */
+ .mode = VOICECALL_HP | VOICECALL_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, /* 1Ah */
+ .mask = WM8994_IN1R_VOL_MASK,
+ .gain = WM8994_IN1R_VU | 0x1D /* +27dB */
+ }, {
+ .mode = VOICECALL_HP | VOICECALL_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x3a /* +1dB */
+ }, {
+ .mode = VOICECALL_HP | VOICECALL_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x3a /* +1dB */
+ }, {/* HP_NO_MIC */
+ .mode = VOICECALL_HP_NO_MIC | VOICECALL_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */
+ .mask = WM8994_IN1L_VOL_MASK,
+ .gain = WM8994_IN1L_VU | 0x12 /* +10.5dB */
+ }, {
+ .mode = VOICECALL_HP_NO_MIC | VOICECALL_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */
+ .mask = WM8994_HPOUT1L_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x3a /* +1dB */
+ }, {
+ .mode = VOICECALL_HP_NO_MIC | VOICECALL_MODE | GAIN_DIVISION_BIT_1,
+ .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */
+ .mask = WM8994_HPOUT1R_VOL_MASK,
+ .gain = WM8994_HPOUT1_VU | 0x3a /* +1dB */
+ },
+};
+
+static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
+{
+ unsigned int reg;
+ int count = 0;
+ unsigned int val, start;
+
+ val = op | WM8994_DCS_ENA_CHAN_0 | WM8994_DCS_ENA_CHAN_1;
+
+ /* Trigger the command */
+ snd_soc_write(codec, WM8994_DC_SERVO_1, val);
+
+ start = jiffies;
+ pr_debug("Waiting for DC servo...\n");
+
+ do {
+ count++;
+ msleep(1);
+ reg = snd_soc_read(codec, WM8994_DC_SERVO_1);
+ pr_debug("DC servo: %x\n", reg);
+ } while (reg & op && count < 400);
+
+ pr_info("DC servo took %dms\n", jiffies_to_msecs(jiffies - start));
+
+ if (reg & op)
+ pr_err("Timed out waiting for DC Servo\n");
+}
+
+/* S5P_SLEEP_CONFIG must be controlled by codec if codec use XUSBTI */
+int wm8994_configure_clock(struct snd_soc_codec *codec, int en)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ if (en) {
+ clk_enable(wm8994->codec_clk);
+ DEBUG_LOG("USBOSC Enabled in Sleep Mode\n");
+ } else {
+ clk_disable(wm8994->codec_clk);
+ DEBUG_LOG("USBOSC disable in Sleep Mode\n");
+ }
+
+ return 0;
+}
+
+void audio_ctrl_mic_bias_gpio(struct wm8994_platform_data *pdata, int enable)
+{
+ DEBUG_LOG("enable = [%d]", enable);
+
+ if (!pdata)
+ pr_err("failed to turn off micbias pin\n");
+ else {
+ if (enable)
+ pdata->set_mic_bias(true);
+ else
+ pdata->set_mic_bias(false);
+ }
+}
+
+static int wm8994_earsel_control(struct wm8994_platform_data *pdata, int en)
+{
+
+ if (!pdata) {
+ pr_err("failed to control wm8994 ear selection\n");
+ return -EINVAL;
+ }
+
+ gpio_set_value(pdata->ear_sel, en);
+
+ return 0;
+
+}
+
+/* Audio Routing routines for the universal board..wm8994 codec*/
+void wm8994_disable_path(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ u16 val;
+ enum audio_path path = wm8994->cur_path;
+
+ DEBUG_LOG("Path = [%d]", path);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_1);
+
+ switch (path) {
+ case RCV:
+ /* Disbale the HPOUT2 */
+ val &= ~(WM8994_HPOUT2_ENA_MASK);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ /* Disable left MIXOUT */
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_1);
+ val &= ~(WM8994_DAC1L_TO_MIXOUTL_MASK);
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, val);
+
+ /* Disable right MIXOUT */
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_2);
+ val &= ~(WM8994_DAC1R_TO_MIXOUTR_MASK);
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, val);
+
+ /* Disable HPOUT Mixer */
+ val = wm8994_read(codec, WM8994_HPOUT2_MIXER);
+ val &= ~(WM8994_MIXOUTLVOL_TO_HPOUT2_MASK |
+ WM8994_MIXOUTRVOL_TO_HPOUT2_MASK);
+ wm8994_write(codec, WM8994_HPOUT2_MIXER, val);
+
+ /* Disable mixout volume control */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_3);
+ val &= ~(WM8994_MIXOUTLVOL_ENA_MASK |
+ WM8994_MIXOUTRVOL_ENA_MASK |
+ WM8994_MIXOUTL_ENA_MASK |
+ WM8994_MIXOUTR_ENA_MASK);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, val);
+ break;
+
+ case SPK:
+ /* Disbale the SPKOUTL */
+ val &= ~(WM8994_SPKOUTL_ENA_MASK);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ /* Disable SPKLVOL */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_3);
+ val &= ~(WM8994_SPKLVOL_ENA_MASK);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, val);
+
+ /* Disable SPKOUT mixer */
+ val = wm8994_read(codec, WM8994_SPKOUT_MIXERS);
+ val &= ~(WM8994_SPKMIXL_TO_SPKOUTL_MASK |
+ WM8994_SPKMIXR_TO_SPKOUTL_MASK |
+ WM8994_SPKMIXR_TO_SPKOUTR_MASK);
+ wm8994_write(codec, WM8994_SPKOUT_MIXERS, val);
+
+ /* Mute Speaker mixer */
+ val = wm8994_read(codec, WM8994_SPEAKER_MIXER);
+ val &= ~(WM8994_DAC1L_TO_SPKMIXL_MASK);
+ wm8994_write(codec, WM8994_SPEAKER_MIXER, val);
+ break;
+
+ case HP:
+ case HP_NO_MIC:
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(0x02C0);
+ val |= 0x02C0;
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, 0x02C0);
+
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(0x02C0);
+ val |= 0x02C0;
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, 0x02C0);
+
+ val = wm8994_read(codec, WM8994_ANALOGUE_HP_1);
+ val &= ~(0x0022);
+ val |= 0x0022;
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x0022);
+
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_1);
+ val &= ~(0x0);
+ val |= 0x0;
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, 0x0);
+
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_2);
+ val &= ~(0x0);
+ val |= 0x0;
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, 0x0);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_5);
+ val &= ~(0x0300);
+ val |= 0x0300;
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_5, 0x0300);
+
+ val = wm8994_read(codec, WM8994_CHARGE_PUMP_1);
+ val &= ~(0x1F25);
+ val |= 0x1F25;
+ wm8994_write(codec, WM8994_CHARGE_PUMP_1, 0x1F25);
+ break;
+
+ case BT:
+ val = wm8994_read(codec, WM8994_AIF1_DAC1_FILTERS_1);
+ val &= ~(WM8994_AIF1DAC1_MUTE_MASK | WM8994_AIF1DAC1_MONO_MASK);
+ val |= (WM8994_AIF1DAC1_MUTE);
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, val);
+ break;
+
+ case SPK_HP:
+ val &= ~(WM8994_HPOUT1L_ENA_MASK | WM8994_HPOUT1R_ENA_MASK |
+ WM8994_SPKOUTL_ENA_MASK);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ /* Disable DAC1L to HPOUT1L path */
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_1);
+ val &= ~(WM8994_DAC1L_TO_HPOUT1L_MASK |
+ WM8994_DAC1L_TO_MIXOUTL_MASK);
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, val);
+
+ /* Disable DAC1R to HPOUT1R path */
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_2);
+ val &= ~(WM8994_DAC1R_TO_HPOUT1R_MASK |
+ WM8994_DAC1R_TO_MIXOUTR_MASK);
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, val);
+
+ /* Disable Charge Pump */
+ val = wm8994_read(codec, WM8994_CHARGE_PUMP_1);
+ val &= ~WM8994_CP_ENA_MASK;
+ val |= WM8994_CP_ENA_DEFAULT;
+ wm8994_write(codec, WM8994_CHARGE_PUMP_1, val);
+
+ /* Intermediate HP settings */
+ val = wm8994_read(codec, WM8994_ANALOGUE_HP_1);
+ val &= ~(WM8994_HPOUT1R_DLY_MASK | WM8994_HPOUT1R_OUTP_MASK |
+ WM8994_HPOUT1R_RMV_SHORT_MASK | WM8994_HPOUT1L_DLY_MASK |
+ WM8994_HPOUT1L_OUTP_MASK | WM8994_HPOUT1L_RMV_SHORT_MASK);
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, val);
+
+ /* Disable SPKLVOL */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_3);
+ val &= ~(WM8994_SPKLVOL_ENA_MASK);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, val);
+
+ /* Disable SPKOUT mixer */
+ val = wm8994_read(codec, WM8994_SPKOUT_MIXERS);
+ val &= ~(WM8994_SPKMIXL_TO_SPKOUTL_MASK |
+ WM8994_SPKMIXR_TO_SPKOUTL_MASK |
+ WM8994_SPKMIXR_TO_SPKOUTR_MASK);
+ wm8994_write(codec, WM8994_SPKOUT_MIXERS, val);
+
+ /* Mute Speaker mixer */
+ val = wm8994_read(codec, WM8994_SPEAKER_MIXER);
+ val &= ~(WM8994_DAC1L_TO_SPKMIXL_MASK);
+ wm8994_write(codec, WM8994_SPEAKER_MIXER, val);
+ break;
+
+ default:
+ DEBUG_LOG_ERR("Path[%d] is not invaild!\n", path);
+ return;
+ break;
+ }
+}
+
+void wm8994_disable_rec_path(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ u16 val;
+ enum mic_path mic = wm8994->rec_path;
+
+ wm8994->rec_path = MIC_OFF;
+
+ if (!(wm8994->codec_state & CALL_ACTIVE))
+ audio_ctrl_mic_bias_gpio(wm8994->pdata, 0);
+
+ switch (mic) {
+ case MAIN:
+ DEBUG_LOG("Disabling MAIN Mic Path..\n");
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_2);
+ val &= ~(WM8994_IN1L_ENA_MASK | WM8994_MIXINL_ENA_MASK);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_2, val);
+
+ /* Mute IN1L PGA, update volume */
+ val = wm8994_read(codec,
+ WM8994_LEFT_LINE_INPUT_1_2_VOLUME);
+ val &= ~(WM8994_IN1L_MUTE_MASK | WM8994_IN1L_VOL_MASK);
+ val |= (WM8994_IN1L_VU | WM8994_IN1L_MUTE);
+ wm8994_write(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME,
+ val);
+
+ /*Mute the PGA */
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_3);
+ val &= ~(WM8994_IN1L_TO_MIXINL_MASK |
+ WM8994_IN1L_MIXINL_VOL_MASK |
+ WM8994_MIXOUTL_MIXINL_VOL_MASK);
+ wm8994_write(codec, WM8994_INPUT_MIXER_3, val);
+
+ /* Disconnect IN1LN ans IN1LP to the inputs */
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_2);
+ val &= (WM8994_IN1LN_TO_IN1L_MASK | WM8994_IN1LP_TO_IN1L_MASK);
+ wm8994_write(codec, WM8994_INPUT_MIXER_2, val);
+
+ /* Digital Paths */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_4);
+ val &= ~(WM8994_ADCL_ENA_MASK | WM8994_AIF1ADC1L_ENA_MASK);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4, val);
+
+ /* Disable timeslots */
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_ADC1L_TO_AIF1ADC1L);
+ wm8994_write(codec, WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING, val);
+ break;
+
+ case SUB:
+ DEBUG_LOG("Disbaling SUB Mic path..\n");
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_2);
+ val &= ~(WM8994_IN1R_ENA_MASK | WM8994_MIXINR_ENA_MASK);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_2, val);
+
+ /* Disable volume,unmute Right Line */
+ val = wm8994_read(codec,
+ WM8994_RIGHT_LINE_INPUT_1_2_VOLUME);
+ val &= ~WM8994_IN1R_MUTE_MASK; /* Unmute IN1R */
+ val |= (WM8994_IN1R_VU | WM8994_IN1R_MUTE);
+ wm8994_write(codec, WM8994_RIGHT_LINE_INPUT_1_2_VOLUME,
+ val);
+
+ /* Mute right pga, set volume */
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_4);
+ val &= ~(WM8994_IN1R_TO_MIXINR_MASK |
+ WM8994_IN1R_MIXINR_VOL_MASK |
+ WM8994_MIXOUTR_MIXINR_VOL_MASK);
+ wm8994_write(codec, WM8994_INPUT_MIXER_4, val);
+
+ /* Disconnect in1rn to inr1 and in1rp to inrp */
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_2);
+ val &= ~(WM8994_IN1RN_TO_IN1R_MASK | WM8994_IN1RP_TO_IN1R_MASK);
+ wm8994_write(codec, WM8994_INPUT_MIXER_2, val);
+
+ /* Digital Paths */
+ /* Disable right ADC and time slot */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_4);
+ val &= ~(WM8994_ADCR_ENA_MASK | WM8994_AIF1ADC1R_ENA_MASK);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4, val);
+
+ /* ADC Right mixer routing */
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_ADC1R_TO_AIF1ADC1R_MASK);
+ wm8994_write(codec, WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING, val);
+ break;
+
+ case BT_REC:
+ DEBUG_LOG("Disbaling BT Mic path..\n");
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF2DACL_TO_AIF1ADC1L_MASK |
+ WM8994_ADC1L_TO_AIF1ADC1L_MASK);
+ wm8994_write(codec, WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF2DACR_TO_AIF1ADC1R_MASK |
+ WM8994_ADC1R_TO_AIF1ADC1R_MASK);
+ wm8994_write(codec, WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_AIF2_DAC_FILTERS_1);
+ val &= ~(WM8994_AIF2DAC_MUTE_MASK);
+ val |= (WM8994_AIF2DAC_MUTE);
+ wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, val);
+ break;
+
+ case MIC_OFF:
+ DEBUG_LOG("Mic is already OFF!\n");
+ break;
+
+ default:
+ DEBUG_LOG_ERR("Path[%d] is not invaild!\n", mic);
+ break;
+ }
+}
+
+void wm8994_set_bluetooth_common_setting(struct snd_soc_codec *codec)
+{
+ u32 val;
+
+ wm8994_write(codec, WM8994_GPIO_1, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_2, 0x8100);
+ wm8994_write(codec, WM8994_GPIO_3, 0x0100);
+ wm8994_write(codec, WM8994_GPIO_4, 0x0100);
+ wm8994_write(codec, WM8994_GPIO_5, 0x8100);
+ wm8994_write(codec, WM8994_GPIO_6, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_7, 0x0100);
+ wm8994_write(codec, WM8994_GPIO_8, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_9, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_10, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_11, 0xA101);
+
+ wm8994_write(codec, WM8994_FLL2_CONTROL_2, 0x0700);
+ wm8994_write(codec, WM8994_FLL2_CONTROL_3, 0x3126);
+ wm8994_write(codec, WM8994_FLL2_CONTROL_4, 0x0100);
+ wm8994_write(codec, WM8994_FLL2_CONTROL_5, 0x0C88);
+ wm8994_write(codec, WM8994_FLL2_CONTROL_1,
+ WM8994_FLL2_FRACN_ENA | WM8994_FLL2_ENA);
+
+ val = wm8994_read(codec, WM8994_AIF2_CLOCKING_1);
+ if (!(val & WM8994_AIF2CLK_ENA))
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0018);
+
+ wm8994_write(codec, WM8994_AIF2_RATE, 0x9 << WM8994_AIF2CLK_RATE_SHIFT);
+
+ /* AIF2 Interface - PCM Stereo mode */
+ /* Left Justified, BCLK invert, LRCLK Invert */
+ wm8994_write(codec, WM8994_AIF2_CONTROL_1,
+ WM8994_AIF2ADCR_SRC | WM8994_AIF2_BCLK_INV | 0x18);
+
+ wm8994_write(codec, WM8994_AIF2_BCLK, 0x70);
+ wm8994_write(codec, WM8994_AIF2_CONTROL_2, 0x0000);
+ wm8994_write(codec, WM8994_AIF2_MASTER_SLAVE, WM8994_AIF2_MSTR |
+ WM8994_AIF2_CLK_FRC | WM8994_AIF2_LRCLK_FRC);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_5);
+ val &= ~(WM8994_AIF2DACL_ENA_MASK | WM8994_AIF2DACR_ENA_MASK |
+ WM8994_AIF1DAC1L_ENA_MASK | WM8994_AIF1DAC1R_ENA_MASK |
+ WM8994_DAC1L_ENA_MASK | WM8994_DAC1R_ENA_MASK);
+ val |= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA |
+ WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA |
+ WM8994_DAC1L_ENA | WM8994_DAC1R_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_5, val);
+
+ /* Clocking */
+ val = wm8994_read(codec, WM8994_CLOCKING_1);
+ val |= (WM8994_DSP_FS2CLK_ENA | WM8994_SYSCLK_SRC);
+ wm8994_write(codec, WM8994_CLOCKING_1, val);
+
+ /* AIF1 & AIF2 Output is connected to DAC1 */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1L_TO_DAC1L_MASK |
+ WM8994_AIF2DACL_TO_DAC1L_MASK);
+ val |= (WM8994_AIF1DAC1L_TO_DAC1L | WM8994_AIF2DACL_TO_DAC1L);
+ wm8994_write(codec, WM8994_DAC1_LEFT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1R_TO_DAC1R_MASK |
+ WM8994_AIF2DACR_TO_DAC1R_MASK);
+ val |= (WM8994_AIF1DAC1R_TO_DAC1R | WM8994_AIF2DACR_TO_DAC1R);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING, val);
+}
+
+void wm8994_record_headset_mic(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ u16 val;
+
+ DEBUG_LOG("Recording through Headset Mic\n");
+
+ wm8994_write(codec, WM8994_ANTIPOP_2, 0x68);
+
+ /* Enable high pass filter to control bounce on startup */
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_FILTERS);
+ val &= ~(WM8994_AIF1ADC1L_HPF_MASK | WM8994_AIF1ADC1R_HPF_MASK);
+ val |= (WM8994_AIF1ADC1R_HPF);
+ wm8994_write(codec, WM8994_AIF1_ADC1_FILTERS, val);
+
+ /* Enable mic bias, vmid, bias generator */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_1);
+ val &= ~(WM8994_BIAS_ENA_MASK | WM8994_VMID_SEL_MASK);
+ val |= (WM8994_BIAS_ENA | WM8994_VMID_SEL_NORMAL);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_1);
+ val &= ~(WM8994_INPUTS_CLAMP_MASK);
+ val |= (WM8994_INPUTS_CLAMP);
+ wm8994_write(codec, WM8994_INPUT_MIXER_1, val);
+
+ val = (WM8994_MIXINR_ENA | WM8994_IN1R_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_2, val);
+
+
+ val = (WM8994_IN1RN_TO_IN1R | WM8994_IN1RP_TO_IN1R);
+ wm8994_write(codec, WM8994_INPUT_MIXER_2, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_LINE_INPUT_1_2_VOLUME);
+ val &= ~(WM8994_IN1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_4);
+ val &= ~(WM8994_IN1R_TO_MIXINR_MASK);
+ val |= (WM8994_IN1R_TO_MIXINR);
+ wm8994_write(codec, WM8994_INPUT_MIXER_4 , val);
+
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_1);
+ val &= ~(WM8994_INPUTS_CLAMP_MASK);
+ wm8994_write(codec, WM8994_INPUT_MIXER_1, val);
+
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_RIGHT_VOLUME);
+ val |= (WM8994_AIF1ADC1_VU);
+ wm8994_write(codec, WM8994_AIF1_ADC1_RIGHT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_FILTERS);
+ val &= ~(WM8994_AIF1ADC1L_HPF_MASK | WM8994_AIF1ADC1R_HPF_MASK);
+ val |= (WM8994_AIF1ADC1R_HPF | 0x2000);
+ wm8994_write(codec, WM8994_AIF1_ADC1_FILTERS, val);
+
+ val = wm8994_read(codec, WM8994_AIF1_MASTER_SLAVE);
+ val |= (WM8994_AIF1_MSTR | WM8994_AIF1_CLK_FRC | WM8994_AIF1_LRCLK_FRC);
+ wm8994_write(codec, WM8994_AIF1_MASTER_SLAVE, val);
+
+ wm8994_write(codec, WM8994_GPIO_1, 0xA101);
+
+ /* Mixing left channel output to right channel */
+ val = wm8994_read(codec, WM8994_AIF1_CONTROL_1);
+ val &= ~(WM8994_AIF1ADCL_SRC_MASK | WM8994_AIF1ADCR_SRC_MASK);
+ val |= (WM8994_AIF1ADCL_SRC | WM8994_AIF1ADCR_SRC);
+ wm8994_write(codec, WM8994_AIF1_CONTROL_1, val);
+
+ /* Digital Paths */
+ /* Enable right ADC and time slot */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_4);
+ val &= ~(WM8994_ADCR_ENA_MASK | WM8994_AIF1ADC1R_ENA_MASK);
+ val |= (WM8994_AIF1ADC1R_ENA | WM8994_ADCR_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4, val);
+
+
+ /* ADC Right mixer routing */
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_ADC1R_TO_AIF1ADC1R_MASK);
+ val |= WM8994_ADC1R_TO_AIF1ADC1R;
+ wm8994_write(codec, WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_SPEAKER_MIXER);
+ val &= ~WM8994_MIXINL_TO_SPKMIXL_MASK;
+ wm8994_write(codec, WM8994_SPEAKER_MIXER, val);
+
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_1);
+ val &= ~WM8994_MIXINL_TO_MIXOUTL_MASK;
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, val);
+
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_2);
+ val &= ~WM8994_MIXINR_TO_MIXOUTR_MASK;
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, val);
+
+ val = wm8994_read(codec, WM8994_DAC2_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_ADC1_TO_DAC2L_MASK);
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_DAC2_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_ADC1_TO_DAC2R_MASK);
+ wm8994_write(codec, WM8994_DAC2_RIGHT_MIXER_ROUTING, val);
+
+ if (wm8994->input_source == RECOGNITION)
+ wm8994_set_codec_gain(codec, RECORDING_MODE, RECORDING_REC_HP);
+ else if (wm8994->input_source == CAMCORDER)
+ wm8994_set_codec_gain(codec, RECORDING_MODE, RECORDING_CAM_HP);
+ else if (wm8994->input_source == VOICE_COMMUNICATION)
+ wm8994_set_codec_gain(codec, RECORDING_MODE, RECORDING_VC_HP);
+ else
+ wm8994_set_codec_gain(codec, RECORDING_MODE, RECORDING_HP);
+
+}
+
+void wm8994_record_main_mic(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ u16 val;
+
+ DEBUG_LOG("Recording through Main Mic\n");
+ audio_ctrl_mic_bias_gpio(wm8994->pdata, 1);
+
+ /* Main mic volume issue fix: requested H/W */
+ wm8994_write(codec, WM8994_ANTIPOP_2, 0x68);
+
+ /* High pass filter to control bounce on enable */
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_FILTERS);
+ val &= ~(WM8994_AIF1ADC1L_HPF_MASK | WM8994_AIF1ADC1R_HPF_MASK);
+ val |= (WM8994_AIF1ADC1L_HPF);
+ wm8994_write(codec, WM8994_AIF1_ADC1_FILTERS, val);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_1);
+ val &= ~(WM8994_BIAS_ENA_MASK | WM8994_VMID_SEL_MASK);
+ val |= (WM8994_BIAS_ENA | WM8994_VMID_SEL_NORMAL);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_1);
+ val &= ~(WM8994_INPUTS_CLAMP_MASK);
+ val |= (WM8994_INPUTS_CLAMP);
+ wm8994_write(codec, WM8994_INPUT_MIXER_1, val);
+
+ val = (WM8994_MIXINL_ENA | WM8994_IN1L_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_2, val);
+
+ val = (WM8994_IN1LP_TO_IN1L | WM8994_IN1LN_TO_IN1L);
+ wm8994_write(codec, WM8994_INPUT_MIXER_2, val);
+
+
+ val = wm8994_read(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME);
+ val &= ~(WM8994_IN1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_3);
+ val &= ~(WM8994_IN1L_TO_MIXINL_MASK);
+ val |= (WM8994_IN1L_TO_MIXINL);
+ wm8994_write(codec, WM8994_INPUT_MIXER_3, val);
+
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_1);
+ val &= ~(WM8994_INPUTS_CLAMP_MASK);
+ wm8994_write(codec, WM8994_INPUT_MIXER_1, val);
+
+
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_LEFT_VOLUME);
+ val |= (WM8994_AIF1ADC1_VU);
+ wm8994_write(codec, WM8994_AIF1_ADC1_LEFT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_FILTERS);
+ val &= ~(WM8994_AIF1ADC1L_HPF_MASK | WM8994_AIF1ADC1R_HPF_MASK);
+ val |= (WM8994_AIF1ADC1L_HPF | 0x2000);
+ wm8994_write(codec, WM8994_AIF1_ADC1_FILTERS, val);
+
+ val = wm8994_read(codec, WM8994_AIF1_MASTER_SLAVE);
+ val |= (WM8994_AIF1_MSTR | WM8994_AIF1_CLK_FRC | WM8994_AIF1_LRCLK_FRC);
+ wm8994_write(codec, WM8994_AIF1_MASTER_SLAVE, val);
+
+ wm8994_write(codec, WM8994_GPIO_1, 0xA101);
+
+ val = wm8994_read(codec, WM8994_AIF1_CONTROL_1);
+ val &= ~(WM8994_AIF1ADCL_SRC_MASK | WM8994_AIF1ADCR_SRC_MASK);
+ val |= (WM8994_AIF1ADCR_SRC);
+ wm8994_write(codec, WM8994_AIF1_CONTROL_1, val);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_4);
+ val &= ~(WM8994_ADCL_ENA_MASK | WM8994_AIF1ADC1L_ENA_MASK);
+ val |= (WM8994_AIF1ADC1L_ENA | WM8994_ADCL_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4, val);
+
+ /* Enable timeslots */
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING);
+ val |= WM8994_ADC1L_TO_AIF1ADC1L;
+ wm8994_write(codec, WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_SPEAKER_MIXER);
+ val &= ~WM8994_MIXINL_TO_SPKMIXL_MASK;
+ wm8994_write(codec, WM8994_SPEAKER_MIXER, val);
+
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_1);
+ val &= ~WM8994_MIXINL_TO_MIXOUTL_MASK;
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, val);
+
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_2);
+ val &= ~WM8994_MIXINR_TO_MIXOUTR_MASK;
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, val);
+
+ val = wm8994_read(codec, WM8994_DAC2_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_ADC1_TO_DAC2L_MASK);
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_DAC2_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_ADC1_TO_DAC2R_MASK);
+ wm8994_write(codec, WM8994_DAC2_RIGHT_MIXER_ROUTING, val);
+
+ if (wm8994->input_source == RECOGNITION)
+ wm8994_set_codec_gain(codec, RECORDING_MODE,
+ RECORDING_REC_MAIN);
+ else if (wm8994->input_source == CAMCORDER)
+ wm8994_set_codec_gain(codec, RECORDING_MODE,
+ RECORDING_CAM_MAIN);
+ else if (wm8994->input_source == VOICE_COMMUNICATION)
+ wm8994_set_codec_gain(codec, RECORDING_MODE,
+ RECORDING_VC_MAIN);
+ else
+ wm8994_set_codec_gain(codec, RECORDING_MODE, RECORDING_MAIN);
+
+}
+
+void wm8994_record_bluetooth(struct snd_soc_codec *codec)
+{
+ u16 val;
+
+ DEBUG_LOG("BT Record Path for Voice Command\n");
+
+ wm8994_set_bluetooth_common_setting(codec);
+
+ val = wm8994_read(codec, WM8994_DAC2_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_ADC1_TO_DAC2L_MASK);
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_DAC2_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_ADC1_TO_DAC2R_MASK);
+ wm8994_write(codec, WM8994_DAC2_RIGHT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_1);
+ val &= ~(WM8994_BIAS_ENA_MASK | WM8994_VMID_SEL_MASK);
+ val |= (WM8994_BIAS_ENA | WM8994_VMID_SEL_NORMAL);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_2, 0x0000);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, 0x0000);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_4);
+ val &= ~(WM8994_AIF1ADC1L_ENA_MASK | WM8994_AIF1ADC1R_ENA_MASK);
+ val |= (WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC1R_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4 , val);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_5);
+ val &= ~(WM8994_AIF2DACL_ENA_MASK | WM8994_AIF2DACR_ENA_MASK);
+ val |= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_5, val);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_6);
+ val &= ~(WM8994_AIF3_ADCDAT_SRC_MASK | WM8994_AIF2_DACDAT_SRC_MASK);
+ val |= (0x1 << WM8994_AIF3_ADCDAT_SRC_SHIFT | WM8994_AIF2_DACDAT_SRC);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_6, val);
+
+ val = wm8994_read(codec, WM8994_AIF2_DAC_FILTERS_1);
+ val &= ~(WM8994_AIF2DAC_MUTE_MASK);
+ wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, val);
+
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF2DACL_TO_AIF1ADC1L_MASK);
+ val |= (WM8994_AIF2DACL_TO_AIF1ADC1L);
+ wm8994_write(codec, WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF2DACR_TO_AIF1ADC1R_MASK);
+ val |= (WM8994_AIF2DACR_TO_AIF1ADC1R);
+ wm8994_write(codec, WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING, val);
+
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0019);
+
+ wm8994_write(codec, WM8994_OVERSAMPLING, 0X0000);
+
+ wm8994_write(codec, WM8994_GPIO_8, WM8994_GP8_DIR | WM8994_GP8_DB);
+ wm8994_write(codec, WM8994_GPIO_9, WM8994_GP9_DB);
+ wm8994_write(codec, WM8994_GPIO_10, WM8994_GP10_DB);
+ wm8994_write(codec, WM8994_GPIO_11, WM8994_GP11_DB);
+}
+void wm8994_set_playback_receiver(struct snd_soc_codec *codec)
+{
+ u16 val;
+
+ DEBUG_LOG("");
+
+ val = wm8994_read(codec, WM8994_LEFT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTL_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTL_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OPGA_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTR_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTR_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OPGA_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_HPOUT2_VOLUME);
+ val &= ~(WM8994_HPOUT2_MUTE_MASK);
+ wm8994_write(codec, WM8994_HPOUT2_VOLUME, val);
+
+ /* Unmute DAC1 left */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(WM8994_DAC1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val);
+
+ /* Unmute and volume ctrl RightDAC */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(WM8994_DAC1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_1);
+ val &= ~(WM8994_DAC1L_TO_MIXOUTL_MASK);
+ val |= (WM8994_DAC1L_TO_MIXOUTL);
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, val);
+
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_2);
+ val &= ~(WM8994_DAC1R_TO_MIXOUTR_MASK);
+ val |= (WM8994_DAC1R_TO_MIXOUTR);
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, val);
+
+ val = wm8994_read(codec, WM8994_HPOUT2_MIXER);
+ val &= ~(WM8994_MIXOUTLVOL_TO_HPOUT2_MASK |
+ WM8994_MIXOUTRVOL_TO_HPOUT2_MASK);
+ val |= (WM8994_MIXOUTRVOL_TO_HPOUT2 | WM8994_MIXOUTLVOL_TO_HPOUT2);
+ wm8994_write(codec, WM8994_HPOUT2_MIXER, val);
+
+ wm8994_set_codec_gain(codec, PLAYBACK_MODE, PLAYBACK_RCV);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_5);
+ val &= ~(WM8994_DAC1R_ENA_MASK | WM8994_DAC1L_ENA_MASK |
+ WM8994_AIF1DAC1R_ENA_MASK | WM8994_AIF1DAC1L_ENA_MASK);
+ val |= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA |
+ WM8994_DAC1L_ENA | WM8994_DAC1R_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_5, val);
+
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1L_TO_DAC1L_MASK);
+ val |= (WM8994_AIF1DAC1L_TO_DAC1L);
+ wm8994_write(codec, WM8994_DAC1_LEFT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1R_TO_DAC1R_MASK);
+ val |= (WM8994_AIF1DAC1R_TO_DAC1R);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_CLOCKING_1);
+ val &= ~(WM8994_DSP_FS1CLK_ENA_MASK | WM8994_DSP_FSINTCLK_ENA_MASK);
+ val |= (WM8994_DSP_FS1CLK_ENA | WM8994_DSP_FSINTCLK_ENA);
+ wm8994_write(codec, WM8994_CLOCKING_1, val);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_3);
+ val &= ~(WM8994_MIXOUTLVOL_ENA_MASK | WM8994_MIXOUTRVOL_ENA_MASK |
+ WM8994_MIXOUTL_ENA_MASK | WM8994_MIXOUTR_ENA_MASK);
+ val |= (WM8994_MIXOUTL_ENA | WM8994_MIXOUTR_ENA |
+ WM8994_MIXOUTRVOL_ENA | WM8994_MIXOUTLVOL_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, val);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_1);
+ val &= ~(WM8994_BIAS_ENA_MASK | WM8994_VMID_SEL_MASK |
+ WM8994_HPOUT2_ENA_MASK | WM8994_HPOUT1L_ENA_MASK |
+ WM8994_HPOUT1R_ENA_MASK | WM8994_SPKOUTL_ENA_MASK);
+ val |= (WM8994_BIAS_ENA | WM8994_VMID_SEL_NORMAL | WM8994_HPOUT2_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ val = wm8994_read(codec, WM8994_AIF1_DAC1_FILTERS_1);
+ val &= ~(WM8994_AIF1DAC1_MUTE_MASK | WM8994_AIF1DAC1_MONO_MASK);
+ val |= (WM8994_AIF1DAC1_UNMUTE | WM8994_AIF1DAC1_MONO);
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, val);
+
+}
+
+void wm8994_set_playback_headset(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ u16 val;
+
+ u16 testreturn1 = 0;
+ u16 testreturn2 = 0;
+ u16 testlow1 = 0;
+ u16 testhigh1 = 0;
+ u8 testlow = 0;
+ u8 testhigh = 0;
+
+ DEBUG_LOG("");
+
+ wm8994_earsel_control(wm8994->pdata, 0);
+
+ /* Enable the Timeslot0 to DAC1L */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1L_TO_DAC1L_MASK);
+ val |= WM8994_AIF1DAC1L_TO_DAC1L;
+ wm8994_write(codec, WM8994_DAC1_LEFT_MIXER_ROUTING, val);
+
+ /* Enable the Timeslot0 to DAC1R */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1R_TO_DAC1R_MASK);
+ val |= WM8994_AIF1DAC1R_TO_DAC1R;
+ wm8994_write(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, 0x56);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x56, val);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0000);
+ val = 0x0000;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, WM8994_CLASS_W_1);
+ val &= ~(0x0005);
+ val |= 0x0005;
+ wm8994_write(codec, WM8994_CLASS_W_1, val);
+
+ val = wm8994_read(codec, WM8994_LEFT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1L_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1L_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1R_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1R_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_LEFT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTL_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTL_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OPGA_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTR_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTR_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OPGA_VOLUME, val);
+
+ if (wm8994->ringtone_active)
+ wm8994_set_codec_gain(codec, PLAYBACK_MODE, PLAYBACK_RING_HP);
+ else if (wm8994->cur_path == HP_NO_MIC)
+ wm8994_set_codec_gain(codec, PLAYBACK_MODE, PLAYBACK_HP_NO_MIC);
+ else
+ wm8994_set_codec_gain(codec, PLAYBACK_MODE, PLAYBACK_HP);
+
+ val = wm8994_read(codec, WM8994_DC_SERVO_2);
+ val &= ~(0x03E0);
+ val = 0x03E0;
+ wm8994_write(codec, WM8994_DC_SERVO_2, val);
+
+ /* Enable vmid,bias, hp left and right */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_1);
+ val &= ~(WM8994_BIAS_ENA_MASK | WM8994_VMID_SEL_MASK |
+ WM8994_HPOUT1L_ENA_MASK | WM8994_HPOUT1R_ENA_MASK |
+ WM8994_SPKOUTR_ENA_MASK | WM8994_SPKOUTL_ENA_MASK);
+ val |= (WM8994_BIAS_ENA | WM8994_VMID_SEL_NORMAL |
+ WM8994_HPOUT1R_ENA | WM8994_HPOUT1L_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ val = wm8994_read(codec, WM8994_ANALOGUE_HP_1);
+ val &= ~(0x0022);
+ val = 0x0022;
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, val);
+
+ /* Enable Charge Pump */
+ /* this is from wolfson */
+ val = wm8994_read(codec, WM8994_CHARGE_PUMP_1);
+ val &= ~WM8994_CP_ENA_MASK ;
+ val |= WM8994_CP_ENA | WM8994_CP_ENA_DEFAULT;
+ wm8994_write(codec, WM8994_CHARGE_PUMP_1, val);
+
+ msleep(5);
+
+ /* Enable Dac1 and DAC2 and the Timeslot0 for AIF1 */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_5);
+ val &= ~(WM8994_DAC1R_ENA_MASK | WM8994_DAC1L_ENA_MASK |
+ WM8994_AIF1DAC1R_ENA_MASK | WM8994_AIF1DAC1L_ENA_MASK);
+ val |= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA |
+ WM8994_DAC1L_ENA | WM8994_DAC1R_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_5, val);
+
+ /* Enable DAC1L to HPOUT1L path */
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_1);
+ val &= ~(WM8994_DAC1L_TO_HPOUT1L_MASK | WM8994_DAC1L_TO_MIXOUTL_MASK);
+ val |= WM8994_DAC1L_TO_MIXOUTL;
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, val);
+
+ /* Enable DAC1R to HPOUT1R path */
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_2);
+ val &= ~(WM8994_DAC1R_TO_HPOUT1R_MASK | WM8994_DAC1R_TO_MIXOUTR_MASK);
+ val |= WM8994_DAC1R_TO_MIXOUTR;
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, val);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_3);
+ val &= ~(WM8994_MIXOUTLVOL_ENA_MASK | WM8994_MIXOUTRVOL_ENA_MASK |
+ WM8994_MIXOUTL_ENA_MASK | WM8994_MIXOUTR_ENA_MASK |
+ WM8994_SPKRVOL_ENA_MASK | WM8994_SPKLVOL_ENA_MASK);
+ val |= (WM8994_MIXOUTLVOL_ENA | WM8994_MIXOUTRVOL_ENA |
+ WM8994_MIXOUTL_ENA | WM8994_MIXOUTR_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, 0x0030);
+
+ if (!wm8994->dc_servo[DCS_MEDIA]) {
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_SERIES_0 |
+ WM8994_DCS_TRIG_SERIES_1);
+
+ testreturn1 = wm8994_read(codec, WM8994_DC_SERVO_4);
+
+ testlow = (signed char)(testreturn1 & 0xff);
+ testhigh = (signed char)((testreturn1>>8) & 0xff);
+
+ testlow1 = ((signed short)(testlow-5)) & 0x00ff;
+ testhigh1 = (((signed short)(testhigh-5)<<8) & 0xff00);
+ testreturn2 = testlow1|testhigh1;
+ } else {
+ testreturn2 = wm8994->dc_servo[DCS_MEDIA];
+ }
+
+ wm8994_write(codec, WM8994_DC_SERVO_4, testreturn2);
+ wm8994->dc_servo[DCS_MEDIA] = testreturn2;
+
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_DAC_WR_0 | WM8994_DCS_TRIG_DAC_WR_1);
+
+ /* Intermediate HP settings */
+ val = wm8994_read(codec, WM8994_ANALOGUE_HP_1);
+ val &= ~(WM8994_HPOUT1R_DLY_MASK | WM8994_HPOUT1R_OUTP_MASK |
+ WM8994_HPOUT1R_RMV_SHORT_MASK | WM8994_HPOUT1L_DLY_MASK |
+ WM8994_HPOUT1L_OUTP_MASK | WM8994_HPOUT1L_RMV_SHORT_MASK);
+ val = (WM8994_HPOUT1L_RMV_SHORT | WM8994_HPOUT1L_OUTP|
+ WM8994_HPOUT1L_DLY | WM8994_HPOUT1R_RMV_SHORT |
+ WM8994_HPOUT1R_OUTP | WM8994_HPOUT1R_DLY);
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, val);
+
+ /* Unmute DAC1 left */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(WM8994_DAC1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val);
+
+ /* Unmute and volume ctrl RightDAC */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(WM8994_DAC1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val);
+
+ /* Unmute the AF1DAC1 */
+ val = wm8994_read(codec, WM8994_AIF1_DAC1_FILTERS_1);
+ val &= ~(WM8994_AIF1DAC1_MUTE_MASK | WM8994_AIF1DAC1_MONO_MASK);
+ val |= WM8994_AIF1DAC1_UNMUTE;
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, val);
+
+}
+
+void wm8994_set_playback_speaker(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ u16 val;
+
+ DEBUG_LOG("");
+
+ /* Disable end point for preventing pop up noise.*/
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_1);
+ val &= ~(WM8994_SPKOUTL_ENA_MASK);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_3);
+ val &= ~(WM8994_MIXOUTLVOL_ENA_MASK | WM8994_MIXOUTRVOL_ENA_MASK |
+ WM8994_MIXOUTL_ENA_MASK | WM8994_MIXOUTR_ENA_MASK |
+ WM8994_SPKRVOL_ENA_MASK | WM8994_SPKLVOL_ENA_MASK);
+ val |= WM8994_SPKLVOL_ENA;
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, val);
+
+ /* Speaker Volume Control */
+ /* Unmute the SPKMIXVOLUME */
+ val = wm8994_read(codec, WM8994_SPEAKER_VOLUME_LEFT);
+ val &= ~(WM8994_SPKOUTL_MUTE_N_MASK);
+ val |= (WM8994_SPKOUTL_MUTE_N);
+ wm8994_write(codec, WM8994_SPEAKER_VOLUME_LEFT, val);
+
+ val = wm8994_read(codec, WM8994_SPEAKER_VOLUME_RIGHT);
+ val &= ~(WM8994_SPKOUTR_MUTE_N_MASK);
+ wm8994_write(codec, WM8994_SPEAKER_VOLUME_RIGHT, val);
+
+ /* Unmute DAC1 left */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(WM8994_DAC1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val);
+
+ /* Unmute and volume ctrl RightDAC */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(WM8994_DAC1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_SPKOUT_MIXERS);
+ val &= ~(WM8994_SPKMIXL_TO_SPKOUTL_MASK |
+ WM8994_SPKMIXR_TO_SPKOUTL_MASK |
+ WM8994_SPKMIXR_TO_SPKOUTR_MASK);
+ val |= WM8994_SPKMIXL_TO_SPKOUTL;
+ wm8994_write(codec, WM8994_SPKOUT_MIXERS, val);
+
+ /* Unmute the DAC path */
+ val = wm8994_read(codec, WM8994_SPEAKER_MIXER);
+ val &= ~(WM8994_DAC1L_TO_SPKMIXL_MASK);
+ val |= WM8994_DAC1L_TO_SPKMIXL;
+ wm8994_write(codec, WM8994_SPEAKER_MIXER, val);
+
+ /* Eable DAC1 Left and timeslot left */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_5);
+ val &= ~(WM8994_DAC1L_ENA_MASK | WM8994_AIF1DAC1R_ENA_MASK |
+ WM8994_AIF1DAC1L_ENA_MASK);
+ val |= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA | WM8994_DAC1L_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_5, val);
+
+ /* DRC setting */
+ wm8994_write(codec, WM8994_AIF1_DRC1_1, 0x00BC);
+ wm8994_write(codec, WM8994_AIF1_DRC1_3, 0x0028);
+ wm8994_write(codec, WM8994_AIF1_DRC1_4, 0x0186);
+
+ /* EQ AIF1 setting */
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_GAINS_1, 0x0019);
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_GAINS_2, 0x6280);
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_1_A, 0x0FC3);
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_1_B, 0x03FD);
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_1_PG, 0x00F4);
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_2_A, 0x1F30);
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_2_B, 0xF0CD);
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_2_C, 0x040A);
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_2_PG, 0x032C);
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_3_A, 0x1C52);
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_3_B, 0xF379);
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_3_C, 0x040A);
+ wm8994_write(codec, WM8994_AIF1_DAC1_EQ_BAND_3_PG, 0x0DC1);
+
+ if (wm8994->ringtone_active)
+ wm8994_set_codec_gain(codec, PLAYBACK_MODE, PLAYBACK_RING_SPK);
+ else
+ wm8994_set_codec_gain(codec, PLAYBACK_MODE, PLAYBACK_SPK);
+
+ /* enable timeslot0 to left dac */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1L_TO_DAC1L_MASK);
+ val |= WM8994_AIF1DAC1L_TO_DAC1L;
+ wm8994_write(codec, WM8994_DAC1_LEFT_MIXER_ROUTING, val);
+
+#ifdef CONFIG_SND_VOODOO
+ voodoo_hook_playback_speaker();
+#endif
+
+ /* Enbale bias,vmid and Left speaker */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_1);
+ val &= ~(WM8994_BIAS_ENA_MASK | WM8994_VMID_SEL_MASK |
+ WM8994_HPOUT1L_ENA_MASK | WM8994_HPOUT1R_ENA_MASK |
+ WM8994_SPKOUTR_ENA_MASK | WM8994_SPKOUTL_ENA_MASK);
+ val |= (WM8994_BIAS_ENA | WM8994_VMID_SEL_NORMAL | WM8994_SPKOUTL_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ /* Unmute */
+ val = wm8994_read(codec, WM8994_AIF1_DAC1_FILTERS_1);
+ val &= ~(WM8994_AIF1DAC1_MUTE_MASK | WM8994_AIF1DAC1_MONO_MASK);
+ val |= (WM8994_AIF1DAC1_UNMUTE | WM8994_AIF1DAC1_MONO);
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, val);
+
+}
+
+void wm8994_set_playback_speaker_headset(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ u16 val;
+
+ u16 nreadservo4val = 0;
+ u16 ncompensationresult = 0;
+ u16 ncompensationresultlow = 0;
+ u16 ncompensationresulthigh = 0;
+ u8 nservo4low = 0;
+ u8 nservo4high = 0;
+
+ wm8994_earsel_control(wm8994->pdata, 0);
+
+ /* Enable the Timeslot0 to DAC1L */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1L_TO_DAC1L_MASK);
+ val |= WM8994_AIF1DAC1L_TO_DAC1L;
+ wm8994_write(codec, WM8994_DAC1_LEFT_MIXER_ROUTING, val);
+
+ /* Enable the Timeslot0 to DAC1R */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1R_TO_DAC1R_MASK);
+ val |= WM8994_AIF1DAC1R_TO_DAC1R;
+ wm8994_write(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING, val);
+
+ /* Speaker Volume Control */
+ val = wm8994_read(codec, WM8994_SPEAKER_VOLUME_LEFT);
+ val &= ~(WM8994_SPKOUTL_MUTE_N_MASK);
+ val |= (WM8994_SPKOUTL_MUTE_N);
+ wm8994_write(codec, WM8994_SPEAKER_VOLUME_LEFT, val);
+
+ val = wm8994_read(codec, WM8994_SPEAKER_VOLUME_RIGHT);
+ val &= ~(WM8994_SPKOUTR_MUTE_N_MASK);
+ wm8994_write(codec, WM8994_SPEAKER_VOLUME_RIGHT, val);
+
+ val = wm8994_read(codec, WM8994_SPKOUT_MIXERS);
+ val &= ~(WM8994_SPKMIXL_TO_SPKOUTL_MASK |
+ WM8994_SPKMIXR_TO_SPKOUTL_MASK |
+ WM8994_SPKMIXR_TO_SPKOUTR_MASK);
+ val |= WM8994_SPKMIXL_TO_SPKOUTL;
+ wm8994_write(codec, WM8994_SPKOUT_MIXERS, val);
+
+ /* Unmute the DAC path */
+ val = wm8994_read(codec, WM8994_SPEAKER_MIXER);
+ val &= ~(WM8994_DAC1L_TO_SPKMIXL_MASK);
+ val |= WM8994_DAC1L_TO_SPKMIXL;
+ wm8994_write(codec, WM8994_SPEAKER_MIXER, val);
+
+ /* Configuring the Digital Paths */
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, 0x56);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x56, val);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0000);
+ val = 0x0000;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, WM8994_CLASS_W_1);
+ val &= ~(0x0005);
+ val = 0x0005;
+ wm8994_write(codec, WM8994_CLASS_W_1, val);
+
+ val = wm8994_read(codec, WM8994_LEFT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1L_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1L_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1R_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1R_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OUTPUT_VOLUME, val);
+
+ /* DC Servo Series Count */
+ val = 0x03E0;
+ wm8994_write(codec, WM8994_DC_SERVO_2, val);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_1);
+ val &= ~(WM8994_BIAS_ENA_MASK | WM8994_VMID_SEL_MASK |
+ WM8994_HPOUT1L_ENA_MASK | WM8994_HPOUT1R_ENA_MASK |
+ WM8994_SPKOUTL_ENA_MASK);
+ val |= (WM8994_BIAS_ENA | WM8994_VMID_SEL_NORMAL |
+ WM8994_HPOUT1R_ENA | WM8994_HPOUT1L_ENA |
+ WM8994_SPKOUTL_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ val = (WM8994_HPOUT1L_DLY | WM8994_HPOUT1R_DLY);
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, val);
+
+ /* Enable Charge Pump */
+ /* this is from wolfson */
+ val = wm8994_read(codec, WM8994_CHARGE_PUMP_1);
+ val &= ~WM8994_CP_ENA_MASK ;
+ val |= WM8994_CP_ENA | WM8994_CP_ENA_DEFAULT;
+ wm8994_write(codec, WM8994_CHARGE_PUMP_1, val);
+
+ msleep(5);
+
+ /* Enable DAC1 and DAC2 and the Timeslot0 for AIF1 */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_5);
+ val &= ~(WM8994_DAC1R_ENA_MASK | WM8994_DAC1L_ENA_MASK |
+ WM8994_AIF1DAC1R_ENA_MASK | WM8994_AIF1DAC1L_ENA_MASK);
+ val |= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA |
+ WM8994_DAC1L_ENA | WM8994_DAC1R_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_5, val);
+
+ /* Enbale DAC1L to HPOUT1L path */
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_1);
+ val &= ~(WM8994_DAC1L_TO_HPOUT1L_MASK | WM8994_DAC1L_TO_MIXOUTL_MASK);
+ val |= WM8994_DAC1L_TO_MIXOUTL;
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, val);
+
+ /* Enbale DAC1R to HPOUT1R path */
+ val = wm8994_read(codec, WM8994_OUTPUT_MIXER_2);
+ val &= ~(WM8994_DAC1R_TO_HPOUT1R_MASK | WM8994_DAC1R_TO_MIXOUTR_MASK);
+ val |= WM8994_DAC1R_TO_MIXOUTR;
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, val);
+
+ /* Enbale bias,vmid, hp left and right and Left speaker */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_3);
+ val &= ~(WM8994_MIXOUTLVOL_ENA_MASK | WM8994_MIXOUTRVOL_ENA_MASK |
+ WM8994_MIXOUTL_ENA_MASK | WM8994_MIXOUTR_ENA_MASK |
+ WM8994_SPKLVOL_ENA_MASK);
+ val |= (WM8994_MIXOUTL_ENA | WM8994_MIXOUTR_ENA | WM8994_SPKLVOL_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, val);
+
+ /* DC Servo */
+ if (!wm8994->dc_servo[DCS_SPK_HP]) {
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_SERIES_0 |
+ WM8994_DCS_TRIG_SERIES_1);
+
+ nreadservo4val = wm8994_read(codec, WM8994_DC_SERVO_4);
+ nservo4low = (signed char)(nreadservo4val & 0xff);
+ nservo4high = (signed char)((nreadservo4val>>8) & 0xff);
+
+ ncompensationresultlow = ((signed short)nservo4low - 5)
+ & 0x00ff;
+ ncompensationresulthigh = ((signed short)(nservo4high - 5)<<8)
+ & 0xff00;
+ ncompensationresult = ncompensationresultlow |
+ ncompensationresulthigh;
+ } else {
+ ncompensationresult = wm8994->dc_servo[DCS_SPK_HP];
+ }
+
+ wm8994_write(codec, WM8994_DC_SERVO_4, ncompensationresult);
+ wm8994->dc_servo[DCS_SPK_HP] = ncompensationresult;
+
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_DAC_WR_1 | WM8994_DCS_TRIG_DAC_WR_0);
+
+ val = wm8994_read(codec, WM8994_ANALOGUE_HP_1);
+ val &= ~(WM8994_HPOUT1R_DLY_MASK | WM8994_HPOUT1R_OUTP_MASK |
+ WM8994_HPOUT1R_RMV_SHORT_MASK | WM8994_HPOUT1L_DLY_MASK |
+ WM8994_HPOUT1L_OUTP_MASK | WM8994_HPOUT1L_RMV_SHORT_MASK);
+ val |= (WM8994_HPOUT1L_RMV_SHORT | WM8994_HPOUT1L_OUTP |
+ WM8994_HPOUT1L_DLY | WM8994_HPOUT1R_RMV_SHORT |
+ WM8994_HPOUT1R_OUTP | WM8994_HPOUT1R_DLY);
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, val);
+
+ if (wm8994->ringtone_active)
+ wm8994_set_codec_gain(codec, PLAYBACK_MODE,
+ PLAYBACK_RING_SPK_HP);
+ else
+ wm8994_set_codec_gain(codec, PLAYBACK_MODE, PLAYBACK_SPK_HP);
+
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(WM8994_DAC1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(WM8994_DAC1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_AIF1_DAC1_FILTERS_1);
+ val &= ~(WM8994_AIF1DAC1_MUTE_MASK | WM8994_AIF1DAC1_MONO_MASK);
+ val |= (WM8994_AIF1DAC1_UNMUTE | WM8994_AIF1DAC1_MONO);
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, val);
+
+}
+
+void wm8994_set_playback_bluetooth(struct snd_soc_codec *codec)
+{
+ u16 val;
+
+ DEBUG_LOG("BT Playback Path for SCO\n");
+
+ wm8994_set_bluetooth_common_setting(codec);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_1);
+ val &= ~(WM8994_BIAS_ENA_MASK | WM8994_VMID_SEL_MASK);
+ val |= (WM8994_BIAS_ENA | WM8994_VMID_SEL_NORMAL);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_2, 0x0000);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, 0x0000);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_4);
+ val &= ~(WM8994_AIF2ADCL_ENA_MASK | WM8994_AIF2ADCR_ENA_MASK);
+ val |= (WM8994_AIF2ADCL_ENA | WM8994_AIF2ADCR_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4, val);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_5);
+ val &= ~(WM8994_AIF2DACL_ENA_MASK | WM8994_AIF2DACR_ENA_MASK |
+ WM8994_AIF1DAC1L_ENA_MASK | WM8994_AIF1DAC1R_ENA_MASK |
+ WM8994_DAC1L_ENA_MASK | WM8994_DAC1R_ENA_MASK);
+ val |= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA |
+ WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA |
+ WM8994_DAC1L_ENA | WM8994_DAC1R_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_5, val);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_6);
+ val &= ~(WM8994_AIF3_ADCDAT_SRC_MASK);
+ val |= (0x0001 << WM8994_AIF3_ADCDAT_SRC_SHIFT);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_6, val);
+
+ /* Mixer Routing*/
+ val = wm8994_read(codec, WM8994_DAC2_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1L_TO_DAC2L_MASK);
+ val |= (WM8994_AIF1DAC1L_TO_DAC2L);
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_DAC2_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1R_TO_DAC2R_MASK);
+ val |= (WM8994_AIF1DAC1R_TO_DAC2R);
+ wm8994_write(codec, WM8994_DAC2_RIGHT_MIXER_ROUTING, val);
+
+ /* Volume*/
+ wm8994_write(codec, WM8994_DAC2_LEFT_VOLUME, 0x01C0);
+ wm8994_write(codec, WM8994_DAC2_RIGHT_VOLUME, 0x01C0);
+
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0019);
+
+ wm8994_write(codec, WM8994_OVERSAMPLING, 0X0000);
+
+ /* GPIO Configuration*/
+ wm8994_write(codec, WM8994_GPIO_8, WM8994_GP8_DIR | WM8994_GP8_DB);
+ wm8994_write(codec, WM8994_GPIO_9, WM8994_GP9_DB);
+ wm8994_write(codec, WM8994_GPIO_10, WM8994_GP10_DB);
+ wm8994_write(codec, WM8994_GPIO_11, WM8994_GP11_DB);
+
+ /* Un-Mute*/
+ val = wm8994_read(codec, WM8994_AIF1_DAC1_FILTERS_1);
+ val &= ~(WM8994_AIF1DAC1_MUTE_MASK | WM8994_AIF1DAC1_MONO_MASK);
+ val |= (WM8994_AIF1DAC1_UNMUTE);
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, val);
+
+}
+
+static void wm8994_set_cdma_voicecall_common_setting(struct snd_soc_codec *codec)
+{
+ int val;
+
+ wm8994_write(codec, WM8994_ANTIPOP_2, 0x0068);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, 0x0003);
+ msleep(50);
+ /* GPIO Configuration */
+ wm8994_write(codec, WM8994_GPIO_1, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_2, 0x8100);
+ wm8994_write(codec, WM8994_GPIO_3, 0x8100);
+ wm8994_write(codec, WM8994_GPIO_4, 0x8100);
+ wm8994_write(codec, WM8994_GPIO_5, 0x8100);
+ wm8994_write(codec, WM8994_GPIO_6, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_7, 0x0100);
+ wm8994_write(codec, WM8994_GPIO_8, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_9, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_10, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_11, 0xA101);
+
+ wm8994_write(codec, WM8994_FLL2_CONTROL_2, 0x2F00);
+ wm8994_write(codec, WM8994_FLL2_CONTROL_3, 0x3126);
+ wm8994_write(codec, WM8994_FLL2_CONTROL_4, 0x0600);
+ wm8994_write(codec, WM8994_FLL2_CONTROL_5, 0x0C81);
+ wm8994_write(codec, WM8994_FLL2_CONTROL_1, 0x0001);
+
+ val = wm8994_read(codec, WM8994_AIF2_CLOCKING_1);
+ if (!(val & WM8994_AIF2CLK_ENA))
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0009);
+
+ wm8994_write(codec, WM8994_AIF2_RATE, 0x0003);
+
+ /* AIF2 Interface - PCM Stereo mode */
+ /* Left Justified, BCLK invert, LRCLK Invert */
+ wm8994_write(codec, WM8994_AIF2_CONTROL_1, 0x4118);
+
+ wm8994_write(codec, WM8994_AIF2_BCLK, 0x70);
+ wm8994_write(codec, WM8994_AIF2_CONTROL_2, 0x0000);
+ wm8994_write(codec, WM8994_AIF2_MASTER_SLAVE, 0);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_5);
+ val &= ~(WM8994_AIF2DACL_ENA_MASK | WM8994_AIF2DACR_ENA_MASK |
+ WM8994_AIF1DAC1L_ENA_MASK | WM8994_AIF1DAC1R_ENA_MASK |
+ WM8994_DAC1L_ENA_MASK | WM8994_DAC1R_ENA_MASK);
+ val |= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA |
+ WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA |
+ WM8994_DAC1L_ENA | WM8994_DAC1R_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_5, val);
+
+ /* Clocking */
+ val = wm8994_read(codec, WM8994_CLOCKING_1);
+ val |= (WM8994_DSP_FS2CLK_ENA);
+ wm8994_write(codec, WM8994_CLOCKING_1, 0x000F);
+
+ /* AIF1 & AIF2 Output is connected to DAC1 */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1L_TO_DAC1L_MASK |
+ WM8994_AIF2DACL_TO_DAC1L_MASK);
+ val |= (WM8994_AIF1DAC1L_TO_DAC1L | WM8994_AIF2DACL_TO_DAC1L);
+ wm8994_write(codec, WM8994_DAC1_LEFT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1R_TO_DAC1R_MASK |
+ WM8994_AIF2DACR_TO_DAC1R_MASK);
+ val |= (WM8994_AIF1DAC1R_TO_DAC1R | WM8994_AIF2DACR_TO_DAC1R);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING, val);
+
+ wm8994_write(codec, 0x6, 0x0);
+}
+
+static void wm8994_set_gsm_voicecall_common_setting(struct snd_soc_codec *codec)
+{
+ int val;
+
+ /* GPIO Configuration */
+ wm8994_write(codec, WM8994_GPIO_1, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_2, 0x8100);
+ wm8994_write(codec, WM8994_GPIO_3, 0x0100);
+ wm8994_write(codec, WM8994_GPIO_4, 0x0100);
+ wm8994_write(codec, WM8994_GPIO_5, 0x8100);
+ wm8994_write(codec, WM8994_GPIO_6, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_7, 0x0100);
+ wm8994_write(codec, WM8994_GPIO_8, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_9, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_10, 0xA101);
+ wm8994_write(codec, WM8994_GPIO_11, 0xA101);
+
+ wm8994_write(codec, WM8994_FLL2_CONTROL_2, 0x2F00);
+ wm8994_write(codec, WM8994_FLL2_CONTROL_3, 0x3126);
+ wm8994_write(codec, WM8994_FLL2_CONTROL_4, 0x0100);
+ wm8994_write(codec, WM8994_FLL2_CONTROL_5, 0x0C88);
+ wm8994_write(codec, WM8994_FLL2_CONTROL_1,
+ WM8994_FLL2_FRACN_ENA | WM8994_FLL2_ENA);
+
+ val = wm8994_read(codec, WM8994_AIF2_CLOCKING_1);
+ if (!(val & WM8994_AIF2CLK_ENA))
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0018);
+
+ wm8994_write(codec, WM8994_AIF2_RATE, 0x3 << WM8994_AIF2CLK_RATE_SHIFT);
+
+ /* AIF2 Interface - PCM Stereo mode */
+ /* Left Justified, BCLK invert, LRCLK Invert */
+ wm8994_write(codec, WM8994_AIF2_CONTROL_1,
+ WM8994_AIF2ADCR_SRC | WM8994_AIF2_BCLK_INV | 0x18);
+
+ wm8994_write(codec, WM8994_AIF2_BCLK, 0x70);
+ wm8994_write(codec, WM8994_AIF2_CONTROL_2, 0x0000);
+ wm8994_write(codec, WM8994_AIF2_MASTER_SLAVE, WM8994_AIF2_MSTR |
+ WM8994_AIF2_CLK_FRC | WM8994_AIF2_LRCLK_FRC);
+
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_5);
+ val &= ~(WM8994_AIF2DACL_ENA_MASK | WM8994_AIF2DACR_ENA_MASK |
+ WM8994_AIF1DAC1L_ENA_MASK | WM8994_AIF1DAC1R_ENA_MASK |
+ WM8994_DAC1L_ENA_MASK | WM8994_DAC1R_ENA_MASK);
+ val |= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA |
+ WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA |
+ WM8994_DAC1L_ENA | WM8994_DAC1R_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_5, val);
+
+ /* Clocking */
+ val = wm8994_read(codec, WM8994_CLOCKING_1);
+ val |= (WM8994_DSP_FS2CLK_ENA);
+ wm8994_write(codec, WM8994_CLOCKING_1, val);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_6, 0x0);
+
+ /* AIF1 & AIF2 Output is connected to DAC1 */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1L_TO_DAC1L_MASK |
+ WM8994_AIF2DACL_TO_DAC1L_MASK);
+ val |= (WM8994_AIF1DAC1L_TO_DAC1L | WM8994_AIF2DACL_TO_DAC1L);
+ wm8994_write(codec, WM8994_DAC1_LEFT_MIXER_ROUTING, val);
+
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING);
+ val &= ~(WM8994_AIF1DAC1R_TO_DAC1R_MASK |
+ WM8994_AIF2DACR_TO_DAC1R_MASK);
+ val |= (WM8994_AIF1DAC1R_TO_DAC1R | WM8994_AIF2DACR_TO_DAC1R);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING, val);
+
+ wm8994_write(codec, 0x6, 0x0);
+}
+
+
+void wm8994_set_voicecall_common_setting(struct snd_soc_codec *codec)
+{
+ if (herring_is_cdma_wimax_dev())
+ wm8994_set_cdma_voicecall_common_setting(codec);
+ else
+ wm8994_set_gsm_voicecall_common_setting(codec);
+
+#ifdef CONFIG_SND_VOODOO_RECORD_PRESETS
+ voodoo_hook_record_main_mic();
+#endif
+}
+
+static void wm8994_set_cdma_voicecall_receiver(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ int val;
+
+ DEBUG_LOG("");
+
+ audio_ctrl_mic_bias_gpio(wm8994->pdata, 1);
+
+ wm8994_write(codec, 0x0039, 0x0068); /* Anti Pop2 */
+ wm8994_write(codec, 0x0001, 0x0003); /* Power Management 1 */
+ msleep(50);
+ wm8994_write(codec, 0x0015, 0x0040);
+ wm8994_write(codec, 0x0702, 0x8100); /* GPIO 3. Speech PCM Clock */
+ wm8994_write(codec, 0x0703, 0x8100); /* GPIO 4. Speech PCM Sync */
+ /* GPIO 5. Speech PCM Data Out */
+ wm8994_write(codec, 0x0704, 0x8100);
+ /* GPIO 7. Speech PCM Data Input */
+ wm8994_write(codec, 0x0706, 0x0100);
+ wm8994_write(codec, 0x0244, 0x0C81); /* FLL2 Control 5 */
+ wm8994_write(codec, 0x0241, 0x2F00); /* FLL2 Control 2 */
+ wm8994_write(codec, 0x0243, 0x0600); /* FLL2 Control 4 */
+ wm8994_write(codec, 0x0240, 0x0001); /* FLL2 Control 1 */
+ msleep(3);
+
+ /* AIF2 Clocking 1. Clock Source Select */
+ wm8994_write(codec, 0x0204, 0x0008);
+
+ /* Clocking 1. '0x000A' is added for a playback. (original = 0x0007) */
+ wm8994_write(codec, 0x0208, 0x000F);
+
+ wm8994_write(codec, 0x0620, 0x0000); /* Oversampling */
+ wm8994_write(codec, 0x0211, 0x0003); /* AIF2 Rate */
+ wm8994_write(codec, 0x0310, 0x4118); /* AIF2 Control 1 */
+ /* AIF2 Control 2 pcm format is changed ulaw to linear */
+ wm8994_write(codec, 0x0311, 0x0000);
+ wm8994_write(codec, 0x0520, 0x0000); /* AIF2 DAC Filter 1 */
+ /* AIF2 Clocking 1. AIF2 Clock Enable */
+ wm8994_write(codec, 0x0204, 0x0009);
+
+ wm8994_write(codec, 0x0601, 0x0005); /* DAC1 Left Mixer Routing */
+ /* DAC1 Right Mixer Routing(Playback) */
+ wm8994_write(codec, 0x0602, 0x0001);
+ wm8994_write(codec, 0x0603, 0x018C); /* DAC2 Mixer Volumes */
+ wm8994_write(codec, 0x0604, 0x0030); /* DAC2 Left Mixer Routing */
+ wm8994_write(codec, 0x0605, 0x0010); /* DAC2 Right Mixer Routing */
+ wm8994_write(codec, 0x0621, 0x01C0); /* Sidetone */
+ wm8994_write(codec, 0x0002, 0x6240); /* Power Management 2 */
+ wm8994_write(codec, 0x0028, 0x0030); /* Input Mixer 2 */
+ wm8994_write(codec, 0x0018, 0x010A);
+
+ /* Output Mixer 5 */
+ val = wm8994_read(codec, 0x0031);
+ val &= ~(WM8994_DACL_MIXOUTL_VOL_MASK);
+ val |= 0x0000 << 0x0009;
+ wm8994_write(codec, 0x0031, val);
+
+ /* Output Mixer 6 */
+ val = wm8994_read(codec, 0x0032);
+ val &= ~(WM8994_DACR_MIXOUTR_VOL_MASK);
+ val |= 0x0000 << 0x0009;
+ wm8994_write(codec, 0x0032, val);
+
+ /* Left OPGA Volume */
+ val = wm8994_read(codec, 0x0020);
+ val &= ~(WM8994_MIXOUTL_MUTE_N_MASK | WM8994_MIXOUTL_VOL_MASK);
+ val |= (0x0100 | 0x0040 | 0x3D);
+ /* 05.24 Maximum ´ëºñ -6dB HAC ¿ë test -2 3B -> 39 */
+ wm8994_write(codec, 0x0020, 0x01F9);
+
+ /* Right OPGA Volume */
+ val = wm8994_read(codec, 0x0021);
+ val &= ~(WM8994_MIXOUTR_MUTE_N_MASK | WM8994_MIXOUTR_VOL_MASK);
+ val |= (0x0100 | 0x0040 | 0x3D);
+ wm8994_write(codec, 0x0021, 0x01F9);
+
+ wm8994_write(codec, 0x0312, 0x0000); /* Slave */
+ /* sub mic */
+ wm8994_write(codec, 0x0029, 0x0030); /* Input Mixer 3 */
+
+ wm8994_write(codec, 0x0015, 0x0000);
+ wm8994_write(codec, 0x0500, 0x0100); /* AIF2 ADC Left Volume */
+ wm8994_write(codec, 0x0004, 0x2002); /* Power Management 4 */
+ /* Power Management 5.'0x0303' added for a playback.(Original=0x2002) */
+ wm8994_write(codec, 0x0005, 0x2303);
+ /* Power Management 3.'0x00F0' added for a playback.(Original=0x00A0) */
+ wm8994_write(codec, 0x0003, 0x00F0);
+ wm8994_write(codec, 0x002D, 0x0001); /* Output Mixer 1 */
+ wm8994_write(codec, 0x002E, 0x0001); /* Output Mixer 2(Playback) */
+ /* HPOUT2 Mixer. '0x0008' added for a playback.(Original=0x0010) */
+ wm8994_write(codec, 0x0033, 0x0018);
+ wm8994_write(codec, 0x0038, 0x0040); /* Anti Pop 1 */
+ wm8994_write(codec, 0x0420, 0x0080); /* AIF1 DAC1 FIlter(Playback) */
+
+ /* HPOUT2 Volume */
+ wm8994_write(codec, 0x001F, 0x0000); /* HPOUT2 Volume */
+
+ wm8994_write(codec, 0x0001, 0x0803); /* Power Management 1 */
+
+ /* DAC1 Left Volume */
+ val = wm8994_read(codec, 0x0610);
+ val &= ~(WM8994_DAC1L_MUTE_MASK | WM8994_DAC1L_VOL_MASK);
+ val |= 0xC0;
+ wm8994_write(codec, 0x0610, 0x01C0);
+
+ /* DAC1 Right Volume */
+ val = wm8994_read(codec, 0x0611);
+ val &= ~(WM8994_DAC1R_MUTE_MASK | WM8994_DAC1R_VOL_MASK);
+ val |= 0xC0;
+ wm8994_write(codec, 0x0611, 0x01C0);
+
+ /* Power Management 3(Playback) */
+ wm8994_write(codec, 0x0003, 0x00F0);
+
+ wm8994_write(codec, 0x06, 0x0000);
+ wm8994_write(codec, 0x0612, 0x01C0); /* DAC2 Left Volume */
+ wm8994_write(codec, 0x0613, 0x01C0); /* DAC2 Right Volume */
+ wm8994_write(codec, 0x0500, 0x01C0); /* AIF2 ADC Left Volume */
+}
+
+static void wm8994_set_gsm_voicecall_receiver(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ int val;
+
+ DEBUG_LOG("");
+
+ audio_ctrl_mic_bias_gpio(wm8994->pdata, 1);
+
+ wm8994_set_voicecall_common_setting(codec);
+
+ wm8994_write(codec, WM8994_CHARGE_PUMP_1, WM8994_CP_ENA_DEFAULT);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_2,
+ WM8994_TSHUT_ENA | WM8994_TSHUT_OPDIS | WM8994_MIXINL_ENA |
+ WM8994_IN1L_ENA);
+
+ wm8994_write(codec, WM8994_INPUT_MIXER_2,
+ WM8994_IN1LP_TO_IN1L | WM8994_IN1LN_TO_IN1L);
+
+ /* Digital Path Enables and Unmutes */
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4,
+ WM8994_AIF2ADCL_ENA | WM8994_ADCL_ENA);
+
+ wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x000C);
+ wm8994_write(codec, WM8994_DAC2_LEFT_VOLUME, 0x01C0);
+ wm8994_write(codec, WM8994_DAC2_RIGHT_VOLUME, 0x01C0);
+
+ /* Tx -> AIF2 Path */
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING,
+ WM8994_ADC1_TO_DAC2L);
+ wm8994_write(codec, WM8994_DAC2_RIGHT_MIXER_ROUTING,
+ WM8994_ADC1_TO_DAC2R);
+
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0019);
+
+ /* Unmute IN1L PGA, update volume */
+ val = wm8994_read(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME);
+ val &= ~(WM8994_IN1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME, val);
+
+ /* Unmute the PGA */
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_3);
+ val &= ~(WM8994_IN1L_TO_MIXINL_MASK);
+ val |= (WM8994_IN1L_TO_MIXINL);
+ wm8994_write(codec, WM8994_INPUT_MIXER_3, val);
+
+ /* Volume Control - Output */
+ val = wm8994_read(codec, WM8994_LEFT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTL_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTL_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OPGA_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTR_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTR_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OPGA_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_HPOUT2_VOLUME);
+ val &= ~(WM8994_HPOUT2_MUTE_MASK);
+ wm8994_write(codec, WM8994_HPOUT2_VOLUME, val);
+
+ wm8994_set_codec_gain(codec, VOICECALL_MODE, VOICECALL_RCV);
+
+ /* Unmute DAC1 left */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(WM8994_DAC1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val);
+
+ /* Unmute and volume ctrl RightDAC */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(WM8994_DAC1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val);
+
+ /* Output Mixing */
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, WM8994_DAC1L_TO_MIXOUTL);
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, WM8994_DAC1R_TO_MIXOUTR);
+
+ /* Analogue Output Configuration */
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3,
+ WM8994_MIXOUTLVOL_ENA | WM8994_MIXOUTRVOL_ENA |
+ WM8994_MIXOUTL_ENA | WM8994_MIXOUTR_ENA);
+ wm8994_write(codec, WM8994_HPOUT2_MIXER, WM8994_MIXOUTLVOL_TO_HPOUT2 |
+ WM8994_MIXOUTRVOL_TO_HPOUT2);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1,
+ WM8994_HPOUT2_ENA | WM8994_VMID_SEL_NORMAL | WM8994_BIAS_ENA);
+
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, 0x0000);
+ wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, 0x0000);
+
+}
+
+
+void wm8994_set_voicecall_receiver(struct snd_soc_codec *codec)
+{
+ if (herring_is_cdma_wimax_dev())
+ wm8994_set_cdma_voicecall_receiver(codec);
+ else
+ wm8994_set_gsm_voicecall_receiver(codec);
+}
+
+void wm8994_set_voicecall_headset(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ int val;
+
+ u16 testreturn1 = 0;
+ u16 testreturn2 = 0;
+ u16 testlow1 = 0;
+ u16 testhigh1 = 0;
+ u8 testlow = 0;
+ u8 testhigh = 0;
+
+ DEBUG_LOG("");
+
+ wm8994_earsel_control(wm8994->pdata, 1);
+
+ wm8994_set_voicecall_common_setting(codec);
+
+ /* Digital Path Enables and Unmutes */
+ if (wm8994->hw_version == 3) { /* H/W Rev D */
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING,
+ WM8994_ADC2_TO_DAC2L);
+ wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x0180);
+ wm8994_write(codec, WM8994_SIDETONE, 0x01C0);
+ } else { /* H/W Rev B */
+ wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x000C);
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING,
+ WM8994_ADC1_TO_DAC2L);
+ wm8994_write(codec, WM8994_SIDETONE, 0x01C1);
+ }
+
+ /* Analogue Input Configuration */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_2);
+ val &= ~(WM8994_TSHUT_ENA_MASK | WM8994_TSHUT_OPDIS_MASK |
+ WM8994_MIXINR_ENA_MASK | WM8994_IN1R_ENA_MASK);
+ val |= (WM8994_TSHUT_ENA | WM8994_TSHUT_OPDIS |
+ WM8994_MIXINR_ENA | WM8994_IN1R_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_2, 0x6110);
+
+ val = wm8994_read(codec, WM8994_RIGHT_LINE_INPUT_1_2_VOLUME);
+ val &= ~(WM8994_IN1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_4);
+ val &= ~(WM8994_IN1R_TO_MIXINR_MASK);
+ val |= (WM8994_IN1R_TO_MIXINR);
+ wm8994_write(codec, WM8994_INPUT_MIXER_4, val);
+
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_2);
+ val &= ~(WM8994_IN1RP_TO_IN1R_MASK | WM8994_IN1RN_TO_IN1R_MASK);
+ val |= (WM8994_IN1RP_TO_IN1R | WM8994_IN1RN_TO_IN1R);
+ wm8994_write(codec, WM8994_INPUT_MIXER_2, 0x0003);
+
+ /* Unmute*/
+ val = wm8994_read(codec, WM8994_LEFT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTL_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTL_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OPGA_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTR_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTR_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OPGA_VOLUME, val);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4, 0x2001);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, 0x56);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x56, val);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0000);
+ val = 0x0000;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, WM8994_CLASS_W_1);
+ val &= ~(0x0005);
+ val |= 0x0005;
+ wm8994_write(codec, WM8994_CLASS_W_1, val);
+
+ val = wm8994_read(codec, WM8994_LEFT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1L_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1L_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1R_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1R_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_DC_SERVO_2);
+ val &= ~(0x03E0);
+ val = 0x03E0;
+ wm8994_write(codec, WM8994_DC_SERVO_2, val);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, 0x0303);
+
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x0022);
+ wm8994_write(codec, WM8994_CHARGE_PUMP_1, 0x9F25);
+
+ msleep(5);
+
+ /* Analogue Output Configuration */
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, 0x0001);
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, 0x0001);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, 0x0030);
+
+ if (herring_is_cdma_wimax_dev())
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0009);
+ else
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0019);
+
+ if (!wm8994->dc_servo[DCS_VOICE]) {
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_SERIES_0 |
+ WM8994_DCS_TRIG_SERIES_1);
+
+ testreturn1 = wm8994_read(codec, WM8994_DC_SERVO_4);
+
+ testlow = (signed char)(testreturn1 & 0xff);
+ testhigh = (signed char)((testreturn1>>8) & 0xff);
+
+ testlow1 = ((signed short)testlow - 5) & 0x00ff;
+ testhigh1 = (((signed short)(testhigh - 5)<<8) & 0xff00);
+ testreturn2 = testlow1|testhigh1;
+ } else {
+ testreturn2 = wm8994->dc_servo[DCS_VOICE];
+ }
+
+ wm8994_write(codec, WM8994_DC_SERVO_4, testreturn2);
+
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_DAC_WR_0 | WM8994_DCS_TRIG_DAC_WR_1);
+
+ wm8994->dc_servo[DCS_VOICE] = testreturn2;
+
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x00EE);
+
+ wm8994_set_codec_gain(codec, VOICECALL_MODE, VOICECALL_HP);
+
+ /* Unmute DAC1 left */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(WM8994_DAC1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val);
+
+ /* Unmute and volume ctrl RightDAC */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(WM8994_DAC1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val);
+
+ wm8994_write(codec, WM8994_DAC2_LEFT_VOLUME, 0x01C0);
+
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, 0x0000);
+ wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, 0x0000);
+
+}
+
+void wm8994_set_voicecall_headphone(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ int val;
+
+ u16 testreturn1 = 0;
+ u16 testreturn2 = 0;
+ u16 testlow1 = 0;
+ u16 testhigh1 = 0;
+ u8 testlow = 0;
+ u8 testhigh = 0;
+
+ DEBUG_LOG("");
+ audio_ctrl_mic_bias_gpio(wm8994->pdata, 1);
+
+ wm8994_earsel_control(wm8994->pdata, 1);
+
+ wm8994_set_voicecall_common_setting(codec);
+
+ /* Digital Path Enables and Unmutes */
+ wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x000C);
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING,
+ WM8994_ADC1_TO_DAC2L);
+
+ /* Analogue Input Configuration */
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_2,
+ WM8994_TSHUT_ENA | WM8994_TSHUT_OPDIS | WM8994_MIXINL_ENA |
+ WM8994_IN1L_ENA);
+
+ /* Unmute IN1L PGA, update volume */
+ val = wm8994_read(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME);
+ val &= ~(WM8994_IN1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME, val);
+
+ /* Unmute the PGA */
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_3);
+ val &= ~(WM8994_IN1L_TO_MIXINL_MASK);
+ val |= (WM8994_IN1L_TO_MIXINL);
+ wm8994_write(codec, WM8994_INPUT_MIXER_3, val);
+
+ wm8994_write(codec, WM8994_INPUT_MIXER_2,
+ WM8994_IN1LP_TO_IN1L | WM8994_IN1LN_TO_IN1L);
+
+ /* Unmute*/
+ val = wm8994_read(codec, WM8994_LEFT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTL_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTL_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OPGA_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTR_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTR_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OPGA_VOLUME, val);
+
+ /* Digital Path Enables and Unmutes */
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4,
+ WM8994_AIF2ADCL_ENA | WM8994_ADCL_ENA);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, 0x56);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x56, val);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0000);
+ val = 0x0000;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, WM8994_CLASS_W_1);
+ val &= ~(0x0005);
+ val |= 0x0005;
+ wm8994_write(codec, WM8994_CLASS_W_1, val);
+
+ val = wm8994_read(codec, WM8994_LEFT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1L_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1L_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1R_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1R_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_DC_SERVO_2);
+ val &= ~(0x03E0);
+ val = 0x03E0;
+ wm8994_write(codec, WM8994_DC_SERVO_2, val);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, 0x0303);
+
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x0022);
+ wm8994_write(codec, WM8994_CHARGE_PUMP_1, 0x9F25);
+
+ msleep(5);
+
+ /* Analogue Output Configuration */
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, 0x0001);
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, 0x0001);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, 0x0030);
+
+ if (herring_is_cdma_wimax_dev())
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0009);
+ else
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0019);
+
+ if (!wm8994->dc_servo[DCS_VOICE]) {
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_SERIES_0 |
+ WM8994_DCS_TRIG_SERIES_1);
+
+ testreturn1 = wm8994_read(codec, WM8994_DC_SERVO_4);
+
+ testlow = (signed char)(testreturn1 & 0xff);
+ testhigh = (signed char)((testreturn1>>8) & 0xff);
+
+ testlow1 = ((signed short)testlow - 5) & 0x00ff;
+ testhigh1 = (((signed short)(testhigh - 5)<<8) & 0xff00);
+ testreturn2 = testlow1|testhigh1;
+ } else {
+ testreturn2 = wm8994->dc_servo[DCS_VOICE];
+ }
+
+ wm8994_write(codec, WM8994_DC_SERVO_4, testreturn2);
+
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_DAC_WR_0 | WM8994_DCS_TRIG_DAC_WR_1);
+
+ wm8994->dc_servo[DCS_VOICE] = testreturn2;
+
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x00EE);
+
+ wm8994_set_codec_gain(codec, VOICECALL_MODE, VOICECALL_HP_NO_MIC);
+
+ /* Unmute DAC1 left */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(WM8994_DAC1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val);
+
+ /* Unmute and volume ctrl RightDAC */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(WM8994_DAC1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val);
+
+ wm8994_write(codec, WM8994_DAC2_LEFT_VOLUME, 0x01C0);
+
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, 0x0000);
+ wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, 0x0000);
+
+}
+
+void wm8994_set_voicecall_speaker(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ int val;
+
+ DEBUG_LOG("");
+
+ audio_ctrl_mic_bias_gpio(wm8994->pdata, 1);
+
+ wm8994_set_voicecall_common_setting(codec);
+
+ wm8994_write(codec, 0x601, 0x0005);
+ wm8994_write(codec, 0x602, 0x0005);
+ wm8994_write(codec, 0x603, 0x000C);
+ /* Tx -> AIF2 Path */
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING,
+ WM8994_ADC1_TO_DAC2L);
+
+ /* Analogue Input Configuration*/
+ wm8994_write(codec, 0x02, 0x6240);
+ wm8994_write(codec, WM8994_INPUT_MIXER_2, WM8994_IN1LP_TO_IN1L |
+ WM8994_IN1LN_TO_IN1L);
+
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_3);
+ val &= ~(WM8994_IN1L_TO_MIXINL_MASK);
+ val |= (WM8994_IN1L_TO_MIXINL);
+ wm8994_write(codec, WM8994_INPUT_MIXER_3, val);
+
+ val = wm8994_read(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME);
+ val &= ~(WM8994_IN1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME, val);
+
+ /* Analogue Output Configuration*/
+ wm8994_write(codec, 0x03, 0x0300);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4,
+ WM8994_AIF2ADCL_ENA | WM8994_ADCL_ENA);
+
+ if (herring_is_cdma_wimax_dev())
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0009);
+ else
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0019);
+
+ val = wm8994_read(codec, WM8994_SPEAKER_VOLUME_LEFT);
+ val &= ~(WM8994_SPKOUTL_MUTE_N_MASK);
+ val |= (WM8994_SPKOUTL_MUTE_N);
+ wm8994_write(codec, WM8994_SPEAKER_VOLUME_LEFT, val);
+
+ val = wm8994_read(codec, WM8994_SPEAKER_VOLUME_RIGHT);
+ val &= ~(WM8994_SPKOUTR_MUTE_N_MASK | WM8994_SPKOUTR_VOL_MASK);
+ wm8994_write(codec, WM8994_SPEAKER_VOLUME_RIGHT, val);
+
+ val = wm8994_read(codec, WM8994_SPKOUT_MIXERS);
+ val &= ~(WM8994_SPKMIXL_TO_SPKOUTL_MASK |
+ WM8994_SPKMIXR_TO_SPKOUTL_MASK |
+ WM8994_SPKMIXR_TO_SPKOUTR_MASK);
+ val |= WM8994_SPKMIXL_TO_SPKOUTL;
+ wm8994_write(codec, WM8994_SPKOUT_MIXERS, val);
+
+ wm8994_write(codec, 0x36, 0x0003);
+ /* Digital Path Enables and Unmutes*/
+
+ wm8994_write(codec, WM8994_SIDETONE, 0x01C0);
+
+
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x0000);
+ wm8994_write(codec, WM8994_DC_SERVO_1, 0x0000);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1,
+ WM8994_SPKOUTL_ENA | WM8994_VMID_SEL_NORMAL | WM8994_BIAS_ENA);
+
+ wm8994_set_codec_gain(codec, VOICECALL_MODE, VOICECALL_SPK);
+
+ /* Unmute DAC1 left */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(WM8994_DAC1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val);
+
+ /* Unmute and volume ctrl RightDAC */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(WM8994_DAC1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val);
+
+ wm8994_write(codec, WM8994_DAC2_LEFT_VOLUME, 0x01C0);
+ wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, WM8994_AIF1DAC1_UNMUTE);
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, WM8994_AIF1DAC2_UNMUTE);
+}
+
+void wm8994_set_voicecall_bluetooth(struct snd_soc_codec *codec)
+{
+ int val;
+
+ DEBUG_LOG("");
+
+ wm8994_set_voicecall_common_setting(codec);
+
+ /* GPIO Configuration */
+ wm8994_write(codec, WM8994_GPIO_8, WM8994_GP8_DIR | WM8994_GP8_DB);
+ wm8994_write(codec, WM8994_GPIO_9, WM8994_GP9_DB);
+ wm8994_write(codec, WM8994_GPIO_10, WM8994_GP10_DB);
+ wm8994_write(codec, WM8994_GPIO_11, WM8994_GP11_DB);
+
+ /* Digital Path Enables and Unmutes */
+ val = wm8994_read(codec, WM8994_POWER_MANAGEMENT_1);
+ val &= ~(WM8994_SPKOUTL_ENA_MASK | WM8994_HPOUT2_ENA_MASK |
+ WM8994_HPOUT1L_ENA_MASK | WM8994_HPOUT1R_ENA_MASK);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, val);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4,
+ WM8994_AIF2ADCL_ENA | WM8994_ADCL_ENA);
+
+ /* If Input MIC is enabled, bluetooth Rx is muted. */
+ wm8994_write(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME,
+ WM8994_IN1L_MUTE);
+ wm8994_write(codec, WM8994_RIGHT_LINE_INPUT_1_2_VOLUME,
+ WM8994_IN1R_MUTE);
+ wm8994_write(codec, WM8994_INPUT_MIXER_2, 0x00);
+ wm8994_write(codec, WM8994_INPUT_MIXER_3, 0x00);
+ wm8994_write(codec, WM8994_INPUT_MIXER_4, 0x00);
+
+ /*
+ * for BT DTMF Play
+ * Rx Path: AIF2ADCDAT2 select
+ * CP(CALL) Path:GPIO5/DACDAT2 select
+ * AP(DTMF) Path: DACDAT1 select
+ * Tx Path: GPIO8/DACDAT3 select
+ */
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_6, 0x000C);
+
+ /* AIF1 & AIF2 Output is connected to DAC1 */
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING,
+ WM8994_AIF2DACL_TO_DAC2L | WM8994_AIF1DAC1L_TO_DAC2L);
+ wm8994_write(codec, WM8994_DAC2_RIGHT_MIXER_ROUTING,
+ WM8994_AIF2DACR_TO_DAC2R | WM8994_AIF1DAC1R_TO_DAC2R);
+
+ if (herring_is_cdma_wimax_dev())
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0009);
+ else
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0019);
+
+ wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x000C);
+
+ wm8994_write(codec, WM8994_DAC2_LEFT_VOLUME, 0x01C0);
+ wm8994_write(codec, WM8994_DAC2_RIGHT_VOLUME, 0x01C0);
+
+ wm8994_write(codec, WM8994_OVERSAMPLING, 0X0000);
+
+ wm8994_set_codec_gain(codec, VOICECALL_MODE, VOICECALL_BT);
+
+ /* Unmute DAC1 left */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(WM8994_DAC1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val);
+
+ /* Unmute and volume ctrl RightDAC */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(WM8994_DAC1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val);
+
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, 0x0000);
+ wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, 0x0000);
+}
+
+void wm8994_set_voicecall_tty_vco(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ int val;
+
+ u16 testreturn1 = 0;
+ u16 testreturn2 = 0;
+ u16 testlow1 = 0;
+ u16 testhigh1 = 0;
+ u8 testlow = 0;
+ u8 testhigh = 0;
+
+ DEBUG_LOG("");
+ audio_ctrl_mic_bias_gpio(wm8994->pdata, 1);
+
+ wm8994_earsel_control(wm8994->pdata, 1);
+
+ wm8994_set_voicecall_common_setting(codec);
+
+ /* Digital Path Enables and Unmutes */
+ wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x000C);
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING,
+ WM8994_ADC1_TO_DAC2L);
+
+ /* Analogue Input Configuration */
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_2,
+ WM8994_TSHUT_ENA | WM8994_TSHUT_OPDIS | WM8994_MIXINL_ENA |
+ WM8994_IN1L_ENA);
+
+ /* Unmute IN1L PGA, update volume */
+ val = wm8994_read(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME);
+ val &= ~(WM8994_IN1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME, val);
+
+ /* Unmute the PGA */
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_3);
+ val &= ~(WM8994_IN1L_TO_MIXINL_MASK);
+ val |= (WM8994_IN1L_TO_MIXINL);
+ wm8994_write(codec, WM8994_INPUT_MIXER_3, val);
+
+ wm8994_write(codec, WM8994_INPUT_MIXER_2,
+ WM8994_IN1LP_TO_IN1L | WM8994_IN1LN_TO_IN1L);
+
+ /* Unmute*/
+ val = wm8994_read(codec, WM8994_LEFT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTL_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTL_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OPGA_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTR_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTR_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OPGA_VOLUME, val);
+
+ /* Digital Path Enables and Unmutes */
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4,
+ WM8994_AIF2ADCL_ENA | WM8994_ADCL_ENA);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, 0x56);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x56, val);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0000);
+ val = 0x0000;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, WM8994_CLASS_W_1);
+ val &= ~(0x0005);
+ val |= 0x0005;
+ wm8994_write(codec, WM8994_CLASS_W_1, val);
+
+ val = wm8994_read(codec, WM8994_LEFT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1L_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1L_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1R_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1R_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_DC_SERVO_2);
+ val &= ~(0x03E0);
+ val = 0x03E0;
+ wm8994_write(codec, WM8994_DC_SERVO_2, val);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, 0x0303);
+
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x0022);
+ wm8994_write(codec, WM8994_CHARGE_PUMP_1, 0x9F25);
+
+ msleep(5);
+
+ /* Analogue Output Configuration */
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, 0x0001);
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, 0x0001);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, 0x0030);
+
+ if (herring_is_cdma_wimax_dev())
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0009);
+ else
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0019);
+
+ if (!wm8994->dc_servo[DCS_VOICE]) {
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_SERIES_0 |
+ WM8994_DCS_TRIG_SERIES_1);
+
+ testreturn1 = wm8994_read(codec, WM8994_DC_SERVO_4);
+
+ testlow = (signed char)(testreturn1 & 0xff);
+ testhigh = (signed char)((testreturn1>>8) & 0xff);
+
+ testlow1 = ((signed short)testlow - 5) & 0x00ff;
+ testhigh1 = (((signed short)(testhigh - 5)<<8) & 0xff00);
+ testreturn2 = testlow1|testhigh1;
+ } else {
+ testreturn2 = wm8994->dc_servo[DCS_VOICE];
+ }
+
+ wm8994_write(codec, WM8994_DC_SERVO_4, testreturn2);
+
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_DAC_WR_0 | WM8994_DCS_TRIG_DAC_WR_1);
+
+ wm8994->dc_servo[DCS_VOICE] = testreturn2;
+
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x00EE);
+
+ wm8994_set_codec_gain(codec, VOICECALL_MODE, VOICECALL_TTY_VCO);
+
+ /* Unmute DAC1 left */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(WM8994_DAC1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val);
+
+ /* Unmute and volume ctrl RightDAC */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(WM8994_DAC1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val);
+
+ wm8994_write(codec, WM8994_DAC2_LEFT_VOLUME, 0x01C0);
+
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, 0x0000);
+ wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, 0x0000);
+
+}
+
+void wm8994_set_voicecall_tty_hco(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ int val;
+
+ u16 testreturn1 = 0;
+ u16 testreturn2 = 0;
+ u16 testlow1 = 0;
+ u16 testhigh1 = 0;
+ u8 testlow = 0;
+ u8 testhigh = 0;
+
+ DEBUG_LOG("");
+
+ wm8994_earsel_control(wm8994->pdata, 1);
+
+ wm8994_set_voicecall_common_setting(codec);
+
+ /* Digital Path Enables and Unmutes */
+ if (wm8994->hw_version == 3) { /* H/W Rev D */
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING,
+ WM8994_ADC2_TO_DAC2L);
+ wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x0180);
+ wm8994_write(codec, WM8994_SIDETONE, 0x01C0);
+ } else { /* H/W Rev B */
+ wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x000C);
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING,
+ WM8994_ADC1_TO_DAC2L);
+ wm8994_write(codec, WM8994_SIDETONE, 0x01C1);
+ }
+
+ /* Analogue Input Configuration */
+ val = (WM8994_TSHUT_ENA | WM8994_TSHUT_OPDIS |
+ WM8994_MIXINR_ENA | WM8994_IN1R_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_2, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_LINE_INPUT_1_2_VOLUME);
+ val &= ~(WM8994_IN1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_4);
+ val &= ~(WM8994_IN1R_TO_MIXINR_MASK);
+ val |= (WM8994_IN1R_TO_MIXINR);
+ wm8994_write(codec, WM8994_INPUT_MIXER_4, val);
+
+ val = (WM8994_IN1RP_TO_IN1R | WM8994_IN1RN_TO_IN1R);
+ wm8994_write(codec, WM8994_INPUT_MIXER_2, val);
+
+ /* Unmute*/
+ val = wm8994_read(codec, WM8994_LEFT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTL_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTL_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OPGA_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTR_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTR_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OPGA_VOLUME, val);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4,
+ WM8994_AIF2ADCL_ENA | WM8994_ADCR_ENA);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, 0x56);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x56, val);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0000);
+ val = 0x0000;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, WM8994_CLASS_W_1);
+ val &= ~(0x0005);
+ val |= 0x0005;
+ wm8994_write(codec, WM8994_CLASS_W_1, val);
+
+ val = wm8994_read(codec, WM8994_LEFT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1L_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1L_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1R_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1R_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_DC_SERVO_2);
+ val &= ~(0x03E0);
+ val = 0x03E0;
+ wm8994_write(codec, WM8994_DC_SERVO_2, val);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1,
+ WM8994_HPOUT2_ENA | WM8994_VMID_SEL_NORMAL | WM8994_BIAS_ENA);
+
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x0022);
+ wm8994_write(codec, WM8994_CHARGE_PUMP_1, 0x9F25);
+
+ msleep(5);
+
+ /* Analogue Output Configuration */
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, 0x0001);
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, 0x0001);
+ wm8994_write(codec, WM8994_HPOUT2_MIXER, WM8994_MIXOUTLVOL_TO_HPOUT2 |
+ WM8994_MIXOUTRVOL_TO_HPOUT2);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3,
+ WM8994_MIXOUTLVOL_ENA | WM8994_MIXOUTRVOL_ENA |
+ WM8994_MIXOUTL_ENA | WM8994_MIXOUTR_ENA);
+
+ if (herring_is_cdma_wimax_dev())
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0009);
+ else
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0019);
+
+ if (!wm8994->dc_servo[DCS_VOICE]) {
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_SERIES_0 |
+ WM8994_DCS_TRIG_SERIES_1);
+
+ testreturn1 = wm8994_read(codec, WM8994_DC_SERVO_4);
+
+ testlow = (signed char)(testreturn1 & 0xff);
+ testhigh = (signed char)((testreturn1>>8) & 0xff);
+
+ testlow1 = ((signed short)testlow - 5) & 0x00ff;
+ testhigh1 = (((signed short)(testhigh - 5)<<8) & 0xff00);
+ testreturn2 = testlow1|testhigh1;
+ } else {
+ testreturn2 = wm8994->dc_servo[DCS_VOICE];
+ }
+
+ wm8994_write(codec, WM8994_DC_SERVO_4, testreturn2);
+
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_DAC_WR_0 | WM8994_DCS_TRIG_DAC_WR_1);
+
+ wm8994->dc_servo[DCS_VOICE] = testreturn2;
+
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x00EE);
+
+ val = wm8994_read(codec, WM8994_HPOUT2_VOLUME);
+ val &= ~(WM8994_HPOUT2_MUTE_MASK);
+ wm8994_write(codec, WM8994_HPOUT2_VOLUME, val);
+
+ wm8994_set_codec_gain(codec, VOICECALL_MODE, VOICECALL_TTY_HCO);
+
+ /* Unmute DAC1 left */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(WM8994_DAC1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val);
+
+ /* Unmute and volume ctrl RightDAC */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(WM8994_DAC1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val);
+
+ wm8994_write(codec, WM8994_DAC2_LEFT_VOLUME, 0x01C0);
+
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, 0x0000);
+ wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, 0x0000);
+
+}
+
+void wm8994_set_voicecall_tty_full(struct snd_soc_codec *codec)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+
+ int val;
+
+ u16 testreturn1 = 0;
+ u16 testreturn2 = 0;
+ u16 testlow1 = 0;
+ u16 testhigh1 = 0;
+ u8 testlow = 0;
+ u8 testhigh = 0;
+
+ DEBUG_LOG("");
+
+ wm8994_earsel_control(wm8994->pdata, 1);
+
+ wm8994_set_voicecall_common_setting(codec);
+
+ /* Digital Path Enables and Unmutes */
+ if (wm8994->hw_version == 3) { /* H/W Rev D */
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING,
+ WM8994_ADC2_TO_DAC2L);
+ wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x0180);
+ wm8994_write(codec, WM8994_SIDETONE, 0x01C0);
+ } else { /* H/W Rev B */
+ wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x000C);
+ wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING,
+ WM8994_ADC1_TO_DAC2L);
+ wm8994_write(codec, WM8994_SIDETONE, 0x01C1);
+ }
+
+ /* Analogue Input Configuration */
+ val = (WM8994_TSHUT_ENA | WM8994_TSHUT_OPDIS |
+ WM8994_MIXINR_ENA | WM8994_IN1R_ENA);
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_2, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_LINE_INPUT_1_2_VOLUME);
+ val &= ~(WM8994_IN1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_INPUT_MIXER_4);
+ val &= ~(WM8994_IN1R_TO_MIXINR_MASK);
+ val |= (WM8994_IN1R_TO_MIXINR);
+ wm8994_write(codec, WM8994_INPUT_MIXER_4, val);
+
+ val = (WM8994_IN1RP_TO_IN1R | WM8994_IN1RN_TO_IN1R);
+ wm8994_write(codec, WM8994_INPUT_MIXER_2, val);
+
+ /* Unmute*/
+ val = wm8994_read(codec, WM8994_LEFT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTL_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTL_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OPGA_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OPGA_VOLUME);
+ val &= ~(WM8994_MIXOUTR_MUTE_N_MASK);
+ val |= (WM8994_MIXOUTR_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OPGA_VOLUME, val);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_4, 0x2001);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, 0x56);
+ val &= ~(0x0003);
+ val = 0x0003;
+ wm8994_write(codec, 0x56, val);
+
+ val = wm8994_read(codec, 0x102);
+ val &= ~(0x0000);
+ val = 0x0000;
+ wm8994_write(codec, 0x102, val);
+
+ val = wm8994_read(codec, WM8994_CLASS_W_1);
+ val &= ~(0x0005);
+ val |= 0x0005;
+ wm8994_write(codec, WM8994_CLASS_W_1, val);
+
+ val = wm8994_read(codec, WM8994_LEFT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1L_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1L_MUTE_N);
+ wm8994_write(codec, WM8994_LEFT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_RIGHT_OUTPUT_VOLUME);
+ val &= ~(WM8994_HPOUT1R_MUTE_N_MASK);
+ val |= (WM8994_HPOUT1R_MUTE_N);
+ wm8994_write(codec, WM8994_RIGHT_OUTPUT_VOLUME, val);
+
+ val = wm8994_read(codec, WM8994_DC_SERVO_2);
+ val &= ~(0x03E0);
+ val = 0x03E0;
+ wm8994_write(codec, WM8994_DC_SERVO_2, val);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, 0x0303);
+
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x0022);
+ wm8994_write(codec, WM8994_CHARGE_PUMP_1, 0x9F25);
+
+ msleep(5);
+
+ /* Analogue Output Configuration */
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_1, 0x0001);
+ wm8994_write(codec, WM8994_OUTPUT_MIXER_2, 0x0001);
+
+ wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, 0x0030);
+
+ if (herring_is_cdma_wimax_dev())
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0009);
+ else
+ wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0019);
+
+ if (!wm8994->dc_servo[DCS_VOICE]) {
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_SERIES_0 |
+ WM8994_DCS_TRIG_SERIES_1);
+
+ testreturn1 = wm8994_read(codec, WM8994_DC_SERVO_4);
+
+ testlow = (signed char)(testreturn1 & 0xff);
+ testhigh = (signed char)((testreturn1>>8) & 0xff);
+
+ testlow1 = ((signed short)testlow - 5) & 0x00ff;
+ testhigh1 = (((signed short)(testhigh - 5)<<8) & 0xff00);
+ testreturn2 = testlow1|testhigh1;
+ } else {
+ testreturn2 = wm8994->dc_servo[DCS_VOICE];
+ }
+
+ wm8994_write(codec, WM8994_DC_SERVO_4, testreturn2);
+
+ wait_for_dc_servo(codec,
+ WM8994_DCS_TRIG_DAC_WR_0 | WM8994_DCS_TRIG_DAC_WR_1);
+
+ wm8994->dc_servo[DCS_VOICE] = testreturn2;
+
+ wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x00EE);
+
+ wm8994_set_codec_gain(codec, VOICECALL_MODE, VOICECALL_TTY_FULL);
+
+ /* Unmute DAC1 left */
+ val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME);
+ val &= ~(WM8994_DAC1L_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val);
+
+ /* Unmute and volume ctrl RightDAC */
+ val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME);
+ val &= ~(WM8994_DAC1R_MUTE_MASK);
+ wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val);
+
+ wm8994_write(codec, WM8994_DAC2_LEFT_VOLUME, 0x01C0);
+
+ wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, 0x0000);
+ wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, 0x0000);
+
+}
+
+int wm8994_set_codec_gain(struct snd_soc_codec *codec, u16 mode, u16 device)
+{
+ struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+ int i;
+ u32 gain_set_bits = COMMON_SET_BIT;
+ u16 val;
+ struct gain_info_t *default_gain_table_p = NULL;
+ int table_num = 0;
+
+ if (mode == PLAYBACK_MODE) {
+
+ if (herring_is_cdma_wimax_dev())
+ default_gain_table_p = cdma_playback_gain_table;
+ else
+ default_gain_table_p = playback_gain_table;
+
+ table_num = PLAYBACK_GAIN_NUM;
+
+ switch (device) {
+ case PLAYBACK_RCV:
+ gain_set_bits |= PLAYBACK_RCV;
+ break;
+ case PLAYBACK_SPK:
+ gain_set_bits |= PLAYBACK_SPK;
+ break;
+ case PLAYBACK_HP:
+ gain_set_bits |= PLAYBACK_HP;
+ break;
+ case PLAYBACK_BT:
+ gain_set_bits |= PLAYBACK_BT;
+ break;
+ case PLAYBACK_SPK_HP:
+ gain_set_bits |= PLAYBACK_SPK_HP;
+ break;
+ case PLAYBACK_RING_SPK:
+ gain_set_bits |= (PLAYBACK_SPK | PLAYBACK_RING_SPK);
+ break;
+ case PLAYBACK_RING_HP:
+ gain_set_bits |= (PLAYBACK_HP | PLAYBACK_RING_HP);
+ break;
+ case PLAYBACK_RING_SPK_HP:
+ gain_set_bits |= (PLAYBACK_SPK_HP |
+ PLAYBACK_RING_SPK_HP);
+ break;
+ case PLAYBACK_HP_NO_MIC:
+ gain_set_bits |= PLAYBACK_HP_NO_MIC;
+ break;
+ default:
+ pr_err("playback modo gain flag is wrong\n");
+ break;
+ }
+ } else if (mode == VOICECALL_MODE) {
+ if (herring_is_cdma_wimax_dev())
+ default_gain_table_p = cdma_voicecall_gain_table;
+ else
+ default_gain_table_p = voicecall_gain_table;
+ table_num = VOICECALL_GAIN_NUM;
+
+ switch (device) {
+ case VOICECALL_RCV:
+ gain_set_bits |= VOICECALL_RCV;
+ break;
+ case VOICECALL_SPK:
+ gain_set_bits |= VOICECALL_SPK;
+ break;
+ case VOICECALL_HP:
+ gain_set_bits |= VOICECALL_HP;
+ break;
+ case VOICECALL_HP_NO_MIC:
+ gain_set_bits |= VOICECALL_HP_NO_MIC;
+ break;
+ case VOICECALL_BT:
+ gain_set_bits |= VOICECALL_BT;
+ break;
+ case VOICECALL_TTY_VCO:
+ gain_set_bits |= (VOICECALL_HP_NO_MIC | VOICECALL_TTY_VCO);
+ break;
+ case VOICECALL_TTY_HCO:
+ gain_set_bits |= (VOICECALL_RCV | VOICECALL_TTY_HCO);
+ break;
+ case VOICECALL_TTY_FULL:
+ gain_set_bits |= (VOICECALL_HP | VOICECALL_TTY_FULL);
+ break;
+ default:
+ pr_err("voicemode gain flag is wrong\n");
+ }
+ } else if (mode == RECORDING_MODE) {
+ default_gain_table_p = recording_gain_table;
+ table_num = RECORDING_GAIN_NUM;
+
+ switch (device) {
+ case RECORDING_MAIN:
+ gain_set_bits |= RECORDING_MAIN;
+ break;
+ case RECORDING_HP:
+ gain_set_bits |= RECORDING_HP;
+ break;
+ case RECORDING_BT:
+ gain_set_bits |= RECORDING_BT;
+ break;
+ case RECORDING_REC_MAIN:
+ gain_set_bits |= RECORDING_REC_MAIN;
+ break;
+ case RECORDING_REC_HP:
+ gain_set_bits |= RECORDING_REC_HP;
+ break;
+ case RECORDING_REC_BT:
+ gain_set_bits |= RECORDING_REC_BT;
+ break;
+ case RECORDING_CAM_MAIN:
+ gain_set_bits |= RECORDING_CAM_MAIN;
+ break;
+ case RECORDING_CAM_HP:
+ gain_set_bits |= RECORDING_CAM_HP;
+ break;
+ case RECORDING_CAM_BT:
+ gain_set_bits |= RECORDING_CAM_BT;
+ break;
+ case RECORDING_VC_MAIN:
+ gain_set_bits |= RECORDING_VC_MAIN;
+ break;
+ case RECORDING_VC_HP:
+ gain_set_bits |= RECORDING_VC_HP;
+ break;
+ case RECORDING_VC_BT:
+ gain_set_bits |= RECORDING_VC_BT;
+ break;
+ default:
+ pr_err("recording gain flag is wrong\n");
+ }
+
+ }
+
+ DEBUG_LOG("Set gain mode = 0x%x, device = 0x%x, gain_bits = 0x%x,\
+ table_num=%d, gain_code = %d\n",
+ mode, device, gain_set_bits, table_num, wm8994->gain_code);
+
+ /* default gain table setting */
+ for (i = 0; i < table_num; i++) {
+ if ((default_gain_table_p + i)->mode & gain_set_bits) {
+ val = wm8994_read(codec, (default_gain_table_p + i)->reg);
+ val &= ~((default_gain_table_p + i)->mask);
+ val |= (default_gain_table_p + i)->gain;
+ wm8994_write(codec, (default_gain_table_p + i)->reg, val);
+ }
+ }
+
+ if (wm8994->gain_code) {
+ gain_set_bits &= ~(COMMON_SET_BIT);
+
+ switch (wm8994->gain_code) {
+ case 1:
+ gain_set_bits |= (mode | GAIN_DIVISION_BIT_1);
+ break;
+ case 2:
+ gain_set_bits |= (mode | GAIN_DIVISION_BIT_2);
+ break;
+ case 3:
+ /* eur and eur tft device are same gain values currently
+ * but gain code is different because of modem.
+ */
+ gain_set_bits |= (mode | GAIN_DIVISION_BIT_1);
+ break;
+ default:
+ DEBUG_LOG_ERR("gain_code(%d) isn't support", wm8994->gain_code);
+ return 0;
+ }
+
+ default_gain_table_p = gain_code_table;
+ table_num = GAIN_CODE_NUM;
+
+ for (i = 0; i < table_num; i++) {
+ if ((default_gain_table_p + i)->mode == gain_set_bits) {
+ val = wm8994_read(codec, (default_gain_table_p + i)->reg);
+ val &= ~((default_gain_table_p + i)->mask);
+ val |= (default_gain_table_p + i)->gain;
+ wm8994_write(codec, (default_gain_table_p + i)->reg, val);
+ }
+ }
+
+ }
+ return 0;
+
+}
+