Commit a84e361e authored by Mark Brown's avatar Mark Brown

ASoC: Merge up fixes

For the benefit of CI.
parents b399dc73 1263cc0f
...@@ -213,6 +213,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { ...@@ -213,6 +213,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "21J6"), DMI_MATCH(DMI_PRODUCT_NAME, "21J6"),
} }
}, },
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "82QF"),
}
},
{ {
.driver_data = &acp6x_card, .driver_data = &acp6x_card,
.matches = { .matches = {
...@@ -220,6 +227,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { ...@@ -220,6 +227,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "82TL"), DMI_MATCH(DMI_PRODUCT_NAME, "82TL"),
} }
}, },
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "82UG"),
}
},
{ {
.driver_data = &acp6x_card, .driver_data = &acp6x_card,
.matches = { .matches = {
...@@ -262,6 +276,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { ...@@ -262,6 +276,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "M6500RC"), DMI_MATCH(DMI_PRODUCT_NAME, "M6500RC"),
} }
}, },
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Micro-Star International Co., Ltd."),
DMI_MATCH(DMI_PRODUCT_NAME, "Bravo 15 B7ED"),
}
},
{ {
.driver_data = &acp6x_card, .driver_data = &acp6x_card,
.matches = { .matches = {
......
...@@ -1207,6 +1207,7 @@ void cs35l56_remove(struct cs35l56_private *cs35l56) ...@@ -1207,6 +1207,7 @@ void cs35l56_remove(struct cs35l56_private *cs35l56)
flush_workqueue(cs35l56->dsp_wq); flush_workqueue(cs35l56->dsp_wq);
destroy_workqueue(cs35l56->dsp_wq); destroy_workqueue(cs35l56->dsp_wq);
pm_runtime_dont_use_autosuspend(cs35l56->base.dev);
pm_runtime_suspend(cs35l56->base.dev); pm_runtime_suspend(cs35l56->base.dev);
pm_runtime_disable(cs35l56->base.dev); pm_runtime_disable(cs35l56->base.dev);
......
...@@ -1468,8 +1468,10 @@ static int wm8960_i2c_probe(struct i2c_client *i2c) ...@@ -1468,8 +1468,10 @@ static int wm8960_i2c_probe(struct i2c_client *i2c)
} }
wm8960->regmap = devm_regmap_init_i2c(i2c, &wm8960_regmap); wm8960->regmap = devm_regmap_init_i2c(i2c, &wm8960_regmap);
if (IS_ERR(wm8960->regmap)) if (IS_ERR(wm8960->regmap)) {
return PTR_ERR(wm8960->regmap); ret = PTR_ERR(wm8960->regmap);
goto bulk_disable;
}
if (pdata) if (pdata)
memcpy(&wm8960->pdata, pdata, sizeof(struct wm8960_data)); memcpy(&wm8960->pdata, pdata, sizeof(struct wm8960_data));
...@@ -1479,13 +1481,14 @@ static int wm8960_i2c_probe(struct i2c_client *i2c) ...@@ -1479,13 +1481,14 @@ static int wm8960_i2c_probe(struct i2c_client *i2c)
ret = i2c_master_recv(i2c, &val, sizeof(val)); ret = i2c_master_recv(i2c, &val, sizeof(val));
if (ret >= 0) { if (ret >= 0) {
dev_err(&i2c->dev, "Not wm8960, wm8960 reg can not read by i2c\n"); dev_err(&i2c->dev, "Not wm8960, wm8960 reg can not read by i2c\n");
return -EINVAL; ret = -EINVAL;
goto bulk_disable;
} }
ret = wm8960_reset(wm8960->regmap); ret = wm8960_reset(wm8960->regmap);
if (ret != 0) { if (ret != 0) {
dev_err(&i2c->dev, "Failed to issue reset\n"); dev_err(&i2c->dev, "Failed to issue reset\n");
return ret; goto bulk_disable;
} }
if (wm8960->pdata.shared_lrclk) { if (wm8960->pdata.shared_lrclk) {
...@@ -1494,7 +1497,7 @@ static int wm8960_i2c_probe(struct i2c_client *i2c) ...@@ -1494,7 +1497,7 @@ static int wm8960_i2c_probe(struct i2c_client *i2c)
if (ret != 0) { if (ret != 0) {
dev_err(&i2c->dev, "Failed to enable LRCM: %d\n", dev_err(&i2c->dev, "Failed to enable LRCM: %d\n",
ret); ret);
return ret; goto bulk_disable;
} }
} }
...@@ -1528,7 +1531,13 @@ static int wm8960_i2c_probe(struct i2c_client *i2c) ...@@ -1528,7 +1531,13 @@ static int wm8960_i2c_probe(struct i2c_client *i2c)
ret = devm_snd_soc_register_component(&i2c->dev, ret = devm_snd_soc_register_component(&i2c->dev,
&soc_component_dev_wm8960, &wm8960_dai, 1); &soc_component_dev_wm8960, &wm8960_dai, 1);
if (ret)
goto bulk_disable;
return 0;
bulk_disable:
regulator_bulk_disable(ARRAY_SIZE(wm8960->supplies), wm8960->supplies);
return ret; return ret;
} }
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
static struct snd_pcm_hardware imx_rpmsg_pcm_hardware = { static struct snd_pcm_hardware imx_rpmsg_pcm_hardware = {
.info = SNDRV_PCM_INFO_INTERLEAVED | .info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_BATCH |
SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_NO_PERIOD_WAKEUP | SNDRV_PCM_INFO_NO_PERIOD_WAKEUP |
......
...@@ -112,34 +112,6 @@ static int axg_spdifin_prepare(struct snd_pcm_substream *substream, ...@@ -112,34 +112,6 @@ static int axg_spdifin_prepare(struct snd_pcm_substream *substream,
return 0; return 0;
} }
static int axg_spdifin_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai);
int ret;
ret = clk_prepare_enable(priv->refclk);
if (ret) {
dev_err(dai->dev,
"failed to enable spdifin reference clock\n");
return ret;
}
regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN,
SPDIFIN_CTRL0_EN);
return 0;
}
static void axg_spdifin_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai);
regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, 0);
clk_disable_unprepare(priv->refclk);
}
static void axg_spdifin_write_mode_param(struct regmap *map, int mode, static void axg_spdifin_write_mode_param(struct regmap *map, int mode,
unsigned int val, unsigned int val,
unsigned int num_per_reg, unsigned int num_per_reg,
...@@ -251,17 +223,32 @@ static int axg_spdifin_dai_probe(struct snd_soc_dai *dai) ...@@ -251,17 +223,32 @@ static int axg_spdifin_dai_probe(struct snd_soc_dai *dai)
ret = axg_spdifin_sample_mode_config(dai, priv); ret = axg_spdifin_sample_mode_config(dai, priv);
if (ret) { if (ret) {
dev_err(dai->dev, "mode configuration failed\n"); dev_err(dai->dev, "mode configuration failed\n");
clk_disable_unprepare(priv->pclk); goto pclk_err;
return ret;
} }
ret = clk_prepare_enable(priv->refclk);
if (ret) {
dev_err(dai->dev,
"failed to enable spdifin reference clock\n");
goto pclk_err;
}
regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN,
SPDIFIN_CTRL0_EN);
return 0; return 0;
pclk_err:
clk_disable_unprepare(priv->pclk);
return ret;
} }
static int axg_spdifin_dai_remove(struct snd_soc_dai *dai) static int axg_spdifin_dai_remove(struct snd_soc_dai *dai)
{ {
struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai); struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai);
regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, 0);
clk_disable_unprepare(priv->refclk);
clk_disable_unprepare(priv->pclk); clk_disable_unprepare(priv->pclk);
return 0; return 0;
} }
...@@ -270,8 +257,6 @@ static const struct snd_soc_dai_ops axg_spdifin_ops = { ...@@ -270,8 +257,6 @@ static const struct snd_soc_dai_ops axg_spdifin_ops = {
.probe = axg_spdifin_dai_probe, .probe = axg_spdifin_dai_probe,
.remove = axg_spdifin_dai_remove, .remove = axg_spdifin_dai_remove,
.prepare = axg_spdifin_prepare, .prepare = axg_spdifin_prepare,
.startup = axg_spdifin_startup,
.shutdown = axg_spdifin_shutdown,
}; };
static int axg_spdifin_iec958_info(struct snd_kcontrol *kcontrol, static int axg_spdifin_iec958_info(struct snd_kcontrol *kcontrol,
......
...@@ -1302,6 +1302,7 @@ static int rsnd_dai_of_node(struct rsnd_priv *priv, int *is_graph) ...@@ -1302,6 +1302,7 @@ static int rsnd_dai_of_node(struct rsnd_priv *priv, int *is_graph)
i++; i++;
if (i >= RSND_MAX_COMPONENT) { if (i >= RSND_MAX_COMPONENT) {
dev_info(dev, "reach to max component\n"); dev_info(dev, "reach to max component\n");
of_node_put(ports);
break; break;
} }
} }
......
...@@ -985,6 +985,7 @@ static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd, ...@@ -985,6 +985,7 @@ static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd,
{ {
struct snd_soc_dai *cpu_dai; struct snd_soc_dai *cpu_dai;
struct snd_soc_dai *codec_dai; struct snd_soc_dai *codec_dai;
struct snd_pcm_hw_params tmp_params;
int i, ret = 0; int i, ret = 0;
snd_soc_dpcm_mutex_assert_held(rtd); snd_soc_dpcm_mutex_assert_held(rtd);
...@@ -998,7 +999,6 @@ static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd, ...@@ -998,7 +999,6 @@ static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd,
goto out; goto out;
for_each_rtd_codec_dais(rtd, i, codec_dai) { for_each_rtd_codec_dais(rtd, i, codec_dai) {
struct snd_pcm_hw_params codec_params;
unsigned int tdm_mask = snd_soc_dai_tdm_mask_get(codec_dai, substream->stream); unsigned int tdm_mask = snd_soc_dai_tdm_mask_get(codec_dai, substream->stream);
/* /*
...@@ -1019,23 +1019,22 @@ static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd, ...@@ -1019,23 +1019,22 @@ static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd,
continue; continue;
/* copy params for each codec */ /* copy params for each codec */
codec_params = *params; tmp_params = *params;
/* fixup params based on TDM slot masks */ /* fixup params based on TDM slot masks */
if (tdm_mask) if (tdm_mask)
soc_pcm_codec_params_fixup(&codec_params, tdm_mask); soc_pcm_codec_params_fixup(&tmp_params, tdm_mask);
ret = snd_soc_dai_hw_params(codec_dai, substream, ret = snd_soc_dai_hw_params(codec_dai, substream,
&codec_params); &tmp_params);
if(ret < 0) if(ret < 0)
goto out; goto out;
soc_pcm_set_dai_params(codec_dai, &codec_params); soc_pcm_set_dai_params(codec_dai, &tmp_params);
snd_soc_dapm_update_dai(substream, &codec_params, codec_dai); snd_soc_dapm_update_dai(substream, &tmp_params, codec_dai);
} }
for_each_rtd_cpu_dais(rtd, i, cpu_dai) { for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
struct snd_pcm_hw_params cpu_params;
unsigned int ch_mask = 0; unsigned int ch_mask = 0;
int j; int j;
...@@ -1047,7 +1046,7 @@ static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd, ...@@ -1047,7 +1046,7 @@ static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd,
continue; continue;
/* copy params for each cpu */ /* copy params for each cpu */
cpu_params = *params; tmp_params = *params;
if (!rtd->dai_link->codec_ch_maps) if (!rtd->dai_link->codec_ch_maps)
goto hw_params; goto hw_params;
...@@ -1062,16 +1061,16 @@ static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd, ...@@ -1062,16 +1061,16 @@ static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd,
/* fixup cpu channel number */ /* fixup cpu channel number */
if (ch_mask) if (ch_mask)
soc_pcm_codec_params_fixup(&cpu_params, ch_mask); soc_pcm_codec_params_fixup(&tmp_params, ch_mask);
hw_params: hw_params:
ret = snd_soc_dai_hw_params(cpu_dai, substream, &cpu_params); ret = snd_soc_dai_hw_params(cpu_dai, substream, &tmp_params);
if (ret < 0) if (ret < 0)
goto out; goto out;
/* store the parameters for each DAI */ /* store the parameters for each DAI */
soc_pcm_set_dai_params(cpu_dai, &cpu_params); soc_pcm_set_dai_params(cpu_dai, &tmp_params);
snd_soc_dapm_update_dai(substream, &cpu_params, cpu_dai); snd_soc_dapm_update_dai(substream, &tmp_params, cpu_dai);
} }
ret = snd_soc_pcm_component_hw_params(substream, params); ret = snd_soc_pcm_component_hw_params(substream, params);
......
...@@ -217,6 +217,7 @@ int snd_soc_dai_is_dummy(struct snd_soc_dai *dai) ...@@ -217,6 +217,7 @@ int snd_soc_dai_is_dummy(struct snd_soc_dai *dai)
return 1; return 1;
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(snd_soc_dai_is_dummy);
int snd_soc_component_is_dummy(struct snd_soc_component *component) int snd_soc_component_is_dummy(struct snd_soc_component *component)
{ {
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <sound/graph_card.h> #include <sound/graph_card.h>
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include <sound/soc-dai.h>
#define MAX_PLLA_OUT0_DIV 128 #define MAX_PLLA_OUT0_DIV 128
...@@ -44,6 +45,21 @@ struct tegra_audio_cdata { ...@@ -44,6 +45,21 @@ struct tegra_audio_cdata {
unsigned int plla_out0_rates[NUM_RATE_TYPE]; unsigned int plla_out0_rates[NUM_RATE_TYPE];
}; };
static bool need_clk_update(struct snd_soc_dai *dai)
{
if (snd_soc_dai_is_dummy(dai) ||
!dai->driver->ops ||
!dai->driver->name)
return false;
if (strstr(dai->driver->name, "I2S") ||
strstr(dai->driver->name, "DMIC") ||
strstr(dai->driver->name, "DSPK"))
return true;
return false;
}
/* Setup PLL clock as per the given sample rate */ /* Setup PLL clock as per the given sample rate */
static int tegra_audio_graph_update_pll(struct snd_pcm_substream *substream, static int tegra_audio_graph_update_pll(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params) struct snd_pcm_hw_params *params)
...@@ -140,19 +156,7 @@ static int tegra_audio_graph_hw_params(struct snd_pcm_substream *substream, ...@@ -140,19 +156,7 @@ static int tegra_audio_graph_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
int err; int err;
/* if (need_clk_update(cpu_dai)) {
* This gets called for each DAI link (FE or BE) when DPCM is used.
* We may not want to update PLLA rate for each call. So PLLA update
* must be restricted to external I/O links (I2S, DMIC or DSPK) since
* they actually depend on it. I/O modules update their clocks in
* hw_param() of their respective component driver and PLLA rate
* update here helps them to derive appropriate rates.
*
* TODO: When more HW accelerators get added (like sample rate
* converter, volume gain controller etc., which don't really
* depend on PLLA) we need a better way to filter here.
*/
if (cpu_dai->driver->ops && rtd->dai_link->no_pcm) {
err = tegra_audio_graph_update_pll(substream, params); err = tegra_audio_graph_update_pll(substream, params);
if (err) if (err)
return err; return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment