Merge remote-tracking branches 'asoc/topic/suspend', 'asoc/topic/tas2552', 'asoc/topic/tegra', 'asoc/topic/tlv320aic31xx' and 'asoc/topic/tlv320aic3x' into asoc-next
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-max98090.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-max98090.txt
index 9c7c55c..c949abc 100644
--- a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-max98090.txt
+++ b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-max98090.txt
@@ -25,6 +25,7 @@
 
 Optional properties:
 - nvidia,hp-det-gpios : The GPIO that detect headphones are plugged in
+- nvidia,mic-det-gpios : The GPIO that detect microphones are plugged in
 
 Example:
 
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
index 922006d..4c3b0af 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -1337,8 +1337,6 @@
 		}
 	}
 
-	pm860x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
 	return 0;
 
 out:
@@ -1354,7 +1352,6 @@
 
 	for (i = 3; i >= 0; i--)
 		free_irq(pm860x->irq[i], pm860x);
-	pm860x_set_bias_level(codec, SND_SOC_BIAS_OFF);
 	return 0;
 }
 
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c
index da4f758..35fbef7 100644
--- a/sound/soc/codecs/cs42l52.c
+++ b/sound/soc/codecs/cs42l52.c
@@ -946,20 +946,6 @@
 		.ops = &cs42l52_ops,
 };
 
-static int cs42l52_suspend(struct snd_soc_codec *codec)
-{
-	cs42l52_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
-	return 0;
-}
-
-static int cs42l52_resume(struct snd_soc_codec *codec)
-{
-	cs42l52_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
-	return 0;
-}
-
 static int beep_rates[] = {
 	261, 522, 585, 667, 706, 774, 889, 1000,
 	1043, 1200, 1333, 1412, 1600, 1714, 2000, 2182
@@ -1104,8 +1090,6 @@
 
 	cs42l52_init_beep(codec);
 
-	cs42l52_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
 	cs42l52->sysclk = CS42L52_DEFAULT_CLK;
 	cs42l52->config.format = CS42L52_DEFAULT_FORMAT;
 
@@ -1115,7 +1099,6 @@
 static int cs42l52_remove(struct snd_soc_codec *codec)
 {
 	cs42l52_free_beep(codec);
-	cs42l52_set_bias_level(codec, SND_SOC_BIAS_OFF);
 
 	return 0;
 }
@@ -1123,9 +1106,8 @@
 static struct snd_soc_codec_driver soc_codec_dev_cs42l52 = {
 	.probe = cs42l52_probe,
 	.remove = cs42l52_remove,
-	.suspend = cs42l52_suspend,
-	.resume = cs42l52_resume,
 	.set_bias_level = cs42l52_set_bias_level,
+	.suspend_bias_off = true,
 
 	.dapm_widgets = cs42l52_dapm_widgets,
 	.num_dapm_widgets = ARRAY_SIZE(cs42l52_dapm_widgets),
diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c
index bb74dd1..2ddc7ac 100644
--- a/sound/soc/codecs/cs42l56.c
+++ b/sound/soc/codecs/cs42l56.c
@@ -1016,20 +1016,6 @@
 		.ops = &cs42l56_ops,
 };
 
-static int cs42l56_suspend(struct snd_soc_codec *codec)
-{
-	cs42l56_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
-	return 0;
-}
-
-static int cs42l56_resume(struct snd_soc_codec *codec)
-{
-	cs42l56_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
-	return 0;
-}
-
 static int beep_freq[] = {
 	261, 522, 585, 667, 706, 774, 889, 1000,
 	1043, 1200, 1333, 1412, 1600, 1714, 2000, 2182
@@ -1168,15 +1154,12 @@
 {
 	cs42l56_init_beep(codec);
 
-	cs42l56_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
 	return 0;
 }
 
 static int cs42l56_remove(struct snd_soc_codec *codec)
 {
 	cs42l56_free_beep(codec);
-	cs42l56_set_bias_level(codec, SND_SOC_BIAS_OFF);
 
 	return 0;
 }
@@ -1184,9 +1167,8 @@
 static struct snd_soc_codec_driver soc_codec_dev_cs42l56 = {
 	.probe = cs42l56_probe,
 	.remove = cs42l56_remove,
-	.suspend = cs42l56_suspend,
-	.resume = cs42l56_resume,
 	.set_bias_level = cs42l56_set_bias_level,
+	.suspend_bias_off = true,
 
 	.dapm_widgets = cs42l56_dapm_widgets,
 	.num_dapm_widgets = ARRAY_SIZE(cs42l56_dapm_widgets),
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c
index 0e7b9eb..2f8b946 100644
--- a/sound/soc/codecs/cs42l73.c
+++ b/sound/soc/codecs/cs42l73.c
@@ -1330,25 +1330,10 @@
 	 }
 };
 
-static int cs42l73_suspend(struct snd_soc_codec *codec)
-{
-	cs42l73_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
-	return 0;
-}
-
-static int cs42l73_resume(struct snd_soc_codec *codec)
-{
-	cs42l73_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-	return 0;
-}
-
 static int cs42l73_probe(struct snd_soc_codec *codec)
 {
 	struct cs42l73_private *cs42l73 = snd_soc_codec_get_drvdata(codec);
 
-	cs42l73_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
 	/* Set Charge Pump Frequency */
 	if (cs42l73->pdata.chgfreq)
 		snd_soc_update_bits(codec, CS42L73_CPFCHC,
@@ -1362,18 +1347,10 @@
 	return 0;
 }
 
-static int cs42l73_remove(struct snd_soc_codec *codec)
-{
-	cs42l73_set_bias_level(codec, SND_SOC_BIAS_OFF);
-	return 0;
-}
-
 static struct snd_soc_codec_driver soc_codec_dev_cs42l73 = {
 	.probe = cs42l73_probe,
-	.remove = cs42l73_remove,
-	.suspend = cs42l73_suspend,
-	.resume = cs42l73_resume,
 	.set_bias_level = cs42l73_set_bias_level,
+	.suspend_bias_off = true,
 
 	.dapm_widgets = cs42l73_dapm_widgets,
 	.num_dapm_widgets = ARRAY_SIZE(cs42l73_dapm_widgets),
diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c
index fa15fa1..61b2f9a 100644
--- a/sound/soc/codecs/da732x.c
+++ b/sound/soc/codecs/da732x.c
@@ -35,7 +35,6 @@
 
 struct da732x_priv {
 	struct regmap *regmap;
-	struct snd_soc_codec *codec;
 
 	unsigned int sysclk;
 	bool pll_en;
@@ -1508,31 +1507,7 @@
 	return 0;
 }
 
-static int da732x_probe(struct snd_soc_codec *codec)
-{
-	struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = &codec->dapm;
-
-	da732x->codec = codec;
-
-	dapm->idle_bias_off = false;
-
-	da732x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
-	return 0;
-}
-
-static int da732x_remove(struct snd_soc_codec *codec)
-{
-
-	da732x_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
-	return 0;
-}
-
 static struct snd_soc_codec_driver soc_codec_dev_da732x = {
-	.probe			= da732x_probe,
-	.remove			= da732x_remove,
 	.set_bias_level		= da732x_set_bias_level,
 	.controls		= da732x_snd_controls,
 	.num_controls		= ARRAY_SIZE(da732x_snd_controls),
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c
index bcebd1a..df7c01c 100644
--- a/sound/soc/codecs/jz4740.c
+++ b/sound/soc/codecs/jz4740.c
@@ -293,41 +293,13 @@
 	regmap_update_bits(jz4740_codec->regmap, JZ4740_REG_CODEC_1,
 			JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE);
 
-	jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
 	return 0;
 }
 
-static int jz4740_codec_dev_remove(struct snd_soc_codec *codec)
-{
-	jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
-	return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-
-static int jz4740_codec_suspend(struct snd_soc_codec *codec)
-{
-	return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF);
-}
-
-static int jz4740_codec_resume(struct snd_soc_codec *codec)
-{
-	return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-}
-
-#else
-#define jz4740_codec_suspend NULL
-#define jz4740_codec_resume NULL
-#endif
-
 static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = {
 	.probe = jz4740_codec_dev_probe,
-	.remove = jz4740_codec_dev_remove,
-	.suspend = jz4740_codec_suspend,
-	.resume = jz4740_codec_resume,
 	.set_bias_level = jz4740_codec_set_bias_level,
+	.suspend_bias_off = true,
 
 	.controls = jz4740_codec_controls,
 	.num_controls = ARRAY_SIZE(jz4740_codec_controls),
diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c
index e661e84..711f550 100644
--- a/sound/soc/codecs/ml26124.c
+++ b/sound/soc/codecs/ml26124.c
@@ -565,41 +565,19 @@
 	.symmetric_rates = 1,
 };
 
-#ifdef CONFIG_PM
-static int ml26124_suspend(struct snd_soc_codec *codec)
-{
-	ml26124_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
-	return 0;
-}
-
-static int ml26124_resume(struct snd_soc_codec *codec)
-{
-	ml26124_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
-	return 0;
-}
-#else
-#define ml26124_suspend NULL
-#define ml26124_resume NULL
-#endif
-
 static int ml26124_probe(struct snd_soc_codec *codec)
 {
 	/* Software Reset */
 	snd_soc_update_bits(codec, ML26124_SW_RST, 0x01, 1);
 	snd_soc_update_bits(codec, ML26124_SW_RST, 0x01, 0);
 
-	ml26124_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
 	return 0;
 }
 
 static struct snd_soc_codec_driver soc_codec_dev_ml26124 = {
 	.probe =	ml26124_probe,
-	.suspend =	ml26124_suspend,
-	.resume =	ml26124_resume,
 	.set_bias_level = ml26124_set_bias_level,
+	.suspend_bias_off = true,
 	.dapm_widgets = ml26124_dapm_widgets,
 	.num_dapm_widgets = ARRAY_SIZE(ml26124_dapm_widgets),
 	.dapm_routes = ml26124_intercon,
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 3e9db43..6bb77d7 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -1076,26 +1076,6 @@
 	}
 }
 
-#ifdef CONFIG_SUSPEND
-static int sgtl5000_suspend(struct snd_soc_codec *codec)
-{
-	sgtl5000_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
-	return 0;
-}
-
-static int sgtl5000_resume(struct snd_soc_codec *codec)
-{
-	/* Bring the codec back up to standby to enable regulators */
-	sgtl5000_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
-	return 0;
-}
-#else
-#define sgtl5000_suspend NULL
-#define sgtl5000_resume  NULL
-#endif	/* CONFIG_SUSPEND */
-
 /*
  * sgtl5000 has 3 internal power supplies:
  * 1. VAG, normally set to vdda/2
@@ -1355,11 +1335,6 @@
 	 */
 	snd_soc_write(codec, SGTL5000_DAP_CTRL, 0);
 
-	/* leading to standby state */
-	ret = sgtl5000_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-	if (ret)
-		goto err;
-
 	return 0;
 
 err:
@@ -1376,8 +1351,6 @@
 {
 	struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
 
-	sgtl5000_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
 	regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
 						sgtl5000->supplies);
 	regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
@@ -1390,9 +1363,8 @@
 static struct snd_soc_codec_driver sgtl5000_driver = {
 	.probe = sgtl5000_probe,
 	.remove = sgtl5000_remove,
-	.suspend = sgtl5000_suspend,
-	.resume = sgtl5000_resume,
 	.set_bias_level = sgtl5000_set_bias_level,
+	.suspend_bias_off = true,
 	.controls = sgtl5000_snd_controls,
 	.num_controls = ARRAY_SIZE(sgtl5000_snd_controls),
 	.dapm_widgets = sgtl5000_dapm_widgets,
diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c
index 23b3296..f039dc8 100644
--- a/sound/soc/codecs/tas2552.c
+++ b/sound/soc/codecs/tas2552.c
@@ -78,6 +78,44 @@
 	unsigned int mclk;
 };
 
+/* Input mux controls */
+static const char *tas2552_input_texts[] = {
+	"Digital", "Analog"
+};
+
+static SOC_ENUM_SINGLE_DECL(tas2552_input_mux_enum, TAS2552_CFG_3, 7,
+			    tas2552_input_texts);
+
+static const struct snd_kcontrol_new tas2552_input_mux_control[] = {
+	SOC_DAPM_ENUM("Input selection", tas2552_input_mux_enum)
+};
+
+static const struct snd_soc_dapm_widget tas2552_dapm_widgets[] =
+{
+	SND_SOC_DAPM_INPUT("IN"),
+
+	/* MUX Controls */
+	SND_SOC_DAPM_MUX("Input selection", SND_SOC_NOPM, 0, 0,
+				tas2552_input_mux_control),
+
+	SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_OUT_DRV("ClassD", TAS2552_CFG_2, 7, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("PLL", TAS2552_CFG_2, 3, 0, NULL, 0),
+
+	SND_SOC_DAPM_OUTPUT("OUT")
+};
+
+static const struct snd_soc_dapm_route tas2552_audio_map[] = {
+	{"DAC", NULL, "DAC IN"},
+	{"Input selection", "Digital", "DAC"},
+	{"Input selection", "Analog", "IN"},
+	{"ClassD", NULL, "Input selection"},
+	{"OUT", NULL, "ClassD"},
+	{"ClassD", NULL, "PLL"},
+};
+
+#ifdef CONFIG_PM_RUNTIME
 static void tas2552_sw_shutdown(struct tas2552_data *tas_data, int sw_shutdown)
 {
 	u8 cfg1_reg;
@@ -90,6 +128,7 @@
 	snd_soc_update_bits(tas_data->codec, TAS2552_CFG_1,
 						 TAS2552_SWS_MASK, cfg1_reg);
 }
+#endif
 
 static int tas2552_hw_params(struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params,
@@ -101,10 +140,6 @@
 	int d;
 	u8 p, j;
 
-	/* Turn on Class D amplifier */
-	snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_CLASSD_EN_MASK,
-						TAS2552_CLASSD_EN);
-
 	if (!tas2552->mclk)
 		return -EINVAL;
 
@@ -147,9 +182,6 @@
 
 	}
 
-	snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE,
-						TAS2552_PLL_ENABLE);
-
 	return 0;
 }
 
@@ -269,19 +301,10 @@
 			   NULL)
 };
 
-static void tas2552_shutdown(struct snd_pcm_substream *substream,
-			   struct snd_soc_dai *dai)
-{
-	struct snd_soc_codec *codec = dai->codec;
-
-	snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE, 0);
-}
-
 static struct snd_soc_dai_ops tas2552_speaker_dai_ops = {
 	.hw_params	= tas2552_hw_params,
 	.set_sysclk	= tas2552_set_dai_sysclk,
 	.set_fmt	= tas2552_set_dai_fmt,
-	.shutdown	= tas2552_shutdown,
 	.digital_mute = tas2552_mute,
 };
 
@@ -294,7 +317,7 @@
 	{
 		.name = "tas2552-amplifier",
 		.playback = {
-			.stream_name = "Speaker",
+			.stream_name = "Playback",
 			.channels_min = 2,
 			.channels_max = 2,
 			.rates = SNDRV_PCM_RATE_8000_192000,
@@ -312,6 +335,7 @@
 static const struct snd_kcontrol_new tas2552_snd_controls[] = {
 	SOC_SINGLE_TLV("Speaker Driver Playback Volume",
 			 TAS2552_PGA_GAIN, 0, 0x1f, 1, dac_tlv),
+	SOC_DAPM_SINGLE("Playback AMP", SND_SOC_NOPM, 0, 1, 0),
 };
 
 static const struct reg_default tas2552_init_regs[] = {
@@ -321,6 +345,7 @@
 static int tas2552_codec_probe(struct snd_soc_codec *codec)
 {
 	struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_context *dapm = &codec->dapm;
 	int ret;
 
 	tas2552->codec = codec;
@@ -362,9 +387,14 @@
 		goto patch_fail;
 	}
 
-	snd_soc_write(codec, TAS2552_CFG_2, TAS2552_CLASSD_EN |
-				  TAS2552_BOOST_EN | TAS2552_APT_EN |
-				  TAS2552_LIM_EN);
+	snd_soc_write(codec, TAS2552_CFG_2, TAS2552_BOOST_EN |
+				  TAS2552_APT_EN | TAS2552_LIM_EN);
+
+	snd_soc_dapm_new_controls(dapm, tas2552_dapm_widgets,
+				ARRAY_SIZE(tas2552_dapm_widgets));
+	snd_soc_dapm_add_routes(dapm, tas2552_audio_map,
+				ARRAY_SIZE(tas2552_audio_map));
+
 	return 0;
 
 patch_fail:
diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c
index aea9e1f..145fe5b 100644
--- a/sound/soc/codecs/tlv320aic31xx.c
+++ b/sound/soc/codecs/tlv320aic31xx.c
@@ -167,13 +167,13 @@
 	struct regulator_bulk_data supplies[AIC31XX_NUM_SUPPLIES];
 	struct aic31xx_disable_nb disable_nb[AIC31XX_NUM_SUPPLIES];
 	unsigned int sysclk;
+	u8 p_div;
 	int rate_div_line;
 };
 
 struct aic31xx_rate_divs {
-	u32 mclk;
+	u32 mclk_p;
 	u32 rate;
-	u8 p_val;
 	u8 pll_j;
 	u16 pll_d;
 	u16 dosr;
@@ -186,62 +186,51 @@
 
 /* ADC dividers can be disabled by cofiguring them to 0 */
 static const struct aic31xx_rate_divs aic31xx_divs[] = {
-	/* mclk      rate  pll: p  j	 d     dosr ndac mdac  aors nadc madc */
+	/* mclk/p    rate  pll: j     d        dosr ndac mdac  aors nadc madc */
 	/* 8k rate */
-	{12000000,   8000,	1, 8, 1920,	128,  48,  2,	128,  48,  2},
-	{12000000,   8000,	1, 8, 1920,	128,  32,  3,	128,  32,  3},
-	{24000000,   8000,	2, 8, 1920,	128,  48,  2,	128,  48,  2},
-	{25000000,   8000,	2, 7, 8643,	128,  48,  2,	128,  48,  2},
+	{12000000,   8000,	8, 1920,	128,  48,  2,	128,  48,  2},
+	{12000000,   8000,	8, 1920,	128,  32,  3,	128,  32,  3},
+	{12500000,   8000,	7, 8643,	128,  48,  2,	128,  48,  2},
 	/* 11.025k rate */
-	{12000000,  11025,	1, 7, 5264,	128,  32,  2,	128,  32,  2},
-	{12000000,  11025,	1, 8, 4672,	128,  24,  3,	128,  24,  3},
-	{24000000,  11025,	2, 7, 5264,	128,  32,  2,	128,  32,  2},
-	{25000000,  11025,	2, 7, 2253,	128,  32,  2,	128,  32,  2},
+	{12000000,  11025,	7, 5264,	128,  32,  2,	128,  32,  2},
+	{12000000,  11025,	8, 4672,	128,  24,  3,	128,  24,  3},
+	{12500000,  11025,	7, 2253,	128,  32,  2,	128,  32,  2},
 	/* 16k rate */
-	{12000000,  16000,	1, 8, 1920,	128,  24,  2,	128,  24,  2},
-	{12000000,  16000,	1, 8, 1920,	128,  16,  3,	128,  16,  3},
-	{24000000,  16000,	2, 8, 1920,	128,  24,  2,	128,  24,  2},
-	{25000000,  16000,	2, 7, 8643,	128,  24,  2,	128,  24,  2},
+	{12000000,  16000,	8, 1920,	128,  24,  2,	128,  24,  2},
+	{12000000,  16000,	8, 1920,	128,  16,  3,	128,  16,  3},
+	{12500000,  16000,	7, 8643,	128,  24,  2,	128,  24,  2},
 	/* 22.05k rate */
-	{12000000,  22050,	1, 7, 5264,	128,  16,  2,	128,  16,  2},
-	{12000000,  22050,	1, 8, 4672,	128,  12,  3,	128,  12,  3},
-	{24000000,  22050,	2, 7, 5264,	128,  16,  2,	128,  16,  2},
-	{25000000,  22050,	2, 7, 2253,	128,  16,  2,	128,  16,  2},
+	{12000000,  22050,	7, 5264,	128,  16,  2,	128,  16,  2},
+	{12000000,  22050,	8, 4672,	128,  12,  3,	128,  12,  3},
+	{12500000,  22050,	7, 2253,	128,  16,  2,	128,  16,  2},
 	/* 32k rate */
-	{12000000,  32000,	1, 8, 1920,	128,  12,  2,	128,  12,  2},
-	{12000000,  32000,	1, 8, 1920,	128,   8,  3,	128,   8,  3},
-	{24000000,  32000,	2, 8, 1920,	128,  12,  2,	128,  12,  2},
-	{25000000,  32000,	2, 7, 8643,	128,  12,  2,	128,  12,  2},
+	{12000000,  32000,	8, 1920,	128,  12,  2,	128,  12,  2},
+	{12000000,  32000,	8, 1920,	128,   8,  3,	128,   8,  3},
+	{12500000,  32000,	7, 8643,	128,  12,  2,	128,  12,  2},
 	/* 44.1k rate */
-	{12000000,  44100,	1, 7, 5264,	128,   8,  2,	128,   8,  2},
-	{12000000,  44100,	1, 8, 4672,	128,   6,  3,	128,   6,  3},
-	{24000000,  44100,	2, 7, 5264,	128,   8,  2,	128,   8,  2},
-	{25000000,  44100,	2, 7, 2253,	128,   8,  2,	128,   8,  2},
+	{12000000,  44100,	7, 5264,	128,   8,  2,	128,   8,  2},
+	{12000000,  44100,	8, 4672,	128,   6,  3,	128,   6,  3},
+	{12500000,  44100,	7, 2253,	128,   8,  2,	128,   8,  2},
 	/* 48k rate */
-	{12000000,  48000,	1, 8, 1920,	128,   8,  2,	128,   8,  2},
-	{12000000,  48000,	1, 7, 6800,	 96,   5,  4,	 96,   5,  4},
-	{24000000,  48000,	2, 8, 1920,	128,   8,  2,	128,   8,  2},
-	{25000000,  48000,	2, 7, 8643,	128,   8,  2,	128,   8,  2},
+	{12000000,  48000,	8, 1920,	128,   8,  2,	128,   8,  2},
+	{12000000,  48000,	7, 6800,	 96,   5,  4,	 96,   5,  4},
+	{12500000,  48000,	7, 8643,	128,   8,  2,	128,   8,  2},
 	/* 88.2k rate */
-	{12000000,  88200,	1, 7, 5264,	 64,   8,  2,	 64,   8,  2},
-	{12000000,  88200,	1, 8, 4672,	 64,   6,  3,	 64,   6,  3},
-	{24000000,  88200,	2, 7, 5264,	 64,   8,  2,	 64,   8,  2},
-	{25000000,  88200,	2, 7, 2253,	 64,   8,  2,	 64,   8,  2},
+	{12000000,  88200,	7, 5264,	 64,   8,  2,	 64,   8,  2},
+	{12000000,  88200,	8, 4672,	 64,   6,  3,	 64,   6,  3},
+	{12500000,  88200,	7, 2253,	 64,   8,  2,	 64,   8,  2},
 	/* 96k rate */
-	{12000000,  96000,	1, 8, 1920,	 64,   8,  2,	 64,   8,  2},
-	{12000000,  96000,	1, 7, 6800,	 48,   5,  4,	 48,   5,  4},
-	{24000000,  96000,	2, 8, 1920,	 64,   8,  2,	 64,   8,  2},
-	{25000000,  96000,	2, 7, 8643,	 64,   8,  2,	 64,   8,  2},
+	{12000000,  96000,	8, 1920,	 64,   8,  2,	 64,   8,  2},
+	{12000000,  96000,	7, 6800,	 48,   5,  4,	 48,   5,  4},
+	{12500000,  96000,	7, 8643,	 64,   8,  2,	 64,   8,  2},
 	/* 176.4k rate */
-	{12000000, 176400,	1, 7, 5264,	 32,   8,  2,	 32,   8,  2},
-	{12000000, 176400,	1, 8, 4672,	 32,   6,  3,	 32,   6,  3},
-	{24000000, 176400,	2, 7, 5264,	 32,   8,  2,	 32,   8,  2},
-	{25000000, 176400,	2, 7, 2253,	 32,   8,  2,	 32,   8,  2},
+	{12000000, 176400,	7, 5264,	 32,   8,  2,	 32,   8,  2},
+	{12000000, 176400,	8, 4672,	 32,   6,  3,	 32,   6,  3},
+	{12500000, 176400,	7, 2253,	 32,   8,  2,	 32,   8,  2},
 	/* 192k rate */
-	{12000000, 192000,	1, 8, 1920,	 32,   8,  2,	 32,   8,  2},
-	{12000000, 192000,	1, 7, 6800,	 24,   5,  4,	 24,   5,  4},
-	{24000000, 192000,	2, 8, 1920,	 32,   8,  2,	 32,   8,  2},
-	{25000000, 192000,	2, 7, 8643,	 32,   8,  2,	 32,   8,  2},
+	{12000000, 192000,	8, 1920,	 32,   8,  2,	 32,   8,  2},
+	{12000000, 192000,	7, 6800,	 24,   5,  4,	 24,   5,  4},
+	{12500000, 192000,	7, 8643,	 32,   8,  2,	 32,   8,  2},
 };
 
 static const char * const ldac_in_text[] = {
@@ -692,6 +681,7 @@
 {
 	struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
 	int bclk_score = snd_soc_params_to_frame_size(params);
+	int mclk_p = aic31xx->sysclk / aic31xx->p_div;
 	int bclk_n = 0;
 	int match = -1;
 	int i;
@@ -704,7 +694,7 @@
 
 	for (i = 0; i < ARRAY_SIZE(aic31xx_divs); i++) {
 		if (aic31xx_divs[i].rate == params_rate(params) &&
-		    aic31xx_divs[i].mclk == aic31xx->sysclk) {
+		    aic31xx_divs[i].mclk_p == mclk_p) {
 			int s =	(aic31xx_divs[i].dosr * aic31xx_divs[i].mdac) %
 				snd_soc_params_to_frame_size(params);
 			int bn = (aic31xx_divs[i].dosr * aic31xx_divs[i].mdac) /
@@ -738,7 +728,7 @@
 
 	/* PLL configuration */
 	snd_soc_update_bits(codec, AIC31XX_PLLPR, AIC31XX_PLL_MASK,
-			    (aic31xx_divs[i].p_val << 4) | 0x01);
+			    (aic31xx->p_div << 4) | 0x01);
 	snd_soc_write(codec, AIC31XX_PLLJ, aic31xx_divs[i].pll_j);
 
 	snd_soc_write(codec, AIC31XX_PLLDMSB,
@@ -772,7 +762,7 @@
 	dev_dbg(codec->dev,
 		"pll %d.%04d/%d dosr %d n %d m %d aosr %d n %d m %d bclk_n %d\n",
 		aic31xx_divs[i].pll_j, aic31xx_divs[i].pll_d,
-		aic31xx_divs[i].p_val, aic31xx_divs[i].dosr,
+		aic31xx->p_div, aic31xx_divs[i].dosr,
 		aic31xx_divs[i].ndac, aic31xx_divs[i].mdac,
 		aic31xx_divs[i].aosr, aic31xx_divs[i].nadc,
 		aic31xx_divs[i].madc, bclk_n);
@@ -840,7 +830,7 @@
 {
 	struct snd_soc_codec *codec = codec_dai->codec;
 	u8 iface_reg1 = 0;
-	u8 iface_reg3 = 0;
+	u8 iface_reg2 = 0;
 	u8 dsp_a_val = 0;
 
 	dev_dbg(codec->dev, "## %s: fmt = 0x%x\n", __func__, fmt);
@@ -865,7 +855,7 @@
 		/* NOTE: BCLKINV bit value 1 equas NB and 0 equals IB */
 		switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 		case SND_SOC_DAIFMT_NB_NF:
-			iface_reg3 |= AIC31XX_BCLKINV_MASK;
+			iface_reg2 |= AIC31XX_BCLKINV_MASK;
 			break;
 		case SND_SOC_DAIFMT_IB_NF:
 			break;
@@ -897,7 +887,7 @@
 			    dsp_a_val);
 	snd_soc_update_bits(codec, AIC31XX_IFACE2,
 			    AIC31XX_BCLKINV_MASK,
-			    iface_reg3);
+			    iface_reg2);
 
 	return 0;
 }
@@ -912,7 +902,16 @@
 	dev_dbg(codec->dev, "## %s: clk_id = %d, freq = %d, dir = %d\n",
 		__func__, clk_id, freq, dir);
 
-	for (i = 0; aic31xx_divs[i].mclk != freq; i++) {
+	for (i = 1; freq/i > 20000000 && i < 8; i++)
+		;
+	if (freq/i > 20000000) {
+		dev_err(aic31xx->dev, "%s: Too high mclk frequency %u\n",
+			__func__, freq);
+			return -EINVAL;
+	}
+	aic31xx->p_div = i;
+
+	for (i = 0; aic31xx_divs[i].mclk_p != freq/aic31xx->p_div; i++) {
 		if (i == ARRAY_SIZE(aic31xx_divs)) {
 			dev_err(aic31xx->dev, "%s: Unsupported frequency %d\n",
 				__func__, freq);
diff --git a/sound/soc/codecs/tlv320aic31xx.h b/sound/soc/codecs/tlv320aic31xx.h
index 52ed57c..fe16c34 100644
--- a/sound/soc/codecs/tlv320aic31xx.h
+++ b/sound/soc/codecs/tlv320aic31xx.h
@@ -18,7 +18,8 @@
 #define AIC31XX_RATES	SNDRV_PCM_RATE_8000_192000
 
 #define AIC31XX_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
-			 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
+			 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE \
+			 | SNDRV_PCM_FMTBIT_S32_LE)
 
 
 #define AIC31XX_STEREO_CLASS_D_BIT	0x1
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index f2c416d..f7c2a57 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -1121,6 +1121,7 @@
 static int aic3x_set_power(struct snd_soc_codec *codec, int power)
 {
 	struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
+	unsigned int pll_c, pll_d;
 	int ret;
 
 	if (power) {
@@ -1138,6 +1139,18 @@
 		/* Sync reg_cache with the hardware */
 		regcache_cache_only(aic3x->regmap, false);
 		regcache_sync(aic3x->regmap);
+
+		/* Rewrite paired PLL D registers in case cached sync skipped
+		 * writing one of them and thus caused other one also not
+		 * being written
+		 */
+		pll_c = snd_soc_read(codec, AIC3X_PLL_PROGC_REG);
+		pll_d = snd_soc_read(codec, AIC3X_PLL_PROGD_REG);
+		if (pll_c == aic3x_reg[AIC3X_PLL_PROGC_REG].def ||
+			pll_d == aic3x_reg[AIC3X_PLL_PROGD_REG].def) {
+			snd_soc_write(codec, AIC3X_PLL_PROGC_REG, pll_c);
+			snd_soc_write(codec, AIC3X_PLL_PROGD_REG, pll_d);
+		}
 	} else {
 		/*
 		 * Do soft reset to this codec instance in order to clear
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index a237f16..31bb480 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -413,7 +413,6 @@
 	return 0;
 }
 #else
-#define wm8741_suspend NULL
 #define wm8741_resume NULL
 #endif
 
diff --git a/sound/soc/tegra/tegra_max98090.c b/sound/soc/tegra/tegra_max98090.c
index b86cd99..01921d7 100644
--- a/sound/soc/tegra/tegra_max98090.c
+++ b/sound/soc/tegra/tegra_max98090.c
@@ -42,6 +42,7 @@
 struct tegra_max98090 {
 	struct tegra_asoc_utils_data util_data;
 	int gpio_hp_det;
+	int gpio_mic_det;
 };
 
 static int tegra_max98090_asoc_hw_params(struct snd_pcm_substream *substream,
@@ -112,6 +113,22 @@
 	.invert = 1,
 };
 
+static struct snd_soc_jack tegra_max98090_mic_jack;
+
+static struct snd_soc_jack_pin tegra_max98090_mic_jack_pins[] = {
+	{
+		.pin = "Mic Jack",
+		.mask = SND_JACK_MICROPHONE,
+	},
+};
+
+static struct snd_soc_jack_gpio tegra_max98090_mic_jack_gpio = {
+	.name = "Mic detection",
+	.report = SND_JACK_MICROPHONE,
+	.debounce_time = 150,
+	.invert = 1,
+};
+
 static const struct snd_soc_dapm_widget tegra_max98090_dapm_widgets[] = {
 	SND_SOC_DAPM_HP("Headphones", NULL),
 	SND_SOC_DAPM_SPK("Speakers", NULL),
@@ -141,6 +158,19 @@
 					&tegra_max98090_hp_jack_gpio);
 	}
 
+	if (gpio_is_valid(machine->gpio_mic_det)) {
+		snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE,
+				 &tegra_max98090_mic_jack);
+		snd_soc_jack_add_pins(&tegra_max98090_mic_jack,
+				      ARRAY_SIZE(tegra_max98090_mic_jack_pins),
+				      tegra_max98090_mic_jack_pins);
+
+		tegra_max98090_mic_jack_gpio.gpio = machine->gpio_mic_det;
+		snd_soc_jack_add_gpios(&tegra_max98090_mic_jack,
+				       1,
+				       &tegra_max98090_mic_jack_gpio);
+	}
+
 	return 0;
 }
 
@@ -153,6 +183,11 @@
 					&tegra_max98090_hp_jack_gpio);
 	}
 
+	if (gpio_is_valid(machine->gpio_mic_det)) {
+		snd_soc_jack_free_gpios(&tegra_max98090_mic_jack, 1,
+					&tegra_max98090_mic_jack_gpio);
+	}
+
 	return 0;
 }
 
@@ -201,6 +236,11 @@
 	if (machine->gpio_hp_det == -EPROBE_DEFER)
 		return -EPROBE_DEFER;
 
+	machine->gpio_mic_det =
+			of_get_named_gpio(np, "nvidia,mic-det-gpios", 0);
+	if (machine->gpio_mic_det == -EPROBE_DEFER)
+		return -EPROBE_DEFER;
+
 	ret = snd_soc_of_parse_card_name(card, "nvidia,model");
 	if (ret)
 		goto err;