summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/sound/nvidia,tegra-audio-max98090.txt1
-rw-r--r--sound/soc/codecs/88pm860x-codec.c3
-rw-r--r--sound/soc/codecs/cs42l52.c20
-rw-r--r--sound/soc/codecs/cs42l56.c20
-rw-r--r--sound/soc/codecs/cs42l73.c25
-rw-r--r--sound/soc/codecs/da732x.c25
-rw-r--r--sound/soc/codecs/jz4740.c30
-rw-r--r--sound/soc/codecs/ml26124.c24
-rw-r--r--sound/soc/codecs/sgtl5000.c30
-rw-r--r--sound/soc/codecs/tas2552.c70
-rw-r--r--sound/soc/codecs/tlv320aic31xx.c107
-rw-r--r--sound/soc/codecs/tlv320aic31xx.h3
-rw-r--r--sound/soc/codecs/tlv320aic3x.c13
-rw-r--r--sound/soc/codecs/wm8741.c1
-rw-r--r--sound/soc/tegra/tegra_max98090.c40
15 files changed, 165 insertions, 247 deletions
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-max98090.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-max98090.txt
index 9c7c55c7137..c949abc2992 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 @@ Required properties:
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 922006dd058..4c3b0af39fd 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -1337,8 +1337,6 @@ static int pm860x_probe(struct snd_soc_codec *codec)
}
}
- pm860x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
return 0;
out:
@@ -1354,7 +1352,6 @@ static int pm860x_remove(struct snd_soc_codec *codec)
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 da4f758cd12..35fbef743fb 100644
--- a/sound/soc/codecs/cs42l52.c
+++ b/sound/soc/codecs/cs42l52.c
@@ -946,20 +946,6 @@ static struct snd_soc_dai_driver cs42l52_dai = {
.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 @@ static int cs42l52_probe(struct snd_soc_codec *codec)
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_probe(struct snd_soc_codec *codec)
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 int cs42l52_remove(struct snd_soc_codec *codec)
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 bb74dd17fa2..2ddc7ac10ad 100644
--- a/sound/soc/codecs/cs42l56.c
+++ b/sound/soc/codecs/cs42l56.c
@@ -1016,20 +1016,6 @@ static struct snd_soc_dai_driver cs42l56_dai = {
.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 @@ static int cs42l56_probe(struct snd_soc_codec *codec)
{
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 int cs42l56_remove(struct snd_soc_codec *codec)
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 0e7b9eb2ba6..2f8b94683e8 100644
--- a/sound/soc/codecs/cs42l73.c
+++ b/sound/soc/codecs/cs42l73.c
@@ -1330,25 +1330,10 @@ static struct snd_soc_dai_driver cs42l73_dai[] = {
}
};
-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 @@ static int cs42l73_probe(struct snd_soc_codec *codec)
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 fa15fa1c051..61b2f9a2eef 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 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec,
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 bcebd1a9ce3..df7c01cf707 100644
--- a/sound/soc/codecs/jz4740.c
+++ b/sound/soc/codecs/jz4740.c
@@ -293,41 +293,13 @@ static int jz4740_codec_dev_probe(struct snd_soc_codec *codec)
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 e661e8420e3..711f5503952 100644
--- a/sound/soc/codecs/ml26124.c
+++ b/sound/soc/codecs/ml26124.c
@@ -565,41 +565,19 @@ static struct snd_soc_dai_driver ml26124_dai = {
.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 3e9db43ed76..6bb77d76561 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -1076,26 +1076,6 @@ static bool sgtl5000_readable(struct device *dev, unsigned int reg)
}
}
-#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 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
*/
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 @@ static int sgtl5000_remove(struct snd_soc_codec *codec)
{
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 int sgtl5000_remove(struct snd_soc_codec *codec)
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 23b32960ff1..f039dc82597 100644
--- a/sound/soc/codecs/tas2552.c
+++ b/sound/soc/codecs/tas2552.c
@@ -78,6 +78,44 @@ struct tas2552_data {
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 @@ static void tas2552_sw_shutdown(struct tas2552_data *tas_data, int sw_shutdown)
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 @@ static int tas2552_hw_params(struct snd_pcm_substream *substream,
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 @@ static int tas2552_hw_params(struct snd_pcm_substream *substream,
}
- snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE,
- TAS2552_PLL_ENABLE);
-
return 0;
}
@@ -269,19 +301,10 @@ static const struct dev_pm_ops tas2552_pm = {
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 @@ static struct snd_soc_dai_driver tas2552_dai[] = {
{
.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 DECLARE_TLV_DB_SCALE(dac_tlv, -7, 100, 24);
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 const struct reg_default tas2552_init_regs[] = {
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 @@ static int tas2552_codec_probe(struct snd_soc_codec *codec)
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 aea9e1ff912..145fe5b253d 100644
--- a/sound/soc/codecs/tlv320aic31xx.c
+++ b/sound/soc/codecs/tlv320aic31xx.c
@@ -167,13 +167,13 @@ struct aic31xx_priv {
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 @@ struct aic31xx_rate_divs {
/* 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 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec,
{
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 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec,
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 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec,
/* 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 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec,
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 @@ static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai,
{
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 @@ static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai,
/* 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 @@ static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai,
dsp_a_val);
snd_soc_update_bits(codec, AIC31XX_IFACE2,
AIC31XX_BCLKINV_MASK,
- iface_reg3);
+ iface_reg2);
return 0;
}
@@ -912,7 +902,16 @@ static int aic31xx_set_dai_sysclk(struct snd_soc_dai *codec_dai,
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 52ed57c69df..fe16c34607b 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 f2c416d16b6..f7c2a575a89 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -1121,6 +1121,7 @@ static int aic3x_regulator_event(struct notifier_block *nb,
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 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power)
/* 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 a237f1627f6..31bb4801a00 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -413,7 +413,6 @@ static int wm8741_resume(struct snd_soc_codec *codec)
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 b86cd9936ef..01921d7e73f 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 @@ static struct snd_soc_jack_gpio tegra_max98090_hp_jack_gpio = {
.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 @@ static int tegra_max98090_asoc_init(struct snd_soc_pcm_runtime *rtd)
&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 @@ static int tegra_max98090_card_remove(struct snd_soc_card *card)
&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 @@ static int tegra_max98090_probe(struct platform_device *pdev)
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;