From ce35adf759aab6fcc13754eb8db020a41d531c6b Mon Sep 17 00:00:00 2001 From: Ramesh Babu K V Date: Fri, 10 Feb 2012 22:45:50 +0530 Subject: [PATCH] [PORT FROM R2]audio: sn95031: modify PCM2 enabling sequence BZ: 24696 PCM2 port enabling sequence is changed. PCM2 port is enabled after enabling the DMIC clock and other widgets. Also converted some msleep() to usleep_range() since msleeps below 20 ms are not guaranteed. Change-Id: I565172acdabd1934a50dd178e086231a659ed8bc old-Change-Id: Ic3bd318c9a10d102e2c818429e4c63eb5ff2290a Signed-off-by: Ramesh Babu K V Signed-off-by: Omair Mohammed Abdullah Reviewed-on: http://android.intel.com:8080/38989 Tested-by: Hibare, PramodX Reviewed-by: Hibare, PramodX Reviewed-by: buildbot Tested-by: buildbot --- sound/soc/codecs/sn95031.c | 68 ++++++++++++++++++++++++++-------------------- sound/soc/codecs/sn95031.h | 6 ++++ 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c index f01f069..380cdf4 100644 --- a/sound/soc/codecs/sn95031.c +++ b/sound/soc/codecs/sn95031.c @@ -154,10 +154,11 @@ static void sn95031_configure_pll(struct snd_soc_codec *codec, int operation) } static int sn95031_codec_stream_event(struct snd_soc_dapm_context *dapm, - int event) + enum snd_soc_bias_level event) { - pr_debug("%s:Event=%d\n", __func__, event); + const char *dai_name = dapm->card->dai_link->codec_dai_name; + pr_debug("%s:Event=%d\n", __func__, event); if (event == SND_SOC_DAPM_STREAM_STOP) { /* disable the MSIC PLL only if no other active streams */ if (dapm->codec->active == 0) { @@ -165,9 +166,16 @@ static int sn95031_codec_stream_event(struct snd_soc_dapm_context *dapm, /* disable PLLIN source clock */ intel_sst_set_pll(false, SST_PLL_MSIC); } + } else if (event == SND_SOC_DAPM_STREAM_START) { + /* enable pcm 2*/ + if (!strcmp(dai_name, HEADSET_DAI_NAME) + || !strcmp(dai_name, SPKR_DAI_NAME)) + snd_soc_update_bits(dapm->codec, SN95031_PCM2C2, + BIT(0), BIT(0)); } return 0; } + static int sn95031_set_vaud_bias(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { @@ -187,7 +195,7 @@ static int sn95031_set_vaud_bias(struct snd_soc_codec *codec, intel_sst_set_pll(true, SST_PLL_MSIC); /* allow few ms to stabilize the clock before enabling the MSIC PLL */ - usleep_range(5000, 6000); + usleep_range(5000, 5000); sn95031_configure_pll(codec, ENABLE_PLL); } break; @@ -197,7 +205,7 @@ static int sn95031_set_vaud_bias(struct snd_soc_codec *codec, pr_debug("vaud_bias power up rail\n"); /* power up the rail, on in normal and aoac mode */ snd_soc_write(codec, SN95031_VAUD, 0x2D); - msleep(1); + usleep_range(1000, 1000); } else if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) { pr_debug("vaud_bias standby\n"); } @@ -225,14 +233,14 @@ static int sn95031_vhs_event(struct snd_soc_dapm_widget *w, /* power up the rail- 1.8v, powersave mode */ snd_soc_write(w->codec, SN95031_VHSP, 0xED); snd_soc_write(w->codec, SN95031_VHSN, 0x2D); - msleep(1); + usleep_range(1000, 1000); } else if (SND_SOC_DAPM_EVENT_OFF(event)) { pr_debug("VHS SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n"); /* First disable VHSN and then followed by VHSP rail. Need to have minimum of 5ms delay between the rail shutdowns to avoid any glitches due to transients. */ snd_soc_write(w->codec, SN95031_VHSN, 0x24); - usleep_range(5000, 6000); + usleep_range(5000, 5000); snd_soc_write(w->codec, SN95031_VHSP, 0x24); } return 0; @@ -245,7 +253,7 @@ static int sn95031_vihf_event(struct snd_soc_dapm_widget *w, pr_debug("VIHF SND_SOC_DAPM_EVENT_ON doing rail startup now\n"); /* power up the rail */ snd_soc_write(w->codec, SN95031_VIHF, 0x2D); - msleep(1); + usleep_range(1000, 1000); } else if (SND_SOC_DAPM_EVENT_OFF(event)) { pr_debug("VIHF SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n"); snd_soc_write(w->codec, SN95031_VIHF, 0x24); @@ -256,7 +264,7 @@ static int sn95031_vihf_event(struct snd_soc_dapm_widget *w, static int sn95031_dmic12_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - unsigned int ldo = 0, clk_dir = 0, data_dir = 0, bias = 0; + unsigned int ldo = 0, clk_dir = 0, data_dir = 0, bias = 0, clk = 0; pr_debug("sn95031_dmic12_event\n"); if (SND_SOC_DAPM_EVENT_ON(event)) { @@ -265,19 +273,21 @@ static int sn95031_dmic12_event(struct snd_soc_dapm_widget *w, clk_dir = BIT(0); data_dir = BIT(7); bias = BIT(3); + clk = BIT(0); } /* program DMIC LDO, clock and set clock */ snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo); snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(0), clk_dir); snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(7), data_dir); snd_soc_update_bits(w->codec, SN95031_DMICMUX, BIT(3), bias); + snd_soc_update_bits(w->codec, SN95031_DMICLK, BIT(0), clk); return 0; } static int sn95031_dmic34_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - unsigned int ldo = 0, clk_dir = 0, data_dir = 0, bias = 0; + unsigned int ldo = 0, clk_dir = 0, data_dir = 0, bias = 0, clk = 0; pr_debug("sn95031_dmic34_event\n"); if (SND_SOC_DAPM_EVENT_ON(event)) { @@ -286,19 +296,21 @@ static int sn95031_dmic34_event(struct snd_soc_dapm_widget *w, clk_dir = BIT(2); data_dir = BIT(1); bias = BIT(4); + clk = BIT(1); } /* program DMIC LDO, clock and set clock */ snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo); snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(2), clk_dir); snd_soc_update_bits(w->codec, SN95031_DMICBUF45, BIT(1), data_dir); snd_soc_update_bits(w->codec, SN95031_DMICMUX, BIT(4), bias); + snd_soc_update_bits(w->codec, SN95031_DMICLK, BIT(1), clk); return 0; } static int sn95031_dmic56_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - unsigned int ldo = 0, clk_dir = 0, data_dir = 0, bias = 0; + unsigned int ldo = 0, clk_dir = 0, data_dir = 0, bias = 0, clk = 0; pr_debug("sn95031_dmic56_event\n"); if (SND_SOC_DAPM_EVENT_ON(event)) { @@ -307,13 +319,14 @@ static int sn95031_dmic56_event(struct snd_soc_dapm_widget *w, clk_dir = BIT(4); data_dir = BIT(3); bias = BIT(5); + clk = BIT(2); } - /* program DMIC LDO */ snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(7)|BIT(6), ldo); snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(4), clk_dir); snd_soc_update_bits(w->codec, SN95031_DMICBUF45, BIT(3), data_dir); snd_soc_update_bits(w->codec, SN95031_DMICMUX, BIT(5), bias); + snd_soc_update_bits(w->codec, SN95031_DMICLK, BIT(2), clk); return 0; } @@ -664,13 +677,13 @@ static const struct snd_soc_dapm_widget sn95031_dapm_widgets[] = { /* Dummy widget to trigger VAUDA on/off */ SND_SOC_DAPM_MICBIAS("VirtBias", SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_SUPPLY("DMIC12supply", SN95031_DMICLK, 0, 0, + SND_SOC_DAPM_SUPPLY("DMIC12supply", SND_SOC_NOPM, 0, 0, sn95031_dmic12_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_SUPPLY("DMIC34supply", SN95031_DMICLK, 1, 0, + SND_SOC_DAPM_SUPPLY("DMIC34supply", SND_SOC_NOPM, 1, 0, sn95031_dmic34_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_SUPPLY("DMIC56supply", SN95031_DMICLK, 2, 0, + SND_SOC_DAPM_SUPPLY("DMIC56supply", SND_SOC_NOPM, 2, 0, sn95031_dmic56_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_AIF_OUT("PCM2_Out", "Capture", 0, @@ -929,18 +942,18 @@ static const struct snd_soc_dapm_route sn95031_audio_map[] = { static int sn95031_pcm_hs_mute(struct snd_soc_dai *dai, int mute) { snd_soc_update_bits(dai->codec, - SN95031_HSLVOLCTRL, BIT(7), (!mute << 7)); + SN95031_HSLVOLCTRL, BIT(7), !mute << 7); snd_soc_update_bits(dai->codec, - SN95031_HSRVOLCTRL, BIT(7), (!mute << 7)); + SN95031_HSRVOLCTRL, BIT(7), !mute << 7); return 0; } static int sn95031_pcm_spkr_mute(struct snd_soc_dai *dai, int mute) { snd_soc_update_bits(dai->codec, - SN95031_IHFLVOLCTRL, BIT(7), (!mute << 7)); + SN95031_IHFLVOLCTRL, BIT(7), !mute << 7); snd_soc_update_bits(dai->codec, - SN95031_IHFRVOLCTRL, BIT(7), (!mute << 7)); + SN95031_IHFRVOLCTRL, BIT(7), !mute << 7); return 0; } @@ -962,7 +975,7 @@ static int sn95031_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, return 0; } mode = snd_soc_read(codec, SN95031_PCM1C3) >> 7; - if (!mode && (!strcmp(codec_dai->name, "SN95031 Voice"))) { + if (!mode && (!strcmp(codec_dai->name, VOICE_DAI_NAME))) { target_clk_src = SN95031_PCM1BCLK; snd_soc_write(codec, SN95031_PCM1C2, 0x04); } else { @@ -981,7 +994,7 @@ static int sn95031_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, intel_sst_set_pll(true, SST_PLL_MSIC); /* allow few ms to stabilize the clock before enabling the MSIC PLL */ - usleep_range(5000, 6000); + usleep_range(5000, 5000); sn95031_configure_pll(codec, ENABLE_PLL); } else sn95031_ctx->pll_state = PLL_ENABLE_PENDING; @@ -1022,10 +1035,7 @@ static int sn95031_codec_set_params(struct snd_soc_codec *codec, default: return -EINVAL; } - snd_soc_update_bits(codec, SN95031_PCM2C2, - BIT(4)|BIT(5), format); - /* enable pcm 2 */ - snd_soc_update_bits(codec, SN95031_PCM2C2, BIT(0), BIT(0)); + snd_soc_update_bits(codec, SN95031_PCM2C2, BIT(4)|BIT(5), format); return 0; } @@ -1170,7 +1180,7 @@ static struct snd_soc_dai_ops sn95031_voice_dai_ops = { static struct snd_soc_dai_driver sn95031_dais[] = { { - .name = "SN95031 Headset", + .name = HEADSET_DAI_NAME, .playback = { .stream_name = "Headset", .channels_min = 2, @@ -1187,7 +1197,7 @@ static struct snd_soc_dai_driver sn95031_dais[] = { }, .ops = &sn95031_headset_dai_ops, }, -{ .name = "SN95031 Speaker", +{ .name = SPKR_DAI_NAME, .playback = { .stream_name = "Speaker", .channels_min = 2, @@ -1197,7 +1207,7 @@ static struct snd_soc_dai_driver sn95031_dais[] = { }, .ops = &sn95031_speaker_dai_ops, }, -{ .name = "SN95031 Vibra1", +{ .name = VIBRA1_DAI_NAME, .playback = { .stream_name = "Vibra1", .channels_min = 1, @@ -1207,7 +1217,7 @@ static struct snd_soc_dai_driver sn95031_dais[] = { }, .ops = &sn95031_vib1_dai_ops, }, -{ .name = "SN95031 Vibra2", +{ .name = VIBRA2_DAI_NAME, .playback = { .stream_name = "Vibra2", .channels_min = 1, @@ -1218,7 +1228,7 @@ static struct snd_soc_dai_driver sn95031_dais[] = { .ops = &sn95031_vib2_dai_ops, }, { - .name = "SN95031 Voice", + .name = VOICE_DAI_NAME, .playback = { .stream_name = "Downlink", .channels_min = 1, diff --git a/sound/soc/codecs/sn95031.h b/sound/soc/codecs/sn95031.h index 3e08147..aa3b6ba 100644 --- a/sound/soc/codecs/sn95031.h +++ b/sound/soc/codecs/sn95031.h @@ -147,6 +147,12 @@ #define DISABLE_PLL 0 #define ENABLE_PLL 1 +#define HEADSET_DAI_NAME "SN95031 Headset" +#define SPKR_DAI_NAME "SN95031 Speaker" +#define VOICE_DAI_NAME "SN95031 Voice" +#define VIBRA1_DAI_NAME "SN95031 Vibra1" +#define VIBRA2_DAI_NAME "SN95031 Vibra2" + enum sn95031_pll_status { PLL_DISABLED, PLL_ENABLE_PENDING, -- 2.7.4