Merge tag 'asoc-fix-v5.12-rc2' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Fixes for v5.12
Quite a lot of mostly platform specific fixes here, the only one which
is generic is a fix for regressions on devices with more complex
clocking support with simple-card. There's also a few new device IDs
and platform quirks.
diff --git a/sound/firewire/dice/dice-stream.c b/sound/firewire/dice/dice-stream.c
index 8e0c038..1a14c08 100644
--- a/sound/firewire/dice/dice-stream.c
+++ b/sound/firewire/dice/dice-stream.c
@@ -493,11 +493,10 @@ void snd_dice_stream_stop_duplex(struct snd_dice *dice)
struct reg_params tx_params, rx_params;
if (dice->substreams_counter == 0) {
- if (get_register_params(dice, &tx_params, &rx_params) >= 0) {
- amdtp_domain_stop(&dice->domain);
+ if (get_register_params(dice, &tx_params, &rx_params) >= 0)
finish_session(dice, &tx_params, &rx_params);
- }
+ amdtp_domain_stop(&dice->domain);
release_resources(dice);
}
}
diff --git a/sound/hda/intel-nhlt.c b/sound/hda/intel-nhlt.c
index d053bec..e223723 100644
--- a/sound/hda/intel-nhlt.c
+++ b/sound/hda/intel-nhlt.c
@@ -39,6 +39,11 @@ int intel_nhlt_get_dmic_geo(struct device *dev, struct nhlt_acpi_table *nhlt)
if (!nhlt)
return 0;
+ if (nhlt->header.length <= sizeof(struct acpi_table_header)) {
+ dev_warn(dev, "Invalid DMIC description table\n");
+ return 0;
+ }
+
for (j = 0, epnt = nhlt->desc; j < nhlt->endpoint_count; j++,
epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length)) {
diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c
index 6a85645..17a25e4 100644
--- a/sound/pci/hda/hda_bind.c
+++ b/sound/pci/hda/hda_bind.c
@@ -47,6 +47,10 @@ static void hda_codec_unsol_event(struct hdac_device *dev, unsigned int ev)
if (codec->bus->shutdown)
return;
+ /* ignore unsol events during system suspend/resume */
+ if (codec->core.dev.power.power_state.event != PM_EVENT_ON)
+ return;
+
if (codec->patch_ops.unsol_event)
codec->patch_ops.unsol_event(codec, ev);
}
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index 9087981..ca2f2ec 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -609,13 +609,6 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
20,
178000000);
- /* by some reason, the playback stream stalls on PulseAudio with
- * tsched=1 when a capture stream triggers. Until we figure out the
- * real cause, disable tsched mode by telling the PCM info flag.
- */
- if (chip->driver_caps & AZX_DCAPS_AMD_WORKAROUND)
- runtime->hw.info |= SNDRV_PCM_INFO_BATCH;
-
if (chip->align_buffer_size)
/* constrain buffer sizes to be multiple of 128
bytes. This is more efficient in terms of memory
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 8b7c550..f5cba7a 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -4065,7 +4065,7 @@ static int add_micmute_led_hook(struct hda_codec *codec)
spec->micmute_led.led_mode = MICMUTE_LED_FOLLOW_MUTE;
spec->micmute_led.capture = 0;
- spec->micmute_led.led_value = 0;
+ spec->micmute_led.led_value = -1;
spec->micmute_led.old_hook = spec->cap_sync_hook;
spec->cap_sync_hook = update_micmute_led;
if (!snd_hda_gen_add_kctl(spec, NULL, &micmute_led_mode_ctl))
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 5b492c3..5eea130 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1026,6 +1026,8 @@ static int azx_prepare(struct device *dev)
chip = card->private_data;
chip->pm_prepared = 1;
+ flush_work(&azx_bus(chip)->unsol_work);
+
/* HDA controller always requires different WAKEEN for runtime suspend
* and system suspend, so don't use direct-complete here.
*/
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index c966f49f..b2b620f 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -1309,6 +1309,7 @@ static const struct snd_pci_quirk ca0132_quirks[] = {
SND_PCI_QUIRK(0x1102, 0x0013, "Recon3D", QUIRK_R3D),
SND_PCI_QUIRK(0x1102, 0x0018, "Recon3D", QUIRK_R3D),
SND_PCI_QUIRK(0x1102, 0x0051, "Sound Blaster AE-5", QUIRK_AE5),
+ SND_PCI_QUIRK(0x1102, 0x0191, "Sound Blaster AE-5 Plus", QUIRK_AE5),
SND_PCI_QUIRK(0x1102, 0x0081, "Sound Blaster AE-7", QUIRK_AE7),
{}
};
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index f2aa226d..c20dad4 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -149,6 +149,21 @@ static int cx_auto_vmaster_mute_led(struct led_classdev *led_cdev,
return 0;
}
+static void cxt_init_gpio_led(struct hda_codec *codec)
+{
+ struct conexant_spec *spec = codec->spec;
+ unsigned int mask = spec->gpio_mute_led_mask | spec->gpio_mic_led_mask;
+
+ if (mask) {
+ snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK,
+ mask);
+ snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION,
+ mask);
+ snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
+ spec->gpio_led);
+ }
+}
+
static int cx_auto_init(struct hda_codec *codec)
{
struct conexant_spec *spec = codec->spec;
@@ -156,6 +171,7 @@ static int cx_auto_init(struct hda_codec *codec)
if (!spec->dynamic_eapd)
cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
+ cxt_init_gpio_led(codec);
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
return 0;
@@ -215,6 +231,7 @@ enum {
CXT_FIXUP_HP_SPECTRE,
CXT_FIXUP_HP_GATE_MIC,
CXT_FIXUP_MUTE_LED_GPIO,
+ CXT_FIXUP_HP_ZBOOK_MUTE_LED,
CXT_FIXUP_HEADSET_MIC,
CXT_FIXUP_HP_MIC_NO_PRESENCE,
};
@@ -654,31 +671,36 @@ static int cxt_gpio_micmute_update(struct led_classdev *led_cdev,
return 0;
}
+static void cxt_setup_mute_led(struct hda_codec *codec,
+ unsigned int mute, unsigned int mic_mute)
+{
+ struct conexant_spec *spec = codec->spec;
+
+ spec->gpio_led = 0;
+ spec->mute_led_polarity = 0;
+ if (mute) {
+ snd_hda_gen_add_mute_led_cdev(codec, cxt_gpio_mute_update);
+ spec->gpio_mute_led_mask = mute;
+ }
+ if (mic_mute) {
+ snd_hda_gen_add_micmute_led_cdev(codec, cxt_gpio_micmute_update);
+ spec->gpio_mic_led_mask = mic_mute;
+ }
+}
static void cxt_fixup_mute_led_gpio(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
- struct conexant_spec *spec = codec->spec;
- static const struct hda_verb gpio_init[] = {
- { 0x01, AC_VERB_SET_GPIO_MASK, 0x03 },
- { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03 },
- {}
- };
-
- if (action == HDA_FIXUP_ACT_PRE_PROBE) {
- snd_hda_gen_add_mute_led_cdev(codec, cxt_gpio_mute_update);
- spec->gpio_led = 0;
- spec->mute_led_polarity = 0;
- spec->gpio_mute_led_mask = 0x01;
- spec->gpio_mic_led_mask = 0x02;
- snd_hda_gen_add_micmute_led_cdev(codec, cxt_gpio_micmute_update);
- }
- snd_hda_add_verbs(codec, gpio_init);
- if (spec->gpio_led)
- snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
- spec->gpio_led);
+ if (action == HDA_FIXUP_ACT_PRE_PROBE)
+ cxt_setup_mute_led(codec, 0x01, 0x02);
}
+static void cxt_fixup_hp_zbook_mute_led(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
+{
+ if (action == HDA_FIXUP_ACT_PRE_PROBE)
+ cxt_setup_mute_led(codec, 0x10, 0x20);
+}
/* ThinkPad X200 & co with cxt5051 */
static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = {
@@ -839,6 +861,10 @@ static const struct hda_fixup cxt_fixups[] = {
.type = HDA_FIXUP_FUNC,
.v.func = cxt_fixup_mute_led_gpio,
},
+ [CXT_FIXUP_HP_ZBOOK_MUTE_LED] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = cxt_fixup_hp_zbook_mute_led,
+ },
[CXT_FIXUP_HEADSET_MIC] = {
.type = HDA_FIXUP_FUNC,
.v.func = cxt_fixup_headset_mic,
@@ -917,6 +943,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
SND_PCI_QUIRK(0x103c, 0x8299, "HP 800 G3 SFF", CXT_FIXUP_HP_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x103c, 0x829a, "HP 800 G3 DM", CXT_FIXUP_HP_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x103c, 0x8402, "HP ProBook 645 G4", CXT_FIXUP_MUTE_LED_GPIO),
+ SND_PCI_QUIRK(0x103c, 0x8427, "HP ZBook Studio G5", CXT_FIXUP_HP_ZBOOK_MUTE_LED),
SND_PCI_QUIRK(0x103c, 0x8455, "HP Z2 G4", CXT_FIXUP_HP_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x103c, 0x8456, "HP Z2 G4 SFF", CXT_FIXUP_HP_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x103c, 0x8457, "HP Z2 G4 mini", CXT_FIXUP_HP_MIC_NO_PRESENCE),
@@ -956,6 +983,7 @@ static const struct hda_model_fixup cxt5066_fixup_models[] = {
{ .id = CXT_FIXUP_MUTE_LED_EAPD, .name = "mute-led-eapd" },
{ .id = CXT_FIXUP_HP_DOCK, .name = "hp-dock" },
{ .id = CXT_FIXUP_MUTE_LED_GPIO, .name = "mute-led-gpio" },
+ { .id = CXT_FIXUP_HP_ZBOOK_MUTE_LED, .name = "hp-zbook-mute-led" },
{ .id = CXT_FIXUP_HP_MIC_NO_PRESENCE, .name = "hp-mic-fix" },
{}
};
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index e6d0843..45ae845 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -2480,6 +2480,18 @@ static void generic_hdmi_free(struct hda_codec *codec)
}
#ifdef CONFIG_PM
+static int generic_hdmi_suspend(struct hda_codec *codec)
+{
+ struct hdmi_spec *spec = codec->spec;
+ int pin_idx;
+
+ for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
+ struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
+ cancel_delayed_work_sync(&per_pin->work);
+ }
+ return 0;
+}
+
static int generic_hdmi_resume(struct hda_codec *codec)
{
struct hdmi_spec *spec = codec->spec;
@@ -2503,6 +2515,7 @@ static const struct hda_codec_ops generic_hdmi_patch_ops = {
.build_controls = generic_hdmi_build_controls,
.unsol_event = hdmi_unsol_event,
#ifdef CONFIG_PM
+ .suspend = generic_hdmi_suspend,
.resume = generic_hdmi_resume,
#endif
};
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index b47504f..316b9b4 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -4225,6 +4225,12 @@ static void alc_fixup_hp_gpio_led(struct hda_codec *codec,
}
}
+static void alc236_fixup_hp_gpio_led(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
+{
+ alc_fixup_hp_gpio_led(codec, action, 0x02, 0x01);
+}
+
static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
@@ -6381,6 +6387,7 @@ enum {
ALC294_FIXUP_ASUS_GX502_VERBS,
ALC285_FIXUP_HP_GPIO_LED,
ALC285_FIXUP_HP_MUTE_LED,
+ ALC236_FIXUP_HP_GPIO_LED,
ALC236_FIXUP_HP_MUTE_LED,
ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET,
ALC295_FIXUP_ASUS_MIC_NO_PRESENCE,
@@ -7616,6 +7623,10 @@ static const struct hda_fixup alc269_fixups[] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc285_fixup_hp_mute_led,
},
+ [ALC236_FIXUP_HP_GPIO_LED] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc236_fixup_hp_gpio_led,
+ },
[ALC236_FIXUP_HP_MUTE_LED] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc236_fixup_hp_mute_led,
@@ -8045,9 +8056,12 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x8783, "HP ZBook Fury 15 G7 Mobile Workstation",
ALC285_FIXUP_HP_GPIO_AMP_INIT),
SND_PCI_QUIRK(0x103c, 0x87c8, "HP", ALC287_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x87e5, "HP ProBook 440 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x87f4, "HP", ALC287_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x87f5, "HP", ALC287_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x87f7, "HP Spectre x360 14", ALC245_FIXUP_HP_X360_AMP),
+ SND_PCI_QUIRK(0x103c, 0x8846, "HP EliteBook 850 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
+ SND_PCI_QUIRK(0x103c, 0x884c, "HP EliteBook 840 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
@@ -8242,7 +8256,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1b35, 0x1237, "CZC L101", ALC269_FIXUP_CZC_L101),
SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
SND_PCI_QUIRK(0x1d72, 0x1602, "RedmiBook", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1d72, 0x1701, "XiaomiNotebook Pro", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1d72, 0x1947, "RedmiBook Air", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE),
SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802),
SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X),
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 85ed850..b6f4c08 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -830,6 +830,9 @@ static int usb_audio_probe(struct usb_interface *intf,
snd_media_device_create(chip, intf);
}
+ if (quirk)
+ chip->quirk_type = quirk->type;
+
usb_chip[chip->index] = chip;
chip->intf[chip->num_interfaces] = intf;
chip->num_interfaces++;
@@ -904,6 +907,9 @@ static void usb_audio_disconnect(struct usb_interface *intf)
}
}
+ if (chip->quirk_type & QUIRK_SETUP_DISABLE_AUTOSUSPEND)
+ usb_enable_autosuspend(interface_to_usbdev(intf));
+
chip->num_interfaces--;
if (chip->num_interfaces <= 0) {
usb_chip[chip->index] = NULL;
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 737b272..d3001fb 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -547,7 +547,7 @@ static int setup_disable_autosuspend(struct snd_usb_audio *chip,
struct usb_driver *driver,
const struct snd_usb_audio_quirk *quirk)
{
- driver->supports_autosuspend = 0;
+ usb_disable_autosuspend(interface_to_usbdev(iface));
return 1; /* Continue with creating streams and mixer */
}
@@ -1520,6 +1520,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip)
case USB_ID(0x1901, 0x0191): /* GE B850V3 CP2114 audio interface */
case USB_ID(0x21b4, 0x0081): /* AudioQuest DragonFly */
case USB_ID(0x2912, 0x30c8): /* Audioengine D1 */
+ case USB_ID(0x413c, 0xa506): /* Dell AE515 sound bar */
return true;
}
@@ -1670,6 +1671,14 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe,
&& (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS)
msleep(20);
+ /*
+ * Plantronics headsets (C320, C320-M, etc) need a delay to avoid
+ * random microhpone failures.
+ */
+ if (USB_ID_VENDOR(chip->usb_id) == 0x047f &&
+ (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS)
+ msleep(20);
+
/* Zoom R16/24, many Logitech(at least H650e/H570e/BCC950),
* Jabra 550a, Kingston HyperX needs a tiny delay here,
* otherwise requests like get/set frequency return
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 215c177..60b9dd7d 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -27,6 +27,7 @@ struct snd_usb_audio {
struct snd_card *card;
struct usb_interface *intf[MAX_CARD_INTERFACES];
u32 usb_id;
+ uint16_t quirk_type;
struct mutex mutex;
unsigned int system_suspend;
atomic_t active;