summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorScott Peterson <speterson@nvidia.com>2013-02-25 14:24:16 -0800
committerSimone Willett <swillett@nvidia.com>2013-03-08 15:13:58 -0800
commit2a185e7a11ee3a95e3ca435588522975e5a5fc31 (patch)
tree79aedcac0cb4605e9712ec9387ede4a690d2fe49 /sound
parent583e9a2130ac6d7f557834c7145a55932077c32e (diff)
asoc: alc5640 Heaphone gain boost
Modified rt5640.c to enable greater output swing by enabling dynamic control of charge pump as well as adding headphone DC calibration and power management changes. bug 1211589 Change-Id: I8337008366fd3c647a3f58e523b933b9f5860549 Signed-off-by: Scott Peterson <speterson@nvidia.com> Reviewed-on: http://git-master/r/207350 GVS: Gerrit_Virtual_Submit Reviewed-by: Vijay Mali <vmali@nvidia.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/rt5640.c271
-rw-r--r--sound/soc/codecs/rt5640.h56
2 files changed, 311 insertions, 16 deletions
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index ce9536bce8a6..7844b54aa961 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -33,6 +33,7 @@
#define RT5640_REG_RW 1
#define RT5640_DET_EXT_MIC 0
#define RT5639_RESET_ID 0x0008
+#define USE_ONEBIT_DEPOP 1 /* for one bit depop */
#define CHECK_I2C_SHUTDOWN(r, c) { if (r && r->shutdown_complete) { \
dev_err(c->dev, "error: i2c state is 'shutdown'\n"); \
@@ -45,7 +46,7 @@ struct rt5640_init_reg {
};
static struct rt5640_init_reg init_list[] = {
- {RT5640_DUMMY1 , 0x3701},/*fa[12:13] = 1'b;fa[8~10]=1;fa[0]=1*/
+ {RT5640_GEN_CTRL1 , 0x3701},/*fa[12:13] = 1'b; fa[8~10]=1; fa[0]=1 */
{RT5640_DEPOP_M1 , 0x0019},/* 8e[4:3] = 11'b; 8e[0] = 1'b */
{RT5640_DEPOP_M2 , 0x3100},/* 8f[13] = 1'b */
{RT5640_ADDA_CLK1 , 0x1114},/* 73[2] = 1'b */
@@ -53,6 +54,7 @@ static struct rt5640_init_reg init_list[] = {
{RT5640_PRIV_INDEX , 0x003d},/* PR3d[12] = 1'b */
{RT5640_PRIV_DATA , 0x3600},
{RT5640_CLS_D_OUT , 0xa000},/* 8d[11] = 0'b */
+ {RT5640_CLS_D_OVCD , 0x0328},//8c[8] = 1'b
{RT5640_PRIV_INDEX , 0x001c},/* PR1c = 0D21'h */
{RT5640_PRIV_DATA , 0x0D21},
{RT5640_PRIV_INDEX , 0x001b},/* PR1B = 0D21'h */
@@ -74,9 +76,16 @@ static struct rt5640_init_reg init_list[] = {
{RT5640_HP_VOL , 0x8888},/* OUTMIX -> HPVOL */
{RT5640_HPO_MIXER , 0xc000},/* HPVOL -> HPOLMIX */
/* {RT5640_HPO_MIXER , 0xa000},// DAC1 -> HPOLMIX */
+ {RT5640_CHARGE_PUMP , 0x0f00},
+ {RT5640_PRIV_INDEX , 0x0090},
+ {RT5640_PRIV_DATA , 0x2000},
+ {RT5640_PRIV_INDEX , 0x0091},
+ {RT5640_PRIV_DATA , 0x1000},
+ {RT5640_HP_CALIB_AMP_DET, 0x0420},
{RT5640_SPK_L_MIXER , 0x0036},/* DACL1 -> SPKMIXL */
{RT5640_SPK_R_MIXER , 0x0036},/* DACR1 -> SPKMIXR */
{RT5640_SPK_VOL , 0x8888},/* SPKMIX -> SPKVOL */
+ {RT5640_SPO_CLSD_RATIO , 0x0001},
{RT5640_SPO_L_MIXER , 0xe800},/* SPKVOLL -> SPOLMIX */
{RT5640_SPO_R_MIXER , 0x2800},/* SPKVOLR -> SPORMIX */
/* {RT5640_SPO_L_MIXER , 0xb800},//DAC -> SPOLMIX */
@@ -167,7 +176,7 @@ static const u16 rt5640_reg[RT5640_VENDOR_ID2 + 1] = {
[RT5640_DEPOP_M1] = 0x0004,
[RT5640_DEPOP_M2] = 0x1100,
[RT5640_DEPOP_M3] = 0x0646,
- [RT5640_CHARGE_PUMP] = 0x0c00,
+ [RT5640_CHARGE_PUMP] = 0x0d00,
[RT5640_MICBIAS] = 0x3000,
[RT5640_EQ_CTRL1] = 0x2080,
[RT5640_DRC_AGC_1] = 0x2206,
@@ -182,12 +191,13 @@ static const u16 rt5640_reg[RT5640_VENDOR_ID2 + 1] = {
[RT5640_MP3_PLUS2] = 0x1c17,
[RT5640_3D_HP] = 0x8c00,
[RT5640_ADJ_HPF] = 0x2a20,
- [RT5640_HP_CALIB_AMP_DET] = 0x0400,
+ [RT5640_HP_CALIB_AMP_DET] = 0x0420,
[RT5640_SV_ZCD1] = 0x0809,
[RT5640_VENDOR_ID1] = 0x10ec,
[RT5640_VENDOR_ID2] = 0x6231,
};
+
static int rt5640_reset(struct snd_soc_codec *codec)
{
return snd_soc_write(codec, RT5640_RESET, 0);
@@ -304,6 +314,9 @@ static int rt5640_volatile_register(
case RT5640_DSP_CTRL3:
case RT5640_PGM_REG_ARR1:
case RT5640_PGM_REG_ARR3:
+ case RT5640_VENDOR_ID:
+ case RT5640_VENDOR_ID1:
+ case RT5640_VENDOR_ID2:
return 1;
default:
return 0;
@@ -424,18 +437,45 @@ static int rt5640_readable_register(
case RT5640_HP_CALIB2:
case RT5640_SV_ZCD1:
case RT5640_SV_ZCD2:
- case RT5640_DUMMY1:
- case RT5640_DUMMY2:
- case RT5640_DUMMY3:
+ case RT5640_GEN_CTRL1:
+ case RT5640_GEN_CTRL2:
+ case RT5640_GEN_CTRL3:
case RT5640_VENDOR_ID:
case RT5640_VENDOR_ID1:
case RT5640_VENDOR_ID2:
+ case RT5640_DUMMY_PR3F:
return 1;
default:
return 0;
}
}
+void DC_Calibrate(struct snd_soc_codec *codec)
+{
+ unsigned int sclk_src;
+
+ sclk_src = snd_soc_read(codec, RT5640_GLB_CLK) &
+ RT5640_SCLK_SRC_MASK;
+
+ snd_soc_update_bits(codec, RT5640_PWR_ANLG2,
+ RT5640_PWR_MB1, RT5640_PWR_MB1);
+ snd_soc_update_bits(codec, RT5640_DEPOP_M2,
+ RT5640_DEPOP_MASK, RT5640_DEPOP_MAN);
+ snd_soc_update_bits(codec, RT5640_DEPOP_M1,
+ RT5640_HP_CP_MASK | RT5640_HP_SG_MASK | RT5640_HP_CB_MASK,
+ RT5640_HP_CP_PU | RT5640_HP_SG_DIS | RT5640_HP_CB_PU);
+
+ snd_soc_update_bits(codec, RT5640_GLB_CLK,
+ RT5640_SCLK_SRC_MASK, 0x2 << RT5640_SCLK_SRC_SFT);
+
+ rt5640_index_write(codec, RT5640_HP_DCC_INT1, 0x9f00);
+ snd_soc_update_bits(codec, RT5640_PWR_ANLG2,
+ RT5640_PWR_MB1, 0);
+ snd_soc_update_bits(codec, RT5640_GLB_CLK,
+ RT5640_SCLK_SRC_MASK, sclk_src);
+}
+
+
int rt5640_headset_detect(struct snd_soc_codec *codec, int jack_insert)
{
int jack_type;
@@ -451,7 +491,7 @@ int rt5640_headset_detect(struct snd_soc_codec *codec, int jack_insert)
if (SND_SOC_BIAS_OFF == codec->dapm.bias_level) {
snd_soc_write(codec, RT5640_PWR_ANLG1, 0x2004);
snd_soc_write(codec, RT5640_MICBIAS, 0x3830);
- snd_soc_write(codec, RT5640_DUMMY1 , 0x3701);
+ snd_soc_write(codec, RT5640_GEN_CTRL1 , 0x3701);
}
sclk_src = snd_soc_read(codec, RT5640_GLB_CLK) &
RT5640_SCLK_SRC_MASK;
@@ -466,9 +506,9 @@ int rt5640_headset_detect(struct snd_soc_codec *codec, int jack_insert)
RT5640_PWR_CLK25M_MASK | RT5640_PWR_MB_MASK,
RT5640_MIC1_OVCD_EN | RT5640_MIC1_OVTH_600UA |
RT5640_PWR_MB_PU | RT5640_PWR_CLK25M_PU);
- snd_soc_update_bits(codec, RT5640_DUMMY1,
+ snd_soc_update_bits(codec, RT5640_GEN_CTRL1,
0x1, 0x1);
- msleep(150);
+ msleep(100);
if (snd_soc_read(codec, RT5640_IRQ_CTRL2) & 0x8)
jack_type = RT5640_HEADPHO_DET;
else
@@ -1266,24 +1306,225 @@ static int spk_event(struct snd_soc_dapm_widget *w,
return 0;
}
+#if USE_ONEBIT_DEPOP
+void hp_amp_power(struct snd_soc_codec *codec, int on)
+{
+ static int hp_amp_power_count;
+// printk("one bit hp_amp_power on=%d hp_amp_power_count=%d\n",on,hp_amp_power_count);
+
+ if (on) {
+ if (hp_amp_power_count <= 0) {
+ /* depop parameters */
+ snd_soc_update_bits(codec, RT5640_DEPOP_M2,
+ RT5640_DEPOP_MASK, RT5640_DEPOP_MAN);
+ snd_soc_update_bits(codec, RT5640_DEPOP_M1,
+ RT5640_HP_CP_MASK | RT5640_HP_SG_MASK | RT5640_HP_CB_MASK,
+ RT5640_HP_CP_PU | RT5640_HP_SG_DIS | RT5640_HP_CB_PU);
+ /* headphone amp power on */
+ snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
+ RT5640_PWR_FV1 | RT5640_PWR_FV2, 0);
+ msleep(5);
+ snd_soc_update_bits(codec, RT5640_PWR_VOL,
+ RT5640_PWR_HV_L | RT5640_PWR_HV_R,
+ RT5640_PWR_HV_L | RT5640_PWR_HV_R);
+ snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
+ RT5640_PWR_HP_L | RT5640_PWR_HP_R | RT5640_PWR_HA,
+ RT5640_PWR_HP_L | RT5640_PWR_HP_R | RT5640_PWR_HA);
+ snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
+ RT5640_PWR_FV1 | RT5640_PWR_FV2 ,
+ RT5640_PWR_FV1 | RT5640_PWR_FV2 );
+ }
+ hp_amp_power_count++;
+ } else {
+ hp_amp_power_count--;
+ if (hp_amp_power_count <= 0) {
+ snd_soc_update_bits(codec, RT5640_DEPOP_M1,
+ RT5640_HP_CB_MASK, RT5640_HP_CB_PD);
+ msleep(30);
+ snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
+ RT5640_PWR_HP_L | RT5640_PWR_HP_R | RT5640_PWR_HA,
+ 0);
+ snd_soc_write(codec, RT5640_DEPOP_M2, 0x3100);
+ }
+ }
+}
+
+static void rt5640_pmu_depop(struct snd_soc_codec *codec)
+{
+ hp_amp_power(codec, 1);
+ /* headphone unmute sequence */
+ snd_soc_update_bits(codec, RT5640_DEPOP_M2,
+ RT5640_DEPOP_MASK | RT5640_DIG_DP_MASK,
+ RT5640_DEPOP_AUTO | RT5640_DIG_DP_EN);
+ snd_soc_update_bits(codec, RT5640_CHARGE_PUMP,
+ RT5640_PM_HP_MASK, RT5640_PM_HP_HV);
+ snd_soc_update_bits(codec, RT5640_DEPOP_M3,
+ RT5640_CP_FQ1_MASK | RT5640_CP_FQ2_MASK | RT5640_CP_FQ3_MASK,
+ (RT5640_CP_FQ_192_KHZ << RT5640_CP_FQ1_SFT) |
+ (RT5640_CP_FQ_24_KHZ << RT5640_CP_FQ2_SFT) |
+ (RT5640_CP_FQ_192_KHZ << RT5640_CP_FQ3_SFT));
+ rt5640_index_write(codec, RT5640_MAMP_INT_REG2, 0x1c00);
+ snd_soc_update_bits(codec, RT5640_DEPOP_M1,
+ RT5640_HP_CP_MASK | RT5640_HP_SG_MASK | RT5640_HP_CO_MASK,
+ RT5640_HP_CP_PU | RT5640_HP_SG_DIS | RT5640_HP_CO_EN);
+ msleep(5);
+ snd_soc_update_bits(codec, RT5640_HP_VOL,
+ RT5640_L_MUTE | RT5640_R_MUTE, 0);
+ msleep(65);
+ //snd_soc_update_bits(codec, RT5640_HP_CALIB_AMP_DET,
+ // RT5640_HPD_PS_MASK, RT5640_HPD_PS_EN);
+}
+
+static void rt5640_pmd_depop(struct snd_soc_codec *codec)
+{
+ snd_soc_update_bits(codec, RT5640_DEPOP_M3,
+ RT5640_CP_FQ1_MASK | RT5640_CP_FQ2_MASK | RT5640_CP_FQ3_MASK,
+ (RT5640_CP_FQ_96_KHZ << RT5640_CP_FQ1_SFT) |
+ (RT5640_CP_FQ_12_KHZ << RT5640_CP_FQ2_SFT) |
+ (RT5640_CP_FQ_96_KHZ << RT5640_CP_FQ3_SFT));
+ rt5640_index_write(codec, RT5640_MAMP_INT_REG2, 0x7c00);
+ //snd_soc_update_bits(codec, RT5640_HP_CALIB_AMP_DET,
+ // RT5640_HPD_PS_MASK, RT5640_HPD_PS_DIS);
+ snd_soc_update_bits(codec, RT5640_HP_VOL,
+ RT5640_L_MUTE | RT5640_R_MUTE,
+ RT5640_L_MUTE | RT5640_R_MUTE);
+ msleep(50);
+ hp_amp_power(codec, 0);
+}
+
+#else //seq
+void hp_amp_power(struct snd_soc_codec *codec, int on)
+{
+ static int hp_amp_power_count;
+// printk("hp_amp_power on=%d hp_amp_power_count=%d\n",on,hp_amp_power_count);
+
+ if (on) {
+ if (hp_amp_power_count <= 0) {
+ /* depop parameters */
+ snd_soc_update_bits(codec, RT5640_DEPOP_M2,
+ RT5640_DEPOP_MASK, RT5640_DEPOP_MAN);
+ snd_soc_update_bits(codec, RT5640_DEPOP_M1,
+ RT5640_HP_CP_MASK | RT5640_HP_SG_MASK | RT5640_HP_CB_MASK,
+ RT5640_HP_CP_PU | RT5640_HP_SG_DIS | RT5640_HP_CB_PU);
+ /* headphone amp power on */
+ snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
+ RT5640_PWR_FV1 | RT5640_PWR_FV2 , 0);
+ snd_soc_update_bits(codec, RT5640_PWR_VOL,
+ RT5640_PWR_HV_L | RT5640_PWR_HV_R,
+ RT5640_PWR_HV_L | RT5640_PWR_HV_R);
+ snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
+ RT5640_PWR_HP_L | RT5640_PWR_HP_R | RT5640_PWR_HA | RT5640_PWR_LM,
+ RT5640_PWR_HP_L | RT5640_PWR_HP_R | RT5640_PWR_HA | RT5640_PWR_LM);
+ msleep(50);
+ snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
+ RT5640_PWR_FV1 | RT5640_PWR_FV2,
+ RT5640_PWR_FV1 | RT5640_PWR_FV2);
+ snd_soc_update_bits(codec, RT5640_CHARGE_PUMP,
+ RT5640_PM_HP_MASK, RT5640_PM_HP_HV);
+ snd_soc_update_bits(codec, RT5640_DEPOP_M1,
+ RT5640_HP_CO_MASK | RT5640_HP_SG_MASK,
+ RT5640_HP_CO_EN | RT5640_HP_SG_EN);
+ }
+ hp_amp_power_count++;
+ } else {
+ hp_amp_power_count--;
+ if (hp_amp_power_count <= 0) {
+ snd_soc_update_bits(codec, RT5640_DEPOP_M1,
+ RT5640_HP_SG_MASK | RT5640_HP_L_SMT_MASK |
+ RT5640_HP_R_SMT_MASK, RT5640_HP_SG_DIS |
+ RT5640_HP_L_SMT_DIS | RT5640_HP_R_SMT_DIS);
+ /* headphone amp power down */
+ snd_soc_update_bits(codec, RT5640_DEPOP_M1,
+ RT5640_SMT_TRIG_MASK | RT5640_HP_CD_PD_MASK |
+ RT5640_HP_CO_MASK | RT5640_HP_CP_MASK |
+ RT5640_HP_SG_MASK | RT5640_HP_CB_MASK,
+ RT5640_SMT_TRIG_DIS | RT5640_HP_CD_PD_EN |
+ RT5640_HP_CO_DIS | RT5640_HP_CP_PD |
+ RT5640_HP_SG_EN | RT5640_HP_CB_PD);
+ snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
+ RT5640_PWR_HP_L | RT5640_PWR_HP_R | RT5640_PWR_HA | RT5640_PWR_LM,
+ 0);
+ }
+ }
+}
+
+static void rt5640_pmu_depop(struct snd_soc_codec *codec)
+{
+ hp_amp_power(codec, 1);
+ /* headphone unmute sequence */
+ snd_soc_update_bits(codec, RT5640_DEPOP_M3,
+ RT5640_CP_FQ1_MASK | RT5640_CP_FQ2_MASK | RT5640_CP_FQ3_MASK,
+ (RT5640_CP_FQ_192_KHZ << RT5640_CP_FQ1_SFT) |
+ (RT5640_CP_FQ_12_KHZ << RT5640_CP_FQ2_SFT) |
+ (RT5640_CP_FQ_192_KHZ << RT5640_CP_FQ3_SFT));
+ rt5640_index_write(codec, RT5640_MAMP_INT_REG2, 0xfc00);
+ snd_soc_update_bits(codec, RT5640_DEPOP_M1,
+ RT5640_SMT_TRIG_MASK, RT5640_SMT_TRIG_EN);
+ snd_soc_update_bits(codec, RT5640_DEPOP_M1,
+ RT5640_RSTN_MASK, RT5640_RSTN_EN);
+ snd_soc_update_bits(codec, RT5640_DEPOP_M1,
+ RT5640_RSTN_MASK | RT5640_HP_L_SMT_MASK | RT5640_HP_R_SMT_MASK,
+ RT5640_RSTN_DIS | RT5640_HP_L_SMT_EN | RT5640_HP_R_SMT_EN);
+ snd_soc_update_bits(codec, RT5640_HP_VOL,
+ RT5640_L_MUTE | RT5640_R_MUTE, 0);
+ msleep(100);
+ snd_soc_update_bits(codec, RT5640_DEPOP_M1,
+ RT5640_HP_SG_MASK | RT5640_HP_L_SMT_MASK |
+ RT5640_HP_R_SMT_MASK, RT5640_HP_SG_DIS |
+ RT5640_HP_L_SMT_DIS | RT5640_HP_R_SMT_DIS);
+ msleep(20);
+}
+
+static void rt5640_pmd_depop(struct snd_soc_codec *codec)
+{
+ /* headphone mute sequence */
+ snd_soc_update_bits(codec, RT5640_DEPOP_M3,
+ RT5640_CP_FQ1_MASK | RT5640_CP_FQ2_MASK | RT5640_CP_FQ3_MASK,
+ (RT5640_CP_FQ_96_KHZ << RT5640_CP_FQ1_SFT) |
+ (RT5640_CP_FQ_12_KHZ << RT5640_CP_FQ2_SFT) |
+ (RT5640_CP_FQ_96_KHZ << RT5640_CP_FQ3_SFT));
+ rt5640_index_write(codec, RT5640_MAMP_INT_REG2, 0xfc00);
+ snd_soc_update_bits(codec, RT5640_DEPOP_M1,
+ RT5640_HP_SG_MASK, RT5640_HP_SG_EN);
+ snd_soc_update_bits(codec, RT5640_DEPOP_M1,
+ RT5640_RSTP_MASK, RT5640_RSTP_EN);
+ snd_soc_update_bits(codec, RT5640_DEPOP_M1,
+ RT5640_RSTP_MASK | RT5640_HP_L_SMT_MASK |
+ RT5640_HP_R_SMT_MASK, RT5640_RSTP_DIS |
+ RT5640_HP_L_SMT_EN | RT5640_HP_R_SMT_EN);
+ msleep(90);
+ snd_soc_update_bits(codec, RT5640_HP_VOL,
+ RT5640_L_MUTE | RT5640_R_MUTE, RT5640_L_MUTE | RT5640_R_MUTE);
+ msleep(30);
+
+ hp_amp_power(codec, 0);
+}
+#endif
+
static int hp_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
+ struct snd_soc_codec *codec = w->codec;
+
switch (event) {
case SND_SOC_DAPM_POST_PMU:
pr_info("hp_event --SND_SOC_DAPM_POST_PMU\n");
+ rt5640_pmu_depop(codec);
break;
case SND_SOC_DAPM_PRE_PMD:
- pr_info("hp_event --SND_SOC_DAPM_POST_PMD\n");
+ pr_info("hp_event --SND_SOC_DAPM_PRE_PMD\n");
+ rt5640_pmd_depop(codec);
break;
default:
return 0;
}
+
return 0;
}
+
static int rt5640_set_dmic1_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@@ -2434,10 +2675,11 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec,
RT5640_PWR_BG | RT5640_PWR_VREF2,
RT5640_PWR_VREF1 | RT5640_PWR_MB |
RT5640_PWR_BG | RT5640_PWR_VREF2);
- msleep(10);
+ msleep(5);
snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
RT5640_PWR_FV1 | RT5640_PWR_FV2,
RT5640_PWR_FV1 | RT5640_PWR_FV2);
+ snd_soc_write(codec, RT5640_GEN_CTRL1, 0x3701);
codec->cache_only = false;
codec->cache_sync = 1;
snd_soc_cache_sync(codec);
@@ -2456,6 +2698,9 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec,
snd_soc_update_bits(codec, RT5640_MONO_OUT,
RT5640_L_MUTE, RT5640_L_MUTE);
#endif
+ snd_soc_write(codec, RT5640_DEPOP_M1, 0x0004);
+ snd_soc_write(codec, RT5640_DEPOP_M2, 0x1100);
+ snd_soc_write(codec, RT5640_GEN_CTRL1, 0x3700);
snd_soc_write(codec, RT5640_PWR_DIG1, 0x0000);
snd_soc_write(codec, RT5640_PWR_DIG2, 0x0000);
snd_soc_write(codec, RT5640_PWR_VOL, 0x0000);
@@ -2504,7 +2749,7 @@ static int rt5640_probe(struct snd_soc_codec *codec)
RT5640_PWR_BG | RT5640_PWR_VREF2,
RT5640_PWR_VREF1 | RT5640_PWR_MB |
RT5640_PWR_BG | RT5640_PWR_VREF2);
- msleep(100);
+ msleep(10);
snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
RT5640_PWR_FV1 | RT5640_PWR_FV2,
RT5640_PWR_FV1 | RT5640_PWR_FV2);
@@ -2531,6 +2776,8 @@ static int rt5640_probe(struct snd_soc_codec *codec)
rt5640_register_dsp(codec);
#endif
+ DC_Calibrate(codec);
+
codec->dapm.bias_level = SND_SOC_BIAS_STANDBY;
snd_soc_add_codec_controls(codec, rt5640_snd_controls,
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h
index af48091e57b5..d99e7577c708 100644
--- a/sound/soc/codecs/rt5640.h
+++ b/sound/soc/codecs/rt5640.h
@@ -22,6 +22,8 @@
#define RT5640_HP_VOL 0x02
#define RT5640_OUTPUT 0x03
#define RT5640_MONO_OUT 0x04
+/* Dummy */
+#define RT5640_DUMMY_PR3F 0x05
/* I/O - Input */
#define RT5640_IN1_IN2 0x0d
#define RT5640_IN3_IN4 0x0e
@@ -137,13 +139,19 @@
#define RT5640_HP_CALIB2 0xd7
#define RT5640_SV_ZCD1 0xd9
#define RT5640_SV_ZCD2 0xda
-/* Dummy Register */
-#define RT5640_DUMMY1 0xfa
-#define RT5640_DUMMY2 0xfb
-#define RT5640_DUMMY3 0xfc
+/* General Control */
+#define RT5640_GEN_CTRL1 0xfa
+#define RT5640_GEN_CTRL2 0xfb
+#define RT5640_GEN_CTRL3 0xfc
/* Index of Codec Private Register definition */
+#define RT5640_BIAS_CUR1 0x12
+#define RT5640_BIAS_CUR3 0x14
+#define RT5640_CLSD_INT_REG1 0x1c
+#define RT5640_MAMP_INT_REG2 0x37
+#define RT5640_CHOP_DAC_ADC 0x3d
+#define RT5640_MIXER_INT_REG 0x3f
#define RT5640_3D_SPK 0x63
#define RT5640_WND_1 0x6c
#define RT5640_WND_2 0x6d
@@ -152,6 +160,7 @@
#define RT5640_WND_5 0x70
#define RT5640_WND_8 0x73
#define RT5640_DIP_SPK_INF 0x75
+#define RT5640_HP_DCC_INT1 0x77
#define RT5640_EQ_BW_LOP 0xa0
#define RT5640_EQ_GN_LOP 0xa1
#define RT5640_EQ_FC_BP1 0xa2
@@ -191,7 +200,9 @@
/* IN1 and IN2 Control (0x0d) */
/* IN3 and IN4 Control (0x0e) */
+#define RT5640_BST_MASK1 (0xf<<12)
#define RT5640_BST_SFT1 12
+#define RT5640_BST_MASK2 (0xf<<8)
#define RT5640_BST_SFT2 8
#define RT5640_IN_DF1 (0x1 << 7)
#define RT5640_IN_SFT1 7
@@ -1205,6 +1216,14 @@
#define RT5640_CP_FQ2_SFT 4
#define RT5640_CP_FQ3_MASK (0x7)
#define RT5640_CP_FQ3_SFT 0
+#define RT5640_CP_FQ_1_5_KHZ 0
+#define RT5640_CP_FQ_3_KHZ 1
+#define RT5640_CP_FQ_6_KHZ 2
+#define RT5640_CP_FQ_12_KHZ 3
+#define RT5640_CP_FQ_24_KHZ 4
+#define RT5640_CP_FQ_48_KHZ 5
+#define RT5640_CP_FQ_96_KHZ 6
+#define RT5640_CP_FQ_192_KHZ 7
/* HPOUT charge pump (0x91) */
#define RT5640_OSW_L_MASK (0x1 << 11)
@@ -1336,6 +1355,7 @@
#define RT5640_EQ_LPF_SFT 0
#define RT5640_EQ_LPF_DIS (0x0)
#define RT5640_EQ_LPF_EN (0x1)
+#define RT5640_EQ_CTRL_MASK (0x7f)
/* Memory Test (0xb2) */
#define RT5640_MT_MASK (0x1 << 15)
@@ -1708,6 +1728,8 @@
#define RT5640_DSP_CMD_MR (0x37) /* Memory Read */
#define RT5640_DSP_CMD_RR (0x60) /* Register Read */
#define RT5640_DSP_CMD_RW (0x68) /* Register Write */
+#define RT5640_DSP_REG_DATHI (0x26) /* High Data Addr */
+#define RT5640_DSP_REG_DATLO (0x25) /* Low Data Addr */
/* Programmable Register Array Control 1 (0xc8) */
#define RT5640_REG_SEQ_MASK (0xf << 12)
@@ -2019,6 +2041,32 @@ enum {
#define RT5640_EQ_PST_VOL_MASK (0xffff)
#define RT5640_EQ_PST_VOL_SFT 0
+/* General Control1 (0xfa) */
+#define RT5640_M_MAMIX_L (0x1 << 13)
+#define RT5640_M_MAMIX_R (0x1 << 12)
+
+/* General Control2 (0xfb) */
+#define RT5640_RXDC_SRC_MASK (0x1 << 7)
+#define RT5640_RXDC_SRC_STO (0x0 << 7)
+#define RT5640_RXDC_SRC_MONO (0x1 << 7)
+#define RT5640_RXDC_SRC_SFT (7)
+#define RT5640_RXDP2_SEL_MASK (0x1 << 3)
+#define RT5640_RXDP2_SEL_IF2 (0x0 << 3)
+#define RT5640_RXDP2_SEL_ADC (0x1 << 3)
+#define RT5640_RXDP2_SEL_SFT (3)
+
+
+/* Vendor ID (0xfd) */
+#define RT5640_VER_C 0x2
+#define RT5640_VER_D 0x3
+
+
+/* Volume Rescale */
+#define RT5640_VOL_RSCL_MAX 0x27
+#define RT5640_VOL_RSCL_RANGE 0x1F
+/* Debug String Length */
+#define RT5640_REG_DISP_LEN 10
+
#define RT5640_NO_JACK BIT(0)
#define RT5640_HEADSET_DET BIT(1)
#define RT5640_HEADPHO_DET BIT(2)