sound fixes for 6.12-rc5

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.
 -----BEGIN PGP SIGNATURE-----
 
 iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmcbWbMOHHRpd2FpQHN1
 c2UuZGUACgkQLtJE4w1nLE/YKxAAt4WhN/98T2y5RBZEpDyDrxFF3TGNhgHO61tv
 9zEpOpz2CR4vP7qbImTlzWZ8ehcbqQK3I3xlq/xsD8/nRacUyVO1XX3Zb+SlSYGp
 Ln6IFiLSnCuJKavEJtoWbEIsg+jhKQCvApq55Yxvxk/PO91Sehx+/LWa0ZeHbVrG
 ChJRXStBEfUu1eBQL/7oMPkXm7QJYzR3pE4eieom33I4wJXFRHrBtSR4Ldj1kpCJ
 GQKVqZVkUgFLLzHckJyHTswi2wX1w8H6FWTIQydqK8beHCCEBR3c3PzUQgI5QXwS
 Hfe2lyvOkK78eAPn8GdAAT1cMdMfAy/iLC78QDGhk117JACOzEU8mRWYS3Dh268a
 W8iiNYhnTRC/7M6OM+boD7IhCXADlA3wiEwV4n5BtqkjmXkNJDEWxMZrUyk6R/rO
 csEsARtue3ISClEnU0ih3Ebl3iHCUlzzCkG0bNPkMnw6dRtJyppg9LpBijt7Y6Ep
 DyaAGFBI5qMcOHIh6A35m8K3d9YwnqhAj/ZdmMLS34r8e96KdBNH4yKo7ftqqHXW
 eRDCDSjKdeWSfymutwV2jfVLR0e1C77ysL9z1MZgoRfLskjpET3Qp526hIBe+qoG
 TbGl5VLyZqhRmHwYxdDsAq+XbMm41eHJskg49iOIG3Cru1y30y0or2R1e9r10/eB
 Ue8Pb1w=
 =hhTD
 -----END PGP SIGNATURE-----

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
  ...
This commit is contained in:
Linus Torvalds 2024-10-25 10:35:29 -07:00
commit 01154cc30e
35 changed files with 329 additions and 111 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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.

View File

@ -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);
snd_hda_codec_write(codec, hp_pin, 0,
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
if (hp_pin_sense)
msleep(85);
msleep(75);
snd_hda_codec_write(codec, hp_pin, 0,
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
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),

View File

@ -325,6 +325,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "M6500RC"),
}
},
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "E1404FA"),
}
},
{
.driver_data = &acp6x_card,
.matches = {
@ -339,6 +346,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "M7600RE"),
}
},
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "M3502RA"),
}
},
{
.driver_data = &acp6x_card,
.matches = {

View File

@ -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;
}

View File

@ -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)

View File

@ -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;
}

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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

View File

@ -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;

View File

@ -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");

View File

@ -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))

View File

@ -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;

View File

@ -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)

16
sound/soc/intel/avs/pcm.h Normal file
View File

@ -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

View File

@ -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);

View File

@ -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) {

View File

@ -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

View File

@ -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,

View File

@ -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 = {

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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:

View File

@ -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;

View File

@ -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,

View File

@ -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;