sound fixes for 5.11-rc6

Although the incoming fixes haven't settled down yet, all changes
 here are small and mostly device-specific fixes, so nothing look
 worrisome.
 
 - Yet another USB-audio regression fixes
 - HD-audio ID fix and device-specific quirks
 - SOF Intel / SoundWire fixes including topology
 - ASoC Qualcomm and Mediatek fixes
 -----BEGIN PGP SIGNATURE-----
 
 iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmAScssOHHRpd2FpQHN1
 c2UuZGUACgkQLtJE4w1nLE8mmw//ao2U5h564+N8VPbY/ftGtm5MqF7T9Fd+DgGH
 xBu3tSG7ZHjEACWDOQ8J2MA6filbNlFkPi8sm8JpCXoVhllBTlpTTJY4eFiE4bQ+
 stJgFkhUKJ6eRePWpNE1txAuwdYfGG3eS7gd51lrKsN19kpx6fXgSnXP4RqhCokf
 SikAwrZsWQZR9zvBWNnnW6Jw4UPVKhO1cC79ia5ZwvDls4DsA8yscwzo7aDWS346
 roh8Q/+Pf9k+/wJcbComHZzV11LJ/VUF0jwI2L3VX4US2saP/I9reHz9AO0jhS6V
 VL4U6EPy+EFGVGhtYGR8dcxBk7PnOnhcZlNsbYa3OhPwL9YMXFE7n6glBvSLLWCU
 gGxsp8OwRMFcUYD8M4y1dCD3PZCS5gOp3k7ko3McbU6PWmpBQujuzwmXOdYkeBMR
 9L9I9Al/6PVZN4NB7j4rLGTEgXfspvAenjERo3VP78qBIeg9xUpr++5aePSJMeXS
 g9q5Dr/urW0aQEqhSbF80719eWBHSXYvS72hq3wjbSZOszaySEWpewtHc+64PjNE
 AebGjd/UUTiGs1LsGkurnwABRMvz/gQLKWszfxOnL8nsX5+SmK7d5ruYrMa0KEAm
 KU/yBDhXmC+QdpB5p1wTM21bHOKvW76PBrpnWPSl6ulm1cK1xOiMC5n7fXwaARfM
 jB4u1xs=
 =IWq4
 -----END PGP SIGNATURE-----

Merge tag 'sound-5.11-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
 "Although the incoming fixes haven't settled down yet, all changes here
  are small and mostly device-specific fixes, so nothing look worrisome.

   - Yet another USB-audio regression fixes

   - HD-audio ID fix and device-specific quirks

   - SOF Intel / SoundWire fixes including topology

   - ASoC Qualcomm and Mediatek fixes"

* tag 'sound-5.11-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (24 commits)
  ALSA: hda/via: Apply the workaround generically for Clevo machines
  ASoC: Intel: sof_sdw: set proper flags for Dell TGL-H SKU 0A5E
  ASoC: qcom: lpass: Fix out-of-bounds DAI ID lookup
  ASoC: mediatek: mt8192-mt6359: add format constraints for RT5682
  ASoC: ak4458: correct reset polarity
  ASoC: SOF: SND_INTEL_DSP_CONFIG dependency
  ASoC: SOF: Intel: soundwire: fix select/depend unmet dependencies
  ALSA: hda: intel-dsp-config: add PCI id for TGL-H
  ALSA: usb-audio: workaround for iface reset issue
  ALSA: pcm: One more dependency for hw constraints
  ALSA: hda/realtek: Enable headset of ASUS B1400CEPE with ALC256
  ASoC: Intel: Skylake: Zero snd_ctl_elem_value
  ASoC: Intel: Skylake: skl-topology: Fix OOPs ib skl_tplg_complete
  ASoC: qcom: Fix number of HDMI RDMA channels on sc7180
  ASoC: mediatek: mt8183-da7219: ignore TDM DAI link by default
  ASoC: mediatek: mt8183-mt6358: ignore TDM DAI link by default
  ASoC: topology: Properly unregister DAI on removal
  ASoC: topology: Fix memory corruption in soc_tplg_denum_create_values()
  ASoC: qcom: lpass-ipq806x: fix bitwidth regmap field
  ASoC: AMD Renoir - refine DMI entries for some Lenovo products
  ...
This commit is contained in:
Linus Torvalds 2021-01-28 09:06:52 -08:00
commit be4a338596
28 changed files with 204 additions and 65 deletions

View File

@ -7,8 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Mediatek MT8192 with MT6359, RT1015 and RT5682 ASoC sound card driver title: Mediatek MT8192 with MT6359, RT1015 and RT5682 ASoC sound card driver
maintainers: maintainers:
- Jiaxin Yu <jiaxin.yu@mediatek.com> - Jiaxin Yu <jiaxin.yu@mediatek.com>
- Shane Chien <shane.chien@mediatek.com> - Shane Chien <shane.chien@mediatek.com>
description: description:
This binding describes the MT8192 sound card. This binding describes the MT8192 sound card.

View File

@ -2,9 +2,8 @@
#ifndef __DT_APQ8016_LPASS_H #ifndef __DT_APQ8016_LPASS_H
#define __DT_APQ8016_LPASS_H #define __DT_APQ8016_LPASS_H
#define MI2S_PRIMARY 0 #include <dt-bindings/sound/qcom,lpass.h>
#define MI2S_SECONDARY 1
#define MI2S_TERTIARY 2 /* NOTE: Use qcom,lpass.h to define any AIF ID's for LPASS */
#define MI2S_QUATERNARY 3
#endif /* __DT_APQ8016_LPASS_H */ #endif /* __DT_APQ8016_LPASS_H */

View File

@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __DT_QCOM_LPASS_H
#define __DT_QCOM_LPASS_H
#define MI2S_PRIMARY 0
#define MI2S_SECONDARY 1
#define MI2S_TERTIARY 2
#define MI2S_QUATERNARY 3
#define MI2S_QUINARY 4
#define LPASS_DP_RX 5
#define LPASS_MCLK0 0
#endif /* __DT_QCOM_LPASS_H */

View File

@ -2,10 +2,8 @@
#ifndef __DT_SC7180_LPASS_H #ifndef __DT_SC7180_LPASS_H
#define __DT_SC7180_LPASS_H #define __DT_SC7180_LPASS_H
#define MI2S_PRIMARY 0 #include <dt-bindings/sound/qcom,lpass.h>
#define MI2S_SECONDARY 1
#define LPASS_DP_RX 2
#define LPASS_MCLK0 0 /* NOTE: Use qcom,lpass.h to define any AIF ID's for LPASS */
#endif /* __DT_APQ8016_LPASS_H */ #endif /* __DT_APQ8016_LPASS_H */

View File

@ -229,7 +229,7 @@ typedef int (*snd_pcm_hw_rule_func_t)(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule { struct snd_pcm_hw_rule {
unsigned int cond; unsigned int cond;
int var; int var;
int deps[4]; int deps[5];
snd_pcm_hw_rule_func_t func; snd_pcm_hw_rule_func_t func;
void *private; void *private;

View File

@ -382,8 +382,8 @@ retry:
continue; continue;
/* /*
* The 'deps' array includes maximum three dependencies * The 'deps' array includes maximum four dependencies
* to SNDRV_PCM_HW_PARAM_XXXs for this rule. The fourth * to SNDRV_PCM_HW_PARAM_XXXs for this rule. The fifth
* member of this array is a sentinel and should be * member of this array is a sentinel and should be
* negative value. * negative value.
* *

View File

@ -307,6 +307,10 @@ static const struct config_entry config_table[] = {
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
.device = 0xa0c8, .device = 0xa0c8,
}, },
{
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
.device = 0x43c8,
},
#endif #endif
/* Elkhart Lake */ /* Elkhart Lake */

View File

@ -8006,6 +8006,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC), SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC),
SND_PCI_QUIRK(0x1043, 0x18f1, "Asus FX505DT", ALC256_FIXUP_ASUS_HEADSET_MIC), SND_PCI_QUIRK(0x1043, 0x18f1, "Asus FX505DT", ALC256_FIXUP_ASUS_HEADSET_MIC),
SND_PCI_QUIRK(0x1043, 0x194e, "ASUS UX563FD", ALC294_FIXUP_ASUS_HPE), SND_PCI_QUIRK(0x1043, 0x194e, "ASUS UX563FD", ALC294_FIXUP_ASUS_HPE),
SND_PCI_QUIRK(0x1043, 0x1982, "ASUS B1400CEPE", ALC256_FIXUP_ASUS_HPE),
SND_PCI_QUIRK(0x1043, 0x19ce, "ASUS B9450FA", ALC294_FIXUP_ASUS_HPE), SND_PCI_QUIRK(0x1043, 0x19ce, "ASUS B9450FA", ALC294_FIXUP_ASUS_HPE),
SND_PCI_QUIRK(0x1043, 0x19e1, "ASUS UX581LV", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1043, 0x19e1, "ASUS UX581LV", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),

View File

@ -1043,7 +1043,7 @@ static const struct hda_fixup via_fixups[] = {
static const struct snd_pci_quirk vt2002p_fixups[] = { static const struct snd_pci_quirk vt2002p_fixups[] = {
SND_PCI_QUIRK(0x1043, 0x1487, "Asus G75", VIA_FIXUP_ASUS_G75), SND_PCI_QUIRK(0x1043, 0x1487, "Asus G75", VIA_FIXUP_ASUS_G75),
SND_PCI_QUIRK(0x1043, 0x8532, "Asus X202E", VIA_FIXUP_INTMIC_BOOST), SND_PCI_QUIRK(0x1043, 0x8532, "Asus X202E", VIA_FIXUP_INTMIC_BOOST),
SND_PCI_QUIRK(0x1558, 0x3501, "Clevo W35xSS_370SS", VIA_FIXUP_POWER_SAVE), SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", VIA_FIXUP_POWER_SAVE),
{} {}
}; };

View File

@ -165,10 +165,24 @@ static int rn_acp_deinit(void __iomem *acp_base)
static const struct dmi_system_id rn_acp_quirk_table[] = { static const struct dmi_system_id rn_acp_quirk_table[] = {
{ {
/* Lenovo IdeaPad Flex 5 14ARE05, IdeaPad 5 15ARE05 */ /* Lenovo IdeaPad S340-14API */
.matches = { .matches = {
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_EXACT_MATCH(DMI_BOARD_NAME, "LNVNB161216"), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "81NB"),
}
},
{
/* Lenovo IdeaPad Flex 5 14ARE05 */
.matches = {
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "81X2"),
}
},
{
/* Lenovo IdeaPad 5 15ARE05 */
.matches = {
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "81YQ"),
} }
}, },
{ {

View File

@ -595,18 +595,10 @@ static struct snd_soc_dai_driver ak4497_dai = {
.ops = &ak4458_dai_ops, .ops = &ak4458_dai_ops,
}; };
static void ak4458_power_off(struct ak4458_priv *ak4458) static void ak4458_reset(struct ak4458_priv *ak4458, bool active)
{ {
if (ak4458->reset_gpiod) { if (ak4458->reset_gpiod) {
gpiod_set_value_cansleep(ak4458->reset_gpiod, 0); gpiod_set_value_cansleep(ak4458->reset_gpiod, active);
usleep_range(1000, 2000);
}
}
static void ak4458_power_on(struct ak4458_priv *ak4458)
{
if (ak4458->reset_gpiod) {
gpiod_set_value_cansleep(ak4458->reset_gpiod, 1);
usleep_range(1000, 2000); usleep_range(1000, 2000);
} }
} }
@ -620,7 +612,7 @@ static int ak4458_init(struct snd_soc_component *component)
if (ak4458->mute_gpiod) if (ak4458->mute_gpiod)
gpiod_set_value_cansleep(ak4458->mute_gpiod, 1); gpiod_set_value_cansleep(ak4458->mute_gpiod, 1);
ak4458_power_on(ak4458); ak4458_reset(ak4458, false);
ret = snd_soc_component_update_bits(component, AK4458_00_CONTROL1, ret = snd_soc_component_update_bits(component, AK4458_00_CONTROL1,
0x80, 0x80); /* ACKS bit = 1; 10000000 */ 0x80, 0x80); /* ACKS bit = 1; 10000000 */
@ -650,7 +642,7 @@ static void ak4458_remove(struct snd_soc_component *component)
{ {
struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component); struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
ak4458_power_off(ak4458); ak4458_reset(ak4458, true);
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
@ -660,7 +652,7 @@ static int __maybe_unused ak4458_runtime_suspend(struct device *dev)
regcache_cache_only(ak4458->regmap, true); regcache_cache_only(ak4458->regmap, true);
ak4458_power_off(ak4458); ak4458_reset(ak4458, true);
if (ak4458->mute_gpiod) if (ak4458->mute_gpiod)
gpiod_set_value_cansleep(ak4458->mute_gpiod, 0); gpiod_set_value_cansleep(ak4458->mute_gpiod, 0);
@ -685,8 +677,8 @@ static int __maybe_unused ak4458_runtime_resume(struct device *dev)
if (ak4458->mute_gpiod) if (ak4458->mute_gpiod)
gpiod_set_value_cansleep(ak4458->mute_gpiod, 1); gpiod_set_value_cansleep(ak4458->mute_gpiod, 1);
ak4458_power_off(ak4458); ak4458_reset(ak4458, true);
ak4458_power_on(ak4458); ak4458_reset(ak4458, false);
regcache_cache_only(ak4458->regmap, false); regcache_cache_only(ak4458->regmap, false);
regcache_mark_dirty(ak4458->regmap); regcache_mark_dirty(ak4458->regmap);

View File

@ -2031,11 +2031,14 @@ static struct wm_coeff_ctl *wm_adsp_get_ctl(struct wm_adsp *dsp,
unsigned int alg) unsigned int alg)
{ {
struct wm_coeff_ctl *pos, *rslt = NULL; struct wm_coeff_ctl *pos, *rslt = NULL;
const char *fw_txt = wm_adsp_fw_text[dsp->fw];
list_for_each_entry(pos, &dsp->ctl_list, list) { list_for_each_entry(pos, &dsp->ctl_list, list) {
if (!pos->subname) if (!pos->subname)
continue; continue;
if (strncmp(pos->subname, name, pos->subname_len) == 0 && if (strncmp(pos->subname, name, pos->subname_len) == 0 &&
strncmp(pos->fw_name, fw_txt,
SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == 0 &&
pos->alg_region.alg == alg && pos->alg_region.alg == alg &&
pos->alg_region.type == type) { pos->alg_region.type == type) {
rslt = pos; rslt = pos;

View File

@ -67,6 +67,16 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
.driver_data = (void *)(SOF_RT711_JD_SRC_JD2 | .driver_data = (void *)(SOF_RT711_JD_SRC_JD2 |
SOF_RT715_DAI_ID_FIX), SOF_RT715_DAI_ID_FIX),
}, },
{
.callback = sof_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5E")
},
.driver_data = (void *)(SOF_RT711_JD_SRC_JD2 |
SOF_RT715_DAI_ID_FIX |
SOF_SDW_FOUR_SPK),
},
{ {
.callback = sof_sdw_quirk_cb, .callback = sof_sdw_quirk_cb,
.matches = { .matches = {

View File

@ -3619,19 +3619,20 @@ static void skl_tplg_complete(struct snd_soc_component *component)
list_for_each_entry(dobj, &component->dobj_list, list) { list_for_each_entry(dobj, &component->dobj_list, list) {
struct snd_kcontrol *kcontrol = dobj->control.kcontrol; struct snd_kcontrol *kcontrol = dobj->control.kcontrol;
struct soc_enum *se = struct soc_enum *se;
(struct soc_enum *)kcontrol->private_value; char **texts;
char **texts = dobj->control.dtexts;
char chan_text[4]; char chan_text[4];
if (dobj->type != SND_SOC_DOBJ_ENUM || if (dobj->type != SND_SOC_DOBJ_ENUM || !kcontrol ||
dobj->control.kcontrol->put != kcontrol->put != skl_tplg_multi_config_set_dmic)
skl_tplg_multi_config_set_dmic)
continue; continue;
se = (struct soc_enum *)kcontrol->private_value;
texts = dobj->control.dtexts;
sprintf(chan_text, "c%d", mach->mach_params.dmic_num); sprintf(chan_text, "c%d", mach->mach_params.dmic_num);
for (i = 0; i < se->items; i++) { for (i = 0; i < se->items; i++) {
struct snd_ctl_elem_value val; struct snd_ctl_elem_value val = {};
if (strstr(texts[i], chan_text)) { if (strstr(texts[i], chan_text)) {
val.value.enumerated.item[0] = i; val.value.enumerated.item[0] = i;

View File

@ -532,6 +532,7 @@ static struct snd_soc_dai_link mt8183_da7219_dai_links[] = {
.dpcm_playback = 1, .dpcm_playback = 1,
.ignore_suspend = 1, .ignore_suspend = 1,
.be_hw_params_fixup = mt8183_i2s_hw_params_fixup, .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
.ignore = 1,
.init = mt8183_da7219_max98357_hdmi_init, .init = mt8183_da7219_max98357_hdmi_init,
SND_SOC_DAILINK_REG(tdm), SND_SOC_DAILINK_REG(tdm),
}, },
@ -754,8 +755,10 @@ static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev)
} }
} }
if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) {
dai_link->codecs->of_node = hdmi_codec; dai_link->codecs->of_node = hdmi_codec;
dai_link->ignore = 0;
}
if (!dai_link->platforms->name) if (!dai_link->platforms->name)
dai_link->platforms->of_node = platform_node; dai_link->platforms->of_node = platform_node;

View File

@ -515,6 +515,7 @@ static struct snd_soc_dai_link mt8183_mt6358_ts3a227_dai_links[] = {
.ignore_suspend = 1, .ignore_suspend = 1,
.be_hw_params_fixup = mt8183_i2s_hw_params_fixup, .be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
.ops = &mt8183_mt6358_tdm_ops, .ops = &mt8183_mt6358_tdm_ops,
.ignore = 1,
.init = mt8183_mt6358_ts3a227_max98357_hdmi_init, .init = mt8183_mt6358_ts3a227_max98357_hdmi_init,
SND_SOC_DAILINK_REG(tdm), SND_SOC_DAILINK_REG(tdm),
}, },
@ -661,8 +662,10 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev)
SND_SOC_DAIFMT_CBM_CFM; SND_SOC_DAIFMT_CBM_CFM;
} }
if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) {
dai_link->codecs->of_node = hdmi_codec; dai_link->codecs->of_node = hdmi_codec;
dai_link->ignore = 0;
}
if (!dai_link->platforms->name) if (!dai_link->platforms->name)
dai_link->platforms->of_node = platform_node; dai_link->platforms->of_node = platform_node;

View File

@ -401,6 +401,53 @@ static const struct snd_soc_ops mt8192_mt6359_rt1015_rt5682_capture1_ops = {
.startup = mt8192_mt6359_rt1015_rt5682_cap1_startup, .startup = mt8192_mt6359_rt1015_rt5682_cap1_startup,
}; };
static int
mt8192_mt6359_rt5682_startup(struct snd_pcm_substream *substream)
{
static const unsigned int channels[] = {
1, 2
};
static const struct snd_pcm_hw_constraint_list constraints_channels = {
.count = ARRAY_SIZE(channels),
.list = channels,
.mask = 0,
};
static const unsigned int rates[] = {
48000
};
static const struct snd_pcm_hw_constraint_list constraints_rates = {
.count = ARRAY_SIZE(rates),
.list = rates,
.mask = 0,
};
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
int ret;
ret = snd_pcm_hw_constraint_list(runtime, 0,
SNDRV_PCM_HW_PARAM_CHANNELS,
&constraints_channels);
if (ret < 0) {
dev_err(rtd->dev, "hw_constraint_list channels failed\n");
return ret;
}
ret = snd_pcm_hw_constraint_list(runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
&constraints_rates);
if (ret < 0) {
dev_err(rtd->dev, "hw_constraint_list rate failed\n");
return ret;
}
return 0;
}
static const struct snd_soc_ops mt8192_mt6359_rt5682_ops = {
.startup = mt8192_mt6359_rt5682_startup,
};
/* FE */ /* FE */
SND_SOC_DAILINK_DEFS(playback1, SND_SOC_DAILINK_DEFS(playback1,
DAILINK_COMP_ARRAY(COMP_CPU("DL1")), DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
@ -648,6 +695,7 @@ static struct snd_soc_dai_link mt8192_mt6359_dai_links[] = {
SND_SOC_DPCM_TRIGGER_PRE}, SND_SOC_DPCM_TRIGGER_PRE},
.dynamic = 1, .dynamic = 1,
.dpcm_playback = 1, .dpcm_playback = 1,
.ops = &mt8192_mt6359_rt5682_ops,
SND_SOC_DAILINK_REG(playback3), SND_SOC_DAILINK_REG(playback3),
}, },
{ {
@ -721,6 +769,7 @@ static struct snd_soc_dai_link mt8192_mt6359_dai_links[] = {
SND_SOC_DPCM_TRIGGER_PRE}, SND_SOC_DPCM_TRIGGER_PRE},
.dynamic = 1, .dynamic = 1,
.dpcm_capture = 1, .dpcm_capture = 1,
.ops = &mt8192_mt6359_rt5682_ops,
SND_SOC_DAILINK_REG(capture2), SND_SOC_DAILINK_REG(capture2),
}, },
{ {

View File

@ -344,8 +344,30 @@ int asoc_qcom_lpass_cpu_dai_probe(struct snd_soc_dai *dai)
} }
EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_dai_probe); EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_dai_probe);
static int asoc_qcom_of_xlate_dai_name(struct snd_soc_component *component,
struct of_phandle_args *args,
const char **dai_name)
{
struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
struct lpass_variant *variant = drvdata->variant;
int id = args->args[0];
int ret = -EINVAL;
int i;
for (i = 0; i < variant->num_dai; i++) {
if (variant->dai_driver[i].id == id) {
*dai_name = variant->dai_driver[i].name;
ret = 0;
break;
}
}
return ret;
}
static const struct snd_soc_component_driver lpass_cpu_comp_driver = { static const struct snd_soc_component_driver lpass_cpu_comp_driver = {
.name = "lpass-cpu", .name = "lpass-cpu",
.of_xlate_dai_name = asoc_qcom_of_xlate_dai_name,
}; };
static bool lpass_cpu_regmap_writeable(struct device *dev, unsigned int reg) static bool lpass_cpu_regmap_writeable(struct device *dev, unsigned int reg)

View File

@ -131,7 +131,7 @@ static struct lpass_variant ipq806x_data = {
.micmode = REG_FIELD_ID(0x0010, 4, 7, 5, 0x4), .micmode = REG_FIELD_ID(0x0010, 4, 7, 5, 0x4),
.micmono = REG_FIELD_ID(0x0010, 3, 3, 5, 0x4), .micmono = REG_FIELD_ID(0x0010, 3, 3, 5, 0x4),
.wssrc = REG_FIELD_ID(0x0010, 2, 2, 5, 0x4), .wssrc = REG_FIELD_ID(0x0010, 2, 2, 5, 0x4),
.bitwidth = REG_FIELD_ID(0x0010, 0, 0, 5, 0x4), .bitwidth = REG_FIELD_ID(0x0010, 0, 1, 5, 0x4),
.rdma_dyncclk = REG_FIELD_ID(0x6000, 12, 12, 4, 0x1000), .rdma_dyncclk = REG_FIELD_ID(0x6000, 12, 12, 4, 0x1000),
.rdma_bursten = REG_FIELD_ID(0x6000, 11, 11, 4, 0x1000), .rdma_bursten = REG_FIELD_ID(0x6000, 11, 11, 4, 0x1000),

View File

@ -133,7 +133,7 @@
#define LPAIF_WRDMAPERCNT_REG(v, chan) LPAIF_WRDMA_REG_ADDR(v, 0x14, (chan)) #define LPAIF_WRDMAPERCNT_REG(v, chan) LPAIF_WRDMA_REG_ADDR(v, 0x14, (chan))
#define LPAIF_INTFDMA_REG(v, chan, reg, dai_id) \ #define LPAIF_INTFDMA_REG(v, chan, reg, dai_id) \
((v->dai_driver[dai_id].id == LPASS_DP_RX) ? \ ((dai_id == LPASS_DP_RX) ? \
LPAIF_HDMI_RDMA##reg##_REG(v, chan) : \ LPAIF_HDMI_RDMA##reg##_REG(v, chan) : \
LPAIF_RDMA##reg##_REG(v, chan)) LPAIF_RDMA##reg##_REG(v, chan))

View File

@ -257,6 +257,9 @@ static int lpass_platform_pcmops_hw_params(struct snd_soc_component *component,
break; break;
case MI2S_PRIMARY: case MI2S_PRIMARY:
case MI2S_SECONDARY: case MI2S_SECONDARY:
case MI2S_TERTIARY:
case MI2S_QUATERNARY:
case MI2S_QUINARY:
ret = regmap_fields_write(dmactl->intf, id, ret = regmap_fields_write(dmactl->intf, id,
LPAIF_DMACTL_AUDINTF(dma_port)); LPAIF_DMACTL_AUDINTF(dma_port));
if (ret) { if (ret) {
@ -507,6 +510,9 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
break; break;
case MI2S_PRIMARY: case MI2S_PRIMARY:
case MI2S_SECONDARY: case MI2S_SECONDARY:
case MI2S_TERTIARY:
case MI2S_QUATERNARY:
case MI2S_QUINARY:
reg_irqclr = LPAIF_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST); reg_irqclr = LPAIF_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST);
val_irqclr = LPAIF_IRQ_ALL(ch); val_irqclr = LPAIF_IRQ_ALL(ch);
@ -559,6 +565,9 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
break; break;
case MI2S_PRIMARY: case MI2S_PRIMARY:
case MI2S_SECONDARY: case MI2S_SECONDARY:
case MI2S_TERTIARY:
case MI2S_QUATERNARY:
case MI2S_QUINARY:
reg_irqen = LPAIF_IRQEN_REG(v, LPAIF_IRQ_PORT_HOST); reg_irqen = LPAIF_IRQEN_REG(v, LPAIF_IRQ_PORT_HOST);
val_mask = LPAIF_IRQ_ALL(ch); val_mask = LPAIF_IRQ_ALL(ch);
val_irqen = 0; val_irqen = 0;
@ -655,6 +664,9 @@ static irqreturn_t lpass_dma_interrupt_handler(
break; break;
case MI2S_PRIMARY: case MI2S_PRIMARY:
case MI2S_SECONDARY: case MI2S_SECONDARY:
case MI2S_TERTIARY:
case MI2S_QUATERNARY:
case MI2S_QUINARY:
map = drvdata->lpaif_map; map = drvdata->lpaif_map;
reg = LPAIF_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST); reg = LPAIF_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST);
val = 0; val = 0;

View File

@ -20,7 +20,7 @@
#include "lpass.h" #include "lpass.h"
static struct snd_soc_dai_driver sc7180_lpass_cpu_dai_driver[] = { static struct snd_soc_dai_driver sc7180_lpass_cpu_dai_driver[] = {
[MI2S_PRIMARY] = { {
.id = MI2S_PRIMARY, .id = MI2S_PRIMARY,
.name = "Primary MI2S", .name = "Primary MI2S",
.playback = { .playback = {
@ -44,9 +44,7 @@ static struct snd_soc_dai_driver sc7180_lpass_cpu_dai_driver[] = {
}, },
.probe = &asoc_qcom_lpass_cpu_dai_probe, .probe = &asoc_qcom_lpass_cpu_dai_probe,
.ops = &asoc_qcom_lpass_cpu_dai_ops, .ops = &asoc_qcom_lpass_cpu_dai_ops,
}, }, {
[MI2S_SECONDARY] = {
.id = MI2S_SECONDARY, .id = MI2S_SECONDARY,
.name = "Secondary MI2S", .name = "Secondary MI2S",
.playback = { .playback = {
@ -60,8 +58,7 @@ static struct snd_soc_dai_driver sc7180_lpass_cpu_dai_driver[] = {
}, },
.probe = &asoc_qcom_lpass_cpu_dai_probe, .probe = &asoc_qcom_lpass_cpu_dai_probe,
.ops = &asoc_qcom_lpass_cpu_dai_ops, .ops = &asoc_qcom_lpass_cpu_dai_ops,
}, }, {
[LPASS_DP_RX] = {
.id = LPASS_DP_RX, .id = LPASS_DP_RX,
.name = "Hdmi", .name = "Hdmi",
.playback = { .playback = {
@ -174,7 +171,7 @@ static struct lpass_variant sc7180_data = {
.rdma_channels = 5, .rdma_channels = 5,
.hdmi_rdma_reg_base = 0x64000, .hdmi_rdma_reg_base = 0x64000,
.hdmi_rdma_reg_stride = 0x1000, .hdmi_rdma_reg_stride = 0x1000,
.hdmi_rdma_channels = 4, .hdmi_rdma_channels = 3,
.dmactl_audif_start = 1, .dmactl_audif_start = 1,
.wrdma_reg_base = 0x18000, .wrdma_reg_base = 0x18000,
.wrdma_reg_stride = 0x1000, .wrdma_reg_stride = 0x1000,

View File

@ -12,7 +12,7 @@
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <dt-bindings/sound/sc7180-lpass.h> #include <dt-bindings/sound/qcom,lpass.h>
#include "lpass-hdmi.h" #include "lpass-hdmi.h"
#define LPASS_AHBIX_CLOCK_FREQUENCY 131072000 #define LPASS_AHBIX_CLOCK_FREQUENCY 131072000

View File

@ -447,7 +447,7 @@ static void remove_dai(struct snd_soc_component *comp,
{ {
struct snd_soc_dai_driver *dai_drv = struct snd_soc_dai_driver *dai_drv =
container_of(dobj, struct snd_soc_dai_driver, dobj); container_of(dobj, struct snd_soc_dai_driver, dobj);
struct snd_soc_dai *dai; struct snd_soc_dai *dai, *_dai;
if (pass != SOC_TPLG_PASS_PCM_DAI) if (pass != SOC_TPLG_PASS_PCM_DAI)
return; return;
@ -455,9 +455,9 @@ static void remove_dai(struct snd_soc_component *comp,
if (dobj->ops && dobj->ops->dai_unload) if (dobj->ops && dobj->ops->dai_unload)
dobj->ops->dai_unload(comp, dobj); dobj->ops->dai_unload(comp, dobj);
for_each_component_dais(comp, dai) for_each_component_dais_safe(comp, dai, _dai)
if (dai->driver == dai_drv) if (dai->driver == dai_drv)
dai->driver = NULL; snd_soc_unregister_dai(dai);
list_del(&dobj->list); list_del(&dobj->list);
} }
@ -902,7 +902,7 @@ static int soc_tplg_denum_create_values(struct soc_tplg *tplg, struct soc_enum *
return -EINVAL; return -EINVAL;
se->dobj.control.dvalues = devm_kcalloc(tplg->dev, le32_to_cpu(ec->items), se->dobj.control.dvalues = devm_kcalloc(tplg->dev, le32_to_cpu(ec->items),
sizeof(u32), sizeof(*se->dobj.control.dvalues),
GFP_KERNEL); GFP_KERNEL);
if (!se->dobj.control.dvalues) if (!se->dobj.control.dvalues)
return -ENOMEM; return -ENOMEM;
@ -1742,7 +1742,7 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg,
list_add(&dai_drv->dobj.list, &tplg->comp->dobj_list); list_add(&dai_drv->dobj.list, &tplg->comp->dobj_list);
/* register the DAI to the component */ /* register the DAI to the component */
dai = devm_snd_soc_register_dai(tplg->dev, tplg->comp, dai_drv, false); dai = snd_soc_register_dai(tplg->comp, dai_drv, false);
if (!dai) if (!dai)
return -ENOMEM; return -ENOMEM;
@ -1750,6 +1750,7 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg,
ret = snd_soc_dapm_new_dai_widgets(dapm, dai); ret = snd_soc_dapm_new_dai_widgets(dapm, dai);
if (ret != 0) { if (ret != 0) {
dev_err(dai->dev, "Failed to create DAI widgets %d\n", ret); dev_err(dai->dev, "Failed to create DAI widgets %d\n", ret);
snd_soc_unregister_dai(dai);
return ret; return ret;
} }

View File

@ -355,7 +355,7 @@ config SND_SOC_SOF_HDA
config SND_SOC_SOF_INTEL_SOUNDWIRE_LINK config SND_SOC_SOF_INTEL_SOUNDWIRE_LINK
bool "SOF support for SoundWire" bool "SOF support for SoundWire"
depends on SOUNDWIRE && ACPI depends on ACPI
help help
This adds support for SoundWire with Sound Open Firmware This adds support for SoundWire with Sound Open Firmware
for Intel(R) platforms. for Intel(R) platforms.
@ -371,6 +371,7 @@ config SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
config SND_SOC_SOF_INTEL_SOUNDWIRE config SND_SOC_SOF_INTEL_SOUNDWIRE
tristate tristate
select SOUNDWIRE
select SOUNDWIRE_INTEL select SOUNDWIRE_INTEL
help help
This option is not user-selectable but automagically handled by This option is not user-selectable but automagically handled by

View File

@ -131,12 +131,13 @@ static int sof_acpi_probe(struct platform_device *pdev)
if (!id) if (!id)
return -ENODEV; return -ENODEV;
ret = snd_intel_acpi_dsp_driver_probe(dev, id->id); if (IS_REACHABLE(CONFIG_SND_INTEL_DSP_CONFIG)) {
if (ret != SND_INTEL_DSP_DRIVER_ANY && ret != SND_INTEL_DSP_DRIVER_SOF) { ret = snd_intel_acpi_dsp_driver_probe(dev, id->id);
dev_dbg(dev, "SOF ACPI driver not selected, aborting probe\n"); if (ret != SND_INTEL_DSP_DRIVER_ANY && ret != SND_INTEL_DSP_DRIVER_SOF) {
return -ENODEV; dev_dbg(dev, "SOF ACPI driver not selected, aborting probe\n");
return -ENODEV;
}
} }
dev_dbg(dev, "ACPI DSP detected"); dev_dbg(dev, "ACPI DSP detected");
sof_pdata = devm_kzalloc(dev, sizeof(*sof_pdata), GFP_KERNEL); sof_pdata = devm_kzalloc(dev, sizeof(*sof_pdata), GFP_KERNEL);

View File

@ -344,10 +344,12 @@ static int sof_pci_probe(struct pci_dev *pci,
const struct snd_sof_dsp_ops *ops; const struct snd_sof_dsp_ops *ops;
int ret; int ret;
ret = snd_intel_dsp_driver_probe(pci); if (IS_REACHABLE(CONFIG_SND_INTEL_DSP_CONFIG)) {
if (ret != SND_INTEL_DSP_DRIVER_ANY && ret != SND_INTEL_DSP_DRIVER_SOF) { ret = snd_intel_dsp_driver_probe(pci);
dev_dbg(&pci->dev, "SOF PCI driver not selected, aborting probe\n"); if (ret != SND_INTEL_DSP_DRIVER_ANY && ret != SND_INTEL_DSP_DRIVER_SOF) {
return -ENODEV; dev_dbg(&pci->dev, "SOF PCI driver not selected, aborting probe\n");
return -ENODEV;
}
} }
dev_dbg(&pci->dev, "PCI DSP detected"); dev_dbg(&pci->dev, "PCI DSP detected");

View File

@ -466,6 +466,17 @@ static int validate_sample_rate_table_v2v3(struct snd_usb_audio *chip,
unsigned int nr_rates; unsigned int nr_rates;
int i, err; int i, err;
/* performing the rate verification may lead to unexpected USB bus
* behavior afterwards by some unknown reason. Do this only for the
* known devices.
*/
switch (USB_ID_VENDOR(chip->usb_id)) {
case 0x07fd: /* MOTU */
break;
default:
return 0; /* don't perform the validation as default */
}
table = kcalloc(fp->nr_rates, sizeof(*table), GFP_KERNEL); table = kcalloc(fp->nr_rates, sizeof(*table), GFP_KERNEL);
if (!table) if (!table)
return -ENOMEM; return -ENOMEM;