diff options
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r-- | sound/soc/codecs/Kconfig | 4 | ||||
-rw-r--r-- | sound/soc/codecs/Makefile | 2 | ||||
-rw-r--r-- | sound/soc/codecs/mxs-adc-codec.c | 237 | ||||
-rw-r--r-- | sound/soc/codecs/sgtl5000.c | 49 | ||||
-rw-r--r-- | sound/soc/codecs/wm8753.c | 14 | ||||
-rw-r--r-- | sound/soc/codecs/wm8753.h | 1 |
6 files changed, 219 insertions, 88 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 4362689dd639..dd28cad09934 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -17,6 +17,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_AK4104 if SPI_MASTER select SND_SOC_AK4535 if I2C select SND_SOC_CS4270 if I2C + select SND_SOC_CS42888 if I2C select SND_SOC_PCM3008 select SND_SOC_SPDIF select SND_SOC_SSM2602 if I2C @@ -90,6 +91,9 @@ config SND_SOC_CS4270_VD33_ERRATA bool depends on SND_SOC_CS4270 +config SND_SOC_CS42888 + tristate + config SND_SOC_L3 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 8add6333d7c5..8fd4da08392c 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -5,6 +5,7 @@ snd-soc-ak4104-objs := ak4104.o snd-soc-ak4535-objs := ak4535.o snd-soc-ak5702-objs := ak5702.o snd-soc-cs4270-objs := cs4270.o +snd-soc-cs42888-objs := cs42888.o snd-soc-l3-objs := l3.o snd-soc-pcm3008-objs := pcm3008.o snd-soc-spdif-objs := spdif_transciever.o @@ -50,6 +51,7 @@ obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o obj-$(CONFIG_SND_SOC_AK5702) += snd-soc-ak5702.o obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o +obj-$(CONFIG_SND_SOC_CS42888) += snd-soc-cs42888.o obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o diff --git a/sound/soc/codecs/mxs-adc-codec.c b/sound/soc/codecs/mxs-adc-codec.c index 246dab352342..f8f10619731a 100644 --- a/sound/soc/codecs/mxs-adc-codec.c +++ b/sound/soc/codecs/mxs-adc-codec.c @@ -48,6 +48,8 @@ #define BF(value, field) (((value) << BP_##field) & BM_##field) #endif +#define BM_RTC_PERSISTENT0_RELEASE_GND BF(0x2, RTC_PERSISTENT0_SPARE_ANALOG) + #define REGS_RTC_BASE (IO_ADDRESS(RTC_PHYS_ADDR)) struct mxs_codec_priv { @@ -252,6 +254,47 @@ static int dac_put_volsw(struct snd_kcontrol *kcontrol, return 0; } +static int pga_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* Prepare powering up HP and SPEAKER output */ + __raw_writel(BM_AUDIOOUT_ANACTRL_HP_HOLD_GND, + REGS_AUDIOOUT_BASE + HW_AUDIOOUT_ANACTRL_SET); + __raw_writel(BM_RTC_PERSISTENT0_RELEASE_GND, + REGS_RTC_BASE + HW_RTC_PERSISTENT0_SET); + msleep(100); + break; + case SND_SOC_DAPM_POST_PMU: + __raw_writel(BM_AUDIOOUT_ANACTRL_HP_HOLD_GND, + REGS_AUDIOOUT_BASE + HW_AUDIOOUT_ANACTRL_CLR); + break; + case SND_SOC_DAPM_POST_PMD: + __raw_writel(BM_RTC_PERSISTENT0_RELEASE_GND, + REGS_RTC_BASE + HW_RTC_PERSISTENT0_CLR); + break; + } + return 0; +} + +static int adc_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + __raw_writel(BM_RTC_PERSISTENT0_RELEASE_GND, + REGS_RTC_BASE + HW_RTC_PERSISTENT0_SET); + msleep(100); + break; + case SND_SOC_DAPM_POST_PMD: + __raw_writel(BM_RTC_PERSISTENT0_RELEASE_GND, + REGS_RTC_BASE + HW_RTC_PERSISTENT0_CLR); + break; + } + return 0; +} + static const char *mxs_codec_adc_input_sel[] = { "Mic", "Line In 1", "Head Phone", "Line In 2" }; @@ -282,8 +325,6 @@ static const struct snd_kcontrol_new mxs_snd_controls[] = { SOC_DOUBLE_R("DAC Playback Switch", DAC_VOLUME_H, DAC_VOLUME_L, 8, 0x01, 1), SOC_DOUBLE("HP Playback Volume", DAC_HPVOL_L, 8, 0, 0x7F, 1), - SOC_SINGLE("HP Playback Switch", DAC_HPVOL_H, 8, 0x1, 1), - SOC_SINGLE("Speaker Playback Switch", DAC_SPEAKERCTRL_H, 8, 0x1, 1), /* Capture Volume */ SOC_DOUBLE_R("ADC Capture Volume", @@ -310,10 +351,10 @@ SOC_DAPM_ENUM("Route", mxs_codec_enum[2]); static const struct snd_soc_dapm_widget mxs_codec_widgets[] = { - SND_SOC_DAPM_ADC("Left ADC", "Left Capture", DAC_PWRDN_L, 8, 1), - SND_SOC_DAPM_ADC("Right ADC", "Right Capture", DAC_PWRDN_H, 0, 1), + SND_SOC_DAPM_ADC_E("ADC", "Capture", DAC_PWRDN_L, 8, 1, adc_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_DAC("DAC", "Playback", DAC_PWRDN_L, 12, 1), SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0, &mxs_left_adc_controls), @@ -321,7 +362,10 @@ static const struct snd_soc_dapm_widget mxs_codec_widgets[] = { &mxs_right_adc_controls), SND_SOC_DAPM_MUX("HP Mux", SND_SOC_NOPM, 0, 0, &mxs_hp_controls), - + SND_SOC_DAPM_PGA_E("HP AMP", DAC_PWRDN_L, 0, 1, NULL, 0, pga_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA("SPEAKER AMP", DAC_PWRDN_H, 8, 1, NULL, 0), SND_SOC_DAPM_INPUT("LINE1L"), SND_SOC_DAPM_INPUT("LINE1R"), SND_SOC_DAPM_INPUT("LINE2L"), @@ -348,20 +392,23 @@ static const struct snd_soc_dapm_route intercon[] = { {"Right ADC Mux", "Head Phone", "HPR"}, /* ADC */ - {"Left ADC", NULL, "Left ADC Mux"}, - {"Right ADC", NULL, "Right ADC Mux"}, + {"ADC", NULL, "Left ADC Mux"}, + {"ADC", NULL, "Right ADC Mux"}, /* HP Mux */ {"HP Mux", "DAC Out", "DAC"}, {"HP Mux", "Line In 1", "LINE1L"}, {"HP Mux", "Line In 1", "LINE1R"}, + /* HP amp */ + {"HP AMP", NULL, "HP Mux"}, /* HP output */ - {"HPR", NULL, "HP MUX"}, - {"HPL", NULL, "HP MUX"}, + {"HPR", NULL, "HP AMP"}, + {"HPL", NULL, "HP AMP"}, /* Speaker amp */ - {"SPEAKER", NULL, "DAC"}, + {"SPEAKER AMP", NULL, "DAC"}, + {"SPEAKER", NULL, "SPEAKER AMP"}, }; static int mxs_codec_add_widgets(struct snd_soc_codec *codec) @@ -488,29 +535,84 @@ static int mxs_codec_hw_params(struct snd_pcm_substream *substream, static int mxs_codec_dig_mute(struct snd_soc_dai *dai, int mute) { + int l, r; + int ll, rr; + u32 reg, reg1, reg2; u32 dac_mask = BM_AUDIOOUT_DACVOLUME_MUTE_LEFT | BM_AUDIOOUT_DACVOLUME_MUTE_RIGHT; - u32 reg1 = 0; - u32 reg = 0; if (mute) { - reg1 = __raw_readl(REGS_AUDIOOUT_BASE + HW_AUDIOOUT_HPVOL); - reg = reg1 | BF_AUDIOOUT_HPVOL_VOL_LEFT(0x7f) | \ - BF_AUDIOOUT_HPVOL_VOL_RIGHT(0x7f); - __raw_writel(reg, REGS_AUDIOOUT_BASE + HW_AUDIOOUT_HPVOL); + reg = __raw_readl(REGS_AUDIOOUT_BASE + \ + HW_AUDIOOUT_DACVOLUME); + + reg1 = reg & ~BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT; + reg1 = reg1 & ~BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT; + + l = (reg & BM_AUDIOOUT_DACVOLUME_VOLUME_LEFT) >> + BP_AUDIOOUT_DACVOLUME_VOLUME_LEFT; + r = (reg & BM_AUDIOOUT_DACVOLUME_VOLUME_RIGHT) >> + BP_AUDIOOUT_DACVOLUME_VOLUME_RIGHT; + + /* fade out dac vol */ + while ((l > DAC_VOLUME_MIN) || (r > DAC_VOLUME_MIN)) { + l -= 0x8; + r -= 0x8; + ll = l > DAC_VOLUME_MIN ? l : DAC_VOLUME_MIN; + rr = r > DAC_VOLUME_MIN ? r : DAC_VOLUME_MIN; + reg2 = reg1 | BF_AUDIOOUT_DACVOLUME_VOLUME_LEFT(ll) + | BF_AUDIOOUT_DACVOLUME_VOLUME_RIGHT(rr); + __raw_writel(reg2, + REGS_AUDIOOUT_BASE + HW_AUDIOOUT_DACVOLUME); + msleep(1); + } __raw_writel(dac_mask, - REGS_AUDIOOUT_BASE + HW_AUDIOOUT_DACVOLUME_SET); - __raw_writel(BM_AUDIOOUT_HPVOL_MUTE, - REGS_AUDIOOUT_BASE + HW_AUDIOOUT_HPVOL_SET); - - __raw_writel(reg1, REGS_AUDIOOUT_BASE + HW_AUDIOOUT_HPVOL); - } else { + REGS_AUDIOOUT_BASE + HW_AUDIOOUT_DACVOLUME_SET); + reg = reg | dac_mask; + __raw_writel(reg, + REGS_AUDIOOUT_BASE + HW_AUDIOOUT_DACVOLUME); + } else __raw_writel(dac_mask, REGS_AUDIOOUT_BASE + HW_AUDIOOUT_DACVOLUME_CLR); - __raw_writel(BM_AUDIOOUT_HPVOL_MUTE, - REGS_AUDIOOUT_BASE + HW_AUDIOOUT_HPVOL_CLR); + + return 0; +} + +static int mxs_codec_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + pr_debug("dapm level %d\n", level); + switch (level) { + case SND_SOC_BIAS_ON: /* full On */ + if (codec->bias_level == SND_SOC_BIAS_ON) + break; + break; + + case SND_SOC_BIAS_PREPARE: /* partial On */ + if (codec->bias_level == SND_SOC_BIAS_PREPARE) + break; + /* Set Capless mode */ + __raw_writel(BM_AUDIOOUT_PWRDN_CAPLESS, + REGS_AUDIOOUT_BASE + HW_AUDIOOUT_PWRDN_CLR); + break; + + case SND_SOC_BIAS_STANDBY: /* Off, with power */ + if (codec->bias_level == SND_SOC_BIAS_STANDBY) + break; + /* Unset Capless mode */ + __raw_writel(BM_AUDIOOUT_PWRDN_CAPLESS, + REGS_AUDIOOUT_BASE + HW_AUDIOOUT_PWRDN_SET); + break; + + case SND_SOC_BIAS_OFF: /* Off, without power */ + if (codec->bias_level == SND_SOC_BIAS_OFF) + break; + /* Unset Capless mode */ + __raw_writel(BM_AUDIOOUT_PWRDN_CAPLESS, + REGS_AUDIOOUT_BASE + HW_AUDIOOUT_PWRDN_SET); + break; } + codec->bias_level = level; return 0; } @@ -533,6 +635,58 @@ static void mxs_codec_dac_set_vag(void) __raw_writel(refctrl_val, REGS_AUDIOOUT_BASE + HW_AUDIOOUT_REFCTRL); } +static bool mxs_codec_dac_is_capless() +{ + if ((__raw_readl(REGS_AUDIOOUT_BASE + HW_AUDIOOUT_PWRDN) + & BM_AUDIOOUT_PWRDN_CAPLESS) == 0) + return false; + else + return true; +} +static void mxs_codec_dac_arm_short_cm(bool bShort) +{ + __raw_writel(BF(3, AUDIOOUT_ANACTRL_SHORTMODE_CM), + REGS_AUDIOOUT_BASE + HW_AUDIOOUT_ANACTRL_CLR); + __raw_writel(BM_AUDIOOUT_ANACTRL_SHORT_CM_STS, + REGS_AUDIOOUT_BASE + HW_AUDIOOUT_ANACTRL_CLR); + if (bShort) + __raw_writel(BF(1, AUDIOOUT_ANACTRL_SHORTMODE_CM), + REGS_AUDIOOUT_BASE + HW_AUDIOOUT_ANACTRL_SET); +} +static void mxs_codec_dac_arm_short_lr(bool bShort) +{ + __raw_writel(BF(3, AUDIOOUT_ANACTRL_SHORTMODE_LR), + REGS_AUDIOOUT_BASE + HW_AUDIOOUT_ANACTRL_CLR); + __raw_writel(BM_AUDIOOUT_ANACTRL_SHORT_LR_STS, + REGS_AUDIOOUT_BASE + HW_AUDIOOUT_ANACTRL_CLR); + if (bShort) + __raw_writel(BF(1, AUDIOOUT_ANACTRL_SHORTMODE_LR), + REGS_AUDIOOUT_BASE + HW_AUDIOOUT_ANACTRL_SET); +} +static void mxs_codec_dac_set_short_trip_level(u8 u8level) +{ + __raw_writel(__raw_readl(REGS_AUDIOOUT_BASE + + HW_AUDIOOUT_ANACTRL) + & (~BM_AUDIOOUT_ANACTRL_SHORT_LVLADJL) + & (~BM_AUDIOOUT_ANACTRL_SHORT_LVLADJR) + | BF(u8level, AUDIOOUT_ANACTRL_SHORT_LVLADJL) + | BF(u8level, AUDIOOUT_ANACTRL_SHORT_LVLADJR), + REGS_AUDIOOUT_BASE + HW_AUDIOOUT_ANACTRL); +} +static void mxs_codec_dac_arm_short(bool bLatchCM, bool bLatchLR) +{ + if (bLatchCM) { + if (mxs_codec_dac_is_capless()) + mxs_codec_dac_arm_short_cm(true); + } else + mxs_codec_dac_arm_short_cm(false); + + if (bLatchLR) + mxs_codec_dac_arm_short_lr(true); + else + mxs_codec_dac_arm_short_lr(false); + +} static void mxs_codec_dac_power_on(struct mxs_codec_priv *mxs_adc) { @@ -542,17 +696,13 @@ mxs_codec_dac_power_on(struct mxs_codec_priv *mxs_adc) __raw_writel(BM_AUDIOOUT_ANACLKCTRL_CLKGATE, REGS_AUDIOOUT_BASE + HW_AUDIOOUT_ANACLKCTRL_CLR); - /* Set capless mode */ - __raw_writel(BM_AUDIOOUT_PWRDN_CAPLESS, REGS_AUDIOOUT_BASE - + HW_AUDIOOUT_PWRDN_CLR); - /* 16 bit word length */ __raw_writel(BM_AUDIOOUT_CTRL_WORD_LENGTH, REGS_AUDIOOUT_BASE + HW_AUDIOOUT_CTRL_SET); - /* Powerup DAC */ - __raw_writel(BM_AUDIOOUT_PWRDN_DAC, - REGS_AUDIOOUT_BASE + HW_AUDIOOUT_PWRDN_CLR); + /* Arm headphone LR short protect */ + mxs_codec_dac_set_short_trip_level(0); + mxs_codec_dac_arm_short(false, true); /* Update DAC volume over zero crossings */ __raw_writel(BM_AUDIOOUT_DACVOLUME_EN_ZCD, @@ -566,30 +716,26 @@ mxs_codec_dac_power_on(struct mxs_codec_priv *mxs_adc) __raw_writel(BM_AUDIOOUT_HPVOL_EN_MSTR_ZCD, REGS_AUDIOOUT_BASE + HW_AUDIOOUT_HPVOL_SET); - /* Prepare powering up HP output */ - __raw_writel(BM_AUDIOOUT_ANACTRL_HP_HOLD_GND, - REGS_AUDIOOUT_BASE + HW_AUDIOOUT_ANACTRL_SET); - __raw_writel(BF(0x2, RTC_PERSISTENT0_SPARE_ANALOG), - REGS_RTC_BASE + HW_RTC_PERSISTENT0_SET); - __raw_writel(BM_AUDIOOUT_PWRDN_HEADPHONE, - REGS_AUDIOOUT_BASE + HW_AUDIOOUT_PWRDN_CLR); __raw_writel(BM_AUDIOOUT_ANACTRL_HP_CLASSAB, REGS_AUDIOOUT_BASE + HW_AUDIOOUT_ANACTRL_SET); - __raw_writel(BM_AUDIOOUT_ANACTRL_HP_HOLD_GND, - REGS_AUDIOOUT_BASE + HW_AUDIOOUT_ANACTRL_CLR); + /* Mute HP output */ __raw_writel(BM_AUDIOOUT_HPVOL_MUTE, REGS_AUDIOOUT_BASE + HW_AUDIOOUT_HPVOL_SET); - __raw_writel(BM_AUDIOOUT_PWRDN_SPEAKER, - REGS_AUDIOOUT_BASE + HW_AUDIOOUT_PWRDN_CLR); /* Mute speaker amp */ __raw_writel(BM_AUDIOOUT_SPEAKERCTRL_MUTE, REGS_AUDIOOUT_BASE + HW_AUDIOOUT_SPEAKERCTRL_SET); + /* Enable the audioout */ + __raw_writel(BM_AUDIOOUT_CTRL_RUN, + REGS_AUDIOOUT_BASE + HW_AUDIOOUT_CTRL_SET); } static void mxs_codec_dac_power_down(struct mxs_codec_priv *mxs_adc) { + /* Disable the audioout */ + __raw_writel(BM_AUDIOOUT_CTRL_RUN, + REGS_AUDIOOUT_BASE + HW_AUDIOOUT_CTRL_CLR); /* Disable class AB */ __raw_writel(BM_AUDIOOUT_ANACTRL_HP_CLASSAB, REGS_AUDIOOUT_BASE + HW_AUDIOOUT_ANACTRL_CLR); @@ -858,7 +1004,8 @@ static int mxs_codec_probe(struct platform_device *pdev) snd_soc_free_pcms(socdev); return ret; } - + /* Set default bias level*/ + mxs_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY); return 0; } @@ -982,6 +1129,8 @@ static int __init mxs_codec_audio_probe(struct platform_device *pdev) codec->private_data = mxs_adc; codec->read = mxs_codec_read; codec->write = mxs_codec_write; + codec->bias_level = SND_SOC_BIAS_OFF; + codec->set_bias_level = mxs_codec_set_bias_level; codec->dai = &mxs_codec_dai; codec->num_dai = 1; codec->reg_cache_size = sizeof(mxs_audio_regs) >> 1; diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index a63b65cdc04d..9bea4d8a523d 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -200,39 +200,6 @@ static void dump_reg(struct snd_soc_codec *codec) } #endif -static int dac_mux_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); - struct snd_soc_codec *codec = widget->codec; - unsigned int reg; - - if (ucontrol->value.enumerated.item[0]) { - reg = sgtl5000_read(codec, SGTL5000_CHIP_CLK_TOP_CTRL); - reg |= SGTL5000_INT_OSC_EN; - sgtl5000_write(codec, SGTL5000_CHIP_CLK_TOP_CTRL, reg); - - if (codec->bias_level != SND_SOC_BIAS_ON) { - sgtl5000_set_bias_level(codec, SND_SOC_BIAS_PREPARE); - snd_soc_dapm_put_enum_double(kcontrol, ucontrol); - sgtl5000_set_bias_level(codec, SND_SOC_BIAS_ON); - } else - snd_soc_dapm_put_enum_double(kcontrol, ucontrol); - - reg = sgtl5000_read(codec, SGTL5000_CHIP_ANA_CTRL); - reg &= ~(SGTL5000_LINE_OUT_MUTE | SGTL5000_HP_MUTE); - sgtl5000_write(codec, SGTL5000_CHIP_ANA_CTRL, reg); - } else { - reg = sgtl5000_read(codec, SGTL5000_CHIP_CLK_TOP_CTRL); - reg &= ~SGTL5000_INT_OSC_EN; - sgtl5000_write(codec, SGTL5000_CHIP_CLK_TOP_CTRL, reg); - - snd_soc_dapm_put_enum_double(kcontrol, ucontrol); - sgtl5000_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - } - return 0; -} - static const char *adc_mux_text[] = { "MIC_IN", "LINE_IN" }; @@ -250,16 +217,8 @@ SOC_ENUM_SINGLE(SGTL5000_CHIP_ANA_CTRL, 6, 2, dac_mux_text); static const struct snd_kcontrol_new adc_mux = SOC_DAPM_ENUM("ADC Mux", adc_enum); -static const struct snd_kcontrol_new dac_mux = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "DAC Mux", - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE - | SNDRV_CTL_ELEM_ACCESS_VOLATILE, - .info = snd_soc_info_enum_double, - .get = snd_soc_dapm_get_enum_double, - .put = dac_mux_put, - .private_value = (unsigned long)&dac_enum, -}; +static const struct snd_kcontrol_new dac_mux = +SOC_DAPM_ENUM("DAC Mux", dac_enum); static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = { SND_SOC_DAPM_INPUT("LINE_IN"), @@ -649,6 +608,8 @@ static int sgtl5000_pcm_hw_params(struct snd_pcm_substream *substream, fs = sgtl5000->lrclk; /* SGTL5000 rev1 has a IC bug to prevent switching to MCLK from PLL. */ if (!sgtl5000->master) { + sys_fs = sgtl5000->lrclk; + clk_ctl = SGTL5000_RATE_MODE_DIV_1 << SGTL5000_RATE_MODE_SHIFT; if (fs * 256 == sgtl5000->sysclk) clk_ctl |= SGTL5000_MCLK_FREQ_256FS << \ SGTL5000_MCLK_FREQ_SHIFT; @@ -783,7 +744,7 @@ static int sgtl5000_set_bias_level(struct snd_soc_codec *codec, avoid pops. */ reg = sgtl5000_read(codec, SGTL5000_CHIP_ANA_POWER); if (reg & SGTL5000_VAG_POWERUP) - delay = 400; + delay = 600; reg &= ~SGTL5000_VAG_POWERUP; reg |= SGTL5000_DAC_POWERUP; reg |= SGTL5000_HP_POWERUP; diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index 921932ab2d3a..7b3963461234 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -595,6 +595,7 @@ static const struct snd_soc_dapm_route audio_map[] = { /* Mono Capture mixer-mux */ {"Capture Right Mixer", "Stereo", "Capture Right Mux"}, + {"Capture Left Mixer", "Stereo", "Capture Left Mux"}, {"Capture Left Mixer", "Analogue Mix Left", "Capture Left Mux"}, {"Capture Left Mixer", "Analogue Mix Left", "Capture Right Mux"}, {"Capture Right Mixer", "Analogue Mix Right", "Capture Left Mux"}, @@ -1265,6 +1266,13 @@ static int wm8753_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_ON: /* set vmid to 50k and unmute dac */ wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x00c0); + + /* wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x00c0); */ + /* + * Force the enable of the MICBIAS, otherwise the microphone will not + * work. + */ + wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x00e0); break; case SND_SOC_BIAS_PREPARE: /* set vmid to 5k for quick power up */ @@ -1702,6 +1710,12 @@ static int wm8753_register(struct wm8753_priv *wm8753) wm8753_codec = codec; + /* Configure bclk as mclk/4 */ + reg = wm8753_read_reg_cache(codec, WM8753_SRATE2); + reg &= ~WM8753_BCLK_DIV_MASK; + reg |= WM8753_BCLK_DIV_4; + wm8753_write(codec, WM8753_SRATE2, reg); + for (i = 0; i < ARRAY_SIZE(wm8753_dai); i++) wm8753_dai[i].dev = codec->dev; diff --git a/sound/soc/codecs/wm8753.h b/sound/soc/codecs/wm8753.h index 57b2ba244040..40c55ad713aa 100644 --- a/sound/soc/codecs/wm8753.h +++ b/sound/soc/codecs/wm8753.h @@ -99,6 +99,7 @@ #define WM8753_PCM_DIV_8 (7 << 6) /* BCLK clock dividers */ +#define WM8753_BCLK_DIV_MASK (7 << 3) #define WM8753_BCLK_DIV_1 (0 << 3) #define WM8753_BCLK_DIV_2 (1 << 3) #define WM8753_BCLK_DIV_4 (2 << 3) |