sound fixes for 7.0

Still a bit higher amount than wished, but nothing looks really scary,
 and all changes are about nice and smooth device-specific fixes.
 
 - HD-audio quirks, one revert for a regression and another oneliner
 - AMD ACP quirks
 - Fixes for SDCA interrupt handling
 - A few Intel SOF, avs and NVL fixes
 - Fixes for TAS2552 DT, NAU8325, and STM32
 -----BEGIN PGP SIGNATURE-----
 
 iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmnXw6IOHHRpd2FpQHN1
 c2UuZGUACgkQLtJE4w1nLE8wXRAAwvJic7rPrAGoUaCqEFt7f/ytXVh96plCggzW
 0GFxqm3gKd0/1d8ebGqyKEdHqiDVv4qoTZKNtgCk0puMNj4GuBPU1Qiu2yIJkL1b
 /tziS4nLzTtHgpwfOgb2UEStX0BuY1igeowRg2H2v4c6e/CeMpfz77sUNepUlHj6
 a3eSSguDp0VMAwoulnOcblSnHiY+m8ddkSFV/S0tB7dojiIox+fbrpj8ynN8pU1A
 9fW3gF9cOVKoqR3I5jIXy2l1LdALS9c7HlksAhBc5zK3NQnZv3kEjzx9ddsHW3O+
 8Ygjl94xp4njuQqM+raE1CgMKzqaGAN+kqCmbMNK1ADCdTH2CB+TsfIP4KeD6/5K
 990NIQsdkd6GlMQv3N7WabxPBMmK815GBpqm72R7CUTMt1zT7xVr5RXACTZG4VEv
 lSDLN7W3kYo37Tlda3Zc187sTvIS+YIuf4fWsgREVX+hI304C+GY+dW3F2LVVxd+
 FmUe7PKzVM8M9KK3WCdMte4w7toq0gdVPFL7v23wA91a01sj9UScNZgCHk9puwAm
 v+Ms9BzNhnUPbr+JiFrCQcB01n3cZiFexk6DH1393dfVV86+q29VAC90IbLy1sJL
 ClM/LMy6n1rG+T0OC8NyVnfrzztoLInq5NZ98ZmaLjA67sC5M0+tdujMlwrrCZ5B
 mUnMZWk=
 =h9zn
 -----END PGP SIGNATURE-----

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

Pull sound fixes from Takashi Iwai:
 "Still a bit higher amount than wished, but nothing looks really scary,
  and all changes are about nice and smooth device-specific fixes.

   - HD-audio quirks, one revert for a regression and another oneliner

   - AMD ACP quirks

   - Fixes for SDCA interrupt handling

   - A few Intel SOF, avs and NVL fixes

   - Fixes for TAS2552 DT, NAU8325, and STM32"

* tag 'sound-7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ASoC: amd: acp: update DMI quirk and add ACP DMIC for Lenovo platforms
  ASoC: SDCA: Unregister IRQ handlers on module remove
  ASoC: SDCA: mask Function_Status value
  ASoC: SDCA: Fix overwritten var within for loop
  ASoC: stm32_sai: fix incorrect BCLK polarity for DSP_A/B, LEFT_J
  ASoC: SOF: Intel: hda: modify period size constraints for ACE4
  ALSA: hda/intel: enforce stricter period-size alignment for Intel NVL
  ASoC: nau8325: Add software reset during probe
  Revert "ALSA: hda/realtek: Add quirk for Gigabyte Technology to fix headphone"
  ASoC: Intel: avs: Fix memory leak in avs_register_i2s_test_boards()
  ASoC: SOF: Intel: fix iteration in is_endpoint_present()
  ASoC: SOF: Intel: Fix endpoint index if endpoints are missing
  ASoC: SDCA: Fix errors in IRQ cleanup
  ASoC: amd: acp: add Lenovo P16s G5 AMD quirk for legacy SDW machine
  ASoC: dt-bindings: ti,tas2552: Add sound-dai-cells
  ALSA: hda/realtek: Add quirk for Lenovo Yoga Pro 7 14IAH10
This commit is contained in:
Linus Torvalds 2026-04-09 11:17:16 -07:00
commit bb2ea74eeb
13 changed files with 165 additions and 38 deletions

View File

@ -12,8 +12,8 @@ maintainers:
- Baojun Xu <baojun.xu@ti.com>
description: >
The TAS2552 can receive its reference clock via MCLK, BCLK, IVCLKIN pin or
use the internal 1.8MHz. This CLKIN is used by the PLL. In addition to PLL,
The TAS2552 can receive its reference clock via MCLK, BCLK, IVCLKIN pin or
use the internal 1.8MHz. This CLKIN is used by the PLL. In addition to PLL,
the PDM reference clock is also selectable: PLL, IVCLKIN, BCLK or MCLK.
For system integration the dt-bindings/sound/tas2552.h header file provides
@ -34,6 +34,9 @@ properties:
maxItems: 1
description: gpio pin to enable/disable the device
'#sound-dai-cells':
const: 0
required:
- compatible
- reg
@ -41,7 +44,10 @@ required:
- iovdd-supply
- avdd-supply
additionalProperties: false
allOf:
- $ref: dai-common.yaml#
unevaluatedProperties: false
examples:
- |
@ -54,6 +60,7 @@ examples:
audio-codec@41 {
compatible = "ti,tas2552";
reg = <0x41>;
#sound-dai-cells = <0>;
vbat-supply = <&reg_vbat>;
iovdd-supply = <&reg_iovdd>;
avdd-supply = <&reg_avdd>;

View File

@ -69,6 +69,8 @@ struct sdca_interrupt_info {
int sdca_irq_request(struct device *dev, struct sdca_interrupt_info *interrupt_info,
int sdca_irq, const char *name, irq_handler_t handler,
void *data);
void sdca_irq_free(struct device *dev, struct sdca_interrupt_info *interrupt_info,
int sdca_irq, const char *name, void *data);
int sdca_irq_data_populate(struct device *dev, struct regmap *function_regmap,
struct snd_soc_component *component,
struct sdca_function_data *function,
@ -81,6 +83,9 @@ int sdca_irq_populate_early(struct device *dev, struct regmap *function_regmap,
int sdca_irq_populate(struct sdca_function_data *function,
struct snd_soc_component *component,
struct sdca_interrupt_info *info);
void sdca_irq_cleanup(struct device *dev,
struct sdca_function_data *function,
struct sdca_interrupt_info *info);
struct sdca_interrupt_info *sdca_irq_allocate(struct device *dev,
struct regmap *regmap, int irq);

View File

@ -7680,6 +7680,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x38fd, "ThinkBook plus Gen5 Hybrid", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
SND_PCI_QUIRK(0x17aa, 0x390d, "Lenovo Yoga Pro 7 14ASP10", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
SND_PCI_QUIRK(0x17aa, 0x3911, "Lenovo Yoga Pro 7 14IAH10", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
SND_PCI_QUIRK(0x17aa, 0x3913, "Lenovo 145", ALC236_FIXUP_LENOVO_INV_DMIC),
SND_PCI_QUIRK(0x17aa, 0x391a, "Lenovo Yoga Slim 7 14AKP10", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
SND_PCI_QUIRK(0x17aa, 0x391f, "Yoga S990-16 pro Quad YC Quad", ALC287_FIXUP_TXNW2781_I2C),

View File

@ -313,7 +313,6 @@ enum {
ALC897_FIXUP_HEADSET_MIC_PIN2,
ALC897_FIXUP_UNIS_H3C_X500S,
ALC897_FIXUP_HEADSET_MIC_PIN3,
ALC897_FIXUP_H610M_HP_PIN,
};
static const struct hda_fixup alc662_fixups[] = {
@ -767,13 +766,6 @@ static const struct hda_fixup alc662_fixups[] = {
{ }
},
},
[ALC897_FIXUP_H610M_HP_PIN] = {
.type = HDA_FIXUP_PINS,
.v.pins = (const struct hda_pintbl[]) {
{ 0x19, 0x0321403f }, /* HP out */
{ }
},
},
};
static const struct hda_quirk alc662_fixup_tbl[] = {
@ -823,7 +815,6 @@ static const struct hda_quirk alc662_fixup_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
SND_PCI_QUIRK(0x1458, 0xa194, "H610M H V2 DDR4", ALC897_FIXUP_H610M_HP_PIN),
SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
SND_PCI_QUIRK(0x17aa, 0x1057, "Lenovo P360", ALC897_FIXUP_HEADSET_MIC_PIN),

View File

@ -295,6 +295,9 @@ enum {
#define AZX_DCAPS_INTEL_LNL \
(AZX_DCAPS_INTEL_SKYLAKE | AZX_DCAPS_PIO_COMMANDS)
#define AZX_DCAPS_INTEL_NVL \
(AZX_DCAPS_INTEL_LNL & ~AZX_DCAPS_NO_ALIGN_BUFSIZE)
/* quirks for ATI SB / AMD Hudson */
#define AZX_DCAPS_PRESET_ATI_SB \
(AZX_DCAPS_NO_TCSEL | AZX_DCAPS_POSFIX_LPIB |\
@ -2565,8 +2568,8 @@ static const struct pci_device_id azx_ids[] = {
/* Wildcat Lake */
{ PCI_DEVICE_DATA(INTEL, HDA_WCL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_LNL) },
/* Nova Lake */
{ PCI_DEVICE_DATA(INTEL, HDA_NVL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_LNL) },
{ PCI_DEVICE_DATA(INTEL, HDA_NVL_S, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_LNL) },
{ PCI_DEVICE_DATA(INTEL, HDA_NVL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_NVL) },
{ PCI_DEVICE_DATA(INTEL, HDA_NVL_S, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_NVL) },
/* Apollolake (Broxton-P) */
{ PCI_DEVICE_DATA(INTEL, HDA_APL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON) },
/* Gemini-Lake */

View File

@ -99,17 +99,33 @@ static const struct dmi_system_id soc_sdw_quirk_table[] = {
.callback = soc_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "21YW"),
DMI_MATCH(DMI_PRODUCT_SKU, "21YW"),
},
.driver_data = (void *)(ASOC_SDW_CODEC_SPKR),
.driver_data = (void *)((ASOC_SDW_CODEC_SPKR) | (ASOC_SDW_ACP_DMIC)),
},
{
.callback = soc_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "21YX"),
DMI_MATCH(DMI_PRODUCT_SKU, "21YX"),
},
.driver_data = (void *)(ASOC_SDW_CODEC_SPKR),
.driver_data = (void *)((ASOC_SDW_CODEC_SPKR) | (ASOC_SDW_ACP_DMIC)),
},
{
.callback = soc_sdw_quirk_cb,
.matches = { /* Lenovo P16s G5 AMD */
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_SKU, "21XG"),
},
.driver_data = (void *)(ASOC_SDW_ACP_DMIC),
},
{
.callback = soc_sdw_quirk_cb,
.matches = { /* Lenovo P16s G5 AMD */
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_SKU, "21XH"),
},
.driver_data = (void *)(ASOC_SDW_ACP_DMIC),
},
{
.callback = soc_sdw_quirk_cb,

View File

@ -142,7 +142,7 @@ static bool nau8325_readable_reg(struct device *dev, unsigned int reg)
static bool nau8325_writeable_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case NAU8325_R00_HARDWARE_RST:
case NAU8325_R00_HARDWARE_RST ... NAU8325_R01_SOFTWARE_RST:
case NAU8325_R03_CLK_CTRL ... NAU8325_R06_INT_CLR_STATUS:
case NAU8325_R09_IRQOUT ... NAU8325_R13_DAC_VOLUME:
case NAU8325_R29_DAC_CTRL1 ... NAU8325_R2A_DAC_CTRL2:
@ -670,6 +670,12 @@ static void nau8325_reset_chip(struct regmap *regmap)
regmap_write(regmap, NAU8325_R00_HARDWARE_RST, 0x0000);
}
static void nau8325_software_reset(struct regmap *regmap)
{
regmap_write(regmap, NAU8325_R01_SOFTWARE_RST, 0x0000);
regmap_write(regmap, NAU8325_R01_SOFTWARE_RST, 0x0000);
}
static void nau8325_init_regs(struct nau8325 *nau8325)
{
struct regmap *regmap = nau8325->regmap;
@ -856,6 +862,7 @@ static int nau8325_i2c_probe(struct i2c_client *i2c)
nau8325_print_device_properties(nau8325);
nau8325_reset_chip(nau8325->regmap);
nau8325_software_reset(nau8325->regmap);
ret = regmap_read(nau8325->regmap, NAU8325_R02_DEVICE_ID, &value);
if (ret) {
dev_dbg(dev, "Failed to read device id (%d)", ret);

View File

@ -520,7 +520,8 @@ static int avs_register_i2s_test_boards(struct avs_dev *adev)
if (num_elems > max_ssps) {
dev_err(adev->dev, "board supports only %d SSP, %d specified\n",
max_ssps, num_elems);
return -EINVAL;
ret = -EINVAL;
goto exit;
}
for (ssp_port = 0; ssp_port < num_elems; ssp_port++) {
@ -528,11 +529,13 @@ static int avs_register_i2s_test_boards(struct avs_dev *adev)
for_each_set_bit(tdm_slot, &tdm_slots, 16) {
ret = avs_register_i2s_test_board(adev, ssp_port, tdm_slot);
if (ret)
return ret;
goto exit;
}
}
return 0;
exit:
kfree(array);
return ret;
}
static int avs_register_i2s_board(struct avs_dev *adev, struct snd_soc_acpi_mach *mach)

View File

@ -198,6 +198,14 @@ static int class_function_component_probe(struct snd_soc_component *component)
return sdca_irq_populate(drv->function, component, core->irq_info);
}
static void class_function_component_remove(struct snd_soc_component *component)
{
struct class_function_drv *drv = snd_soc_component_get_drvdata(component);
struct sdca_class_drv *core = drv->core;
sdca_irq_cleanup(component->dev, drv->function, core->irq_info);
}
static int class_function_set_jack(struct snd_soc_component *component,
struct snd_soc_jack *jack, void *d)
{
@ -209,6 +217,7 @@ static int class_function_set_jack(struct snd_soc_component *component,
static const struct snd_soc_component_driver class_function_component_drv = {
.probe = class_function_component_probe,
.remove = class_function_component_remove,
.endianness = 1,
};
@ -402,6 +411,13 @@ static int class_function_probe(struct auxiliary_device *auxdev,
return 0;
}
static void class_function_remove(struct auxiliary_device *auxdev)
{
struct class_function_drv *drv = auxiliary_get_drvdata(auxdev);
sdca_irq_cleanup(drv->dev, drv->function, drv->core->irq_info);
}
static int class_function_runtime_suspend(struct device *dev)
{
struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
@ -550,6 +566,7 @@ static struct auxiliary_driver class_function_drv = {
},
.probe = class_function_probe,
.remove = class_function_remove,
.id_table = class_function_id_table
};
module_auxiliary_driver(class_function_drv);

View File

@ -117,9 +117,7 @@ static irqreturn_t function_status_handler(int irq, void *data)
status = val;
for_each_set_bit(mask, &status, BITS_PER_BYTE) {
mask = 1 << mask;
switch (mask) {
switch (BIT(mask)) {
case SDCA_CTL_ENTITY_0_FUNCTION_NEEDS_INITIALIZATION:
//FIXME: Add init writes
break;
@ -140,7 +138,7 @@ static irqreturn_t function_status_handler(int irq, void *data)
}
}
ret = regmap_write(interrupt->function_regmap, reg, val);
ret = regmap_write(interrupt->function_regmap, reg, val & 0x7F);
if (ret < 0) {
dev_err(dev, "failed to clear function status: %d\n", ret);
goto error;
@ -252,8 +250,7 @@ static int sdca_irq_request_locked(struct device *dev,
if (irq < 0)
return irq;
ret = devm_request_threaded_irq(dev, irq, NULL, handler,
IRQF_ONESHOT, name, data);
ret = request_threaded_irq(irq, NULL, handler, IRQF_ONESHOT, name, data);
if (ret)
return ret;
@ -264,6 +261,22 @@ static int sdca_irq_request_locked(struct device *dev,
return 0;
}
static void sdca_irq_free_locked(struct device *dev, struct sdca_interrupt_info *info,
int sdca_irq, const char *name, void *data)
{
int irq;
irq = regmap_irq_get_virq(info->irq_data, sdca_irq);
if (irq < 0)
return;
free_irq(irq, data);
info->irqs[sdca_irq].irq = 0;
dev_dbg(dev, "freed irq %d for %s\n", irq, name);
}
/**
* sdca_irq_request - request an individual SDCA interrupt
* @dev: Pointer to the struct device against which things should be allocated.
@ -302,6 +315,30 @@ int sdca_irq_request(struct device *dev, struct sdca_interrupt_info *info,
}
EXPORT_SYMBOL_NS_GPL(sdca_irq_request, "SND_SOC_SDCA");
/**
* sdca_irq_free - free an individual SDCA interrupt
* @dev: Pointer to the struct device.
* @info: Pointer to the interrupt information structure.
* @sdca_irq: SDCA interrupt position.
* @name: Name to be given to the IRQ.
* @data: Private data pointer that will be passed to the handler.
*
* Typically this is handled internally by sdca_irq_cleanup, however if
* a device requires custom IRQ handling this can be called manually before
* calling sdca_irq_cleanup, which will then skip that IRQ whilst processing.
*/
void sdca_irq_free(struct device *dev, struct sdca_interrupt_info *info,
int sdca_irq, const char *name, void *data)
{
if (sdca_irq < 0 || sdca_irq >= SDCA_MAX_INTERRUPTS)
return;
guard(mutex)(&info->irq_lock);
sdca_irq_free_locked(dev, info, sdca_irq, name, data);
}
EXPORT_SYMBOL_NS_GPL(sdca_irq_free, "SND_SOC_SDCA");
/**
* sdca_irq_data_populate - Populate common interrupt data
* @dev: Pointer to the Function device.
@ -328,8 +365,8 @@ int sdca_irq_data_populate(struct device *dev, struct regmap *regmap,
if (!dev)
return -ENODEV;
name = devm_kasprintf(dev, GFP_KERNEL, "%s %s %s", function->desc->name,
entity->label, control->label);
name = kasprintf(GFP_KERNEL, "%s %s %s", function->desc->name,
entity->label, control->label);
if (!name)
return -ENOMEM;
@ -516,6 +553,35 @@ int sdca_irq_populate(struct sdca_function_data *function,
}
EXPORT_SYMBOL_NS_GPL(sdca_irq_populate, "SND_SOC_SDCA");
/**
* sdca_irq_cleanup - Free all the individual IRQs for an SDCA Function
* @sdev: Device pointer against which the sdca_interrupt_info was allocated.
* @function: Pointer to the SDCA Function.
* @info: Pointer to the SDCA interrupt info for this device.
*
* Typically this would be called from the driver for a single SDCA Function.
*/
void sdca_irq_cleanup(struct device *dev,
struct sdca_function_data *function,
struct sdca_interrupt_info *info)
{
int i;
guard(mutex)(&info->irq_lock);
for (i = 0; i < SDCA_MAX_INTERRUPTS; i++) {
struct sdca_interrupt *interrupt = &info->irqs[i];
if (interrupt->function != function || !interrupt->irq)
continue;
sdca_irq_free_locked(dev, info, i, interrupt->name, interrupt);
kfree(interrupt->name);
}
}
EXPORT_SYMBOL_NS_GPL(sdca_irq_cleanup, "SND_SOC_SDCA");
/**
* sdca_irq_allocate - allocate an SDCA interrupt structure for a device
* @sdev: Device pointer against which things should be allocated.

View File

@ -219,6 +219,7 @@ EXPORT_SYMBOL_NS(hda_dsp_pcm_pointer, "SND_SOC_SOF_INTEL_HDA_COMMON");
int hda_dsp_pcm_open(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream)
{
const struct sof_intel_dsp_desc *chip_info = get_chip_info(sdev->pdata);
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_component *scomp = sdev->component;
@ -268,8 +269,17 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev,
return -ENODEV;
}
/* minimum as per HDA spec */
snd_pcm_hw_constraint_step(substream->runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 4);
/*
* Set period size constraint to ensure BDLE buffer length and
* start address alignment requirements are met. Align to 128
* bytes for newer Intel platforms, with older ones using 4 byte alignment.
*/
if (chip_info->hw_ip_version >= SOF_INTEL_ACE_4_0)
snd_pcm_hw_constraint_step(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 128);
else
snd_pcm_hw_constraint_step(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 4);
/* avoid circular buffer wrap in middle of period */
snd_pcm_hw_constraint_integer(substream->runtime,

View File

@ -1133,8 +1133,7 @@ static void hda_generic_machine_select(struct snd_sof_dev *sdev,
#if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
static bool is_endpoint_present(struct sdw_slave *sdw_device,
struct asoc_sdw_codec_info *dai_info, int dai_type)
static bool is_endpoint_present(struct sdw_slave *sdw_device, int dai_type)
{
int i;
@ -1145,7 +1144,7 @@ static bool is_endpoint_present(struct sdw_slave *sdw_device,
}
for (i = 0; i < sdw_device->sdca_data.num_functions; i++) {
if (dai_type == dai_info->dais[i].dai_type)
if (dai_type == asoc_sdw_get_dai_type(sdw_device->sdca_data.function[i].type))
return true;
}
dev_dbg(&sdw_device->dev, "Endpoint DAI type %d not found\n", dai_type);
@ -1199,11 +1198,10 @@ static struct snd_soc_acpi_adr_device *find_acpi_adr_device(struct device *dev,
}
for (j = 0; j < codec_info_list[i].dai_num; j++) {
/* Check if the endpoint is present by the SDCA DisCo table */
if (!is_endpoint_present(sdw_device, &codec_info_list[i],
codec_info_list[i].dais[j].dai_type))
if (!is_endpoint_present(sdw_device, codec_info_list[i].dais[j].dai_type))
continue;
endpoints[ep_index].num = ep_index;
endpoints[ep_index].num = j;
if (codec_info_list[i].dais[j].dai_type == SOC_SDW_DAI_TYPE_AMP) {
/* Assume all amp are aggregated */
endpoints[ep_index].aggregated = 1;

View File

@ -802,6 +802,7 @@ static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
break;
/* Left justified */
case SND_SOC_DAIFMT_MSB:
cr1 |= SAI_XCR1_CKSTR;
frcr |= SAI_XFRCR_FSPOL | SAI_XFRCR_FSDEF;
break;
/* Right justified */
@ -809,9 +810,11 @@ static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
frcr |= SAI_XFRCR_FSPOL | SAI_XFRCR_FSDEF;
break;
case SND_SOC_DAIFMT_DSP_A:
cr1 |= SAI_XCR1_CKSTR;
frcr |= SAI_XFRCR_FSPOL | SAI_XFRCR_FSOFF;
break;
case SND_SOC_DAIFMT_DSP_B:
cr1 |= SAI_XCR1_CKSTR;
frcr |= SAI_XFRCR_FSPOL;
break;
default: