From 1c993300ab1cec9a0a6a3c417614a1d9f35b175b Mon Sep 17 00:00:00 2001 From: Amadeusz Sławiński Date: Fri, 30 Sep 2022 14:45:37 +0200 Subject: ASoC: Intel: avs: Add max98927 machine board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To support AVS-max98927 configuration add machine board connecting AVS platform component driver with max98927 codec one. Reviewed-by: Cezary Rojewski Signed-off-by: Amadeusz Sławiński Link: https://lore.kernel.org/r/20220930124538.354992-2-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/Kconfig | 10 ++ sound/soc/intel/avs/boards/Makefile | 2 + sound/soc/intel/avs/boards/max98927.c | 236 ++++++++++++++++++++++++++++++++++ 3 files changed, 248 insertions(+) create mode 100644 sound/soc/intel/avs/boards/max98927.c (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/boards/Kconfig b/sound/soc/intel/avs/boards/Kconfig index 4d68e3ef992b..9bd40fdd9028 100644 --- a/sound/soc/intel/avs/boards/Kconfig +++ b/sound/soc/intel/avs/boards/Kconfig @@ -36,6 +36,16 @@ config SND_SOC_INTEL_AVS_MACH_I2S_TEST This adds support for I2S test-board which can be used to verify transfer over I2S interface with SSP loopback scenarios. +config SND_SOC_INTEL_AVS_MACH_MAX98927 + tristate "max98927 I2S board" + depends on I2C + depends on MFD_INTEL_LPSS || COMPILE_TEST + select SND_SOC_MAX98927 + help + This adds support for AVS with MAX98927 I2S codec configuration. + Say Y or m if you have such a device. This is a recommended option. + If unsure select "N". + config SND_SOC_INTEL_AVS_MACH_MAX98357A tristate "max98357A I2S board" depends on I2C diff --git a/sound/soc/intel/avs/boards/Makefile b/sound/soc/intel/avs/boards/Makefile index bc75376d58c2..4d70b8d09ce5 100644 --- a/sound/soc/intel/avs/boards/Makefile +++ b/sound/soc/intel/avs/boards/Makefile @@ -4,6 +4,7 @@ snd-soc-avs-da7219-objs := da7219.o snd-soc-avs-dmic-objs := dmic.o snd-soc-avs-hdaudio-objs := hdaudio.o snd-soc-avs-i2s-test-objs := i2s_test.o +snd-soc-avs-max98927-objs := max98927.o snd-soc-avs-max98357a-objs := max98357a.o snd-soc-avs-max98373-objs := max98373.o snd-soc-avs-nau8825-objs := nau8825.o @@ -17,6 +18,7 @@ obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_DA7219) += snd-soc-avs-da7219.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_DMIC) += snd-soc-avs-dmic.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_HDAUDIO) += snd-soc-avs-hdaudio.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_I2S_TEST) += snd-soc-avs-i2s-test.o +obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98927) += snd-soc-avs-max98927.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98357A) += snd-soc-avs-max98357a.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98373) += snd-soc-avs-max98373.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_NAU8825) += snd-soc-avs-nau8825.o diff --git a/sound/soc/intel/avs/boards/max98927.c b/sound/soc/intel/avs/boards/max98927.c new file mode 100644 index 000000000000..35c4f8f55035 --- /dev/null +++ b/sound/soc/intel/avs/boards/max98927.c @@ -0,0 +1,236 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2022 Intel Corporation. All rights reserved. +// +// Authors: Cezary Rojewski +// Amadeusz Slawinski +// + +#include +#include +#include +#include +#include +#include + +#define MAX98927_DEV0_NAME "i2c-MX98927:00" +#define MAX98927_DEV1_NAME "i2c-MX98927:01" +#define MAX98927_CODEC_NAME "max98927-aif1" + +static struct snd_soc_codec_conf card_codec_conf[] = { + { + .dlc = COMP_CODEC_CONF(MAX98927_DEV0_NAME), + .name_prefix = "Right", + }, + { + .dlc = COMP_CODEC_CONF(MAX98927_DEV1_NAME), + .name_prefix = "Left", + }, +}; + +static const struct snd_kcontrol_new card_controls[] = { + SOC_DAPM_PIN_SWITCH("Left Spk"), + SOC_DAPM_PIN_SWITCH("Right Spk"), +}; + +static const struct snd_soc_dapm_widget card_widgets[] = { + SND_SOC_DAPM_SPK("Left Spk", NULL), + SND_SOC_DAPM_SPK("Right Spk", NULL), +}; + +static const struct snd_soc_dapm_route card_base_routes[] = { + { "Left Spk", NULL, "Left BE_OUT" }, + { "Right Spk", NULL, "Right BE_OUT" }, +}; + +static int +avs_max98927_be_fixup(struct snd_soc_pcm_runtime *runrime, struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate, *channels; + struct snd_mask *fmt; + + rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); + channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + + /* The ADSP will covert the FE rate to 48k, stereo */ + rate->min = rate->max = 48000; + channels->min = channels->max = 2; + + /* set SSP0 to 16 bit */ + snd_mask_none(fmt); + snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE); + return 0; +} + +static int avs_max98927_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *runtime = asoc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai; + int ret = 0; + int i; + + for_each_rtd_codec_dais(runtime, i, codec_dai) { + if (!strcmp(codec_dai->component->name, MAX98927_DEV0_NAME)) + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x30, 3, 8, 16); + else if (!strcmp(codec_dai->component->name, MAX98927_DEV1_NAME)) + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xC0, 3, 8, 16); + + if (ret < 0) { + dev_err(runtime->dev, "hw_params for %s failed: %d\n", + codec_dai->component->name, ret); + return ret; + } + } + + return 0; +} + +static const struct snd_soc_ops avs_max98927_ops = { + .hw_params = avs_max98927_hw_params, +}; + +static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, + struct snd_soc_dai_link **dai_link) +{ + struct snd_soc_dai_link_component *platform; + struct snd_soc_dai_link *dl; + + dl = devm_kzalloc(dev, sizeof(*dl), GFP_KERNEL); + platform = devm_kzalloc(dev, sizeof(*platform), GFP_KERNEL); + if (!dl || !platform) + return -ENOMEM; + + platform->name = platform_name; + + dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); + dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs) * 2, GFP_KERNEL); + if (!dl->name || !dl->cpus || !dl->codecs) + return -ENOMEM; + + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); + dl->codecs[0].name = devm_kasprintf(dev, GFP_KERNEL, MAX98927_DEV0_NAME); + dl->codecs[0].dai_name = devm_kasprintf(dev, GFP_KERNEL, MAX98927_CODEC_NAME); + dl->codecs[1].name = devm_kasprintf(dev, GFP_KERNEL, MAX98927_DEV1_NAME); + dl->codecs[1].dai_name = devm_kasprintf(dev, GFP_KERNEL, MAX98927_CODEC_NAME); + if (!dl->cpus->dai_name || !dl->codecs[0].name || !dl->codecs[0].dai_name || + !dl->codecs[1].name || !dl->codecs[1].dai_name) + return -ENOMEM; + + dl->num_cpus = 1; + dl->num_codecs = 2; + dl->platforms = platform; + dl->num_platforms = 1; + dl->id = 0; + dl->dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; + dl->be_hw_params_fixup = avs_max98927_be_fixup; + dl->nonatomic = 1; + dl->no_pcm = 1; + dl->dpcm_capture = 1; + dl->dpcm_playback = 1; + dl->ignore_pmdown_time = 1; + dl->ops = &avs_max98927_ops; + + *dai_link = dl; + + return 0; +} + +static int avs_create_dapm_routes(struct device *dev, int ssp_port, + struct snd_soc_dapm_route **routes, int *num_routes) +{ + struct snd_soc_dapm_route *dr; + const int num_base = ARRAY_SIZE(card_base_routes); + const int num_dr = num_base + 2; + int idx; + + dr = devm_kcalloc(dev, num_dr, sizeof(*dr), GFP_KERNEL); + if (!dr) + return -ENOMEM; + + memcpy(dr, card_base_routes, num_base * sizeof(*dr)); + + idx = num_base; + dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "Left HiFi Playback"); + dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); + if (!dr[idx].sink || !dr[idx].source) + return -ENOMEM; + + idx++; + dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "Right HiFi Playback"); + dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); + if (!dr[idx].sink || !dr[idx].source) + return -ENOMEM; + + *routes = dr; + *num_routes = num_dr; + + return 0; +} + +static int avs_max98927_probe(struct platform_device *pdev) +{ + struct snd_soc_dapm_route *routes; + struct snd_soc_dai_link *dai_link; + struct snd_soc_acpi_mach *mach; + struct snd_soc_card *card; + struct device *dev = &pdev->dev; + const char *pname; + int num_routes, ssp_port, ret; + + mach = dev_get_platdata(dev); + pname = mach->mach_params.platform; + ssp_port = __ffs(mach->mach_params.i2s_link_mask); + + ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link); + if (ret) { + dev_err(dev, "Failed to create dai link: %d", ret); + return ret; + } + + ret = avs_create_dapm_routes(dev, ssp_port, &routes, &num_routes); + if (ret) { + dev_err(dev, "Failed to create dapm routes: %d", ret); + return ret; + } + + card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); + if (!card) + return -ENOMEM; + + card->name = "avs_max98927"; + card->dev = dev; + card->owner = THIS_MODULE; + card->dai_link = dai_link; + card->num_links = 1; + card->codec_conf = card_codec_conf; + card->num_configs = ARRAY_SIZE(card_codec_conf); + card->controls = card_controls; + card->num_controls = ARRAY_SIZE(card_controls); + card->dapm_widgets = card_widgets; + card->num_dapm_widgets = ARRAY_SIZE(card_widgets); + card->dapm_routes = routes; + card->num_dapm_routes = num_routes; + card->fully_routed = true; + + ret = snd_soc_fixup_dai_links_platform_name(card, pname); + if (ret) + return ret; + + return devm_snd_soc_register_card(dev, card); +} + +static struct platform_driver avs_max98927_driver = { + .probe = avs_max98927_probe, + .driver = { + .name = "avs_max98927", + .pm = &snd_soc_pm_ops, + }, +}; + +module_platform_driver(avs_max98927_driver) + +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:avs_max98927"); -- cgit v1.2.3-70-g09d2 From 999ce9967a2f5a64c4bd04ae1edf0a979cf68833 Mon Sep 17 00:00:00 2001 From: Amadeusz Sławiński Date: Fri, 30 Sep 2022 14:45:38 +0200 Subject: ASoC: Intel: avs: Load max98927 on target platform MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to load proper board configuration it needs to be looked up in ACPI. Add board configuration for MAXIM 98927 codec present on Chromebooks. Reviewed-by: Cezary Rojewski Signed-off-by: Amadeusz Sławiński Link: https://lore.kernel.org/r/20220930124538.354992-3-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/board_selection.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/board_selection.c b/sound/soc/intel/avs/board_selection.c index 87f9c18be238..1a85349f9563 100644 --- a/sound/soc/intel/avs/board_selection.c +++ b/sound/soc/intel/avs/board_selection.c @@ -121,6 +121,14 @@ static struct snd_soc_acpi_mach avs_kbl_i2s_machines[] = { .machine_quirk = dmi_match_quirk, .tplg_filename = "rt298-tplg.bin", }, + { + .id = "MX98927", + .drv_name = "avs_max98927", + .mach_params = { + .i2s_link_mask = AVS_SSP(0), + }, + .tplg_filename = "max98927-tplg.bin", + }, { .id = "MX98373", .drv_name = "avs_max98373", -- cgit v1.2.3-70-g09d2 From 83375566a7a7042cb34b24986d100f46bfa0c1e5 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 10 Oct 2022 14:19:41 +0200 Subject: ASoC: Intel: avs: Fix DMA mask assignment Spelling error leads to incorrect behavior when setting up DMA mask. Fixes: a5bbbde2b81e ("ASoC: Intel: avs: Use helper function to set up DMA") Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221010121955.718168-2-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c index bb0719c58ca4..4f93639ce488 100644 --- a/sound/soc/intel/avs/core.c +++ b/sound/soc/intel/avs/core.c @@ -440,7 +440,7 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) if (bus->mlcap) snd_hdac_ext_bus_get_ml_capabilities(bus); - if (!dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) + if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); dma_set_max_seg_size(dev, UINT_MAX); -- cgit v1.2.3-70-g09d2 From 23ae34e033b2c0e5e88237af82b163b296fd6aa9 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 10 Oct 2022 14:19:42 +0200 Subject: ASoC: Intel: avs: Fix potential RX buffer overflow If an event caused firmware to return invalid RX size for LARGE_CONFIG_GET, memcpy_fromio() could end up copying too many bytes. Fix by utilizing min_t(). Reported-by: CoolStar Fixes: f14a1c5a9f83 ("ASoC: Intel: avs: Add module management requests") Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221010121955.718168-3-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/ipc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/ipc.c b/sound/soc/intel/avs/ipc.c index 020d85c7520d..77da206f7dbb 100644 --- a/sound/soc/intel/avs/ipc.c +++ b/sound/soc/intel/avs/ipc.c @@ -192,7 +192,8 @@ static void avs_dsp_receive_rx(struct avs_dev *adev, u64 header) /* update size in case of LARGE_CONFIG_GET */ if (msg.msg_target == AVS_MOD_MSG && msg.global_msg_type == AVS_MOD_LARGE_CONFIG_GET) - ipc->rx.size = msg.ext.large_config.data_off_size; + ipc->rx.size = min_t(u32, AVS_MAILBOX_SIZE, + msg.ext.large_config.data_off_size); memcpy_fromio(ipc->rx.data, avs_uplink_addr(adev), ipc->rx.size); trace_avs_msg_payload(ipc->rx.data, ipc->rx.size); -- cgit v1.2.3-70-g09d2 From 9d0737fa0e7530313634c0ecd75f09a95ba8d44a Mon Sep 17 00:00:00 2001 From: Amadeusz Sławiński Date: Mon, 10 Oct 2022 14:19:44 +0200 Subject: ASoC: Intel: avs: Add quirk for KBL-R RVP platform MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit KBL-R RVPs contain built-in rt298 codec which requires different PLL clock and .dai_fmt configuration than seen on other boards. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221010121955.718168-5-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/rt298.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/boards/rt298.c b/sound/soc/intel/avs/boards/rt298.c index b28d36872dcb..58c9d9edecf0 100644 --- a/sound/soc/intel/avs/boards/rt298.c +++ b/sound/soc/intel/avs/boards/rt298.c @@ -6,6 +6,7 @@ // Amadeusz Slawinski // +#include #include #include #include @@ -14,6 +15,16 @@ #include #include "../../../codecs/rt298.h" +static const struct dmi_system_id kblr_dmi_table[] = { + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_BOARD_NAME, "Kabylake R DDR4 RVP"), + }, + }, + {} +}; + static const struct snd_kcontrol_new card_controls[] = { SOC_DAPM_PIN_SWITCH("Headphone Jack"), SOC_DAPM_PIN_SWITCH("Mic Jack"), @@ -96,9 +107,15 @@ avs_rt298_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_param { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + unsigned int clk_freq; int ret; - ret = snd_soc_dai_set_sysclk(codec_dai, RT298_SCLK_S_PLL, 19200000, SND_SOC_CLOCK_IN); + if (dmi_first_match(kblr_dmi_table)) + clk_freq = 24000000; + else + clk_freq = 19200000; + + ret = snd_soc_dai_set_sysclk(codec_dai, RT298_SCLK_S_PLL, clk_freq, SND_SOC_CLOCK_IN); if (ret < 0) dev_err(rtd->dev, "Set codec sysclk failed: %d\n", ret); @@ -139,7 +156,10 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in dl->platforms = platform; dl->num_platforms = 1; dl->id = 0; - dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; + if (dmi_first_match(kblr_dmi_table)) + dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; + else + dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; dl->init = avs_rt298_codec_init; dl->be_hw_params_fixup = avs_rt298_be_fixup; dl->ops = &avs_rt298_ops; -- cgit v1.2.3-70-g09d2 From 8b2446eaa45a3be5bb5c6fb79cc745d228dac431 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 10 Oct 2022 14:19:45 +0200 Subject: ASoC: Intel: avs: Support AML with rt286 configuration ACPI ID of INT343A signals rt286 device for SKL, KBL and AML platforms. Add the missing AML entry. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221010121955.718168-6-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/board_selection.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/board_selection.c b/sound/soc/intel/avs/board_selection.c index 87f9c18be238..95afbac0f358 100644 --- a/sound/soc/intel/avs/board_selection.c +++ b/sound/soc/intel/avs/board_selection.c @@ -29,6 +29,12 @@ static const struct dmi_system_id kbl_dmi_table[] = { DMI_MATCH(DMI_BOARD_NAME, "Skylake Y LPDDR3 RVP3"), }, }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_BOARD_NAME, "AmberLake Y"), + }, + }, {} }; -- cgit v1.2.3-70-g09d2 From fecc00b448a9b89c858468318bfdddbc5bd9dc6d Mon Sep 17 00:00:00 2001 From: Amadeusz Sławiński Date: Mon, 10 Oct 2022 14:19:46 +0200 Subject: ASoC: Intel: avs: Support da7219 on both KBL and APL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit KBL and APL devices use same codec but have different clock, so it must be set appropriately depending on device. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221010121955.718168-7-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/da7219.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/boards/da7219.c b/sound/soc/intel/avs/boards/da7219.c index 02ae542ad779..503a967a1c3a 100644 --- a/sound/soc/intel/avs/boards/da7219.c +++ b/sound/soc/intel/avs/boards/da7219.c @@ -6,6 +6,7 @@ // #include +#include #include #include #include @@ -80,7 +81,10 @@ static int avs_da7219_codec_init(struct snd_soc_pcm_runtime *runtime) int ret; jack = snd_soc_card_get_drvdata(card); - clk_freq = 19200000; + if (soc_intel_is_apl()) + clk_freq = 19200000; + else /* kbl */ + clk_freq = 24576000; ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, clk_freq, SND_SOC_CLOCK_IN); if (ret) { -- cgit v1.2.3-70-g09d2 From d1356811abf785b995dd74750fc75efffa3d7656 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 10 Oct 2022 14:19:47 +0200 Subject: ASoC: Intel: avs: Add missing SKL-based device IDs Enable additional SKL-based configurations by filling device ID table with new entries. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221010121955.718168-8-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/core.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c index 4f93639ce488..900d250799b7 100644 --- a/sound/soc/intel/avs/core.c +++ b/sound/soc/intel/avs/core.c @@ -667,7 +667,11 @@ static const struct avs_spec apl_desc = { static const struct pci_device_id avs_ids[] = { { PCI_VDEVICE(INTEL, 0x9d70), (unsigned long)&skl_desc }, /* SKL */ + { PCI_VDEVICE(INTEL, 0xa170), (unsigned long)&skl_desc }, /* SKL-H */ { PCI_VDEVICE(INTEL, 0x9d71), (unsigned long)&skl_desc }, /* KBL */ + { PCI_VDEVICE(INTEL, 0xa171), (unsigned long)&skl_desc }, /* KBL-H */ + { PCI_VDEVICE(INTEL, 0xa2f0), (unsigned long)&skl_desc }, /* KBL-S */ + { PCI_VDEVICE(INTEL, 0xa3f0), (unsigned long)&skl_desc }, /* CML-V */ { PCI_VDEVICE(INTEL, 0x5a98), (unsigned long)&apl_desc }, /* APL */ { PCI_VDEVICE(INTEL, 0x3198), (unsigned long)&apl_desc }, /* GML */ { 0 } -- cgit v1.2.3-70-g09d2 From e720e68b3fa25268e1df8a6d91d3bdb80f4fc38a Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 10 Oct 2022 14:19:48 +0200 Subject: ASoC: Intel: avs: Simplify d0ix disabling routine No need to atomic_add_return(1) when there is atomic_inc_return() available. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221010121955.718168-9-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/ipc.c b/sound/soc/intel/avs/ipc.c index 77da206f7dbb..152f8d0bdf8e 100644 --- a/sound/soc/intel/avs/ipc.c +++ b/sound/soc/intel/avs/ipc.c @@ -74,7 +74,7 @@ int avs_dsp_disable_d0ix(struct avs_dev *adev) struct avs_ipc *ipc = adev->ipc; /* Prevent PG only on the first disable. */ - if (atomic_add_return(1, &ipc->d0ix_disable_depth) == 1) { + if (atomic_inc_return(&ipc->d0ix_disable_depth) == 1) { cancel_delayed_work_sync(&ipc->d0ix_work); return avs_dsp_set_d0ix(adev, false); } -- cgit v1.2.3-70-g09d2 From e331b534d3b1a5a36a7bc1e7a85e21d2561aa2e6 Mon Sep 17 00:00:00 2001 From: Amadeusz Sławiński Date: Mon, 10 Oct 2022 14:19:49 +0200 Subject: ASoC: Intel: avs: Add missing include to HDA board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In some configurations board fails to compile due to missing header. Add it to fix build. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221010121955.718168-10-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/hdaudio.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/boards/hdaudio.c b/sound/soc/intel/avs/boards/hdaudio.c index 073663ba140d..e68c4c7aa2ba 100644 --- a/sound/soc/intel/avs/boards/hdaudio.c +++ b/sound/soc/intel/avs/boards/hdaudio.c @@ -6,6 +6,7 @@ // Amadeusz Slawinski // +#include #include #include #include -- cgit v1.2.3-70-g09d2 From 18a787909ca6bac3a3a3235c08d68a4a9838fe7b Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 10 Oct 2022 14:19:50 +0200 Subject: ASoC: Intel: avs: Do not reuse msg between different IPC handlers While LOG_BUFFER_STATUS is a simple notification with only one meaningful field, same message ptr shall not be reused for two different handlers. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221010121955.718168-11-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/apl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/apl.c b/sound/soc/intel/avs/apl.c index b8e2b23c9f64..7c8ce98eda9d 100644 --- a/sound/soc/intel/avs/apl.c +++ b/sound/soc/intel/avs/apl.c @@ -133,12 +133,14 @@ static int apl_coredump(struct avs_dev *adev, union avs_notify_msg *msg) buf = apl_log_payload_addr(addr); memcpy_fromio(&layout, addr, sizeof(layout)); if (!apl_is_entry_stackdump(buf + layout.read_ptr)) { + union avs_notify_msg lbs_msg = AVS_NOTIFICATION(LOG_BUFFER_STATUS); + /* * DSP awaits the remaining logs to be * gathered before dumping stack */ - msg->log.core = msg->ext.coredump.core_id; - avs_dsp_op(adev, log_buffer_status, msg); + lbs_msg.log.core = msg->ext.coredump.core_id; + avs_dsp_op(adev, log_buffer_status, &lbs_msg); } pos = dump + AVS_FW_REGS_SIZE; -- cgit v1.2.3-70-g09d2 From 2d27a1caf8ef0c443486b18de2fada3120e3fbe1 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 10 Oct 2022 14:19:51 +0200 Subject: ASoC: Intel: avs: Do not treat unsupported IPCs as invalid Utilize NOT_SUPPORTED status code to differentiate between unsupported and invalid requests. Skip over error paths if it is the former that is communicated by the base firmware. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221010121955.718168-12-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/avs.h | 4 +++- sound/soc/intel/avs/messages.h | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h index 92e37722d280..91f78eb11bc1 100644 --- a/sound/soc/intel/avs/avs.h +++ b/sound/soc/intel/avs/avs.h @@ -220,8 +220,10 @@ static inline void avs_ipc_err(struct avs_dev *adev, struct avs_ipc_msg *tx, /* * If IPC channel is blocked e.g.: due to ongoing recovery, * -EPERM error code is expected and thus it's not an actual error. + * + * Unsupported IPCs are of no harm either. */ - if (error == -EPERM) + if (error == -EPERM || error == AVS_IPC_NOT_SUPPORTED) dev_dbg(adev->dev, "%s 0x%08x 0x%08x failed: %d\n", name, tx->glb.primary, tx->glb.ext.val, error); else diff --git a/sound/soc/intel/avs/messages.h b/sound/soc/intel/avs/messages.h index c0f90dba9af8..02b3b7a74783 100644 --- a/sound/soc/intel/avs/messages.h +++ b/sound/soc/intel/avs/messages.h @@ -150,6 +150,8 @@ union avs_module_msg { }; } __packed; +#define AVS_IPC_NOT_SUPPORTED 15 + union avs_reply_msg { u64 val; struct { -- cgit v1.2.3-70-g09d2 From 65edda6015682a31d82111b7a417eaa8232547f8 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 10 Oct 2022 14:19:52 +0200 Subject: ASoC: Intel: avs: Do not print IPC error message twice ENABLE_LOGS and SYSTEM_TIME IPCs call LARGE_CONFIG_SET internally which dumps an error message in case of an error. There is no need to repeat the process in the top level handler. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221010121955.718168-13-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/messages.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/messages.c b/sound/soc/intel/avs/messages.c index d4bcee1aabcf..6b0fecbf07c3 100644 --- a/sound/soc/intel/avs/messages.c +++ b/sound/soc/intel/avs/messages.c @@ -687,20 +687,13 @@ int avs_ipc_get_modules_info(struct avs_dev *adev, struct avs_mods_info **info) int avs_ipc_set_enable_logs(struct avs_dev *adev, u8 *log_info, size_t size) { - int ret; - - ret = avs_ipc_set_large_config(adev, AVS_BASEFW_MOD_ID, AVS_BASEFW_INST_ID, - AVS_BASEFW_ENABLE_LOGS, log_info, size); - if (ret) - dev_err(adev->dev, "enable logs failed: %d\n", ret); - - return ret; + return avs_ipc_set_large_config(adev, AVS_BASEFW_MOD_ID, AVS_BASEFW_INST_ID, + AVS_BASEFW_ENABLE_LOGS, log_info, size); } int avs_ipc_set_system_time(struct avs_dev *adev) { struct avs_sys_time sys_time; - int ret; u64 us; /* firmware expects UTC time in micro seconds */ @@ -708,12 +701,8 @@ int avs_ipc_set_system_time(struct avs_dev *adev) sys_time.val_l = us & UINT_MAX; sys_time.val_u = us >> 32; - ret = avs_ipc_set_large_config(adev, AVS_BASEFW_MOD_ID, AVS_BASEFW_INST_ID, - AVS_BASEFW_SYSTEM_TIME, (u8 *)&sys_time, sizeof(sys_time)); - if (ret) - dev_err(adev->dev, "set system time failed: %d\n", ret); - - return ret; + return avs_ipc_set_large_config(adev, AVS_BASEFW_MOD_ID, AVS_BASEFW_INST_ID, + AVS_BASEFW_SYSTEM_TIME, (u8 *)&sys_time, sizeof(sys_time)); } int avs_ipc_copier_set_sink_format(struct avs_dev *adev, u16 module_id, -- cgit v1.2.3-70-g09d2 From 263e3e2dfef7a9d39c91bbd2ff61bd0619c68e3b Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 10 Oct 2022 14:19:53 +0200 Subject: ASoC: Intel: avs: Simplify ignore_fw_version description Reword the parameter description to drop any confusion regarding its purpose. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221010121955.718168-14-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/loader.c b/sound/soc/intel/avs/loader.c index 9e3f8ff33a87..2d80a271eb50 100644 --- a/sound/soc/intel/avs/loader.c +++ b/sound/soc/intel/avs/loader.c @@ -43,7 +43,7 @@ /* Occasionally, engineering (release candidate) firmware is provided for testing. */ static bool debug_ignore_fw_version; module_param_named(ignore_fw_version, debug_ignore_fw_version, bool, 0444); -MODULE_PARM_DESC(ignore_fw_version, "Verify FW version 0=yes (default), 1=no"); +MODULE_PARM_DESC(ignore_fw_version, "Ignore firmware version check 0=no (default), 1=yes"); #define AVS_LIB_NAME_SIZE 8 -- cgit v1.2.3-70-g09d2 From bfced33e1eb868b1085c7cfadfb71e6e497059cb Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 10 Oct 2022 14:19:54 +0200 Subject: ASoC: Intel: avs: Simplify log control for SKL Loop only till the actual number of AudioDSP cores, not the value of mask made from said number. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221010121955.718168-15-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/skl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/skl.c b/sound/soc/intel/avs/skl.c index bda5ec7510fe..dc98b5cf900f 100644 --- a/sound/soc/intel/avs/skl.c +++ b/sound/soc/intel/avs/skl.c @@ -28,12 +28,12 @@ static int skl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 info->core_mask = resource_mask; if (enable) - for_each_set_bit(i, &resource_mask, GENMASK(num_cores, 0)) { + for_each_set_bit(i, &resource_mask, num_cores) { info->logs_core[i].enable = enable; info->logs_core[i].min_priority = *priorities++; } else - for_each_set_bit(i, &resource_mask, GENMASK(num_cores, 0)) + for_each_set_bit(i, &resource_mask, num_cores) info->logs_core[i].enable = enable; ret = avs_ipc_set_enable_logs(adev, (u8 *)info, size); -- cgit v1.2.3-70-g09d2 From fac33cb5c12c58e031a5e2f8e3e8c7de8604a764 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 17 Oct 2022 15:49:44 -0500 Subject: ASoC: Intel: Skylake: simplify S3 resume flows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit cce6c149eba3a ("ASoC: Intel: Skylake: add link management") added a perfectly logical/symmetrical link handling for 'suspend_active' aka S0ix However that commit also added a less obvious part, where during S3 resume the code will "turn off the links which are off before suspend" as well as stop the cmd_io which is not started. This sequence looks completely unnecessary and possibly wrong, remove it. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Rander Wang Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Reviewed-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221017204946.207986-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index bbba2df33aaf..1cfdb04f589f 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -387,15 +387,6 @@ static int skl_resume(struct device *dev) snd_hdac_bus_init_cmd_io(bus); } else { ret = _skl_resume(bus); - - /* turn off the links which are off before suspend */ - list_for_each_entry(hlink, &bus->hlink_list, list) { - if (!hlink->ref_count) - snd_hdac_ext_bus_link_power_down(hlink); - } - - if (!bus->cmd_dma_state) - snd_hdac_bus_stop_cmd_io(bus); } return ret; -- cgit v1.2.3-70-g09d2 From 8e1ae6f62c7e8f904949e9c60a4a38715c8c0aff Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 17 Oct 2022 15:49:45 -0500 Subject: ASoC: Intel: avs: simplify S3 resume flows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The same code was directly copied from the skylake driver where it was already questionable. Remove and simplify the flow. Tested-by: Cezary Rojewski Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Rander Wang Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Reviewed-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221017204946.207986-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/core.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c index 900d250799b7..d067ce951afc 100644 --- a/sound/soc/intel/avs/core.c +++ b/sound/soc/intel/avs/core.c @@ -580,7 +580,6 @@ static int __maybe_unused avs_suspend_common(struct avs_dev *adev) static int __maybe_unused avs_resume_common(struct avs_dev *adev, bool purge) { struct hdac_bus *bus = &adev->base.core; - struct hdac_ext_link *hlink; int ret; snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, true); @@ -595,16 +594,6 @@ static int __maybe_unused avs_resume_common(struct avs_dev *adev, bool purge) return ret; } - /* turn off the links that were off before suspend */ - list_for_each_entry(hlink, &bus->hlink_list, list) { - if (!hlink->ref_count) - snd_hdac_ext_bus_link_power_down(hlink); - } - - /* check dma status and clean up CORB/RIRB buffers */ - if (!bus->cmd_dma_state) - snd_hdac_bus_stop_cmd_io(bus); - return 0; } -- cgit v1.2.3-70-g09d2 From 1c9096f32ad23f5867e752f238fd25e4fec55ecd Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 17 Oct 2022 23:36:49 +0000 Subject: ASoC: soc-dapm.c: ignore parameter NULL at snd_soc_dapm_free_widget() Currently snd_soc_dapm_free_widget() is assuming input parameter is non NULL. Thus, caller need to care about it. This patch care it at snd_soc_dapm_free_widget(). Signed-off-by: Kuninori Morimoto Link: https://lore.kernel.org/r/87wn8yowdr.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/hda.c | 6 ++---- sound/soc/intel/avs/pcm.c | 6 ++---- sound/soc/soc-dapm.c | 3 +++ 3 files changed, 7 insertions(+), 8 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/codecs/hda.c b/sound/soc/codecs/hda.c index a335e96cf53a..5a13065485ab 100644 --- a/sound/soc/codecs/hda.c +++ b/sound/soc/codecs/hda.c @@ -130,10 +130,8 @@ static void hda_codec_unregister_dais(struct hda_codec *codec, if (strcmp(dai->driver->name, pcm->name)) continue; - if (dai->playback_widget) - snd_soc_dapm_free_widget(dai->playback_widget); - if (dai->capture_widget) - snd_soc_dapm_free_widget(dai->capture_widget); + snd_soc_dapm_free_widget(dai->playback_widget); + snd_soc_dapm_free_widget(dai->capture_widget); snd_soc_unregister_dai(dai); break; } diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c index 8fe5917b1e26..8037b15cbdcf 100644 --- a/sound/soc/intel/avs/pcm.c +++ b/sound/soc/intel/avs/pcm.c @@ -1016,10 +1016,8 @@ static void avs_component_hda_unregister_dais(struct snd_soc_component *componen if (!strstr(dai->driver->name, name)) continue; - if (dai->playback_widget) - snd_soc_dapm_free_widget(dai->playback_widget); - if (dai->capture_widget) - snd_soc_dapm_free_widget(dai->capture_widget); + snd_soc_dapm_free_widget(dai->playback_widget); + snd_soc_dapm_free_widget(dai->capture_widget); snd_soc_unregister_dai(dai); } } diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index f9c4fd11853c..5280a1aafb92 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -2489,6 +2489,9 @@ void snd_soc_dapm_free_widget(struct snd_soc_dapm_widget *w) struct snd_soc_dapm_path *p, *next_p; enum snd_soc_dapm_direction dir; + if (!w) + return; + list_del(&w->list); list_del(&w->dirty); /* -- cgit v1.2.3-70-g09d2 From b0cd60f3e9f53209bb4f443ae8b4e92057517efc Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Wed, 19 Oct 2022 11:21:09 -0500 Subject: ALSA/ASoC: hda: clarify bus_get_link() and bus_link_get() helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have two helpers with confusing names and different purposes. Rename bus_get_link() and bus_get_link_at() as bus_get_hlink_by_name() and bus_get_hlink_by_addr() respectively. No functionality change Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Rander Wang Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20221019162115.185917-5-pierre-louis.bossart@linux.intel.com Signed-off-by: Takashi Iwai --- include/sound/hdaudio_ext.h | 6 +++--- sound/hda/ext/hdac_ext_controller.c | 24 ++++++++++++------------ sound/soc/codecs/hda.c | 4 ++-- sound/soc/codecs/hdac_hda.c | 6 +++--- sound/soc/codecs/hdac_hdmi.c | 8 ++++---- sound/soc/intel/avs/pcm.c | 4 ++-- sound/soc/intel/skylake/skl-pcm.c | 4 ++-- sound/soc/sof/intel/hda-dai.c | 4 ++-- 8 files changed, 30 insertions(+), 30 deletions(-) (limited to 'sound/soc/intel') diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h index 8e48a4decfa0..397ab4fc9828 100644 --- a/include/sound/hdaudio_ext.h +++ b/include/sound/hdaudio_ext.h @@ -27,9 +27,9 @@ void snd_hdac_ext_stream_spbcap_enable(struct hdac_bus *chip, bool enable, int index); int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_bus *bus); -struct hdac_ext_link *snd_hdac_ext_bus_link_at(struct hdac_bus *bus, int addr); -struct hdac_ext_link *snd_hdac_ext_bus_get_link(struct hdac_bus *bus, - const char *codec_name); +struct hdac_ext_link *snd_hdac_ext_bus_get_hlink_by_addr(struct hdac_bus *bus, int addr); +struct hdac_ext_link *snd_hdac_ext_bus_get_hlink_by_name(struct hdac_bus *bus, + const char *codec_name); enum hdac_ext_stream_type { HDAC_EXT_STREAM_TYPE_COUPLED = 0, diff --git a/sound/hda/ext/hdac_ext_controller.c b/sound/hda/ext/hdac_ext_controller.c index d3e9c4ae19ee..3730c30470f1 100644 --- a/sound/hda/ext/hdac_ext_controller.c +++ b/sound/hda/ext/hdac_ext_controller.c @@ -126,13 +126,13 @@ void snd_hdac_link_free_all(struct hdac_bus *bus) EXPORT_SYMBOL_GPL(snd_hdac_link_free_all); /** - * snd_hdac_ext_bus_link_at - get link at specified address - * @bus: link's parent bus device + * snd_hdac_ext_bus_get_hlink_by_addr - get hlink at specified address + * @bus: hlink's parent bus device * @addr: codec device address * - * Returns link object or NULL if matching link is not found. + * Returns hlink object or NULL if matching hlink is not found. */ -struct hdac_ext_link *snd_hdac_ext_bus_link_at(struct hdac_bus *bus, int addr) +struct hdac_ext_link *snd_hdac_ext_bus_get_hlink_by_addr(struct hdac_bus *bus, int addr) { struct hdac_ext_link *hlink; int i; @@ -143,15 +143,15 @@ struct hdac_ext_link *snd_hdac_ext_bus_link_at(struct hdac_bus *bus, int addr) return hlink; return NULL; } -EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_at); +EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_get_hlink_by_addr); /** - * snd_hdac_ext_bus_get_link - get link based on codec name + * snd_hdac_ext_bus_get_hlink_by_name - get hlink based on codec name * @bus: the pointer to HDAC bus object * @codec_name: codec name */ -struct hdac_ext_link *snd_hdac_ext_bus_get_link(struct hdac_bus *bus, - const char *codec_name) +struct hdac_ext_link *snd_hdac_ext_bus_get_hlink_by_name(struct hdac_bus *bus, + const char *codec_name) { int bus_idx, addr; @@ -162,9 +162,9 @@ struct hdac_ext_link *snd_hdac_ext_bus_get_link(struct hdac_bus *bus, if (addr < 0 || addr > 31) return NULL; - return snd_hdac_ext_bus_link_at(bus, addr); + return snd_hdac_ext_bus_get_hlink_by_addr(bus, addr); } -EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_get_link); +EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_get_hlink_by_name); static int check_hdac_link_power_active(struct hdac_ext_link *hlink, bool enable) { @@ -337,7 +337,7 @@ static void hdac_ext_codec_link_up(struct hdac_device *codec) { const char *devname = dev_name(&codec->dev); struct hdac_ext_link *hlink = - snd_hdac_ext_bus_get_link(codec->bus, devname); + snd_hdac_ext_bus_get_hlink_by_name(codec->bus, devname); if (hlink) snd_hdac_ext_bus_link_get(codec->bus, hlink); @@ -347,7 +347,7 @@ static void hdac_ext_codec_link_down(struct hdac_device *codec) { const char *devname = dev_name(&codec->dev); struct hdac_ext_link *hlink = - snd_hdac_ext_bus_get_link(codec->bus, devname); + snd_hdac_ext_bus_get_hlink_by_name(codec->bus, devname); if (hlink) snd_hdac_ext_bus_link_put(codec->bus, hlink); diff --git a/sound/soc/codecs/hda.c b/sound/soc/codecs/hda.c index 61e8e9be6b8d..0b8ccc5be480 100644 --- a/sound/soc/codecs/hda.c +++ b/sound/soc/codecs/hda.c @@ -181,7 +181,7 @@ static int hda_codec_probe(struct snd_soc_component *component) !pm_runtime_status_suspended(&hdev->dev)); #endif - hlink = snd_hdac_ext_bus_link_at(bus, hdev->addr); + hlink = snd_hdac_ext_bus_get_hlink_by_addr(bus, hdev->addr); if (!hlink) { dev_err(&hdev->dev, "hdac link not found\n"); return -EIO; @@ -289,7 +289,7 @@ static void hda_codec_remove(struct snd_soc_component *component) if (hda_codec_is_display(codec)) snd_hdac_display_power(bus, hdev->addr, false); - hlink = snd_hdac_ext_bus_link_at(bus, hdev->addr); + hlink = snd_hdac_ext_bus_get_hlink_by_addr(bus, hdev->addr); if (hlink) snd_hdac_ext_bus_link_put(bus, hlink); /* diff --git a/sound/soc/codecs/hdac_hda.c b/sound/soc/codecs/hdac_hda.c index 8af434e14bfb..be66853afbe2 100644 --- a/sound/soc/codecs/hdac_hda.c +++ b/sound/soc/codecs/hdac_hda.c @@ -400,7 +400,7 @@ static int hdac_hda_codec_probe(struct snd_soc_component *component) hda_codec_patch_t patch; int ret; - hlink = snd_hdac_ext_bus_get_link(hdev->bus, dev_name(&hdev->dev)); + hlink = snd_hdac_ext_bus_get_hlink_by_name(hdev->bus, dev_name(&hdev->dev)); if (!hlink) { dev_err(&hdev->dev, "hdac link not found\n"); return -EIO; @@ -516,7 +516,7 @@ static void hdac_hda_codec_remove(struct snd_soc_component *component) struct hda_codec *codec = hda_pvt->codec; struct hdac_ext_link *hlink = NULL; - hlink = snd_hdac_ext_bus_get_link(hdev->bus, dev_name(&hdev->dev)); + hlink = snd_hdac_ext_bus_get_hlink_by_name(hdev->bus, dev_name(&hdev->dev)); if (!hlink) { dev_err(&hdev->dev, "hdac link not found\n"); return; @@ -584,7 +584,7 @@ static int hdac_hda_dev_probe(struct hdac_device *hdev) int ret; /* hold the ref while we probe */ - hlink = snd_hdac_ext_bus_get_link(hdev->bus, dev_name(&hdev->dev)); + hlink = snd_hdac_ext_bus_get_hlink_by_name(hdev->bus, dev_name(&hdev->dev)); if (!hlink) { dev_err(&hdev->dev, "hdac link not found\n"); return -EIO; diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index cb23650ad522..ed4f7cdda04f 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -1967,7 +1967,7 @@ static int hdmi_codec_probe(struct snd_soc_component *component) * hold the ref while we probe, also no need to drop the ref on * exit, we call pm_runtime_suspend() so that will do for us */ - hlink = snd_hdac_ext_bus_get_link(hdev->bus, dev_name(&hdev->dev)); + hlink = snd_hdac_ext_bus_get_hlink_by_name(hdev->bus, dev_name(&hdev->dev)); if (!hlink) { dev_err(&hdev->dev, "hdac link not found\n"); return -EIO; @@ -2144,7 +2144,7 @@ static int hdac_hdmi_dev_probe(struct hdac_device *hdev) const struct hda_device_id *hdac_id = hdac_get_device_id(hdev, hdrv); /* hold the ref while we probe */ - hlink = snd_hdac_ext_bus_get_link(hdev->bus, dev_name(&hdev->dev)); + hlink = snd_hdac_ext_bus_get_hlink_by_name(hdev->bus, dev_name(&hdev->dev)); if (!hlink) { dev_err(&hdev->dev, "hdac link not found\n"); return -EIO; @@ -2244,7 +2244,7 @@ static int hdac_hdmi_runtime_suspend(struct device *dev) snd_hdac_codec_read(hdev, hdev->afg, 0, AC_VERB_SET_POWER_STATE, AC_PWRST_D3); - hlink = snd_hdac_ext_bus_get_link(bus, dev_name(dev)); + hlink = snd_hdac_ext_bus_get_hlink_by_name(bus, dev_name(dev)); if (!hlink) { dev_err(dev, "hdac link not found\n"); return -EIO; @@ -2270,7 +2270,7 @@ static int hdac_hdmi_runtime_resume(struct device *dev) if (!bus) return 0; - hlink = snd_hdac_ext_bus_get_link(bus, dev_name(dev)); + hlink = snd_hdac_ext_bus_get_hlink_by_name(bus, dev_name(dev)); if (!hlink) { dev_err(dev, "hdac link not found\n"); return -EIO; diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c index 8fe5917b1e26..4e5849535a8c 100644 --- a/sound/soc/intel/avs/pcm.c +++ b/sound/soc/intel/avs/pcm.c @@ -292,7 +292,7 @@ static int avs_dai_hda_be_hw_free(struct snd_pcm_substream *substream, struct sn /* clear link <-> stream mapping */ codec = dev_to_hda_codec(asoc_rtd_to_codec(rtd, 0)->dev); - link = snd_hdac_ext_bus_link_at(&codec->bus->core, codec->core.addr); + link = snd_hdac_ext_bus_get_hlink_by_addr(&codec->bus->core, codec->core.addr); if (!link) return -EINVAL; @@ -325,7 +325,7 @@ static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct sn snd_hdac_ext_link_stream_reset(link_stream); snd_hdac_ext_link_stream_setup(link_stream, format_val); - link = snd_hdac_ext_bus_link_at(bus, codec->core.addr); + link = snd_hdac_ext_bus_get_hlink_by_addr(bus, codec->core.addr); if (!link) return -EINVAL; diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index 1015716f9336..b07c5b58e0a6 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c @@ -558,7 +558,7 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream, snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev); - link = snd_hdac_ext_bus_get_link(bus, codec_dai->component->name); + link = snd_hdac_ext_bus_get_hlink_by_name(bus, codec_dai->component->name); if (!link) return -EINVAL; @@ -643,7 +643,7 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream, link_dev->link_prepared = 0; - link = snd_hdac_ext_bus_get_link(bus, asoc_rtd_to_codec(rtd, 0)->component->name); + link = snd_hdac_ext_bus_get_hlink_by_name(bus, asoc_rtd_to_codec(rtd, 0)->component->name); if (!link) return -EINVAL; diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index 0fadf99f2efa..b71bb29e764b 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -149,7 +149,7 @@ static int hda_link_dma_cleanup(struct snd_pcm_substream *substream, struct hdac_ext_link *hlink; int stream_tag; - hlink = snd_hdac_ext_bus_get_link(bus, codec_dai->component->name); + hlink = snd_hdac_ext_bus_get_hlink_by_name(bus, codec_dai->component->name); if (!hlink) return -EINVAL; @@ -225,7 +225,7 @@ static int hda_link_dma_hw_params(struct snd_pcm_substream *substream, snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)hext_stream); } - hlink = snd_hdac_ext_bus_get_link(bus, codec_dai->component->name); + hlink = snd_hdac_ext_bus_get_hlink_by_name(bus, codec_dai->component->name); if (!hlink) return -EINVAL; -- cgit v1.2.3-70-g09d2 From 7f05ca9a7467f05b8703b37bdc1ddddd0e9f8876 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Wed, 19 Oct 2022 11:21:10 -0500 Subject: ALSA/ASoC: hda: ext: add 'ext' prefix to snd_hdac_link_free_all MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No functionality change, just prefix addition to clearly identify that the helper only applies to the 'ext' part for Intel platforms. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20221019162115.185917-6-pierre-louis.bossart@linux.intel.com Signed-off-by: Takashi Iwai --- include/sound/hdaudio_ext.h | 2 +- sound/hda/ext/hdac_ext_controller.c | 6 +++--- sound/soc/intel/avs/core.c | 2 +- sound/soc/intel/skylake/skl.c | 2 +- sound/soc/sof/intel/hda.c | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) (limited to 'sound/soc/intel') diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h index 397ab4fc9828..f0edbadc9902 100644 --- a/include/sound/hdaudio_ext.h +++ b/include/sound/hdaudio_ext.h @@ -80,7 +80,7 @@ struct hdac_ext_stream { int snd_hdac_ext_stream_init_all(struct hdac_bus *bus, int start_idx, int num_stream, int dir); void snd_hdac_ext_stream_free_all(struct hdac_bus *bus); -void snd_hdac_link_free_all(struct hdac_bus *bus); +void snd_hdac_ext_link_free_all(struct hdac_bus *bus); struct hdac_ext_stream *snd_hdac_ext_stream_assign(struct hdac_bus *bus, struct snd_pcm_substream *substream, int type); diff --git a/sound/hda/ext/hdac_ext_controller.c b/sound/hda/ext/hdac_ext_controller.c index 3730c30470f1..c0b801fa93c0 100644 --- a/sound/hda/ext/hdac_ext_controller.c +++ b/sound/hda/ext/hdac_ext_controller.c @@ -108,12 +108,12 @@ int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_bus *bus) EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_get_ml_capabilities); /** - * snd_hdac_link_free_all- free hdac extended link objects + * snd_hdac_ext_link_free_all- free hdac extended link objects * * @bus: the pointer to HDAC bus object */ -void snd_hdac_link_free_all(struct hdac_bus *bus) +void snd_hdac_ext_link_free_all(struct hdac_bus *bus) { struct hdac_ext_link *hlink; @@ -123,7 +123,7 @@ void snd_hdac_link_free_all(struct hdac_bus *bus) kfree(hlink); } } -EXPORT_SYMBOL_GPL(snd_hdac_link_free_all); +EXPORT_SYMBOL_GPL(snd_hdac_ext_link_free_all); /** * snd_hdac_ext_bus_get_hlink_by_addr - get hlink at specified address diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c index bb0719c58ca4..8d502fee38b5 100644 --- a/sound/soc/intel/avs/core.c +++ b/sound/soc/intel/avs/core.c @@ -504,7 +504,7 @@ static void avs_pci_remove(struct pci_dev *pci) snd_hdac_bus_free_stream_pages(bus); snd_hdac_ext_stream_free_all(bus); /* reverse ml_capabilities */ - snd_hdac_link_free_all(bus); + snd_hdac_ext_link_free_all(bus); snd_hdac_ext_bus_exit(bus); avs_dsp_core_disable(adev, GENMASK(adev->hw_cfg.dsp_cores - 1, 0)); diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index bbba2df33aaf..780207fe814f 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -445,7 +445,7 @@ static int skl_free(struct hdac_bus *bus) free_irq(bus->irq, (void *)bus); snd_hdac_bus_free_stream_pages(bus); snd_hdac_ext_stream_free_all(bus); - snd_hdac_link_free_all(bus); + snd_hdac_ext_link_free_all(bus); if (bus->remap_addr) iounmap(bus->remap_addr); diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 1188ec51816b..c6c6ea8a73f6 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -1224,7 +1224,7 @@ int hda_dsp_remove(struct snd_sof_dev *sdev) hda_dsp_stream_free(sdev); #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - snd_hdac_link_free_all(bus); + snd_hdac_ext_link_free_all(bus); #endif iounmap(sdev->bar[HDA_DSP_BAR]); -- cgit v1.2.3-70-g09d2 From 00b6cd957d665aad5e86f019961089842c7a6ae4 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Wed, 19 Oct 2022 11:21:11 -0500 Subject: ALSA/ASoC: hda: ext: remove 'link' prefix for stream-related operations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We should only use 'link' in the context of multi-link configurations. Streams are configured from a different register space and are not dependent on link except for LOSIDV settings. Not functionality change, just pure rename. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20221019162115.185917-7-pierre-louis.bossart@linux.intel.com Signed-off-by: Takashi Iwai --- include/sound/hdaudio_ext.h | 8 ++++---- sound/hda/ext/hdac_ext_stream.c | 28 ++++++++++++++-------------- sound/soc/intel/avs/pcm.c | 8 ++++---- sound/soc/intel/skylake/skl-pcm.c | 8 ++++---- sound/soc/sof/intel/hda-dai.c | 16 ++++++++-------- 5 files changed, 34 insertions(+), 34 deletions(-) (limited to 'sound/soc/intel') diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h index f0edbadc9902..472fed072e98 100644 --- a/include/sound/hdaudio_ext.h +++ b/include/sound/hdaudio_ext.h @@ -100,10 +100,10 @@ int snd_hdac_ext_stream_set_dpibr(struct hdac_bus *bus, struct hdac_ext_stream *hext_stream, u32 value); int snd_hdac_ext_stream_set_lpib(struct hdac_ext_stream *hext_stream, u32 value); -void snd_hdac_ext_link_stream_start(struct hdac_ext_stream *hext_stream); -void snd_hdac_ext_link_stream_clear(struct hdac_ext_stream *hext_stream); -void snd_hdac_ext_link_stream_reset(struct hdac_ext_stream *hext_stream); -int snd_hdac_ext_link_stream_setup(struct hdac_ext_stream *hext_stream, int fmt); +void snd_hdac_ext_stream_start(struct hdac_ext_stream *hext_stream); +void snd_hdac_ext_stream_clear(struct hdac_ext_stream *hext_stream); +void snd_hdac_ext_stream_reset(struct hdac_ext_stream *hext_stream); +int snd_hdac_ext_stream_setup(struct hdac_ext_stream *hext_stream, int fmt); struct hdac_ext_link { struct hdac_bus *bus; diff --git a/sound/hda/ext/hdac_ext_stream.c b/sound/hda/ext/hdac_ext_stream.c index 70f3ad71aaf0..c06beaaffe0a 100644 --- a/sound/hda/ext/hdac_ext_stream.c +++ b/sound/hda/ext/hdac_ext_stream.c @@ -140,36 +140,36 @@ void snd_hdac_ext_stream_decouple(struct hdac_bus *bus, EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_decouple); /** - * snd_hdac_ext_link_stream_start - start a stream + * snd_hdac_ext_stream_start - start a stream * @hext_stream: HD-audio ext core stream to start */ -void snd_hdac_ext_link_stream_start(struct hdac_ext_stream *hext_stream) +void snd_hdac_ext_stream_start(struct hdac_ext_stream *hext_stream) { snd_hdac_updatel(hext_stream->pplc_addr, AZX_REG_PPLCCTL, AZX_PPLCCTL_RUN, AZX_PPLCCTL_RUN); } -EXPORT_SYMBOL_GPL(snd_hdac_ext_link_stream_start); +EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_start); /** - * snd_hdac_ext_link_stream_clear - stop a stream DMA + * snd_hdac_ext_stream_clear - stop a stream DMA * @hext_stream: HD-audio ext core stream to stop */ -void snd_hdac_ext_link_stream_clear(struct hdac_ext_stream *hext_stream) +void snd_hdac_ext_stream_clear(struct hdac_ext_stream *hext_stream) { snd_hdac_updatel(hext_stream->pplc_addr, AZX_REG_PPLCCTL, AZX_PPLCCTL_RUN, 0); } -EXPORT_SYMBOL_GPL(snd_hdac_ext_link_stream_clear); +EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_clear); /** - * snd_hdac_ext_link_stream_reset - reset a stream + * snd_hdac_ext_stream_reset - reset a stream * @hext_stream: HD-audio ext core stream to reset */ -void snd_hdac_ext_link_stream_reset(struct hdac_ext_stream *hext_stream) +void snd_hdac_ext_stream_reset(struct hdac_ext_stream *hext_stream) { unsigned char val; int timeout; - snd_hdac_ext_link_stream_clear(hext_stream); + snd_hdac_ext_stream_clear(hext_stream); snd_hdac_updatel(hext_stream->pplc_addr, AZX_REG_PPLCCTL, AZX_PPLCCTL_STRST, AZX_PPLCCTL_STRST); @@ -196,20 +196,20 @@ void snd_hdac_ext_link_stream_reset(struct hdac_ext_stream *hext_stream) } while (--timeout); } -EXPORT_SYMBOL_GPL(snd_hdac_ext_link_stream_reset); +EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_reset); /** - * snd_hdac_ext_link_stream_setup - set up the SD for streaming + * snd_hdac_ext_stream_setup - set up the SD for streaming * @hext_stream: HD-audio ext core stream to set up * @fmt: stream format */ -int snd_hdac_ext_link_stream_setup(struct hdac_ext_stream *hext_stream, int fmt) +int snd_hdac_ext_stream_setup(struct hdac_ext_stream *hext_stream, int fmt) { struct hdac_stream *hstream = &hext_stream->hstream; unsigned int val; /* make sure the run bit is zero for SD */ - snd_hdac_ext_link_stream_clear(hext_stream); + snd_hdac_ext_stream_clear(hext_stream); /* program the stream_tag */ val = readl(hext_stream->pplc_addr + AZX_REG_PPLCCTL); val = (val & ~AZX_PPLCCTL_STRM_MASK) | @@ -221,7 +221,7 @@ int snd_hdac_ext_link_stream_setup(struct hdac_ext_stream *hext_stream, int fmt) return 0; } -EXPORT_SYMBOL_GPL(snd_hdac_ext_link_stream_setup); +EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_setup); /** * snd_hdac_ext_link_set_stream_id - maps stream id to link output diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c index 4e5849535a8c..d77afe5c65b9 100644 --- a/sound/soc/intel/avs/pcm.c +++ b/sound/soc/intel/avs/pcm.c @@ -322,8 +322,8 @@ static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct sn runtime->sample_bits, 0); snd_hdac_ext_stream_decouple(bus, link_stream, true); - snd_hdac_ext_link_stream_reset(link_stream); - snd_hdac_ext_link_stream_setup(link_stream, format_val); + snd_hdac_ext_stream_reset(link_stream); + snd_hdac_ext_stream_setup(link_stream, format_val); link = snd_hdac_ext_bus_get_hlink_by_addr(bus, codec->core.addr); if (!link) @@ -355,7 +355,7 @@ static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd, switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - snd_hdac_ext_link_stream_start(link_stream); + snd_hdac_ext_stream_start(link_stream); ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO); if (ret < 0) @@ -368,7 +368,7 @@ static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd, if (ret < 0) dev_err(dai->dev, "pause BE path failed: %d\n", ret); - snd_hdac_ext_link_stream_clear(link_stream); + snd_hdac_ext_stream_clear(link_stream); if (cmd == SNDRV_PCM_TRIGGER_STOP) { ret = avs_path_reset(data->path); diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index b07c5b58e0a6..f7e97b5a449f 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c @@ -190,9 +190,9 @@ int skl_pcm_link_dma_prepare(struct device *dev, struct skl_pipe_params *params) dev_dbg(dev, "format_val=%d, rate=%d, ch=%d, format=%d\n", format_val, params->s_freq, params->ch, params->format); - snd_hdac_ext_link_stream_reset(stream); + snd_hdac_ext_stream_reset(stream); - snd_hdac_ext_link_stream_setup(stream, format_val); + snd_hdac_ext_stream_setup(stream, format_val); stream_tag = hstream->stream_tag; if (stream->hstream.direction == SNDRV_PCM_STREAM_PLAYBACK) { @@ -612,13 +612,13 @@ static int skl_link_pcm_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - snd_hdac_ext_link_stream_start(link_dev); + snd_hdac_ext_stream_start(link_dev); break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: - snd_hdac_ext_link_stream_clear(link_dev); + snd_hdac_ext_stream_clear(link_dev); if (cmd == SNDRV_PCM_TRIGGER_SUSPEND) snd_hdac_ext_stream_decouple(bus, stream, false); break; diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index b71bb29e764b..575adf3133c2 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -154,7 +154,7 @@ static int hda_link_dma_cleanup(struct snd_pcm_substream *substream, return -EINVAL; if (trigger_suspend_stop) - snd_hdac_ext_link_stream_clear(hext_stream); + snd_hdac_ext_stream_clear(hext_stream); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { stream_tag = hdac_stream(hext_stream)->stream_tag; @@ -180,7 +180,7 @@ static int hda_link_dma_params(struct hdac_ext_stream *hext_stream, struct hdac_ext_link *hlink; unsigned int format_val; - snd_hdac_ext_link_stream_reset(hext_stream); + snd_hdac_ext_stream_reset(hext_stream); format_val = snd_hdac_calc_stream_format(params->s_freq, params->ch, params->format, @@ -189,7 +189,7 @@ static int hda_link_dma_params(struct hdac_ext_stream *hext_stream, dev_dbg(bus->dev, "format_val=%d, rate=%d, ch=%d, format=%d\n", format_val, params->s_freq, params->ch, params->format); - snd_hdac_ext_link_stream_setup(hext_stream, format_val); + snd_hdac_ext_stream_setup(hext_stream, format_val); if (hext_stream->hstream.direction == SNDRV_PCM_STREAM_PLAYBACK) { list_for_each_entry(hlink, &bus->hlink_list, list) { @@ -270,7 +270,7 @@ static int hda_link_dma_trigger(struct snd_pcm_substream *substream, int cmd) switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - snd_hdac_ext_link_stream_start(hext_stream); + snd_hdac_ext_stream_start(hext_stream); break; case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: @@ -280,7 +280,7 @@ static int hda_link_dma_trigger(struct snd_pcm_substream *substream, int cmd) break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - snd_hdac_ext_link_stream_clear(hext_stream); + snd_hdac_ext_stream_clear(hext_stream); break; default: @@ -476,7 +476,7 @@ static int ipc4_hda_dai_trigger(struct snd_pcm_substream *substream, switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - snd_hdac_ext_link_stream_start(hext_stream); + snd_hdac_ext_stream_start(hext_stream); break; case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: @@ -491,7 +491,7 @@ static int ipc4_hda_dai_trigger(struct snd_pcm_substream *substream, pipeline->state = SOF_IPC4_PIPE_PAUSED; - snd_hdac_ext_link_stream_clear(hext_stream); + snd_hdac_ext_stream_clear(hext_stream); ret = sof_ipc4_set_pipeline_state(sdev, swidget->pipeline_id, SOF_IPC4_PIPE_RESET); @@ -519,7 +519,7 @@ static int ipc4_hda_dai_trigger(struct snd_pcm_substream *substream, pipeline->state = SOF_IPC4_PIPE_PAUSED; - snd_hdac_ext_link_stream_clear(hext_stream); + snd_hdac_ext_stream_clear(hext_stream); break; } default: -- cgit v1.2.3-70-g09d2 From 7fa403f2a0f4a9f0fd0e0e0f472dab60f632f06e Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Wed, 19 Oct 2022 11:21:12 -0500 Subject: ALSA/ASoC: hda: ext: add 'bus' prefix for multi-link stream setting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All the helpers dealing with multi-link configurations are located in the hdac_ext_controller.c, except the two set/clear routines that modify the LOSIDV registers. For consistency, move the two helpers and add the 'bus' prefix. One could argue that the 'ml' prefix might be more relevant but that would be a larger code change. No functionality change, just move and rename. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20221019162115.185917-8-pierre-louis.bossart@linux.intel.com Signed-off-by: Takashi Iwai --- include/sound/hdaudio_ext.h | 8 ++++---- sound/hda/ext/hdac_ext_controller.c | 24 ++++++++++++++++++++++++ sound/hda/ext/hdac_ext_stream.c | 24 ------------------------ sound/soc/intel/avs/pcm.c | 4 ++-- sound/soc/intel/skylake/skl-pcm.c | 6 +++--- sound/soc/sof/intel/hda-dai.c | 6 +++--- 6 files changed, 36 insertions(+), 36 deletions(-) (limited to 'sound/soc/intel') diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h index 472fed072e98..79aea619adda 100644 --- a/include/sound/hdaudio_ext.h +++ b/include/sound/hdaudio_ext.h @@ -121,10 +121,10 @@ int snd_hdac_ext_bus_link_power_up(struct hdac_ext_link *hlink); int snd_hdac_ext_bus_link_power_down(struct hdac_ext_link *hlink); int snd_hdac_ext_bus_link_power_up_all(struct hdac_bus *bus); int snd_hdac_ext_bus_link_power_down_all(struct hdac_bus *bus); -void snd_hdac_ext_link_set_stream_id(struct hdac_ext_link *hlink, - int stream); -void snd_hdac_ext_link_clear_stream_id(struct hdac_ext_link *hlink, - int stream); +void snd_hdac_ext_bus_link_set_stream_id(struct hdac_ext_link *hlink, + int stream); +void snd_hdac_ext_bus_link_clear_stream_id(struct hdac_ext_link *hlink, + int stream); int snd_hdac_ext_bus_link_get(struct hdac_bus *bus, struct hdac_ext_link *hlink); int snd_hdac_ext_bus_link_put(struct hdac_bus *bus, struct hdac_ext_link *hlink); diff --git a/sound/hda/ext/hdac_ext_controller.c b/sound/hda/ext/hdac_ext_controller.c index c0b801fa93c0..08d3313f2df7 100644 --- a/sound/hda/ext/hdac_ext_controller.c +++ b/sound/hda/ext/hdac_ext_controller.c @@ -253,6 +253,30 @@ int snd_hdac_ext_bus_link_power_down_all(struct hdac_bus *bus) } EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power_down_all); +/** + * snd_hdac_ext_bus_link_set_stream_id - maps stream id to link output + * @link: HD-audio ext link to set up + * @stream: stream id + */ +void snd_hdac_ext_bus_link_set_stream_id(struct hdac_ext_link *link, + int stream) +{ + snd_hdac_updatew(link->ml_addr, AZX_REG_ML_LOSIDV, (1 << stream), 1 << stream); +} +EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_set_stream_id); + +/** + * snd_hdac_ext_bus_link_clear_stream_id - maps stream id to link output + * @link: HD-audio ext link to set up + * @stream: stream id + */ +void snd_hdac_ext_bus_link_clear_stream_id(struct hdac_ext_link *link, + int stream) +{ + snd_hdac_updatew(link->ml_addr, AZX_REG_ML_LOSIDV, (1 << stream), 0); +} +EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_clear_stream_id); + int snd_hdac_ext_bus_link_get(struct hdac_bus *bus, struct hdac_ext_link *hlink) { diff --git a/sound/hda/ext/hdac_ext_stream.c b/sound/hda/ext/hdac_ext_stream.c index c06beaaffe0a..da2a9b54a5be 100644 --- a/sound/hda/ext/hdac_ext_stream.c +++ b/sound/hda/ext/hdac_ext_stream.c @@ -223,30 +223,6 @@ int snd_hdac_ext_stream_setup(struct hdac_ext_stream *hext_stream, int fmt) } EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_setup); -/** - * snd_hdac_ext_link_set_stream_id - maps stream id to link output - * @link: HD-audio ext link to set up - * @stream: stream id - */ -void snd_hdac_ext_link_set_stream_id(struct hdac_ext_link *link, - int stream) -{ - snd_hdac_updatew(link->ml_addr, AZX_REG_ML_LOSIDV, (1 << stream), 1 << stream); -} -EXPORT_SYMBOL_GPL(snd_hdac_ext_link_set_stream_id); - -/** - * snd_hdac_ext_link_clear_stream_id - maps stream id to link output - * @link: HD-audio ext link to set up - * @stream: stream id - */ -void snd_hdac_ext_link_clear_stream_id(struct hdac_ext_link *link, - int stream) -{ - snd_hdac_updatew(link->ml_addr, AZX_REG_ML_LOSIDV, (1 << stream), 0); -} -EXPORT_SYMBOL_GPL(snd_hdac_ext_link_clear_stream_id); - static struct hdac_ext_stream * hdac_ext_link_stream_assign(struct hdac_bus *bus, struct snd_pcm_substream *substream) diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c index d77afe5c65b9..95cb87339400 100644 --- a/sound/soc/intel/avs/pcm.c +++ b/sound/soc/intel/avs/pcm.c @@ -297,7 +297,7 @@ static int avs_dai_hda_be_hw_free(struct snd_pcm_substream *substream, struct sn return -EINVAL; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - snd_hdac_ext_link_clear_stream_id(link, hdac_stream(link_stream)->stream_tag); + snd_hdac_ext_bus_link_clear_stream_id(link, hdac_stream(link_stream)->stream_tag); return 0; } @@ -330,7 +330,7 @@ static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct sn return -EINVAL; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - snd_hdac_ext_link_set_stream_id(link, hdac_stream(link_stream)->stream_tag); + snd_hdac_ext_bus_link_set_stream_id(link, hdac_stream(link_stream)->stream_tag); ret = avs_dai_prepare(to_avs_dev(dai->dev), substream, dai); if (ret) diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index f7e97b5a449f..27b03c34abd0 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c @@ -198,8 +198,8 @@ int skl_pcm_link_dma_prepare(struct device *dev, struct skl_pipe_params *params) if (stream->hstream.direction == SNDRV_PCM_STREAM_PLAYBACK) { list_for_each_entry(link, &bus->hlink_list, list) { if (link->index == params->link_index) - snd_hdac_ext_link_set_stream_id(link, - stream_tag); + snd_hdac_ext_bus_link_set_stream_id(link, + stream_tag); } } @@ -649,7 +649,7 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream, if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { stream_tag = hdac_stream(link_dev)->stream_tag; - snd_hdac_ext_link_clear_stream_id(link, stream_tag); + snd_hdac_ext_bus_link_clear_stream_id(link, stream_tag); } snd_hdac_ext_stream_release(link_dev, HDAC_EXT_STREAM_TYPE_LINK); diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index 575adf3133c2..64e8ca016b21 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -158,7 +158,7 @@ static int hda_link_dma_cleanup(struct snd_pcm_substream *substream, if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { stream_tag = hdac_stream(hext_stream)->stream_tag; - snd_hdac_ext_link_clear_stream_id(hlink, stream_tag); + snd_hdac_ext_bus_link_clear_stream_id(hlink, stream_tag); } snd_soc_dai_set_dma_data(cpu_dai, substream, NULL); snd_hdac_ext_stream_release(hext_stream, HDAC_EXT_STREAM_TYPE_LINK); @@ -194,8 +194,8 @@ static int hda_link_dma_params(struct hdac_ext_stream *hext_stream, if (hext_stream->hstream.direction == SNDRV_PCM_STREAM_PLAYBACK) { list_for_each_entry(hlink, &bus->hlink_list, list) { if (hlink->index == params->link_index) - snd_hdac_ext_link_set_stream_id(hlink, - stream_tag); + snd_hdac_ext_bus_link_set_stream_id(hlink, + stream_tag); } } -- cgit v1.2.3-70-g09d2 From 6258234129b013c534fa10abaf08751b2401b22b Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Wed, 19 Oct 2022 11:21:15 -0500 Subject: ALSA/ASoC: hda: move SPIB/DRMS functionality from ext layer The SPIB and DRMS capabilities are orthogonal to the DSP enablement and can be used whether the stream is coupled or not. The existing code partitioning makes limited sense, the capabilities are parsed at the sound/hda level but helpers are located in sound/hda/ext. This patch moves all the SPIB/DRMS functionality to the sound/hda layer. This reduces the complexity of the sound/hda/ext layer which is now limited to handling the multi-link extensions and stream coupling/decoupling helpers. Note that this is an iso-functionality code move and rename, the HDaudio legacy driver would need additional changes to make use of these capabilities. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20221019162115.185917-11-pierre-louis.bossart@linux.intel.com Signed-off-by: Takashi Iwai --- include/sound/hdaudio.h | 26 ++++++ include/sound/hdaudio_ext.h | 34 -------- sound/hda/ext/hdac_ext_stream.c | 139 --------------------------------- sound/hda/hdac_stream.c | 136 ++++++++++++++++++++++++++++++++ sound/soc/intel/avs/loader.c | 16 ++-- sound/soc/intel/skylake/skl-messages.c | 6 +- sound/soc/intel/skylake/skl-pcm.c | 17 ++-- sound/soc/sof/intel/hda-pcm.c | 3 +- sound/soc/sof/intel/hda-stream.c | 16 ++-- 9 files changed, 190 insertions(+), 203 deletions(-) (limited to 'sound/soc/intel') diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index 35778f953a3f..78f1809a4ad6 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h @@ -495,6 +495,13 @@ static inline u16 snd_hdac_reg_readw(struct hdac_bus *bus, void __iomem *addr) snd_hdac_chip_writeb(chip, reg, \ (snd_hdac_chip_readb(chip, reg) & ~(mask)) | (val)) +/* update register macro */ +#define snd_hdac_updatel(addr, reg, mask, val) \ + writel(((readl(addr + reg) & ~(mask)) | (val)), addr + reg) + +#define snd_hdac_updatew(addr, reg, mask, val) \ + writew(((readw(addr + reg) & ~(mask)) | (val)), addr + reg) + /* * HD-audio stream */ @@ -511,6 +518,13 @@ struct hdac_stream { void __iomem *sd_addr; /* stream descriptor pointer */ + void __iomem *spib_addr; /* software position in buffers stream pointer */ + void __iomem *fifo_addr; /* software position Max fifos stream pointer */ + + void __iomem *dpibr_addr; /* DMA position in buffer resume pointer */ + u32 dpib; /* DMA position in buffer */ + u32 lpib; /* Linear position in buffer */ + u32 sd_int_sta_mask; /* stream int status mask */ /* pcm support */ @@ -575,6 +589,18 @@ void snd_hdac_stream_timecounter_init(struct hdac_stream *azx_dev, int snd_hdac_get_stream_stripe_ctl(struct hdac_bus *bus, struct snd_pcm_substream *substream); +void snd_hdac_stream_spbcap_enable(struct hdac_bus *chip, + bool enable, int index); +int snd_hdac_stream_set_spib(struct hdac_bus *bus, + struct hdac_stream *azx_dev, u32 value); +int snd_hdac_stream_get_spbmaxfifo(struct hdac_bus *bus, + struct hdac_stream *azx_dev); +void snd_hdac_stream_drsm_enable(struct hdac_bus *bus, + bool enable, int index); +int snd_hdac_stream_set_dpibr(struct hdac_bus *bus, + struct hdac_stream *azx_dev, u32 value); +int snd_hdac_stream_set_lpib(struct hdac_stream *azx_dev, u32 value); + /* * macros for easy use */ diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h index 79aea619adda..90fd47e05370 100644 --- a/include/sound/hdaudio_ext.h +++ b/include/sound/hdaudio_ext.h @@ -23,9 +23,6 @@ void snd_hdac_ext_bus_device_remove(struct hdac_bus *bus); void snd_hdac_ext_bus_ppcap_enable(struct hdac_bus *chip, bool enable); void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_bus *chip, bool enable); -void snd_hdac_ext_stream_spbcap_enable(struct hdac_bus *chip, - bool enable, int index); - int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_bus *bus); struct hdac_ext_link *snd_hdac_ext_bus_get_hlink_by_addr(struct hdac_bus *bus, int addr); struct hdac_ext_link *snd_hdac_ext_bus_get_hlink_by_name(struct hdac_bus *bus, @@ -43,11 +40,6 @@ enum hdac_ext_stream_type { * @hstream: hdac_stream * @pphc_addr: processing pipe host stream pointer * @pplc_addr: processing pipe link stream pointer - * @spib_addr: software position in buffers stream pointer - * @fifo_addr: software position Max fifos stream pointer - * @dpibr_addr: DMA position in buffer resume pointer - * @dpib: DMA position in buffer - * @lpib: Linear position in buffer * @decoupled: stream host and link is decoupled * @link_locked: link is locked * @link_prepared: link is prepared @@ -59,13 +51,6 @@ struct hdac_ext_stream { void __iomem *pphc_addr; void __iomem *pplc_addr; - void __iomem *spib_addr; - void __iomem *fifo_addr; - - void __iomem *dpibr_addr; - - u32 dpib; - u32 lpib; bool decoupled:1; bool link_locked:1; bool link_prepared; @@ -90,16 +75,6 @@ void snd_hdac_ext_stream_decouple_locked(struct hdac_bus *bus, void snd_hdac_ext_stream_decouple(struct hdac_bus *bus, struct hdac_ext_stream *azx_dev, bool decouple); -int snd_hdac_ext_stream_set_spib(struct hdac_bus *bus, - struct hdac_ext_stream *hext_stream, u32 value); -int snd_hdac_ext_stream_get_spbmaxfifo(struct hdac_bus *bus, - struct hdac_ext_stream *hext_stream); -void snd_hdac_ext_stream_drsm_enable(struct hdac_bus *bus, - bool enable, int index); -int snd_hdac_ext_stream_set_dpibr(struct hdac_bus *bus, - struct hdac_ext_stream *hext_stream, u32 value); -int snd_hdac_ext_stream_set_lpib(struct hdac_ext_stream *hext_stream, u32 value); - void snd_hdac_ext_stream_start(struct hdac_ext_stream *hext_stream); void snd_hdac_ext_stream_clear(struct hdac_ext_stream *hext_stream); void snd_hdac_ext_stream_reset(struct hdac_ext_stream *hext_stream); @@ -131,15 +106,6 @@ int snd_hdac_ext_bus_link_put(struct hdac_bus *bus, struct hdac_ext_link *hlink) void snd_hdac_ext_bus_link_power(struct hdac_device *codec, bool enable); -/* update register macro */ -#define snd_hdac_updatel(addr, reg, mask, val) \ - writel(((readl(addr + reg) & ~(mask)) | (val)), \ - addr + reg) - -#define snd_hdac_updatew(addr, reg, mask, val) \ - writew(((readw(addr + reg) & ~(mask)) | (val)), \ - addr + reg) - #define snd_hdac_adsp_writeb(chip, reg, value) \ snd_hdac_reg_writeb(chip, (chip)->dsp_ba + (reg), value) #define snd_hdac_adsp_readb(chip, reg) \ diff --git a/sound/hda/ext/hdac_ext_stream.c b/sound/hda/ext/hdac_ext_stream.c index b36378bf6da6..2a071a09224d 100644 --- a/sound/hda/ext/hdac_ext_stream.c +++ b/sound/hda/ext/hdac_ext_stream.c @@ -39,20 +39,6 @@ static void snd_hdac_ext_stream_init(struct hdac_bus *bus, AZX_PPLC_INTERVAL * idx; } - if (bus->spbcap) { - hext_stream->spib_addr = bus->spbcap + AZX_SPB_BASE + - AZX_SPB_INTERVAL * idx + - AZX_SPB_SPIB; - - hext_stream->fifo_addr = bus->spbcap + AZX_SPB_BASE + - AZX_SPB_INTERVAL * idx + - AZX_SPB_MAXFIFO; - } - - if (bus->drsmcap) - hext_stream->dpibr_addr = bus->drsmcap + AZX_DRSM_BASE + - AZX_DRSM_INTERVAL * idx; - hext_stream->decoupled = false; snd_hdac_stream_init(bus, &hext_stream->hstream, idx, direction, tag); } @@ -381,128 +367,3 @@ void snd_hdac_ext_stream_release(struct hdac_ext_stream *hext_stream, int type) } EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_release); - -/** - * snd_hdac_ext_stream_spbcap_enable - enable SPIB for a stream - * @bus: HD-audio core bus - * @enable: flag to enable/disable SPIB - * @index: stream index for which SPIB need to be enabled - */ -void snd_hdac_ext_stream_spbcap_enable(struct hdac_bus *bus, - bool enable, int index) -{ - u32 mask = 0; - - if (!bus->spbcap) { - dev_err(bus->dev, "Address of SPB capability is NULL\n"); - return; - } - - mask |= (1 << index); - - if (enable) - snd_hdac_updatel(bus->spbcap, AZX_REG_SPB_SPBFCCTL, mask, mask); - else - snd_hdac_updatel(bus->spbcap, AZX_REG_SPB_SPBFCCTL, mask, 0); -} -EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_spbcap_enable); - -/** - * snd_hdac_ext_stream_set_spib - sets the spib value of a stream - * @bus: HD-audio core bus - * @hext_stream: hdac_ext_stream - * @value: spib value to set - */ -int snd_hdac_ext_stream_set_spib(struct hdac_bus *bus, - struct hdac_ext_stream *hext_stream, u32 value) -{ - - if (!bus->spbcap) { - dev_err(bus->dev, "Address of SPB capability is NULL\n"); - return -EINVAL; - } - - writel(value, hext_stream->spib_addr); - - return 0; -} -EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_set_spib); - -/** - * snd_hdac_ext_stream_get_spbmaxfifo - gets the spib value of a stream - * @bus: HD-audio core bus - * @hext_stream: hdac_ext_stream - * - * Return maxfifo for the stream - */ -int snd_hdac_ext_stream_get_spbmaxfifo(struct hdac_bus *bus, - struct hdac_ext_stream *hext_stream) -{ - - if (!bus->spbcap) { - dev_err(bus->dev, "Address of SPB capability is NULL\n"); - return -EINVAL; - } - - return readl(hext_stream->fifo_addr); -} -EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_get_spbmaxfifo); - -/** - * snd_hdac_ext_stream_drsm_enable - enable DMA resume for a stream - * @bus: HD-audio core bus - * @enable: flag to enable/disable DRSM - * @index: stream index for which DRSM need to be enabled - */ -void snd_hdac_ext_stream_drsm_enable(struct hdac_bus *bus, - bool enable, int index) -{ - u32 mask = 0; - - if (!bus->drsmcap) { - dev_err(bus->dev, "Address of DRSM capability is NULL\n"); - return; - } - - mask |= (1 << index); - - if (enable) - snd_hdac_updatel(bus->drsmcap, AZX_REG_DRSM_CTL, mask, mask); - else - snd_hdac_updatel(bus->drsmcap, AZX_REG_DRSM_CTL, mask, 0); -} -EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_drsm_enable); - -/** - * snd_hdac_ext_stream_set_dpibr - sets the dpibr value of a stream - * @bus: HD-audio core bus - * @hext_stream: hdac_ext_stream - * @value: dpib value to set - */ -int snd_hdac_ext_stream_set_dpibr(struct hdac_bus *bus, - struct hdac_ext_stream *hext_stream, u32 value) -{ - - if (!bus->drsmcap) { - dev_err(bus->dev, "Address of DRSM capability is NULL\n"); - return -EINVAL; - } - - writel(value, hext_stream->dpibr_addr); - - return 0; -} -EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_set_dpibr); - -/** - * snd_hdac_ext_stream_set_lpib - sets the lpib value of a stream - * @hext_stream: hdac_ext_stream - * @value: lpib value to set - */ -int snd_hdac_ext_stream_set_lpib(struct hdac_ext_stream *hext_stream, u32 value) -{ - snd_hdac_stream_writel(&hext_stream->hstream, SD_LPIB, value); - - return 0; -} -EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_set_lpib); diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c index 1b8be39c38a9..35fe2bd582ac 100644 --- a/sound/hda/hdac_stream.c +++ b/sound/hda/hdac_stream.c @@ -103,6 +103,20 @@ void snd_hdac_stream_init(struct hdac_bus *bus, struct hdac_stream *azx_dev, azx_dev->stream_tag = tag; snd_hdac_dsp_lock_init(azx_dev); list_add_tail(&azx_dev->list, &bus->stream_list); + + if (bus->spbcap) { + azx_dev->spib_addr = bus->spbcap + AZX_SPB_BASE + + AZX_SPB_INTERVAL * idx + + AZX_SPB_SPIB; + + azx_dev->fifo_addr = bus->spbcap + AZX_SPB_BASE + + AZX_SPB_INTERVAL * idx + + AZX_SPB_MAXFIFO; + } + + if (bus->drsmcap) + azx_dev->dpibr_addr = bus->drsmcap + AZX_DRSM_BASE + + AZX_DRSM_INTERVAL * idx; } EXPORT_SYMBOL_GPL(snd_hdac_stream_init); @@ -718,6 +732,128 @@ void snd_hdac_stream_sync(struct hdac_stream *azx_dev, bool start, } EXPORT_SYMBOL_GPL(snd_hdac_stream_sync); +/** + * snd_hdac_stream_spbcap_enable - enable SPIB for a stream + * @bus: HD-audio core bus + * @enable: flag to enable/disable SPIB + * @index: stream index for which SPIB need to be enabled + */ +void snd_hdac_stream_spbcap_enable(struct hdac_bus *bus, + bool enable, int index) +{ + u32 mask = 0; + + if (!bus->spbcap) { + dev_err(bus->dev, "Address of SPB capability is NULL\n"); + return; + } + + mask |= (1 << index); + + if (enable) + snd_hdac_updatel(bus->spbcap, AZX_REG_SPB_SPBFCCTL, mask, mask); + else + snd_hdac_updatel(bus->spbcap, AZX_REG_SPB_SPBFCCTL, mask, 0); +} +EXPORT_SYMBOL_GPL(snd_hdac_stream_spbcap_enable); + +/** + * snd_hdac_stream_set_spib - sets the spib value of a stream + * @bus: HD-audio core bus + * @azx_dev: hdac_stream + * @value: spib value to set + */ +int snd_hdac_stream_set_spib(struct hdac_bus *bus, + struct hdac_stream *azx_dev, u32 value) +{ + if (!bus->spbcap) { + dev_err(bus->dev, "Address of SPB capability is NULL\n"); + return -EINVAL; + } + + writel(value, azx_dev->spib_addr); + + return 0; +} +EXPORT_SYMBOL_GPL(snd_hdac_stream_set_spib); + +/** + * snd_hdac_stream_get_spbmaxfifo - gets the spib value of a stream + * @bus: HD-audio core bus + * @azx_dev: hdac_stream + * + * Return maxfifo for the stream + */ +int snd_hdac_stream_get_spbmaxfifo(struct hdac_bus *bus, + struct hdac_stream *azx_dev) +{ + if (!bus->spbcap) { + dev_err(bus->dev, "Address of SPB capability is NULL\n"); + return -EINVAL; + } + + return readl(azx_dev->fifo_addr); +} +EXPORT_SYMBOL_GPL(snd_hdac_stream_get_spbmaxfifo); + +/** + * snd_hdac_stream_drsm_enable - enable DMA resume for a stream + * @bus: HD-audio core bus + * @enable: flag to enable/disable DRSM + * @index: stream index for which DRSM need to be enabled + */ +void snd_hdac_stream_drsm_enable(struct hdac_bus *bus, + bool enable, int index) +{ + u32 mask = 0; + + if (!bus->drsmcap) { + dev_err(bus->dev, "Address of DRSM capability is NULL\n"); + return; + } + + mask |= (1 << index); + + if (enable) + snd_hdac_updatel(bus->drsmcap, AZX_REG_DRSM_CTL, mask, mask); + else + snd_hdac_updatel(bus->drsmcap, AZX_REG_DRSM_CTL, mask, 0); +} +EXPORT_SYMBOL_GPL(snd_hdac_stream_drsm_enable); + +/** + * snd_hdac_stream_set_dpibr - sets the dpibr value of a stream + * @bus: HD-audio core bus + * @azx_dev: hdac_stream + * @value: dpib value to set + */ +int snd_hdac_stream_set_dpibr(struct hdac_bus *bus, + struct hdac_stream *azx_dev, u32 value) +{ + if (!bus->drsmcap) { + dev_err(bus->dev, "Address of DRSM capability is NULL\n"); + return -EINVAL; + } + + writel(value, azx_dev->dpibr_addr); + + return 0; +} +EXPORT_SYMBOL_GPL(snd_hdac_stream_set_dpibr); + +/** + * snd_hdac_stream_set_lpib - sets the lpib value of a stream + * @azx_dev: hdac_stream + * @value: lpib value to set + */ +int snd_hdac_stream_set_lpib(struct hdac_stream *azx_dev, u32 value) +{ + snd_hdac_stream_writel(azx_dev, SD_LPIB, value); + + return 0; +} +EXPORT_SYMBOL_GPL(snd_hdac_stream_set_lpib); + #ifdef CONFIG_SND_HDA_DSP_LOADER /** * snd_hdac_dsp_prepare - prepare for DSP loading diff --git a/sound/soc/intel/avs/loader.c b/sound/soc/intel/avs/loader.c index 9e3f8ff33a87..34923558dfa5 100644 --- a/sound/soc/intel/avs/loader.c +++ b/sound/soc/intel/avs/loader.c @@ -369,8 +369,8 @@ int avs_hda_load_basefw(struct avs_dev *adev, struct firmware *fw) goto release_stream; /* enable SPIB for hda stream */ - snd_hdac_ext_stream_spbcap_enable(bus, true, hstream->index); - ret = snd_hdac_ext_stream_set_spib(bus, estream, fw->size); + snd_hdac_stream_spbcap_enable(bus, true, hstream->index); + ret = snd_hdac_stream_set_spib(bus, hstream, fw->size); if (ret) goto cleanup_resources; @@ -400,8 +400,8 @@ int avs_hda_load_basefw(struct avs_dev *adev, struct firmware *fw) cleanup_resources: /* disable SPIB for hda stream */ - snd_hdac_ext_stream_spbcap_enable(bus, false, hstream->index); - snd_hdac_ext_stream_set_spib(bus, estream, 0); + snd_hdac_stream_spbcap_enable(bus, false, hstream->index); + snd_hdac_stream_set_spib(bus, hstream, 0); snd_hdac_dsp_cleanup(hstream, &dmab); release_stream: @@ -436,8 +436,8 @@ int avs_hda_load_library(struct avs_dev *adev, struct firmware *lib, u32 id) goto release_stream; /* enable SPIB for hda stream */ - snd_hdac_ext_stream_spbcap_enable(bus, true, stream->index); - snd_hdac_ext_stream_set_spib(bus, estream, lib->size); + snd_hdac_stream_spbcap_enable(bus, true, stream->index); + snd_hdac_stream_set_spib(bus, stream, lib->size); memcpy(dmab.area, lib->data, lib->size); @@ -451,8 +451,8 @@ int avs_hda_load_library(struct avs_dev *adev, struct firmware *lib, u32 id) } /* disable SPIB for hda stream */ - snd_hdac_ext_stream_spbcap_enable(bus, false, stream->index); - snd_hdac_ext_stream_set_spib(bus, estream, 0); + snd_hdac_stream_spbcap_enable(bus, false, stream->index); + snd_hdac_stream_set_spib(bus, stream, 0); snd_hdac_dsp_cleanup(stream, &dmab); release_stream: diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c index eaad180af42e..5ab0917a2b3d 100644 --- a/sound/soc/intel/skylake/skl-messages.c +++ b/sound/soc/intel/skylake/skl-messages.c @@ -53,17 +53,15 @@ static int skl_dsp_setup_spib(struct device *dev, unsigned int size, struct hdac_bus *bus = dev_get_drvdata(dev); struct hdac_stream *stream = snd_hdac_get_stream(bus, SNDRV_PCM_STREAM_PLAYBACK, stream_tag); - struct hdac_ext_stream *estream; if (!stream) return -EINVAL; - estream = stream_to_hdac_ext_stream(stream); /* enable/disable SPIB for this hdac stream */ - snd_hdac_ext_stream_spbcap_enable(bus, enable, stream->index); + snd_hdac_stream_spbcap_enable(bus, enable, stream->index); /* set the spib value */ - snd_hdac_ext_stream_set_spib(bus, estream, size); + snd_hdac_stream_set_spib(bus, stream, size); return 0; } diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index 27b03c34abd0..dc627d18518d 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c @@ -467,6 +467,7 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd, struct skl_module_cfg *mconfig; struct hdac_bus *bus = get_bus_ctx(substream); struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); + struct hdac_stream *hstream = hdac_stream(stream); struct snd_soc_dapm_widget *w; int ret; @@ -484,11 +485,9 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd, * dpib & lpib position to resume before starting the * DMA */ - snd_hdac_ext_stream_drsm_enable(bus, true, - hdac_stream(stream)->index); - snd_hdac_ext_stream_set_dpibr(bus, stream, - stream->lpib); - snd_hdac_ext_stream_set_lpib(stream, stream->lpib); + snd_hdac_stream_drsm_enable(bus, true, hstream->index); + snd_hdac_stream_set_dpibr(bus, hstream, hstream->lpib); + snd_hdac_stream_set_lpib(hstream, hstream->lpib); } fallthrough; @@ -520,13 +519,13 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd, ret = skl_decoupled_trigger(substream, cmd); if ((cmd == SNDRV_PCM_TRIGGER_SUSPEND) && !w->ignore_suspend) { /* save the dpib and lpib positions */ - stream->dpib = readl(bus->remap_addr + + hstream->dpib = readl(bus->remap_addr + AZX_REG_VS_SDXDPIB_XBASE + (AZX_REG_VS_SDXDPIB_XINTERVAL * - hdac_stream(stream)->index)); + hstream->index)); + + hstream->lpib = snd_hdac_stream_get_pos_lpib(hstream); - stream->lpib = snd_hdac_stream_get_pos_lpib( - hdac_stream(stream)); snd_hdac_ext_stream_decouple(bus, stream, false); } break; diff --git a/sound/soc/sof/intel/hda-pcm.c b/sound/soc/sof/intel/hda-pcm.c index 0a9c80216a8c..dc0b359ed9b6 100644 --- a/sound/soc/sof/intel/hda-pcm.c +++ b/sound/soc/sof/intel/hda-pcm.c @@ -142,7 +142,6 @@ int hda_dsp_pcm_hw_params(struct snd_sof_dev *sdev, int hda_dsp_pcm_ack(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream) { struct hdac_stream *hstream = substream->runtime->private_data; - struct hdac_ext_stream *hext_stream = stream_to_hdac_ext_stream(hstream); struct snd_pcm_runtime *runtime = substream->runtime; ssize_t appl_pos, buf_size; u32 spib; @@ -156,7 +155,7 @@ int hda_dsp_pcm_ack(struct snd_sof_dev *sdev, struct snd_pcm_substream *substrea if (!spib) spib = buf_size; - sof_io_write(sdev, hext_stream->spib_addr, spib); + sof_io_write(sdev, hstream->spib_addr, spib); return 0; } diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c index be60e7785da9..8cb91788912c 100644 --- a/sound/soc/sof/intel/hda-stream.c +++ b/sound/soc/sof/intel/hda-stream.c @@ -173,7 +173,7 @@ int hda_dsp_stream_spib_config(struct snd_sof_dev *sdev, enable << hstream->index); /* set the SPIB value */ - sof_io_write(sdev, hext_stream->spib_addr, size); + sof_io_write(sdev, hstream->spib_addr, size); return 0; } @@ -883,18 +883,19 @@ int hda_dsp_stream_init(struct snd_sof_dev *sdev) SOF_HDA_PPLC_BASE + SOF_HDA_PPLC_MULTI * num_total + SOF_HDA_PPLC_INTERVAL * i; + hstream = &hext_stream->hstream; + /* do we support SPIB */ if (sdev->bar[HDA_DSP_SPIB_BAR]) { - hext_stream->spib_addr = sdev->bar[HDA_DSP_SPIB_BAR] + + hstream->spib_addr = sdev->bar[HDA_DSP_SPIB_BAR] + SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i + SOF_HDA_SPIB_SPIB; - hext_stream->fifo_addr = sdev->bar[HDA_DSP_SPIB_BAR] + + hstream->fifo_addr = sdev->bar[HDA_DSP_SPIB_BAR] + SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i + SOF_HDA_SPIB_MAXFIFO; } - hstream = &hext_stream->hstream; hstream->bus = bus; hstream->sd_int_sta_mask = 1 << i; hstream->index = i; @@ -939,18 +940,19 @@ int hda_dsp_stream_init(struct snd_sof_dev *sdev) SOF_HDA_PPLC_BASE + SOF_HDA_PPLC_MULTI * num_total + SOF_HDA_PPLC_INTERVAL * i; + hstream = &hext_stream->hstream; + /* do we support SPIB */ if (sdev->bar[HDA_DSP_SPIB_BAR]) { - hext_stream->spib_addr = sdev->bar[HDA_DSP_SPIB_BAR] + + hstream->spib_addr = sdev->bar[HDA_DSP_SPIB_BAR] + SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i + SOF_HDA_SPIB_SPIB; - hext_stream->fifo_addr = sdev->bar[HDA_DSP_SPIB_BAR] + + hstream->fifo_addr = sdev->bar[HDA_DSP_SPIB_BAR] + SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i + SOF_HDA_SPIB_MAXFIFO; } - hstream = &hext_stream->hstream; hstream->bus = bus; hstream->sd_int_sta_mask = 1 << i; hstream->index = i; -- cgit v1.2.3-70-g09d2 From 4088355afac9d36bc0c27c34d34b74091e5a7c7e Mon Sep 17 00:00:00 2001 From: Amadeusz Sławiński Date: Mon, 24 Oct 2022 21:08:40 +0200 Subject: ASoC: Intel: boards: Fix typo in comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It keeps propagating through machine boards, fix it once and for all. Reviewed-by: Cezary Rojewski Signed-off-by: Amadeusz Sławiński Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20221024190841.31572-2-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bdw-rt5650.c | 2 +- sound/soc/intel/boards/bdw-rt5677.c | 2 +- sound/soc/intel/boards/bxt_rt298.c | 2 +- sound/soc/intel/boards/bytcht_cx2072x.c | 2 +- sound/soc/intel/boards/bytcht_es8316.c | 2 +- sound/soc/intel/boards/bytcr_rt5640.c | 2 +- sound/soc/intel/boards/bytcr_rt5651.c | 2 +- sound/soc/intel/boards/bytcr_wm5102.c | 2 +- sound/soc/intel/boards/cht_bsw_max98090_ti.c | 2 +- sound/soc/intel/boards/cht_bsw_nau8824.c | 2 +- sound/soc/intel/boards/cht_bsw_rt5645.c | 2 +- sound/soc/intel/boards/cht_bsw_rt5672.c | 2 +- sound/soc/intel/boards/skl_nau88l25_max98357a.c | 2 +- sound/soc/intel/boards/skl_nau88l25_ssm4567.c | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/boards/bdw-rt5650.c b/sound/soc/intel/boards/bdw-rt5650.c index 67c3f49b924c..d0682bc543c9 100644 --- a/sound/soc/intel/boards/bdw-rt5650.c +++ b/sound/soc/intel/boards/bdw-rt5650.c @@ -88,7 +88,7 @@ static int broadwell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_interval *chan = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); - /* The ADSP will covert the FE rate to 48k, max 4-channels */ + /* The ADSP will convert the FE rate to 48k, max 4-channels */ rate->min = rate->max = 48000; chan->min = 2; chan->max = 4; diff --git a/sound/soc/intel/boards/bdw-rt5677.c b/sound/soc/intel/boards/bdw-rt5677.c index 31488702768e..f3e08d258ac1 100644 --- a/sound/soc/intel/boards/bdw-rt5677.c +++ b/sound/soc/intel/boards/bdw-rt5677.c @@ -141,7 +141,7 @@ static int broadwell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_interval *chan = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); - /* The ADSP will covert the FE rate to 48k, stereo */ + /* The ADSP will convert the FE rate to 48k, stereo */ rate->min = rate->max = 48000; chan->min = chan->max = 2; diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c index 4bd93c3ba377..bf89fe80423d 100644 --- a/sound/soc/intel/boards/bxt_rt298.c +++ b/sound/soc/intel/boards/bxt_rt298.c @@ -210,7 +210,7 @@ static int broxton_ssp5_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_CHANNELS); struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - /* The ADSP will covert the FE rate to 48k, stereo */ + /* The ADSP will convert the FE rate to 48k, stereo */ rate->min = rate->max = 48000; chan->min = chan->max = 2; diff --git a/sound/soc/intel/boards/bytcht_cx2072x.c b/sound/soc/intel/boards/bytcht_cx2072x.c index ae899866863e..41cec67157b6 100644 --- a/sound/soc/intel/boards/bytcht_cx2072x.c +++ b/sound/soc/intel/boards/bytcht_cx2072x.c @@ -111,7 +111,7 @@ static int byt_cht_cx2072x_fixup(struct snd_soc_pcm_runtime *rtd, hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); int ret; - /* The DSP will covert the FE rate to 48k, stereo, 24bits */ + /* The DSP will convert the FE rate to 48k, stereo, 24bits */ rate->min = rate->max = 48000; channels->min = channels->max = 2; diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c index 6432b83f616f..cdcb448d5212 100644 --- a/sound/soc/intel/boards/bytcht_es8316.c +++ b/sound/soc/intel/boards/bytcht_es8316.c @@ -243,7 +243,7 @@ static int byt_cht_es8316_codec_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_CHANNELS); int ret, bits; - /* The DSP will covert the FE rate to 48k, stereo */ + /* The DSP will convert the FE rate to 48k, stereo */ rate->min = rate->max = 48000; channels->min = channels->max = 2; diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index fb9d9e271845..6db07b2417ca 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -1390,7 +1390,7 @@ static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_CHANNELS); int ret, bits; - /* The DSP will covert the FE rate to 48k, stereo */ + /* The DSP will convert the FE rate to 48k, stereo */ rate->min = rate->max = 48000; channels->min = channels->max = 2; diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index 2beb686768f2..81ac6eeda2e6 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -683,7 +683,7 @@ static int byt_rt5651_codec_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_CHANNELS); int ret, bits; - /* The DSP will covert the FE rate to 48k, stereo */ + /* The DSP will convert the FE rate to 48k, stereo */ rate->min = rate->max = 48000; channels->min = channels->max = 2; diff --git a/sound/soc/intel/boards/bytcr_wm5102.c b/sound/soc/intel/boards/bytcr_wm5102.c index 45a6805787f5..1669eb3bd80f 100644 --- a/sound/soc/intel/boards/bytcr_wm5102.c +++ b/sound/soc/intel/boards/bytcr_wm5102.c @@ -248,7 +248,7 @@ static int byt_wm5102_codec_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_CHANNELS); int ret; - /* The DSP will covert the FE rate to 48k, stereo */ + /* The DSP will convert the FE rate to 48k, stereo */ rate->min = 48000; rate->max = 48000; channels->min = 2; diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c index 64eb73525ee3..2c086e901aae 100644 --- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c +++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c @@ -272,7 +272,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } - /* The DSP will covert the FE rate to 48k, stereo, 24bits */ + /* The DSP will convert the FE rate to 48k, stereo, 24bits */ rate->min = rate->max = 48000; channels->min = channels->max = 2; diff --git a/sound/soc/intel/boards/cht_bsw_nau8824.c b/sound/soc/intel/boards/cht_bsw_nau8824.c index 4c1d83b317c7..af2d9a78465d 100644 --- a/sound/soc/intel/boards/cht_bsw_nau8824.c +++ b/sound/soc/intel/boards/cht_bsw_nau8824.c @@ -136,7 +136,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); int ret; - /* The DSP will covert the FE rate to 48k, stereo, 24bits */ + /* The DSP will convert the FE rate to 48k, stereo, 24bits */ rate->min = rate->max = 48000; channels->min = channels->max = 2; diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c index 96501aed8bee..25a054bd4073 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5645.c +++ b/sound/soc/intel/boards/cht_bsw_rt5645.c @@ -344,7 +344,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); - /* The DSP will covert the FE rate to 48k, stereo, 24bits */ + /* The DSP will convert the FE rate to 48k, stereo, 24bits */ rate->min = rate->max = 48000; channels->min = channels->max = 2; diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c index ca47f6476b07..49d3da8f7316 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5672.c +++ b/sound/soc/intel/boards/cht_bsw_rt5672.c @@ -270,7 +270,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_CHANNELS); int ret, bits; - /* The DSP will covert the FE rate to 48k, stereo, 24bits */ + /* The DSP will convert the FE rate to 48k, stereo, 24bits */ rate->min = rate->max = 48000; channels->min = channels->max = 2; diff --git a/sound/soc/intel/boards/skl_nau88l25_max98357a.c b/sound/soc/intel/boards/skl_nau88l25_max98357a.c index 8dceb0b02581..e13a5a4d8f7e 100644 --- a/sound/soc/intel/boards/skl_nau88l25_max98357a.c +++ b/sound/soc/intel/boards/skl_nau88l25_max98357a.c @@ -154,7 +154,7 @@ static int skylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_CHANNELS); struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - /* The ADSP will covert the FE rate to 48k, stereo */ + /* The ADSP will convert the FE rate to 48k, stereo */ rate->min = rate->max = 48000; chan->min = chan->max = 2; diff --git a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c index 62c0d46d0086..575604dc8936 100644 --- a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c +++ b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c @@ -333,7 +333,7 @@ static int skylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_CHANNELS); struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - /* The ADSP will covert the FE rate to 48k, stereo */ + /* The ADSP will convert the FE rate to 48k, stereo */ rate->min = rate->max = 48000; chan->min = chan->max = 2; -- cgit v1.2.3-70-g09d2 From 0d527a99229b65c781acd747c111e41626e9f041 Mon Sep 17 00:00:00 2001 From: Amadeusz Sławiński Date: Mon, 24 Oct 2022 21:08:41 +0200 Subject: ASoC: Intel: avs: boards: Fix typo in comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It keeps propagating through machine boards, fix it once and for all. Reviewed-by: Cezary Rojewski Signed-off-by: Amadeusz Sławiński Link: https://lore.kernel.org/r/20221024190841.31572-3-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/max98373.c | 2 +- sound/soc/intel/avs/boards/max98927.c | 2 +- sound/soc/intel/avs/boards/ssm4567.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/boards/max98373.c b/sound/soc/intel/avs/boards/max98373.c index 0fa8f5606385..8e221ecd34b0 100644 --- a/sound/soc/intel/avs/boards/max98373.c +++ b/sound/soc/intel/avs/boards/max98373.c @@ -53,7 +53,7 @@ avs_max98373_be_fixup(struct snd_soc_pcm_runtime *runrime, struct snd_pcm_hw_par channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - /* The ADSP will covert the FE rate to 48k, stereo */ + /* The ADSP will convert the FE rate to 48k, stereo */ rate->min = rate->max = 48000; channels->min = channels->max = 2; diff --git a/sound/soc/intel/avs/boards/max98927.c b/sound/soc/intel/avs/boards/max98927.c index 35c4f8f55035..7cccce99f92e 100644 --- a/sound/soc/intel/avs/boards/max98927.c +++ b/sound/soc/intel/avs/boards/max98927.c @@ -53,7 +53,7 @@ avs_max98927_be_fixup(struct snd_soc_pcm_runtime *runrime, struct snd_pcm_hw_par channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - /* The ADSP will covert the FE rate to 48k, stereo */ + /* The ADSP will convert the FE rate to 48k, stereo */ rate->min = rate->max = 48000; channels->min = channels->max = 2; diff --git a/sound/soc/intel/avs/boards/ssm4567.c b/sound/soc/intel/avs/boards/ssm4567.c index 9f84c8ab3447..c5db69612762 100644 --- a/sound/soc/intel/avs/boards/ssm4567.c +++ b/sound/soc/intel/avs/boards/ssm4567.c @@ -103,7 +103,7 @@ avs_ssm4567_be_fixup(struct snd_soc_pcm_runtime *runrime, struct snd_pcm_hw_para channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - /* The ADSP will covert the FE rate to 48k, stereo */ + /* The ADSP will convert the FE rate to 48k, stereo */ rate->min = rate->max = 48000; channels->min = channels->max = 2; -- cgit v1.2.3-70-g09d2 From 0abfc84ba22aca05a5268128f719386648351020 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Thu, 27 Oct 2022 14:46:54 +0200 Subject: ASoC: Intel: avs: Split pcm pages freeing operation from hw_free() Prepare for introduction of PCM power management support. As freeing pages during the suspend operation is not desired, separate snd_pcm_lib_free_pages() from existing avs_dai_fe_hw_free() so that majority of the code found within it can be reused for standard and PM flows both. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221027124702.1761002-2-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/pcm.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c index 293336c2fc63..fea801243d37 100644 --- a/sound/soc/intel/avs/pcm.c +++ b/sound/soc/intel/avs/pcm.c @@ -499,7 +499,7 @@ create_err: return ret; } -static int avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) +static int __avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct avs_dma_data *data; struct hdac_ext_stream *host_stream; @@ -523,9 +523,15 @@ static int avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_so snd_hdac_stream_cleanup(hdac_stream(host_stream)); hdac_stream(host_stream)->prepared = false; - ret = snd_pcm_lib_free_pages(substream); - if (ret < 0) - dev_dbg(dai->dev, "Failed to free pages!\n"); + return ret; +} + +static int avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) +{ + int ret; + + ret = __avs_dai_fe_hw_free(substream, dai); + snd_pcm_lib_free_pages(substream); return ret; } -- cgit v1.2.3-70-g09d2 From 2b9a50ea845ebe95473f5b85dfcc9b806c252fac Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Thu, 27 Oct 2022 14:46:55 +0200 Subject: ASoC: Intel: avs: Introduce PCM power management routines Implement suspend/resume() operations for component drivers. For most scenarios, the PM flow is similar to standard streaming one, except for the part where the position register are being saved and the lack of PCM pages freeing. To reduce code duplication, all avs_dai_suspend_XXX() and avs_dai_resume_XXX() functions reuse their non-PM equivalents. Given that path binding/unbinding happens only in FE part of the stream, the order of suspend() goes: 1. hw_free() all FE DAIs, paths are unbound here 2. hw_free() all BE DAIs Consequently, for resume() its: 1. hw_params() all BE DAIs 2. hw_params() all FE DAIs, paths are bound here 3. prepare() all BE DAIs 4. prepare() all FE DAIs As component->suspend/resume() do not provide substream pointer, store it ourselves so that the PM flow has all the necessary information to proceed. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221027124702.1761002-3-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- include/sound/hdaudio_ext.h | 5 ++ sound/soc/intel/avs/pcm.c | 214 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 215 insertions(+), 4 deletions(-) (limited to 'sound/soc/intel') diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h index 90fd47e05370..68ab89211de2 100644 --- a/include/sound/hdaudio_ext.h +++ b/include/sound/hdaudio_ext.h @@ -51,6 +51,11 @@ struct hdac_ext_stream { void __iomem *pphc_addr; void __iomem *pplc_addr; + u32 pphcllpl; + u32 pphcllpu; + u32 pphcldpl; + u32 pphcldpu; + bool decoupled:1; bool link_locked:1; bool link_prepared; diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c index fea801243d37..df965dbb8d12 100644 --- a/sound/soc/intel/avs/pcm.c +++ b/sound/soc/intel/avs/pcm.c @@ -28,6 +28,8 @@ struct avs_dma_data { * host stream assigned */ struct hdac_ext_stream *host_stream; + + struct snd_pcm_substream *substream; }; static struct avs_tplg_path_template * @@ -55,7 +57,8 @@ avs_dai_find_path_template(struct snd_soc_dai *dai, bool is_fe, int direction) return dw->priv; } -static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai, bool is_fe) +static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai, bool is_fe, + const struct snd_soc_dai_ops *ops) { struct avs_tplg_path_template *template; struct avs_dma_data *data; @@ -71,6 +74,7 @@ static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_d if (!data) return -ENOMEM; + data->substream = substream; data->template = template; snd_soc_dai_set_dma_data(dai, substream, data); @@ -151,9 +155,11 @@ static int avs_dai_prepare(struct avs_dev *adev, struct snd_pcm_substream *subst return ret; } +static const struct snd_soc_dai_ops avs_dai_nonhda_be_ops; + static int avs_dai_nonhda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - return avs_dai_startup(substream, dai, false); + return avs_dai_startup(substream, dai, false, &avs_dai_nonhda_be_ops); } static void avs_dai_nonhda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) @@ -245,9 +251,11 @@ static const struct snd_soc_dai_ops avs_dai_nonhda_be_ops = { .trigger = avs_dai_nonhda_be_trigger, }; +static const struct snd_soc_dai_ops avs_dai_hda_be_ops; + static int avs_dai_hda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - return avs_dai_startup(substream, dai, false); + return avs_dai_startup(substream, dai, false, &avs_dai_hda_be_ops); } static void avs_dai_hda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) @@ -407,6 +415,8 @@ static const struct snd_pcm_hw_constraint_list hw_rates = { .mask = 0, }; +const struct snd_soc_dai_ops avs_dai_fe_ops; + static int avs_dai_fe_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_pcm_runtime *runtime = substream->runtime; @@ -416,7 +426,7 @@ static int avs_dai_fe_startup(struct snd_pcm_substream *substream, struct snd_so struct hdac_ext_stream *host_stream; int ret; - ret = avs_dai_startup(substream, dai, true); + ret = avs_dai_startup(substream, dai, true, &avs_dai_fe_ops); if (ret) return ret; @@ -758,6 +768,198 @@ static void avs_component_remove(struct snd_soc_component *component) } } +static int avs_dai_resume_hw_params(struct snd_soc_dai *dai, struct avs_dma_data *data) +{ + struct snd_pcm_substream *substream; + struct snd_soc_pcm_runtime *rtd; + int ret; + + substream = data->substream; + rtd = snd_pcm_substream_chip(substream); + + ret = dai->driver->ops->hw_params(substream, &rtd->dpcm[substream->stream].hw_params, dai); + if (ret) + dev_err(dai->dev, "hw_params on resume failed: %d\n", ret); + + return ret; +} + +static int avs_dai_resume_fe_prepare(struct snd_soc_dai *dai, struct avs_dma_data *data) +{ + struct hdac_ext_stream *host_stream; + struct hdac_stream *hstream; + struct hdac_bus *bus; + int ret; + + host_stream = data->host_stream; + hstream = hdac_stream(host_stream); + bus = hdac_stream(host_stream)->bus; + + /* Set DRSM before programming stream and position registers. */ + snd_hdac_stream_drsm_enable(bus, true, hstream->index); + + ret = dai->driver->ops->prepare(data->substream, dai); + if (ret) { + dev_err(dai->dev, "prepare FE on resume failed: %d\n", ret); + return ret; + } + + writel(host_stream->pphcllpl, host_stream->pphc_addr + AZX_REG_PPHCLLPL); + writel(host_stream->pphcllpu, host_stream->pphc_addr + AZX_REG_PPHCLLPU); + writel(host_stream->pphcldpl, host_stream->pphc_addr + AZX_REG_PPHCLDPL); + writel(host_stream->pphcldpu, host_stream->pphc_addr + AZX_REG_PPHCLDPU); + + /* As per HW spec recommendation, program LPIB and DPIB to the same value. */ + snd_hdac_stream_set_lpib(hstream, hstream->lpib); + snd_hdac_stream_set_dpibr(bus, hstream, hstream->lpib); + + return 0; +} + +static int avs_dai_resume_be_prepare(struct snd_soc_dai *dai, struct avs_dma_data *data) +{ + int ret; + + ret = dai->driver->ops->prepare(data->substream, dai); + if (ret) + dev_err(dai->dev, "prepare BE on resume failed: %d\n", ret); + + return ret; +} + +static int avs_dai_suspend_fe_hw_free(struct snd_soc_dai *dai, struct avs_dma_data *data) +{ + struct hdac_ext_stream *host_stream; + int ret; + + host_stream = data->host_stream; + + /* Store position addresses so we can resume from them later on. */ + hdac_stream(host_stream)->lpib = snd_hdac_stream_get_pos_lpib(hdac_stream(host_stream)); + host_stream->pphcllpl = readl(host_stream->pphc_addr + AZX_REG_PPHCLLPL); + host_stream->pphcllpu = readl(host_stream->pphc_addr + AZX_REG_PPHCLLPU); + host_stream->pphcldpl = readl(host_stream->pphc_addr + AZX_REG_PPHCLDPL); + host_stream->pphcldpu = readl(host_stream->pphc_addr + AZX_REG_PPHCLDPU); + + ret = __avs_dai_fe_hw_free(data->substream, dai); + if (ret < 0) + dev_err(dai->dev, "hw_free FE on suspend failed: %d\n", ret); + + return ret; +} + +static int avs_dai_suspend_be_hw_free(struct snd_soc_dai *dai, struct avs_dma_data *data) +{ + int ret; + + ret = dai->driver->ops->hw_free(data->substream, dai); + if (ret < 0) + dev_err(dai->dev, "hw_free BE on suspend failed: %d\n", ret); + + return ret; +} + +static int avs_component_pm_op(struct snd_soc_component *component, bool be, + int (*op)(struct snd_soc_dai *, struct avs_dma_data *)) +{ + struct snd_soc_pcm_runtime *rtd; + struct avs_dma_data *data; + struct snd_soc_dai *dai; + int ret; + + for_each_component_dais(component, dai) { + data = dai->playback_dma_data; + if (data) { + rtd = snd_pcm_substream_chip(data->substream); + if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) { + ret = op(dai, data); + if (ret < 0) + return ret; + } + } + + data = dai->capture_dma_data; + if (data) { + rtd = snd_pcm_substream_chip(data->substream); + if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) { + ret = op(dai, data); + if (ret < 0) + return ret; + } + } + } + + return 0; +} + +static int avs_component_resume_hw_params(struct snd_soc_component *component, bool be) +{ + return avs_component_pm_op(component, be, &avs_dai_resume_hw_params); +} + +static int avs_component_resume_prepare(struct snd_soc_component *component, bool be) +{ + int (*prepare_cb)(struct snd_soc_dai *dai, struct avs_dma_data *data); + + if (be) + prepare_cb = &avs_dai_resume_be_prepare; + else + prepare_cb = &avs_dai_resume_fe_prepare; + + return avs_component_pm_op(component, be, prepare_cb); +} + +static int avs_component_suspend_hw_free(struct snd_soc_component *component, bool be) +{ + int (*hw_free_cb)(struct snd_soc_dai *dai, struct avs_dma_data *data); + + if (be) + hw_free_cb = &avs_dai_suspend_be_hw_free; + else + hw_free_cb = &avs_dai_suspend_fe_hw_free; + + return avs_component_pm_op(component, be, hw_free_cb); +} + +static int avs_component_suspend(struct snd_soc_component *component) +{ + int ret; + + /* + * When freeing paths, FEs need to be first as they perform + * path unbinding. + */ + ret = avs_component_suspend_hw_free(component, false); + if (ret) + return ret; + + return avs_component_suspend_hw_free(component, true); +} + +static int avs_component_resume(struct snd_soc_component *component) +{ + int ret; + + /* + * When creating paths, FEs need to be last as they perform + * path binding. + */ + ret = avs_component_resume_hw_params(component, true); + if (ret) + return ret; + + ret = avs_component_resume_hw_params(component, false); + if (ret) + return ret; + + /* It is expected that the LINK stream is prepared first. */ + ret = avs_component_resume_prepare(component, true); + if (ret) + return ret; + + return avs_component_resume_prepare(component, false); +} + static int avs_component_open(struct snd_soc_component *component, struct snd_pcm_substream *substream) { @@ -846,6 +1048,8 @@ static const struct snd_soc_component_driver avs_component_driver = { .name = "avs-pcm", .probe = avs_component_probe, .remove = avs_component_remove, + .suspend = avs_component_suspend, + .resume = avs_component_resume, .open = avs_component_open, .pointer = avs_component_pointer, .mmap = avs_component_mmap, @@ -1161,6 +1365,8 @@ static const struct snd_soc_component_driver avs_hda_component_driver = { .name = "avs-hda-pcm", .probe = avs_component_hda_probe, .remove = avs_component_hda_remove, + .suspend = avs_component_suspend, + .resume = avs_component_resume, .open = avs_component_hda_open, .close = avs_component_hda_close, .pointer = avs_component_pointer, -- cgit v1.2.3-70-g09d2 From 8e097f9a5529f0e6af30e1fac0d4e2a97c241392 Mon Sep 17 00:00:00 2001 From: Amadeusz Sławiński Date: Thu, 27 Oct 2022 14:46:57 +0200 Subject: ASoC: Intel: avs: Handle SUSPEND and RESUME triggers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With power management operations added, service SUSPEND and RESUME trigger commands for running streams. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221027124702.1761002-5-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/pcm.c | 75 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 60 insertions(+), 15 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c index df965dbb8d12..db29496e16ab 100644 --- a/sound/soc/intel/avs/pcm.c +++ b/sound/soc/intel/avs/pcm.c @@ -208,30 +208,43 @@ static int avs_dai_nonhda_be_prepare(struct snd_pcm_substream *substream, struct static int avs_dai_nonhda_be_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { + struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); struct avs_dma_data *data; int ret = 0; data = snd_soc_dai_get_dma_data(dai, substream); switch (cmd) { + case SNDRV_PCM_TRIGGER_RESUME: + if (rtd->dai_link->ignore_suspend) + break; + fallthrough; case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + ret = avs_path_pause(data->path); + if (ret < 0) { + dev_err(dai->dev, "pause BE path failed: %d\n", ret); + break; + } + ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO); if (ret < 0) dev_err(dai->dev, "run BE path failed: %d\n", ret); break; + case SNDRV_PCM_TRIGGER_SUSPEND: + if (rtd->dai_link->ignore_suspend) + break; + fallthrough; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_STOP: ret = avs_path_pause(data->path); if (ret < 0) dev_err(dai->dev, "pause BE path failed: %d\n", ret); - if (cmd == SNDRV_PCM_TRIGGER_STOP) { - ret = avs_path_reset(data->path); - if (ret < 0) - dev_err(dai->dev, "reset BE path failed: %d\n", ret); - } + ret = avs_path_reset(data->path); + if (ret < 0) + dev_err(dai->dev, "reset BE path failed: %d\n", ret); break; default: @@ -351,6 +364,7 @@ static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct sn static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { + struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); struct hdac_ext_stream *link_stream; struct avs_dma_data *data; int ret = 0; @@ -361,15 +375,29 @@ static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd, link_stream = substream->runtime->private_data; switch (cmd) { + case SNDRV_PCM_TRIGGER_RESUME: + if (rtd->dai_link->ignore_suspend) + break; + fallthrough; case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: snd_hdac_ext_stream_start(link_stream); + ret = avs_path_pause(data->path); + if (ret < 0) { + dev_err(dai->dev, "pause BE path failed: %d\n", ret); + break; + } + ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO); if (ret < 0) dev_err(dai->dev, "run BE path failed: %d\n", ret); break; + case SNDRV_PCM_TRIGGER_SUSPEND: + if (rtd->dai_link->ignore_suspend) + break; + fallthrough; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_STOP: ret = avs_path_pause(data->path); @@ -378,11 +406,9 @@ static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd, snd_hdac_ext_stream_clear(link_stream); - if (cmd == SNDRV_PCM_TRIGGER_STOP) { - ret = avs_path_reset(data->path); - if (ret < 0) - dev_err(dai->dev, "reset BE path failed: %d\n", ret); - } + ret = avs_path_reset(data->path); + if (ret < 0) + dev_err(dai->dev, "reset BE path failed: %d\n", ret); break; default: @@ -587,6 +613,7 @@ static int avs_dai_fe_prepare(struct snd_pcm_substream *substream, struct snd_so static int avs_dai_fe_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { + struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); struct avs_dma_data *data; struct hdac_ext_stream *host_stream; struct hdac_bus *bus; @@ -598,17 +625,36 @@ static int avs_dai_fe_trigger(struct snd_pcm_substream *substream, int cmd, stru bus = hdac_stream(host_stream)->bus; switch (cmd) { + case SNDRV_PCM_TRIGGER_RESUME: + if (rtd->dai_link->ignore_suspend) + break; + fallthrough; case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: spin_lock_irqsave(&bus->reg_lock, flags); snd_hdac_stream_start(hdac_stream(host_stream), true); spin_unlock_irqrestore(&bus->reg_lock, flags); + /* Timeout on DRSM poll shall not stop the resume so ignore the result. */ + if (cmd == SNDRV_PCM_TRIGGER_RESUME) + snd_hdac_stream_wait_drsm(hdac_stream(host_stream)); + + ret = avs_path_pause(data->path); + if (ret < 0) { + dev_err(dai->dev, "pause FE path failed: %d\n", ret); + break; + } + ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO); if (ret < 0) dev_err(dai->dev, "run FE path failed: %d\n", ret); + break; + case SNDRV_PCM_TRIGGER_SUSPEND: + if (rtd->dai_link->ignore_suspend) + break; + fallthrough; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_STOP: ret = avs_path_pause(data->path); @@ -619,11 +665,9 @@ static int avs_dai_fe_trigger(struct snd_pcm_substream *substream, int cmd, stru snd_hdac_stream_stop(hdac_stream(host_stream)); spin_unlock_irqrestore(&bus->reg_lock, flags); - if (cmd == SNDRV_PCM_TRIGGER_STOP) { - ret = avs_path_reset(data->path); - if (ret < 0) - dev_err(dai->dev, "reset FE path failed: %d\n", ret); - } + ret = avs_path_reset(data->path); + if (ret < 0) + dev_err(dai->dev, "reset FE path failed: %d\n", ret); break; default: @@ -974,6 +1018,7 @@ static int avs_component_open(struct snd_soc_component *component, SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_NO_PERIOD_WAKEUP; hwparams.formats = SNDRV_PCM_FMTBIT_S16_LE | -- cgit v1.2.3-70-g09d2 From eb0699c4cd6e32d5e2bfc9356ab9e19a6164c94e Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Thu, 27 Oct 2022 14:46:58 +0200 Subject: ASoC: Intel: avs: Restart instead of resuming HDA capture streams Resuming of capture streams for HD-Audio is unsupported so remove the relevant flag from the hardware params when assigning them during avs_component_hda_open(). Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221027124702.1761002-6-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/pcm.c | 50 ++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 22 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c index db29496e16ab..660129508c08 100644 --- a/sound/soc/intel/avs/pcm.c +++ b/sound/soc/intel/avs/pcm.c @@ -1004,34 +1004,34 @@ static int avs_component_resume(struct snd_soc_component *component) return avs_component_resume_prepare(component, false); } +static const struct snd_pcm_hardware avs_pcm_hardware = { + .info = SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_RESUME | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .buffer_bytes_max = AZX_MAX_BUF_SIZE, + .period_bytes_min = 128, + .period_bytes_max = AZX_MAX_BUF_SIZE / 2, + .periods_min = 2, + .periods_max = AZX_MAX_FRAG, + .fifo_size = 0, +}; + static int avs_component_open(struct snd_soc_component *component, struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); - struct snd_pcm_hardware hwparams; /* only FE DAI links are handled here */ if (rtd->dai_link->no_pcm) return 0; - hwparams.info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_RESUME | - SNDRV_PCM_INFO_NO_PERIOD_WAKEUP; - - hwparams.formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_S32_LE; - hwparams.period_bytes_min = 128; - hwparams.period_bytes_max = AZX_MAX_BUF_SIZE / 2; - hwparams.periods_min = 2; - hwparams.periods_max = AZX_MAX_FRAG; - hwparams.buffer_bytes_max = AZX_MAX_BUF_SIZE; - hwparams.fifo_size = 0; - - return snd_soc_set_runtime_hwparams(substream, &hwparams); + return snd_soc_set_runtime_hwparams(substream, &avs_pcm_hardware); } static unsigned int avs_hda_stream_dpib_read(struct hdac_ext_stream *stream) @@ -1375,9 +1375,15 @@ static int avs_component_hda_open(struct snd_soc_component *component, struct hdac_ext_stream *link_stream; struct hda_codec *codec; - /* only BE DAI links are handled here */ - if (!rtd->dai_link->no_pcm) - return avs_component_open(component, substream); + if (!rtd->dai_link->no_pcm) { + struct snd_pcm_hardware hwparams = avs_pcm_hardware; + + /* RESUME unsupported for de-coupled HD-Audio capture. */ + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + hwparams.info &= ~SNDRV_PCM_INFO_RESUME; + + return snd_soc_set_runtime_hwparams(substream, &hwparams); + } codec = dev_to_hda_codec(asoc_rtd_to_codec(rtd, 0)->dev); link_stream = snd_hdac_ext_stream_assign(&codec->bus->core, substream, -- cgit v1.2.3-70-g09d2 From 730cb320ec2973fb2aea72ea27f7edc6a847a664 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Thu, 27 Oct 2022 14:46:59 +0200 Subject: ASoC: Intel: avs: Count low power streams Streaming in S0iX differs from SX scenarios. Store the number of so-called low-power streams to be able to differentiate between the two. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221027124702.1761002-7-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/avs.h | 1 + sound/soc/intel/avs/pcm.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h index 91f78eb11bc1..fb73d207697f 100644 --- a/sound/soc/intel/avs/avs.h +++ b/sound/soc/intel/avs/avs.h @@ -127,6 +127,7 @@ struct avs_dev { struct list_head fw_list; int *core_refs; /* reference count per core */ char **lib_names; + int num_lp_paths; struct completion fw_ready; struct work_struct probe_work; diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c index 660129508c08..157d25e32e16 100644 --- a/sound/soc/intel/avs/pcm.c +++ b/sound/soc/intel/avs/pcm.c @@ -60,6 +60,8 @@ avs_dai_find_path_template(struct snd_soc_dai *dai, bool is_fe, int direction) static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai, bool is_fe, const struct snd_soc_dai_ops *ops) { + struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); + struct avs_dev *adev = to_avs_dev(dai->dev); struct avs_tplg_path_template *template; struct avs_dma_data *data; @@ -78,6 +80,9 @@ static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_d data->template = template; snd_soc_dai_set_dma_data(dai, substream, data); + if (rtd->dai_link->ignore_suspend) + adev->num_lp_paths++; + return 0; } @@ -164,8 +169,13 @@ static int avs_dai_nonhda_be_startup(struct snd_pcm_substream *substream, struct static void avs_dai_nonhda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { + struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); + struct avs_dev *adev = to_avs_dev(dai->dev); struct avs_dma_data *data; + if (rtd->dai_link->ignore_suspend) + adev->num_lp_paths--; + data = snd_soc_dai_get_dma_data(dai, substream); snd_soc_dai_set_dma_data(dai, substream, NULL); @@ -479,8 +489,13 @@ static int avs_dai_fe_startup(struct snd_pcm_substream *substream, struct snd_so static void avs_dai_fe_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { + struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); + struct avs_dev *adev = to_avs_dev(dai->dev); struct avs_dma_data *data; + if (rtd->dai_link->ignore_suspend) + adev->num_lp_paths--; + data = snd_soc_dai_get_dma_data(dai, substream); snd_soc_dai_set_dma_data(dai, substream, NULL); -- cgit v1.2.3-70-g09d2 From d56829e9c1cb90044c07337fe90a9828fdb165c0 Mon Sep 17 00:00:00 2001 From: Piotr Maziarz Date: Thu, 27 Oct 2022 14:47:00 +0200 Subject: ASoC: Intel: avs: Standby power-state support Introduce avs_suspend_standby() and avs_resume_standby() to support S0IX streaming. The AudioDSP is not shutdown during such scenario and the PCI device is armed for possible wake operation through an audio event. As capability for a stream to be active during low power S0 is based off of ->ignore_suspend, adjust the field's value according to platform capabilities if needed. Signed-off-by: Piotr Maziarz Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221027124702.1761002-8-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/avs.h | 7 ++++ sound/soc/intel/avs/core.c | 75 ++++++++++++++++++++++++++++++++++++++---- sound/soc/intel/avs/topology.c | 10 ++++++ 3 files changed, 85 insertions(+), 7 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h index fb73d207697f..8d05b27608fe 100644 --- a/sound/soc/intel/avs/avs.h +++ b/sound/soc/intel/avs/avs.h @@ -24,6 +24,13 @@ struct avs_tplg_library; struct avs_soc_component; struct avs_ipc_msg; +#ifdef CONFIG_ACPI +#define AVS_S0IX_SUPPORTED \ + (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) +#else +#define AVS_S0IX_SUPPORTED false +#endif + /* * struct avs_dsp_ops - Platform-specific DSP operations * diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c index 0aaded90a99a..6b68d926c9f4 100644 --- a/sound/soc/intel/avs/core.c +++ b/sound/soc/intel/avs/core.c @@ -534,12 +534,30 @@ static void avs_pci_remove(struct pci_dev *pci) pm_runtime_get_noresume(&pci->dev); } -static int __maybe_unused avs_suspend_common(struct avs_dev *adev) +static int avs_suspend_standby(struct avs_dev *adev) +{ + struct hdac_bus *bus = &adev->base.core; + struct pci_dev *pci = adev->base.pci; + + if (bus->cmd_dma_state) + snd_hdac_bus_stop_cmd_io(bus); + + snd_hdac_ext_bus_link_power_down_all(bus); + + enable_irq_wake(pci->irq); + pci_save_state(pci); + + return 0; +} + +static int __maybe_unused avs_suspend_common(struct avs_dev *adev, bool low_power) { struct hdac_bus *bus = &adev->base.core; int ret; flush_work(&adev->probe_work); + if (low_power && adev->num_lp_paths) + return avs_suspend_standby(adev); snd_hdac_ext_bus_link_power_down_all(bus); @@ -577,11 +595,30 @@ static int __maybe_unused avs_suspend_common(struct avs_dev *adev) return 0; } -static int __maybe_unused avs_resume_common(struct avs_dev *adev, bool purge) +static int avs_resume_standby(struct avs_dev *adev) +{ + struct hdac_bus *bus = &adev->base.core; + struct pci_dev *pci = adev->base.pci; + + pci_restore_state(pci); + disable_irq_wake(pci->irq); + + snd_hdac_ext_bus_link_power_up_all(bus); + + if (bus->cmd_dma_state) + snd_hdac_bus_init_cmd_io(bus); + + return 0; +} + +static int __maybe_unused avs_resume_common(struct avs_dev *adev, bool low_power, bool purge) { struct hdac_bus *bus = &adev->base.core; int ret; + if (low_power && adev->num_lp_paths) + return avs_resume_standby(adev); + snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, true); avs_hdac_bus_init_chip(bus, true); @@ -599,26 +636,50 @@ static int __maybe_unused avs_resume_common(struct avs_dev *adev, bool purge) static int __maybe_unused avs_suspend(struct device *dev) { - return avs_suspend_common(to_avs_dev(dev)); + return avs_suspend_common(to_avs_dev(dev), true); } static int __maybe_unused avs_resume(struct device *dev) { - return avs_resume_common(to_avs_dev(dev), true); + return avs_resume_common(to_avs_dev(dev), true, true); } static int __maybe_unused avs_runtime_suspend(struct device *dev) { - return avs_suspend_common(to_avs_dev(dev)); + return avs_suspend_common(to_avs_dev(dev), true); } static int __maybe_unused avs_runtime_resume(struct device *dev) { - return avs_resume_common(to_avs_dev(dev), true); + return avs_resume_common(to_avs_dev(dev), true, false); +} + +static int __maybe_unused avs_freeze(struct device *dev) +{ + return avs_suspend_common(to_avs_dev(dev), false); +} +static int __maybe_unused avs_thaw(struct device *dev) +{ + return avs_resume_common(to_avs_dev(dev), false, true); +} + +static int __maybe_unused avs_poweroff(struct device *dev) +{ + return avs_suspend_common(to_avs_dev(dev), false); +} + +static int __maybe_unused avs_restore(struct device *dev) +{ + return avs_resume_common(to_avs_dev(dev), false, true); } static const struct dev_pm_ops avs_dev_pm = { - SET_SYSTEM_SLEEP_PM_OPS(avs_suspend, avs_resume) + .suspend = avs_suspend, + .resume = avs_resume, + .freeze = avs_freeze, + .thaw = avs_thaw, + .poweroff = avs_poweroff, + .restore = avs_restore, SET_RUNTIME_PM_OPS(avs_runtime_suspend, avs_runtime_resume, NULL) }; diff --git a/sound/soc/intel/avs/topology.c b/sound/soc/intel/avs/topology.c index 8a9f9fc48938..e845eaf0a1e7 100644 --- a/sound/soc/intel/avs/topology.c +++ b/sound/soc/intel/avs/topology.c @@ -1405,6 +1405,11 @@ static int avs_widget_load(struct snd_soc_component *comp, int index, if (!le32_to_cpu(dw->priv.size)) return 0; + if (w->ignore_suspend && !AVS_S0IX_SUPPORTED) { + dev_info_once(comp->dev, "Device does not support S0IX, check BIOS settings\n"); + w->ignore_suspend = false; + } + tplg = acomp->tplg; mach = dev_get_platdata(comp->card->dev); @@ -1442,6 +1447,11 @@ static int avs_dai_load(struct snd_soc_component *comp, int index, static int avs_link_load(struct snd_soc_component *comp, int index, struct snd_soc_dai_link *link, struct snd_soc_tplg_link_config *cfg) { + if (link->ignore_suspend && !AVS_S0IX_SUPPORTED) { + dev_info_once(comp->dev, "Device does not support S0IX, check BIOS settings\n"); + link->ignore_suspend = false; + } + if (!link->no_pcm) { /* Stream control handled by IPCs. */ link->nonatomic = true; -- cgit v1.2.3-70-g09d2 From 2a87f17775c1cbcfb99225312e8cc7a06aa109b9 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Thu, 27 Oct 2022 14:47:01 +0200 Subject: ASoC: Intel: avs: Power and clock gating policy overriding Provide pgctl/cgctl_mask module parameters for overriding power and clock gating policies respectively. These help deal with rare firmware loading failures on some configurations. There're no golden masks that cover all known problems so leave the defaults as is. While at it, update avs_hda_l1sen_enable()'s definition so it aligns with its power/clock friends. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221027124702.1761002-9-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/core.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c index 6b68d926c9f4..f7bc06404dbc 100644 --- a/sound/soc/intel/avs/core.c +++ b/sound/soc/intel/avs/core.c @@ -27,6 +27,14 @@ #include "avs.h" #include "cldma.h" +static u32 pgctl_mask = AZX_PGCTL_LSRMD_MASK; +module_param(pgctl_mask, uint, 0444); +MODULE_PARM_DESC(pgctl_mask, "PCI PGCTL policy override"); + +static u32 cgctl_mask = AZX_CGCTL_MISCBDCGE_MASK; +module_param(cgctl_mask, uint, 0444); +MODULE_PARM_DESC(cgctl_mask, "PCI CGCTL policy override"); + static void avs_hda_update_config_dword(struct hdac_bus *bus, u32 reg, u32 mask, u32 value) { @@ -41,19 +49,16 @@ avs_hda_update_config_dword(struct hdac_bus *bus, u32 reg, u32 mask, u32 value) void avs_hda_power_gating_enable(struct avs_dev *adev, bool enable) { - u32 value; + u32 value = enable ? 0 : pgctl_mask; - value = enable ? 0 : AZX_PGCTL_LSRMD_MASK; - avs_hda_update_config_dword(&adev->base.core, AZX_PCIREG_PGCTL, - AZX_PGCTL_LSRMD_MASK, value); + avs_hda_update_config_dword(&adev->base.core, AZX_PCIREG_PGCTL, pgctl_mask, value); } static void avs_hdac_clock_gating_enable(struct hdac_bus *bus, bool enable) { - u32 value; + u32 value = enable ? cgctl_mask : 0; - value = enable ? AZX_CGCTL_MISCBDCGE_MASK : 0; - avs_hda_update_config_dword(bus, AZX_PCIREG_CGCTL, AZX_CGCTL_MISCBDCGE_MASK, value); + avs_hda_update_config_dword(bus, AZX_PCIREG_CGCTL, cgctl_mask, value); } void avs_hda_clock_gating_enable(struct avs_dev *adev, bool enable) @@ -63,9 +68,8 @@ void avs_hda_clock_gating_enable(struct avs_dev *adev, bool enable) void avs_hda_l1sen_enable(struct avs_dev *adev, bool enable) { - u32 value; + u32 value = enable ? AZX_VS_EM2_L1SEN : 0; - value = enable ? AZX_VS_EM2_L1SEN : 0; snd_hdac_chip_updatel(&adev->base.core, VS_EM2, AZX_VS_EM2_L1SEN, value); } -- cgit v1.2.3-70-g09d2 From 758ba92f3a2f86493a9147abd31a5bdc0befc273 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Thu, 27 Oct 2022 14:47:02 +0200 Subject: ASoC: Intel: avs: Enact power gating policy Update all firmware loading functions to also account for the power gating policy. As module loading routine is missing the chicken bits manipulation entirely, add the entire set there. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221027124702.1761002-10-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/loader.c | 10 ++++++++++ sound/soc/intel/avs/pcm.c | 2 ++ 2 files changed, 12 insertions(+) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/loader.c b/sound/soc/intel/avs/loader.c index eb10e45790e7..56bb0a59249d 100644 --- a/sound/soc/intel/avs/loader.c +++ b/sound/soc/intel/avs/loader.c @@ -224,11 +224,19 @@ static int avs_cldma_load_module(struct avs_dev *adev, struct avs_module_entry * if (ret < 0) return ret; + avs_hda_power_gating_enable(adev, false); + avs_hda_clock_gating_enable(adev, false); + avs_hda_l1sen_enable(adev, false); + hda_cldma_set_data(cl, (void *)mod->data, mod->size); hda_cldma_transfer(cl, msecs_to_jiffies(AVS_CLDMA_START_DELAY_MS)); ret = avs_ipc_load_modules(adev, &mentry->module_id, 1); hda_cldma_stop(cl); + avs_hda_l1sen_enable(adev, true); + avs_hda_clock_gating_enable(adev, true); + avs_hda_power_gating_enable(adev, true); + if (ret) { dev_err(adev->dev, "load module %d failed: %d\n", mentry->module_id, ret); avs_release_last_firmware(adev); @@ -605,6 +613,7 @@ int avs_dsp_boot_firmware(struct avs_dev *adev, bool purge) for (i = 1; i < adev->fw_cfg.max_libs_count; i++) memset(adev->lib_names[i], 0, AVS_LIB_NAME_SIZE); + avs_hda_power_gating_enable(adev, false); avs_hda_clock_gating_enable(adev, false); avs_hda_l1sen_enable(adev, false); @@ -625,6 +634,7 @@ int avs_dsp_boot_firmware(struct avs_dev *adev, bool purge) reenable_gating: avs_hda_l1sen_enable(adev, true); avs_hda_clock_gating_enable(adev, true); + avs_hda_power_gating_enable(adev, true); if (ret < 0) return ret; diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c index 157d25e32e16..ca624fbb5c0d 100644 --- a/sound/soc/intel/avs/pcm.c +++ b/sound/soc/intel/avs/pcm.c @@ -737,6 +737,7 @@ static int avs_component_load_libraries(struct avs_soc_component *acomp) if (ret < 0) return ret; + avs_hda_power_gating_enable(adev, false); avs_hda_clock_gating_enable(adev, false); avs_hda_l1sen_enable(adev, false); @@ -744,6 +745,7 @@ static int avs_component_load_libraries(struct avs_soc_component *acomp) avs_hda_l1sen_enable(adev, true); avs_hda_clock_gating_enable(adev, true); + avs_hda_power_gating_enable(adev, true); if (!ret) ret = avs_module_info_init(adev, false); -- cgit v1.2.3-70-g09d2 From 0aa60ddc219e7bac967605ecbe46f2f6cd24ee9c Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Fri, 21 Oct 2022 20:38:48 +0800 Subject: ASoC: Intel: Skylake: fix possible memory leak in skl_codec_device_init() If snd_hdac_device_register() fails, 'codec' and name allocated in dev_set_name() called in snd_hdac_device_init() are leaked. Fix this by calling put_device(), so they can be freed in snd_hda_codec_dev_release() and kobject_cleanup(). Fixes: e4746d94d00c ("ASoC: Intel: Skylake: Introduce HDA codec init and exit routines") Fixes: dfe66a18780d ("ALSA: hdac_ext: add extended HDA bus") Suggested-by: Cezary Rojewski Signed-off-by: Yang Yingliang Reviewed-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221021123849.456857-1-yangyingliang@huawei.com Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index c6f319bcd2c4..9bd9f9866898 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -680,11 +680,6 @@ static void load_codec_module(struct hda_codec *codec) #endif /* CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC */ -static void skl_codec_device_exit(struct device *dev) -{ - snd_hdac_device_exit(dev_to_hdac_dev(dev)); -} - static struct hda_codec *skl_codec_device_init(struct hdac_bus *bus, int addr) { struct hda_codec *codec; @@ -697,12 +692,11 @@ static struct hda_codec *skl_codec_device_init(struct hdac_bus *bus, int addr) } codec->core.type = HDA_DEV_ASOC; - codec->core.dev.release = skl_codec_device_exit; ret = snd_hdac_device_register(&codec->core); if (ret) { dev_err(bus->dev, "failed to register hdac device\n"); - snd_hdac_device_exit(&codec->core); + put_device(&codec->core.dev); return ERR_PTR(ret); } -- cgit v1.2.3-70-g09d2 From b43d0c0a42b2c44da824b3de0364d73be722a8c7 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 3 Nov 2022 12:06:24 +0000 Subject: ASoC: Intel: cirrus-common: Make const array uid_strings static Don't populate the read-only const array uid_strings on the stack but instead make it static. Also makes the object code a little smaller. Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20221103120624.72583-1-colin.i.king@gmail.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_cirrus_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/boards/sof_cirrus_common.c b/sound/soc/intel/boards/sof_cirrus_common.c index 6e39eda77385..851c516c8f5b 100644 --- a/sound/soc/intel/boards/sof_cirrus_common.c +++ b/sound/soc/intel/boards/sof_cirrus_common.c @@ -155,7 +155,7 @@ static const char * const cs35l41_name_prefixes[] = { "WL", "WR", "TL", "TR" }; */ static int cs35l41_compute_codec_conf(void) { - const char * const uid_strings[] = { "0", "1", "2", "3" }; + static const char * const uid_strings[] = { "0", "1", "2", "3" }; unsigned int uid, sz = 0; struct acpi_device *adev; struct device *physdev; -- cgit v1.2.3-70-g09d2 From 9a1fe79daddbdc57307bd7dd9a29ef06aa7b5f34 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 31 Oct 2022 17:02:22 +0100 Subject: ASoC: Intel: Drop da7219_aad_jack_det() usage Do not access the internal function directly, do so through component->set_jack() instead. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221031160227.2352630-3-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bxt_da7219_max98357a.c | 3 +-- sound/soc/intel/boards/kbl_da7219_max98357a.c | 3 +-- sound/soc/intel/boards/kbl_da7219_max98927.c | 3 +-- sound/soc/intel/boards/sof_da7219_max98373.c | 4 ++-- 4 files changed, 5 insertions(+), 8 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c index 7c6c95e99ade..c593995facaa 100644 --- a/sound/soc/intel/boards/bxt_da7219_max98357a.c +++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c @@ -19,7 +19,6 @@ #include #include "../../codecs/hdac_hdmi.h" #include "../../codecs/da7219.h" -#include "../../codecs/da7219-aad.h" #include "../common/soc-intel-quirks.h" #include "hda_dsp_common.h" @@ -259,7 +258,7 @@ static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); - da7219_aad_jack_det(component, &broxton_headset); + snd_soc_component_set_jack(component, &broxton_headset, NULL); snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); diff --git a/sound/soc/intel/boards/kbl_da7219_max98357a.c b/sound/soc/intel/boards/kbl_da7219_max98357a.c index 329457e3e3a2..18365ce6bcba 100644 --- a/sound/soc/intel/boards/kbl_da7219_max98357a.c +++ b/sound/soc/intel/boards/kbl_da7219_max98357a.c @@ -19,7 +19,6 @@ #include #include "../../codecs/da7219.h" #include "../../codecs/hdac_hdmi.h" -#include "../../codecs/da7219-aad.h" #define KBL_DIALOG_CODEC_DAI "da7219-hifi" #define KBL_MAXIM_CODEC_DAI "HiFi" @@ -207,7 +206,7 @@ static int kabylake_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP); snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); - da7219_aad_jack_det(component, &ctx->kabylake_headset); + snd_soc_component_set_jack(component, &ctx->kabylake_headset, NULL); ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); if (ret) diff --git a/sound/soc/intel/boards/kbl_da7219_max98927.c b/sound/soc/intel/boards/kbl_da7219_max98927.c index 362579f25835..ad4223fee0c5 100644 --- a/sound/soc/intel/boards/kbl_da7219_max98927.c +++ b/sound/soc/intel/boards/kbl_da7219_max98927.c @@ -19,7 +19,6 @@ #include #include "../../codecs/da7219.h" #include "../../codecs/hdac_hdmi.h" -#include "../../codecs/da7219-aad.h" #define KBL_DIALOG_CODEC_DAI "da7219-hifi" #define MAX98927_CODEC_DAI "max98927-aif1" @@ -382,7 +381,7 @@ static int kabylake_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); - da7219_aad_jack_det(component, &ctx->kabylake_headset); + snd_soc_component_set_jack(component, &ctx->kabylake_headset, NULL); return 0; } diff --git a/sound/soc/intel/boards/sof_da7219_max98373.c b/sound/soc/intel/boards/sof_da7219_max98373.c index e048e789e633..740aa11cb019 100644 --- a/sound/soc/intel/boards/sof_da7219_max98373.c +++ b/sound/soc/intel/boards/sof_da7219_max98373.c @@ -7,13 +7,13 @@ #include #include +#include #include #include #include #include #include #include "../../codecs/da7219.h" -#include "../../codecs/da7219-aad.h" #include "hda_dsp_common.h" #define DIALOG_CODEC_DAI "da7219-hifi" @@ -184,7 +184,7 @@ static int da7219_codec_init(struct snd_soc_pcm_runtime *rtd) snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP); snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); - da7219_aad_jack_det(component, jack); + snd_soc_component_set_jack(component, jack, NULL); return ret; } -- cgit v1.2.3-70-g09d2 From 7af1ca5bb5e3c2e472a040f8b52382ccc57bb01a Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 31 Oct 2022 17:02:26 +0100 Subject: ASoC: Intel: avs: Drop da7219_aad_jack_det() usage Do not access the internal function directly, do so through component->set_jack() instead. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221031160227.2352630-7-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/da7219.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/boards/da7219.c b/sound/soc/intel/avs/boards/da7219.c index 503a967a1c3a..ad86cef101cc 100644 --- a/sound/soc/intel/avs/boards/da7219.c +++ b/sound/soc/intel/avs/boards/da7219.c @@ -16,7 +16,6 @@ #include #include #include "../../../codecs/da7219.h" -#include "../../../codecs/da7219-aad.h" #define DA7219_DAI_NAME "da7219-hifi" @@ -110,7 +109,7 @@ static int avs_da7219_codec_init(struct snd_soc_pcm_runtime *runtime) snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); - da7219_aad_jack_det(component, jack); + snd_soc_component_set_jack(component, jack, NULL); return 0; } -- cgit v1.2.3-70-g09d2 From 1b435e405d63155d2391c27054cf98237d11d0a4 Mon Sep 17 00:00:00 2001 From: Shuming Fan Date: Wed, 9 Nov 2022 17:13:06 +0800 Subject: ASoC: Intel: sof_sdw_rt1308: add BQ params for the Dell models The Dell SKU 0A5D/0A5E/0990/098F model needs the BQ params for the tweeter/woofer. Signed-off-by: Shuming Fan Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Link: https://lore.kernel.org/r/20221109091306.17221-1-shumingf@realtek.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 1 + sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h | 162 ++++++++++++++++++++++ sound/soc/intel/boards/sof_sdw_common.h | 2 + sound/soc/intel/boards/sof_sdw_rt1308.c | 120 ++++++++++++++++ 4 files changed, 285 insertions(+) create mode 100644 sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index ee9857dc3135..a3bbdc261a4a 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -510,6 +510,7 @@ static struct sof_sdw_codec_info codec_info_list[] = { .dai_name = "rt1308-aif", .ops = &sof_sdw_rt1308_i2s_ops, .init = sof_sdw_rt1308_init, + .exit = sof_sdw_rt1308_exit, .codec_type = SOF_SDW_CODEC_TYPE_AMP, }, { diff --git a/sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h b/sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h new file mode 100644 index 000000000000..bb90a5922fd2 --- /dev/null +++ b/sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h @@ -0,0 +1,162 @@ +/* SPDX-License-Identifier: GPL-2.0-only + */ + +/* + * sof_sdw_amp_coeff_tables.h - related coefficients for amplifier parameters + */ + +#ifndef SND_SOC_SOF_SDW_AMP_COEFF_H +#define SND_SOC_SOF_SDW_AMP_COEFF_H + +#define RT1308_MAX_BQ_REG 480 + +static const u8 dell_0a5d_bq_params[] = { + 0xb0, 0xc5, 0x00, /* address: 0xc5b0; data: 0x00 */ + 0xb1, 0xc5, 0x32, + 0xb2, 0xc5, 0x44, + 0xb3, 0xc5, 0x19, + 0xc0, 0xc5, 0x04, + 0xc1, 0xc5, 0x00, + 0xc2, 0xc5, 0x00, + 0xc3, 0xc5, 0x00, + 0xd0, 0xc5, 0x02, + 0xd1, 0xc5, 0x00, + 0xd2, 0xc5, 0x00, + 0xd3, 0xc5, 0x00, + 0xe0, 0xc5, 0x01, + 0xe1, 0xc5, 0xe8, + 0xe2, 0xc5, 0x5f, + 0xe3, 0xc5, 0x8a, + 0xf0, 0xc5, 0x1f, + 0xf1, 0xc5, 0x4e, + 0xf2, 0xc5, 0x90, + 0xf3, 0xc5, 0x11, + 0x50, 0xc6, 0x01, + 0x51, 0xc6, 0xff, + 0x52, 0xc6, 0x45, + 0x53, 0xc6, 0x41, + 0x60, 0xc6, 0x1c, + 0x61, 0xc6, 0x00, + 0x62, 0xc6, 0x00, + 0x63, 0xc6, 0x00, + 0x70, 0xc6, 0x02, + 0x71, 0xc6, 0x00, + 0x72, 0xc6, 0x00, + 0x73, 0xc6, 0x00, + 0x80, 0xc6, 0x03, + 0x81, 0xc6, 0xfe, + 0x82, 0xc6, 0x89, + 0x83, 0xc6, 0xfa, + 0x90, 0xc6, 0x1e, + 0x91, 0xc6, 0x01, + 0x92, 0xc6, 0x74, + 0x93, 0xc6, 0xf6, + 0x00, 0xc6, 0x01, + 0x01, 0xc6, 0xd9, + 0x02, 0xc6, 0xfb, + 0x03, 0xc6, 0xc4, + 0x10, 0xc6, 0x1c, + 0x11, 0xc6, 0x00, + 0x12, 0xc6, 0x00, + 0x13, 0xc6, 0x00, + 0x20, 0xc6, 0x02, + 0x21, 0xc6, 0x00, + 0x22, 0xc6, 0x00, + 0x23, 0xc6, 0x00, + 0x30, 0xc6, 0x03, + 0x31, 0xc6, 0xaf, + 0x32, 0xc6, 0x23, + 0x33, 0xc6, 0xcb, + 0x40, 0xc6, 0x1e, + 0x41, 0xc6, 0x47, + 0x42, 0xc6, 0x34, + 0x43, 0xc6, 0xba, + 0xa0, 0xc6, 0x01, + 0xa1, 0xc6, 0xff, + 0xa2, 0xc6, 0x45, + 0xa3, 0xc6, 0x41, + 0xb0, 0xc6, 0x1c, + 0xb1, 0xc6, 0x00, + 0xb2, 0xc6, 0x00, + 0xb3, 0xc6, 0x00, + 0xc0, 0xc6, 0x02, + 0xc1, 0xc6, 0x00, + 0xc2, 0xc6, 0x00, + 0xc3, 0xc6, 0x00, + 0xd0, 0xc6, 0x03, + 0xd1, 0xc6, 0xfe, + 0xd2, 0xc6, 0x89, + 0xd3, 0xc6, 0xfa, + 0xe0, 0xc6, 0x1e, + 0xe1, 0xc6, 0x01, + 0xe2, 0xc6, 0x74, + 0xe3, 0xc6, 0xf6, + 0x40, 0xc5, 0x0d, + 0x30, 0xc7, 0x15, + 0x31, 0xc7, 0x7c, + 0x32, 0xc7, 0x0f, + 0x33, 0xc7, 0xa0, + 0x40, 0xc7, 0x00, + 0x41, 0xc7, 0x00, + 0x42, 0xc7, 0xf8, + 0x43, 0xc7, 0xf8, + 0x50, 0xc7, 0x00, + 0x51, 0xc7, 0x00, + 0x52, 0xc7, 0x00, + 0x53, 0xc7, 0x01, + 0x90, 0xc7, 0x00, + 0x91, 0xc7, 0x14, + 0x92, 0xc7, 0x00, + 0x93, 0xc7, 0x14, + 0xa0, 0xc7, 0x00, + 0xa1, 0xc7, 0x00, + 0xa2, 0xc7, 0xf8, + 0xa3, 0xc7, 0xf8, + 0xb0, 0xc7, 0x00, + 0xb1, 0xc7, 0x00, + 0xb2, 0xc7, 0x00, + 0xb3, 0xc7, 0x00, + 0x60, 0xc7, 0x03, + 0x61, 0xc7, 0xe8, + 0x62, 0xc7, 0x03, + 0x63, 0xc7, 0xb6, + 0x70, 0xc7, 0x00, + 0x71, 0xc7, 0x00, + 0x72, 0xc7, 0xf8, + 0x73, 0xc7, 0xf8, + 0x80, 0xc7, 0x00, + 0x81, 0xc7, 0x00, + 0x82, 0xc7, 0x00, + 0x83, 0xc7, 0x00, + 0xc0, 0xc7, 0x00, + 0xc1, 0xc7, 0x14, + 0xc2, 0xc7, 0x00, + 0xc3, 0xc7, 0x14, + 0xd0, 0xc7, 0x00, + 0xd1, 0xc7, 0x00, + 0xd2, 0xc7, 0xf8, + 0xd3, 0xc7, 0xf8, + 0xe0, 0xc7, 0x00, + 0xe1, 0xc7, 0x00, + 0xe2, 0xc7, 0x00, + 0xe3, 0xc7, 0x00, + 0x60, 0xc5, 0x02, + 0x61, 0xc5, 0x00, + 0x62, 0xc5, 0x00, + 0x63, 0xc5, 0x00, + 0x70, 0xc5, 0x02, + 0x71, 0xc5, 0x00, + 0x72, 0xc5, 0x00, + 0x73, 0xc5, 0x00, + 0x80, 0xc5, 0x02, + 0x81, 0xc5, 0x00, + 0x82, 0xc5, 0x00, + 0x83, 0xc5, 0x00, + 0x90, 0xc5, 0x02, + 0x91, 0xc5, 0x00, + 0x92, 0xc5, 0x00, + 0x93, 0xc5, 0x00, + 0x50, 0xc5, 0x01, +}; + +#endif diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h index e2457738a332..772af23e7497 100644 --- a/sound/soc/intel/boards/sof_sdw_common.h +++ b/sound/soc/intel/boards/sof_sdw_common.h @@ -83,6 +83,7 @@ struct mc_private { bool idisp_codec; struct snd_soc_jack sdw_headset; struct device *headset_codec_dev; /* only one headset per card */ + struct device *amp_dev1, *amp_dev2; }; extern unsigned long sof_sdw_quirk; @@ -132,6 +133,7 @@ int sof_sdw_rt1308_init(struct snd_soc_card *card, struct snd_soc_dai_link *dai_links, struct sof_sdw_codec_info *info, bool playback); +int sof_sdw_rt1308_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); /* RT1316 support */ int sof_sdw_rt1316_init(struct snd_soc_card *card, diff --git a/sound/soc/intel/boards/sof_sdw_rt1308.c b/sound/soc/intel/boards/sof_sdw_rt1308.c index f078fb1aad02..a19b055b9c6f 100644 --- a/sound/soc/intel/boards/sof_sdw_rt1308.c +++ b/sound/soc/intel/boards/sof_sdw_rt1308.c @@ -11,9 +11,86 @@ #include #include #include +#include +#include +#include #include "sof_sdw_common.h" +#include "sof_sdw_amp_coeff_tables.h" #include "../../codecs/rt1308.h" +struct rt1308_platform_data { + const unsigned char *bq_params; + const unsigned int bq_params_cnt; +}; + +static const struct rt1308_platform_data dell_0a5d_platform_data = { + .bq_params = dell_0a5d_bq_params, + .bq_params_cnt = ARRAY_SIZE(dell_0a5d_bq_params), +}; + +static const struct dmi_system_id dmi_platform_data[] = { + /* CometLake devices */ + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990") + }, + .driver_data = (void *)&dell_0a5d_platform_data, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F") + }, + .driver_data = (void *)&dell_0a5d_platform_data, + }, + /* TigerLake devices */ + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5D") + }, + .driver_data = (void *)&dell_0a5d_platform_data, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5E") + }, + .driver_data = (void *)&dell_0a5d_platform_data, + }, +}; + +static int rt1308_add_device_props(struct device *sdw_dev) +{ + struct property_entry props[3] = {}; + struct fwnode_handle *fwnode; + const struct dmi_system_id *dmi_data; + const struct rt1308_platform_data *pdata; + unsigned char params[RT1308_MAX_BQ_REG]; + int ret; + + dmi_data = dmi_first_match(dmi_platform_data); + if (!dmi_data) + return 0; + + pdata = dmi_data->driver_data; + memcpy(¶ms, pdata->bq_params, sizeof(unsigned char) * pdata->bq_params_cnt); + + props[0] = PROPERTY_ENTRY_U8_ARRAY("realtek,bq-params", params); + props[1] = PROPERTY_ENTRY_U32("realtek,bq-params-cnt", pdata->bq_params_cnt); + + fwnode = fwnode_create_software_node(props, NULL); + if (IS_ERR(fwnode)) + return PTR_ERR(fwnode); + + ret = device_add_software_node(sdw_dev, to_software_node(fwnode)); + + fwnode_handle_put(fwnode); + + return ret; +} + static const struct snd_soc_dapm_widget rt1308_widgets[] = { SND_SOC_DAPM_SPK("Speaker", NULL), }; @@ -127,12 +204,33 @@ struct snd_soc_ops sof_sdw_rt1308_i2s_ops = { .hw_params = rt1308_i2s_hw_params, }; +int sof_sdw_rt1308_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link) +{ + struct mc_private *ctx = snd_soc_card_get_drvdata(card); + + if (ctx->amp_dev1) { + device_remove_software_node(ctx->amp_dev1); + put_device(ctx->amp_dev1); + } + + if (ctx->amp_dev2) { + device_remove_software_node(ctx->amp_dev2); + put_device(ctx->amp_dev2); + } + + return 0; +} + int sof_sdw_rt1308_init(struct snd_soc_card *card, const struct snd_soc_acpi_link_adr *link, struct snd_soc_dai_link *dai_links, struct sof_sdw_codec_info *info, bool playback) { + struct mc_private *ctx = snd_soc_card_get_drvdata(card); + struct device *sdw_dev1, *sdw_dev2; + int ret; + /* Count amp number and do init on playback link only. */ if (!playback) return 0; @@ -142,6 +240,28 @@ int sof_sdw_rt1308_init(struct snd_soc_card *card, dai_links->init = first_spk_init; if (info->amp_num == 2) { + sdw_dev1 = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[0].name); + if (!sdw_dev1) + return -EPROBE_DEFER; + + ret = rt1308_add_device_props(sdw_dev1); + if (ret < 0) { + put_device(sdw_dev1); + return ret; + } + ctx->amp_dev1 = sdw_dev1; + + sdw_dev2 = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[1].name); + if (!sdw_dev2) + return -EPROBE_DEFER; + + ret = rt1308_add_device_props(sdw_dev2); + if (ret < 0) { + put_device(sdw_dev2); + return ret; + } + ctx->amp_dev2 = sdw_dev2; + /* * if two 1308s are in one dai link, the init function * in this dai link will be first set for the first speaker, -- cgit v1.2.3-70-g09d2 From cf6946d95005add8437f874e0952ec4f28fe5c02 Mon Sep 17 00:00:00 2001 From: Shuming Fan Date: Wed, 9 Nov 2022 17:13:17 +0800 Subject: ASoC: Intel: sof_sdw_rt1316: add BQ params for the Dell models The Dell SKU 0B00/0B01/0AFE/0AFF model needs the BQ params for the tweeter/woofer. Signed-off-by: Shuming Fan Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Link: https://lore.kernel.org/r/20221109091317.17240-1-shumingf@realtek.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 1 + sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h | 138 ++++++++++++++++++++++ sound/soc/intel/boards/sof_sdw_common.h | 1 + sound/soc/intel/boards/sof_sdw_rt1316.c | 119 +++++++++++++++++++ 4 files changed, 259 insertions(+) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index a3bbdc261a4a..949adfdd0e3c 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -518,6 +518,7 @@ static struct sof_sdw_codec_info codec_info_list[] = { .direction = {true, true}, .dai_name = "rt1316-aif", .init = sof_sdw_rt1316_init, + .exit = sof_sdw_rt1316_exit, .codec_type = SOF_SDW_CODEC_TYPE_AMP, }, { diff --git a/sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h b/sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h index bb90a5922fd2..82230fbb5b05 100644 --- a/sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h +++ b/sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h @@ -9,6 +9,7 @@ #define SND_SOC_SOF_SDW_AMP_COEFF_H #define RT1308_MAX_BQ_REG 480 +#define RT1316_MAX_BQ_REG 580 static const u8 dell_0a5d_bq_params[] = { 0xb0, 0xc5, 0x00, /* address: 0xc5b0; data: 0x00 */ @@ -159,4 +160,141 @@ static const u8 dell_0a5d_bq_params[] = { 0x50, 0xc5, 0x01, }; +static const u8 dell_0b00_bq_params[] = { + 0x03, 0xc2, 0x00, + 0x04, 0xc2, 0xb2, + 0x05, 0xc2, 0xe0, + 0x06, 0xc2, 0x3a, + 0x07, 0xc2, 0x01, + 0x08, 0xc2, 0x65, + 0x09, 0xc2, 0xc0, + 0x0a, 0xc2, 0x75, + 0x0b, 0xc2, 0x00, + 0x0c, 0xc2, 0xb2, + 0x0d, 0xc2, 0xe0, + 0x0e, 0xc2, 0x3a, + 0x0f, 0xc2, 0xf7, + 0x10, 0xc2, 0x4d, + 0x11, 0xc2, 0x5b, + 0x12, 0xc2, 0xe9, + 0x13, 0xc2, 0x03, + 0x14, 0xc2, 0x7e, + 0x15, 0xc2, 0x25, + 0x16, 0xc2, 0x01, + 0x17, 0xc2, 0x07, + 0x18, 0xc2, 0xfd, + 0x19, 0xc2, 0x15, + 0x1a, 0xc2, 0x04, + 0x1b, 0xc2, 0xf0, + 0x1c, 0xc2, 0x05, + 0x1d, 0xc2, 0xd5, + 0x1e, 0xc2, 0xf7, + 0x1f, 0xc2, 0x07, + 0x20, 0xc2, 0xfd, + 0x21, 0xc2, 0x15, + 0x22, 0xc2, 0x04, + 0x23, 0xc2, 0xf0, + 0x24, 0xc2, 0x05, + 0x25, 0xc2, 0xd8, + 0x26, 0xc2, 0x17, + 0x27, 0xc2, 0x07, + 0x28, 0xc2, 0xfa, + 0x29, 0xc2, 0x2c, + 0x2a, 0xc2, 0x29, + 0x2b, 0xc2, 0x07, + 0x2c, 0xc2, 0x74, + 0x2d, 0xc2, 0xe0, + 0x2e, 0xc2, 0x33, + 0x2f, 0xc2, 0xf1, + 0x30, 0xc2, 0x16, + 0x31, 0xc2, 0x3f, + 0x32, 0xc2, 0x9b, + 0x33, 0xc2, 0x07, + 0x34, 0xc2, 0x74, + 0x35, 0xc2, 0xe0, + 0x36, 0xc2, 0x33, + 0x37, 0xc2, 0xf1, + 0x38, 0xc2, 0x29, + 0x39, 0xc2, 0xb0, + 0x3a, 0xc2, 0x4d, + 0x3b, 0xc2, 0x06, + 0x3c, 0xc2, 0xfd, + 0x3d, 0xc2, 0x31, + 0x3e, 0xc2, 0x18, + 0x3f, 0xc2, 0x07, + 0x40, 0xc2, 0xfd, + 0x41, 0xc2, 0x15, + 0x42, 0xc2, 0x04, + 0x43, 0xc2, 0xf0, + 0x44, 0xc2, 0x05, + 0x45, 0xc2, 0xd5, + 0x46, 0xc2, 0xf7, + 0x47, 0xc2, 0x07, + 0x48, 0xc2, 0xfd, + 0x49, 0xc2, 0x15, + 0x4a, 0xc2, 0x04, + 0x4b, 0xc2, 0xf0, + 0x4c, 0xc2, 0x05, + 0x4d, 0xc2, 0xd8, + 0x4e, 0xc2, 0x17, + 0x4f, 0xc2, 0x07, + 0x50, 0xc2, 0xfa, + 0x51, 0xc2, 0x2c, + 0x52, 0xc2, 0x29, + 0x0b, 0xc0, 0x30, + 0x80, 0xc3, 0x13, + 0x81, 0xc3, 0x88, + 0x82, 0xc3, 0x17, + 0x83, 0xc3, 0x70, + 0x84, 0xc3, 0x00, + 0x85, 0xc3, 0x00, + 0x86, 0xc3, 0xff, + 0x87, 0xc3, 0xee, + 0x88, 0xc3, 0x02, + 0x92, 0xc3, 0x00, + 0x93, 0xc3, 0x14, + 0x94, 0xc3, 0x00, + 0x95, 0xc3, 0x14, + 0x96, 0xc3, 0x00, + 0x97, 0xc3, 0x00, + 0x98, 0xc3, 0x00, + 0x99, 0xc3, 0x00, + 0x9a, 0xc3, 0x01, + 0x89, 0xc3, 0x03, + 0x8a, 0xc3, 0xe8, + 0x8b, 0xc3, 0x03, + 0x8c, 0xc3, 0xb6, + 0x8d, 0xc3, 0x00, + 0x8e, 0xc3, 0x00, + 0x8f, 0xc3, 0xff, + 0x90, 0xc3, 0xee, + 0x91, 0xc3, 0x01, + 0x9b, 0xc3, 0x00, + 0x9c, 0xc3, 0x14, + 0x9d, 0xc3, 0x00, + 0x9e, 0xc3, 0x14, + 0x9f, 0xc3, 0x00, + 0xa0, 0xc3, 0x00, + 0xa1, 0xc3, 0x00, + 0xa2, 0xc3, 0x00, + 0xa3, 0xc3, 0x01, + 0x61, 0xc2, 0x08, + 0x62, 0xc2, 0x00, + 0x63, 0xc2, 0x00, + 0x64, 0xc2, 0x00, + 0x65, 0xc2, 0x08, + 0x66, 0xc2, 0x00, + 0x67, 0xc2, 0x00, + 0x68, 0xc2, 0x00, + 0x69, 0xc2, 0x08, + 0x6a, 0xc2, 0x00, + 0x6b, 0xc2, 0x00, + 0x6c, 0xc2, 0x00, + 0x6d, 0xc2, 0x08, + 0x6e, 0xc2, 0x00, + 0x6f, 0xc2, 0x00, + 0x70, 0xc2, 0x00, + 0x00, 0xc2, 0xc0, +}; + #endif diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h index 772af23e7497..bac93fdc8d82 100644 --- a/sound/soc/intel/boards/sof_sdw_common.h +++ b/sound/soc/intel/boards/sof_sdw_common.h @@ -141,6 +141,7 @@ int sof_sdw_rt1316_init(struct snd_soc_card *card, struct snd_soc_dai_link *dai_links, struct sof_sdw_codec_info *info, bool playback); +int sof_sdw_rt1316_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); /* RT715 support */ int sof_sdw_rt715_init(struct snd_soc_card *card, diff --git a/sound/soc/intel/boards/sof_sdw_rt1316.c b/sound/soc/intel/boards/sof_sdw_rt1316.c index 58194b380232..f6bbea0d3810 100644 --- a/sound/soc/intel/boards/sof_sdw_rt1316.c +++ b/sound/soc/intel/boards/sof_sdw_rt1316.c @@ -11,7 +11,83 @@ #include #include #include +#include +#include +#include #include "sof_sdw_common.h" +#include "sof_sdw_amp_coeff_tables.h" + +struct rt1316_platform_data { + const unsigned char *bq_params; + const unsigned int bq_params_cnt; +}; + +static const struct rt1316_platform_data dell_0b00_platform_data = { + .bq_params = dell_0b00_bq_params, + .bq_params_cnt = ARRAY_SIZE(dell_0b00_bq_params), +}; + +static const struct dmi_system_id dmi_platform_data[] = { + /* AlderLake devices */ + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B00") + }, + .driver_data = (void *)&dell_0b00_platform_data, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B01") + }, + .driver_data = (void *)&dell_0b00_platform_data, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AFF") + }, + .driver_data = (void *)&dell_0b00_platform_data, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AFE") + }, + .driver_data = (void *)&dell_0b00_platform_data, + }, +}; + +static int rt1316_add_device_props(struct device *sdw_dev) +{ + struct property_entry props[3] = {}; + struct fwnode_handle *fwnode; + const struct dmi_system_id *dmi_data; + const struct rt1316_platform_data *pdata; + unsigned char params[RT1316_MAX_BQ_REG]; + int ret; + + dmi_data = dmi_first_match(dmi_platform_data); + if (!dmi_data) + return 0; + + pdata = dmi_data->driver_data; + memcpy(¶ms, pdata->bq_params, sizeof(unsigned char) * pdata->bq_params_cnt); + + props[0] = PROPERTY_ENTRY_U8_ARRAY("realtek,bq-params", params); + props[1] = PROPERTY_ENTRY_U32("realtek,bq-params-cnt", pdata->bq_params_cnt); + + fwnode = fwnode_create_software_node(props, NULL); + if (IS_ERR(fwnode)) + return PTR_ERR(fwnode); + + ret = device_add_software_node(sdw_dev, to_software_node(fwnode)); + + fwnode_handle_put(fwnode); + + return ret; +} static const struct snd_soc_dapm_widget rt1316_widgets[] = { SND_SOC_DAPM_SPK("Speaker", NULL), @@ -89,12 +165,33 @@ static int all_spk_init(struct snd_soc_pcm_runtime *rtd) return second_spk_init(rtd); } +int sof_sdw_rt1316_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link) +{ + struct mc_private *ctx = snd_soc_card_get_drvdata(card); + + if (ctx->amp_dev1) { + device_remove_software_node(ctx->amp_dev1); + put_device(ctx->amp_dev1); + } + + if (ctx->amp_dev2) { + device_remove_software_node(ctx->amp_dev2); + put_device(ctx->amp_dev2); + } + + return 0; +} + int sof_sdw_rt1316_init(struct snd_soc_card *card, const struct snd_soc_acpi_link_adr *link, struct snd_soc_dai_link *dai_links, struct sof_sdw_codec_info *info, bool playback) { + struct mc_private *ctx = snd_soc_card_get_drvdata(card); + struct device *sdw_dev1, *sdw_dev2; + int ret; + /* Count amp number and do init on playback link only. */ if (!playback) return 0; @@ -104,6 +201,28 @@ int sof_sdw_rt1316_init(struct snd_soc_card *card, dai_links->init = first_spk_init; if (info->amp_num == 2) { + sdw_dev1 = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[0].name); + if (!sdw_dev1) + return -EPROBE_DEFER; + + ret = rt1316_add_device_props(sdw_dev1); + if (ret < 0) { + put_device(sdw_dev1); + return ret; + } + ctx->amp_dev1 = sdw_dev1; + + sdw_dev2 = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[1].name); + if (!sdw_dev2) + return -EPROBE_DEFER; + + ret = rt1316_add_device_props(sdw_dev2); + if (ret < 0) { + put_device(sdw_dev2); + return ret; + } + ctx->amp_dev2 = sdw_dev2; + /* * if two 1316s are in one dai link, the init function * in this dai link will be first set for the first speaker, -- cgit v1.2.3-70-g09d2 From d608bc44181c1010eca165e895bbe630077b2e16 Mon Sep 17 00:00:00 2001 From: Gongjun Song Date: Thu, 10 Nov 2022 16:54:28 -0600 Subject: ASoC: Intel: sof_sdw: Add support for SKU 0C10 product MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SKU 0C10 product supports SoundWire capture from local microphone and two SoundWire amplifiers(no headset codec). Reviewed-by: Kai Vehmanen Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Signed-off-by: Gongjun Song Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20221110225432.144184-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index ee9857dc3135..ed4ca10b6710 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -355,6 +355,17 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { .driver_data = (void *)(SOF_SDW_TGL_HDMI | RT711_JD2), }, + /* RaptorLake devices */ + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C10"), + }, + /* No Jack */ + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + SOF_SDW_FOUR_SPK), + }, /* MeteorLake devices */ { .callback = sof_sdw_quirk_cb, -- cgit v1.2.3-70-g09d2 From 55fc03445e2c4e05169db0390ceb92d7ffea1a96 Mon Sep 17 00:00:00 2001 From: Gongjun Song Date: Thu, 10 Nov 2022 16:54:29 -0600 Subject: ASoC: Intel: soc-acpi: add SKU 0C10 SoundWire configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Audio hardware configuration of SKU 0C10 product is rt714 on link0, two rt1316s on link1 and link2 Reviewed-by: Kai Vehmanen Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Signed-off-by: Gongjun Song Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20221110225432.144184-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/common/soc-acpi-intel-rpl-match.c | 43 +++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c index 9ccf7370157b..371333ed8c16 100644 --- a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c @@ -65,6 +65,15 @@ static const struct snd_soc_acpi_adr_device rt1316_1_group1_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt1316_2_group1_adr[] = { + { + .adr = 0x000230025D131601ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "rt1316-2" + } +}; + static const struct snd_soc_acpi_adr_device rt1316_3_group1_adr[] = { { .adr = 0x000330025D131601ull, @@ -74,6 +83,15 @@ static const struct snd_soc_acpi_adr_device rt1316_3_group1_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt714_0_adr[] = { + { + .adr = 0x000030025D071401ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt714" + } +}; + static const struct snd_soc_acpi_adr_device rt714_2_adr[] = { { .adr = 0x000230025D071401ull, @@ -107,6 +125,25 @@ static const struct snd_soc_acpi_link_adr rpl_sdca_3_in_1[] = { {} }; +static const struct snd_soc_acpi_link_adr rpl_sdw_rt1316_link12_rt714_link0[] = { + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1316_1_group1_adr), + .adr_d = rt1316_1_group1_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt1316_2_group1_adr), + .adr_d = rt1316_2_group1_adr, + }, + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt714_0_adr), + .adr_d = rt714_0_adr, + }, + {} +}; + struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_machines[] = { {}, }; @@ -120,6 +157,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_sdw_machines[] = { .drv_name = "sof_sdw", .sof_tplg_filename = "sof-rpl-rt711-l0-rt1316-l13-rt714-l2.tplg", }, + { + .link_mask = 0x7, /* rt714 on link0 & two rt1316s on link1 and link2 */ + .links = rpl_sdw_rt1316_link12_rt714_link0, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-rpl-rt1316-l12-rt714-l0.tplg", + }, { .link_mask = 0x1, /* link0 required */ .links = rpl_rvp, -- cgit v1.2.3-70-g09d2 From 880bf4b47fc1810616e254738bb40fe108c01cb9 Mon Sep 17 00:00:00 2001 From: Gongjun Song Date: Thu, 10 Nov 2022 16:54:30 -0600 Subject: ASoC: Intel: sof_sdw: Add support for SKU 0C40 product MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SKU 0C40 product supports a SoundWire headset codec, SoundWire capture from local microphones and two SoundWire amplifiers. Reviewed-by: Kai Vehmanen Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Signed-off-by: Gongjun Song Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20221110225432.144184-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index ed4ca10b6710..47f743debc72 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -366,6 +366,16 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { .driver_data = (void *)(SOF_SDW_TGL_HDMI | SOF_SDW_FOUR_SPK), }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C40") + }, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + RT711_JD2 | + SOF_SDW_FOUR_SPK), + }, /* MeteorLake devices */ { .callback = sof_sdw_quirk_cb, -- cgit v1.2.3-70-g09d2 From 97b5fbf44c001a1c575550e4b40c4abd9d7db175 Mon Sep 17 00:00:00 2001 From: Gongjun Song Date: Thu, 10 Nov 2022 16:54:31 -0600 Subject: ASoC: Intel: soc-acpi: add SKU 0C40 SoundWire configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Audio hardware configuration of SKU 0C40 product is rt711 on link2, two rt1316s on link0 and link1, rt714 on link 3. Reviewed-by: Kai Vehmanen Reviewed-by: Bard Liao Reviewed-by: Péter Ujfalusi Signed-off-by: Gongjun Song Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20221110225432.144184-5-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/common/soc-acpi-intel-rpl-match.c | 66 +++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c index 371333ed8c16..7c2e94dcf8fc 100644 --- a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c @@ -56,6 +56,15 @@ static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt711_sdca_2_adr[] = { + { + .adr = 0x000230025D071101ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt711" + } +}; + static const struct snd_soc_acpi_adr_device rt1316_1_group1_adr[] = { { .adr = 0x000131025D131601ull, /* unique ID is set for some reason */ @@ -83,6 +92,24 @@ static const struct snd_soc_acpi_adr_device rt1316_3_group1_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt1316_0_group2_adr[] = { + { + .adr = 0x000030025D131601ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "rt1316-1" + } +}; + +static const struct snd_soc_acpi_adr_device rt1316_1_group2_adr[] = { + { + .adr = 0x000131025D131601ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "rt1316-2" + } +}; + static const struct snd_soc_acpi_adr_device rt714_0_adr[] = { { .adr = 0x000030025D071401ull, @@ -101,6 +128,15 @@ static const struct snd_soc_acpi_adr_device rt714_2_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt714_3_adr[] = { + { + .adr = 0x000330025D071401ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt714" + } +}; + static const struct snd_soc_acpi_link_adr rpl_sdca_3_in_1[] = { { .mask = BIT(0), @@ -125,6 +161,30 @@ static const struct snd_soc_acpi_link_adr rpl_sdca_3_in_1[] = { {} }; +static const struct snd_soc_acpi_link_adr rpl_sdw_rt711_link2_rt1316_link01_rt714_link3[] = { + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt711_sdca_2_adr), + .adr_d = rt711_sdca_2_adr, + }, + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt1316_0_group2_adr), + .adr_d = rt1316_0_group2_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1316_1_group2_adr), + .adr_d = rt1316_1_group2_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt714_3_adr), + .adr_d = rt714_3_adr, + }, + {} +}; + static const struct snd_soc_acpi_link_adr rpl_sdw_rt1316_link12_rt714_link0[] = { { .mask = BIT(1), @@ -157,6 +217,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_sdw_machines[] = { .drv_name = "sof_sdw", .sof_tplg_filename = "sof-rpl-rt711-l0-rt1316-l13-rt714-l2.tplg", }, + { + .link_mask = 0xF, /* 4 active links required */ + .links = rpl_sdw_rt711_link2_rt1316_link01_rt714_link3, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-rpl-rt711-l2-rt1316-l01-rt714-l3.tplg", + }, { .link_mask = 0x7, /* rt714 on link0 & two rt1316s on link1 and link2 */ .links = rpl_sdw_rt1316_link12_rt714_link0, -- cgit v1.2.3-70-g09d2 From 8dcc205931b0ee729641ae6b37e0866b13aa081b Mon Sep 17 00:00:00 2001 From: Yong Zhi Date: Thu, 10 Nov 2022 16:54:32 -0600 Subject: ASoC: Intel: soc-acpi: add MTL AIC SoundWire configurations Add support to the following daughter card: SDW0: MX98373 Speaker SDW2: ALC5682 Headset Share same driver data used by sof_sdw driver for mtlrvp. Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Signed-off-by: Yong Zhi Signed-off-by: Jairaj Arava Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20221110225432.144184-6-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/common/soc-acpi-intel-mtl-match.c | 59 +++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/common/soc-acpi-intel-mtl-match.c b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c index 36c361fb28a4..b1a66a0f6818 100644 --- a/sound/soc/intel/common/soc-acpi-intel-mtl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c @@ -39,6 +39,20 @@ static const struct snd_soc_acpi_endpoint single_endpoint = { .group_id = 0, }; +static const struct snd_soc_acpi_endpoint spk_l_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 0, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_r_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 1, + .group_id = 1, +}; + static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = { { .adr = 0x000030025D071101ull, @@ -48,6 +62,45 @@ static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = { } }; +static const struct snd_soc_acpi_adr_device mx8373_0_adr[] = { + { + .adr = 0x000023019F837300ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "Left" + }, + { + .adr = 0x000027019F837300ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "Right" + } +}; + +static const struct snd_soc_acpi_adr_device rt5682_2_adr[] = { + { + .adr = 0x000221025D568200ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt5682" + } +}; + +static const struct snd_soc_acpi_link_adr rt5682_link2_max98373_link0[] = { + /* Expected order: jack -> amp */ + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt5682_2_adr), + .adr_d = rt5682_2_adr, + }, + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(mx8373_0_adr), + .adr_d = mx8373_0_adr, + }, + {} +}; + static const struct snd_soc_acpi_link_adr mtl_rvp[] = { { .mask = BIT(0), @@ -84,6 +137,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = { .drv_name = "sof_sdw", .sof_tplg_filename = "sof-mtl-rt711.tplg", }, + { + .link_mask = BIT(0) | BIT(2), + .links = rt5682_link2_max98373_link0, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-mtl-sdw-rt5682-l2-max98373-l0.tplg", + }, {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_mtl_sdw_machines); -- cgit v1.2.3-70-g09d2 From 1a9a5ebe1175537dc817531fe74c5949c3a823c1 Mon Sep 17 00:00:00 2001 From: Ajye Huang Date: Tue, 8 Nov 2022 12:27:15 +0800 Subject: ASoC: Intel: sof_rt5682: add support for ALC5682I-VD with amp rt1019p This patch adds the driver data for two rt1019 speaker amplifiers on SSP1 and ALC5682I-VD on SSP0 for ADL platform. Signed-off-by: Ajye Huang Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20221108042716.2930255-2-ajye_huang@compal.corp-partner.google.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_rt5682.c | 3 +-- sound/soc/intel/common/soc-acpi-intel-adl-match.c | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index 2d0986824b3d..ffec9e4a5103 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -1080,10 +1080,9 @@ static const struct platform_device_id board_ids[] = { SOF_SSP_BT_OFFLOAD_PRESENT), }, { - .name = "adl_rt1019_rt5682s", + .name = "adl_rt1019_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_RT5682S_HEADPHONE_CODEC_PRESENT | SOF_SPEAKER_AMP_PRESENT | SOF_RT1019_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1) | diff --git a/sound/soc/intel/common/soc-acpi-intel-adl-match.c b/sound/soc/intel/common/soc-acpi-intel-adl-match.c index 9990d5502d26..3ca0a96d94de 100644 --- a/sound/soc/intel/common/soc-acpi-intel-adl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-adl-match.c @@ -489,8 +489,8 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = { .sof_tplg_filename = "sof-adl-max98360a-nau8825.tplg", }, { - .id = "RTL5682", - .drv_name = "adl_rt1019_rt5682s", + .comp_ids = &adl_rt5682_rt5682s_hp, + .drv_name = "adl_rt1019_rt5682", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &adl_rt1019p_amp, .sof_tplg_filename = "sof-adl-rt1019-rt5682.tplg", -- cgit v1.2.3-70-g09d2 From c7a79f546100300d18585506f8fd0460a874df4a Mon Sep 17 00:00:00 2001 From: Ajye Huang Date: Tue, 8 Nov 2022 12:27:16 +0800 Subject: ASoC: Intel: sof rt5682: remove the duplicate codes Remove the redundant code to prevent user confuse. Signed-off-by: Ajye Huang Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20221108042716.2930255-3-ajye_huang@compal.corp-partner.google.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_rt5682.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index ffec9e4a5103..0521b0a08b20 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -855,10 +855,6 @@ static int sof_audio_probe(struct platform_device *pdev) if (acpi_dev_present("RTL5682", NULL, -1)) sof_rt5682_quirk |= SOF_RT5682S_HEADPHONE_CODEC_PRESENT; - /* Detect the headset codec variant to support machines in DMI quirk */ - if (acpi_dev_present("RTL5682", NULL, -1)) - sof_rt5682_quirk |= SOF_RT5682S_HEADPHONE_CODEC_PRESENT; - if (soc_intel_is_byt() || soc_intel_is_cht()) { is_legacy_cpu = 1; dmic_be_num = 0; -- cgit v1.2.3-70-g09d2 From 13c459fa37c9f26e9bf884a832dd67598b5c4d3e Mon Sep 17 00:00:00 2001 From: Brent Lu Date: Thu, 17 Nov 2022 17:19:19 -0600 Subject: ASoC: Intel: sof_nau8825: support rt1015p speaker amplifier Add rt1015p speaker amplifier support with a new board info 'adl_rt1015p_nau8825' which supports NAU8825 on SSP0 and ALC1015Q on SSP1. Reviewed-by: Bard Liao Signed-off-by: Brent Lu Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20221117231919.112483-1-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_nau8825.c | 16 ++++++++++++++++ sound/soc/intel/common/soc-acpi-intel-adl-match.c | 12 ++++++++++++ 2 files changed, 28 insertions(+) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/boards/sof_nau8825.c b/sound/soc/intel/boards/sof_nau8825.c index 5585c217f78d..27880224359d 100644 --- a/sound/soc/intel/boards/sof_nau8825.c +++ b/sound/soc/intel/boards/sof_nau8825.c @@ -47,6 +47,7 @@ #define SOF_RT1019P_SPEAKER_AMP_PRESENT BIT(14) #define SOF_MAX98373_SPEAKER_AMP_PRESENT BIT(15) #define SOF_MAX98360A_SPEAKER_AMP_PRESENT BIT(16) +#define SOF_RT1015P_SPEAKER_AMP_PRESENT BIT(17) static unsigned long sof_nau8825_quirk = SOF_NAU8825_SSP_CODEC(0); @@ -483,6 +484,8 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, } else if (sof_nau8825_quirk & SOF_MAX98360A_SPEAKER_AMP_PRESENT) { max_98360a_dai_link(&links[id]); + } else if (sof_nau8825_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) { + sof_rt1015p_dai_link(&links[id]); } else { goto devm_err; } @@ -576,6 +579,8 @@ static int sof_audio_probe(struct platform_device *pdev) if (sof_nau8825_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) max_98373_set_codec_conf(&sof_audio_card_nau8825); + else if (sof_nau8825_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) + sof_rt1015p_codec_conf(&sof_audio_card_nau8825); if (sof_nau8825_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) sof_audio_card_nau8825.num_links++; @@ -642,6 +647,16 @@ static const struct platform_device_id board_ids[] = { SOF_SSP_BT_OFFLOAD_PRESENT), }, + { + .name = "adl_rt1015p_nau8825", + .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | + SOF_SPEAKER_AMP_PRESENT | + SOF_RT1015P_SPEAKER_AMP_PRESENT | + SOF_NAU8825_SSP_AMP(1) | + SOF_NAU8825_NUM_HDMIDEV(4) | + SOF_BT_OFFLOAD_SSP(2) | + SOF_SSP_BT_OFFLOAD_PRESENT), + }, { } }; MODULE_DEVICE_TABLE(platform, board_ids); @@ -663,3 +678,4 @@ MODULE_AUTHOR("Mac Chiang "); MODULE_LICENSE("GPL"); MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON); +MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON); diff --git a/sound/soc/intel/common/soc-acpi-intel-adl-match.c b/sound/soc/intel/common/soc-acpi-intel-adl-match.c index 3ca0a96d94de..60aee56f94bd 100644 --- a/sound/soc/intel/common/soc-acpi-intel-adl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-adl-match.c @@ -430,6 +430,11 @@ static const struct snd_soc_acpi_codecs adl_rt5682_rt5682s_hp = { .codecs = {"10EC5682", "RTL5682"}, }; +static const struct snd_soc_acpi_codecs adl_rt1015p_amp = { + .num_codecs = 1, + .codecs = {"RTL1015"} +}; + static const struct snd_soc_acpi_codecs adl_rt1019p_amp = { .num_codecs = 1, .codecs = {"RTL1019"} @@ -495,6 +500,13 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = { .quirk_data = &adl_rt1019p_amp, .sof_tplg_filename = "sof-adl-rt1019-rt5682.tplg", }, + { + .id = "10508825", + .drv_name = "adl_rt1015p_nau8825", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &adl_rt1015p_amp, + .sof_tplg_filename = "sof-adl-rt1015-nau8825.tplg", + }, { .id = "10508825", .drv_name = "sof_nau8825", -- cgit v1.2.3-70-g09d2 From f38d4c72cb2d68e73d3e54feb68febd6b7c4bfd2 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Fri, 18 Nov 2022 12:30:52 +0100 Subject: ASoC: Intel: avs: Initialize private data for subsequent HDA FEs HDAudio implementation found in sound/pci/hda expects a valid stream pointer in substream->runtime->private_data location. For ASoC users, that should point to a valid link stream which is assigned when BE opens. As BE borrows its runtime from FE, the information may be lost when reparenting comes into picture - see dpcm_be_reparent(). To support the DPCM reparenting functionality for HDAudio scenarios while still fulfilling expectations of HDAudio common code, have all FEs point to the same private data. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221118113052.1340593-1-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/pcm.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c index ca624fbb5c0d..b4e7514f8789 100644 --- a/sound/soc/intel/avs/pcm.c +++ b/sound/soc/intel/avs/pcm.c @@ -1394,9 +1394,29 @@ static int avs_component_hda_open(struct snd_soc_component *component, if (!rtd->dai_link->no_pcm) { struct snd_pcm_hardware hwparams = avs_pcm_hardware; + struct snd_soc_pcm_runtime *be; + struct snd_soc_dpcm *dpcm; + int dir = substream->stream; + + /* + * Support the DPCM reparenting while still fulfilling expectations of HDAudio + * common code - a valid stream pointer at substream->runtime->private_data - + * by having all FEs point to the same private data. + */ + for_each_dpcm_be(rtd, dir, dpcm) { + struct snd_pcm_substream *be_substream; + + be = dpcm->be; + if (be->dpcm[dir].users == 1) + break; + + be_substream = snd_soc_dpcm_get_substream(be, dir); + substream->runtime->private_data = be_substream->runtime->private_data; + break; + } /* RESUME unsupported for de-coupled HD-Audio capture. */ - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + if (dir == SNDRV_PCM_STREAM_CAPTURE) hwparams.info &= ~SNDRV_PCM_INFO_RESUME; return snd_soc_set_runtime_hwparams(substream, &hwparams); -- cgit v1.2.3-70-g09d2 From 041fe8858475a0337b28404ec5136f4fc583b3aa Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 18 Nov 2022 09:51:06 +0800 Subject: ASoC: Intel: sof_sdw_amp: mark coeff tables with __maybe_unused MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The same file provides two tables used in separate drivers, make them as __maybe_unused to avoid errors: sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h:163:17: error: ‘dell_0b00_bq_params’ defined but not used [-Werror=unused-const-variable=] 163 | static const u8 dell_0b00_bq_params[] = { Signed-off-by: Pierre-Louis Bossart Signed-off-by: Bard Liao Link: https://lore.kernel.org/r/20221118015106.532302-1-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h b/sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h index 82230fbb5b05..4a3e6fdbd623 100644 --- a/sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h +++ b/sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h @@ -11,7 +11,7 @@ #define RT1308_MAX_BQ_REG 480 #define RT1316_MAX_BQ_REG 580 -static const u8 dell_0a5d_bq_params[] = { +static const u8 __maybe_unused dell_0a5d_bq_params[] = { 0xb0, 0xc5, 0x00, /* address: 0xc5b0; data: 0x00 */ 0xb1, 0xc5, 0x32, 0xb2, 0xc5, 0x44, @@ -160,7 +160,7 @@ static const u8 dell_0a5d_bq_params[] = { 0x50, 0xc5, 0x01, }; -static const u8 dell_0b00_bq_params[] = { +static const u8 __maybe_unused dell_0b00_bq_params[] = { 0x03, 0xc2, 0x00, 0x04, 0xc2, 0xb2, 0x05, 0xc2, 0xe0, -- cgit v1.2.3-70-g09d2 From a9248c868c39440369c614598b2465d1a1b1cf62 Mon Sep 17 00:00:00 2001 From: Gongjun Song Date: Tue, 22 Nov 2022 13:20:52 +0800 Subject: ASoC: Intel: sof_sdw: Add support for SKU 0C4F product SKU 0C4F product supports a SoundWire headset codec, SoundWire capture from local microphones and two SoundWire amplifiers. Signed-off-by: Gongjun Song Signed-off-by: Bard Liao Link: https://lore.kernel.org/r/20221122052052.687281-1-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 172f008adea0..ffef492e3f3d 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -376,6 +376,16 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { RT711_JD2 | SOF_SDW_FOUR_SPK), }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C4F") + }, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + RT711_JD2 | + SOF_SDW_FOUR_SPK), + }, /* MeteorLake devices */ { .callback = sof_sdw_quirk_cb, -- cgit v1.2.3-70-g09d2 From e5d4d2b23aed20a7815d1b500dbcd50af1da0023 Mon Sep 17 00:00:00 2001 From: Lili Li Date: Mon, 21 Nov 2022 18:47:42 +0800 Subject: ASoC: Intel: Skylake: Fix Kconfig dependency Commit e4746d94d00c ("ASoC: Intel: Skylake: Introduce HDA codec init and exit routines") introduced HDA codec init routine which depends on SND_HDA. Select SND_SOC_HDAC_HDA unconditionally to fix following compile error: ERROR: modpost: "snd_hda_codec_device_init" [sound/soc/intel/skylake/snd-soc-skl.ko] undefined! Fixes: e4746d94d00c ("ASoC: Intel: Skylake: Introduce HDA codec init and exit routines") Reviewed-by: Junxiao Chang Suggested-by: Cezary Rojewski Signed-off-by: Lili Li Reviewed-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221121104742.1007486-1-lili.li@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index d2ca710ac3fa..ac799de4f7fd 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -177,7 +177,7 @@ config SND_SOC_INTEL_SKYLAKE_COMMON select SND_HDA_DSP_LOADER select SND_SOC_TOPOLOGY select SND_SOC_INTEL_SST - select SND_SOC_HDAC_HDA if SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC + select SND_SOC_HDAC_HDA select SND_SOC_ACPI_INTEL_MATCH select SND_INTEL_DSP_CONFIG help -- cgit v1.2.3-70-g09d2 From 8c4b3a8ea2c04d7979f378165e5c3dfa270659b6 Mon Sep 17 00:00:00 2001 From: Gongjun Song Date: Thu, 17 Nov 2022 08:27:56 +0800 Subject: ASoC: intel: sof_sdw: add rt1318 codec support. Add rt1318 sdca codec support in sof_sdw machine driver. Signed-off-by: Gongjun Song Signed-off-by: Bard Liao Link: https://lore.kernel.org/r/20221117002758.496211-2-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/Kconfig | 1 + sound/soc/intel/boards/Makefile | 4 +- sound/soc/intel/boards/sof_sdw.c | 7 ++ sound/soc/intel/boards/sof_sdw_common.h | 7 ++ sound/soc/intel/boards/sof_sdw_rt1318.c | 120 ++++++++++++++++++++++++++++++++ 5 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 sound/soc/intel/boards/sof_sdw_rt1318.c (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index aa12d7e3dd2f..a472de1909f4 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -668,6 +668,7 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH select SND_SOC_RT1308_SDW select SND_SOC_RT1308 select SND_SOC_RT1316_SDW + select SND_SOC_RT1318_SDW select SND_SOC_RT715_SDW select SND_SOC_RT715_SDCA_SDW select SND_SOC_RT5682_SDW diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile index 53458e748191..7e1a4ff77ac3 100644 --- a/sound/soc/intel/boards/Makefile +++ b/sound/soc/intel/boards/Makefile @@ -37,8 +37,8 @@ snd-soc-sof_da7219_max98373-objs := sof_da7219_max98373.o snd-soc-ehl-rt5660-objs := ehl_rt5660.o snd-soc-sof-ssp-amp-objs := sof_ssp_amp.o snd-soc-sof-sdw-objs += sof_sdw.o \ - sof_sdw_max98373.o \ - sof_sdw_rt1308.o sof_sdw_rt1316.o \ + sof_sdw_max98373.o sof_sdw_rt1308.o \ + sof_sdw_rt1316.o sof_sdw_rt1318.o \ sof_sdw_rt5682.o sof_sdw_rt700.o \ sof_sdw_rt711.o sof_sdw_rt711_sdca.o \ sof_sdw_rt715.o sof_sdw_rt715_sdca.o \ diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 172f008adea0..b86b1c5579bb 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -542,6 +542,13 @@ static struct sof_sdw_codec_info codec_info_list[] = { .exit = sof_sdw_rt1316_exit, .codec_type = SOF_SDW_CODEC_TYPE_AMP, }, + { + .part_id = 0x1318, + .direction = {true, true}, + .dai_name = "rt1318-aif", + .init = sof_sdw_rt1318_init, + .codec_type = SOF_SDW_CODEC_TYPE_AMP, + }, { .part_id = 0x714, .version_id = 3, diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h index bac93fdc8d82..54a50f7da4da 100644 --- a/sound/soc/intel/boards/sof_sdw_common.h +++ b/sound/soc/intel/boards/sof_sdw_common.h @@ -143,6 +143,13 @@ int sof_sdw_rt1316_init(struct snd_soc_card *card, bool playback); int sof_sdw_rt1316_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); +/* RT1318 support */ +int sof_sdw_rt1318_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback); + /* RT715 support */ int sof_sdw_rt715_init(struct snd_soc_card *card, const struct snd_soc_acpi_link_adr *link, diff --git a/sound/soc/intel/boards/sof_sdw_rt1318.c b/sound/soc/intel/boards/sof_sdw_rt1318.c new file mode 100644 index 000000000000..dbee4bf5c814 --- /dev/null +++ b/sound/soc/intel/boards/sof_sdw_rt1318.c @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2022 Intel Corporation + +/* + * sof_sdw_rt1318 - Helpers to handle RT1318 from generic machine driver + */ + +#include +#include +#include +#include +#include +#include +#include "sof_sdw_common.h" + +static const struct snd_soc_dapm_widget rt1318_widgets[] = { + SND_SOC_DAPM_SPK("Speaker", NULL), +}; + +/* + * dapm routes for rt1318 will be registered dynamically according + * to the number of rt1318 used. The first two entries will be registered + * for one codec case, and the last two entries are also registered + * if two 1318s are used. + */ +static const struct snd_soc_dapm_route rt1318_map[] = { + { "Speaker", NULL, "rt1318-1 SPOL" }, + { "Speaker", NULL, "rt1318-1 SPOR" }, + { "Speaker", NULL, "rt1318-2 SPOL" }, + { "Speaker", NULL, "rt1318-2 SPOR" }, +}; + +static const struct snd_kcontrol_new rt1318_controls[] = { + SOC_DAPM_PIN_SWITCH("Speaker"), +}; + +static int first_spk_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + int ret; + + card->components = devm_kasprintf(card->dev, GFP_KERNEL, + "%s spk:rt1318", + card->components); + if (!card->components) + return -ENOMEM; + + ret = snd_soc_add_card_controls(card, rt1318_controls, + ARRAY_SIZE(rt1318_controls)); + if (ret) { + dev_err(card->dev, "rt1318 controls addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_new_controls(&card->dapm, rt1318_widgets, + ARRAY_SIZE(rt1318_widgets)); + if (ret) { + dev_err(card->dev, "rt1318 widgets addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, rt1318_map, 2); + if (ret) + dev_err(rtd->dev, "failed to add first SPK map: %d\n", ret); + + return ret; +} + +static int second_spk_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + int ret; + + ret = snd_soc_dapm_add_routes(&card->dapm, rt1318_map + 2, 2); + if (ret) + dev_err(rtd->dev, "failed to add second SPK map: %d\n", ret); + + return ret; +} + +static int all_spk_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret; + + ret = first_spk_init(rtd); + if (ret) + return ret; + + return second_spk_init(rtd); +} + +int sof_sdw_rt1318_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback) +{ + /* Count amp number and do init on playback link only. */ + if (!playback) + return 0; + + info->amp_num++; + if (info->amp_num == 1) + dai_links->init = first_spk_init; + + if (info->amp_num == 2) { + /* + * if two 1318s are in one dai link, the init function + * in this dai link will be first set for the first speaker, + * and it should be reset to initialize all speakers when + * the second speaker is found. + */ + if (dai_links->init) + dai_links->init = all_spk_init; + else + dai_links->init = second_spk_init; + } + + return 0; +} -- cgit v1.2.3-70-g09d2 From d84e10da17e7fc07e758a8b8f1fd6150bcd8ba08 Mon Sep 17 00:00:00 2001 From: Gongjun Song Date: Thu, 17 Nov 2022 08:27:57 +0800 Subject: ASoC: Intel: sof_sdw: Add support for SKU 0C11 product SKU 0C11 product supports a SoundWire headset codec, SoundWire capture from local microphones and two SoundWire amplifiers. Signed-off-by: Gongjun Song Signed-off-by: Bard Liao Link: https://lore.kernel.org/r/20221117002758.496211-3-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index b86b1c5579bb..33b404299430 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -366,6 +366,16 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { .driver_data = (void *)(SOF_SDW_TGL_HDMI | SOF_SDW_FOUR_SPK), }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C11") + }, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + RT711_JD2 | + SOF_SDW_FOUR_SPK), + }, { .callback = sof_sdw_quirk_cb, .matches = { -- cgit v1.2.3-70-g09d2 From 0050e3d3d43db6a60b96eb8cbd2b9bcb0cd5db17 Mon Sep 17 00:00:00 2001 From: Gongjun Song Date: Thu, 17 Nov 2022 08:27:58 +0800 Subject: ASoC: Intel: soc-acpi: add SKU 0C11 SoundWire configuration Audio hardware configuration of SKU 0C11 product is rt711 on link0, two rt1318s on link1 and link2, rt714 on link3 Signed-off-by: Gongjun Song Signed-off-by: Bard Liao Link: https://lore.kernel.org/r/20221117002758.496211-4-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/common/soc-acpi-intel-rpl-match.c | 48 +++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c index 7c2e94dcf8fc..3c5229f41bb0 100644 --- a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c @@ -110,6 +110,24 @@ static const struct snd_soc_acpi_adr_device rt1316_1_group2_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt1318_1_group1_adr[] = { + { + .adr = 0x000131025D131801ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "rt1318-1" + } +}; + +static const struct snd_soc_acpi_adr_device rt1318_2_group1_adr[] = { + { + .adr = 0x000230025D131801ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "rt1318-2" + } +}; + static const struct snd_soc_acpi_adr_device rt714_0_adr[] = { { .adr = 0x000030025D071401ull, @@ -185,6 +203,30 @@ static const struct snd_soc_acpi_link_adr rpl_sdw_rt711_link2_rt1316_link01_rt71 {} }; +static const struct snd_soc_acpi_link_adr rpl_sdw_rt711_link0_rt1318_link12_rt714_link3[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt711_sdca_0_adr), + .adr_d = rt711_sdca_0_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1318_1_group1_adr), + .adr_d = rt1318_1_group1_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt1318_2_group1_adr), + .adr_d = rt1318_2_group1_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt714_3_adr), + .adr_d = rt714_3_adr, + }, + {} +}; + static const struct snd_soc_acpi_link_adr rpl_sdw_rt1316_link12_rt714_link0[] = { { .mask = BIT(1), @@ -223,6 +265,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_sdw_machines[] = { .drv_name = "sof_sdw", .sof_tplg_filename = "sof-rpl-rt711-l2-rt1316-l01-rt714-l3.tplg", }, + { + .link_mask = 0xF, /* 4 active links required */ + .links = rpl_sdw_rt711_link0_rt1318_link12_rt714_link3, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-rpl-rt711-l0-rt1318-l12-rt714-l3.tplg", + }, { .link_mask = 0x7, /* rt714 on link0 & two rt1316s on link1 and link2 */ .links = rpl_sdw_rt1316_link12_rt714_link0, -- cgit v1.2.3-70-g09d2 From 0848e94c3954051e1a52bb088240ed63758b309b Mon Sep 17 00:00:00 2001 From: Alicja Michalska Date: Tue, 22 Nov 2022 00:20:40 +0100 Subject: ASoC: Intel: avs: Add missing audio amplifier for KBL KBL platform is missing the definition of 'max98357a' audio amplifier. This amplifier is used on many KBL Chromebooks, for instance variant 'nami' of 'Google/poppy' baseboard. Reported-by: CoolStar Signed-off-by: Alicja Michalska Link: https://lore.kernel.org/r/Y3wHyJ/EcsLRHGr3@tora Signed-off-by: Mark Brown --- sound/soc/intel/avs/board_selection.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/board_selection.c b/sound/soc/intel/avs/board_selection.c index 01c1a5324b51..02cc1ce8f5f5 100644 --- a/sound/soc/intel/avs/board_selection.c +++ b/sound/soc/intel/avs/board_selection.c @@ -143,6 +143,14 @@ static struct snd_soc_acpi_mach avs_kbl_i2s_machines[] = { }, .tplg_filename = "max98373-tplg.bin", }, + { + .id = "MX98357A", + .drv_name = "avs_max98357a", + .mach_params = { + .i2s_link_mask = AVS_SSP(0), + }, + .tplg_filename = "max98357a-tplg.bin", + }, { .id = "DLGS7219", .drv_name = "avs_da7219", -- cgit v1.2.3-70-g09d2 From c30c8f9d51ec24b36e2c65a6307a5c8cbc5a0ebc Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 16 Nov 2022 12:55:49 +0100 Subject: ASoC: Intel: avs: Lock substream before snd_pcm_stop() snd_pcm_stop() shall be called with stream lock held to prevent any races between nonatomic streaming operations. Fixes: 2f1f570cd730 ("ASoC: Intel: avs: Coredump and recovery flow") Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221116115550.1100398-2-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/ipc.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/ipc.c b/sound/soc/intel/avs/ipc.c index 152f8d0bdf8e..af8a260093f4 100644 --- a/sound/soc/intel/avs/ipc.c +++ b/sound/soc/intel/avs/ipc.c @@ -123,7 +123,10 @@ static void avs_dsp_recovery(struct avs_dev *adev) if (!substream || !substream->runtime) continue; + /* No need for _irq() as we are in nonatomic context. */ + snd_pcm_stream_lock(substream); snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED); + snd_pcm_stream_unlock(substream); } } } -- cgit v1.2.3-70-g09d2 From f3fbb553f98563f692e356aca87d656baba910a0 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 16 Nov 2022 12:55:50 +0100 Subject: ASoC: Intel: avs: Disconnect substream if suspend or resume fails To improve performance and overall system stability, suspend/resume operations for ASoC cards always return success status and defer the actual work. Because of that, if a substream fails to resume, userspace may still attempt to invoke commands on it as from their perspective the operation completed successfully. Set substream's state to DISCONNECTED to ensure no further commands are attempted. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221116115550.1100398-3-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/pcm.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c index b4e7514f8789..70d687fa9923 100644 --- a/sound/soc/intel/avs/pcm.c +++ b/sound/soc/intel/avs/pcm.c @@ -934,8 +934,11 @@ static int avs_component_pm_op(struct snd_soc_component *component, bool be, rtd = snd_pcm_substream_chip(data->substream); if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) { ret = op(dai, data); - if (ret < 0) + if (ret < 0) { + __snd_pcm_set_state(data->substream->runtime, + SNDRV_PCM_STATE_DISCONNECTED); return ret; + } } } @@ -944,8 +947,11 @@ static int avs_component_pm_op(struct snd_soc_component *component, bool be, rtd = snd_pcm_substream_chip(data->substream); if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) { ret = op(dai, data); - if (ret < 0) + if (ret < 0) { + __snd_pcm_set_state(data->substream->runtime, + SNDRV_PCM_STATE_DISCONNECTED); return ret; + } } } } -- cgit v1.2.3-70-g09d2 From d60a197e50eca5017076b3867c1a49cb5118d597 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Fri, 25 Nov 2022 19:40:22 +0100 Subject: ASoC: Intel: bdw_rt286: Refactor jack handling Use link->exit() rather than pdev->remove() to unassign jack during card unbind procedure so codec link initialization and exit procedures are symmetrical. Also, there is no need to perform search for codec dai in suspend_pre() and resume_post() ourselves. Use snd_soc_card_get_codec_dai() instead. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221125184032.2565979-2-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bdw_rt286.c | 55 +++++++++++--------------------------- 1 file changed, 16 insertions(+), 39 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/boards/bdw_rt286.c b/sound/soc/intel/boards/bdw_rt286.c index 6b76df0e7c9b..b7687a93a923 100644 --- a/sound/soc/intel/boards/bdw_rt286.c +++ b/sound/soc/intel/boards/bdw_rt286.c @@ -73,6 +73,13 @@ static int codec_link_init(struct snd_soc_pcm_runtime *rtd) return snd_soc_component_set_jack(codec, &card_headset, NULL); } +static void codec_link_exit(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_component *codec = asoc_rtd_to_codec(rtd, 0)->component; + + snd_soc_component_set_jack(codec, NULL, NULL); +} + static int codec_link_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { @@ -165,6 +172,7 @@ static struct snd_soc_dai_link card_dai_links[] = { .nonatomic = 1, .no_pcm = 1, .init = codec_link_init, + .exit = codec_link_exit, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC, .ignore_pmdown_time = 1, .be_hw_params_fixup = codec_link_hw_params_fixup, @@ -175,43 +183,24 @@ static struct snd_soc_dai_link card_dai_links[] = { }, }; -static void bdw_rt286_disable_jack(struct snd_soc_card *card) -{ - struct snd_soc_component *component; - - for_each_card_components(card, component) { - if (!strcmp(component->name, "i2c-INT343A:00")) { - dev_dbg(component->dev, "disabling jack detect before going to suspend.\n"); - snd_soc_component_set_jack(component, NULL, NULL); - break; - } - } -} - -static int bdw_rt286_suspend(struct snd_soc_card *card) +static int card_suspend_pre(struct snd_soc_card *card) { - bdw_rt286_disable_jack(card); + struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, "rt286-aif1"); - return 0; + return snd_soc_component_set_jack(codec_dai->component, NULL, NULL); } -static int bdw_rt286_resume(struct snd_soc_card *card) +static int card_resume_post(struct snd_soc_card *card) { - struct snd_soc_component *component; - - for_each_card_components(card, component) { - if (!strcmp(component->name, "i2c-INT343A:00")) { - dev_dbg(component->dev, "enabling jack detect for resume.\n"); - snd_soc_component_set_jack(component, &card_headset, NULL); - break; - } - } + struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, "rt286-aif1"); - return 0; + return snd_soc_component_set_jack(codec_dai->component, &card_headset, NULL); } static struct snd_soc_card bdw_rt286_card = { .owner = THIS_MODULE, + .suspend_pre = card_suspend_pre, + .resume_post = card_resume_post, .dai_link = card_dai_links, .num_links = ARRAY_SIZE(card_dai_links), .controls = card_controls, @@ -221,8 +210,6 @@ static struct snd_soc_card bdw_rt286_card = { .dapm_routes = card_routes, .num_dapm_routes = ARRAY_SIZE(card_routes), .fully_routed = true, - .suspend_pre = bdw_rt286_suspend, - .resume_post = bdw_rt286_resume, }; /* Use space before codec name to simplify card ID, and simplify driver name. */ @@ -254,18 +241,8 @@ static int bdw_rt286_probe(struct platform_device *pdev) return devm_snd_soc_register_card(dev, &bdw_rt286_card); } -static int bdw_rt286_remove(struct platform_device *pdev) -{ - struct snd_soc_card *card = platform_get_drvdata(pdev); - - bdw_rt286_disable_jack(card); - - return 0; -} - static struct platform_driver bdw_rt286_driver = { .probe = bdw_rt286_probe, - .remove = bdw_rt286_remove, .driver = { .name = "bdw_rt286", .pm = &snd_soc_pm_ops -- cgit v1.2.3-70-g09d2 From 833e250ef592c3c02dda400c1c44306f74241d33 Mon Sep 17 00:00:00 2001 From: Amadeusz Sławiński Date: Fri, 25 Nov 2022 19:40:23 +0100 Subject: ASoC: Intel: avs: da7219: Refactor jack handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use link->exit() rather than pdev->remove() to unassign jack during card unbind procedure so codec link initialization and exit procedures are symmetrical. Also, there is no need to perform search for codec dai in suspend_pre() and resume_post() ourselves. Use snd_soc_card_get_codec_dai() instead. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221125184032.2565979-3-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/da7219.c | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/boards/da7219.c b/sound/soc/intel/avs/boards/da7219.c index ad86cef101cc..acd43b6108e9 100644 --- a/sound/soc/intel/avs/boards/da7219.c +++ b/sound/soc/intel/avs/boards/da7219.c @@ -72,10 +72,10 @@ static const struct snd_soc_dapm_route card_base_routes[] = { static int avs_da7219_codec_init(struct snd_soc_pcm_runtime *runtime) { - struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, 0); + struct snd_soc_component *component = codec_dai->component; struct snd_soc_card *card = runtime->card; struct snd_soc_jack *jack; - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, 0); int clk_freq; int ret; @@ -109,9 +109,12 @@ static int avs_da7219_codec_init(struct snd_soc_pcm_runtime *runtime) snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); - snd_soc_component_set_jack(component, jack, NULL); + return snd_soc_component_set_jack(component, jack, NULL); +} - return 0; +static void avs_da7219_codec_exit(struct snd_soc_pcm_runtime *rtd) +{ + snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component, NULL, NULL); } static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, @@ -146,6 +149,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in dl->id = 0; dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; dl->init = avs_da7219_codec_init; + dl->exit = avs_da7219_codec_exit; dl->nonatomic = 1; dl->no_pcm = 1; dl->dpcm_capture = 1; @@ -188,30 +192,19 @@ static int avs_create_dapm_routes(struct device *dev, int ssp_port, return 0; } -static int avs_card_set_jack(struct snd_soc_card *card, struct snd_soc_jack *jack) -{ - struct snd_soc_component *component; - - for_each_card_components(card, component) - snd_soc_component_set_jack(component, jack, NULL); - return 0; -} - -static int avs_card_remove(struct snd_soc_card *card) -{ - return avs_card_set_jack(card, NULL); -} - static int avs_card_suspend_pre(struct snd_soc_card *card) { - return avs_card_set_jack(card, NULL); + struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, DA7219_DAI_NAME); + + return snd_soc_component_set_jack(codec_dai->component, NULL, NULL); } static int avs_card_resume_post(struct snd_soc_card *card) { + struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, DA7219_DAI_NAME); struct snd_soc_jack *jack = snd_soc_card_get_drvdata(card); - return avs_card_set_jack(card, jack); + return snd_soc_component_set_jack(codec_dai->component, jack, NULL); } static int avs_da7219_probe(struct platform_device *pdev) @@ -249,7 +242,6 @@ static int avs_da7219_probe(struct platform_device *pdev) card->name = "avs_da7219"; card->dev = dev; card->owner = THIS_MODULE; - card->remove = avs_card_remove; card->suspend_pre = avs_card_suspend_pre; card->resume_post = avs_card_resume_post; card->dai_link = dai_link; -- cgit v1.2.3-70-g09d2 From 9febcd7a0180b1ea5b49cda1838aef49ef936805 Mon Sep 17 00:00:00 2001 From: Amadeusz Sławiński Date: Fri, 25 Nov 2022 19:40:24 +0100 Subject: ASoC: Intel: avs: nau8825: Refactor jack handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use link->exit() rather than pdev->remove() to unassign jack during card unbind procedure so codec link initialization and exit procedures are symmetrical. Also, there is no need to perform search for codec dai in suspend_pre() and resume_post() ourselves. Use snd_soc_card_get_codec_dai() instead. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221125184032.2565979-4-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/nau8825.c | 35 +++++++++++------------------------ 1 file changed, 11 insertions(+), 24 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/boards/nau8825.c b/sound/soc/intel/avs/boards/nau8825.c index f76909e9f990..6731d8a49076 100644 --- a/sound/soc/intel/avs/boards/nau8825.c +++ b/sound/soc/intel/avs/boards/nau8825.c @@ -79,11 +79,9 @@ static struct snd_soc_jack_pin card_headset_pins[] = { static int avs_nau8825_codec_init(struct snd_soc_pcm_runtime *runtime) { - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, 0); - struct snd_soc_component *component = codec_dai->component; + struct snd_soc_card *card = runtime->card; struct snd_soc_jack_pin *pins; struct snd_soc_jack *jack; - struct snd_soc_card *card = runtime->card; int num_pins, ret; jack = snd_soc_card_get_drvdata(card); @@ -108,11 +106,12 @@ static int avs_nau8825_codec_init(struct snd_soc_pcm_runtime *runtime) snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); - //snd_soc_component_set_jack(component, jack, NULL); - // TODO: Fix nau8825 codec to use .set_jack, like everyone else - nau8825_enable_jack_detect(component, jack); + return snd_soc_component_set_jack(asoc_rtd_to_codec(runtime, 0)->component, jack, NULL); +} - return 0; +static void avs_nau8825_codec_exit(struct snd_soc_pcm_runtime *rtd) +{ + snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component, NULL, NULL); } static int @@ -203,6 +202,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in dl->id = 0; dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; dl->init = avs_nau8825_codec_init; + dl->exit = avs_nau8825_codec_exit; dl->be_hw_params_fixup = avs_nau8825_be_fixup; dl->ops = &avs_nau8825_ops; dl->nonatomic = 1; @@ -247,23 +247,11 @@ static int avs_create_dapm_routes(struct device *dev, int ssp_port, return 0; } -static int avs_card_set_jack(struct snd_soc_card *card, struct snd_soc_jack *jack) -{ - struct snd_soc_component *component; - - for_each_card_components(card, component) - snd_soc_component_set_jack(component, jack, NULL); - return 0; -} - -static int avs_card_remove(struct snd_soc_card *card) -{ - return avs_card_set_jack(card, NULL); -} - static int avs_card_suspend_pre(struct snd_soc_card *card) { - return avs_card_set_jack(card, NULL); + struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, SKL_NUVOTON_CODEC_DAI); + + return snd_soc_component_set_jack(codec_dai->component, NULL, NULL); } static int avs_card_resume_post(struct snd_soc_card *card) @@ -280,7 +268,7 @@ static int avs_card_resume_post(struct snd_soc_card *card) codec_dai->playback_widget->active) snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_FS, 0, SND_SOC_CLOCK_IN); - return avs_card_set_jack(card, jack); + return snd_soc_component_set_jack(codec_dai->component, jack, NULL); } static int avs_nau8825_probe(struct platform_device *pdev) @@ -318,7 +306,6 @@ static int avs_nau8825_probe(struct platform_device *pdev) card->name = "avs_nau8825"; card->dev = dev; card->owner = THIS_MODULE; - card->remove = avs_card_remove; card->suspend_pre = avs_card_suspend_pre; card->resume_post = avs_card_resume_post; card->dai_link = dai_link; -- cgit v1.2.3-70-g09d2 From 58391e7ca04be3960579a51d9a47d0fbc1b1607e Mon Sep 17 00:00:00 2001 From: Amadeusz Sławiński Date: Fri, 25 Nov 2022 19:40:25 +0100 Subject: ASoC: Intel: avs: rt274: Refer to DAI name through a constant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is existing define for codec DAI name, make use of it when setting codec DAI name. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221125184032.2565979-5-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/rt274.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/boards/rt274.c b/sound/soc/intel/avs/boards/rt274.c index afef5a3ca60b..9937cfe9996e 100644 --- a/sound/soc/intel/avs/boards/rt274.c +++ b/sound/soc/intel/avs/boards/rt274.c @@ -160,7 +160,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); dl->codecs->name = devm_kasprintf(dev, GFP_KERNEL, "i2c-INT34C2:00"); - dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, "rt274-aif1"); + dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, RT274_CODEC_DAI); if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) return -ENOMEM; -- cgit v1.2.3-70-g09d2 From a08797afc1f9792b16356f59ba047114dd06a25e Mon Sep 17 00:00:00 2001 From: Amadeusz Sławiński Date: Fri, 25 Nov 2022 19:40:26 +0100 Subject: ASoC: Intel: avs: rt274: Refactor jack handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use link->exit() rather than pdev->remove() to unassign jack during card unbind procedure so codec link initialization and exit procedures are symmetrical. Also, there is no need to perform search for codec dai in suspend_pre() and resume_post() ourselves. Use snd_soc_card_get_codec_dai() instead. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221125184032.2565979-6-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/rt274.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/boards/rt274.c b/sound/soc/intel/avs/boards/rt274.c index 9937cfe9996e..6a1e121f082f 100644 --- a/sound/soc/intel/avs/boards/rt274.c +++ b/sound/soc/intel/avs/boards/rt274.c @@ -119,6 +119,11 @@ static int avs_rt274_codec_init(struct snd_soc_pcm_runtime *runtime) return 0; } +static void avs_rt274_codec_exit(struct snd_soc_pcm_runtime *rtd) +{ + snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component, NULL, NULL); +} + static int avs_rt274_be_fixup(struct snd_soc_pcm_runtime *runtime, struct snd_pcm_hw_params *params) { struct snd_interval *rate, *channels; @@ -171,6 +176,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in dl->id = 0; dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; dl->init = avs_rt274_codec_init; + dl->exit = avs_rt274_codec_exit; dl->be_hw_params_fixup = avs_rt274_be_fixup; dl->nonatomic = 1; dl->no_pcm = 1; @@ -214,30 +220,19 @@ static int avs_create_dapm_routes(struct device *dev, int ssp_port, return 0; } -static int avs_card_set_jack(struct snd_soc_card *card, struct snd_soc_jack *jack) -{ - struct snd_soc_component *component; - - for_each_card_components(card, component) - snd_soc_component_set_jack(component, jack, NULL); - return 0; -} - -static int avs_card_remove(struct snd_soc_card *card) -{ - return avs_card_set_jack(card, NULL); -} - static int avs_card_suspend_pre(struct snd_soc_card *card) { - return avs_card_set_jack(card, NULL); + struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, RT274_CODEC_DAI); + + return snd_soc_component_set_jack(codec_dai->component, NULL, NULL); } static int avs_card_resume_post(struct snd_soc_card *card) { + struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, RT274_CODEC_DAI); struct snd_soc_jack *jack = snd_soc_card_get_drvdata(card); - return avs_card_set_jack(card, jack); + return snd_soc_component_set_jack(codec_dai->component, jack, NULL); } static int avs_rt274_probe(struct platform_device *pdev) @@ -275,7 +270,6 @@ static int avs_rt274_probe(struct platform_device *pdev) card->name = "avs_rt274"; card->dev = dev; card->owner = THIS_MODULE; - card->remove = avs_card_remove; card->suspend_pre = avs_card_suspend_pre; card->resume_post = avs_card_resume_post; card->dai_link = dai_link; -- cgit v1.2.3-70-g09d2 From af8ced412d6ee680faca06700fa784bbef6de702 Mon Sep 17 00:00:00 2001 From: Amadeusz Sławiński Date: Fri, 25 Nov 2022 19:40:27 +0100 Subject: ASoC: Intel: avs: rt286: Add define for codec DAI name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Following commits will make use of it to find codec DAI, define it first. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221125184032.2565979-7-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/rt286.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/boards/rt286.c b/sound/soc/intel/avs/boards/rt286.c index e51d4e181274..7868a2d10cac 100644 --- a/sound/soc/intel/avs/boards/rt286.c +++ b/sound/soc/intel/avs/boards/rt286.c @@ -14,6 +14,8 @@ #include #include "../../../codecs/rt286.h" +#define RT286_CODEC_DAI "rt286-aif1" + static const struct snd_kcontrol_new card_controls[] = { SOC_DAPM_PIN_SWITCH("Headphone Jack"), SOC_DAPM_PIN_SWITCH("Mic Jack"), @@ -130,7 +132,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); dl->codecs->name = devm_kasprintf(dev, GFP_KERNEL, "i2c-INT343A:00"); - dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, "rt286-aif1"); + dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, RT286_CODEC_DAI); if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) return -ENOMEM; -- cgit v1.2.3-70-g09d2 From 2f292443b4c88ccd469e724d022c669349abcbb5 Mon Sep 17 00:00:00 2001 From: Amadeusz Sławiński Date: Fri, 25 Nov 2022 19:40:28 +0100 Subject: ASoC: Intel: avs: rt286: Refactor jack handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use link->exit() rather than pdev->remove() to unassign jack during card unbind procedure so codec link initialization and exit procedures are symmetrical. Also, there is no need to perform search for codec dai in suspend_pre() and resume_post() ourselves. Use snd_soc_card_get_codec_dai() instead. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221125184032.2565979-8-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/rt286.c | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/boards/rt286.c b/sound/soc/intel/avs/boards/rt286.c index 7868a2d10cac..8447b37a2a41 100644 --- a/sound/soc/intel/avs/boards/rt286.c +++ b/sound/soc/intel/avs/boards/rt286.c @@ -50,10 +50,9 @@ static struct snd_soc_jack_pin card_headset_pins[] = { static int avs_rt286_codec_init(struct snd_soc_pcm_runtime *runtime) { - struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; + struct snd_soc_card *card = runtime->card; struct snd_soc_jack_pin *pins; struct snd_soc_jack *jack; - struct snd_soc_card *card = runtime->card; int num_pins, ret; jack = snd_soc_card_get_drvdata(card); @@ -68,9 +67,12 @@ static int avs_rt286_codec_init(struct snd_soc_pcm_runtime *runtime) if (ret) return ret; - snd_soc_component_set_jack(component, jack, NULL); + return snd_soc_component_set_jack(asoc_rtd_to_codec(runtime, 0)->component, jack, NULL); +} - return 0; +static void avs_rt286_codec_exit(struct snd_soc_pcm_runtime *rtd) +{ + snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component, NULL, NULL); } static int avs_rt286_be_fixup(struct snd_soc_pcm_runtime *runtime, struct snd_pcm_hw_params *params) @@ -143,6 +145,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in dl->id = 0; dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; dl->init = avs_rt286_codec_init; + dl->exit = avs_rt286_codec_exit; dl->be_hw_params_fixup = avs_rt286_be_fixup; dl->ops = &avs_rt286_ops; dl->nonatomic = 1; @@ -187,30 +190,19 @@ static int avs_create_dapm_routes(struct device *dev, int ssp_port, return 0; } -static int avs_card_set_jack(struct snd_soc_card *card, struct snd_soc_jack *jack) -{ - struct snd_soc_component *component; - - for_each_card_components(card, component) - snd_soc_component_set_jack(component, jack, NULL); - return 0; -} - -static int avs_card_remove(struct snd_soc_card *card) -{ - return avs_card_set_jack(card, NULL); -} - static int avs_card_suspend_pre(struct snd_soc_card *card) { - return avs_card_set_jack(card, NULL); + struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, RT286_CODEC_DAI); + + return snd_soc_component_set_jack(codec_dai->component, NULL, NULL); } static int avs_card_resume_post(struct snd_soc_card *card) { + struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, RT286_CODEC_DAI); struct snd_soc_jack *jack = snd_soc_card_get_drvdata(card); - return avs_card_set_jack(card, jack); + return snd_soc_component_set_jack(codec_dai->component, jack, NULL); } static int avs_rt286_probe(struct platform_device *pdev) @@ -248,7 +240,6 @@ static int avs_rt286_probe(struct platform_device *pdev) card->name = "avs_rt286"; card->dev = dev; card->owner = THIS_MODULE; - card->remove = avs_card_remove; card->suspend_pre = avs_card_suspend_pre; card->resume_post = avs_card_resume_post; card->dai_link = dai_link; -- cgit v1.2.3-70-g09d2 From 1fa675a00a5028f4f49bd19eaab016ea2d765ba8 Mon Sep 17 00:00:00 2001 From: Amadeusz Sławiński Date: Fri, 25 Nov 2022 19:40:29 +0100 Subject: ASoC: Intel: avs: rt298: Add define for codec DAI name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Following commits will make use of it to find codec DAI, define it first. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221125184032.2565979-9-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/rt298.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/boards/rt298.c b/sound/soc/intel/avs/boards/rt298.c index 58c9d9edecf0..5570949bad8a 100644 --- a/sound/soc/intel/avs/boards/rt298.c +++ b/sound/soc/intel/avs/boards/rt298.c @@ -15,6 +15,8 @@ #include #include "../../../codecs/rt298.h" +#define RT298_CODEC_DAI "rt298-aif1" + static const struct dmi_system_id kblr_dmi_table[] = { { .matches = { @@ -147,7 +149,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); dl->codecs->name = devm_kasprintf(dev, GFP_KERNEL, "i2c-INT343A:00"); - dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, "rt298-aif1"); + dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, RT298_CODEC_DAI); if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) return -ENOMEM; -- cgit v1.2.3-70-g09d2 From 28baae9bfc1fb9fdaff2e8bd328b2a5b12a14273 Mon Sep 17 00:00:00 2001 From: Amadeusz Sławiński Date: Fri, 25 Nov 2022 19:40:30 +0100 Subject: ASoC: Intel: avs: rt298: Refactor jack handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use link->exit() rather than pdev->remove() to unassign jack during card unbind procedure so codec link initialization and exit procedures are symmetrical. Also, there is no need to perform search for codec dai in suspend_pre() and resume_post() ourselves. Use snd_soc_card_get_codec_dai() instead. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221125184032.2565979-10-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/rt298.c | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/boards/rt298.c b/sound/soc/intel/avs/boards/rt298.c index 5570949bad8a..bd25f0fde35e 100644 --- a/sound/soc/intel/avs/boards/rt298.c +++ b/sound/soc/intel/avs/boards/rt298.c @@ -61,10 +61,9 @@ static struct snd_soc_jack_pin card_headset_pins[] = { static int avs_rt298_codec_init(struct snd_soc_pcm_runtime *runtime) { - struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; + struct snd_soc_card *card = runtime->card; struct snd_soc_jack_pin *pins; struct snd_soc_jack *jack; - struct snd_soc_card *card = runtime->card; int num_pins, ret; jack = snd_soc_card_get_drvdata(card); @@ -79,9 +78,12 @@ static int avs_rt298_codec_init(struct snd_soc_pcm_runtime *runtime) if (ret) return ret; - snd_soc_component_set_jack(component, jack, NULL); + return snd_soc_component_set_jack(asoc_rtd_to_codec(runtime, 0)->component, jack, NULL); +} - return 0; +static void avs_rt298_codec_exit(struct snd_soc_pcm_runtime *rtd) +{ + snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component, NULL, NULL); } static int avs_rt298_be_fixup(struct snd_soc_pcm_runtime *runtime, struct snd_pcm_hw_params *params) @@ -163,6 +165,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in else dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; dl->init = avs_rt298_codec_init; + dl->exit = avs_rt298_codec_exit; dl->be_hw_params_fixup = avs_rt298_be_fixup; dl->ops = &avs_rt298_ops; dl->nonatomic = 1; @@ -207,30 +210,19 @@ static int avs_create_dapm_routes(struct device *dev, int ssp_port, return 0; } -static int avs_card_set_jack(struct snd_soc_card *card, struct snd_soc_jack *jack) -{ - struct snd_soc_component *component; - - for_each_card_components(card, component) - snd_soc_component_set_jack(component, jack, NULL); - return 0; -} - -static int avs_card_remove(struct snd_soc_card *card) -{ - return avs_card_set_jack(card, NULL); -} - static int avs_card_suspend_pre(struct snd_soc_card *card) { - return avs_card_set_jack(card, NULL); + struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, RT298_CODEC_DAI); + + return snd_soc_component_set_jack(codec_dai->component, NULL, NULL); } static int avs_card_resume_post(struct snd_soc_card *card) { + struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, RT298_CODEC_DAI); struct snd_soc_jack *jack = snd_soc_card_get_drvdata(card); - return avs_card_set_jack(card, jack); + return snd_soc_component_set_jack(codec_dai->component, jack, NULL); } static int avs_rt298_probe(struct platform_device *pdev) @@ -268,7 +260,6 @@ static int avs_rt298_probe(struct platform_device *pdev) card->name = "avs_rt298"; card->dev = dev; card->owner = THIS_MODULE; - card->remove = avs_card_remove; card->suspend_pre = avs_card_suspend_pre; card->resume_post = avs_card_resume_post; card->dai_link = dai_link; -- cgit v1.2.3-70-g09d2 From 19bb7c3053ee54fd7fa7635f680fba3969f4a026 Mon Sep 17 00:00:00 2001 From: Amadeusz Sławiński Date: Tue, 29 Nov 2022 19:07:37 +0100 Subject: ASoC: Intel: avs: rt5682: Add define for codec DAI name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Following commits will make use of it to find codec DAI, define it first. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221129180738.2866290-2-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/rt5682.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/boards/rt5682.c b/sound/soc/intel/avs/boards/rt5682.c index 01f9b9f0c12b..7c86c8c69dbd 100644 --- a/sound/soc/intel/avs/boards/rt5682.c +++ b/sound/soc/intel/avs/boards/rt5682.c @@ -26,6 +26,7 @@ #define AVS_RT5682_SSP_CODEC_MASK (GENMASK(2, 0)) #define AVS_RT5682_MCLK_EN BIT(3) #define AVS_RT5682_MCLK_24MHZ BIT(4) +#define AVS_RT5682_CODEC_DAI_NAME "rt5682-aif1" /* Default: MCLK on, MCLK 19.2M, SSP0 */ static unsigned long avs_rt5682_quirk = AVS_RT5682_MCLK_EN | AVS_RT5682_SSP_CODEC(0); @@ -184,7 +185,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); dl->codecs->name = devm_kasprintf(dev, GFP_KERNEL, "i2c-10EC5682:00"); - dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, "rt5682-aif1"); + dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, AVS_RT5682_CODEC_DAI_NAME); if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) return -ENOMEM; -- cgit v1.2.3-70-g09d2 From a9d8723c72eada2e303e16a3c81d43bc802fbc6d Mon Sep 17 00:00:00 2001 From: Amadeusz Sławiński Date: Tue, 29 Nov 2022 19:07:38 +0100 Subject: ASoC: Intel: avs: rt5682: Refactor jack handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use link->exit() rather than pdev->remove() to unassign jack during card unbind procedure so codec link initialization and exit procedures are symmetrical. Also, there is no need to perform search for codec dai in suspend_pre() and resume_post() ourselves. Use snd_soc_card_get_codec_dai() instead. Signed-off-by: Amadeusz Sławiński Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221129180738.2866290-3-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/boards/rt5682.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/boards/rt5682.c b/sound/soc/intel/avs/boards/rt5682.c index 7c86c8c69dbd..473e9fe5d0bf 100644 --- a/sound/soc/intel/avs/boards/rt5682.c +++ b/sound/soc/intel/avs/boards/rt5682.c @@ -120,6 +120,11 @@ static int avs_rt5682_codec_init(struct snd_soc_pcm_runtime *runtime) return 0; }; +static void avs_rt5682_codec_exit(struct snd_soc_pcm_runtime *rtd) +{ + snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component, NULL, NULL); +} + static int avs_rt5682_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -195,6 +200,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in dl->num_platforms = 1; dl->id = 0; dl->init = avs_rt5682_codec_init; + dl->exit = avs_rt5682_codec_exit; dl->ops = &avs_rt5682_ops; dl->nonatomic = 1; dl->no_pcm = 1; @@ -238,30 +244,19 @@ static int avs_create_dapm_routes(struct device *dev, int ssp_port, return 0; } -static int avs_card_set_jack(struct snd_soc_card *card, struct snd_soc_jack *jack) -{ - struct snd_soc_component *component; - - for_each_card_components(card, component) - snd_soc_component_set_jack(component, jack, NULL); - return 0; -} - -static int avs_card_remove(struct snd_soc_card *card) -{ - return avs_card_set_jack(card, NULL); -} - static int avs_card_suspend_pre(struct snd_soc_card *card) { - return avs_card_set_jack(card, NULL); + struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, AVS_RT5682_CODEC_DAI_NAME); + + return snd_soc_component_set_jack(codec_dai->component, NULL, NULL); } static int avs_card_resume_post(struct snd_soc_card *card) { + struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, AVS_RT5682_CODEC_DAI_NAME); struct snd_soc_jack *jack = snd_soc_card_get_drvdata(card); - return avs_card_set_jack(card, jack); + return snd_soc_component_set_jack(codec_dai->component, jack, NULL); } static int avs_rt5682_probe(struct platform_device *pdev) @@ -305,7 +300,6 @@ static int avs_rt5682_probe(struct platform_device *pdev) card->name = "avs_rt5682"; card->dev = dev; card->owner = THIS_MODULE; - card->remove = avs_card_remove; card->suspend_pre = avs_card_suspend_pre; card->resume_post = avs_card_resume_post; card->dai_link = dai_link; -- cgit v1.2.3-70-g09d2 From bb03099bf2253fcd1a4d57e6f5ee4e8000911e77 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Fri, 2 Dec 2022 16:28:29 +0100 Subject: ASoC: Intel: avs: Introduce avs_log_buffer_status_locked() Simplify locking of firmware log gathering by providing single location for such purpose. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221202152841.672536-5-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/apl.c | 5 +---- sound/soc/intel/avs/avs.h | 12 ++++++++++++ sound/soc/intel/avs/ipc.c | 2 +- sound/soc/intel/avs/skl.c | 7 +------ 4 files changed, 15 insertions(+), 11 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/apl.c b/sound/soc/intel/avs/apl.c index 7c8ce98eda9d..821d5a9ad25f 100644 --- a/sound/soc/intel/avs/apl.c +++ b/sound/soc/intel/avs/apl.c @@ -50,7 +50,6 @@ static int apl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 static int apl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg) { struct apl_log_buffer_layout layout; - unsigned long flags; void __iomem *addr, *buf; addr = avs_log_buffer_addr(adev, msg->log.core); @@ -59,7 +58,6 @@ static int apl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg memcpy_fromio(&layout, addr, sizeof(layout)); - spin_lock_irqsave(&adev->dbg.trace_lock, flags); if (!kfifo_initialized(&adev->dbg.trace_fifo)) /* consume the logs regardless of consumer presence */ goto update_read_ptr; @@ -78,7 +76,6 @@ static int apl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg wake_up(&adev->dbg.trace_waitq); update_read_ptr: - spin_unlock_irqrestore(&adev->dbg.trace_lock, flags); writel(layout.write_ptr, addr); return 0; } @@ -140,7 +137,7 @@ static int apl_coredump(struct avs_dev *adev, union avs_notify_msg *msg) * gathered before dumping stack */ lbs_msg.log.core = msg->ext.coredump.core_id; - avs_dsp_op(adev, log_buffer_status, &lbs_msg); + avs_log_buffer_status_locked(adev, &lbs_msg); } pos = dump + AVS_FW_REGS_SIZE; diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h index 8d05b27608fe..1c89af6240d2 100644 --- a/sound/soc/intel/avs/avs.h +++ b/sound/soc/intel/avs/avs.h @@ -344,6 +344,18 @@ unsigned int __kfifo_fromio_locked(struct kfifo *fifo, const void __iomem *src, (avs_sram_addr(adev, AVS_DEBUG_WINDOW) + __offset); \ }) +static inline int avs_log_buffer_status_locked(struct avs_dev *adev, union avs_notify_msg *msg) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&adev->dbg.trace_lock, flags); + ret = avs_dsp_op(adev, log_buffer_status, msg); + spin_unlock_irqrestore(&adev->dbg.trace_lock, flags); + + return ret; +} + struct apl_log_buffer_layout { u32 read_ptr; u32 write_ptr; diff --git a/sound/soc/intel/avs/ipc.c b/sound/soc/intel/avs/ipc.c index af8a260093f4..bdf013c3dd12 100644 --- a/sound/soc/intel/avs/ipc.c +++ b/sound/soc/intel/avs/ipc.c @@ -266,7 +266,7 @@ static void avs_dsp_process_notification(struct avs_dev *adev, u64 header) break; case AVS_NOTIFY_LOG_BUFFER_STATUS: - avs_dsp_op(adev, log_buffer_status, &msg); + avs_log_buffer_status_locked(adev, &msg); break; case AVS_NOTIFY_EXCEPTION_CAUGHT: diff --git a/sound/soc/intel/avs/skl.c b/sound/soc/intel/avs/skl.c index dc98b5cf900f..ff690e99d960 100644 --- a/sound/soc/intel/avs/skl.c +++ b/sound/soc/intel/avs/skl.c @@ -55,15 +55,11 @@ int skl_log_buffer_offset(struct avs_dev *adev, u32 core) static int skl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg) { - unsigned long flags; void __iomem *buf; u16 size, write, offset; - spin_lock_irqsave(&adev->dbg.trace_lock, flags); - if (!kfifo_initialized(&adev->dbg.trace_fifo)) { - spin_unlock_irqrestore(&adev->dbg.trace_lock, flags); + if (!kfifo_initialized(&adev->dbg.trace_fifo)) return 0; - } size = avs_log_buffer_size(adev) / 2; write = readl(avs_sram_addr(adev, AVS_FW_REGS_WINDOW) + FW_REGS_DBG_LOG_WP(msg->log.core)); @@ -74,7 +70,6 @@ skl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg) buf = avs_log_buffer_addr(adev, msg->log.core) + offset; __kfifo_fromio_locked(&adev->dbg.trace_fifo, buf, size, &adev->dbg.fifo_lock); wake_up(&adev->dbg.trace_waitq); - spin_unlock_irqrestore(&adev->dbg.trace_lock, flags); return 0; } -- cgit v1.2.3-70-g09d2 From 58029b7734ec84738aeb8fb391e625832bb6b0a6 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Fri, 2 Dec 2022 16:28:30 +0100 Subject: ASoC: Intel: avs: Drop fifo_lock Log gathering is already locked, thanks to ->trace_lock. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221202152841.672536-6-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/apl.c | 9 ++++----- sound/soc/intel/avs/avs.h | 4 +--- sound/soc/intel/avs/skl.c | 2 +- sound/soc/intel/avs/utils.c | 6 +----- 4 files changed, 7 insertions(+), 14 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/apl.c b/sound/soc/intel/avs/apl.c index 821d5a9ad25f..66672ffd95df 100644 --- a/sound/soc/intel/avs/apl.c +++ b/sound/soc/intel/avs/apl.c @@ -65,13 +65,12 @@ static int apl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg buf = apl_log_payload_addr(addr); if (layout.read_ptr > layout.write_ptr) { - __kfifo_fromio_locked(&adev->dbg.trace_fifo, buf + layout.read_ptr, - apl_log_payload_size(adev) - layout.read_ptr, - &adev->dbg.fifo_lock); + __kfifo_fromio(&adev->dbg.trace_fifo, buf + layout.read_ptr, + apl_log_payload_size(adev) - layout.read_ptr); layout.read_ptr = 0; } - __kfifo_fromio_locked(&adev->dbg.trace_fifo, buf + layout.read_ptr, - layout.write_ptr - layout.read_ptr, &adev->dbg.fifo_lock); + __kfifo_fromio(&adev->dbg.trace_fifo, buf + layout.read_ptr, + layout.write_ptr - layout.read_ptr); wake_up(&adev->dbg.trace_waitq); diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h index 1c89af6240d2..957151ecf39a 100644 --- a/sound/soc/intel/avs/avs.h +++ b/sound/soc/intel/avs/avs.h @@ -95,7 +95,6 @@ struct avs_fw_entry { struct avs_debug { struct kfifo trace_fifo; - spinlock_t fifo_lock; /* serialize I/O for trace_fifo */ spinlock_t trace_lock; /* serialize debug window I/O between each LOG_BUFFER_STATUS */ wait_queue_head_t trace_waitq; u32 aging_timer_period; @@ -331,8 +330,7 @@ void avs_unregister_all_boards(struct avs_dev *adev); /* Firmware tracing helpers */ -unsigned int __kfifo_fromio_locked(struct kfifo *fifo, const void __iomem *src, unsigned int len, - spinlock_t *lock); +unsigned int __kfifo_fromio(struct kfifo *fifo, const void __iomem *src, unsigned int len); #define avs_log_buffer_size(adev) \ ((adev)->fw_cfg.trace_log_bytes / (adev)->hw_cfg.dsp_cores) diff --git a/sound/soc/intel/avs/skl.c b/sound/soc/intel/avs/skl.c index ff690e99d960..936cd44eb73e 100644 --- a/sound/soc/intel/avs/skl.c +++ b/sound/soc/intel/avs/skl.c @@ -68,7 +68,7 @@ skl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg) /* Address is guaranteed to exist in SRAM2. */ buf = avs_log_buffer_addr(adev, msg->log.core) + offset; - __kfifo_fromio_locked(&adev->dbg.trace_fifo, buf, size, &adev->dbg.fifo_lock); + __kfifo_fromio(&adev->dbg.trace_fifo, buf, size); wake_up(&adev->dbg.trace_waitq); return 0; diff --git a/sound/soc/intel/avs/utils.c b/sound/soc/intel/avs/utils.c index 13611dee9787..75ad434d7dfb 100644 --- a/sound/soc/intel/avs/utils.c +++ b/sound/soc/intel/avs/utils.c @@ -301,14 +301,11 @@ void avs_release_firmwares(struct avs_dev *adev) } } -unsigned int __kfifo_fromio_locked(struct kfifo *fifo, const void __iomem *src, unsigned int len, - spinlock_t *lock) +unsigned int __kfifo_fromio(struct kfifo *fifo, const void __iomem *src, unsigned int len) { struct __kfifo *__fifo = &fifo->kfifo; - unsigned long flags; unsigned int l, off; - spin_lock_irqsave(lock, flags); len = min(len, kfifo_avail(fifo)); off = __fifo->in & __fifo->mask; l = min(len, kfifo_size(fifo) - off); @@ -318,7 +315,6 @@ unsigned int __kfifo_fromio_locked(struct kfifo *fifo, const void __iomem *src, /* Make sure data copied from SRAM is visible to all CPUs. */ smp_mb(); __fifo->in += len; - spin_unlock_irqrestore(lock, flags); return len; } -- cgit v1.2.3-70-g09d2 From 9e3c15beb8976771f95ba30b3da8bd35dc7188ac Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Fri, 2 Dec 2022 16:28:31 +0100 Subject: ASoC: Intel: avs: Introduce debug-context aware helpers Debug-related fields and log-dumping are useful when debugfs is enabled. Define them under CONFIG_DEBUG_FS and provide stubs when the config is disabled so that the code that makes use of these needs not to be complicated unnecessarily. Members that are duplicated by this patch will be removed by the follow up changes. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221202152841.672536-7-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/Makefile | 4 ++++ sound/soc/intel/avs/avs.h | 29 +++++++++++++++++++++++++++++ sound/soc/intel/avs/debugfs.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 sound/soc/intel/avs/debugfs.c (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/Makefile b/sound/soc/intel/avs/Makefile index 919212825f21..a211a0b7b4a8 100644 --- a/sound/soc/intel/avs/Makefile +++ b/sound/soc/intel/avs/Makefile @@ -9,6 +9,10 @@ snd-soc-avs-objs += trace.o # tell define_trace.h where to find the trace header CFLAGS_trace.o := -I$(src) +ifneq ($(CONFIG_DEBUG_FS),) +snd-soc-avs-objs += debugfs.o +endif + obj-$(CONFIG_SND_SOC_INTEL_AVS) += snd-soc-avs.o # Machine support diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h index 957151ecf39a..3687d03f87d4 100644 --- a/sound/soc/intel/avs/avs.h +++ b/sound/soc/intel/avs/avs.h @@ -9,6 +9,7 @@ #ifndef __SOUND_SOC_INTEL_AVS_H #define __SOUND_SOC_INTEL_AVS_H +#include #include #include #include @@ -146,6 +147,14 @@ struct avs_dev { struct mutex path_mutex; struct avs_debug dbg; + spinlock_t trace_lock; /* serialize debug window I/O between each LOG_BUFFER_STATUS */ +#ifdef CONFIG_DEBUG_FS + struct kfifo trace_fifo; + wait_queue_head_t trace_waitq; + u32 aging_timer_period; + u32 fifo_full_timer_period; + u32 logged_resources; /* context dependent: core or library */ +#endif }; /* from hda_bus to avs_dev */ @@ -366,4 +375,24 @@ struct apl_log_buffer_layout { #define apl_log_payload_addr(addr) \ (addr + sizeof(struct apl_log_buffer_layout)) +#ifdef CONFIG_DEBUG_FS +bool avs_logging_fw(struct avs_dev *adev); +void avs_dump_fw_log(struct avs_dev *adev, const void __iomem *src, unsigned int len); +void avs_dump_fw_log_wakeup(struct avs_dev *adev, const void __iomem *src, unsigned int len); +#else +static inline bool avs_logging_fw(struct avs_dev *adev) +{ + return false; +} + +static inline void avs_dump_fw_log(struct avs_dev *adev, const void __iomem *src, unsigned int len) +{ +} + +static inline void +avs_dump_fw_log_wakeup(struct avs_dev *adev, const void __iomem *src, unsigned int len) +{ +} +#endif + #endif /* __SOUND_SOC_INTEL_AVS_H */ diff --git a/sound/soc/intel/avs/debugfs.c b/sound/soc/intel/avs/debugfs.c new file mode 100644 index 000000000000..ac3889e21542 --- /dev/null +++ b/sound/soc/intel/avs/debugfs.c @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2021-2022 Intel Corporation. All rights reserved. +// +// Authors: Cezary Rojewski +// Amadeusz Slawinski +// + +#include +#include +#include +#include "avs.h" + +bool avs_logging_fw(struct avs_dev *adev) +{ + return kfifo_initialized(&adev->trace_fifo); +} + +void avs_dump_fw_log(struct avs_dev *adev, const void __iomem *src, unsigned int len) +{ + __kfifo_fromio(&adev->trace_fifo, src, len); +} + +void avs_dump_fw_log_wakeup(struct avs_dev *adev, const void __iomem *src, unsigned int len) +{ + avs_dump_fw_log(adev, src, len); + wake_up(&adev->trace_waitq); +} -- cgit v1.2.3-70-g09d2 From b3eefa5d8dbfe5286c3308fa706fc9c45b38fe19 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Fri, 2 Dec 2022 16:28:32 +0100 Subject: ASoC: Intel: avs: Make enable_logs() dependent on DEBUG_FS Without debug filesystem present, this code is redundant. Operations: log_buffer_status and log_buffer_offset are left as is as EXCEPTION_CAUGHT and even unexpected LOG_BUFFER_STATUS notifications may occur without user ever touching debugfs. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221202152841.672536-8-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/apl.c | 7 ++++--- sound/soc/intel/avs/avs.h | 5 +++++ sound/soc/intel/avs/messages.c | 36 +++++++++++++++++++----------------- sound/soc/intel/avs/skl.c | 7 ++++--- 4 files changed, 32 insertions(+), 23 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/apl.c b/sound/soc/intel/avs/apl.c index 66672ffd95df..beef308c9428 100644 --- a/sound/soc/intel/avs/apl.c +++ b/sound/soc/intel/avs/apl.c @@ -13,8 +13,9 @@ #include "path.h" #include "topology.h" -static int apl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_period, - u32 fifo_full_period, unsigned long resource_mask, u32 *priorities) +static int __maybe_unused +apl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_period, + u32 fifo_full_period, unsigned long resource_mask, u32 *priorities) { struct apl_log_state_info *info; u32 size, num_cores = adev->hw_cfg.dsp_cores; @@ -239,10 +240,10 @@ const struct avs_dsp_ops apl_dsp_ops = { .load_basefw = avs_hda_load_basefw, .load_lib = avs_hda_load_library, .transfer_mods = avs_hda_transfer_modules, - .enable_logs = apl_enable_logs, .log_buffer_offset = skl_log_buffer_offset, .log_buffer_status = apl_log_buffer_status, .coredump = apl_coredump, .d0ix_toggle = apl_d0ix_toggle, .set_d0ix = apl_set_d0ix, + AVS_SET_ENABLE_LOGS_OP(apl) }; diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h index 3687d03f87d4..f8f11d8b5936 100644 --- a/sound/soc/intel/avs/avs.h +++ b/sound/soc/intel/avs/avs.h @@ -376,10 +376,15 @@ struct apl_log_buffer_layout { (addr + sizeof(struct apl_log_buffer_layout)) #ifdef CONFIG_DEBUG_FS +#define AVS_SET_ENABLE_LOGS_OP(name) \ + .enable_logs = name##_enable_logs + bool avs_logging_fw(struct avs_dev *adev); void avs_dump_fw_log(struct avs_dev *adev, const void __iomem *src, unsigned int len); void avs_dump_fw_log_wakeup(struct avs_dev *adev, const void __iomem *src, unsigned int len); #else +#define AVS_SET_ENABLE_LOGS_OP(name) + static inline bool avs_logging_fw(struct avs_dev *adev) { return false; diff --git a/sound/soc/intel/avs/messages.c b/sound/soc/intel/avs/messages.c index 6b0fecbf07c3..f734d49e42be 100644 --- a/sound/soc/intel/avs/messages.c +++ b/sound/soc/intel/avs/messages.c @@ -685,6 +685,24 @@ int avs_ipc_get_modules_info(struct avs_dev *adev, struct avs_mods_info **info) return 0; } +int avs_ipc_copier_set_sink_format(struct avs_dev *adev, u16 module_id, + u8 instance_id, u32 sink_id, + const struct avs_audio_format *src_fmt, + const struct avs_audio_format *sink_fmt) +{ + struct avs_copier_sink_format cpr_fmt; + + cpr_fmt.sink_id = sink_id; + /* Firmware expects driver to resend copier's input format. */ + cpr_fmt.src_fmt = *src_fmt; + cpr_fmt.sink_fmt = *sink_fmt; + + return avs_ipc_set_large_config(adev, module_id, instance_id, + AVS_COPIER_SET_SINK_FORMAT, + (u8 *)&cpr_fmt, sizeof(cpr_fmt)); +} + +#ifdef CONFIG_DEBUG_FS int avs_ipc_set_enable_logs(struct avs_dev *adev, u8 *log_info, size_t size) { return avs_ipc_set_large_config(adev, AVS_BASEFW_MOD_ID, AVS_BASEFW_INST_ID, @@ -704,20 +722,4 @@ int avs_ipc_set_system_time(struct avs_dev *adev) return avs_ipc_set_large_config(adev, AVS_BASEFW_MOD_ID, AVS_BASEFW_INST_ID, AVS_BASEFW_SYSTEM_TIME, (u8 *)&sys_time, sizeof(sys_time)); } - -int avs_ipc_copier_set_sink_format(struct avs_dev *adev, u16 module_id, - u8 instance_id, u32 sink_id, - const struct avs_audio_format *src_fmt, - const struct avs_audio_format *sink_fmt) -{ - struct avs_copier_sink_format cpr_fmt; - - cpr_fmt.sink_id = sink_id; - /* Firmware expects driver to resend copier's input format. */ - cpr_fmt.src_fmt = *src_fmt; - cpr_fmt.sink_fmt = *sink_fmt; - - return avs_ipc_set_large_config(adev, module_id, instance_id, - AVS_COPIER_SET_SINK_FORMAT, - (u8 *)&cpr_fmt, sizeof(cpr_fmt)); -} +#endif diff --git a/sound/soc/intel/avs/skl.c b/sound/soc/intel/avs/skl.c index 936cd44eb73e..c5edb0b0df14 100644 --- a/sound/soc/intel/avs/skl.c +++ b/sound/soc/intel/avs/skl.c @@ -12,8 +12,9 @@ #include "avs.h" #include "messages.h" -static int skl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_period, - u32 fifo_full_period, unsigned long resource_mask, u32 *priorities) +static int __maybe_unused +skl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_period, + u32 fifo_full_period, unsigned long resource_mask, u32 *priorities) { struct skl_log_state_info *info; u32 size, num_cores = adev->hw_cfg.dsp_cores; @@ -111,10 +112,10 @@ const struct avs_dsp_ops skl_dsp_ops = { .load_basefw = avs_cldma_load_basefw, .load_lib = avs_cldma_load_library, .transfer_mods = avs_cldma_transfer_modules, - .enable_logs = skl_enable_logs, .log_buffer_offset = skl_log_buffer_offset, .log_buffer_status = skl_log_buffer_status, .coredump = skl_coredump, .d0ix_toggle = skl_d0ix_toggle, .set_d0ix = skl_set_d0ix, + AVS_SET_ENABLE_LOGS_OP(skl) }; -- cgit v1.2.3-70-g09d2 From f7de161fc8d5e1ebac3c361a37b1d748e7086330 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Fri, 2 Dec 2022 16:28:33 +0100 Subject: ASoC: Intel: avs: Drop usage of debug members in non-debug code Switch to debug-context aware wrappers instead of accessing debug members directly allowing for readable separation of debug and non-debug related code. Duplicates are removed along the way. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221202152841.672536-9-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/apl.c | 11 ++++------- sound/soc/intel/avs/avs.h | 16 ++-------------- sound/soc/intel/avs/debugfs.c | 18 ++++++++++++++++++ sound/soc/intel/avs/skl.c | 5 ++--- sound/soc/intel/avs/utils.c | 18 ------------------ 5 files changed, 26 insertions(+), 42 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/apl.c b/sound/soc/intel/avs/apl.c index beef308c9428..02683dce277a 100644 --- a/sound/soc/intel/avs/apl.c +++ b/sound/soc/intel/avs/apl.c @@ -59,21 +59,18 @@ static int apl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg memcpy_fromio(&layout, addr, sizeof(layout)); - if (!kfifo_initialized(&adev->dbg.trace_fifo)) + if (!avs_logging_fw(adev)) /* consume the logs regardless of consumer presence */ goto update_read_ptr; buf = apl_log_payload_addr(addr); if (layout.read_ptr > layout.write_ptr) { - __kfifo_fromio(&adev->dbg.trace_fifo, buf + layout.read_ptr, - apl_log_payload_size(adev) - layout.read_ptr); + avs_dump_fw_log(adev, buf + layout.read_ptr, + apl_log_payload_size(adev) - layout.read_ptr); layout.read_ptr = 0; } - __kfifo_fromio(&adev->dbg.trace_fifo, buf + layout.read_ptr, - layout.write_ptr - layout.read_ptr); - - wake_up(&adev->dbg.trace_waitq); + avs_dump_fw_log_wakeup(adev, buf + layout.read_ptr, layout.write_ptr - layout.read_ptr); update_read_ptr: writel(layout.write_ptr, addr); diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h index f8f11d8b5936..7a9fb27d3845 100644 --- a/sound/soc/intel/avs/avs.h +++ b/sound/soc/intel/avs/avs.h @@ -94,15 +94,6 @@ struct avs_fw_entry { struct list_head node; }; -struct avs_debug { - struct kfifo trace_fifo; - spinlock_t trace_lock; /* serialize debug window I/O between each LOG_BUFFER_STATUS */ - wait_queue_head_t trace_waitq; - u32 aging_timer_period; - u32 fifo_full_timer_period; - u32 logged_resources; /* context dependent: core or library */ -}; - /* * struct avs_dev - Intel HD-Audio driver data * @@ -146,7 +137,6 @@ struct avs_dev { spinlock_t path_list_lock; struct mutex path_mutex; - struct avs_debug dbg; spinlock_t trace_lock; /* serialize debug window I/O between each LOG_BUFFER_STATUS */ #ifdef CONFIG_DEBUG_FS struct kfifo trace_fifo; @@ -339,8 +329,6 @@ void avs_unregister_all_boards(struct avs_dev *adev); /* Firmware tracing helpers */ -unsigned int __kfifo_fromio(struct kfifo *fifo, const void __iomem *src, unsigned int len); - #define avs_log_buffer_size(adev) \ ((adev)->fw_cfg.trace_log_bytes / (adev)->hw_cfg.dsp_cores) @@ -356,9 +344,9 @@ static inline int avs_log_buffer_status_locked(struct avs_dev *adev, union avs_n unsigned long flags; int ret; - spin_lock_irqsave(&adev->dbg.trace_lock, flags); + spin_lock_irqsave(&adev->trace_lock, flags); ret = avs_dsp_op(adev, log_buffer_status, msg); - spin_unlock_irqrestore(&adev->dbg.trace_lock, flags); + spin_unlock_irqrestore(&adev->trace_lock, flags); return ret; } diff --git a/sound/soc/intel/avs/debugfs.c b/sound/soc/intel/avs/debugfs.c index ac3889e21542..78705bcb09fb 100644 --- a/sound/soc/intel/avs/debugfs.c +++ b/sound/soc/intel/avs/debugfs.c @@ -11,6 +11,24 @@ #include #include "avs.h" +static unsigned int __kfifo_fromio(struct kfifo *fifo, const void __iomem *src, unsigned int len) +{ + struct __kfifo *__fifo = &fifo->kfifo; + unsigned int l, off; + + len = min(len, kfifo_avail(fifo)); + off = __fifo->in & __fifo->mask; + l = min(len, kfifo_size(fifo) - off); + + memcpy_fromio(__fifo->data + off, src, l); + memcpy_fromio(__fifo->data, src + l, len - l); + /* Make sure data copied from SRAM is visible to all CPUs. */ + smp_mb(); + __fifo->in += len; + + return len; +} + bool avs_logging_fw(struct avs_dev *adev) { return kfifo_initialized(&adev->trace_fifo); diff --git a/sound/soc/intel/avs/skl.c b/sound/soc/intel/avs/skl.c index c5edb0b0df14..6bb8bbc70442 100644 --- a/sound/soc/intel/avs/skl.c +++ b/sound/soc/intel/avs/skl.c @@ -59,7 +59,7 @@ skl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg) void __iomem *buf; u16 size, write, offset; - if (!kfifo_initialized(&adev->dbg.trace_fifo)) + if (!avs_logging_fw(adev)) return 0; size = avs_log_buffer_size(adev) / 2; @@ -69,8 +69,7 @@ skl_log_buffer_status(struct avs_dev *adev, union avs_notify_msg *msg) /* Address is guaranteed to exist in SRAM2. */ buf = avs_log_buffer_addr(adev, msg->log.core) + offset; - __kfifo_fromio(&adev->dbg.trace_fifo, buf, size); - wake_up(&adev->dbg.trace_waitq); + avs_dump_fw_log_wakeup(adev, buf, size); return 0; } diff --git a/sound/soc/intel/avs/utils.c b/sound/soc/intel/avs/utils.c index 75ad434d7dfb..82416b86662d 100644 --- a/sound/soc/intel/avs/utils.c +++ b/sound/soc/intel/avs/utils.c @@ -300,21 +300,3 @@ void avs_release_firmwares(struct avs_dev *adev) kfree(entry); } } - -unsigned int __kfifo_fromio(struct kfifo *fifo, const void __iomem *src, unsigned int len) -{ - struct __kfifo *__fifo = &fifo->kfifo; - unsigned int l, off; - - len = min(len, kfifo_avail(fifo)); - off = __fifo->in & __fifo->mask; - l = min(len, kfifo_size(fifo) - off); - - memcpy_fromio(__fifo->data + off, src, l); - memcpy_fromio(__fifo->data, src + l, len - l); - /* Make sure data copied from SRAM is visible to all CPUs. */ - smp_mb(); - __fifo->in += len; - - return len; -} -- cgit v1.2.3-70-g09d2 From dab8d000e25c3e91154efca287434a4f78ab65d2 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Fri, 2 Dec 2022 16:28:34 +0100 Subject: ASoC: Intel: avs: Add data probing requests Data probing is a cAVS firmware functionality that allows for data extraction and injection directly from or to DMA stream. To support it, new functions and types are added. These facilitate communication with the firmware. Total of eight IPCs: - probe module initialization and cleanup - addition and removal of probe points - addition and removal of injection DMAs - dumping list of currently connected probe points or enlisted DMAs Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221202152841.672536-10-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/Makefile | 2 +- sound/soc/intel/avs/messages.c | 78 ++++++++++++++++++++++++++++++++++++++++++ sound/soc/intel/avs/messages.h | 53 ++++++++++++++++++++++++++++ sound/soc/intel/avs/probes.c | 46 +++++++++++++++++++++++++ 4 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 sound/soc/intel/avs/probes.c (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/Makefile b/sound/soc/intel/avs/Makefile index a211a0b7b4a8..1c6924a1ebca 100644 --- a/sound/soc/intel/avs/Makefile +++ b/sound/soc/intel/avs/Makefile @@ -10,7 +10,7 @@ snd-soc-avs-objs += trace.o CFLAGS_trace.o := -I$(src) ifneq ($(CONFIG_DEBUG_FS),) -snd-soc-avs-objs += debugfs.o +snd-soc-avs-objs += probes.o debugfs.o endif obj-$(CONFIG_SND_SOC_INTEL_AVS) += snd-soc-avs.o diff --git a/sound/soc/intel/avs/messages.c b/sound/soc/intel/avs/messages.c index f734d49e42be..e11ae4246416 100644 --- a/sound/soc/intel/avs/messages.c +++ b/sound/soc/intel/avs/messages.c @@ -722,4 +722,82 @@ int avs_ipc_set_system_time(struct avs_dev *adev) return avs_ipc_set_large_config(adev, AVS_BASEFW_MOD_ID, AVS_BASEFW_INST_ID, AVS_BASEFW_SYSTEM_TIME, (u8 *)&sys_time, sizeof(sys_time)); } + +int avs_ipc_probe_get_dma(struct avs_dev *adev, struct avs_probe_dma **dmas, size_t *num_dmas) +{ + size_t payload_size; + u32 module_id; + u8 *payload; + int ret; + + module_id = avs_get_module_id(adev, &AVS_PROBE_MOD_UUID); + + ret = avs_ipc_get_large_config(adev, module_id, AVS_PROBE_INST_ID, AVS_PROBE_INJECTION_DMA, + NULL, 0, &payload, &payload_size); + if (ret) + return ret; + + *dmas = (struct avs_probe_dma *)payload; + *num_dmas = payload_size / sizeof(**dmas); + + return 0; +} + +int avs_ipc_probe_attach_dma(struct avs_dev *adev, struct avs_probe_dma *dmas, size_t num_dmas) +{ + u32 module_id = avs_get_module_id(adev, &AVS_PROBE_MOD_UUID); + + return avs_ipc_set_large_config(adev, module_id, AVS_PROBE_INST_ID, AVS_PROBE_INJECTION_DMA, + (u8 *)dmas, array_size(sizeof(*dmas), num_dmas)); +} + +int avs_ipc_probe_detach_dma(struct avs_dev *adev, union avs_connector_node_id *node_ids, + size_t num_node_ids) +{ + u32 module_id = avs_get_module_id(adev, &AVS_PROBE_MOD_UUID); + + return avs_ipc_set_large_config(adev, module_id, AVS_PROBE_INST_ID, + AVS_PROBE_INJECTION_DMA_DETACH, (u8 *)node_ids, + array_size(sizeof(*node_ids), num_node_ids)); +} + +int avs_ipc_probe_get_points(struct avs_dev *adev, struct avs_probe_point_desc **descs, + size_t *num_descs) +{ + size_t payload_size; + u32 module_id; + u8 *payload; + int ret; + + module_id = avs_get_module_id(adev, &AVS_PROBE_MOD_UUID); + + ret = avs_ipc_get_large_config(adev, module_id, AVS_PROBE_INST_ID, AVS_PROBE_POINTS, NULL, + 0, &payload, &payload_size); + if (ret) + return ret; + + *descs = (struct avs_probe_point_desc *)payload; + *num_descs = payload_size / sizeof(**descs); + + return 0; +} + +int avs_ipc_probe_connect_points(struct avs_dev *adev, struct avs_probe_point_desc *descs, + size_t num_descs) +{ + u32 module_id = avs_get_module_id(adev, &AVS_PROBE_MOD_UUID); + + return avs_ipc_set_large_config(adev, module_id, AVS_PROBE_INST_ID, AVS_PROBE_POINTS, + (u8 *)descs, array_size(sizeof(*descs), num_descs)); +} + +int avs_ipc_probe_disconnect_points(struct avs_dev *adev, union avs_probe_point_id *ids, + size_t num_ids) +{ + u32 module_id = avs_get_module_id(adev, &AVS_PROBE_MOD_UUID); + + return avs_ipc_set_large_config(adev, module_id, AVS_PROBE_INST_ID, + AVS_PROBE_POINTS_DISCONNECT, (u8 *)ids, + array_size(sizeof(*ids), num_ids)); +} #endif diff --git a/sound/soc/intel/avs/messages.h b/sound/soc/intel/avs/messages.h index 02b3b7a74783..9dd835527e02 100644 --- a/sound/soc/intel/avs/messages.h +++ b/sound/soc/intel/avs/messages.h @@ -802,4 +802,57 @@ int avs_ipc_copier_set_sink_format(struct avs_dev *adev, u16 module_id, const struct avs_audio_format *src_fmt, const struct avs_audio_format *sink_fmt); +#define AVS_PROBE_INST_ID 0 + +enum avs_probe_runtime_param { + AVS_PROBE_INJECTION_DMA = 1, + AVS_PROBE_INJECTION_DMA_DETACH, + AVS_PROBE_POINTS, + AVS_PROBE_POINTS_DISCONNECT, +}; + +struct avs_probe_dma { + union avs_connector_node_id node_id; + u32 dma_buffer_size; +} __packed; + +enum avs_probe_type { + AVS_PROBE_TYPE_INPUT = 0, + AVS_PROBE_TYPE_OUTPUT, + AVS_PROBE_TYPE_INTERNAL +}; + +union avs_probe_point_id { + u32 value; + struct { + u32 module_id:16; + u32 instance_id:8; + u32 type:2; + u32 index:6; + } id; +} __packed; + +enum avs_connection_purpose { + AVS_CONNECTION_PURPOSE_EXTRACT = 0, + AVS_CONNECTION_PURPOSE_INJECT, + AVS_CONNECTION_PURPOSE_INJECT_REEXTRACT, +}; + +struct avs_probe_point_desc { + union avs_probe_point_id id; + u32 purpose; + union avs_connector_node_id node_id; +} __packed; + +int avs_ipc_probe_get_dma(struct avs_dev *adev, struct avs_probe_dma **dmas, size_t *num_dmas); +int avs_ipc_probe_attach_dma(struct avs_dev *adev, struct avs_probe_dma *dmas, size_t num_dmas); +int avs_ipc_probe_detach_dma(struct avs_dev *adev, union avs_connector_node_id *node_ids, + size_t num_node_ids); +int avs_ipc_probe_get_points(struct avs_dev *adev, struct avs_probe_point_desc **descs, + size_t *num_descs); +int avs_ipc_probe_connect_points(struct avs_dev *adev, struct avs_probe_point_desc *descs, + size_t num_descs); +int avs_ipc_probe_disconnect_points(struct avs_dev *adev, union avs_probe_point_id *ids, + size_t num_ids); + #endif /* __SOUND_SOC_INTEL_AVS_MSGS_H */ diff --git a/sound/soc/intel/avs/probes.c b/sound/soc/intel/avs/probes.c new file mode 100644 index 000000000000..339bad6fec22 --- /dev/null +++ b/sound/soc/intel/avs/probes.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2021-2022 Intel Corporation. All rights reserved. +// +// Authors: Cezary Rojewski +// Amadeusz Slawinski +// + +#include "avs.h" +#include "messages.h" + +__maybe_unused +static int avs_dsp_init_probe(struct avs_dev *adev, union avs_connector_node_id node_id, + size_t buffer_size) + +{ + struct avs_probe_cfg cfg = {{0}}; + struct avs_module_entry mentry; + u16 dummy; + + avs_get_module_entry(adev, &AVS_PROBE_MOD_UUID, &mentry); + + /* + * Probe module uses no cycles, audio data format and input and output + * frame sizes are unused. It is also not owned by any pipeline. + */ + cfg.base.ibs = 1; + /* BSS module descriptor is always segment of index=2. */ + cfg.base.is_pages = mentry.segments[2].flags.length; + cfg.gtw_cfg.node_id = node_id; + cfg.gtw_cfg.dma_buffer_size = buffer_size; + + return avs_dsp_init_module(adev, mentry.module_id, INVALID_PIPELINE_ID, 0, 0, &cfg, + sizeof(cfg), &dummy); +} + +__maybe_unused +static void avs_dsp_delete_probe(struct avs_dev *adev) +{ + struct avs_module_entry mentry; + + avs_get_module_entry(adev, &AVS_PROBE_MOD_UUID, &mentry); + + /* There is only ever one probe module instance. */ + avs_dsp_delete_module(adev, mentry.module_id, 0, INVALID_PIPELINE_ID, 0); +} -- cgit v1.2.3-70-g09d2 From 700462f55493c6831ad71b209eaebe310dcf11fd Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Fri, 2 Dec 2022 16:28:35 +0100 Subject: ASoC: Intel: avs: Probe compress operations Add compress operations handlers for data extraction through probes. A single HDAudio stream is enlisted for said purpose. Operations follow same protocol as for standard PCM streaming on HOST side. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221202152841.672536-11-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/Kconfig | 1 + sound/soc/intel/avs/avs.h | 3 + sound/soc/intel/avs/probes.c | 224 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 225 insertions(+), 3 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index ac799de4f7fd..4b9e498e3303 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -217,6 +217,7 @@ config SND_SOC_INTEL_AVS select SND_SOC_ACPI if ACPI select SND_SOC_TOPOLOGY select SND_SOC_HDA + select SND_SOC_COMPRESS if DEBUG_FS select SND_HDA_EXT_CORE select SND_HDA_DSP_LOADER select SND_INTEL_DSP_CONFIG diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h index 7a9fb27d3845..e5e7c72eb511 100644 --- a/sound/soc/intel/avs/avs.h +++ b/sound/soc/intel/avs/avs.h @@ -144,6 +144,9 @@ struct avs_dev { u32 aging_timer_period; u32 fifo_full_timer_period; u32 logged_resources; /* context dependent: core or library */ + /* probes */ + struct hdac_ext_stream *extractor; + unsigned int num_probe_streams; #endif }; diff --git a/sound/soc/intel/avs/probes.c b/sound/soc/intel/avs/probes.c index 339bad6fec22..e90284ec8500 100644 --- a/sound/soc/intel/avs/probes.c +++ b/sound/soc/intel/avs/probes.c @@ -6,13 +6,15 @@ // Amadeusz Slawinski // +#include +#include +#include +#include #include "avs.h" #include "messages.h" -__maybe_unused static int avs_dsp_init_probe(struct avs_dev *adev, union avs_connector_node_id node_id, size_t buffer_size) - { struct avs_probe_cfg cfg = {{0}}; struct avs_module_entry mentry; @@ -34,7 +36,6 @@ static int avs_dsp_init_probe(struct avs_dev *adev, union avs_connector_node_id sizeof(cfg), &dummy); } -__maybe_unused static void avs_dsp_delete_probe(struct avs_dev *adev) { struct avs_module_entry mentry; @@ -44,3 +45,220 @@ static void avs_dsp_delete_probe(struct avs_dev *adev) /* There is only ever one probe module instance. */ avs_dsp_delete_module(adev, mentry.module_id, 0, INVALID_PIPELINE_ID, 0); } + +static inline struct hdac_ext_stream *avs_compr_get_host_stream(struct snd_compr_stream *cstream) +{ + return cstream->runtime->private_data; +} + +static int avs_probe_compr_open(struct snd_compr_stream *cstream, struct snd_soc_dai *dai) +{ + struct avs_dev *adev = to_avs_dev(dai->dev); + struct hdac_bus *bus = &adev->base.core; + struct hdac_ext_stream *host_stream; + + if (adev->extractor) { + dev_err(dai->dev, "Cannot open more than one extractor stream\n"); + return -EEXIST; + } + + host_stream = snd_hdac_ext_cstream_assign(bus, cstream); + if (!host_stream) { + dev_err(dai->dev, "Failed to assign HDAudio stream for extraction\n"); + return -EBUSY; + } + + adev->extractor = host_stream; + hdac_stream(host_stream)->curr_pos = 0; + cstream->runtime->private_data = host_stream; + + return 0; +} + +static int avs_probe_compr_free(struct snd_compr_stream *cstream, struct snd_soc_dai *dai) +{ + struct hdac_ext_stream *host_stream = avs_compr_get_host_stream(cstream); + struct avs_dev *adev = to_avs_dev(dai->dev); + struct avs_probe_point_desc *desc; + /* Extractor node identifier. */ + unsigned int vindex = INVALID_NODE_ID.vindex; + size_t num_desc; + int i, ret; + + /* Disconnect all probe points. */ + ret = avs_ipc_probe_get_points(adev, &desc, &num_desc); + if (ret) { + dev_err(dai->dev, "get probe points failed: %d\n", ret); + ret = AVS_IPC_RET(ret); + goto exit; + } + + for (i = 0; i < num_desc; i++) + if (desc[i].node_id.vindex == vindex) + avs_ipc_probe_disconnect_points(adev, &desc[i].id, 1); + kfree(desc); + +exit: + if (adev->num_probe_streams) { + adev->num_probe_streams--; + if (!adev->num_probe_streams) { + avs_dsp_delete_probe(adev); + avs_dsp_enable_d0ix(adev); + } + } + + snd_hdac_stream_cleanup(hdac_stream(host_stream)); + hdac_stream(host_stream)->prepared = 0; + snd_hdac_ext_stream_release(host_stream, HDAC_EXT_STREAM_TYPE_HOST); + + snd_compr_free_pages(cstream); + adev->extractor = NULL; + + return ret; +} + +static int avs_probe_compr_set_params(struct snd_compr_stream *cstream, + struct snd_compr_params *params, struct snd_soc_dai *dai) +{ + struct hdac_ext_stream *host_stream = avs_compr_get_host_stream(cstream); + struct snd_compr_runtime *rtd = cstream->runtime; + struct avs_dev *adev = to_avs_dev(dai->dev); + /* compr params do not store bit depth, default to S32_LE. */ + snd_pcm_format_t format = SNDRV_PCM_FORMAT_S32_LE; + unsigned int format_val; + int bps, ret; + + hdac_stream(host_stream)->bufsize = 0; + hdac_stream(host_stream)->period_bytes = 0; + hdac_stream(host_stream)->format_val = 0; + cstream->dma_buffer.dev.type = SNDRV_DMA_TYPE_DEV_SG; + cstream->dma_buffer.dev.dev = adev->dev; + + ret = snd_compr_malloc_pages(cstream, rtd->buffer_size); + if (ret < 0) + return ret; + bps = snd_pcm_format_physical_width(format); + if (bps < 0) + return bps; + format_val = snd_hdac_calc_stream_format(params->codec.sample_rate, params->codec.ch_out, + format, bps, 0); + ret = snd_hdac_stream_set_params(hdac_stream(host_stream), format_val); + if (ret < 0) + return ret; + ret = snd_hdac_stream_setup(hdac_stream(host_stream)); + if (ret < 0) + return ret; + + hdac_stream(host_stream)->prepared = 1; + + if (!adev->num_probe_streams) { + union avs_connector_node_id node_id; + + /* D0ix not allowed during probing. */ + ret = avs_dsp_disable_d0ix(adev); + if (ret) + return ret; + + node_id.vindex = hdac_stream(host_stream)->stream_tag - 1; + node_id.dma_type = AVS_DMA_HDA_HOST_INPUT; + + ret = avs_dsp_init_probe(adev, node_id, rtd->dma_bytes); + if (ret < 0) { + dev_err(dai->dev, "probe init failed: %d\n", ret); + avs_dsp_enable_d0ix(adev); + return ret; + } + } + + adev->num_probe_streams++; + return 0; +} + +static int avs_probe_compr_trigger(struct snd_compr_stream *cstream, int cmd, + struct snd_soc_dai *dai) +{ + struct hdac_ext_stream *host_stream = avs_compr_get_host_stream(cstream); + struct avs_dev *adev = to_avs_dev(dai->dev); + struct hdac_bus *bus = &adev->base.core; + unsigned long cookie; + + if (!hdac_stream(host_stream)->prepared) + return -EPIPE; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + case SNDRV_PCM_TRIGGER_RESUME: + spin_lock_irqsave(&bus->reg_lock, cookie); + snd_hdac_stream_start(hdac_stream(host_stream), true); + spin_unlock_irqrestore(&bus->reg_lock, cookie); + break; + + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_STOP: + spin_lock_irqsave(&bus->reg_lock, cookie); + snd_hdac_stream_stop(hdac_stream(host_stream)); + spin_unlock_irqrestore(&bus->reg_lock, cookie); + break; + + default: + return -EINVAL; + } + + return 0; +} + +static int avs_probe_compr_pointer(struct snd_compr_stream *cstream, + struct snd_compr_tstamp *tstamp, struct snd_soc_dai *dai) +{ + struct hdac_ext_stream *host_stream = avs_compr_get_host_stream(cstream); + struct snd_soc_pcm_stream *pstream; + + pstream = &dai->driver->capture; + tstamp->copied_total = hdac_stream(host_stream)->curr_pos; + tstamp->sampling_rate = snd_pcm_rate_bit_to_rate(pstream->rates); + + return 0; +} + +static int avs_probe_compr_copy(struct snd_soc_component *comp, struct snd_compr_stream *cstream, + char __user *buf, size_t count) +{ + struct snd_compr_runtime *rtd = cstream->runtime; + unsigned int offset, n; + void *ptr; + int ret; + + if (count > rtd->buffer_size) + count = rtd->buffer_size; + + div_u64_rem(rtd->total_bytes_transferred, rtd->buffer_size, &offset); + ptr = rtd->dma_area + offset; + n = rtd->buffer_size - offset; + + if (count < n) { + ret = copy_to_user(buf, ptr, count); + } else { + ret = copy_to_user(buf, ptr, n); + ret += copy_to_user(buf + n, rtd->dma_area, count - n); + } + + if (ret) + return count - ret; + return count; +} + +__maybe_unused +static const struct snd_soc_cdai_ops avs_probe_dai_ops = { + .startup = avs_probe_compr_open, + .shutdown = avs_probe_compr_free, + .set_params = avs_probe_compr_set_params, + .trigger = avs_probe_compr_trigger, + .pointer = avs_probe_compr_pointer, +}; + +__maybe_unused +static const struct snd_compress_ops avs_probe_compress_ops = { + .copy = avs_probe_compr_copy, +}; -- cgit v1.2.3-70-g09d2 From ed914a2a45a45e7d8f900ae8997ca4573792afcc Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Fri, 2 Dec 2022 16:28:36 +0100 Subject: ASoC: Intel: avs: Data probing soc-component Define stub component for data probing. Stub as most operations from standard PCM case do not apply here. Specific bits are CPU DAIs and compress_ops. FE DAIs can link against these new CPU DAI to create new compress devices. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221202152841.672536-12-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/avs.h | 10 +++++++++ sound/soc/intel/avs/pcm.c | 6 ++--- sound/soc/intel/avs/probes.c | 53 ++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 64 insertions(+), 5 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h index e5e7c72eb511..e19d8d89455d 100644 --- a/sound/soc/intel/avs/avs.h +++ b/sound/soc/intel/avs/avs.h @@ -322,6 +322,9 @@ struct avs_soc_component { extern const struct snd_soc_dai_ops avs_dai_fe_ops; +int avs_soc_component_register(struct device *dev, const char *name, + const struct snd_soc_component_driver *drv, + struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais); int avs_dmic_platform_register(struct avs_dev *adev, const char *name); int avs_i2s_platform_register(struct avs_dev *adev, const char *name, unsigned long port_mask, unsigned long *tdms); @@ -373,6 +376,8 @@ struct apl_log_buffer_layout { bool avs_logging_fw(struct avs_dev *adev); void avs_dump_fw_log(struct avs_dev *adev, const void __iomem *src, unsigned int len); void avs_dump_fw_log_wakeup(struct avs_dev *adev, const void __iomem *src, unsigned int len); + +int avs_probe_platform_register(struct avs_dev *adev, const char *name); #else #define AVS_SET_ENABLE_LOGS_OP(name) @@ -389,6 +394,11 @@ static inline void avs_dump_fw_log_wakeup(struct avs_dev *adev, const void __iomem *src, unsigned int len) { } + +static inline int avs_probe_platform_register(struct avs_dev *adev, const char *name) +{ + return 0; +} #endif #endif /* __SOUND_SOC_INTEL_AVS_H */ diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c index 70d687fa9923..f930c5e86a84 100644 --- a/sound/soc/intel/avs/pcm.c +++ b/sound/soc/intel/avs/pcm.c @@ -1126,9 +1126,9 @@ static const struct snd_soc_component_driver avs_component_driver = { .topology_name_prefix = "intel/avs", }; -static int avs_soc_component_register(struct device *dev, const char *name, - const struct snd_soc_component_driver *drv, - struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais) +int avs_soc_component_register(struct device *dev, const char *name, + const struct snd_soc_component_driver *drv, + struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais) { struct avs_soc_component *acomp; int ret; diff --git a/sound/soc/intel/avs/probes.c b/sound/soc/intel/avs/probes.c index e90284ec8500..29d63f2a9616 100644 --- a/sound/soc/intel/avs/probes.c +++ b/sound/soc/intel/avs/probes.c @@ -249,7 +249,6 @@ static int avs_probe_compr_copy(struct snd_soc_component *comp, struct snd_compr return count; } -__maybe_unused static const struct snd_soc_cdai_ops avs_probe_dai_ops = { .startup = avs_probe_compr_open, .shutdown = avs_probe_compr_free, @@ -258,7 +257,57 @@ static const struct snd_soc_cdai_ops avs_probe_dai_ops = { .pointer = avs_probe_compr_pointer, }; -__maybe_unused static const struct snd_compress_ops avs_probe_compress_ops = { .copy = avs_probe_compr_copy, }; + +static struct snd_soc_dai_driver probe_cpu_dais[] = { +{ + .name = "Probe Extraction CPU DAI", + .compress_new = snd_soc_new_compress, + .cops = &avs_probe_dai_ops, + .capture = { + .stream_name = "Probe Extraction", + .channels_min = 1, + .channels_max = 8, + .rates = SNDRV_PCM_RATE_48000, + .rate_min = 48000, + .rate_max = 48000, + }, +}, +}; + +static int avs_probe_component_probe(struct snd_soc_component *component) +{ + struct avs_soc_component *acomp = to_avs_soc_component(component); + struct avs_dev *adev = to_avs_dev(component->dev); + + mutex_lock(&adev->comp_list_mutex); + list_add_tail(&acomp->node, &adev->comp_list); + mutex_unlock(&adev->comp_list_mutex); + return 0; +} + +static void avs_probe_component_remove(struct snd_soc_component *component) +{ + struct avs_soc_component *acomp = to_avs_soc_component(component); + struct avs_dev *adev = to_avs_dev(component->dev); + + mutex_lock(&adev->comp_list_mutex); + list_del(&acomp->node); + mutex_unlock(&adev->comp_list_mutex); +} + +static const struct snd_soc_component_driver avs_probe_component_driver = { + .name = "avs-probe-compr", + .probe = avs_probe_component_probe, + .remove = avs_probe_component_remove, + .compress_ops = &avs_probe_compress_ops, + .module_get_upon_open = 1, /* increment refcount when a stream is opened */ +}; + +int avs_probe_platform_register(struct avs_dev *adev, const char *name) +{ + return avs_soc_component_register(adev->dev, name, &avs_probe_component_driver, + probe_cpu_dais, ARRAY_SIZE(probe_cpu_dais)); +} -- cgit v1.2.3-70-g09d2 From e17527e167ae5bd71fc9cb67da4e73bbb050e6f7 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Fri, 2 Dec 2022 16:28:37 +0100 Subject: ASoC: Intel: avs: Add probe machine board Stub machine board driver with no custom DAPM routes and single FE DAI link for userspace to interact with. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221202152841.672536-13-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/board_selection.c | 33 ++++++++++++++++++ sound/soc/intel/avs/boards/Kconfig | 8 +++++ sound/soc/intel/avs/boards/Makefile | 2 ++ sound/soc/intel/avs/boards/probe.c | 64 +++++++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+) create mode 100644 sound/soc/intel/avs/boards/probe.c (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/board_selection.c b/sound/soc/intel/avs/board_selection.c index 02cc1ce8f5f5..b2823c2107f7 100644 --- a/sound/soc/intel/avs/board_selection.c +++ b/sound/soc/intel/avs/board_selection.c @@ -291,6 +291,33 @@ static void board_pdev_unregister(void *data) platform_device_unregister(data); } +static int __maybe_unused avs_register_probe_board(struct avs_dev *adev) +{ + struct platform_device *board; + struct snd_soc_acpi_mach mach = {{0}}; + int ret; + + ret = avs_probe_platform_register(adev, "probe-platform"); + if (ret < 0) + return ret; + + mach.mach_params.platform = "probe-platform"; + + board = platform_device_register_data(NULL, "avs_probe_mb", PLATFORM_DEVID_NONE, + (const void *)&mach, sizeof(mach)); + if (IS_ERR(board)) { + dev_err(adev->dev, "probe board register failed\n"); + return PTR_ERR(board); + } + + ret = devm_add_action(adev->dev, board_pdev_unregister, board); + if (ret < 0) { + platform_device_unregister(board); + return ret; + } + return 0; +} + static int avs_register_dmic_board(struct avs_dev *adev) { struct platform_device *codec, *board; @@ -500,6 +527,12 @@ int avs_register_all_boards(struct avs_dev *adev) { int ret; +#ifdef CONFIG_DEBUG_FS + ret = avs_register_probe_board(adev); + if (ret < 0) + dev_warn(adev->dev, "enumerate PROBE endpoints failed: %d\n", ret); +#endif + ret = avs_register_dmic_board(adev); if (ret < 0) dev_warn(adev->dev, "enumerate DMIC endpoints failed: %d\n", diff --git a/sound/soc/intel/avs/boards/Kconfig b/sound/soc/intel/avs/boards/Kconfig index 9bd40fdd9028..e4c230efe8d7 100644 --- a/sound/soc/intel/avs/boards/Kconfig +++ b/sound/soc/intel/avs/boards/Kconfig @@ -77,6 +77,14 @@ config SND_SOC_INTEL_AVS_MACH_NAU8825 Say Y or m if you have such a device. This is a recommended option. If unsure select "N". +config SND_SOC_INTEL_AVS_MACH_PROBE + tristate "Probing (data) board" + depends on DEBUG_FS + select SND_HWDEP + help + This adds support for data probing board which can be used to + gather data from runtime stream over compress operations. + config SND_SOC_INTEL_AVS_MACH_RT274 tristate "rt274 in I2S mode" depends on I2C diff --git a/sound/soc/intel/avs/boards/Makefile b/sound/soc/intel/avs/boards/Makefile index 4d70b8d09ce5..b81343420370 100644 --- a/sound/soc/intel/avs/boards/Makefile +++ b/sound/soc/intel/avs/boards/Makefile @@ -8,6 +8,7 @@ snd-soc-avs-max98927-objs := max98927.o snd-soc-avs-max98357a-objs := max98357a.o snd-soc-avs-max98373-objs := max98373.o snd-soc-avs-nau8825-objs := nau8825.o +snd-soc-avs-probe-objs := probe.o snd-soc-avs-rt274-objs := rt274.o snd-soc-avs-rt286-objs := rt286.o snd-soc-avs-rt298-objs := rt298.o @@ -22,6 +23,7 @@ obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98927) += snd-soc-avs-max98927.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98357A) += snd-soc-avs-max98357a.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98373) += snd-soc-avs-max98373.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_NAU8825) += snd-soc-avs-nau8825.o +obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_PROBE) += snd-soc-avs-probe.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT274) += snd-soc-avs-rt274.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT286) += snd-soc-avs-rt286.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT298) += snd-soc-avs-rt298.o diff --git a/sound/soc/intel/avs/boards/probe.c b/sound/soc/intel/avs/boards/probe.c new file mode 100644 index 000000000000..411acaee74f9 --- /dev/null +++ b/sound/soc/intel/avs/boards/probe.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2021-2022 Intel Corporation. All rights reserved. +// +// Authors: Cezary Rojewski +// Amadeusz Slawinski +// + +#include +#include +#include +#include + +SND_SOC_DAILINK_DEF(dummy, DAILINK_COMP_ARRAY(COMP_DUMMY())); +SND_SOC_DAILINK_DEF(probe_cp, DAILINK_COMP_ARRAY(COMP_CPU("Probe Extraction CPU DAI"))); +SND_SOC_DAILINK_DEF(platform, DAILINK_COMP_ARRAY(COMP_PLATFORM("probe-platform"))); + +static struct snd_soc_dai_link probe_mb_dai_links[] = { + { + .name = "Compress Probe Capture", + .nonatomic = 1, + SND_SOC_DAILINK_REG(probe_cp, dummy, platform), + }, +}; + +static int avs_probe_mb_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct snd_soc_acpi_mach *mach; + struct snd_soc_card *card; + int ret; + + mach = dev_get_platdata(dev); + + card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); + if (!card) + return -ENOMEM; + + card->name = "avs_probe_mb"; + card->dev = dev; + card->owner = THIS_MODULE; + card->dai_link = probe_mb_dai_links; + card->num_links = ARRAY_SIZE(probe_mb_dai_links); + card->fully_routed = true; + + ret = snd_soc_fixup_dai_links_platform_name(card, mach->mach_params.platform); + if (ret) + return ret; + + return devm_snd_soc_register_card(dev, card); +} + +static struct platform_driver avs_probe_mb_driver = { + .probe = avs_probe_mb_probe, + .driver = { + .name = "avs_probe_mb", + .pm = &snd_soc_pm_ops, + }, +}; + +module_platform_driver(avs_probe_mb_driver); + +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:avs_probe_mb"); -- cgit v1.2.3-70-g09d2 From 5a565ba23abe478f3d4c3b0c8798bcb5215b82f5 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Fri, 2 Dec 2022 16:28:38 +0100 Subject: ASoC: Intel: avs: Probing and firmware tracing over debugfs Define debugfs subdirectory delegated for IPC communication with DSP. Input format: uint,uint,(...) which are later translated into DWORDS sequence and further into instances of struct of interest given the IPC type. For Extractor probes, following have been enabled: - PROBE_POINT_ADD (echo <..> probe_points) - PROBE_POINT_REMOVE (echo <..> probe_points_remove) - PROBE_POINT_INFO (cat probe_points) Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221202152841.672536-14-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/avs.h | 7 + sound/soc/intel/avs/core.c | 2 + sound/soc/intel/avs/debugfs.c | 326 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 335 insertions(+) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h index e19d8d89455d..d7fccdcb9c16 100644 --- a/sound/soc/intel/avs/avs.h +++ b/sound/soc/intel/avs/avs.h @@ -144,6 +144,7 @@ struct avs_dev { u32 aging_timer_period; u32 fifo_full_timer_period; u32 logged_resources; /* context dependent: core or library */ + struct dentry *debugfs_root; /* probes */ struct hdac_ext_stream *extractor; unsigned int num_probe_streams; @@ -378,6 +379,9 @@ void avs_dump_fw_log(struct avs_dev *adev, const void __iomem *src, unsigned int void avs_dump_fw_log_wakeup(struct avs_dev *adev, const void __iomem *src, unsigned int len); int avs_probe_platform_register(struct avs_dev *adev, const char *name); + +void avs_debugfs_init(struct avs_dev *adev); +void avs_debugfs_exit(struct avs_dev *adev); #else #define AVS_SET_ENABLE_LOGS_OP(name) @@ -399,6 +403,9 @@ static inline int avs_probe_platform_register(struct avs_dev *adev, const char * { return 0; } + +static inline void avs_debugfs_init(struct avs_dev *adev) { } +static inline void avs_debugfs_exit(struct avs_dev *adev) { } #endif #endif /* __SOUND_SOC_INTEL_AVS_H */ diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c index f7bc06404dbc..2ca24273c491 100644 --- a/sound/soc/intel/avs/core.c +++ b/sound/soc/intel/avs/core.c @@ -214,6 +214,7 @@ static void avs_hda_probe_work(struct work_struct *work) adev->nhlt = intel_nhlt_init(adev->dev); if (!adev->nhlt) dev_info(bus->dev, "platform has no NHLT\n"); + avs_debugfs_init(adev); avs_register_all_boards(adev); @@ -491,6 +492,7 @@ static void avs_pci_remove(struct pci_dev *pci) avs_unregister_all_boards(adev); + avs_debugfs_exit(adev); if (adev->nhlt) intel_nhlt_free(adev->nhlt); diff --git a/sound/soc/intel/avs/debugfs.c b/sound/soc/intel/avs/debugfs.c index 78705bcb09fb..678572ee6b9d 100644 --- a/sound/soc/intel/avs/debugfs.c +++ b/sound/soc/intel/avs/debugfs.c @@ -9,7 +9,10 @@ #include #include #include +#include +#include #include "avs.h" +#include "messages.h" static unsigned int __kfifo_fromio(struct kfifo *fifo, const void __iomem *src, unsigned int len) { @@ -44,3 +47,326 @@ void avs_dump_fw_log_wakeup(struct avs_dev *adev, const void __iomem *src, unsig avs_dump_fw_log(adev, src, len); wake_up(&adev->trace_waitq); } + +static ssize_t probe_points_read(struct file *file, char __user *to, size_t count, loff_t *ppos) +{ + struct avs_dev *adev = file->private_data; + struct avs_probe_point_desc *desc; + size_t num_desc, len = 0; + char *buf; + int i, ret; + + /* Prevent chaining, send and dump IPC value just once. */ + if (*ppos) + return 0; + + buf = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + ret = avs_ipc_probe_get_points(adev, &desc, &num_desc); + if (ret) { + ret = AVS_IPC_RET(ret); + goto exit; + } + + for (i = 0; i < num_desc; i++) { + ret = snprintf(buf + len, PAGE_SIZE - len, + "Id: %#010x Purpose: %d Node id: %#x\n", + desc[i].id.value, desc[i].purpose, desc[i].node_id.val); + if (ret < 0) + goto free_desc; + len += ret; + } + + ret = simple_read_from_buffer(to, count, ppos, buf, len); +free_desc: + kfree(desc); +exit: + kfree(buf); + return ret; +} + +static ssize_t probe_points_write(struct file *file, const char __user *from, size_t count, + loff_t *ppos) +{ + struct avs_dev *adev = file->private_data; + struct avs_probe_point_desc *desc; + u32 *array, num_elems; + size_t bytes; + int ret; + + ret = parse_int_array_user(from, count, (int **)&array); + if (ret < 0) + return ret; + + num_elems = *array; + bytes = sizeof(*array) * num_elems; + if (bytes % sizeof(*desc)) { + ret = -EINVAL; + goto exit; + } + + desc = (struct avs_probe_point_desc *)&array[1]; + ret = avs_ipc_probe_connect_points(adev, desc, bytes / sizeof(*desc)); + if (ret) + ret = AVS_IPC_RET(ret); + else + ret = count; +exit: + kfree(array); + return ret; +} + +static const struct file_operations probe_points_fops = { + .open = simple_open, + .read = probe_points_read, + .write = probe_points_write, + .llseek = no_llseek, +}; + +static ssize_t probe_points_disconnect_write(struct file *file, const char __user *from, + size_t count, loff_t *ppos) +{ + struct avs_dev *adev = file->private_data; + union avs_probe_point_id *id; + u32 *array, num_elems; + size_t bytes; + int ret; + + ret = parse_int_array_user(from, count, (int **)&array); + if (ret < 0) + return ret; + + num_elems = *array; + bytes = sizeof(*array) * num_elems; + if (bytes % sizeof(*id)) { + ret = -EINVAL; + goto exit; + } + + id = (union avs_probe_point_id *)&array[1]; + ret = avs_ipc_probe_disconnect_points(adev, id, bytes / sizeof(*id)); + if (ret) + ret = AVS_IPC_RET(ret); + else + ret = count; +exit: + kfree(array); + return ret; +} + +static const struct file_operations probe_points_disconnect_fops = { + .open = simple_open, + .write = probe_points_disconnect_write, + .llseek = default_llseek, +}; + +static ssize_t strace_read(struct file *file, char __user *to, size_t count, loff_t *ppos) +{ + struct avs_dev *adev = file->private_data; + struct kfifo *fifo = &adev->trace_fifo; + unsigned int copied; + + if (kfifo_is_empty(fifo)) { + DEFINE_WAIT(wait); + + prepare_to_wait(&adev->trace_waitq, &wait, TASK_INTERRUPTIBLE); + if (!signal_pending(current)) + schedule(); + finish_wait(&adev->trace_waitq, &wait); + } + + if (kfifo_to_user(fifo, to, count, &copied)) + return -EFAULT; + *ppos += copied; + return copied; +} + +static int strace_open(struct inode *inode, struct file *file) +{ + struct avs_dev *adev = inode->i_private; + int ret; + + if (kfifo_initialized(&adev->trace_fifo)) + return -EBUSY; + + ret = kfifo_alloc(&adev->trace_fifo, PAGE_SIZE, GFP_KERNEL); + if (ret < 0) + return ret; + + file->private_data = adev; + return 0; +} + +static int strace_release(struct inode *inode, struct file *file) +{ + struct avs_dev *adev = file->private_data; + unsigned long flags; + + spin_lock_irqsave(&adev->trace_lock, flags); + kfifo_free(&adev->trace_fifo); + spin_unlock_irqrestore(&adev->trace_lock, flags); + + return 0; +} + +static const struct file_operations strace_fops = { + .llseek = default_llseek, + .read = strace_read, + .open = strace_open, + .release = strace_release, +}; + +#define DISABLE_TIMERS UINT_MAX + +static int enable_logs(struct avs_dev *adev, u32 resource_mask, u32 *priorities) +{ + int ret; + + /* Logging demands D0i0 state from DSP. */ + if (!adev->logged_resources) { + pm_runtime_get_sync(adev->dev); + + ret = avs_dsp_disable_d0ix(adev); + if (ret) + goto err_d0ix; + } + + ret = avs_ipc_set_system_time(adev); + if (ret && ret != AVS_IPC_NOT_SUPPORTED) { + ret = AVS_IPC_RET(ret); + goto err_ipc; + } + + ret = avs_dsp_op(adev, enable_logs, AVS_LOG_ENABLE, adev->aging_timer_period, + adev->fifo_full_timer_period, resource_mask, priorities); + if (ret) + goto err_ipc; + + adev->logged_resources |= resource_mask; + return 0; + +err_ipc: + if (!adev->logged_resources) { + avs_dsp_enable_d0ix(adev); +err_d0ix: + pm_runtime_mark_last_busy(adev->dev); + pm_runtime_put_autosuspend(adev->dev); + } + + return ret; +} + +static int disable_logs(struct avs_dev *adev, u32 resource_mask) +{ + int ret; + + /* Check if there's anything to do. */ + if (!adev->logged_resources) + return 0; + + ret = avs_dsp_op(adev, enable_logs, AVS_LOG_DISABLE, DISABLE_TIMERS, DISABLE_TIMERS, + resource_mask, NULL); + + /* + * If IPC fails causing recovery, logged_resources is already zero + * so unsetting bits is still safe. + */ + adev->logged_resources &= ~resource_mask; + + /* If that's the last resource, allow for D3. */ + if (!adev->logged_resources) { + avs_dsp_enable_d0ix(adev); + pm_runtime_mark_last_busy(adev->dev); + pm_runtime_put_autosuspend(adev->dev); + } + + return ret; +} + +static ssize_t trace_control_read(struct file *file, char __user *to, size_t count, loff_t *ppos) +{ + struct avs_dev *adev = file->private_data; + char buf[64]; + int len; + + len = snprintf(buf, sizeof(buf), "0x%08x\n", adev->logged_resources); + + return simple_read_from_buffer(to, count, ppos, buf, len); +} + +static ssize_t trace_control_write(struct file *file, const char __user *from, size_t count, + loff_t *ppos) +{ + struct avs_dev *adev = file->private_data; + u32 *array, num_elems; + u32 resource_mask; + int ret; + + ret = parse_int_array_user(from, count, (int **)&array); + if (ret < 0) + return ret; + + num_elems = *array; + resource_mask = array[1]; + + /* + * Disable if just resource mask is provided - no log priority flags. + * + * Enable input format: mask, prio1, .., prioN + * Where 'N' equals number of bits set in the 'mask'. + */ + if (num_elems == 1) { + ret = disable_logs(adev, resource_mask); + } else { + if (num_elems != (hweight_long(resource_mask) + 1)) { + ret = -EINVAL; + goto free_array; + } + + ret = enable_logs(adev, resource_mask, &array[2]); + } + + if (!ret) + ret = count; +free_array: + kfree(array); + return ret; +} + +static const struct file_operations trace_control_fops = { + .llseek = default_llseek, + .read = trace_control_read, + .write = trace_control_write, + .open = simple_open, +}; + +void avs_debugfs_init(struct avs_dev *adev) +{ + init_waitqueue_head(&adev->trace_waitq); + spin_lock_init(&adev->trace_lock); + + adev->debugfs_root = debugfs_create_dir("avs", snd_soc_debugfs_root); + + /* Initialize timer periods with recommended defaults. */ + adev->aging_timer_period = 10; + adev->fifo_full_timer_period = 10; + + debugfs_create_file("strace", 0444, adev->debugfs_root, adev, &strace_fops); + debugfs_create_file("trace_control", 0644, adev->debugfs_root, adev, &trace_control_fops); + + debugfs_create_u32("trace_aging_period", 0644, adev->debugfs_root, + &adev->aging_timer_period); + debugfs_create_u32("trace_fifo_full_period", 0644, adev->debugfs_root, + &adev->fifo_full_timer_period); + + debugfs_create_file("probe_points", 0644, adev->debugfs_root, adev, &probe_points_fops); + debugfs_create_file("probe_points_disconnect", 0200, adev->debugfs_root, adev, + &probe_points_disconnect_fops); +} + +void avs_debugfs_exit(struct avs_dev *adev) +{ + debugfs_remove_recursive(adev->debugfs_root); +} -- cgit v1.2.3-70-g09d2 From 34d27c71707c4ed615105376e0f3907d99b1b271 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Fri, 2 Dec 2022 16:28:39 +0100 Subject: ASoC: Intel: avs: Gather remaining logs on strace_release() When user closes the tracer, some logs may still remain in the tail of the buffer as firmware sends LOG_BUFFER_STATUS notification only when certain threshold of data is reached. Add whatever is left to already gathered logs so no information is lost. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221202152841.672536-15-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/debugfs.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/debugfs.c b/sound/soc/intel/avs/debugfs.c index 678572ee6b9d..e7b0b99824aa 100644 --- a/sound/soc/intel/avs/debugfs.c +++ b/sound/soc/intel/avs/debugfs.c @@ -201,11 +201,25 @@ static int strace_open(struct inode *inode, struct file *file) static int strace_release(struct inode *inode, struct file *file) { + union avs_notify_msg msg = AVS_NOTIFICATION(LOG_BUFFER_STATUS); struct avs_dev *adev = file->private_data; - unsigned long flags; + unsigned long resource_mask; + unsigned long flags, i; + u32 num_cores; + + resource_mask = adev->logged_resources; + num_cores = adev->hw_cfg.dsp_cores; spin_lock_irqsave(&adev->trace_lock, flags); + + /* Gather any remaining logs. */ + for_each_set_bit(i, &resource_mask, num_cores) { + msg.log.core = i; + avs_dsp_op(adev, log_buffer_status, &msg); + } + kfifo_free(&adev->trace_fifo); + spin_unlock_irqrestore(&adev->trace_lock, flags); return 0; -- cgit v1.2.3-70-g09d2 From 870f6e5abba95ac78e750b61cf8f3f15be96796f Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Fri, 2 Dec 2022 16:28:40 +0100 Subject: ASoC: Intel: avs: Allow for dumping FW_REGS area SRAM0 window begins with a block of memory, usually of size PAGE_SIZE, dedicated to the base firmware registers. When debugging firmware, it is desirable to be able to dump them at will. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221202152841.672536-16-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/debugfs.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/debugfs.c b/sound/soc/intel/avs/debugfs.c index e7b0b99824aa..e9042d4328c4 100644 --- a/sound/soc/intel/avs/debugfs.c +++ b/sound/soc/intel/avs/debugfs.c @@ -48,6 +48,29 @@ void avs_dump_fw_log_wakeup(struct avs_dev *adev, const void __iomem *src, unsig wake_up(&adev->trace_waitq); } +static ssize_t fw_regs_read(struct file *file, char __user *to, size_t count, loff_t *ppos) +{ + struct avs_dev *adev = file->private_data; + char *buf; + int ret; + + buf = kzalloc(AVS_FW_REGS_SIZE, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + memcpy_fromio(buf, avs_sram_addr(adev, AVS_FW_REGS_WINDOW), AVS_FW_REGS_SIZE); + + ret = simple_read_from_buffer(to, count, ppos, buf, AVS_FW_REGS_SIZE); + kfree(buf); + return ret; +} + +static const struct file_operations fw_regs_fops = { + .open = simple_open, + .read = fw_regs_read, + .llseek = no_llseek, +}; + static ssize_t probe_points_read(struct file *file, char __user *to, size_t count, loff_t *ppos) { struct avs_dev *adev = file->private_data; @@ -369,6 +392,7 @@ void avs_debugfs_init(struct avs_dev *adev) debugfs_create_file("strace", 0444, adev->debugfs_root, adev, &strace_fops); debugfs_create_file("trace_control", 0644, adev->debugfs_root, adev, &trace_control_fops); + debugfs_create_file("fw_regs", 0444, adev->debugfs_root, adev, &fw_regs_fops); debugfs_create_u32("trace_aging_period", 0644, adev->debugfs_root, &adev->aging_timer_period); -- cgit v1.2.3-70-g09d2 From 85ac9c8c8eed76e8a320a9e017c6d36e2a52745b Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Fri, 2 Dec 2022 16:28:41 +0100 Subject: ASoC: Intel: avs: Allow for dumping debug window snapshot Add new read-only debugfs entry which dumps entire content of the SRAM window 2 i.e.: the debug window. Signed-off-by: Cezary Rojewski Link: https://lore.kernel.org/r/20221202152841.672536-17-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/debugfs.c | 26 ++++++++++++++++++++++++++ sound/soc/intel/avs/registers.h | 3 ++- 2 files changed, 28 insertions(+), 1 deletion(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/avs/debugfs.c b/sound/soc/intel/avs/debugfs.c index e9042d4328c4..bdd388ec01ea 100644 --- a/sound/soc/intel/avs/debugfs.c +++ b/sound/soc/intel/avs/debugfs.c @@ -71,6 +71,31 @@ static const struct file_operations fw_regs_fops = { .llseek = no_llseek, }; +static ssize_t debug_window_read(struct file *file, char __user *to, size_t count, loff_t *ppos) +{ + struct avs_dev *adev = file->private_data; + size_t size; + char *buf; + int ret; + + size = adev->hw_cfg.dsp_cores * AVS_WINDOW_CHUNK_SIZE; + buf = kzalloc(size, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + memcpy_fromio(buf, avs_sram_addr(adev, AVS_DEBUG_WINDOW), size); + + ret = simple_read_from_buffer(to, count, ppos, buf, size); + kfree(buf); + return ret; +} + +static const struct file_operations debug_window_fops = { + .open = simple_open, + .read = debug_window_read, + .llseek = no_llseek, +}; + static ssize_t probe_points_read(struct file *file, char __user *to, size_t count, loff_t *ppos) { struct avs_dev *adev = file->private_data; @@ -393,6 +418,7 @@ void avs_debugfs_init(struct avs_dev *adev) debugfs_create_file("strace", 0444, adev->debugfs_root, adev, &strace_fops); debugfs_create_file("trace_control", 0644, adev->debugfs_root, adev, &trace_control_fops); debugfs_create_file("fw_regs", 0444, adev->debugfs_root, adev, &fw_regs_fops); + debugfs_create_file("debug_window", 0444, adev->debugfs_root, adev, &debug_window_fops); debugfs_create_u32("trace_aging_period", 0644, adev->debugfs_root, &adev->aging_timer_period); diff --git a/sound/soc/intel/avs/registers.h b/sound/soc/intel/avs/registers.h index 95be86148cf3..2b464e466ed5 100644 --- a/sound/soc/intel/avs/registers.h +++ b/sound/soc/intel/avs/registers.h @@ -59,7 +59,8 @@ #define AVS_FW_REG_STATUS(adev) (AVS_FW_REG_BASE(adev) + 0x0) #define AVS_FW_REG_ERROR_CODE(adev) (AVS_FW_REG_BASE(adev) + 0x4) -#define AVS_FW_REGS_SIZE PAGE_SIZE +#define AVS_WINDOW_CHUNK_SIZE PAGE_SIZE +#define AVS_FW_REGS_SIZE AVS_WINDOW_CHUNK_SIZE #define AVS_FW_REGS_WINDOW 0 /* DSP -> HOST communication window */ #define AVS_UPLINK_WINDOW AVS_FW_REGS_WINDOW -- cgit v1.2.3-70-g09d2 From 1b41beaa7a58467505ec3023af8aad74f878b888 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Mon, 5 Dec 2022 22:37:21 +0800 Subject: ASoC: sof_es8336: fix possible use-after-free in sof_es8336_remove() sof_es8336_remove() calls cancel_delayed_work(). However, that function does not wait until the work function finishes. This means that the callback function may still be running after the driver's remove function has finished, which would result in a use-after-free. Fix by calling cancel_delayed_work_sync(), which ensures that the work is properly cancelled, no longer running, and unable to re-schedule itself. Fixes: 89cdb224f2ab ("ASoC: sof_es8336: reduce pop noise on speaker") Signed-off-by: Yang Yingliang Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20221205143721.3988988-1-yangyingliang@huawei.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_es8336.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c index 70713e4b07dc..773e5d1d87d4 100644 --- a/sound/soc/intel/boards/sof_es8336.c +++ b/sound/soc/intel/boards/sof_es8336.c @@ -783,7 +783,7 @@ static int sof_es8336_remove(struct platform_device *pdev) struct snd_soc_card *card = platform_get_drvdata(pdev); struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card); - cancel_delayed_work(&priv->pcm_pop_work); + cancel_delayed_work_sync(&priv->pcm_pop_work); gpiod_put(priv->gpio_speakers); device_remove_software_node(priv->codec_dev); put_device(priv->codec_dev); -- cgit v1.2.3-70-g09d2 From 72d9a541d7f186f0ec97c71ba7e477dd9bf4155f Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 5 Dec 2022 09:53:25 +0100 Subject: ASoC: Intel: Skylake: Update pipe_config_idx before filling BE params Without updating the index before BE copier config is filled with hardware parameters, outdated parameters are used instead. Signed-off-by: Cezary Rojewski Tested-by: Lukasz Majczak Link: https://lore.kernel.org/r/20221205085330.857665-2-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl-topology.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index e06eac592da1..fc3d719d93e1 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -1837,16 +1837,24 @@ static int skl_tplg_be_fill_pipe_params(struct snd_soc_dai *dai, { struct nhlt_specific_cfg *cfg; struct skl_pipe *pipe = mconfig->pipe; + struct skl_pipe_params save = *pipe->p_params; struct skl_pipe_fmt *pipe_fmt; struct skl_dev *skl = get_skl_ctx(dai->dev); int link_type = skl_tplg_be_link_type(mconfig->dev_type); u8 dev_type = skl_tplg_be_dev_type(mconfig->dev_type); + int ret; skl_tplg_fill_dma_id(mconfig, params); if (link_type == NHLT_LINK_HDA) return 0; + *pipe->p_params = *params; + ret = skl_tplg_get_pipe_config(skl, mconfig); + if (ret) + goto err; + + dev_dbg(skl->dev, "%s using pipe config: %d\n", __func__, pipe->pipe_config_idx); if (pipe->direction == SNDRV_PCM_STREAM_PLAYBACK) pipe_fmt = &pipe->configs[pipe->pipe_config_idx].out_fmt; else @@ -1865,10 +1873,15 @@ static int skl_tplg_be_fill_pipe_params(struct snd_soc_dai *dai, dev_err(dai->dev, "Blob NULL for id:%d type:%d dirn:%d ch:%d, freq:%d, fmt:%d\n", mconfig->vbus_id, link_type, params->stream, params->ch, params->s_freq, params->s_fmt); - return -EINVAL; + ret = -EINVAL; + goto err; } return 0; + +err: + *pipe->p_params = save; + return ret; } static int skl_tplg_be_set_src_pipe_params(struct snd_soc_dai *dai, -- cgit v1.2.3-70-g09d2 From b0d16e54e7559f2055123ea7b1d9ff1bb808ebad Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 5 Dec 2022 09:53:26 +0100 Subject: ASoC: Intel: Skylake: Remove skl_tplg_is_multi_fmt() Rather than forcing userspace to select proper format with enumerable kcontrols, select it ourselves based on provided hw_params. Signed-off-by: Cezary Rojewski Tested-by: Lukasz Majczak Link: https://lore.kernel.org/r/20221205085330.857665-3-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl-topology.c | 40 ---------------------------------- 1 file changed, 40 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index fc3d719d93e1..f144acae1b44 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -582,38 +582,6 @@ static int skl_tplg_unload_pipe_modules(struct skl_dev *skl, return ret; } -static bool skl_tplg_is_multi_fmt(struct skl_dev *skl, struct skl_pipe *pipe) -{ - struct skl_pipe_fmt *cur_fmt; - struct skl_pipe_fmt *next_fmt; - int i; - - if (pipe->nr_cfgs <= 1) - return false; - - if (pipe->conn_type != SKL_PIPE_CONN_TYPE_FE) - return true; - - for (i = 0; i < pipe->nr_cfgs - 1; i++) { - if (pipe->direction == SNDRV_PCM_STREAM_PLAYBACK) { - cur_fmt = &pipe->configs[i].out_fmt; - next_fmt = &pipe->configs[i + 1].out_fmt; - } else { - cur_fmt = &pipe->configs[i].in_fmt; - next_fmt = &pipe->configs[i + 1].in_fmt; - } - - if (!CHECK_HW_PARAMS(cur_fmt->channels, cur_fmt->freq, - cur_fmt->bps, - next_fmt->channels, - next_fmt->freq, - next_fmt->bps)) - return true; - } - - return false; -} - /* * Here, we select pipe format based on the pipe type and pipe * direction to determine the current config index for the pipeline. @@ -636,14 +604,6 @@ skl_tplg_get_pipe_config(struct skl_dev *skl, struct skl_module_cfg *mconfig) return 0; } - if (skl_tplg_is_multi_fmt(skl, pipe)) { - pipe->cur_config_idx = pipe->pipe_config_idx; - pipe->memory_pages = pconfig->mem_pages; - dev_dbg(skl->dev, "found pipe config idx:%d\n", - pipe->cur_config_idx); - return 0; - } - if (pipe->conn_type == SKL_PIPE_CONN_TYPE_NONE || pipe->nr_cfgs == 1) { dev_dbg(skl->dev, "No conn_type or just 1 pathcfg, taking 0th for %d\n", pipe->ppl_id); -- cgit v1.2.3-70-g09d2 From 75ab3c00769009e32e5cf51c8b503de4f73114e4 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 5 Dec 2022 09:53:27 +0100 Subject: ASoC: Intel: Skylake: Drop pipe_config_idx Field ->pipe_config_idx duplicates the job of ->cur_config_idx so remove it. Signed-off-by: Cezary Rojewski Tested-by: Lukasz Majczak Link: https://lore.kernel.org/r/20221205085330.857665-4-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl-topology.c | 10 +++++----- sound/soc/intel/skylake/skl-topology.h | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index f144acae1b44..567a3b661ce4 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -1351,9 +1351,9 @@ static int skl_tplg_multi_config_set_get(struct snd_kcontrol *kcontrol, return -EIO; if (is_set) - pipe->pipe_config_idx = ucontrol->value.enumerated.item[0]; + pipe->cur_config_idx = ucontrol->value.enumerated.item[0]; else - ucontrol->value.enumerated.item[0] = pipe->pipe_config_idx; + ucontrol->value.enumerated.item[0] = pipe->cur_config_idx; return 0; } @@ -1814,11 +1814,11 @@ static int skl_tplg_be_fill_pipe_params(struct snd_soc_dai *dai, if (ret) goto err; - dev_dbg(skl->dev, "%s using pipe config: %d\n", __func__, pipe->pipe_config_idx); + dev_dbg(skl->dev, "%s using pipe config: %d\n", __func__, pipe->cur_config_idx); if (pipe->direction == SNDRV_PCM_STREAM_PLAYBACK) - pipe_fmt = &pipe->configs[pipe->pipe_config_idx].out_fmt; + pipe_fmt = &pipe->configs[pipe->cur_config_idx].out_fmt; else - pipe_fmt = &pipe->configs[pipe->pipe_config_idx].in_fmt; + pipe_fmt = &pipe->configs[pipe->cur_config_idx].in_fmt; /* update the blob based on virtual bus_id*/ cfg = intel_nhlt_get_endpoint_blob(dai->dev, skl->nhlt, diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h index 017ac0ef324d..6db0fd7bad49 100644 --- a/sound/soc/intel/skylake/skl-topology.h +++ b/sound/soc/intel/skylake/skl-topology.h @@ -324,7 +324,6 @@ struct skl_pipe { struct skl_path_config configs[SKL_MAX_PATH_CONFIGS]; struct list_head w_list; bool passthru; - u32 pipe_config_idx; }; enum skl_module_state { -- cgit v1.2.3-70-g09d2 From 4ac587f3578c5ca490e4df55af6403f5474eb2f0 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 5 Dec 2022 09:53:28 +0100 Subject: ASoC: Intel: Skylake: Introduce single place for pipe-config selection Provide a single location for pipe config selection where all fields that have to be updated whenever ->pipe_config_idx changes can be updated accordingly. Signed-off-by: Cezary Rojewski Tested-by: Lukasz Majczak Link: https://lore.kernel.org/r/20221205085330.857665-5-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl-topology.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 567a3b661ce4..b20643b83401 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -582,6 +582,12 @@ static int skl_tplg_unload_pipe_modules(struct skl_dev *skl, return ret; } +static void skl_tplg_set_pipe_config_idx(struct skl_pipe *pipe, int idx) +{ + pipe->cur_config_idx = idx; + pipe->memory_pages = pipe->configs[idx].mem_pages; +} + /* * Here, we select pipe format based on the pipe type and pipe * direction to determine the current config index for the pipeline. @@ -600,16 +606,14 @@ skl_tplg_get_pipe_config(struct skl_dev *skl, struct skl_module_cfg *mconfig) int i; if (pipe->nr_cfgs == 0) { - pipe->cur_config_idx = 0; + skl_tplg_set_pipe_config_idx(pipe, 0); return 0; } if (pipe->conn_type == SKL_PIPE_CONN_TYPE_NONE || pipe->nr_cfgs == 1) { dev_dbg(skl->dev, "No conn_type or just 1 pathcfg, taking 0th for %d\n", pipe->ppl_id); - pipe->cur_config_idx = 0; - pipe->memory_pages = pconfig->mem_pages; - + skl_tplg_set_pipe_config_idx(pipe, 0); return 0; } @@ -628,10 +632,8 @@ skl_tplg_get_pipe_config(struct skl_dev *skl, struct skl_module_cfg *mconfig) if (CHECK_HW_PARAMS(params->ch, params->s_freq, params->s_fmt, fmt->channels, fmt->freq, fmt->bps)) { - pipe->cur_config_idx = i; - pipe->memory_pages = pconfig->mem_pages; + skl_tplg_set_pipe_config_idx(pipe, i); dev_dbg(skl->dev, "Using pipe config: %d\n", i); - return 0; } } @@ -1351,7 +1353,7 @@ static int skl_tplg_multi_config_set_get(struct snd_kcontrol *kcontrol, return -EIO; if (is_set) - pipe->cur_config_idx = ucontrol->value.enumerated.item[0]; + skl_tplg_set_pipe_config_idx(pipe, ucontrol->value.enumerated.item[0]); else ucontrol->value.enumerated.item[0] = pipe->cur_config_idx; -- cgit v1.2.3-70-g09d2 From 171107237246d66bce04f3769d33648f896b4ce3 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 5 Dec 2022 09:53:29 +0100 Subject: ASoC: Intel: Skylake: Fix driver hang during shutdown AudioDSP cores and HDAudio links need to be turned off on shutdown to ensure no communication or data transfer occurs during the procedure. Fixes: c5a76a246989 ("ASoC: Intel: Skylake: Add shutdown callback") Signed-off-by: Cezary Rojewski Tested-by: Lukasz Majczak Link: https://lore.kernel.org/r/20221205085330.857665-6-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 9bd9f9866898..998bd0232cf1 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -1107,7 +1107,10 @@ static void skl_shutdown(struct pci_dev *pci) if (!skl->init_done) return; - snd_hdac_stop_streams_and_chip(bus); + snd_hdac_stop_streams(bus); + snd_hdac_ext_bus_link_power_down_all(bus); + skl_dsp_sleep(skl->dsp); + list_for_each_entry(s, &bus->stream_list, list) { stream = stream_to_hdac_ext_stream(s); snd_hdac_ext_stream_decouple(bus, stream, false); -- cgit v1.2.3-70-g09d2 From 451d85c46cf719a09a052510d4d4cd920103163a Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 5 Dec 2022 09:53:30 +0100 Subject: ASoC: Intel: Skylake: Use SG allocation for SKL-based firmware load Resign from ->alloc_dma_buf() and use snd_dma_alloc_pages() directly. For data i.e.: base firmware binary transfer, make use of SG allocation to better adapt to memory-limited environment. For BDL descriptor, given its small size this is not required. Signed-off-by: Cezary Rojewski Tested-by: Lukasz Majczak Link: https://lore.kernel.org/r/20221205085330.857665-7-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl-sst-cldma.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/skylake/skl-sst-cldma.c b/sound/soc/intel/skylake/skl-sst-cldma.c index b91f7a652a2b..b0204ea00f07 100644 --- a/sound/soc/intel/skylake/skl-sst-cldma.c +++ b/sound/soc/intel/skylake/skl-sst-cldma.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "../common/sst-dsp.h" #include "../common/sst-dsp-priv.h" @@ -79,21 +80,25 @@ static void skl_cldma_setup_bdle(struct sst_dsp *ctx, __le32 **bdlp, int size, int with_ioc) { __le32 *bdl = *bdlp; + int remaining = ctx->cl_dev.bufsize; + int offset = 0; ctx->cl_dev.frags = 0; - while (size > 0) { - phys_addr_t addr = virt_to_phys(dmab_data->area + - (ctx->cl_dev.frags * ctx->cl_dev.bufsize)); + while (remaining > 0) { + phys_addr_t addr; + int chunk; + addr = snd_sgbuf_get_addr(dmab_data, offset); bdl[0] = cpu_to_le32(lower_32_bits(addr)); bdl[1] = cpu_to_le32(upper_32_bits(addr)); + chunk = snd_sgbuf_get_chunk_size(dmab_data, offset, size); + bdl[2] = cpu_to_le32(chunk); - bdl[2] = cpu_to_le32(ctx->cl_dev.bufsize); - - size -= ctx->cl_dev.bufsize; - bdl[3] = (size || !with_ioc) ? 0 : cpu_to_le32(0x01); + remaining -= chunk; + bdl[3] = (remaining > 0) ? 0 : cpu_to_le32(0x01); bdl += 4; + offset += chunk; ctx->cl_dev.frags++; } } @@ -338,15 +343,15 @@ int skl_cldma_prepare(struct sst_dsp *ctx) ctx->cl_dev.ops.cl_stop_dma = skl_cldma_stop; /* Allocate buffer*/ - ret = ctx->dsp_ops.alloc_dma_buf(ctx->dev, - &ctx->cl_dev.dmab_data, ctx->cl_dev.bufsize); + ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV_SG, ctx->dev, ctx->cl_dev.bufsize, + &ctx->cl_dev.dmab_data); if (ret < 0) { dev_err(ctx->dev, "Alloc buffer for base fw failed: %x\n", ret); return ret; } + /* Setup Code loader BDL */ - ret = ctx->dsp_ops.alloc_dma_buf(ctx->dev, - &ctx->cl_dev.dmab_bdl, PAGE_SIZE); + ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, ctx->dev, BDL_SIZE, &ctx->cl_dev.dmab_bdl); if (ret < 0) { dev_err(ctx->dev, "Alloc buffer for blde failed: %x\n", ret); ctx->dsp_ops.free_dma_buf(ctx->dev, &ctx->cl_dev.dmab_data); -- cgit v1.2.3-70-g09d2 From c0660fce5e0672b9fcffaae02184d58c8ed2aec1 Mon Sep 17 00:00:00 2001 From: Brent Lu Date: Tue, 6 Dec 2022 15:25:05 -0600 Subject: ASoC: Intel: sof_rt5682: add jsl_rt5682 board config This configuration supports JSL boards which implement ALC5682I-VD/VS on SSP0 port. Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Signed-off-by: Brent Lu Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20221206212507.359993-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_rt5682.c | 6 ++++++ sound/soc/intel/common/soc-acpi-intel-jsl-match.c | 5 +++++ 2 files changed, 11 insertions(+) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index 4a2f91249b10..2eabc4b0fafa 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -1104,6 +1104,12 @@ static const struct platform_device_id board_ids[] = { SOF_RT5682_SSP_AMP(1) | SOF_RT5682_NUM_HDMIDEV(4)), }, + { + .name = "jsl_rt5682", + .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | + SOF_RT5682_MCLK_24MHZ | + SOF_RT5682_SSP_CODEC(0)), + }, { } }; MODULE_DEVICE_TABLE(platform, board_ids); diff --git a/sound/soc/intel/common/soc-acpi-intel-jsl-match.c b/sound/soc/intel/common/soc-acpi-intel-jsl-match.c index b95c4b2cda94..f5c7e1bbded0 100644 --- a/sound/soc/intel/common/soc-acpi-intel-jsl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-jsl-match.c @@ -78,6 +78,11 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_jsl_machines[] = { .quirk_data = &mx98360a_spk, .sof_tplg_filename = "sof-jsl-rt5682-mx98360a.tplg", }, + { + .comp_ids = &rt5682_rt5682s_hp, + .drv_name = "jsl_rt5682", + .sof_tplg_filename = "sof-jsl-rt5682.tplg", + }, { .id = "10134242", .drv_name = "jsl_cs4242_mx98360a", -- cgit v1.2.3-70-g09d2 From 5c10da436ebd93f9bfa244ea933773d14b566499 Mon Sep 17 00:00:00 2001 From: Gongjun Song Date: Tue, 6 Dec 2022 15:25:06 -0600 Subject: ASoC: Intel: sof_sdw: use common helpers for all Realtek amps sof_sdw_rt1308.c/sof_sdw_rt1316.c/sof_sdw_rt1318.c handle amp in basically the same way, optimized and merged into one file. Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Signed-off-by: Gongjun Song Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20221206212507.359993-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/Makefile | 3 +- sound/soc/intel/boards/sof_sdw.c | 10 +- sound/soc/intel/boards/sof_sdw_common.h | 20 +- sound/soc/intel/boards/sof_sdw_rt1308.c | 278 ------------------------- sound/soc/intel/boards/sof_sdw_rt1316.c | 239 --------------------- sound/soc/intel/boards/sof_sdw_rt1318.c | 120 ----------- sound/soc/intel/boards/sof_sdw_rt_amp.c | 359 ++++++++++++++++++++++++++++++++ 7 files changed, 369 insertions(+), 660 deletions(-) delete mode 100644 sound/soc/intel/boards/sof_sdw_rt1308.c delete mode 100644 sound/soc/intel/boards/sof_sdw_rt1316.c delete mode 100644 sound/soc/intel/boards/sof_sdw_rt1318.c create mode 100644 sound/soc/intel/boards/sof_sdw_rt_amp.c (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile index 7e1a4ff77ac3..d1fd7a2b32db 100644 --- a/sound/soc/intel/boards/Makefile +++ b/sound/soc/intel/boards/Makefile @@ -37,8 +37,7 @@ snd-soc-sof_da7219_max98373-objs := sof_da7219_max98373.o snd-soc-ehl-rt5660-objs := ehl_rt5660.o snd-soc-sof-ssp-amp-objs := sof_ssp_amp.o snd-soc-sof-sdw-objs += sof_sdw.o \ - sof_sdw_max98373.o sof_sdw_rt1308.o \ - sof_sdw_rt1316.o sof_sdw_rt1318.o \ + sof_sdw_max98373.o sof_sdw_rt_amp.o \ sof_sdw_rt5682.o sof_sdw_rt700.o \ sof_sdw_rt711.o sof_sdw_rt711_sdca.o \ sof_sdw_rt715.o sof_sdw_rt715_sdca.o \ diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index b58c7b35599d..d2ed807abde9 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -550,23 +550,23 @@ static struct sof_sdw_codec_info codec_info_list[] = { .direction = {true, false}, .dai_name = "rt1308-aif", .ops = &sof_sdw_rt1308_i2s_ops, - .init = sof_sdw_rt1308_init, - .exit = sof_sdw_rt1308_exit, + .init = sof_sdw_rt_amp_init, + .exit = sof_sdw_rt_amp_exit, .codec_type = SOF_SDW_CODEC_TYPE_AMP, }, { .part_id = 0x1316, .direction = {true, true}, .dai_name = "rt1316-aif", - .init = sof_sdw_rt1316_init, - .exit = sof_sdw_rt1316_exit, + .init = sof_sdw_rt_amp_init, + .exit = sof_sdw_rt_amp_exit, .codec_type = SOF_SDW_CODEC_TYPE_AMP, }, { .part_id = 0x1318, .direction = {true, true}, .dai_name = "rt1318-aif", - .init = sof_sdw_rt1318_init, + .init = sof_sdw_rt_amp_init, .codec_type = SOF_SDW_CODEC_TYPE_AMP, }, { diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h index 54a50f7da4da..350010b0e5f4 100644 --- a/sound/soc/intel/boards/sof_sdw_common.h +++ b/sound/soc/intel/boards/sof_sdw_common.h @@ -125,30 +125,18 @@ int sof_sdw_rt700_init(struct snd_soc_card *card, struct sof_sdw_codec_info *info, bool playback); -/* RT1308 support */ +/* RT1308 I2S support */ extern struct snd_soc_ops sof_sdw_rt1308_i2s_ops; -int sof_sdw_rt1308_init(struct snd_soc_card *card, +/* generic amp support */ +int sof_sdw_rt_amp_init(struct snd_soc_card *card, const struct snd_soc_acpi_link_adr *link, struct snd_soc_dai_link *dai_links, struct sof_sdw_codec_info *info, bool playback); -int sof_sdw_rt1308_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); +int sof_sdw_rt_amp_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); /* RT1316 support */ -int sof_sdw_rt1316_init(struct snd_soc_card *card, - const struct snd_soc_acpi_link_adr *link, - struct snd_soc_dai_link *dai_links, - struct sof_sdw_codec_info *info, - bool playback); -int sof_sdw_rt1316_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); - -/* RT1318 support */ -int sof_sdw_rt1318_init(struct snd_soc_card *card, - const struct snd_soc_acpi_link_adr *link, - struct snd_soc_dai_link *dai_links, - struct sof_sdw_codec_info *info, - bool playback); /* RT715 support */ int sof_sdw_rt715_init(struct snd_soc_card *card, diff --git a/sound/soc/intel/boards/sof_sdw_rt1308.c b/sound/soc/intel/boards/sof_sdw_rt1308.c deleted file mode 100644 index a19b055b9c6f..000000000000 --- a/sound/soc/intel/boards/sof_sdw_rt1308.c +++ /dev/null @@ -1,278 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright (c) 2020 Intel Corporation - -/* - * sof_sdw_rt1308 - Helpers to handle RT1308 from generic machine driver - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "sof_sdw_common.h" -#include "sof_sdw_amp_coeff_tables.h" -#include "../../codecs/rt1308.h" - -struct rt1308_platform_data { - const unsigned char *bq_params; - const unsigned int bq_params_cnt; -}; - -static const struct rt1308_platform_data dell_0a5d_platform_data = { - .bq_params = dell_0a5d_bq_params, - .bq_params_cnt = ARRAY_SIZE(dell_0a5d_bq_params), -}; - -static const struct dmi_system_id dmi_platform_data[] = { - /* CometLake devices */ - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990") - }, - .driver_data = (void *)&dell_0a5d_platform_data, - }, - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F") - }, - .driver_data = (void *)&dell_0a5d_platform_data, - }, - /* TigerLake devices */ - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5D") - }, - .driver_data = (void *)&dell_0a5d_platform_data, - }, - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5E") - }, - .driver_data = (void *)&dell_0a5d_platform_data, - }, -}; - -static int rt1308_add_device_props(struct device *sdw_dev) -{ - struct property_entry props[3] = {}; - struct fwnode_handle *fwnode; - const struct dmi_system_id *dmi_data; - const struct rt1308_platform_data *pdata; - unsigned char params[RT1308_MAX_BQ_REG]; - int ret; - - dmi_data = dmi_first_match(dmi_platform_data); - if (!dmi_data) - return 0; - - pdata = dmi_data->driver_data; - memcpy(¶ms, pdata->bq_params, sizeof(unsigned char) * pdata->bq_params_cnt); - - props[0] = PROPERTY_ENTRY_U8_ARRAY("realtek,bq-params", params); - props[1] = PROPERTY_ENTRY_U32("realtek,bq-params-cnt", pdata->bq_params_cnt); - - fwnode = fwnode_create_software_node(props, NULL); - if (IS_ERR(fwnode)) - return PTR_ERR(fwnode); - - ret = device_add_software_node(sdw_dev, to_software_node(fwnode)); - - fwnode_handle_put(fwnode); - - return ret; -} - -static const struct snd_soc_dapm_widget rt1308_widgets[] = { - SND_SOC_DAPM_SPK("Speaker", NULL), -}; - -/* - * dapm routes for rt1308 will be registered dynamically according - * to the number of rt1308 used. The first two entries will be registered - * for one codec case, and the last two entries are also registered - * if two 1308s are used. - */ -static const struct snd_soc_dapm_route rt1308_map[] = { - { "Speaker", NULL, "rt1308-1 SPOL" }, - { "Speaker", NULL, "rt1308-1 SPOR" }, - { "Speaker", NULL, "rt1308-2 SPOL" }, - { "Speaker", NULL, "rt1308-2 SPOR" }, -}; - -static const struct snd_kcontrol_new rt1308_controls[] = { - SOC_DAPM_PIN_SWITCH("Speaker"), -}; - -static int first_spk_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_card *card = rtd->card; - int ret; - - card->components = devm_kasprintf(card->dev, GFP_KERNEL, - "%s spk:rt1308", - card->components); - if (!card->components) - return -ENOMEM; - - ret = snd_soc_add_card_controls(card, rt1308_controls, - ARRAY_SIZE(rt1308_controls)); - if (ret) { - dev_err(card->dev, "rt1308 controls addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_new_controls(&card->dapm, rt1308_widgets, - ARRAY_SIZE(rt1308_widgets)); - if (ret) { - dev_err(card->dev, "rt1308 widgets addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_add_routes(&card->dapm, rt1308_map, 2); - if (ret) - dev_err(rtd->dev, "failed to add first SPK map: %d\n", ret); - - return ret; -} - -static int second_spk_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_card *card = rtd->card; - int ret; - - ret = snd_soc_dapm_add_routes(&card->dapm, rt1308_map + 2, 2); - if (ret) - dev_err(rtd->dev, "failed to add second SPK map: %d\n", ret); - - return ret; -} - -static int all_spk_init(struct snd_soc_pcm_runtime *rtd) -{ - int ret; - - ret = first_spk_init(rtd); - if (ret) - return ret; - - return second_spk_init(rtd); -} - -static int rt1308_i2s_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_card *card = rtd->card; - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - int clk_id, clk_freq, pll_out; - int err; - - clk_id = RT1308_PLL_S_MCLK; - clk_freq = 38400000; - - pll_out = params_rate(params) * 512; - - /* Set rt1308 pll */ - err = snd_soc_dai_set_pll(codec_dai, 0, clk_id, clk_freq, pll_out); - if (err < 0) { - dev_err(card->dev, "Failed to set RT1308 PLL: %d\n", err); - return err; - } - - /* Set rt1308 sysclk */ - err = snd_soc_dai_set_sysclk(codec_dai, RT1308_FS_SYS_S_PLL, pll_out, - SND_SOC_CLOCK_IN); - if (err < 0) { - dev_err(card->dev, "Failed to set RT1308 SYSCLK: %d\n", err); - return err; - } - - return 0; -} - -/* machine stream operations */ -struct snd_soc_ops sof_sdw_rt1308_i2s_ops = { - .hw_params = rt1308_i2s_hw_params, -}; - -int sof_sdw_rt1308_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link) -{ - struct mc_private *ctx = snd_soc_card_get_drvdata(card); - - if (ctx->amp_dev1) { - device_remove_software_node(ctx->amp_dev1); - put_device(ctx->amp_dev1); - } - - if (ctx->amp_dev2) { - device_remove_software_node(ctx->amp_dev2); - put_device(ctx->amp_dev2); - } - - return 0; -} - -int sof_sdw_rt1308_init(struct snd_soc_card *card, - const struct snd_soc_acpi_link_adr *link, - struct snd_soc_dai_link *dai_links, - struct sof_sdw_codec_info *info, - bool playback) -{ - struct mc_private *ctx = snd_soc_card_get_drvdata(card); - struct device *sdw_dev1, *sdw_dev2; - int ret; - - /* Count amp number and do init on playback link only. */ - if (!playback) - return 0; - - info->amp_num++; - if (info->amp_num == 1) - dai_links->init = first_spk_init; - - if (info->amp_num == 2) { - sdw_dev1 = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[0].name); - if (!sdw_dev1) - return -EPROBE_DEFER; - - ret = rt1308_add_device_props(sdw_dev1); - if (ret < 0) { - put_device(sdw_dev1); - return ret; - } - ctx->amp_dev1 = sdw_dev1; - - sdw_dev2 = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[1].name); - if (!sdw_dev2) - return -EPROBE_DEFER; - - ret = rt1308_add_device_props(sdw_dev2); - if (ret < 0) { - put_device(sdw_dev2); - return ret; - } - ctx->amp_dev2 = sdw_dev2; - - /* - * if two 1308s are in one dai link, the init function - * in this dai link will be first set for the first speaker, - * and it should be reset to initialize all speakers when - * the second speaker is found. - */ - if (dai_links->init) - dai_links->init = all_spk_init; - else - dai_links->init = second_spk_init; - } - - return 0; -} diff --git a/sound/soc/intel/boards/sof_sdw_rt1316.c b/sound/soc/intel/boards/sof_sdw_rt1316.c deleted file mode 100644 index f6bbea0d3810..000000000000 --- a/sound/soc/intel/boards/sof_sdw_rt1316.c +++ /dev/null @@ -1,239 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright (c) 2020 Intel Corporation - -/* - * sof_sdw_rt1316 - Helpers to handle RT1316 from generic machine driver - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "sof_sdw_common.h" -#include "sof_sdw_amp_coeff_tables.h" - -struct rt1316_platform_data { - const unsigned char *bq_params; - const unsigned int bq_params_cnt; -}; - -static const struct rt1316_platform_data dell_0b00_platform_data = { - .bq_params = dell_0b00_bq_params, - .bq_params_cnt = ARRAY_SIZE(dell_0b00_bq_params), -}; - -static const struct dmi_system_id dmi_platform_data[] = { - /* AlderLake devices */ - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B00") - }, - .driver_data = (void *)&dell_0b00_platform_data, - }, - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B01") - }, - .driver_data = (void *)&dell_0b00_platform_data, - }, - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AFF") - }, - .driver_data = (void *)&dell_0b00_platform_data, - }, - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AFE") - }, - .driver_data = (void *)&dell_0b00_platform_data, - }, -}; - -static int rt1316_add_device_props(struct device *sdw_dev) -{ - struct property_entry props[3] = {}; - struct fwnode_handle *fwnode; - const struct dmi_system_id *dmi_data; - const struct rt1316_platform_data *pdata; - unsigned char params[RT1316_MAX_BQ_REG]; - int ret; - - dmi_data = dmi_first_match(dmi_platform_data); - if (!dmi_data) - return 0; - - pdata = dmi_data->driver_data; - memcpy(¶ms, pdata->bq_params, sizeof(unsigned char) * pdata->bq_params_cnt); - - props[0] = PROPERTY_ENTRY_U8_ARRAY("realtek,bq-params", params); - props[1] = PROPERTY_ENTRY_U32("realtek,bq-params-cnt", pdata->bq_params_cnt); - - fwnode = fwnode_create_software_node(props, NULL); - if (IS_ERR(fwnode)) - return PTR_ERR(fwnode); - - ret = device_add_software_node(sdw_dev, to_software_node(fwnode)); - - fwnode_handle_put(fwnode); - - return ret; -} - -static const struct snd_soc_dapm_widget rt1316_widgets[] = { - SND_SOC_DAPM_SPK("Speaker", NULL), -}; - -/* - * dapm routes for rt1316 will be registered dynamically according - * to the number of rt1316 used. The first two entries will be registered - * for one codec case, and the last two entries are also registered - * if two 1316s are used. - */ -static const struct snd_soc_dapm_route rt1316_map[] = { - { "Speaker", NULL, "rt1316-1 SPOL" }, - { "Speaker", NULL, "rt1316-1 SPOR" }, - { "Speaker", NULL, "rt1316-2 SPOL" }, - { "Speaker", NULL, "rt1316-2 SPOR" }, -}; - -static const struct snd_kcontrol_new rt1316_controls[] = { - SOC_DAPM_PIN_SWITCH("Speaker"), -}; - -static int first_spk_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_card *card = rtd->card; - int ret; - - card->components = devm_kasprintf(card->dev, GFP_KERNEL, - "%s spk:rt1316", - card->components); - if (!card->components) - return -ENOMEM; - - ret = snd_soc_add_card_controls(card, rt1316_controls, - ARRAY_SIZE(rt1316_controls)); - if (ret) { - dev_err(card->dev, "rt1316 controls addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_new_controls(&card->dapm, rt1316_widgets, - ARRAY_SIZE(rt1316_widgets)); - if (ret) { - dev_err(card->dev, "rt1316 widgets addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_add_routes(&card->dapm, rt1316_map, 2); - if (ret) - dev_err(rtd->dev, "failed to add first SPK map: %d\n", ret); - - return ret; -} - -static int second_spk_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_card *card = rtd->card; - int ret; - - ret = snd_soc_dapm_add_routes(&card->dapm, rt1316_map + 2, 2); - if (ret) - dev_err(rtd->dev, "failed to add second SPK map: %d\n", ret); - - return ret; -} - -static int all_spk_init(struct snd_soc_pcm_runtime *rtd) -{ - int ret; - - ret = first_spk_init(rtd); - if (ret) - return ret; - - return second_spk_init(rtd); -} - -int sof_sdw_rt1316_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link) -{ - struct mc_private *ctx = snd_soc_card_get_drvdata(card); - - if (ctx->amp_dev1) { - device_remove_software_node(ctx->amp_dev1); - put_device(ctx->amp_dev1); - } - - if (ctx->amp_dev2) { - device_remove_software_node(ctx->amp_dev2); - put_device(ctx->amp_dev2); - } - - return 0; -} - -int sof_sdw_rt1316_init(struct snd_soc_card *card, - const struct snd_soc_acpi_link_adr *link, - struct snd_soc_dai_link *dai_links, - struct sof_sdw_codec_info *info, - bool playback) -{ - struct mc_private *ctx = snd_soc_card_get_drvdata(card); - struct device *sdw_dev1, *sdw_dev2; - int ret; - - /* Count amp number and do init on playback link only. */ - if (!playback) - return 0; - - info->amp_num++; - if (info->amp_num == 1) - dai_links->init = first_spk_init; - - if (info->amp_num == 2) { - sdw_dev1 = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[0].name); - if (!sdw_dev1) - return -EPROBE_DEFER; - - ret = rt1316_add_device_props(sdw_dev1); - if (ret < 0) { - put_device(sdw_dev1); - return ret; - } - ctx->amp_dev1 = sdw_dev1; - - sdw_dev2 = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[1].name); - if (!sdw_dev2) - return -EPROBE_DEFER; - - ret = rt1316_add_device_props(sdw_dev2); - if (ret < 0) { - put_device(sdw_dev2); - return ret; - } - ctx->amp_dev2 = sdw_dev2; - - /* - * if two 1316s are in one dai link, the init function - * in this dai link will be first set for the first speaker, - * and it should be reset to initialize all speakers when - * the second speaker is found. - */ - if (dai_links->init) - dai_links->init = all_spk_init; - else - dai_links->init = second_spk_init; - } - - return 0; -} diff --git a/sound/soc/intel/boards/sof_sdw_rt1318.c b/sound/soc/intel/boards/sof_sdw_rt1318.c deleted file mode 100644 index dbee4bf5c814..000000000000 --- a/sound/soc/intel/boards/sof_sdw_rt1318.c +++ /dev/null @@ -1,120 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// Copyright (c) 2022 Intel Corporation - -/* - * sof_sdw_rt1318 - Helpers to handle RT1318 from generic machine driver - */ - -#include -#include -#include -#include -#include -#include -#include "sof_sdw_common.h" - -static const struct snd_soc_dapm_widget rt1318_widgets[] = { - SND_SOC_DAPM_SPK("Speaker", NULL), -}; - -/* - * dapm routes for rt1318 will be registered dynamically according - * to the number of rt1318 used. The first two entries will be registered - * for one codec case, and the last two entries are also registered - * if two 1318s are used. - */ -static const struct snd_soc_dapm_route rt1318_map[] = { - { "Speaker", NULL, "rt1318-1 SPOL" }, - { "Speaker", NULL, "rt1318-1 SPOR" }, - { "Speaker", NULL, "rt1318-2 SPOL" }, - { "Speaker", NULL, "rt1318-2 SPOR" }, -}; - -static const struct snd_kcontrol_new rt1318_controls[] = { - SOC_DAPM_PIN_SWITCH("Speaker"), -}; - -static int first_spk_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_card *card = rtd->card; - int ret; - - card->components = devm_kasprintf(card->dev, GFP_KERNEL, - "%s spk:rt1318", - card->components); - if (!card->components) - return -ENOMEM; - - ret = snd_soc_add_card_controls(card, rt1318_controls, - ARRAY_SIZE(rt1318_controls)); - if (ret) { - dev_err(card->dev, "rt1318 controls addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_new_controls(&card->dapm, rt1318_widgets, - ARRAY_SIZE(rt1318_widgets)); - if (ret) { - dev_err(card->dev, "rt1318 widgets addition failed: %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_add_routes(&card->dapm, rt1318_map, 2); - if (ret) - dev_err(rtd->dev, "failed to add first SPK map: %d\n", ret); - - return ret; -} - -static int second_spk_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_card *card = rtd->card; - int ret; - - ret = snd_soc_dapm_add_routes(&card->dapm, rt1318_map + 2, 2); - if (ret) - dev_err(rtd->dev, "failed to add second SPK map: %d\n", ret); - - return ret; -} - -static int all_spk_init(struct snd_soc_pcm_runtime *rtd) -{ - int ret; - - ret = first_spk_init(rtd); - if (ret) - return ret; - - return second_spk_init(rtd); -} - -int sof_sdw_rt1318_init(struct snd_soc_card *card, - const struct snd_soc_acpi_link_adr *link, - struct snd_soc_dai_link *dai_links, - struct sof_sdw_codec_info *info, - bool playback) -{ - /* Count amp number and do init on playback link only. */ - if (!playback) - return 0; - - info->amp_num++; - if (info->amp_num == 1) - dai_links->init = first_spk_init; - - if (info->amp_num == 2) { - /* - * if two 1318s are in one dai link, the init function - * in this dai link will be first set for the first speaker, - * and it should be reset to initialize all speakers when - * the second speaker is found. - */ - if (dai_links->init) - dai_links->init = all_spk_init; - else - dai_links->init = second_spk_init; - } - - return 0; -} diff --git a/sound/soc/intel/boards/sof_sdw_rt_amp.c b/sound/soc/intel/boards/sof_sdw_rt_amp.c new file mode 100644 index 000000000000..26bf9e0dd3d2 --- /dev/null +++ b/sound/soc/intel/boards/sof_sdw_rt_amp.c @@ -0,0 +1,359 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2022 Intel Corporation + +/* + * sof_sdw_rt_amp - Helpers to handle RT1308/RT1316/RT1318 from generic machine driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sof_sdw_common.h" +#include "sof_sdw_amp_coeff_tables.h" +#include "../../codecs/rt1308.h" + +#define CODEC_NAME_SIZE 7 + +/* choose a larger value to resolve compatibility issues */ +#define RT_AMP_MAX_BQ_REG RT1316_MAX_BQ_REG + +struct rt_amp_platform_data { + const unsigned char *bq_params; + const unsigned int bq_params_cnt; +}; + +static const struct rt_amp_platform_data dell_0a5d_platform_data = { + .bq_params = dell_0a5d_bq_params, + .bq_params_cnt = ARRAY_SIZE(dell_0a5d_bq_params), +}; + +static const struct rt_amp_platform_data dell_0b00_platform_data = { + .bq_params = dell_0b00_bq_params, + .bq_params_cnt = ARRAY_SIZE(dell_0b00_bq_params), +}; + +static const struct dmi_system_id dmi_platform_data[] = { + /* CometLake devices */ + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990") + }, + .driver_data = (void *)&dell_0a5d_platform_data, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F") + }, + .driver_data = (void *)&dell_0a5d_platform_data, + }, + /* TigerLake devices */ + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5D") + }, + .driver_data = (void *)&dell_0a5d_platform_data, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5E") + }, + .driver_data = (void *)&dell_0a5d_platform_data, + }, + /* AlderLake devices */ + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B00") + }, + .driver_data = (void *)&dell_0b00_platform_data, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B01") + }, + .driver_data = (void *)&dell_0b00_platform_data, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AFF") + }, + .driver_data = (void *)&dell_0b00_platform_data, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AFE") + }, + .driver_data = (void *)&dell_0b00_platform_data, + }, + {}, +}; + +static int rt_amp_add_device_props(struct device *sdw_dev) +{ + struct property_entry props[3] = {}; + struct fwnode_handle *fwnode; + const struct dmi_system_id *dmi_data; + const struct rt_amp_platform_data *pdata; + unsigned char params[RT_AMP_MAX_BQ_REG]; + int ret; + + dmi_data = dmi_first_match(dmi_platform_data); + if (!dmi_data) + return 0; + + pdata = dmi_data->driver_data; + memcpy(¶ms, pdata->bq_params, sizeof(unsigned char) * pdata->bq_params_cnt); + + props[0] = PROPERTY_ENTRY_U8_ARRAY("realtek,bq-params", params); + props[1] = PROPERTY_ENTRY_U32("realtek,bq-params-cnt", pdata->bq_params_cnt); + + fwnode = fwnode_create_software_node(props, NULL); + if (IS_ERR(fwnode)) + return PTR_ERR(fwnode); + + ret = device_add_software_node(sdw_dev, to_software_node(fwnode)); + + fwnode_handle_put(fwnode); + + return ret; +} + +static const struct snd_kcontrol_new rt_amp_controls[] = { + SOC_DAPM_PIN_SWITCH("Speaker"), +}; + +static const struct snd_soc_dapm_widget rt_amp_widgets[] = { + SND_SOC_DAPM_SPK("Speaker", NULL), +}; + +/* + * dapm routes for rt1308/rt1316/rt1318 will be registered dynamically + * according to the number of rt1308/rt1316/rt1318 used. The first two + * entries will be registered for one codec case, and the last two entries + * are also registered if two 1308s/1316s/1318s are used. + */ +static const struct snd_soc_dapm_route rt1308_map[] = { + { "Speaker", NULL, "rt1308-1 SPOL" }, + { "Speaker", NULL, "rt1308-1 SPOR" }, + { "Speaker", NULL, "rt1308-2 SPOL" }, + { "Speaker", NULL, "rt1308-2 SPOR" }, +}; + +static const struct snd_soc_dapm_route rt1316_map[] = { + { "Speaker", NULL, "rt1316-1 SPOL" }, + { "Speaker", NULL, "rt1316-1 SPOR" }, + { "Speaker", NULL, "rt1316-2 SPOL" }, + { "Speaker", NULL, "rt1316-2 SPOR" }, +}; + +static const struct snd_soc_dapm_route rt1318_map[] = { + { "Speaker", NULL, "rt1318-1 SPOL" }, + { "Speaker", NULL, "rt1318-1 SPOR" }, + { "Speaker", NULL, "rt1318-2 SPOL" }, + { "Speaker", NULL, "rt1318-2 SPOR" }, +}; + +static const struct snd_soc_dapm_route *get_codec_name_and_route(struct snd_soc_pcm_runtime *rtd, + char *codec_name) +{ + const char *dai_name; + + dai_name = rtd->dai_link->codecs->dai_name; + + /* get the codec name */ + snprintf(codec_name, CODEC_NAME_SIZE, "%s", dai_name); + + /* choose the right codec's map */ + if (strcmp(codec_name, "rt1308") == 0) + return rt1308_map; + else if (strcmp(codec_name, "rt1316") == 0) + return rt1316_map; + else + return rt1318_map; +} + +static int first_spk_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + const struct snd_soc_dapm_route *rt_amp_map; + char codec_name[CODEC_NAME_SIZE]; + int ret; + + rt_amp_map = get_codec_name_and_route(rtd, codec_name); + + card->components = devm_kasprintf(card->dev, GFP_KERNEL, + "%s spk:%s", + card->components, codec_name); + if (!card->components) + return -ENOMEM; + + ret = snd_soc_add_card_controls(card, rt_amp_controls, + ARRAY_SIZE(rt_amp_controls)); + if (ret) { + dev_err(card->dev, "%s controls addition failed: %d\n", codec_name, ret); + return ret; + } + + ret = snd_soc_dapm_new_controls(&card->dapm, rt_amp_widgets, + ARRAY_SIZE(rt_amp_widgets)); + if (ret) { + dev_err(card->dev, "%s widgets addition failed: %d\n", codec_name, ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, rt_amp_map, 2); + if (ret) + dev_err(rtd->dev, "failed to add first SPK map: %d\n", ret); + + return ret; +} + +static int second_spk_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + const struct snd_soc_dapm_route *rt_amp_map; + char codec_name[CODEC_NAME_SIZE]; + int ret; + + rt_amp_map = get_codec_name_and_route(rtd, codec_name); + + ret = snd_soc_dapm_add_routes(&card->dapm, rt_amp_map + 2, 2); + if (ret) + dev_err(rtd->dev, "failed to add second SPK map: %d\n", ret); + + return ret; +} + +static int all_spk_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret; + + ret = first_spk_init(rtd); + if (ret) + return ret; + + return second_spk_init(rtd); +} + +static int rt1308_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_card *card = rtd->card; + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + int clk_id, clk_freq, pll_out; + int err; + + clk_id = RT1308_PLL_S_MCLK; + clk_freq = 38400000; + + pll_out = params_rate(params) * 512; + + /* Set rt1308 pll */ + err = snd_soc_dai_set_pll(codec_dai, 0, clk_id, clk_freq, pll_out); + if (err < 0) { + dev_err(card->dev, "Failed to set RT1308 PLL: %d\n", err); + return err; + } + + /* Set rt1308 sysclk */ + err = snd_soc_dai_set_sysclk(codec_dai, RT1308_FS_SYS_S_PLL, pll_out, + SND_SOC_CLOCK_IN); + if (err < 0) { + dev_err(card->dev, "Failed to set RT1308 SYSCLK: %d\n", err); + return err; + } + + return 0; +} + +/* machine stream operations */ +struct snd_soc_ops sof_sdw_rt1308_i2s_ops = { + .hw_params = rt1308_i2s_hw_params, +}; + +int sof_sdw_rt_amp_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link) +{ + struct mc_private *ctx = snd_soc_card_get_drvdata(card); + + if (ctx->amp_dev1) { + device_remove_software_node(ctx->amp_dev1); + put_device(ctx->amp_dev1); + } + + if (ctx->amp_dev2) { + device_remove_software_node(ctx->amp_dev2); + put_device(ctx->amp_dev2); + } + + return 0; +} + +int sof_sdw_rt_amp_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback) +{ + struct mc_private *ctx = snd_soc_card_get_drvdata(card); + struct device *sdw_dev1, *sdw_dev2; + int ret; + + /* Count amp number and do init on playback link only. */ + if (!playback) + return 0; + + info->amp_num++; + if (info->amp_num == 1) + dai_links->init = first_spk_init; + + if (info->amp_num == 2) { + sdw_dev1 = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[0].name); + if (!sdw_dev1) + return -EPROBE_DEFER; + + ret = rt_amp_add_device_props(sdw_dev1); + if (ret < 0) { + put_device(sdw_dev1); + return ret; + } + ctx->amp_dev1 = sdw_dev1; + + sdw_dev2 = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[1].name); + if (!sdw_dev2) + return -EPROBE_DEFER; + + ret = rt_amp_add_device_props(sdw_dev2); + if (ret < 0) { + put_device(sdw_dev2); + return ret; + } + ctx->amp_dev2 = sdw_dev2; + + /* + * if two amps are in one dai link, the init function + * in this dai link will be first set for the first speaker, + * and it should be reset to initialize all speakers when + * the second speaker is found. + */ + if (dai_links->init) + dai_links->init = all_spk_init; + else + dai_links->init = second_spk_init; + } + + return 0; +} -- cgit v1.2.3-70-g09d2 From 47d2b66fec133cb27da3a551334686e465d19469 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Tue, 6 Dec 2022 15:25:07 -0600 Subject: ASoC: Intel: sof_realtek_common: set ret = 0 as initial value 'ret' will not be initialized if dai_fmt is not DSP_A or DSP_B. Reviewed-by: Ranjani Sridharan Signed-off-by: Bard Liao Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20221206212507.359993-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_realtek_common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sound/soc/intel') diff --git a/sound/soc/intel/boards/sof_realtek_common.c b/sound/soc/intel/boards/sof_realtek_common.c index ff2851fc8930..6c12ca92f371 100644 --- a/sound/soc/intel/boards/sof_realtek_common.c +++ b/sound/soc/intel/boards/sof_realtek_common.c @@ -267,7 +267,8 @@ static int rt1015_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); struct snd_soc_dai_link *dai_link = rtd->dai_link; struct snd_soc_dai *codec_dai; - int i, clk_freq, ret; + int i, clk_freq; + int ret = 0; clk_freq = sof_dai_get_bclk(rtd); -- cgit v1.2.3-70-g09d2