Commit 86c2ee16 authored by Takashi Iwai's avatar Takashi Iwai

Merge tag 'asoc-fix-v4.5-rc4' of...

Merge tag 'asoc-fix-v4.5-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus

ASoC: Fixes for v4.5

A rather large batch of fixes here, almost all in the Intel driver.
The changes that got merged in this merge window for Skylake were rather
large and as well as issues that you'd expect in a large block of new
code there were some problems created for older processors which needed
fixing up.  Things are largely settling down now hopefully.
parents 397da2d0 f11aec0d
...@@ -30,6 +30,8 @@ The compatible list for this generic sound card currently: ...@@ -30,6 +30,8 @@ The compatible list for this generic sound card currently:
"fsl,imx-audio-sgtl5000" "fsl,imx-audio-sgtl5000"
(compatible with Documentation/devicetree/bindings/sound/imx-audio-sgtl5000.txt) (compatible with Documentation/devicetree/bindings/sound/imx-audio-sgtl5000.txt)
"fsl,imx-audio-wm8960"
Required properties: Required properties:
- compatible : Contains one of entries in the compatible list. - compatible : Contains one of entries in the compatible list.
......
...@@ -635,6 +635,7 @@ static int acp_dma_open(struct snd_pcm_substream *substream) ...@@ -635,6 +635,7 @@ static int acp_dma_open(struct snd_pcm_substream *substream)
SNDRV_PCM_HW_PARAM_PERIODS); SNDRV_PCM_HW_PARAM_PERIODS);
if (ret < 0) { if (ret < 0) {
dev_err(prtd->platform->dev, "set integer constraint failed\n"); dev_err(prtd->platform->dev, "set integer constraint failed\n");
kfree(adata);
return ret; return ret;
} }
......
...@@ -1929,6 +1929,25 @@ static struct { ...@@ -1929,6 +1929,25 @@ static struct {
{ 1000000, 13500000, 0, 1 }, { 1000000, 13500000, 0, 1 },
}; };
static const unsigned int pseudo_fref_max[ARIZONA_FLL_MAX_FRATIO] = {
13500000,
6144000,
6144000,
3072000,
3072000,
2822400,
2822400,
1536000,
1536000,
1536000,
1536000,
1536000,
1536000,
1536000,
1536000,
768000,
};
static struct { static struct {
unsigned int min; unsigned int min;
unsigned int max; unsigned int max;
...@@ -2042,16 +2061,32 @@ static int arizona_calc_fratio(struct arizona_fll *fll, ...@@ -2042,16 +2061,32 @@ static int arizona_calc_fratio(struct arizona_fll *fll,
/* Adjust FRATIO/refdiv to avoid integer mode if possible */ /* Adjust FRATIO/refdiv to avoid integer mode if possible */
refdiv = cfg->refdiv; refdiv = cfg->refdiv;
arizona_fll_dbg(fll, "pseudo: initial ratio=%u fref=%u refdiv=%u\n",
init_ratio, Fref, refdiv);
while (div <= ARIZONA_FLL_MAX_REFDIV) { while (div <= ARIZONA_FLL_MAX_REFDIV) {
for (ratio = init_ratio; ratio <= ARIZONA_FLL_MAX_FRATIO; for (ratio = init_ratio; ratio <= ARIZONA_FLL_MAX_FRATIO;
ratio++) { ratio++) {
if ((ARIZONA_FLL_VCO_CORNER / 2) / if ((ARIZONA_FLL_VCO_CORNER / 2) /
(fll->vco_mult * ratio) < Fref) (fll->vco_mult * ratio) < Fref) {
arizona_fll_dbg(fll, "pseudo: hit VCO corner\n");
break; break;
}
if (Fref > pseudo_fref_max[ratio - 1]) {
arizona_fll_dbg(fll,
"pseudo: exceeded max fref(%u) for ratio=%u\n",
pseudo_fref_max[ratio - 1],
ratio);
break;
}
if (target % (ratio * Fref)) { if (target % (ratio * Fref)) {
cfg->refdiv = refdiv; cfg->refdiv = refdiv;
cfg->fratio = ratio - 1; cfg->fratio = ratio - 1;
arizona_fll_dbg(fll,
"pseudo: found fref=%u refdiv=%d(%d) ratio=%d\n",
Fref, refdiv, div, ratio);
return ratio; return ratio;
} }
} }
...@@ -2060,6 +2095,9 @@ static int arizona_calc_fratio(struct arizona_fll *fll, ...@@ -2060,6 +2095,9 @@ static int arizona_calc_fratio(struct arizona_fll *fll,
if (target % (ratio * Fref)) { if (target % (ratio * Fref)) {
cfg->refdiv = refdiv; cfg->refdiv = refdiv;
cfg->fratio = ratio - 1; cfg->fratio = ratio - 1;
arizona_fll_dbg(fll,
"pseudo: found fref=%u refdiv=%d(%d) ratio=%d\n",
Fref, refdiv, div, ratio);
return ratio; return ratio;
} }
} }
...@@ -2068,6 +2106,9 @@ static int arizona_calc_fratio(struct arizona_fll *fll, ...@@ -2068,6 +2106,9 @@ static int arizona_calc_fratio(struct arizona_fll *fll,
Fref /= 2; Fref /= 2;
refdiv++; refdiv++;
init_ratio = arizona_find_fratio(Fref, NULL); init_ratio = arizona_find_fratio(Fref, NULL);
arizona_fll_dbg(fll,
"pseudo: change fref=%u refdiv=%d(%d) ratio=%u\n",
Fref, refdiv, div, init_ratio);
} }
arizona_fll_warn(fll, "Falling back to integer mode operation\n"); arizona_fll_warn(fll, "Falling back to integer mode operation\n");
......
...@@ -266,6 +266,8 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) ...@@ -266,6 +266,8 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
} else { } else {
*mic = false; *mic = false;
regmap_write(rt286->regmap, RT286_SET_MIC1, 0x20); regmap_write(rt286->regmap, RT286_SET_MIC1, 0x20);
regmap_update_bits(rt286->regmap,
RT286_CBJ_CTRL1, 0x0400, 0x0000);
} }
} else { } else {
regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf); regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf);
...@@ -470,24 +472,6 @@ static int rt286_set_dmic1_event(struct snd_soc_dapm_widget *w, ...@@ -470,24 +472,6 @@ static int rt286_set_dmic1_event(struct snd_soc_dapm_widget *w,
return 0; return 0;
} }
static int rt286_vref_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
snd_soc_update_bits(codec,
RT286_CBJ_CTRL1, 0x0400, 0x0000);
mdelay(50);
break;
default:
return 0;
}
return 0;
}
static int rt286_ldo2_event(struct snd_soc_dapm_widget *w, static int rt286_ldo2_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event) struct snd_kcontrol *kcontrol, int event)
{ {
...@@ -536,7 +520,7 @@ static const struct snd_soc_dapm_widget rt286_dapm_widgets[] = { ...@@ -536,7 +520,7 @@ static const struct snd_soc_dapm_widget rt286_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY_S("HV", 1, RT286_POWER_CTRL1, SND_SOC_DAPM_SUPPLY_S("HV", 1, RT286_POWER_CTRL1,
12, 1, NULL, 0), 12, 1, NULL, 0),
SND_SOC_DAPM_SUPPLY("VREF", RT286_POWER_CTRL1, SND_SOC_DAPM_SUPPLY("VREF", RT286_POWER_CTRL1,
0, 1, rt286_vref_event, SND_SOC_DAPM_PRE_PMU), 0, 1, NULL, 0),
SND_SOC_DAPM_SUPPLY_S("LDO1", 1, RT286_POWER_CTRL2, SND_SOC_DAPM_SUPPLY_S("LDO1", 1, RT286_POWER_CTRL2,
2, 0, NULL, 0), 2, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY_S("LDO2", 2, RT286_POWER_CTRL1, SND_SOC_DAPM_SUPPLY_S("LDO2", 2, RT286_POWER_CTRL1,
...@@ -910,8 +894,6 @@ static int rt286_set_bias_level(struct snd_soc_codec *codec, ...@@ -910,8 +894,6 @@ static int rt286_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_ON: case SND_SOC_BIAS_ON:
mdelay(10); mdelay(10);
snd_soc_update_bits(codec,
RT286_CBJ_CTRL1, 0x0400, 0x0400);
snd_soc_update_bits(codec, snd_soc_update_bits(codec,
RT286_DC_GAIN, 0x200, 0x0); RT286_DC_GAIN, 0x200, 0x0);
...@@ -920,8 +902,6 @@ static int rt286_set_bias_level(struct snd_soc_codec *codec, ...@@ -920,8 +902,6 @@ static int rt286_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
snd_soc_write(codec, snd_soc_write(codec,
RT286_SET_AUDIO_POWER, AC_PWRST_D3); RT286_SET_AUDIO_POWER, AC_PWRST_D3);
snd_soc_update_bits(codec,
RT286_CBJ_CTRL1, 0x0400, 0x0000);
break; break;
default: default:
......
...@@ -776,7 +776,7 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = { ...@@ -776,7 +776,7 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = {
/* IN1/IN2 Control */ /* IN1/IN2 Control */
SOC_SINGLE_TLV("IN1 Boost", RT5645_IN1_CTRL1, SOC_SINGLE_TLV("IN1 Boost", RT5645_IN1_CTRL1,
RT5645_BST_SFT1, 8, 0, bst_tlv), RT5645_BST_SFT1, 12, 0, bst_tlv),
SOC_SINGLE_TLV("IN2 Boost", RT5645_IN2_CTRL, SOC_SINGLE_TLV("IN2 Boost", RT5645_IN2_CTRL,
RT5645_BST_SFT2, 8, 0, bst_tlv), RT5645_BST_SFT2, 8, 0, bst_tlv),
......
...@@ -3985,7 +3985,6 @@ static int rt5659_i2c_probe(struct i2c_client *i2c, ...@@ -3985,7 +3985,6 @@ static int rt5659_i2c_probe(struct i2c_client *i2c,
if (rt5659 == NULL) if (rt5659 == NULL)
return -ENOMEM; return -ENOMEM;
rt5659->i2c = i2c;
i2c_set_clientdata(i2c, rt5659); i2c_set_clientdata(i2c, rt5659);
if (pdata) if (pdata)
...@@ -4157,24 +4156,17 @@ static int rt5659_i2c_probe(struct i2c_client *i2c, ...@@ -4157,24 +4156,17 @@ static int rt5659_i2c_probe(struct i2c_client *i2c,
INIT_DELAYED_WORK(&rt5659->jack_detect_work, rt5659_jack_detect_work); INIT_DELAYED_WORK(&rt5659->jack_detect_work, rt5659_jack_detect_work);
if (rt5659->i2c->irq) { if (i2c->irq) {
ret = request_threaded_irq(rt5659->i2c->irq, NULL, rt5659_irq, ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING rt5659_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
| IRQF_ONESHOT, "rt5659", rt5659); | IRQF_ONESHOT, "rt5659", rt5659);
if (ret) if (ret)
dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret); dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret);
} }
ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5659, return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5659,
rt5659_dai, ARRAY_SIZE(rt5659_dai)); rt5659_dai, ARRAY_SIZE(rt5659_dai));
if (ret) {
if (rt5659->i2c->irq)
free_irq(rt5659->i2c->irq, rt5659);
}
return 0;
} }
static int rt5659_i2c_remove(struct i2c_client *i2c) static int rt5659_i2c_remove(struct i2c_client *i2c)
...@@ -4191,24 +4183,29 @@ void rt5659_i2c_shutdown(struct i2c_client *client) ...@@ -4191,24 +4183,29 @@ void rt5659_i2c_shutdown(struct i2c_client *client)
regmap_write(rt5659->regmap, RT5659_RESET, 0); regmap_write(rt5659->regmap, RT5659_RESET, 0);
} }
#ifdef CONFIG_OF
static const struct of_device_id rt5659_of_match[] = { static const struct of_device_id rt5659_of_match[] = {
{ .compatible = "realtek,rt5658", }, { .compatible = "realtek,rt5658", },
{ .compatible = "realtek,rt5659", }, { .compatible = "realtek,rt5659", },
{}, { },
}; };
MODULE_DEVICE_TABLE(of, rt5659_of_match);
#endif
#ifdef CONFIG_ACPI
static struct acpi_device_id rt5659_acpi_match[] = { static struct acpi_device_id rt5659_acpi_match[] = {
{ "10EC5658", 0}, { "10EC5658", 0, },
{ "10EC5659", 0}, { "10EC5659", 0, },
{ }, { },
}; };
MODULE_DEVICE_TABLE(acpi, rt5659_acpi_match); MODULE_DEVICE_TABLE(acpi, rt5659_acpi_match);
#endif
struct i2c_driver rt5659_i2c_driver = { struct i2c_driver rt5659_i2c_driver = {
.driver = { .driver = {
.name = "rt5659", .name = "rt5659",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.of_match_table = rt5659_of_match, .of_match_table = of_match_ptr(rt5659_of_match),
.acpi_match_table = ACPI_PTR(rt5659_acpi_match), .acpi_match_table = ACPI_PTR(rt5659_acpi_match),
}, },
.probe = rt5659_i2c_probe, .probe = rt5659_i2c_probe,
......
...@@ -1792,7 +1792,6 @@ struct rt5659_priv { ...@@ -1792,7 +1792,6 @@ struct rt5659_priv {
struct snd_soc_codec *codec; struct snd_soc_codec *codec;
struct rt5659_platform_data pdata; struct rt5659_platform_data pdata;
struct regmap *regmap; struct regmap *regmap;
struct i2c_client *i2c;
struct gpio_desc *gpiod_ldo1_en; struct gpio_desc *gpiod_ldo1_en;
struct gpio_desc *gpiod_reset; struct gpio_desc *gpiod_reset;
struct snd_soc_jack *hs_jack; struct snd_soc_jack *hs_jack;
......
...@@ -31,7 +31,10 @@ static int sigmadsp_write_i2c(void *control_data, ...@@ -31,7 +31,10 @@ static int sigmadsp_write_i2c(void *control_data,
kfree(buf); kfree(buf);
return ret; if (ret < 0)
return ret;
return 0;
} }
static int sigmadsp_read_i2c(void *control_data, static int sigmadsp_read_i2c(void *control_data,
......
...@@ -2382,6 +2382,7 @@ static int wm5110_probe(struct platform_device *pdev) ...@@ -2382,6 +2382,7 @@ static int wm5110_probe(struct platform_device *pdev)
static int wm5110_remove(struct platform_device *pdev) static int wm5110_remove(struct platform_device *pdev)
{ {
snd_soc_unregister_platform(&pdev->dev);
snd_soc_unregister_codec(&pdev->dev); snd_soc_unregister_codec(&pdev->dev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
......
...@@ -240,13 +240,13 @@ SOC_DOUBLE_R("Capture Volume ZC Switch", WM8960_LINVOL, WM8960_RINVOL, ...@@ -240,13 +240,13 @@ SOC_DOUBLE_R("Capture Volume ZC Switch", WM8960_LINVOL, WM8960_RINVOL,
SOC_DOUBLE_R("Capture Switch", WM8960_LINVOL, WM8960_RINVOL, SOC_DOUBLE_R("Capture Switch", WM8960_LINVOL, WM8960_RINVOL,
7, 1, 1), 7, 1, 1),
SOC_SINGLE_TLV("Right Input Boost Mixer RINPUT3 Volume", SOC_SINGLE_TLV("Left Input Boost Mixer LINPUT3 Volume",
WM8960_INBMIX1, 4, 7, 0, lineinboost_tlv), WM8960_INBMIX1, 4, 7, 0, lineinboost_tlv),
SOC_SINGLE_TLV("Right Input Boost Mixer RINPUT2 Volume", SOC_SINGLE_TLV("Left Input Boost Mixer LINPUT2 Volume",
WM8960_INBMIX1, 1, 7, 0, lineinboost_tlv), WM8960_INBMIX1, 1, 7, 0, lineinboost_tlv),
SOC_SINGLE_TLV("Left Input Boost Mixer LINPUT3 Volume", SOC_SINGLE_TLV("Right Input Boost Mixer RINPUT3 Volume",
WM8960_INBMIX2, 4, 7, 0, lineinboost_tlv), WM8960_INBMIX2, 4, 7, 0, lineinboost_tlv),
SOC_SINGLE_TLV("Left Input Boost Mixer LINPUT2 Volume", SOC_SINGLE_TLV("Right Input Boost Mixer RINPUT2 Volume",
WM8960_INBMIX2, 1, 7, 0, lineinboost_tlv), WM8960_INBMIX2, 1, 7, 0, lineinboost_tlv),
SOC_SINGLE_TLV("Right Input Boost Mixer RINPUT1 Volume", SOC_SINGLE_TLV("Right Input Boost Mixer RINPUT1 Volume",
WM8960_RINPATH, 4, 3, 0, micboost_tlv), WM8960_RINPATH, 4, 3, 0, micboost_tlv),
...@@ -643,29 +643,31 @@ static int wm8960_configure_clocking(struct snd_soc_codec *codec) ...@@ -643,29 +643,31 @@ static int wm8960_configure_clocking(struct snd_soc_codec *codec)
return -EINVAL; return -EINVAL;
} }
/* check if the sysclk frequency is available. */ if (wm8960->clk_id != WM8960_SYSCLK_PLL) {
for (i = 0; i < ARRAY_SIZE(sysclk_divs); ++i) { /* check if the sysclk frequency is available. */
if (sysclk_divs[i] == -1) for (i = 0; i < ARRAY_SIZE(sysclk_divs); ++i) {
continue; if (sysclk_divs[i] == -1)
sysclk = freq_out / sysclk_divs[i]; continue;
for (j = 0; j < ARRAY_SIZE(dac_divs); ++j) { sysclk = freq_out / sysclk_divs[i];
if (sysclk == dac_divs[j] * lrclk) { for (j = 0; j < ARRAY_SIZE(dac_divs); ++j) {
if (sysclk != dac_divs[j] * lrclk)
continue;
for (k = 0; k < ARRAY_SIZE(bclk_divs); ++k) for (k = 0; k < ARRAY_SIZE(bclk_divs); ++k)
if (sysclk == bclk * bclk_divs[k] / 10) if (sysclk == bclk * bclk_divs[k] / 10)
break; break;
if (k != ARRAY_SIZE(bclk_divs)) if (k != ARRAY_SIZE(bclk_divs))
break; break;
} }
if (j != ARRAY_SIZE(dac_divs))
break;
} }
if (j != ARRAY_SIZE(dac_divs))
break;
}
if (i != ARRAY_SIZE(sysclk_divs)) { if (i != ARRAY_SIZE(sysclk_divs)) {
goto configure_clock; goto configure_clock;
} else if (wm8960->clk_id != WM8960_SYSCLK_AUTO) { } else if (wm8960->clk_id != WM8960_SYSCLK_AUTO) {
dev_err(codec->dev, "failed to configure clock\n"); dev_err(codec->dev, "failed to configure clock\n");
return -EINVAL; return -EINVAL;
}
} }
/* get a available pll out frequency and set pll */ /* get a available pll out frequency and set pll */
for (i = 0; i < ARRAY_SIZE(sysclk_divs); ++i) { for (i = 0; i < ARRAY_SIZE(sysclk_divs); ++i) {
......
...@@ -645,6 +645,8 @@ static int dw_i2s_probe(struct platform_device *pdev) ...@@ -645,6 +645,8 @@ static int dw_i2s_probe(struct platform_device *pdev)
dev->dev = &pdev->dev; dev->dev = &pdev->dev;
dev->i2s_reg_comp1 = I2S_COMP_PARAM_1;
dev->i2s_reg_comp2 = I2S_COMP_PARAM_2;
if (pdata) { if (pdata) {
dev->capability = pdata->cap; dev->capability = pdata->cap;
clk_id = NULL; clk_id = NULL;
...@@ -652,9 +654,6 @@ static int dw_i2s_probe(struct platform_device *pdev) ...@@ -652,9 +654,6 @@ static int dw_i2s_probe(struct platform_device *pdev)
if (dev->quirks & DW_I2S_QUIRK_COMP_REG_OFFSET) { if (dev->quirks & DW_I2S_QUIRK_COMP_REG_OFFSET) {
dev->i2s_reg_comp1 = pdata->i2s_reg_comp1; dev->i2s_reg_comp1 = pdata->i2s_reg_comp1;
dev->i2s_reg_comp2 = pdata->i2s_reg_comp2; dev->i2s_reg_comp2 = pdata->i2s_reg_comp2;
} else {
dev->i2s_reg_comp1 = I2S_COMP_PARAM_1;
dev->i2s_reg_comp2 = I2S_COMP_PARAM_2;
} }
ret = dw_configure_dai_by_pd(dev, dw_i2s_dai, res, pdata); ret = dw_configure_dai_by_pd(dev, dw_i2s_dai, res, pdata);
} else { } else {
......
...@@ -112,20 +112,6 @@ struct fsl_ssi_rxtx_reg_val { ...@@ -112,20 +112,6 @@ struct fsl_ssi_rxtx_reg_val {
struct fsl_ssi_reg_val tx; struct fsl_ssi_reg_val tx;
}; };
static const struct reg_default fsl_ssi_reg_defaults[] = {
{CCSR_SSI_SCR, 0x00000000},
{CCSR_SSI_SIER, 0x00003003},
{CCSR_SSI_STCR, 0x00000200},
{CCSR_SSI_SRCR, 0x00000200},
{CCSR_SSI_STCCR, 0x00040000},
{CCSR_SSI_SRCCR, 0x00040000},
{CCSR_SSI_SACNT, 0x00000000},
{CCSR_SSI_STMSK, 0x00000000},
{CCSR_SSI_SRMSK, 0x00000000},
{CCSR_SSI_SACCEN, 0x00000000},
{CCSR_SSI_SACCDIS, 0x00000000},
};
static bool fsl_ssi_readable_reg(struct device *dev, unsigned int reg) static bool fsl_ssi_readable_reg(struct device *dev, unsigned int reg)
{ {
switch (reg) { switch (reg) {
...@@ -190,8 +176,7 @@ static const struct regmap_config fsl_ssi_regconfig = { ...@@ -190,8 +176,7 @@ static const struct regmap_config fsl_ssi_regconfig = {
.val_bits = 32, .val_bits = 32,
.reg_stride = 4, .reg_stride = 4,
.val_format_endian = REGMAP_ENDIAN_NATIVE, .val_format_endian = REGMAP_ENDIAN_NATIVE,
.reg_defaults = fsl_ssi_reg_defaults, .num_reg_defaults_raw = CCSR_SSI_SACCDIS / sizeof(uint32_t) + 1,
.num_reg_defaults = ARRAY_SIZE(fsl_ssi_reg_defaults),
.readable_reg = fsl_ssi_readable_reg, .readable_reg = fsl_ssi_readable_reg,
.volatile_reg = fsl_ssi_volatile_reg, .volatile_reg = fsl_ssi_volatile_reg,
.precious_reg = fsl_ssi_precious_reg, .precious_reg = fsl_ssi_precious_reg,
...@@ -201,6 +186,7 @@ static const struct regmap_config fsl_ssi_regconfig = { ...@@ -201,6 +186,7 @@ static const struct regmap_config fsl_ssi_regconfig = {
struct fsl_ssi_soc_data { struct fsl_ssi_soc_data {
bool imx; bool imx;
bool imx21regs; /* imx21-class SSI - no SACC{ST,EN,DIS} regs */
bool offline_config; bool offline_config;
u32 sisr_write_mask; u32 sisr_write_mask;
}; };
...@@ -303,6 +289,7 @@ static struct fsl_ssi_soc_data fsl_ssi_mpc8610 = { ...@@ -303,6 +289,7 @@ static struct fsl_ssi_soc_data fsl_ssi_mpc8610 = {
static struct fsl_ssi_soc_data fsl_ssi_imx21 = { static struct fsl_ssi_soc_data fsl_ssi_imx21 = {
.imx = true, .imx = true,
.imx21regs = true,
.offline_config = true, .offline_config = true,
.sisr_write_mask = 0, .sisr_write_mask = 0,
}; };
...@@ -586,8 +573,12 @@ static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private) ...@@ -586,8 +573,12 @@ static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private)
*/ */
regmap_write(regs, CCSR_SSI_SACNT, regmap_write(regs, CCSR_SSI_SACNT,
CCSR_SSI_SACNT_AC97EN | CCSR_SSI_SACNT_FV); CCSR_SSI_SACNT_AC97EN | CCSR_SSI_SACNT_FV);
regmap_write(regs, CCSR_SSI_SACCDIS, 0xff);
regmap_write(regs, CCSR_SSI_SACCEN, 0x300); /* no SACC{ST,EN,DIS} regs on imx21-class SSI */
if (!ssi_private->soc->imx21regs) {
regmap_write(regs, CCSR_SSI_SACCDIS, 0xff);
regmap_write(regs, CCSR_SSI_SACCEN, 0x300);
}
/* /*
* Enable SSI, Transmit and Receive. AC97 has to communicate with the * Enable SSI, Transmit and Receive. AC97 has to communicate with the
...@@ -1397,6 +1388,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) ...@@ -1397,6 +1388,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
struct resource *res; struct resource *res;
void __iomem *iomem; void __iomem *iomem;
char name[64]; char name[64];
struct regmap_config regconfig = fsl_ssi_regconfig;
of_id = of_match_device(fsl_ssi_ids, &pdev->dev); of_id = of_match_device(fsl_ssi_ids, &pdev->dev);
if (!of_id || !of_id->data) if (!of_id || !of_id->data)
...@@ -1444,15 +1436,25 @@ static int fsl_ssi_probe(struct platform_device *pdev) ...@@ -1444,15 +1436,25 @@ static int fsl_ssi_probe(struct platform_device *pdev)
return PTR_ERR(iomem); return PTR_ERR(iomem);
ssi_private->ssi_phys = res->start; ssi_private->ssi_phys = res->start;
if (ssi_private->soc->imx21regs) {
/*
* According to datasheet imx21-class SSI
* don't have SACC{ST,EN,DIS} regs.
*/
regconfig.max_register = CCSR_SSI_SRMSK;
regconfig.num_reg_defaults_raw =
CCSR_SSI_SRMSK / sizeof(uint32_t) + 1;
}
ret = of_property_match_string(np, "clock-names", "ipg"); ret = of_property_match_string(np, "clock-names", "ipg");
if (ret < 0) { if (ret < 0) {
ssi_private->has_ipg_clk_name = false; ssi_private->has_ipg_clk_name = false;
ssi_private->regs = devm_regmap_init_mmio(&pdev->dev, iomem, ssi_private->regs = devm_regmap_init_mmio(&pdev->dev, iomem,
&fsl_ssi_regconfig); &regconfig);
} else { } else {
ssi_private->has_ipg_clk_name = true; ssi_private->has_ipg_clk_name = true;
ssi_private->regs = devm_regmap_init_mmio_clk(&pdev->dev, ssi_private->regs = devm_regmap_init_mmio_clk(&pdev->dev,
"ipg", iomem, &fsl_ssi_regconfig); "ipg", iomem, &regconfig);
} }
if (IS_ERR(ssi_private->regs)) { if (IS_ERR(ssi_private->regs)) {
dev_err(&pdev->dev, "Failed to init register map\n"); dev_err(&pdev->dev, "Failed to init register map\n");
......
...@@ -72,8 +72,6 @@ static int imx_spdif_audio_probe(struct platform_device *pdev) ...@@ -72,8 +72,6 @@ static int imx_spdif_audio_probe(struct platform_device *pdev)
goto end; goto end;
} }
platform_set_drvdata(pdev, data);
end: end:
of_node_put(spdif_np); of_node_put(spdif_np);
......
...@@ -99,7 +99,7 @@ static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream, ...@@ -99,7 +99,7 @@ static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream,
if (ret && ret != -ENOTSUPP) if (ret && ret != -ENOTSUPP)
goto err; goto err;
} }
return 0;
err: err:
return ret; return ret;
} }
......
...@@ -30,11 +30,15 @@ config SND_SST_IPC_ACPI ...@@ -30,11 +30,15 @@ config SND_SST_IPC_ACPI
config SND_SOC_INTEL_SST config SND_SOC_INTEL_SST
tristate tristate
select SND_SOC_INTEL_SST_ACPI if ACPI select SND_SOC_INTEL_SST_ACPI if ACPI
select SND_SOC_INTEL_SST_MATCH if ACPI
depends on (X86 || COMPILE_TEST) depends on (X86 || COMPILE_TEST)
config SND_SOC_INTEL_SST_ACPI config SND_SOC_INTEL_SST_ACPI
tristate tristate
config SND_SOC_INTEL_SST_MATCH
tristate
config SND_SOC_INTEL_HASWELL config SND_SOC_INTEL_HASWELL
tristate tristate
...@@ -57,7 +61,7 @@ config SND_SOC_INTEL_HASWELL_MACH ...@@ -57,7 +61,7 @@ config SND_SOC_INTEL_HASWELL_MACH
config SND_SOC_INTEL_BYT_RT5640_MACH config SND_SOC_INTEL_BYT_RT5640_MACH
tristate "ASoC Audio driver for Intel Baytrail with RT5640 codec" tristate "ASoC Audio driver for Intel Baytrail with RT5640 codec"
depends on X86_INTEL_LPSS && I2C depends on X86_INTEL_LPSS && I2C
depends on DW_DMAC_CORE=y && (SND_SOC_INTEL_BYTCR_RT5640_MACH = n) depends on DW_DMAC_CORE=y && (SND_SST_IPC_ACPI = n)
select SND_SOC_INTEL_SST select SND_SOC_INTEL_SST
select SND_SOC_INTEL_BAYTRAIL select SND_SOC_INTEL_BAYTRAIL
select SND_SOC_RT5640 select SND_SOC_RT5640
...@@ -69,7 +73,7 @@ config SND_SOC_INTEL_BYT_RT5640_MACH ...@@ -69,7 +73,7 @@ config SND_SOC_INTEL_BYT_RT5640_MACH
config SND_SOC_INTEL_BYT_MAX98090_MACH config SND_SOC_INTEL_BYT_MAX98090_MACH
tristate "ASoC Audio driver for Intel Baytrail with MAX98090 codec" tristate "ASoC Audio driver for Intel Baytrail with MAX98090 codec"
depends on X86_INTEL_LPSS && I2C depends on X86_INTEL_LPSS && I2C
depends on DW_DMAC_CORE=y depends on DW_DMAC_CORE=y && (SND_SST_IPC_ACPI = n)
select SND_SOC_INTEL_SST select SND_SOC_INTEL_SST
select SND_SOC_INTEL_BAYTRAIL select SND_SOC_INTEL_BAYTRAIL
select SND_SOC_MAX98090 select SND_SOC_MAX98090
...@@ -97,6 +101,7 @@ config SND_SOC_INTEL_BYTCR_RT5640_MACH ...@@ -97,6 +101,7 @@ config SND_SOC_INTEL_BYTCR_RT5640_MACH
select SND_SOC_RT5640 select SND_SOC_RT5640
select SND_SST_MFLD_PLATFORM select SND_SST_MFLD_PLATFORM
select SND_SST_IPC_ACPI select SND_SST_IPC_ACPI
select SND_SOC_INTEL_SST_MATCH if ACPI
help help
This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR
platforms with RT5640 audio codec. platforms with RT5640 audio codec.
...@@ -109,6 +114,7 @@ config SND_SOC_INTEL_BYTCR_RT5651_MACH ...@@ -109,6 +114,7 @@ config SND_SOC_INTEL_BYTCR_RT5651_MACH
select SND_SOC_RT5651 select SND_SOC_RT5651
select SND_SST_MFLD_PLATFORM select SND_SST_MFLD_PLATFORM
select SND_SST_IPC_ACPI select SND_SST_IPC_ACPI
select SND_SOC_INTEL_SST_MATCH if ACPI
help help
This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR
platforms with RT5651 audio codec. platforms with RT5651 audio codec.
...@@ -121,6 +127,7 @@ config SND_SOC_INTEL_CHT_BSW_RT5672_MACH ...@@ -121,6 +127,7 @@ config SND_SOC_INTEL_CHT_BSW_RT5672_MACH
select SND_SOC_RT5670 select SND_SOC_RT5670
select SND_SST_MFLD_PLATFORM select SND_SST_MFLD_PLATFORM
select SND_SST_IPC_ACPI select SND_SST_IPC_ACPI
select SND_SOC_INTEL_SST_MATCH if ACPI
help help
This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell
platforms with RT5672 audio codec. platforms with RT5672 audio codec.
...@@ -133,6 +140,7 @@ config SND_SOC_INTEL_CHT_BSW_RT5645_MACH ...@@ -133,6 +140,7 @@ config SND_SOC_INTEL_CHT_BSW_RT5645_MACH
select SND_SOC_RT5645 select SND_SOC_RT5645
select SND_SST_MFLD_PLATFORM select SND_SST_MFLD_PLATFORM
select SND_SST_IPC_ACPI select SND_SST_IPC_ACPI
select SND_SOC_INTEL_SST_MATCH if ACPI
help help
This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell
platforms with RT5645/5650 audio codec. platforms with RT5645/5650 audio codec.
...@@ -145,6 +153,7 @@ config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH ...@@ -145,6 +153,7 @@ config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH
select SND_SOC_TS3A227E select SND_SOC_TS3A227E
select SND_SST_MFLD_PLATFORM select SND_SST_MFLD_PLATFORM
select SND_SST_IPC_ACPI select SND_SST_IPC_ACPI
select SND_SOC_INTEL_SST_MATCH if ACPI
help help
This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell
platforms with MAX98090 audio codec it also can support TI jack chip as aux device. platforms with MAX98090 audio codec it also can support TI jack chip as aux device.
......
...@@ -528,6 +528,7 @@ static struct snd_soc_dai_driver sst_platform_dai[] = { ...@@ -528,6 +528,7 @@ static struct snd_soc_dai_driver sst_platform_dai[] = {
.ops = &sst_compr_dai_ops, .ops = &sst_compr_dai_ops,
.playback = { .playback = {
.stream_name = "Compress Playback", .stream_name = "Compress Playback",
.channels_min = 1,
}, },
}, },
/* BE CPU Dais */ /* BE CPU Dais */
......
...@@ -212,7 +212,10 @@ static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd, ...@@ -212,7 +212,10 @@ static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd,
{ {
struct snd_interval *channels = hw_param_interval(params, struct snd_interval *channels = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS); SNDRV_PCM_HW_PARAM_CHANNELS);
channels->min = channels->max = 4; if (params_channels(params) == 2)
channels->min = channels->max = 2;
else
channels->min = channels->max = 4;
return 0; return 0;
} }
......
snd-soc-sst-dsp-objs := sst-dsp.o snd-soc-sst-dsp-objs := sst-dsp.o
ifneq ($(CONFIG_SND_SST_IPC_ACPI),) snd-soc-sst-acpi-objs := sst-acpi.o
snd-soc-sst-acpi-objs := sst-match-acpi.o snd-soc-sst-match-objs := sst-match-acpi.o
else
snd-soc-sst-acpi-objs := sst-acpi.o sst-match-acpi.o
endif
snd-soc-sst-ipc-objs := sst-ipc.o snd-soc-sst-ipc-objs := sst-ipc.o
snd-soc-sst-dsp-$(CONFIG_DW_DMAC_CORE) += sst-firmware.o snd-soc-sst-dsp-$(CONFIG_DW_DMAC_CORE) += sst-firmware.o
obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o
obj-$(CONFIG_SND_SOC_INTEL_SST_ACPI) += snd-soc-sst-acpi.o obj-$(CONFIG_SND_SOC_INTEL_SST_ACPI) += snd-soc-sst-acpi.o
obj-$(CONFIG_SND_SOC_INTEL_SST_MATCH) += snd-soc-sst-match.o
...@@ -215,6 +215,7 @@ static struct sst_acpi_desc sst_acpi_broadwell_desc = { ...@@ -215,6 +215,7 @@ static struct sst_acpi_desc sst_acpi_broadwell_desc = {
.dma_size = SST_LPT_DSP_DMA_SIZE, .dma_size = SST_LPT_DSP_DMA_SIZE,
}; };
#if !IS_ENABLED(CONFIG_SND_SST_IPC_ACPI)
static struct sst_acpi_mach baytrail_machines[] = { static struct sst_acpi_mach baytrail_machines[] = {
{ "10EC5640", "byt-rt5640", "intel/fw_sst_0f28.bin-48kHz_i2s_master", NULL, NULL, NULL }, { "10EC5640", "byt-rt5640", "intel/fw_sst_0f28.bin-48kHz_i2s_master", NULL, NULL, NULL },
{ "193C9890", "byt-max98090", "intel/fw_sst_0f28.bin-48kHz_i2s_master", NULL, NULL, NULL }, { "193C9890", "byt-max98090", "intel/fw_sst_0f28.bin-48kHz_i2s_master", NULL, NULL, NULL },
...@@ -231,11 +232,14 @@ static struct sst_acpi_desc sst_acpi_baytrail_desc = { ...@@ -231,11 +232,14 @@ static struct sst_acpi_desc sst_acpi_baytrail_desc = {
.sst_id = SST_DEV_ID_BYT, .sst_id = SST_DEV_ID_BYT,
.resindex_dma_base = -1, .resindex_dma_base = -1,
}; };
#endif
static const struct acpi_device_id sst_acpi_match[] = { static const struct acpi_device_id sst_acpi_match[] = {
{ "INT33C8", (unsigned long)&sst_acpi_haswell_desc }, { "INT33C8", (unsigned long)&sst_acpi_haswell_desc },
{ "INT3438", (unsigned long)&sst_acpi_broadwell_desc }, { "INT3438", (unsigned long)&sst_acpi_broadwell_desc },
#if !IS_ENABLED(CONFIG_SND_SST_IPC_ACPI)
{ "80860F28", (unsigned long)&sst_acpi_baytrail_desc }, { "80860F28", (unsigned long)&sst_acpi_baytrail_desc },
#endif
{ } { }
}; };
MODULE_DEVICE_TABLE(acpi, sst_acpi_match); MODULE_DEVICE_TABLE(acpi, sst_acpi_match);
......
...@@ -41,3 +41,6 @@ struct sst_acpi_mach *sst_acpi_find_machine(struct sst_acpi_mach *machines) ...@@ -41,3 +41,6 @@ struct sst_acpi_mach *sst_acpi_find_machine(struct sst_acpi_mach *machines)
return NULL; return NULL;
} }
EXPORT_SYMBOL_GPL(sst_acpi_find_machine); EXPORT_SYMBOL_GPL(sst_acpi_find_machine);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Intel Common ACPI Match module");
...@@ -688,14 +688,14 @@ int skl_unbind_modules(struct skl_sst *ctx, ...@@ -688,14 +688,14 @@ int skl_unbind_modules(struct skl_sst *ctx,
/* get src queue index */ /* get src queue index */
src_index = skl_get_queue_index(src_mcfg->m_out_pin, dst_id, out_max); src_index = skl_get_queue_index(src_mcfg->m_out_pin, dst_id, out_max);
if (src_index < 0) if (src_index < 0)
return -EINVAL; return 0;
msg.src_queue = src_index; msg.src_queue = src_index;
/* get dst queue index */ /* get dst queue index */
dst_index = skl_get_queue_index(dst_mcfg->m_in_pin, src_id, in_max); dst_index = skl_get_queue_index(dst_mcfg->m_in_pin, src_id, in_max);
if (dst_index < 0) if (dst_index < 0)
return -EINVAL; return 0;
msg.dst_queue = dst_index; msg.dst_queue = dst_index;
...@@ -747,7 +747,7 @@ int skl_bind_modules(struct skl_sst *ctx, ...@@ -747,7 +747,7 @@ int skl_bind_modules(struct skl_sst *ctx,
skl_dump_bind_info(ctx, src_mcfg, dst_mcfg); skl_dump_bind_info(ctx, src_mcfg, dst_mcfg);
if (src_mcfg->m_state < SKL_MODULE_INIT_DONE && if (src_mcfg->m_state < SKL_MODULE_INIT_DONE ||
dst_mcfg->m_state < SKL_MODULE_INIT_DONE) dst_mcfg->m_state < SKL_MODULE_INIT_DONE)
return 0; return 0;
......
...@@ -863,6 +863,7 @@ static int skl_get_delay_from_lpib(struct hdac_ext_bus *ebus, ...@@ -863,6 +863,7 @@ static int skl_get_delay_from_lpib(struct hdac_ext_bus *ebus,
else else
delay += hstream->bufsize; delay += hstream->bufsize;
} }
delay = (hstream->bufsize == delay) ? 0 : delay;
if (delay >= hstream->period_bytes) { if (delay >= hstream->period_bytes) {
dev_info(bus->dev, dev_info(bus->dev,
......
...@@ -54,12 +54,9 @@ static int is_skl_dsp_widget_type(struct snd_soc_dapm_widget *w) ...@@ -54,12 +54,9 @@ static int is_skl_dsp_widget_type(struct snd_soc_dapm_widget *w)
/* /*
* Each pipelines needs memory to be allocated. Check if we have free memory * Each pipelines needs memory to be allocated. Check if we have free memory
* from available pool. Then only add this to pool * from available pool.
* This is freed when pipe is deleted
* Note: DSP does actual memory management we only keep track for complete
* pool
*/ */
static bool skl_tplg_alloc_pipe_mem(struct skl *skl, static bool skl_is_pipe_mem_avail(struct skl *skl,
struct skl_module_cfg *mconfig) struct skl_module_cfg *mconfig)
{ {
struct skl_sst *ctx = skl->skl_sst; struct skl_sst *ctx = skl->skl_sst;
...@@ -74,10 +71,20 @@ static bool skl_tplg_alloc_pipe_mem(struct skl *skl, ...@@ -74,10 +71,20 @@ static bool skl_tplg_alloc_pipe_mem(struct skl *skl,
"exceeds ppl memory available %d mem %d\n", "exceeds ppl memory available %d mem %d\n",
skl->resource.max_mem, skl->resource.mem); skl->resource.max_mem, skl->resource.mem);
return false; return false;
} else {
return true;
} }
}
/*
* Add the mem to the mem pool. This is freed when pipe is deleted.
* Note: DSP does actual memory management we only keep track for complete
* pool
*/
static void skl_tplg_alloc_pipe_mem(struct skl *skl,
struct skl_module_cfg *mconfig)
{
skl->resource.mem += mconfig->pipe->memory_pages; skl->resource.mem += mconfig->pipe->memory_pages;
return true;
} }
/* /*
...@@ -85,10 +92,10 @@ static bool skl_tplg_alloc_pipe_mem(struct skl *skl, ...@@ -85,10 +92,10 @@ static bool skl_tplg_alloc_pipe_mem(struct skl *skl,
* quantified in MCPS (Million Clocks Per Second) required for module/pipe * quantified in MCPS (Million Clocks Per Second) required for module/pipe
* *
* Each pipelines needs mcps to be allocated. Check if we have mcps for this * Each pipelines needs mcps to be allocated. Check if we have mcps for this
* pipe. This adds the mcps to driver counter * pipe.
* This is removed on pipeline delete
*/ */
static bool skl_tplg_alloc_pipe_mcps(struct skl *skl,
static bool skl_is_pipe_mcps_avail(struct skl *skl,
struct skl_module_cfg *mconfig) struct skl_module_cfg *mconfig)
{ {
struct skl_sst *ctx = skl->skl_sst; struct skl_sst *ctx = skl->skl_sst;
...@@ -98,13 +105,18 @@ static bool skl_tplg_alloc_pipe_mcps(struct skl *skl, ...@@ -98,13 +105,18 @@ static bool skl_tplg_alloc_pipe_mcps(struct skl *skl,
"%s: module_id %d instance %d\n", __func__, "%s: module_id %d instance %d\n", __func__,
mconfig->id.module_id, mconfig->id.instance_id); mconfig->id.module_id, mconfig->id.instance_id);
dev_err(ctx->dev, dev_err(ctx->dev,
"exceeds ppl memory available %d > mem %d\n", "exceeds ppl mcps available %d > mem %d\n",
skl->resource.max_mcps, skl->resource.mcps); skl->resource.max_mcps, skl->resource.mcps);
return false; return false;
} else {
return true;
} }
}
static void skl_tplg_alloc_pipe_mcps(struct skl *skl,
struct skl_module_cfg *mconfig)
{
skl->resource.mcps += mconfig->mcps; skl->resource.mcps += mconfig->mcps;
return true;
} }
/* /*
...@@ -411,7 +423,7 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) ...@@ -411,7 +423,7 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
mconfig = w->priv; mconfig = w->priv;
/* check resource available */ /* check resource available */
if (!skl_tplg_alloc_pipe_mcps(skl, mconfig)) if (!skl_is_pipe_mcps_avail(skl, mconfig))
return -ENOMEM; return -ENOMEM;
if (mconfig->is_loadable && ctx->dsp->fw_ops.load_mod) { if (mconfig->is_loadable && ctx->dsp->fw_ops.load_mod) {
...@@ -435,6 +447,7 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) ...@@ -435,6 +447,7 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
ret = skl_tplg_set_module_params(w, ctx); ret = skl_tplg_set_module_params(w, ctx);
if (ret < 0) if (ret < 0)
return ret; return ret;
skl_tplg_alloc_pipe_mcps(skl, mconfig);
} }
return 0; return 0;
...@@ -477,10 +490,10 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, ...@@ -477,10 +490,10 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
struct skl_sst *ctx = skl->skl_sst; struct skl_sst *ctx = skl->skl_sst;
/* check resource available */ /* check resource available */
if (!skl_tplg_alloc_pipe_mcps(skl, mconfig)) if (!skl_is_pipe_mcps_avail(skl, mconfig))
return -EBUSY; return -EBUSY;
if (!skl_tplg_alloc_pipe_mem(skl, mconfig)) if (!skl_is_pipe_mem_avail(skl, mconfig))
return -ENOMEM; return -ENOMEM;
/* /*
...@@ -526,11 +539,15 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, ...@@ -526,11 +539,15 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
src_module = dst_module; src_module = dst_module;
} }
skl_tplg_alloc_pipe_mem(skl, mconfig);
skl_tplg_alloc_pipe_mcps(skl, mconfig);
return 0; return 0;
} }
static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w, static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
struct skl *skl, struct skl *skl,
struct snd_soc_dapm_widget *src_w,
struct skl_module_cfg *src_mconfig) struct skl_module_cfg *src_mconfig)
{ {
struct snd_soc_dapm_path *p; struct snd_soc_dapm_path *p;
...@@ -547,6 +564,10 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w, ...@@ -547,6 +564,10 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
dev_dbg(ctx->dev, "%s: sink widget=%s\n", __func__, p->sink->name); dev_dbg(ctx->dev, "%s: sink widget=%s\n", __func__, p->sink->name);
next_sink = p->sink; next_sink = p->sink;
if (!is_skl_dsp_widget_type(p->sink))
return skl_tplg_bind_sinks(p->sink, skl, src_w, src_mconfig);
/* /*
* here we will check widgets in sink pipelines, so that * here we will check widgets in sink pipelines, so that
* can be any widgets type and we are only interested if * can be any widgets type and we are only interested if
...@@ -576,7 +597,7 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w, ...@@ -576,7 +597,7 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w,
} }
if (!sink) if (!sink)
return skl_tplg_bind_sinks(next_sink, skl, src_mconfig); return skl_tplg_bind_sinks(next_sink, skl, src_w, src_mconfig);
return 0; return 0;
} }
...@@ -605,7 +626,7 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, ...@@ -605,7 +626,7 @@ static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
* if sink is not started, start sink pipe first, then start * if sink is not started, start sink pipe first, then start
* this pipe * this pipe
*/ */
ret = skl_tplg_bind_sinks(w, skl, src_mconfig); ret = skl_tplg_bind_sinks(w, skl, w, src_mconfig);
if (ret) if (ret)
return ret; return ret;
...@@ -773,10 +794,7 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, ...@@ -773,10 +794,7 @@ static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
continue; continue;
} }
ret = skl_unbind_modules(ctx, src_module, dst_module); skl_unbind_modules(ctx, src_module, dst_module);
if (ret < 0)
return ret;
src_module = dst_module; src_module = dst_module;
} }
...@@ -814,9 +832,6 @@ static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, ...@@ -814,9 +832,6 @@ static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
* This is a connecter and if path is found that means * This is a connecter and if path is found that means
* unbind between source and sink has not happened yet * unbind between source and sink has not happened yet
*/ */
ret = skl_stop_pipe(ctx, sink_mconfig->pipe);
if (ret < 0)
return ret;
ret = skl_unbind_modules(ctx, src_mconfig, ret = skl_unbind_modules(ctx, src_mconfig,
sink_mconfig); sink_mconfig);
} }
...@@ -842,6 +857,12 @@ static int skl_tplg_vmixer_event(struct snd_soc_dapm_widget *w, ...@@ -842,6 +857,12 @@ static int skl_tplg_vmixer_event(struct snd_soc_dapm_widget *w,
case SND_SOC_DAPM_PRE_PMU: case SND_SOC_DAPM_PRE_PMU:
return skl_tplg_mixer_dapm_pre_pmu_event(w, skl); return skl_tplg_mixer_dapm_pre_pmu_event(w, skl);
case SND_SOC_DAPM_POST_PMU:
return skl_tplg_mixer_dapm_post_pmu_event(w, skl);
case SND_SOC_DAPM_PRE_PMD:
return skl_tplg_mixer_dapm_pre_pmd_event(w, skl);
case SND_SOC_DAPM_POST_PMD: case SND_SOC_DAPM_POST_PMD:
return skl_tplg_mixer_dapm_post_pmd_event(w, skl); return skl_tplg_mixer_dapm_post_pmd_event(w, skl);
} }
...@@ -916,6 +937,13 @@ static int skl_tplg_tlv_control_get(struct snd_kcontrol *kcontrol, ...@@ -916,6 +937,13 @@ static int skl_tplg_tlv_control_get(struct snd_kcontrol *kcontrol,
skl_get_module_params(skl->skl_sst, (u32 *)bc->params, skl_get_module_params(skl->skl_sst, (u32 *)bc->params,
bc->max, bc->param_id, mconfig); bc->max, bc->param_id, mconfig);
/* decrement size for TLV header */
size -= 2 * sizeof(u32);
/* check size as we don't want to send kernel data */
if (size > bc->max)
size = bc->max;
if (bc->params) { if (bc->params) {
if (copy_to_user(data, &bc->param_id, sizeof(u32))) if (copy_to_user(data, &bc->param_id, sizeof(u32)))
return -EFAULT; return -EFAULT;
...@@ -1510,6 +1538,7 @@ int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus) ...@@ -1510,6 +1538,7 @@ int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus)
&skl_tplg_ops, fw, 0); &skl_tplg_ops, fw, 0);
if (ret < 0) { if (ret < 0) {
dev_err(bus->dev, "tplg component load failed%d\n", ret); dev_err(bus->dev, "tplg component load failed%d\n", ret);
release_firmware(fw);
return -EINVAL; return -EINVAL;
} }
......
...@@ -614,8 +614,6 @@ static int skl_probe(struct pci_dev *pci, ...@@ -614,8 +614,6 @@ static int skl_probe(struct pci_dev *pci,
goto out_unregister; goto out_unregister;
/*configure PM */ /*configure PM */
pm_runtime_set_autosuspend_delay(bus->dev, SKL_SUSPEND_DELAY);
pm_runtime_use_autosuspend(bus->dev);
pm_runtime_put_noidle(bus->dev); pm_runtime_put_noidle(bus->dev);
pm_runtime_allow(bus->dev); pm_runtime_allow(bus->dev);
......
...@@ -9,7 +9,7 @@ config SND_SOC_MEDIATEK ...@@ -9,7 +9,7 @@ config SND_SOC_MEDIATEK
config SND_SOC_MT8173_MAX98090 config SND_SOC_MT8173_MAX98090
tristate "ASoC Audio driver for MT8173 with MAX98090 codec" tristate "ASoC Audio driver for MT8173 with MAX98090 codec"
depends on SND_SOC_MEDIATEK depends on SND_SOC_MEDIATEK && I2C
select SND_SOC_MAX98090 select SND_SOC_MAX98090
help help
This adds ASoC driver for Mediatek MT8173 boards This adds ASoC driver for Mediatek MT8173 boards
...@@ -19,7 +19,7 @@ config SND_SOC_MT8173_MAX98090 ...@@ -19,7 +19,7 @@ config SND_SOC_MT8173_MAX98090
config SND_SOC_MT8173_RT5650_RT5676 config SND_SOC_MT8173_RT5650_RT5676
tristate "ASoC Audio driver for MT8173 with RT5650 RT5676 codecs" tristate "ASoC Audio driver for MT8173 with RT5650 RT5676 codecs"
depends on SND_SOC_MEDIATEK depends on SND_SOC_MEDIATEK && I2C
select SND_SOC_RT5645 select SND_SOC_RT5645
select SND_SOC_RT5677 select SND_SOC_RT5677
help help
......
...@@ -381,9 +381,19 @@ static int mxs_saif_startup(struct snd_pcm_substream *substream, ...@@ -381,9 +381,19 @@ static int mxs_saif_startup(struct snd_pcm_substream *substream,
__raw_writel(BM_SAIF_CTRL_CLKGATE, __raw_writel(BM_SAIF_CTRL_CLKGATE,
saif->base + SAIF_CTRL + MXS_CLR_ADDR); saif->base + SAIF_CTRL + MXS_CLR_ADDR);
clk_prepare(saif->clk);
return 0; return 0;
} }
static void mxs_saif_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
clk_unprepare(saif->clk);
}
/* /*
* Should only be called when port is inactive. * Should only be called when port is inactive.
* although can be called multiple times by upper layers. * although can be called multiple times by upper layers.
...@@ -424,8 +434,6 @@ static int mxs_saif_hw_params(struct snd_pcm_substream *substream, ...@@ -424,8 +434,6 @@ static int mxs_saif_hw_params(struct snd_pcm_substream *substream,
return ret; return ret;
} }
/* prepare clk in hw_param, enable in trigger */
clk_prepare(saif->clk);
if (saif != master_saif) { if (saif != master_saif) {
/* /*
* Set an initial clock rate for the saif internal logic to work * Set an initial clock rate for the saif internal logic to work
...@@ -611,6 +619,7 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd, ...@@ -611,6 +619,7 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd,
static const struct snd_soc_dai_ops mxs_saif_dai_ops = { static const struct snd_soc_dai_ops mxs_saif_dai_ops = {
.startup = mxs_saif_startup, .startup = mxs_saif_startup,
.shutdown = mxs_saif_shutdown,
.trigger = mxs_saif_trigger, .trigger = mxs_saif_trigger,
.prepare = mxs_saif_prepare, .prepare = mxs_saif_prepare,
.hw_params = mxs_saif_hw_params, .hw_params = mxs_saif_hw_params,
......
...@@ -440,18 +440,18 @@ static irqreturn_t lpass_platform_lpaif_irq(int irq, void *data) ...@@ -440,18 +440,18 @@ static irqreturn_t lpass_platform_lpaif_irq(int irq, void *data)
} }
static int lpass_platform_alloc_buffer(struct snd_pcm_substream *substream, static int lpass_platform_alloc_buffer(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *soc_runtime) struct snd_soc_pcm_runtime *rt)
{ {
struct snd_dma_buffer *buf = &substream->dma_buffer; struct snd_dma_buffer *buf = &substream->dma_buffer;
size_t size = lpass_platform_pcm_hardware.buffer_bytes_max; size_t size = lpass_platform_pcm_hardware.buffer_bytes_max;
buf->dev.type = SNDRV_DMA_TYPE_DEV; buf->dev.type = SNDRV_DMA_TYPE_DEV;
buf->dev.dev = soc_runtime->dev; buf->dev.dev = rt->platform->dev;
buf->private_data = NULL; buf->private_data = NULL;
buf->area = dma_alloc_coherent(soc_runtime->dev, size, &buf->addr, buf->area = dma_alloc_coherent(rt->platform->dev, size, &buf->addr,
GFP_KERNEL); GFP_KERNEL);
if (!buf->area) { if (!buf->area) {
dev_err(soc_runtime->dev, "%s: Could not allocate DMA buffer\n", dev_err(rt->platform->dev, "%s: Could not allocate DMA buffer\n",
__func__); __func__);
return -ENOMEM; return -ENOMEM;
} }
...@@ -461,12 +461,12 @@ static int lpass_platform_alloc_buffer(struct snd_pcm_substream *substream, ...@@ -461,12 +461,12 @@ static int lpass_platform_alloc_buffer(struct snd_pcm_substream *substream,
} }
static void lpass_platform_free_buffer(struct snd_pcm_substream *substream, static void lpass_platform_free_buffer(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *soc_runtime) struct snd_soc_pcm_runtime *rt)
{ {
struct snd_dma_buffer *buf = &substream->dma_buffer; struct snd_dma_buffer *buf = &substream->dma_buffer;
if (buf->area) { if (buf->area) {
dma_free_coherent(soc_runtime->dev, buf->bytes, buf->area, dma_free_coherent(rt->dev, buf->bytes, buf->area,
buf->addr); buf->addr);
} }
buf->area = NULL; buf->area = NULL;
...@@ -499,9 +499,6 @@ static int lpass_platform_pcm_new(struct snd_soc_pcm_runtime *soc_runtime) ...@@ -499,9 +499,6 @@ static int lpass_platform_pcm_new(struct snd_soc_pcm_runtime *soc_runtime)
snd_soc_pcm_set_drvdata(soc_runtime, data); snd_soc_pcm_set_drvdata(soc_runtime, data);
soc_runtime->dev->coherent_dma_mask = DMA_BIT_MASK(32);
soc_runtime->dev->dma_mask = &soc_runtime->dev->coherent_dma_mask;
ret = lpass_platform_alloc_buffer(substream, soc_runtime); ret = lpass_platform_alloc_buffer(substream, soc_runtime);
if (ret) if (ret)
return ret; return ret;
......
...@@ -310,7 +310,7 @@ struct dapm_kcontrol_data { ...@@ -310,7 +310,7 @@ struct dapm_kcontrol_data {
}; };
static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget, static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget,
struct snd_kcontrol *kcontrol) struct snd_kcontrol *kcontrol, const char *ctrl_name)
{ {
struct dapm_kcontrol_data *data; struct dapm_kcontrol_data *data;
struct soc_mixer_control *mc; struct soc_mixer_control *mc;
...@@ -333,7 +333,7 @@ static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget, ...@@ -333,7 +333,7 @@ static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget,
if (mc->autodisable) { if (mc->autodisable) {
struct snd_soc_dapm_widget template; struct snd_soc_dapm_widget template;
name = kasprintf(GFP_KERNEL, "%s %s", kcontrol->id.name, name = kasprintf(GFP_KERNEL, "%s %s", ctrl_name,
"Autodisable"); "Autodisable");
if (!name) { if (!name) {
ret = -ENOMEM; ret = -ENOMEM;
...@@ -371,7 +371,7 @@ static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget, ...@@ -371,7 +371,7 @@ static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget,
if (e->autodisable) { if (e->autodisable) {
struct snd_soc_dapm_widget template; struct snd_soc_dapm_widget template;
name = kasprintf(GFP_KERNEL, "%s %s", kcontrol->id.name, name = kasprintf(GFP_KERNEL, "%s %s", ctrl_name,
"Autodisable"); "Autodisable");
if (!name) { if (!name) {
ret = -ENOMEM; ret = -ENOMEM;
...@@ -871,7 +871,7 @@ static int dapm_create_or_share_kcontrol(struct snd_soc_dapm_widget *w, ...@@ -871,7 +871,7 @@ static int dapm_create_or_share_kcontrol(struct snd_soc_dapm_widget *w,
kcontrol->private_free = dapm_kcontrol_free; kcontrol->private_free = dapm_kcontrol_free;
ret = dapm_kcontrol_data_alloc(w, kcontrol); ret = dapm_kcontrol_data_alloc(w, kcontrol, name);
if (ret) { if (ret) {
snd_ctl_free_one(kcontrol); snd_ctl_free_one(kcontrol);
goto exit_free; goto exit_free;
......
...@@ -1810,7 +1810,8 @@ int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream) ...@@ -1810,7 +1810,8 @@ int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream)
(be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) && (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) &&
(be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) && (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) &&
(be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED) && (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED) &&
(be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) &&
(be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND))
continue; continue;
dev_dbg(be->dev, "ASoC: hw_free BE %s\n", dev_dbg(be->dev, "ASoC: hw_free BE %s\n",
......
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