diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-10-25 10:35:29 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-10-25 10:35:29 -0700 |
commit | 01154cc30e343952d7ab1c6b35c3577725dc5d54 (patch) | |
tree | 162f1f37ac93e674935d35c72587313f50c20682 | |
parent | fd143856b094b1798318d6816f37ea7380668c4c (diff) | |
parent | c9f7a144e7e3effd49303bfc58c07cc10ab2d573 (diff) |
Merge tag 'sound-6.12-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai:
"The majority of changes here are about ASoC.
There are two core changes in ASoC (the bump of minimal topology ABI
version and the fix for references of components in DAPM code), and
others are mostly various device-specific fixes for SoundWire, AMD,
Intel, SOF, Qualcomm and FSL, in addition to a few usual HD-audio
quirks and fixes"
* tag 'sound-6.12-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (33 commits)
ALSA: hda/realtek: Update default depop procedure
ASoC: qcom: sc7280: Fix missing Soundwire runtime stream alloc
ASoC: fsl_micfil: Add sample rate constraint
ASoC: rt722-sdca: increase clk_stop_timeout to fix clock stop issue
ALSA: hda/tas2781: select CRC32 instead of CRC32_SARWATE
ALSA: hda/realtek: Add subwoofer quirk for Acer Predator G9-593
ALSA: firewire-lib: Avoid division by zero in apply_constraint_to_size()
ASoC: fsl_micfil: Add a flag to distinguish with different volume control types
ASoC: codecs: lpass-rx-macro: fix RXn(rx,n) macro for DSM_CTL and SEC7 regs
ASoC: Change my e-mail to gmail
ASoC: Intel: soc-acpi: lnl: Add match entry for TM2 laptops
ASoC: amd: yc: Fix non-functional mic on ASUS E1404FA
ASoC: SOF: Intel: hda: Always clean up link DMA during stop
soundwire: intel_ace2x: Send PDI stream number during prepare
ASoC: SOF: Intel: hda: Handle prepare without close for non-HDA DAI's
ASoC: SOF: ipc4-topology: Do not set ALH node_id for aggregated DAIs
MAINTAINERS: Update maintainer list for MICROCHIP ASOC, SSC and MCP16502 drivers
ASoC: qcom: Select missing common Soundwire module code on SDM845
ASoC: fsl_esai: change dev_warn to dev_dbg in irq handler
ASoC: rsnd: Fix probe failure on HiHope boards due to endpoint parsing
...
35 files changed, 329 insertions, 111 deletions
diff --git a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml index ab3206ffa4af..beef193aaaeb 100644 --- a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml +++ b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml @@ -102,21 +102,21 @@ properties: default: 2 interrupts: - oneOf: - - minItems: 1 - items: - - description: TX interrupt - - description: RX interrupt - - items: - - description: common/combined interrupt + minItems: 1 + maxItems: 2 interrupt-names: oneOf: - - minItems: 1 + - description: TX interrupt + const: tx + - description: RX interrupt + const: rx + - description: TX and RX interrupts items: - const: tx - const: rx - - const: common + - description: Common/combined interrupt + const: common fck_parent: $ref: /schemas/types.yaml#/definitions/string diff --git a/MAINTAINERS b/MAINTAINERS index 6880a8fac74c..c3255e9a5010 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14986,6 +14986,7 @@ F: drivers/spi/spi-at91-usart.c MICROCHIP AUDIO ASOC DRIVERS M: Claudiu Beznea <claudiu.beznea@tuxon.dev> +M: Andrei Simion <andrei.simion@microchip.com> L: linux-sound@vger.kernel.org S: Supported F: Documentation/devicetree/bindings/sound/atmel* @@ -15094,6 +15095,7 @@ F: include/video/atmel_lcdc.h MICROCHIP MCP16502 PMIC DRIVER M: Claudiu Beznea <claudiu.beznea@tuxon.dev> +M: Andrei Simion <andrei.simion@microchip.com> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Supported F: Documentation/devicetree/bindings/regulator/microchip,mcp16502.yaml @@ -15224,6 +15226,7 @@ F: drivers/spi/spi-atmel.* MICROCHIP SSC DRIVER M: Claudiu Beznea <claudiu.beznea@tuxon.dev> +M: Andrei Simion <andrei.simion@microchip.com> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Supported F: Documentation/devicetree/bindings/misc/atmel-ssc.txt @@ -23145,7 +23148,7 @@ F: Documentation/devicetree/bindings/iio/adc/ti,lmp92064.yaml F: drivers/iio/adc/ti-lmp92064.c TI PCM3060 ASoC CODEC DRIVER -M: Kirill Marinushkin <kmarinushkin@birdec.com> +M: Kirill Marinushkin <k.marinushkin@gmail.com> L: linux-sound@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/sound/pcm3060.txt diff --git a/drivers/soundwire/intel_ace2x.c b/drivers/soundwire/intel_ace2x.c index fff312c6968d..4f3dd70d6a1a 100644 --- a/drivers/soundwire/intel_ace2x.c +++ b/drivers/soundwire/intel_ace2x.c @@ -376,11 +376,12 @@ static int intel_hw_params(struct snd_pcm_substream *substream, static int intel_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai); struct sdw_intel *sdw = cdns_to_intel(cdns); struct sdw_cdns_dai_runtime *dai_runtime; + struct snd_pcm_hw_params *hw_params; int ch, dir; - int ret = 0; dai_runtime = cdns->dai_runtime_array[dai->id]; if (!dai_runtime) { @@ -389,12 +390,8 @@ static int intel_prepare(struct snd_pcm_substream *substream, return -EIO; } + hw_params = &rtd->dpcm[substream->stream].hw_params; if (dai_runtime->suspended) { - struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); - struct snd_pcm_hw_params *hw_params; - - hw_params = &rtd->dpcm[substream->stream].hw_params; - dai_runtime->suspended = false; /* @@ -415,15 +412,11 @@ static int intel_prepare(struct snd_pcm_substream *substream, /* the SHIM will be configured in the callback functions */ sdw_cdns_config_stream(cdns, ch, dir, dai_runtime->pdi); - - /* Inform DSP about PDI stream number */ - ret = intel_params_stream(sdw, substream, dai, - hw_params, - sdw->instance, - dai_runtime->pdi->intel_alh_id); } - return ret; + /* Inform DSP about PDI stream number */ + return intel_params_stream(sdw, substream, dai, hw_params, sdw->instance, + dai_runtime->pdi->intel_alh_id); } static int diff --git a/include/uapi/sound/asoc.h b/include/uapi/sound/asoc.h index 99333cbd3114..c117672d4439 100644 --- a/include/uapi/sound/asoc.h +++ b/include/uapi/sound/asoc.h @@ -88,7 +88,7 @@ /* ABI version */ #define SND_SOC_TPLG_ABI_VERSION 0x5 /* current version */ -#define SND_SOC_TPLG_ABI_VERSION_MIN 0x4 /* oldest version supported */ +#define SND_SOC_TPLG_ABI_VERSION_MIN 0x5 /* oldest version supported */ /* Max size of TLV data */ #define SND_SOC_TPLG_TLV_SIZE 32 diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c index c72b2a754775..7fc51f829ecc 100644 --- a/sound/firewire/amdtp-stream.c +++ b/sound/firewire/amdtp-stream.c @@ -172,6 +172,9 @@ static int apply_constraint_to_size(struct snd_pcm_hw_params *params, step = max(step, amdtp_syt_intervals[i]); } + if (step == 0) + return -EINVAL; + t.min = roundup(s->min, step); t.max = rounddown(s->max, step); t.integer = 1; diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index bb15a0248250..68f1eee9e5c9 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig @@ -198,7 +198,7 @@ config SND_HDA_SCODEC_TAS2781_I2C depends on SND_SOC select SND_SOC_TAS2781_COMLIB select SND_SOC_TAS2781_FMWLIB - select CRC32_SARWATE + select CRC32 help Say Y or M here to include TAS2781 I2C HD-audio side codec support in snd-hda-intel driver, such as ALC287. diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 3bbf5fab2881..3567b14b52b7 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3868,20 +3868,18 @@ static void alc_default_init(struct hda_codec *codec) hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); - if (hp_pin_sense) + if (hp_pin_sense) { msleep(2); - snd_hda_codec_write(codec, hp_pin, 0, - AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); - - if (hp_pin_sense) - msleep(85); + snd_hda_codec_write(codec, hp_pin, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); - snd_hda_codec_write(codec, hp_pin, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + msleep(75); - if (hp_pin_sense) - msleep(100); + snd_hda_codec_write(codec, hp_pin, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); + msleep(75); + } } static void alc_default_shutup(struct hda_codec *codec) @@ -3897,22 +3895,20 @@ static void alc_default_shutup(struct hda_codec *codec) hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); - if (hp_pin_sense) + if (hp_pin_sense) { msleep(2); - snd_hda_codec_write(codec, hp_pin, 0, - AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); - - if (hp_pin_sense) - msleep(85); - - if (!spec->no_shutup_pins) snd_hda_codec_write(codec, hp_pin, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); - if (hp_pin_sense) - msleep(100); + msleep(75); + if (!spec->no_shutup_pins) + snd_hda_codec_write(codec, hp_pin, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); + + msleep(75); + } alc_auto_setup_eapd(codec, false); alc_shutup_pins(codec); } @@ -7649,6 +7645,7 @@ enum { ALC286_FIXUP_ACER_AIO_HEADSET_MIC, ALC256_FIXUP_ASUS_HEADSET_MIC, ALC256_FIXUP_ASUS_MIC_NO_PRESENCE, + ALC255_FIXUP_PREDATOR_SUBWOOFER, ALC299_FIXUP_PREDATOR_SPK, ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE, ALC289_FIXUP_DELL_SPK1, @@ -9063,6 +9060,13 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE }, + [ALC255_FIXUP_PREDATOR_SUBWOOFER] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x17, 0x90170151 }, /* use as internal speaker (LFE) */ + { 0x1b, 0x90170152 } /* use as internal speaker (back) */ + } + }, [ALC299_FIXUP_PREDATOR_SPK] = { .type = HDA_FIXUP_PINS, .v.pins = (const struct hda_pintbl[]) { @@ -10150,6 +10154,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x110e, "Acer Aspire ES1-432", ALC255_FIXUP_ACER_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1025, 0x1166, "Acer Veriton N4640G", ALC269_FIXUP_LIFEBOOK), SND_PCI_QUIRK(0x1025, 0x1167, "Acer Veriton N6640G", ALC269_FIXUP_LIFEBOOK), + SND_PCI_QUIRK(0x1025, 0x1177, "Acer Predator G9-593", ALC255_FIXUP_PREDATOR_SUBWOOFER), + SND_PCI_QUIRK(0x1025, 0x1178, "Acer Predator G9-593", ALC255_FIXUP_PREDATOR_SUBWOOFER), SND_PCI_QUIRK(0x1025, 0x1246, "Acer Predator Helios 500", ALC299_FIXUP_PREDATOR_SPK), SND_PCI_QUIRK(0x1025, 0x1247, "Acer vCopperbox", ALC269VC_FIXUP_ACER_VCOPPERBOX_PINS), SND_PCI_QUIRK(0x1025, 0x1248, "Acer Veriton N4660G", ALC269VC_FIXUP_ACER_MIC_NO_PRESENCE), diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c index ace6328e91e3..438865d5e376 100644 --- a/sound/soc/amd/yc/acp6x-mach.c +++ b/sound/soc/amd/yc/acp6x-mach.c @@ -329,6 +329,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { .driver_data = &acp6x_card, .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "E1404FA"), + } + }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_PRODUCT_NAME, "E1504FA"), } }, @@ -342,6 +349,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { { .driver_data = &acp6x_card, .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "M3502RA"), + } + }, + { + .driver_data = &acp6x_card, + .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "Micro-Star International Co., Ltd."), DMI_MATCH(DMI_PRODUCT_NAME, "Bravo 15 B7ED"), } diff --git a/sound/soc/codecs/aw88399.c b/sound/soc/codecs/aw88399.c index 8dc2b8aa6832..bba59885242d 100644 --- a/sound/soc/codecs/aw88399.c +++ b/sound/soc/codecs/aw88399.c @@ -656,7 +656,7 @@ static int aw_dev_get_dsp_status(struct aw_device *aw_dev) if (ret) return ret; if (!(reg_val & (~AW88399_WDT_CNT_MASK))) - ret = -EPERM; + return -EPERM; return 0; } diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c index ef7a70fa6966..febbbe073962 100644 --- a/sound/soc/codecs/lpass-rx-macro.c +++ b/sound/soc/codecs/lpass-rx-macro.c @@ -202,12 +202,14 @@ #define CDC_RX_RXn_RX_PATH_SEC3(rx, n) (0x042c + rx->rxn_reg_stride * n) #define CDC_RX_RX0_RX_PATH_SEC4 (0x0430) #define CDC_RX_RX0_RX_PATH_SEC7 (0x0434) -#define CDC_RX_RXn_RX_PATH_SEC7(rx, n) (0x0434 + rx->rxn_reg_stride * n) +#define CDC_RX_RXn_RX_PATH_SEC7(rx, n) \ + (0x0434 + (rx->rxn_reg_stride * n) + ((n > 1) ? rx->rxn_reg_stride2 : 0)) #define CDC_RX_DSM_OUT_DELAY_SEL_MASK GENMASK(2, 0) #define CDC_RX_DSM_OUT_DELAY_TWO_SAMPLE 0x2 #define CDC_RX_RX0_RX_PATH_MIX_SEC0 (0x0438) #define CDC_RX_RX0_RX_PATH_MIX_SEC1 (0x043C) -#define CDC_RX_RXn_RX_PATH_DSM_CTL(rx, n) (0x0440 + rx->rxn_reg_stride * n) +#define CDC_RX_RXn_RX_PATH_DSM_CTL(rx, n) \ + (0x0440 + (rx->rxn_reg_stride * n) + ((n > 1) ? rx->rxn_reg_stride2 : 0)) #define CDC_RX_RXn_DSM_CLK_EN_MASK BIT(0) #define CDC_RX_RX0_RX_PATH_DSM_CTL (0x0440) #define CDC_RX_RX0_RX_PATH_DSM_DATA1 (0x0444) @@ -645,6 +647,7 @@ struct rx_macro { int rx_mclk_cnt; enum lpass_codec_version codec_version; int rxn_reg_stride; + int rxn_reg_stride2; bool is_ear_mode_on; bool hph_pwr_mode; bool hph_hd2_mode; @@ -1929,9 +1932,6 @@ static int rx_macro_digital_mute(struct snd_soc_dai *dai, int mute, int stream) CDC_RX_PATH_PGA_MUTE_MASK, 0x0); } - if (j == INTERP_AUX) - dsm_reg = CDC_RX_RXn_RX_PATH_DSM_CTL(rx, 2); - int_mux_cfg0 = CDC_RX_INP_MUX_RX_INT0_CFG0 + j * 8; int_mux_cfg1 = int_mux_cfg0 + 4; int_mux_cfg0_val = snd_soc_component_read(component, int_mux_cfg0); @@ -2702,9 +2702,6 @@ static int rx_macro_enable_interp_clk(struct snd_soc_component *component, main_reg = CDC_RX_RXn_RX_PATH_CTL(rx, interp_idx); dsm_reg = CDC_RX_RXn_RX_PATH_DSM_CTL(rx, interp_idx); - if (interp_idx == INTERP_AUX) - dsm_reg = CDC_RX_RXn_RX_PATH_DSM_CTL(rx, 2); - rx_cfg2_reg = CDC_RX_RXn_RX_PATH_CFG2(rx, interp_idx); if (SND_SOC_DAPM_EVENT_ON(event)) { @@ -3821,6 +3818,7 @@ static int rx_macro_probe(struct platform_device *pdev) case LPASS_CODEC_VERSION_2_0: case LPASS_CODEC_VERSION_2_1: rx->rxn_reg_stride = 0x80; + rx->rxn_reg_stride2 = 0xc; def_count = ARRAY_SIZE(rx_defaults) + ARRAY_SIZE(rx_pre_2_5_defaults); reg_defaults = kmalloc_array(def_count, sizeof(struct reg_default), GFP_KERNEL); if (!reg_defaults) @@ -3834,6 +3832,7 @@ static int rx_macro_probe(struct platform_device *pdev) case LPASS_CODEC_VERSION_2_7: case LPASS_CODEC_VERSION_2_8: rx->rxn_reg_stride = 0xc0; + rx->rxn_reg_stride2 = 0x0; def_count = ARRAY_SIZE(rx_defaults) + ARRAY_SIZE(rx_2_5_defaults); reg_defaults = kmalloc_array(def_count, sizeof(struct reg_default), GFP_KERNEL); if (!reg_defaults) diff --git a/sound/soc/codecs/max98388.c b/sound/soc/codecs/max98388.c index b847d7c59ec0..99986090b4a6 100644 --- a/sound/soc/codecs/max98388.c +++ b/sound/soc/codecs/max98388.c @@ -763,6 +763,7 @@ static int max98388_dai_tdm_slot(struct snd_soc_dai *dai, addr = MAX98388_R2044_PCM_TX_CTRL1 + (cnt / 8); bits = cnt % 8; regmap_update_bits(max98388->regmap, addr, bits, bits); + slot_found++; if (slot_found >= MAX_NUM_CH) break; } diff --git a/sound/soc/codecs/pcm3060-i2c.c b/sound/soc/codecs/pcm3060-i2c.c index 5330cf46b127..3816b25a8ead 100644 --- a/sound/soc/codecs/pcm3060-i2c.c +++ b/sound/soc/codecs/pcm3060-i2c.c @@ -2,7 +2,7 @@ // // PCM3060 I2C driver // -// Copyright (C) 2018 Kirill Marinushkin <kmarinushkin@birdec.com> +// Copyright (C) 2018 Kirill Marinushkin <k.marinushkin@gmail.com> #include <linux/i2c.h> #include <linux/module.h> @@ -55,5 +55,5 @@ static struct i2c_driver pcm3060_i2c_driver = { module_i2c_driver(pcm3060_i2c_driver); MODULE_DESCRIPTION("PCM3060 I2C driver"); -MODULE_AUTHOR("Kirill Marinushkin <kmarinushkin@birdec.com>"); +MODULE_AUTHOR("Kirill Marinushkin <k.marinushkin@gmail.com>"); MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/pcm3060-spi.c b/sound/soc/codecs/pcm3060-spi.c index 3b79734b832b..6095841f2f56 100644 --- a/sound/soc/codecs/pcm3060-spi.c +++ b/sound/soc/codecs/pcm3060-spi.c @@ -2,7 +2,7 @@ // // PCM3060 SPI driver // -// Copyright (C) 2018 Kirill Marinushkin <kmarinushkin@birdec.com> +// Copyright (C) 2018 Kirill Marinushkin <k.marinushkin@gmail.com> #include <linux/module.h> #include <linux/spi/spi.h> @@ -55,5 +55,5 @@ static struct spi_driver pcm3060_spi_driver = { module_spi_driver(pcm3060_spi_driver); MODULE_DESCRIPTION("PCM3060 SPI driver"); -MODULE_AUTHOR("Kirill Marinushkin <kmarinushkin@birdec.com>"); +MODULE_AUTHOR("Kirill Marinushkin <k.marinushkin@gmail.com>"); MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/pcm3060.c b/sound/soc/codecs/pcm3060.c index 586ec8c7246c..8974200652e7 100644 --- a/sound/soc/codecs/pcm3060.c +++ b/sound/soc/codecs/pcm3060.c @@ -2,7 +2,7 @@ // // PCM3060 codec driver // -// Copyright (C) 2018 Kirill Marinushkin <kmarinushkin@birdec.com> +// Copyright (C) 2018 Kirill Marinushkin <k.marinushkin@gmail.com> #include <linux/module.h> #include <sound/pcm_params.h> @@ -343,5 +343,5 @@ int pcm3060_probe(struct device *dev) EXPORT_SYMBOL(pcm3060_probe); MODULE_DESCRIPTION("PCM3060 codec driver"); -MODULE_AUTHOR("Kirill Marinushkin <kmarinushkin@birdec.com>"); +MODULE_AUTHOR("Kirill Marinushkin <k.marinushkin@gmail.com>"); MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/pcm3060.h b/sound/soc/codecs/pcm3060.h index 5e1185e7b03d..1b96835600b4 100644 --- a/sound/soc/codecs/pcm3060.h +++ b/sound/soc/codecs/pcm3060.h @@ -2,7 +2,7 @@ /* * PCM3060 codec driver * - * Copyright (C) 2018 Kirill Marinushkin <kmarinushkin@birdec.com> + * Copyright (C) 2018 Kirill Marinushkin <k.marinushkin@gmail.com> */ #ifndef _SND_SOC_PCM3060_H diff --git a/sound/soc/codecs/rt722-sdca-sdw.c b/sound/soc/codecs/rt722-sdca-sdw.c index 87354bb1564e..d5c985ff5ac5 100644 --- a/sound/soc/codecs/rt722-sdca-sdw.c +++ b/sound/soc/codecs/rt722-sdca-sdw.c @@ -253,7 +253,7 @@ static int rt722_sdca_read_prop(struct sdw_slave *slave) } /* set the timeout values */ - prop->clk_stop_timeout = 200; + prop->clk_stop_timeout = 900; /* wake-up event */ prop->wake_capable = 1; diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index a65f5b9935a2..0b247f16a163 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -119,10 +119,10 @@ static irqreturn_t esai_isr(int irq, void *devid) dev_dbg(&pdev->dev, "isr: Transmission Initialized\n"); if (esr & ESAI_ESR_RFF_MASK) - dev_warn(&pdev->dev, "isr: Receiving overrun\n"); + dev_dbg(&pdev->dev, "isr: Receiving overrun\n"); if (esr & ESAI_ESR_TFE_MASK) - dev_warn(&pdev->dev, "isr: Transmission underrun\n"); + dev_dbg(&pdev->dev, "isr: Transmission underrun\n"); if (esr & ESAI_ESR_TLS_MASK) dev_dbg(&pdev->dev, "isr: Just transmitted the last slot\n"); diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c index 193be098fa5e..0c71a73476df 100644 --- a/sound/soc/fsl/fsl_micfil.c +++ b/sound/soc/fsl/fsl_micfil.c @@ -28,6 +28,13 @@ #define MICFIL_OSR_DEFAULT 16 +#define MICFIL_NUM_RATES 7 +#define MICFIL_CLK_SRC_NUM 3 +/* clock source ids */ +#define MICFIL_AUDIO_PLL1 0 +#define MICFIL_AUDIO_PLL2 1 +#define MICFIL_CLK_EXT3 2 + enum quality { QUALITY_HIGH, QUALITY_MEDIUM, @@ -45,9 +52,12 @@ struct fsl_micfil { struct clk *mclk; struct clk *pll8k_clk; struct clk *pll11k_clk; + struct clk *clk_src[MICFIL_CLK_SRC_NUM]; struct snd_dmaengine_dai_dma_data dma_params_rx; struct sdma_peripheral_config sdmacfg; struct snd_soc_card *card; + struct snd_pcm_hw_constraint_list constraint_rates; + unsigned int constraint_rates_list[MICFIL_NUM_RATES]; unsigned int dataline; char name[32]; int irq[MICFIL_IRQ_LINES]; @@ -67,6 +77,7 @@ struct fsl_micfil_soc_data { bool imx; bool use_edma; bool use_verid; + bool volume_sx; u64 formats; }; @@ -76,6 +87,7 @@ static struct fsl_micfil_soc_data fsl_micfil_imx8mm = { .fifo_depth = 8, .dataline = 0xf, .formats = SNDRV_PCM_FMTBIT_S16_LE, + .volume_sx = true, }; static struct fsl_micfil_soc_data fsl_micfil_imx8mp = { @@ -84,6 +96,7 @@ static struct fsl_micfil_soc_data fsl_micfil_imx8mp = { .fifo_depth = 32, .dataline = 0xf, .formats = SNDRV_PCM_FMTBIT_S32_LE, + .volume_sx = false, }; static struct fsl_micfil_soc_data fsl_micfil_imx93 = { @@ -94,6 +107,7 @@ static struct fsl_micfil_soc_data fsl_micfil_imx93 = { .formats = SNDRV_PCM_FMTBIT_S32_LE, .use_edma = true, .use_verid = true, + .volume_sx = false, }; static const struct of_device_id fsl_micfil_dt_ids[] = { @@ -317,7 +331,26 @@ static int hwvad_detected(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = { +static const struct snd_kcontrol_new fsl_micfil_volume_controls[] = { + SOC_SINGLE_TLV("CH0 Volume", REG_MICFIL_OUT_CTRL, + MICFIL_OUTGAIN_CHX_SHIFT(0), 0xF, 0, gain_tlv), + SOC_SINGLE_TLV("CH1 Volume", REG_MICFIL_OUT_CTRL, + MICFIL_OUTGAIN_CHX_SHIFT(1), 0xF, 0, gain_tlv), + SOC_SINGLE_TLV("CH2 Volume", REG_MICFIL_OUT_CTRL, + MICFIL_OUTGAIN_CHX_SHIFT(2), 0xF, 0, gain_tlv), + SOC_SINGLE_TLV("CH3 Volume", REG_MICFIL_OUT_CTRL, + MICFIL_OUTGAIN_CHX_SHIFT(3), 0xF, 0, gain_tlv), + SOC_SINGLE_TLV("CH4 Volume", REG_MICFIL_OUT_CTRL, + MICFIL_OUTGAIN_CHX_SHIFT(4), 0xF, 0, gain_tlv), + SOC_SINGLE_TLV("CH5 Volume", REG_MICFIL_OUT_CTRL, + MICFIL_OUTGAIN_CHX_SHIFT(5), 0xF, 0, gain_tlv), + SOC_SINGLE_TLV("CH6 Volume", REG_MICFIL_OUT_CTRL, + MICFIL_OUTGAIN_CHX_SHIFT(6), 0xF, 0, gain_tlv), + SOC_SINGLE_TLV("CH7 Volume", REG_MICFIL_OUT_CTRL, + MICFIL_OUTGAIN_CHX_SHIFT(7), 0xF, 0, gain_tlv), +}; + +static const struct snd_kcontrol_new fsl_micfil_volume_sx_controls[] = { SOC_SINGLE_SX_TLV("CH0 Volume", REG_MICFIL_OUT_CTRL, MICFIL_OUTGAIN_CHX_SHIFT(0), 0x8, 0xF, gain_tlv), SOC_SINGLE_SX_TLV("CH1 Volume", REG_MICFIL_OUT_CTRL, @@ -334,6 +367,9 @@ static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = { MICFIL_OUTGAIN_CHX_SHIFT(6), 0x8, 0xF, gain_tlv), SOC_SINGLE_SX_TLV("CH7 Volume", REG_MICFIL_OUT_CTRL, MICFIL_OUTGAIN_CHX_SHIFT(7), 0x8, 0xF, gain_tlv), +}; + +static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = { SOC_ENUM_EXT("MICFIL Quality Select", fsl_micfil_quality_enum, micfil_quality_get, micfil_quality_set), @@ -449,12 +485,34 @@ static int fsl_micfil_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct fsl_micfil *micfil = snd_soc_dai_get_drvdata(dai); + unsigned int rates[MICFIL_NUM_RATES] = {8000, 11025, 16000, 22050, 32000, 44100, 48000}; + int i, j, k = 0; + u64 clk_rate; if (!micfil) { dev_err(dai->dev, "micfil dai priv_data not set\n"); return -EINVAL; } + micfil->constraint_rates.list = micfil->constraint_rates_list; + micfil->constraint_rates.count = 0; + + for (j = 0; j < MICFIL_NUM_RATES; j++) { + for (i = 0; i < MICFIL_CLK_SRC_NUM; i++) { + clk_rate = clk_get_rate(micfil->clk_src[i]); + if (clk_rate != 0 && do_div(clk_rate, rates[j]) == 0) { + micfil->constraint_rates_list[k++] = rates[j]; + micfil->constraint_rates.count++; + break; + } + } + } + + if (micfil->constraint_rates.count > 0) + snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &micfil->constraint_rates); + return 0; } @@ -801,6 +859,20 @@ static int fsl_micfil_dai_probe(struct snd_soc_dai *cpu_dai) return 0; } +static int fsl_micfil_component_probe(struct snd_soc_component *component) +{ + struct fsl_micfil *micfil = snd_soc_component_get_drvdata(component); + + if (micfil->soc->volume_sx) + snd_soc_add_component_controls(component, fsl_micfil_volume_sx_controls, + ARRAY_SIZE(fsl_micfil_volume_sx_controls)); + else + snd_soc_add_component_controls(component, fsl_micfil_volume_controls, + ARRAY_SIZE(fsl_micfil_volume_controls)); + + return 0; +} + static const struct snd_soc_dai_ops fsl_micfil_dai_ops = { .probe = fsl_micfil_dai_probe, .startup = fsl_micfil_startup, @@ -821,6 +893,7 @@ static struct snd_soc_dai_driver fsl_micfil_dai = { static const struct snd_soc_component_driver fsl_micfil_component = { .name = "fsl-micfil-dai", + .probe = fsl_micfil_component_probe, .controls = fsl_micfil_snd_controls, .num_controls = ARRAY_SIZE(fsl_micfil_snd_controls), .legacy_dai_naming = 1, @@ -1134,6 +1207,12 @@ static int fsl_micfil_probe(struct platform_device *pdev) fsl_asoc_get_pll_clocks(&pdev->dev, &micfil->pll8k_clk, &micfil->pll11k_clk); + micfil->clk_src[MICFIL_AUDIO_PLL1] = micfil->pll8k_clk; + micfil->clk_src[MICFIL_AUDIO_PLL2] = micfil->pll11k_clk; + micfil->clk_src[MICFIL_CLK_EXT3] = devm_clk_get(&pdev->dev, "clkext3"); + if (IS_ERR(micfil->clk_src[MICFIL_CLK_EXT3])) + micfil->clk_src[MICFIL_CLK_EXT3] = NULL; + /* init regmap */ regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(regs)) diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c index da7bac09acb4..73d4bde9b2f7 100644 --- a/sound/soc/intel/avs/core.c +++ b/sound/soc/intel/avs/core.c @@ -28,6 +28,7 @@ #include "avs.h" #include "cldma.h" #include "messages.h" +#include "pcm.h" static u32 pgctl_mask = AZX_PGCTL_LSRMD_MASK; module_param(pgctl_mask, uint, 0444); @@ -247,7 +248,7 @@ static void hdac_stream_update_pos(struct hdac_stream *stream, u64 buffer_size) static void hdac_update_stream(struct hdac_bus *bus, struct hdac_stream *stream) { if (stream->substream) { - snd_pcm_period_elapsed(stream->substream); + avs_period_elapsed(stream->substream); } else if (stream->cstream) { u64 buffer_size = stream->cstream->runtime->buffer_size; diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c index afc0fc74cf94..4af811580356 100644 --- a/sound/soc/intel/avs/pcm.c +++ b/sound/soc/intel/avs/pcm.c @@ -16,6 +16,7 @@ #include <sound/soc-component.h> #include "avs.h" #include "path.h" +#include "pcm.h" #include "topology.h" #include "../../codecs/hda.h" @@ -30,6 +31,7 @@ struct avs_dma_data { struct hdac_ext_stream *host_stream; }; + struct work_struct period_elapsed_work; struct snd_pcm_substream *substream; }; @@ -56,6 +58,22 @@ avs_dai_find_path_template(struct snd_soc_dai *dai, bool is_fe, int direction) return dw->priv; } +static void avs_period_elapsed_work(struct work_struct *work) +{ + struct avs_dma_data *data = container_of(work, struct avs_dma_data, period_elapsed_work); + + snd_pcm_period_elapsed(data->substream); +} + +void avs_period_elapsed(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0); + struct avs_dma_data *data = snd_soc_dai_get_dma_data(dai, substream); + + schedule_work(&data->period_elapsed_work); +} + static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); @@ -77,6 +95,7 @@ static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_d data->substream = substream; data->template = template; data->adev = adev; + INIT_WORK(&data->period_elapsed_work, avs_period_elapsed_work); snd_soc_dai_set_dma_data(dai, substream, data); if (rtd->dai_link->ignore_suspend) diff --git a/sound/soc/intel/avs/pcm.h b/sound/soc/intel/avs/pcm.h new file mode 100644 index 000000000000..0f3615c90398 --- /dev/null +++ b/sound/soc/intel/avs/pcm.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright(c) 2024 Intel Corporation + * + * Authors: Cezary Rojewski <cezary.rojewski@intel.com> + * Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com> + */ + +#ifndef __SOUND_SOC_INTEL_AVS_PCM_H +#define __SOUND_SOC_INTEL_AVS_PCM_H + +#include <sound/pcm.h> + +void avs_period_elapsed(struct snd_pcm_substream *substream); + +#endif diff --git a/sound/soc/intel/common/soc-acpi-intel-lnl-match.c b/sound/soc/intel/common/soc-acpi-intel-lnl-match.c index 3c4e0c7ca8ee..094ed4b27cb0 100644 --- a/sound/soc/intel/common/soc-acpi-intel-lnl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-lnl-match.c @@ -225,6 +225,15 @@ static const struct snd_soc_acpi_adr_device rt1316_3_group1_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt1318_1_adr[] = { + { + .adr = 0x000133025D131801ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt1318-1" + } +}; + static const struct snd_soc_acpi_adr_device rt1318_1_group1_adr[] = { { .adr = 0x000130025D131801ull, @@ -243,6 +252,15 @@ static const struct snd_soc_acpi_adr_device rt1318_2_group1_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt713_0_adr[] = { + { + .adr = 0x000031025D071301ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt713" + } +}; + static const struct snd_soc_acpi_adr_device rt714_0_adr[] = { { .adr = 0x000030025D071401ull, @@ -378,6 +396,20 @@ static const struct snd_soc_acpi_link_adr lnl_sdw_rt1318_l12_rt714_l0[] = { {} }; +static const struct snd_soc_acpi_link_adr lnl_sdw_rt713_l0_rt1318_l1[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt713_0_adr), + .adr_d = rt713_0_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1318_1_adr), + .adr_d = rt1318_1_adr, + }, + {} +}; + /* this table is used when there is no I2S codec present */ struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_sdw_machines[] = { /* mockup tests need to be first */ @@ -447,6 +479,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_sdw_machines[] = { .drv_name = "sof_sdw", .sof_tplg_filename = "sof-lnl-rt1318-l12-rt714-l0.tplg" }, + { + .link_mask = BIT(0) | BIT(1), + .links = lnl_sdw_rt713_l0_rt1318_l1, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-lnl-rt713-l0-rt1318-l1.tplg" + }, {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_lnl_sdw_machines); diff --git a/sound/soc/loongson/loongson_card.c b/sound/soc/loongson/loongson_card.c index 7379f24d385c..7910d5d9ac4f 100644 --- a/sound/soc/loongson/loongson_card.c +++ b/sound/soc/loongson/loongson_card.c @@ -144,6 +144,7 @@ static int loongson_card_parse_of(struct loongson_card_data *data) dev_err(dev, "getting cpu dlc error (%d)\n", ret); goto err; } + loongson_dai_links[i].platforms->of_node = loongson_dai_links[i].cpus->of_node; ret = snd_soc_of_get_dlc(codec, NULL, loongson_dai_links[i].codecs, 0); if (ret < 0) { diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index 762491d6f2f2..ca7a30ebd26a 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig @@ -157,6 +157,7 @@ config SND_SOC_SDM845 depends on COMMON_CLK select SND_SOC_QDSP6 select SND_SOC_QCOM_COMMON + select SND_SOC_QCOM_SDW select SND_SOC_RT5663 select SND_SOC_MAX98927 imply SND_SOC_CROS_EC_CODEC @@ -208,6 +209,7 @@ config SND_SOC_SC7280 tristate "SoC Machine driver for SC7280 boards" depends on I2C && SOUNDWIRE select SND_SOC_QCOM_COMMON + select SND_SOC_QCOM_SDW select SND_SOC_LPASS_SC7280 select SND_SOC_MAX98357A select SND_SOC_WCD938X_SDW diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c index 5a47f661e0c6..242bc16da36d 100644 --- a/sound/soc/qcom/lpass-cpu.c +++ b/sound/soc/qcom/lpass-cpu.c @@ -1242,6 +1242,8 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) /* Allocation for i2sctl regmap fields */ drvdata->i2sctl = devm_kzalloc(&pdev->dev, sizeof(struct lpaif_i2sctl), GFP_KERNEL); + if (!drvdata->i2sctl) + return -ENOMEM; /* Initialize bitfields for dai I2SCTL register */ ret = lpass_cpu_init_i2sctl_bitfields(dev, drvdata->i2sctl, diff --git a/sound/soc/qcom/sc7280.c b/sound/soc/qcom/sc7280.c index 207ac5da4dd4..230af8d7b205 100644 --- a/sound/soc/qcom/sc7280.c +++ b/sound/soc/qcom/sc7280.c @@ -23,6 +23,7 @@ #include "common.h" #include "lpass.h" #include "qdsp6/q6afe.h" +#include "sdw.h" #define DEFAULT_MCLK_RATE 19200000 #define RT5682_PLL_FREQ (48000 * 512) @@ -316,6 +317,7 @@ static void sc7280_snd_shutdown(struct snd_pcm_substream *substream) struct snd_soc_card *card = rtd->card; struct sc7280_snd_data *data = snd_soc_card_get_drvdata(card); struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); + struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; switch (cpu_dai->id) { case MI2S_PRIMARY: @@ -333,6 +335,9 @@ static void sc7280_snd_shutdown(struct snd_pcm_substream *substream) default: break; } + + data->sruntime[cpu_dai->id] = NULL; + sdw_release_stream(sruntime); } static int sc7280_snd_startup(struct snd_pcm_substream *substream) @@ -347,6 +352,8 @@ static int sc7280_snd_startup(struct snd_pcm_substream *substream) switch (cpu_dai->id) { case MI2S_PRIMARY: ret = sc7280_rt5682_init(rtd); + if (ret) + return ret; break; case SECONDARY_MI2S_RX: codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S; @@ -360,7 +367,8 @@ static int sc7280_snd_startup(struct snd_pcm_substream *substream) default: break; } - return ret; + + return qcom_snd_sdw_startup(substream); } static const struct snd_soc_ops sc7280_ops = { diff --git a/sound/soc/qcom/sdm845.c b/sound/soc/qcom/sdm845.c index 75701546b6ea..a479d7e5b7fb 100644 --- a/sound/soc/qcom/sdm845.c +++ b/sound/soc/qcom/sdm845.c @@ -15,6 +15,7 @@ #include <uapi/linux/input-event-codes.h> #include "common.h" #include "qdsp6/q6afe.h" +#include "sdw.h" #include "../codecs/rt5663.h" #define DRIVER_NAME "sdm845" @@ -416,7 +417,7 @@ static int sdm845_snd_startup(struct snd_pcm_substream *substream) pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id); break; } - return 0; + return qcom_snd_sdw_startup(substream); } static void sdm845_snd_shutdown(struct snd_pcm_substream *substream) @@ -425,6 +426,7 @@ static void sdm845_snd_shutdown(struct snd_pcm_substream *substream) struct snd_soc_card *card = rtd->card; struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card); struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); + struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; switch (cpu_dai->id) { case PRIMARY_MI2S_RX: @@ -463,6 +465,9 @@ static void sdm845_snd_shutdown(struct snd_pcm_substream *substream) pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id); break; } + + data->sruntime[cpu_dai->id] = NULL; + sdw_release_stream(sruntime); } static int sdm845_snd_prepare(struct snd_pcm_substream *substream) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 9784718a2b6f..eca5ce096e54 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -1281,7 +1281,9 @@ audio_graph: if (!of_node_name_eq(ports, "ports") && !of_node_name_eq(ports, "port")) continue; - priv->component_dais[i] = of_graph_get_endpoint_count(ports); + priv->component_dais[i] = + of_graph_get_endpoint_count(of_node_name_eq(ports, "ports") ? + ports : np); nr += priv->component_dais[i]; i++; if (i >= RSND_MAX_COMPONENT) { @@ -1493,7 +1495,8 @@ static int rsnd_dai_probe(struct rsnd_priv *priv) if (!of_node_name_eq(ports, "ports") && !of_node_name_eq(ports, "port")) continue; - for_each_endpoint_of_node(ports, dai_np) { + for_each_endpoint_of_node(of_node_name_eq(ports, "ports") ? + ports : np, dai_np) { __rsnd_dai_probe(priv, dai_np, dai_np, 0, dai_i); if (!rsnd_is_gen1(priv) && !rsnd_is_gen2(priv)) { rdai = rsnd_rdai_get(priv, dai_i); diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 9330f1a3f758..c34934c31ffe 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -2785,10 +2785,10 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_update_dai); int snd_soc_dapm_widget_name_cmp(struct snd_soc_dapm_widget *widget, const char *s) { - struct snd_soc_component *component = snd_soc_dapm_to_component(widget->dapm); + struct snd_soc_component *component = widget->dapm->component; const char *wname = widget->name; - if (component->name_prefix) + if (component && component->name_prefix) wname += strlen(component->name_prefix) + 1; /* plus space */ return strcmp(wname, s); diff --git a/sound/soc/sof/amd/acp-loader.c b/sound/soc/sof/amd/acp-loader.c index 19f10dd77e4b..077af9e2af8d 100644 --- a/sound/soc/sof/amd/acp-loader.c +++ b/sound/soc/sof/amd/acp-loader.c @@ -206,7 +206,10 @@ int acp_dsp_pre_fw_run(struct snd_sof_dev *sdev) configure_pte_for_fw_loading(FW_SRAM_DATA_BIN, ACP_SRAM_PAGE_COUNT, adata); src_addr = ACP_SYSTEM_MEMORY_WINDOW + ACP_DEFAULT_SRAM_LENGTH + (page_count * ACP_PAGE_SIZE); - dest_addr = ACP_SRAM_BASE_ADDRESS; + if (adata->pci_rev > ACP63_PCI_ID) + dest_addr = ACP7X_SRAM_BASE_ADDRESS; + else + dest_addr = ACP_SRAM_BASE_ADDRESS; ret = configure_and_run_dma(adata, src_addr, dest_addr, adata->fw_sram_data_bin_size); diff --git a/sound/soc/sof/amd/acp.c b/sound/soc/sof/amd/acp.c index d579c3849392..de3001f5b9bb 100644 --- a/sound/soc/sof/amd/acp.c +++ b/sound/soc/sof/amd/acp.c @@ -329,7 +329,9 @@ int configure_and_run_sha_dma(struct acp_dev_data *adata, void *image_addr, fw_qualifier, fw_qualifier & DSP_FW_RUN_ENABLE, ACP_REG_POLL_INTERVAL, ACP_DMA_COMPLETE_TIMEOUT_US); if (ret < 0) { - dev_err(sdev->dev, "PSP validation failed\n"); + val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SHA_PSP_ACK); + dev_err(sdev->dev, "PSP validation failed: fw_qualifier = %#x, ACP_SHA_PSP_ACK = %#x\n", + fw_qualifier, val); return ret; } diff --git a/sound/soc/sof/intel/hda-dai-ops.c b/sound/soc/sof/intel/hda-dai-ops.c index 484c76147885..92681ca7f24d 100644 --- a/sound/soc/sof/intel/hda-dai-ops.c +++ b/sound/soc/sof/intel/hda-dai-ops.c @@ -346,20 +346,21 @@ static int hda_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cpu_dai, case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: snd_hdac_ext_stream_start(hext_stream); break; - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - snd_hdac_ext_stream_clear(hext_stream); - /* - * Save the LLP registers in case the stream is - * restarting due PAUSE_RELEASE, or START without a pcm - * close/open since in this case the LLP register is not reset - * to 0 and the delay calculation will return with invalid - * results. + * Save the LLP registers since in case of PAUSE the LLP + * register are not reset to 0, the delay calculation will use + * the saved offsets for compensating the delay calculation. */ hext_stream->pplcllpl = readl(hext_stream->pplc_addr + AZX_REG_PPLCLLPL); hext_stream->pplcllpu = readl(hext_stream->pplc_addr + AZX_REG_PPLCLLPU); + snd_hdac_ext_stream_clear(hext_stream); + break; + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_STOP: + hext_stream->pplcllpl = 0; + hext_stream->pplcllpu = 0; + snd_hdac_ext_stream_clear(hext_stream); break; default: dev_err(sdev->dev, "unknown trigger command %d\n", cmd); @@ -512,7 +513,6 @@ static const struct hda_dai_widget_dma_ops sdw_ipc4_chain_dma_ops = { static int hda_ipc3_post_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cpu_dai, struct snd_pcm_substream *substream, int cmd) { - struct hdac_ext_stream *hext_stream = hda_get_hext_stream(sdev, cpu_dai, substream); struct snd_soc_dapm_widget *w = snd_soc_dai_get_widget(cpu_dai, substream->stream); switch (cmd) { @@ -527,9 +527,6 @@ static int hda_ipc3_post_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *c if (ret < 0) return ret; - if (cmd == SNDRV_PCM_TRIGGER_STOP) - return hda_link_dma_cleanup(substream, hext_stream, cpu_dai); - break; } case SNDRV_PCM_TRIGGER_PAUSE_PUSH: diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index 1c823f9eea57..ac505c7ad342 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -302,6 +302,7 @@ static int __maybe_unused hda_dai_trigger(struct snd_pcm_substream *substream, i } switch (cmd) { + case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: ret = hda_link_dma_cleanup(substream, hext_stream, dai); if (ret < 0) { @@ -370,6 +371,13 @@ static int non_hda_dai_hw_params_data(struct snd_pcm_substream *substream, return -EINVAL; } + sdev = widget_to_sdev(w); + hext_stream = ops->get_hext_stream(sdev, cpu_dai, substream); + + /* nothing more to do if the link is already prepared */ + if (hext_stream && hext_stream->link_prepared) + return 0; + /* use HDaudio stream handling */ ret = hda_dai_hw_params_data(substream, params, cpu_dai, data, flags); if (ret < 0) { @@ -377,7 +385,6 @@ static int non_hda_dai_hw_params_data(struct snd_pcm_substream *substream, return ret; } - sdev = widget_to_sdev(w); if (sdev->dspless_mode_selected) return 0; @@ -482,6 +489,31 @@ int sdw_hda_dai_hw_params(struct snd_pcm_substream *substream, int ret; int i; + ops = hda_dai_get_ops(substream, cpu_dai); + if (!ops) { + dev_err(cpu_dai->dev, "DAI widget ops not set\n"); + return -EINVAL; + } + + sdev = widget_to_sdev(w); + hext_stream = ops->get_hext_stream(sdev, cpu_dai, substream); + + /* nothing more to do if the link is already prepared */ + if (hext_stream && hext_stream->link_prepared) + return 0; + + /* + * reset the PCMSyCM registers to handle a prepare callback when the PCM is restarted + * due to xruns or after a call to snd_pcm_drain/drop() + */ + ret = hdac_bus_eml_sdw_map_stream_ch(sof_to_bus(sdev), link_id, cpu_dai->id, + 0, 0, substream->stream); + if (ret < 0) { + dev_err(cpu_dai->dev, "%s: hdac_bus_eml_sdw_map_stream_ch failed %d\n", + __func__, ret); + return ret; + } + data.dai_index = (link_id << 8) | cpu_dai->id; data.dai_node_id = intel_alh_id; ret = non_hda_dai_hw_params_data(substream, params, cpu_dai, &data, flags); @@ -490,10 +522,7 @@ int sdw_hda_dai_hw_params(struct snd_pcm_substream *substream, return ret; } - ops = hda_dai_get_ops(substream, cpu_dai); - sdev = widget_to_sdev(w); hext_stream = ops->get_hext_stream(sdev, cpu_dai, substream); - if (!hext_stream) return -ENODEV; diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index 75f6240cf3e1..9d8ebb7c6a10 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -294,14 +294,9 @@ int hda_cl_copy_fw(struct snd_sof_dev *sdev, struct hdac_ext_stream *hext_stream { struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; const struct sof_intel_dsp_desc *chip = hda->desc; - struct sof_intel_hda_stream *hda_stream; - unsigned long time_left; unsigned int reg; int ret, status; - hda_stream = container_of(hext_stream, struct sof_intel_hda_stream, - hext_stream); - dev_dbg(sdev->dev, "Code loader DMA starting\n"); ret = hda_cl_trigger(sdev->dev, hext_stream, SNDRV_PCM_TRIGGER_START); @@ -310,18 +305,6 @@ int hda_cl_copy_fw(struct snd_sof_dev *sdev, struct hdac_ext_stream *hext_stream return ret; } - if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) { - /* Wait for completion of transfer */ - time_left = wait_for_completion_timeout(&hda_stream->ioc, - msecs_to_jiffies(HDA_CL_DMA_IOC_TIMEOUT_MS)); - - if (!time_left) { - dev_err(sdev->dev, "Code loader DMA did not complete\n"); - return -ETIMEDOUT; - } - dev_dbg(sdev->dev, "Code loader DMA done\n"); - } - dev_dbg(sdev->dev, "waiting for FW_ENTERED status\n"); status = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 87be7f16e8c2..240fee2166d1 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -3129,9 +3129,20 @@ static int sof_ipc4_dai_config(struct snd_sof_dev *sdev, struct snd_sof_widget * * group_id during copier's ipc_prepare op. */ if (flags & SOF_DAI_CONFIG_FLAGS_HW_PARAMS) { + struct sof_ipc4_alh_configuration_blob *blob; + + blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; ipc4_copier->dai_index = data->dai_node_id; - copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; - copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(data->dai_node_id); + + /* + * no need to set the node_id for aggregated DAI's. These will be assigned + * a group_id during widget ipc_prepare + */ + if (blob->alh_cfg.device_count == 1) { + copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; + copier_data->gtw_cfg.node_id |= + SOF_IPC4_NODE_INDEX(data->dai_node_id); + } } break; |