sound fixes for 7.1-rc7

It's getting calmer, but we cam up with still a handful small fixes,
 including two core fixes.  All look sane and safe.
 
 * Core:
 - Fix wait queue list corruption in snd_pcm_drain() on linked streams
 - Fix UMP event stack overread in seq dummy driver
 
 * USB-audio:
 - Add quirk for AB13X USB Audio
 - Fix the regression with sticky mixer volumes in 7.1-rc
 
 * ASoC:
 - Fix 32-slot TDM breakage on Freescale SAI
 - Varioud DMI quirks for AMD ACP
 -----BEGIN PGP SIGNATURE-----
 
 iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmokRfcOHHRpd2FpQHN1
 c2UuZGUACgkQLtJE4w1nLE9uuw/9Fjp6ZQOfGXWzrn4UFiCPE2mzVNbclSIYIIUI
 iPRAM7+66Rj5IjPaY/a+csAjRAAodqYoTtZgA8rFfjpv4T4nEUbSfEFWnV252vzM
 JAHZxq4uuxEqUoy7iXPp4k3k9MzEY7AlOYm2F+3CY9cSwn3hwedD03Uq+2qzupmK
 GrVbYhsJD672rFWM9wmGS4hxarEbXjdtxXJ0i9m10/ydJ8bafURcAO62/74ly/JC
 YpF4EJpM1oYlDXrsDvWz226MTiu1o/NuIWU5cHEHeMejX5HXKpdR54mVcR9T/CO4
 KCw2M2nddn92zInm4yRM05MS2dvlcVxixITTclnRS6bFi0N53wWuX2B1UHYiI+Ko
 aKM9Ph3GCaWP+4LwEXM0qG5AscRmpJ5aDx22SLB0ObdjjA4boYIrkLSQeocyWrP3
 9JucaBD36IEYfwbYN4rK1iEBktzoPzTR57GGqVav0+B4b6D688mlgGjo4WtFowc1
 F7AFrwmVozbKyAkq2gqF/6ufIrEY8RB+bRr41MtaG89gu6EiEyNE7V52Jg0WDr7L
 yw/XtZtN4H2t2TO+0hKTV0sLR1HPC/PoCNb5ayHq/8jpcKJ8uC0KfyxVsgpaC0AZ
 3CmtQ4J3hWAFx0Hrl0YKH33taQyAD9M/iOa8WV068YoaxamrkmC3wpIV6C86wL8C
 FbUW4Uk=
 =HHlm
 -----END PGP SIGNATURE-----

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

Pull sound fixes from Takashi Iwai:
 "It's getting calmer, but we still came up with a handful of small
  fixes, including two core fixes. All look sane and safe.

  Core:
   - Fix wait queue list corruption in snd_pcm_drain() on linked streams
   - Fix UMP event stack overread in seq dummy driver

  USB-audio:
   - Add quirk for AB13X USB Audio
   - Fix the regression with sticky mixer volumes in 7.1-rc

  ASoC:
   - Fix 32-slot TDM breakage on Freescale SAI
   - Varioud DMI quirks for AMD ACP"

* tag 'sound-7.1-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: seq: dummy: fix UMP event stack overread
  ALSA: usb-audio: Add iface reset and delay quirk for AB13X USB Audio
  ALSA: PCM: Fix wait queue list corruption in snd_pcm_drain() on linked streams
  ASoC: amd: acp70: add standalone RT721 SoundWire machine
  ASoC: amd: yc: Add MSI Raider A18 HX A9WJG to quirk table
  ASoC: fsl_sai: Fix 32 slots TDM broken by integer shift UB in xMR write
  ASoC: amd: yc: Enable internal mic on MSI Bravo 17 C7VF
  ASoC: amd: acp: Add DMI quirk for Lenovo Yoga Pro 7 15ASH11
  ALSA: usb-audio: Set the value of potential sticky mixers to maximum
This commit is contained in:
Linus Torvalds 2026-06-06 09:49:16 -07:00
commit 6086121dc4
8 changed files with 109 additions and 15 deletions

View File

@ -2199,9 +2199,8 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
drain_no_period_wakeup = to_check->no_period_wakeup;
drain_rate = to_check->rate;
drain_bufsz = to_check->buffer_size;
init_waitqueue_entry(&wait, current);
set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&to_check->sleep, &wait);
init_wait_entry(&wait, 0);
prepare_to_wait(&to_check->sleep, &wait, TASK_INTERRUPTIBLE);
snd_pcm_stream_unlock_irq(substream);
if (drain_no_period_wakeup)
tout = MAX_SCHEDULE_TIMEOUT;
@ -2219,7 +2218,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
group = snd_pcm_stream_group_ref(substream);
snd_pcm_group_for_each_entry(s, substream) {
if (s->runtime == to_check) {
remove_wait_queue(&to_check->sleep, &wait);
finish_wait(&to_check->sleep, &wait);
break;
}
}

View File

@ -9,6 +9,7 @@
#include <linux/module.h>
#include <sound/core.h>
#include "seq_clientmgr.h"
#include "seq_memory.h"
#include <sound/initval.h>
#include <sound/asoundef.h>
@ -81,19 +82,21 @@ dummy_input(struct snd_seq_event *ev, int direct, void *private_data,
int atomic, int hop)
{
struct snd_seq_dummy_port *p;
struct snd_seq_event tmpev;
union __snd_seq_event tmpev;
size_t size;
p = private_data;
if (ev->source.client == SNDRV_SEQ_CLIENT_SYSTEM ||
ev->type == SNDRV_SEQ_EVENT_KERNEL_ERROR)
return 0; /* ignore system messages */
tmpev = *ev;
size = snd_seq_event_packet_size(ev);
memcpy(&tmpev, ev, size);
if (p->duplex)
tmpev.source.port = p->connect;
tmpev.legacy.source.port = p->connect;
else
tmpev.source.port = p->port;
tmpev.dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS;
return snd_seq_kernel_client_dispatch(p->client, &tmpev, atomic, hop);
tmpev.legacy.source.port = p->port;
tmpev.legacy.dest.client = SNDRV_SEQ_ADDRESS_SUBSCRIBERS;
return snd_seq_kernel_client_dispatch(p->client, &tmpev.legacy, atomic, hop);
}
/*

View File

@ -37,6 +37,13 @@ static const struct dmi_system_id acp70_acpi_flag_override_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Zenbook S16 UM5606GA"),
},
},
{
/* Lenovo Yoga Pro 7 15ASH11 (Strix Halo, ACP 7.0) */
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "83W5"),
},
},
{}
};

View File

@ -619,6 +619,45 @@ static const struct snd_soc_acpi_link_adr acp70_rt721_l1u0_tas2783x2_l1u8b[] = {
{}
};
static const struct snd_soc_acpi_endpoint rt721_endpoints[] = {
{ /* Jack Playback/Capture Endpoint (AIF1) */
.num = 0,
.aggregated = 0,
.group_position = 0,
.group_id = 0,
},
{ /* Speaker Amplifier Endpoint (AIF2, internal amp) */
.num = 1,
.aggregated = 0,
.group_position = 0,
.group_id = 0,
},
{ /* DMIC Capture Endpoint (AIF3) */
.num = 2,
.aggregated = 0,
.group_position = 0,
.group_id = 0,
},
};
static const struct snd_soc_acpi_adr_device rt721_1_single_adr[] = {
{
.adr = 0x000130025D072101ull,
.num_endpoints = ARRAY_SIZE(rt721_endpoints),
.endpoints = rt721_endpoints,
.name_prefix = "rt721"
}
};
static const struct snd_soc_acpi_link_adr acp70_rt721_only[] = {
{
.mask = BIT(1),
.num_adr = ARRAY_SIZE(rt721_1_single_adr),
.adr_d = rt721_1_single_adr,
},
{}
};
struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_sdw_machines[] = {
{
.link_mask = BIT(0) | BIT(1),
@ -711,6 +750,11 @@ struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_sdw_machines[] = {
.links = acp70_rt721_l1u0_tas2783x2_l1u8b,
.drv_name = "amd_sdw",
},
{
.link_mask = BIT(1),
.links = acp70_rt721_only,
.drv_name = "amd_sdw",
},
{},
};
EXPORT_SYMBOL(snd_soc_acpi_amd_acp70_sdw_machines);

View File

@ -521,6 +521,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Vector A16 HX A8WHG"),
}
},
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Micro-Star International Co., Ltd."),
DMI_MATCH(DMI_PRODUCT_NAME, "Raider A18 HX A9WJG"),
}
},
{
.driver_data = &acp6x_card,
.matches = {
@ -794,6 +801,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "M7601RM"),
}
},
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Micro-Star International Co., Ltd."),
DMI_MATCH(DMI_BOARD_NAME, "MS-17LN"),
}
},
{}
};

View File

@ -793,7 +793,7 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
FSL_SAI_CR4_FSD_MSTR, FSL_SAI_CR4_FSD_MSTR);
regmap_write(sai->regmap, FSL_SAI_xMR(tx),
~0UL - ((1 << min(channels, slots)) - 1));
~GENMASK_U32(min(channels, slots) - 1, 0));
return 0;
}

View File

@ -1371,10 +1371,8 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
goto no_checks;
ret = check_sticky_volume_control(cval, minchn, saved);
if (ret < 0) {
snd_usb_set_cur_mix_value(cval, minchn, 0, saved);
return ret;
}
if (ret < 0)
goto sticky;
if (cval->min + cval->res < cval->max)
check_volume_control_res(cval, minchn, saved);
@ -1431,6 +1429,33 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval,
}
return 0;
sticky:
/*
* It makes no sense to restore the saved value for a sticky mixer,
* since setting any value is a no-op.
*
* However, in some rare cases, SET_CUR is effective despite GET_CUR
* always returns a constant value. These mixers are not sticky, but
* there's no way to distinguish them. Without any additional
* information, the best thing we can do is to set the mixer value to
* the maximum before bailing out, so that a soft mixer can still reach
* the maximum hardware volume if the mixer turns out to be non-sticky.
* Meanwhile, all channels must be synchronized to prevent imbalance
* volume.
*/
if (!cval->cmask) {
snd_usb_set_cur_mix_value(cval, 0, 0, cval->max);
} else {
for (i = 0; i < MAX_CHANNELS; i++) {
idx = 0;
if (cval->cmask & BIT(i)) {
snd_usb_set_cur_mix_value(cval, i + 1, idx, cval->max);
idx++;
}
}
}
return ret;
}
#define get_min_max(cval, def) get_min_max_with_quirks(cval, def, NULL)

View File

@ -2487,6 +2487,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE),
DEVICE_FLG(0x3443, 0x930d, /* NexiGo N930W 60fps Webcam */
QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_MIC_RES_16),
DEVICE_FLG(0x3c20, 0x3d21, /* AB13X USB Audio */
QUIRK_FLAG_FORCE_IFACE_RESET | QUIRK_FLAG_IFACE_DELAY),
DEVICE_FLG(0x413c, 0xa506, /* Dell AE515 sound bar */
QUIRK_FLAG_GET_SAMPLE_RATE),
DEVICE_FLG(0x534d, 0x0021, /* MacroSilicon MS2100/MS2106 */