Commit 2927e6d3 authored by Mark Brown's avatar Mark Brown

Merge branch 'asoc-5.11' into asoc-5.12

parents 6395a621 b976a5ad
......@@ -7,8 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Mediatek MT8192 with MT6359, RT1015 and RT5682 ASoC sound card driver
maintainers:
- Jiaxin Yu <jiaxin.yu@mediatek.com>
- Shane Chien <shane.chien@mediatek.com>
- Jiaxin Yu <jiaxin.yu@mediatek.com>
- Shane Chien <shane.chien@mediatek.com>
description:
This binding describes the MT8192 sound card.
......
......@@ -14510,10 +14510,18 @@ S: Supported
F: drivers/crypto/qat/
QCOM AUDIO (ASoC) DRIVERS
M: Patrick Lai <plai@codeaurora.org>
M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
M: Banajit Goswami <bgoswami@codeaurora.org>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Supported
F: sound/soc/codecs/lpass-va-macro.c
F: sound/soc/codecs/lpass-wsa-macro.*
F: sound/soc/codecs/msm8916-wcd-analog.c
F: sound/soc/codecs/msm8916-wcd-digital.c
F: sound/soc/codecs/wcd9335.*
F: sound/soc/codecs/wcd934x.c
F: sound/soc/codecs/wcd-clsh-v2.*
F: sound/soc/codecs/wsa881x.c
F: sound/soc/qcom/
QCOM IPA DRIVER
......@@ -16964,7 +16972,7 @@ M: Olivier Moysan <olivier.moysan@st.com>
M: Arnaud Pouliquen <arnaud.pouliquen@st.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Maintained
F: Documentation/devicetree/bindings/sound/st,stm32-*.txt
F: Documentation/devicetree/bindings/iio/adc/st,stm32-*.yaml
F: sound/soc/stm/
STM32 TIMER/LPTIMER DRIVERS
......
......@@ -2,9 +2,8 @@
#ifndef __DT_APQ8016_LPASS_H
#define __DT_APQ8016_LPASS_H
#define MI2S_PRIMARY 0
#define MI2S_SECONDARY 1
#define MI2S_TERTIARY 2
#define MI2S_QUATERNARY 3
#include <dt-bindings/sound/qcom,lpass.h>
/* NOTE: Use qcom,lpass.h to define any AIF ID's for LPASS */
#endif /* __DT_APQ8016_LPASS_H */
/* 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 */
......@@ -2,10 +2,8 @@
#ifndef __DT_SC7180_LPASS_H
#define __DT_SC7180_LPASS_H
#define MI2S_PRIMARY 0
#define MI2S_SECONDARY 1
#define LPASS_DP_RX 2
#include <dt-bindings/sound/qcom,lpass.h>
#define LPASS_MCLK0 0
/* NOTE: Use qcom,lpass.h to define any AIF ID's for LPASS */
#endif /* __DT_APQ8016_LPASS_H */
......@@ -140,21 +140,14 @@ static int snd_acp3x_probe(struct pci_dev *pci,
goto release_regions;
}
/* check for msi interrupt support */
ret = pci_enable_msi(pci);
if (ret)
/* msi is not enabled */
irqflags = IRQF_SHARED;
else
/* msi is enabled */
irqflags = 0;
irqflags = IRQF_SHARED;
addr = pci_resource_start(pci, 0);
adata->acp3x_base = devm_ioremap(&pci->dev, addr,
pci_resource_len(pci, 0));
if (!adata->acp3x_base) {
ret = -ENOMEM;
goto disable_msi;
goto release_regions;
}
pci_set_master(pci);
pci_set_drvdata(pci, adata);
......@@ -162,7 +155,7 @@ static int snd_acp3x_probe(struct pci_dev *pci,
adata->pme_en = rv_readl(adata->acp3x_base + mmACP_PME_EN);
ret = acp3x_init(adata);
if (ret)
goto disable_msi;
goto release_regions;
val = rv_readl(adata->acp3x_base + mmACP_I2S_PIN_CONFIG);
switch (val) {
......@@ -251,8 +244,6 @@ static int snd_acp3x_probe(struct pci_dev *pci,
de_init:
if (acp3x_deinit(adata->acp3x_base))
dev_err(&pci->dev, "ACP de-init failed\n");
disable_msi:
pci_disable_msi(pci);
release_regions:
pci_release_regions(pci);
disable_pci:
......@@ -311,7 +302,6 @@ static void snd_acp3x_remove(struct pci_dev *pci)
dev_err(&pci->dev, "ACP de-init failed\n");
pm_runtime_forbid(&pci->dev);
pm_runtime_get_noresume(&pci->dev);
pci_disable_msi(pci);
pci_release_regions(pci);
pci_disable_device(pci);
}
......
......@@ -165,10 +165,38 @@ static int rn_acp_deinit(void __iomem *acp_base)
static const struct dmi_system_id rn_acp_quirk_table[] = {
{
/* Lenovo IdeaPad Flex 5 14ARE05, IdeaPad 5 15ARE05 */
/* Lenovo IdeaPad S340-14API */
.matches = {
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"),
}
},
{
/* Lenovo ThinkPad E14 Gen 2 */
.matches = {
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_EXACT_MATCH(DMI_BOARD_NAME, "20T6CTO1WW"),
}
},
{
/* Lenovo ThinkPad X395 */
.matches = {
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_EXACT_MATCH(DMI_BOARD_NAME, "20NLCTO1WW"),
}
},
{}
......
......@@ -595,18 +595,10 @@ static struct snd_soc_dai_driver ak4497_dai = {
.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) {
gpiod_set_value_cansleep(ak4458->reset_gpiod, 0);
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);
gpiod_set_value_cansleep(ak4458->reset_gpiod, active);
usleep_range(1000, 2000);
}
}
......@@ -620,7 +612,7 @@ static int ak4458_init(struct snd_soc_component *component)
if (ak4458->mute_gpiod)
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,
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);
ak4458_power_off(ak4458);
ak4458_reset(ak4458, true);
}
#ifdef CONFIG_PM
......@@ -660,7 +652,7 @@ static int __maybe_unused ak4458_runtime_suspend(struct device *dev)
regcache_cache_only(ak4458->regmap, true);
ak4458_power_off(ak4458);
ak4458_reset(ak4458, true);
if (ak4458->mute_gpiod)
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)
gpiod_set_value_cansleep(ak4458->mute_gpiod, 1);
ak4458_power_off(ak4458);
ak4458_power_on(ak4458);
ak4458_reset(ak4458, true);
ak4458_reset(ak4458, false);
regcache_cache_only(ak4458->regmap, false);
regcache_mark_dirty(ak4458->regmap);
......
......@@ -1273,12 +1273,12 @@ static int cpcap_voice_hw_params(struct snd_pcm_substream *substream,
if (direction == SNDRV_PCM_STREAM_CAPTURE) {
mask = 0x0000;
mask |= CPCAP_BIT_MIC1_RX_TIMESLOT0;
mask |= CPCAP_BIT_MIC1_RX_TIMESLOT1;
mask |= CPCAP_BIT_MIC1_RX_TIMESLOT2;
mask |= CPCAP_BIT_MIC2_TIMESLOT0;
mask |= CPCAP_BIT_MIC2_TIMESLOT1;
mask |= CPCAP_BIT_MIC2_TIMESLOT2;
mask |= BIT(CPCAP_BIT_MIC1_RX_TIMESLOT0);
mask |= BIT(CPCAP_BIT_MIC1_RX_TIMESLOT1);
mask |= BIT(CPCAP_BIT_MIC1_RX_TIMESLOT2);
mask |= BIT(CPCAP_BIT_MIC2_TIMESLOT0);
mask |= BIT(CPCAP_BIT_MIC2_TIMESLOT1);
mask |= BIT(CPCAP_BIT_MIC2_TIMESLOT2);
val = 0x0000;
if (channels >= 2)
val = BIT(CPCAP_BIT_MIC1_RX_TIMESLOT0);
......
......@@ -717,7 +717,7 @@ static int hdmi_codec_set_jack(struct snd_soc_component *component,
void *data)
{
struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
int ret = -EOPNOTSUPP;
int ret = -ENOTSUPP;
if (hcp->hcd.ops->hook_plugged_cb) {
hcp->jack = jack;
......
......@@ -190,7 +190,7 @@ static int max98373_feedback_get(struct snd_kcontrol *kcontrol,
}
}
return snd_soc_put_volsw(kcontrol, ucontrol);
return snd_soc_get_volsw(kcontrol, ucontrol);
}
static const struct snd_kcontrol_new max98373_snd_controls[] = {
......
......@@ -710,7 +710,7 @@ static int rt5682_sdw_remove(struct sdw_slave *slave)
struct rt5682_priv *rt5682 = dev_get_drvdata(&slave->dev);
if (rt5682 && rt5682->hw_init)
cancel_delayed_work(&rt5682->jack_detect_work);
cancel_delayed_work_sync(&rt5682->jack_detect_work);
return 0;
}
......@@ -728,6 +728,8 @@ static int __maybe_unused rt5682_dev_suspend(struct device *dev)
if (!rt5682->hw_init)
return 0;
cancel_delayed_work_sync(&rt5682->jack_detect_work);
regcache_cache_only(rt5682->regmap, true);
regcache_mark_dirty(rt5682->regmap);
......
......@@ -2910,6 +2910,9 @@ static int rt5682_suspend(struct snd_soc_component *component)
{
struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component);
if (rt5682->is_sdw)
return 0;
regcache_cache_only(rt5682->regmap, true);
regcache_mark_dirty(rt5682->regmap);
return 0;
......@@ -2919,6 +2922,9 @@ static int rt5682_resume(struct snd_soc_component *component)
{
struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component);
if (rt5682->is_sdw)
return 0;
regcache_cache_only(rt5682->regmap, false);
regcache_sync(rt5682->regmap);
......
......@@ -462,8 +462,8 @@ static int rt700_sdw_remove(struct sdw_slave *slave)
struct rt700_priv *rt700 = dev_get_drvdata(&slave->dev);
if (rt700 && rt700->hw_init) {
cancel_delayed_work(&rt700->jack_detect_work);
cancel_delayed_work(&rt700->jack_btn_check_work);
cancel_delayed_work_sync(&rt700->jack_detect_work);
cancel_delayed_work_sync(&rt700->jack_btn_check_work);
}
return 0;
......
......@@ -463,8 +463,8 @@ static int rt711_sdw_remove(struct sdw_slave *slave)
struct rt711_priv *rt711 = dev_get_drvdata(&slave->dev);
if (rt711 && rt711->hw_init) {
cancel_delayed_work(&rt711->jack_detect_work);
cancel_delayed_work(&rt711->jack_btn_check_work);
cancel_delayed_work_sync(&rt711->jack_detect_work);
cancel_delayed_work_sync(&rt711->jack_btn_check_work);
cancel_work_sync(&rt711->calibration_work);
}
......
......@@ -2033,11 +2033,14 @@ static struct wm_coeff_ctl *wm_adsp_get_ctl(struct wm_adsp *dsp,
unsigned int alg)
{
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) {
if (!pos->subname)
continue;
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.type == type) {
rslt = pos;
......
......@@ -640,6 +640,7 @@ static struct regmap_config wsa881x_regmap_config = {
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
.reg_defaults = wsa881x_defaults,
.max_register = WSA881X_SPKR_STATUS3,
.num_reg_defaults = ARRAY_SIZE(wsa881x_defaults),
.volatile_reg = wsa881x_volatile_register,
.readable_reg = wsa881x_readable_register,
......
......@@ -90,7 +90,7 @@ static int imx_hdmi_init(struct snd_soc_pcm_runtime *rtd)
}
ret = snd_soc_component_set_jack(component, &data->hdmi_jack, NULL);
if (ret && ret != -EOPNOTSUPP) {
if (ret && ret != -ENOTSUPP) {
dev_err(card->dev, "Can't set HDMI Jack %d\n", ret);
return ret;
}
......
......@@ -54,7 +54,8 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A32")
},
.driver_data = (void *)(SOF_RT711_JD_SRC_JD2 |
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
SOF_RT711_JD_SRC_JD2 |
SOF_RT715_DAI_ID_FIX |
SOF_SDW_FOUR_SPK),
},
......@@ -64,9 +65,21 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A3E")
},
.driver_data = (void *)(SOF_RT711_JD_SRC_JD2 |
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
SOF_RT711_JD_SRC_JD2 |
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_SDW_TGL_HDMI |
SOF_RT711_JD_SRC_JD2 |
SOF_RT715_DAI_ID_FIX |
SOF_SDW_FOUR_SPK),
},
{
.callback = sof_sdw_quirk_cb,
.matches = {
......
......@@ -358,14 +358,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[] = {
.link_mask = 0x7,
.links = tgl_sdw_rt711_link1_rt1308_link2_rt715_link0,
.drv_name = "sof_sdw",
.sof_fw_filename = "sof-tgl.ri",
.sof_tplg_filename = "sof-tgl-rt715-rt711-rt1308-mono.tplg",
},
{
.link_mask = 0xF, /* 4 active links required */
.links = tgl_3_in_1_default,
.drv_name = "sof_sdw",
.sof_fw_filename = "sof-tgl.ri",
.sof_tplg_filename = "sof-tgl-rt711-rt1308-rt715.tplg",
},
{
......@@ -377,35 +375,30 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[] = {
.link_mask = 0xF,
.links = tgl_3_in_1_mono_amp,
.drv_name = "sof_sdw",
.sof_fw_filename = "sof-tgl.ri",
.sof_tplg_filename = "sof-tgl-rt711-rt1308-mono-rt715.tplg",
},
{
.link_mask = 0xF, /* 4 active links required */
.links = tgl_3_in_1_sdca,
.drv_name = "sof_sdw",
.sof_fw_filename = "sof-tgl.ri",
.sof_tplg_filename = "sof-tgl-rt711-rt1316-rt714.tplg",
},
{
.link_mask = 0x3, /* rt711 on link 0 and 2 rt1308s on link 1 */
.links = tgl_rvp,
.drv_name = "sof_sdw",
.sof_fw_filename = "sof-tgl.ri",
.sof_tplg_filename = "sof-tgl-rt711-rt1308.tplg",
},
{
.link_mask = 0x3, /* rt5682 on link0 & 2xmax98373 on link 1 */
.links = tgl_chromebook_base,
.drv_name = "sof_sdw",
.sof_fw_filename = "sof-tgl.ri",
.sof_tplg_filename = "sof-tgl-sdw-max98373-rt5682.tplg",
},
{
.link_mask = 0x1, /* this will only enable rt5682 for now */
.links = tgl_chromebook_base,
.drv_name = "sof_sdw",
.sof_fw_filename = "sof-tgl.ri",
.sof_tplg_filename = "sof-tgl-rt5682.tplg",
},
{},
......
......@@ -3619,19 +3619,20 @@ static void skl_tplg_complete(struct snd_soc_component *component)
list_for_each_entry(dobj, &component->dobj_list, list) {
struct snd_kcontrol *kcontrol = dobj->control.kcontrol;
struct soc_enum *se =
(struct soc_enum *)kcontrol->private_value;
char **texts = dobj->control.dtexts;
struct soc_enum *se;
char **texts;
char chan_text[4];
if (dobj->type != SND_SOC_DOBJ_ENUM ||
dobj->control.kcontrol->put !=
skl_tplg_multi_config_set_dmic)
if (dobj->type != SND_SOC_DOBJ_ENUM || !kcontrol ||
kcontrol->put != skl_tplg_multi_config_set_dmic)
continue;
se = (struct soc_enum *)kcontrol->private_value;
texts = dobj->control.dtexts;
sprintf(chan_text, "c%d", mach->mach_params.dmic_num);
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)) {
val.value.enumerated.item[0] = i;
......
......@@ -526,6 +526,7 @@ static struct snd_soc_dai_link mt8183_da7219_dai_links[] = {
.dpcm_playback = 1,
.ignore_suspend = 1,
.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
.ignore = 1,
.init = mt8183_da7219_max98357_hdmi_init,
SND_SOC_DAILINK_REG(tdm),
},
......@@ -748,8 +749,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->ignore = 0;
}
if (!dai_link->platforms->name)
dai_link->platforms->of_node = platform_node;
......
......@@ -509,6 +509,7 @@ static struct snd_soc_dai_link mt8183_mt6358_ts3a227_dai_links[] = {
.ignore_suspend = 1,
.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
.ops = &mt8183_mt6358_tdm_ops,
.ignore = 1,
.init = mt8183_mt6358_ts3a227_max98357_hdmi_init,
SND_SOC_DAILINK_REG(tdm),
},
......@@ -655,8 +656,10 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev)
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->ignore = 0;
}
if (!dai_link->platforms->name)
dai_link->platforms->of_node = platform_node;
......
......@@ -406,6 +406,53 @@ static const struct snd_soc_ops mt8192_mt6359_capture1_ops = {
.startup = mt8192_mt6359_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 */
SND_SOC_DAILINK_DEFS(playback1,
DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
......@@ -653,6 +700,7 @@ static struct snd_soc_dai_link mt8192_mt6359_dai_links[] = {
SND_SOC_DPCM_TRIGGER_PRE},
.dynamic = 1,
.dpcm_playback = 1,
.ops = &mt8192_mt6359_rt5682_ops,
SND_SOC_DAILINK_REG(playback3),
},
{
......@@ -726,6 +774,7 @@ static struct snd_soc_dai_link mt8192_mt6359_dai_links[] = {
SND_SOC_DPCM_TRIGGER_PRE},
.dynamic = 1,
.dpcm_capture = 1,
.ops = &mt8192_mt6359_rt5682_ops,
SND_SOC_DAILINK_REG(capture2),
},
{
......
......@@ -286,16 +286,12 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
dev_err(dai->dev, "error writing to i2sctl reg: %d\n",
ret);
if (drvdata->bit_clk_state[id] == LPAIF_BIT_CLK_DISABLE) {
ret = clk_enable(drvdata->mi2s_bit_clk[id]);
if (ret) {
dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", ret);
clk_disable(drvdata->mi2s_osr_clk[id]);
return ret;
}
drvdata->bit_clk_state[id] = LPAIF_BIT_CLK_ENABLE;
ret = clk_enable(drvdata->mi2s_bit_clk[id]);
if (ret) {
dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", ret);
clk_disable(drvdata->mi2s_osr_clk[id]);
return ret;
}
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
......@@ -310,10 +306,9 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
if (ret)
dev_err(dai->dev, "error writing to i2sctl reg: %d\n",
ret);
if (drvdata->bit_clk_state[id] == LPAIF_BIT_CLK_ENABLE) {
clk_disable(drvdata->mi2s_bit_clk[dai->driver->id]);
drvdata->bit_clk_state[id] = LPAIF_BIT_CLK_DISABLE;
}
clk_disable(drvdata->mi2s_bit_clk[dai->driver->id]);
break;
}
......@@ -344,8 +339,30 @@ int asoc_qcom_lpass_cpu_dai_probe(struct snd_soc_dai *dai)
}
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 = {
.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)
......@@ -578,7 +595,7 @@ static bool lpass_hdmi_regmap_writeable(struct device *dev, unsigned int reg)
return true;
}
for (i = 0; i < v->rdma_channels; ++i) {
for (i = 0; i < v->hdmi_rdma_channels; ++i) {
if (reg == LPAIF_HDMI_RDMACTL_REG(v, i))
return true;
if (reg == LPAIF_HDMI_RDMABASE_REG(v, i))
......@@ -624,7 +641,7 @@ static bool lpass_hdmi_regmap_readable(struct device *dev, unsigned int reg)
if (reg == LPASS_HDMITX_APP_IRQSTAT_REG(v))
return true;
for (i = 0; i < v->rdma_channels; ++i) {
for (i = 0; i < v->hdmi_rdma_channels; ++i) {
if (reg == LPAIF_HDMI_RDMACTL_REG(v, i))
return true;
if (reg == LPAIF_HDMI_RDMABASE_REG(v, i))
......@@ -651,7 +668,7 @@ static bool lpass_hdmi_regmap_volatile(struct device *dev, unsigned int reg)
if (reg == LPASS_HDMI_TX_LEGACY_ADDR(v))
return true;
for (i = 0; i < v->rdma_channels; ++i) {
for (i = 0; i < v->hdmi_rdma_channels; ++i) {
if (reg == LPAIF_HDMI_RDMACURR_REG(v, i))
return true;
}
......@@ -795,7 +812,7 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
return PTR_ERR(drvdata->hdmiif);
lpass_hdmi_regmap_config.max_register = LPAIF_HDMI_RDMAPER_REG(variant,
variant->hdmi_rdma_channels);
variant->hdmi_rdma_channels - 1);
drvdata->hdmiif_map = devm_regmap_init_mmio(dev, drvdata->hdmiif,
&lpass_hdmi_regmap_config);
if (IS_ERR(drvdata->hdmiif_map)) {
......@@ -839,7 +856,6 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
PTR_ERR(drvdata->mi2s_bit_clk[dai_id]));
return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]);
}
drvdata->bit_clk_state[dai_id] = LPAIF_BIT_CLK_DISABLE;
}
/* Allocation for i2sctl regmap fields */
......
......@@ -131,7 +131,7 @@ static struct lpass_variant ipq806x_data = {
.micmode = REG_FIELD_ID(0x0010, 4, 7, 5, 0x4),
.micmono = REG_FIELD_ID(0x0010, 3, 3, 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_bursten = REG_FIELD_ID(0x6000, 11, 11, 4, 0x1000),
......
......@@ -60,9 +60,6 @@
#define LPAIF_I2SCTL_BITWIDTH_24 1
#define LPAIF_I2SCTL_BITWIDTH_32 2
#define LPAIF_BIT_CLK_DISABLE 0
#define LPAIF_BIT_CLK_ENABLE 1
#define LPAIF_I2SCTL_RESET_STATE 0x003C0004
#define LPAIF_DMACTL_RESET_STATE 0x00200000
......@@ -133,7 +130,7 @@
#define LPAIF_WRDMAPERCNT_REG(v, chan) LPAIF_WRDMA_REG_ADDR(v, 0x14, (chan))
#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_RDMA##reg##_REG(v, chan))
......
......@@ -257,6 +257,9 @@ static int lpass_platform_pcmops_hw_params(struct snd_soc_component *component,
break;
case MI2S_PRIMARY:
case MI2S_SECONDARY:
case MI2S_TERTIARY:
case MI2S_QUATERNARY:
case MI2S_QUINARY:
ret = regmap_fields_write(dmactl->intf, id,
LPAIF_DMACTL_AUDINTF(dma_port));
if (ret) {
......@@ -507,6 +510,9 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
break;
case MI2S_PRIMARY:
case MI2S_SECONDARY:
case MI2S_TERTIARY:
case MI2S_QUATERNARY:
case MI2S_QUINARY:
reg_irqclr = LPAIF_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST);
val_irqclr = LPAIF_IRQ_ALL(ch);
......@@ -559,6 +565,9 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
break;
case MI2S_PRIMARY:
case MI2S_SECONDARY:
case MI2S_TERTIARY:
case MI2S_QUATERNARY:
case MI2S_QUINARY:
reg_irqen = LPAIF_IRQEN_REG(v, LPAIF_IRQ_PORT_HOST);
val_mask = LPAIF_IRQ_ALL(ch);
val_irqen = 0;
......@@ -655,6 +664,9 @@ static irqreturn_t lpass_dma_interrupt_handler(
break;
case MI2S_PRIMARY:
case MI2S_SECONDARY:
case MI2S_TERTIARY:
case MI2S_QUATERNARY:
case MI2S_QUINARY:
map = drvdata->lpaif_map;
reg = LPAIF_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST);
val = 0;
......
......@@ -20,7 +20,7 @@
#include "lpass.h"
static struct snd_soc_dai_driver sc7180_lpass_cpu_dai_driver[] = {
[MI2S_PRIMARY] = {
{
.id = MI2S_PRIMARY,
.name = "Primary MI2S",
.playback = {
......@@ -44,9 +44,7 @@ static struct snd_soc_dai_driver sc7180_lpass_cpu_dai_driver[] = {
},
.probe = &asoc_qcom_lpass_cpu_dai_probe,
.ops = &asoc_qcom_lpass_cpu_dai_ops,
},
[MI2S_SECONDARY] = {
}, {
.id = MI2S_SECONDARY,
.name = "Secondary MI2S",
.playback = {
......@@ -60,8 +58,7 @@ static struct snd_soc_dai_driver sc7180_lpass_cpu_dai_driver[] = {
},
.probe = &asoc_qcom_lpass_cpu_dai_probe,
.ops = &asoc_qcom_lpass_cpu_dai_ops,
},
[LPASS_DP_RX] = {
}, {
.id = LPASS_DP_RX,
.name = "Hdmi",
.playback = {
......
......@@ -12,7 +12,7 @@
#include <linux/compiler.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <dt-bindings/sound/sc7180-lpass.h>
#include <dt-bindings/sound/qcom,lpass.h>
#include "lpass-hdmi.h"
#define LPASS_AHBIX_CLOCK_FREQUENCY 131072000
......@@ -68,7 +68,6 @@ struct lpass_data {
unsigned int mi2s_playback_sd_mode[LPASS_MAX_MI2S_PORTS];
unsigned int mi2s_capture_sd_mode[LPASS_MAX_MI2S_PORTS];
int hdmi_port_enable;
int bit_clk_state[LPASS_MAX_MI2S_PORTS];
/* low-power audio interface (LPAIF) registers */
void __iomem *lpaif;
......
......@@ -169,7 +169,7 @@ static inline u32 siu_read32(u32 __iomem *addr)
#define SIU_BRGBSEL (0x108 / sizeof(u32))
#define SIU_BRRB (0x10c / sizeof(u32))
extern struct snd_soc_component_driver siu_component;
extern const struct snd_soc_component_driver siu_component;
extern struct siu_info *siu_i2s_data;
int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card);
......
......@@ -543,7 +543,7 @@ static void siu_pcm_free(struct snd_soc_component *component,
dev_dbg(pcm->card->dev, "%s\n", __func__);
}
struct const snd_soc_component_driver siu_component = {
const struct snd_soc_component_driver siu_component = {
.name = DRV_NAME,
.open = siu_pcm_open,
.close = siu_pcm_close,
......
......@@ -447,7 +447,7 @@ static void remove_dai(struct snd_soc_component *comp,
{
struct snd_soc_dai_driver *dai_drv =
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)
return;
......@@ -455,9 +455,9 @@ static void remove_dai(struct snd_soc_component *comp,
if (dobj->ops && dobj->ops->dai_unload)
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)
dai->driver = NULL;
snd_soc_unregister_dai(dai);
list_del(&dobj->list);
}
......@@ -902,7 +902,7 @@ static int soc_tplg_denum_create_values(struct soc_tplg *tplg, struct soc_enum *
return -EINVAL;
se->dobj.control.dvalues = devm_kcalloc(tplg->dev, le32_to_cpu(ec->items),
sizeof(u32),
sizeof(*se->dobj.control.dvalues),
GFP_KERNEL);
if (!se->dobj.control.dvalues)
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);
/* 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)
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);
if (ret != 0) {
dev_err(dai->dev, "Failed to create DAI widgets %d\n", ret);
snd_soc_unregister_dai(dai);
return ret;
}
......
......@@ -355,7 +355,7 @@ config SND_SOC_SOF_HDA
config SND_SOC_SOF_INTEL_SOUNDWIRE_LINK
bool "SOF support for SoundWire"
depends on SOUNDWIRE && ACPI
depends on ACPI
help
This adds support for SoundWire with Sound Open Firmware
for Intel(R) platforms.
......@@ -371,6 +371,7 @@ config SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
config SND_SOC_SOF_INTEL_SOUNDWIRE
tristate
select SOUNDWIRE
select SOUNDWIRE_INTEL
help
This option is not user-selectable but automagically handled by
......
......@@ -63,16 +63,18 @@ static int hda_codec_load_module(struct hda_codec *codec)
}
/* enable controller wake up event for all codecs with jack connectors */
void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev)
void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev, bool enable)
{
struct hda_bus *hbus = sof_to_hbus(sdev);
struct hdac_bus *bus = sof_to_bus(sdev);
struct hda_codec *codec;
unsigned int mask = 0;
list_for_each_codec(codec, hbus)
if (codec->jacktbl.used)
mask |= BIT(codec->core.addr);
if (enable) {
list_for_each_codec(codec, hbus)
if (codec->jacktbl.used)
mask |= BIT(codec->core.addr);
}
snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, mask);
}
......@@ -81,23 +83,18 @@ void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev)
void hda_codec_jack_check(struct snd_sof_dev *sdev)
{
struct hda_bus *hbus = sof_to_hbus(sdev);
struct hdac_bus *bus = sof_to_bus(sdev);
struct hda_codec *codec;
/* disable controller Wake Up event*/
snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, 0);
list_for_each_codec(codec, hbus)
/*
* Wake up all jack-detecting codecs regardless whether an event
* has been recorded in STATESTS
*/
if (codec->jacktbl.used)
schedule_delayed_work(&codec->jackpoll_work,
codec->jackpoll_interval);
pm_request_resume(&codec->core.dev);
}
#else
void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev) {}
void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev, bool enable) {}
void hda_codec_jack_check(struct snd_sof_dev *sdev) {}
#endif /* CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC */
EXPORT_SYMBOL_NS(hda_codec_jack_wake_enable, SND_SOC_SOF_HDA_AUDIO_CODEC);
......@@ -156,7 +153,8 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address,
if (!hdev->bus->audio_component) {
dev_dbg(sdev->dev,
"iDisp hw present but no driver\n");
goto error;
ret = -ENOENT;
goto out;
}
hda_priv->need_display_power = true;
}
......@@ -173,24 +171,23 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address,
* other return codes without modification
*/
if (ret == 0)
goto error;
ret = -ENOENT;
}
return ret;
error:
snd_hdac_ext_bus_device_exit(hdev);
return -ENOENT;
out:
if (ret < 0) {
snd_hdac_device_unregister(hdev);
put_device(&hdev->dev);
}
#else
hdev = devm_kzalloc(sdev->dev, sizeof(*hdev), GFP_KERNEL);
if (!hdev)
return -ENOMEM;
ret = snd_hdac_ext_bus_device_init(&hbus->core, address, hdev, HDA_DEV_ASOC);
#endif
return ret;
#endif
}
/* Codec initialization */
......
......@@ -617,7 +617,7 @@ static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend)
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
if (runtime_suspend)
hda_codec_jack_wake_enable(sdev);
hda_codec_jack_wake_enable(sdev, true);
/* power down all hda link */
snd_hdac_ext_bus_link_power_down_all(bus);
......@@ -683,8 +683,11 @@ static int hda_resume(struct snd_sof_dev *sdev, bool runtime_resume)
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
/* check jack status */
if (runtime_resume)
hda_codec_jack_check(sdev);
if (runtime_resume) {
hda_codec_jack_wake_enable(sdev, false);
if (sdev->system_suspend_target == SOF_SUSPEND_NONE)
hda_codec_jack_check(sdev);
}
/* turn off the links that were off before suspend */
list_for_each_entry(hlink, &bus->hlink_list, list) {
......@@ -799,11 +802,15 @@ int hda_dsp_runtime_idle(struct snd_sof_dev *sdev)
int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev)
{
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
const struct sof_dsp_power_state target_state = {
.state = SOF_DSP_PM_D3,
};
int ret;
/* cancel any attempt for DSP D0I3 */
cancel_delayed_work_sync(&hda->d0i3_work);
/* stop hda controller and power dsp off */
ret = hda_suspend(sdev, true);
if (ret < 0)
......
......@@ -1169,7 +1169,10 @@ static int hda_sdw_machine_select(struct snd_sof_dev *sdev)
mach->mach_params.links = mach->links;
mach->mach_params.link_mask = mach->link_mask;
mach->mach_params.platform = dev_name(sdev->dev);
pdata->fw_filename = mach->sof_fw_filename;
if (mach->sof_fw_filename)
pdata->fw_filename = mach->sof_fw_filename;
else
pdata->fw_filename = pdata->desc->default_fw_filename;
pdata->tplg_filename = mach->sof_tplg_filename;
} else {
dev_info(sdev->dev,
......
......@@ -654,7 +654,7 @@ void sof_hda_bus_init(struct hdac_bus *bus, struct device *dev);
*/
void hda_codec_probe_bus(struct snd_sof_dev *sdev,
bool hda_codec_use_common_hdmi);
void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev);
void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev, bool enable);
void hda_codec_jack_check(struct snd_sof_dev *sdev);
#endif /* CONFIG_SND_SOC_SOF_HDA */
......
......@@ -731,6 +731,8 @@ int snd_sof_load_firmware_raw(struct snd_sof_dev *sdev)
if (ret < 0) {
dev_err(sdev->dev, "error: request firmware %s failed err: %d\n",
fw_filename, ret);
dev_err(sdev->dev,
"you may need to download the firmware from https://github.com/thesofproject/sof-bin/\n");
goto err;
} else {
dev_dbg(sdev->dev, "request_firmware %s successful\n",
......
......@@ -707,7 +707,12 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa
}
break;
case SOF_DAI_INTEL_ALH:
/* do nothing for ALH dai_link */
/*
* Dai could run with different channel count compared with
* front end, so get dai channel count from topology
*/
channels->min = dai->dai_config->alh.channels;
channels->max = dai->dai_config->alh.channels;
break;
case SOF_DAI_IMX_ESAI:
rate->min = dai->dai_config->esai.fsync_rate;
......
......@@ -131,12 +131,13 @@ static int sof_acpi_probe(struct platform_device *pdev)
if (!id)
return -ENODEV;
ret = snd_intel_acpi_dsp_driver_probe(dev, id->id);
if (ret != SND_INTEL_DSP_DRIVER_ANY && ret != SND_INTEL_DSP_DRIVER_SOF) {
dev_dbg(dev, "SOF ACPI driver not selected, aborting probe\n");
return -ENODEV;
if (IS_REACHABLE(CONFIG_SND_INTEL_DSP_CONFIG)) {
ret = snd_intel_acpi_dsp_driver_probe(dev, id->id);
if (ret != SND_INTEL_DSP_DRIVER_ANY && ret != SND_INTEL_DSP_DRIVER_SOF) {
dev_dbg(dev, "SOF ACPI driver not selected, aborting probe\n");
return -ENODEV;
}
}
dev_dbg(dev, "ACPI DSP detected");
sof_pdata = devm_kzalloc(dev, sizeof(*sof_pdata), GFP_KERNEL);
......
......@@ -346,10 +346,12 @@ static int sof_pci_probe(struct pci_dev *pci,
const struct snd_sof_dsp_ops *ops;
int ret;
ret = snd_intel_dsp_driver_probe(pci);
if (ret != SND_INTEL_DSP_DRIVER_ANY && ret != SND_INTEL_DSP_DRIVER_SOF) {
dev_dbg(&pci->dev, "SOF PCI driver not selected, aborting probe\n");
return -ENODEV;
if (IS_REACHABLE(CONFIG_SND_INTEL_DSP_CONFIG)) {
ret = snd_intel_dsp_driver_probe(pci);
if (ret != SND_INTEL_DSP_DRIVER_ANY && ret != SND_INTEL_DSP_DRIVER_SOF) {
dev_dbg(&pci->dev, "SOF PCI driver not selected, aborting probe\n");
return -ENODEV;
}
}
dev_dbg(&pci->dev, "PCI DSP detected");
......
......@@ -1073,7 +1073,7 @@ static int sof_control_load_volume(struct snd_soc_component *scomp,
scontrol->cmd = SOF_CTRL_CMD_VOLUME;
/* extract tlv data */
if (get_tlv_data(kc->tlv.p, tlv) < 0) {
if (!kc->tlv.p || get_tlv_data(kc->tlv.p, tlv) < 0) {
dev_err(scomp->dev, "error: invalid TLV data\n");
ret = -EINVAL;
goto out_free;
......@@ -3732,6 +3732,8 @@ int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
if (ret < 0) {
dev_err(scomp->dev, "error: tplg request firmware %s failed err: %d\n",
file, ret);
dev_err(scomp->dev,
"you may need to download the firmware from https://github.com/thesofproject/sof-bin/\n");
return ret;
}
......
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