Loading sound/hda/intel-nhlt.c +5 −0 Original line number Diff line number Diff line Loading @@ -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)) { Loading sound/pci/hda/patch_conexant.c +45 −17 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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, }; Loading Loading @@ -654,31 +671,36 @@ static int cxt_gpio_micmute_update(struct led_classdev *led_cdev, return 0; } static void cxt_fixup_mute_led_gpio(struct hda_codec *codec, const struct hda_fixup *fix, int action) static void cxt_setup_mute_led(struct hda_codec *codec, unsigned int mute, unsigned int mic_mute) { 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; 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; } 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); } static void cxt_fixup_mute_led_gpio(struct hda_codec *codec, const struct hda_fixup *fix, int action) { 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[] = { Loading Loading @@ -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, Loading Loading @@ -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), Loading Loading @@ -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" }, {} }; Loading sound/usb/card.c +5 −0 Original line number Diff line number Diff line Loading @@ -830,6 +830,8 @@ static int usb_audio_probe(struct usb_interface *intf, snd_media_device_create(chip, intf); } chip->quirk_type = quirk->type; usb_chip[chip->index] = chip; chip->intf[chip->num_interfaces] = intf; chip->num_interfaces++; Loading Loading @@ -912,6 +914,9 @@ static void usb_audio_disconnect(struct usb_interface *intf) } else { mutex_unlock(®ister_mutex); } if (chip->quirk_type & QUIRK_SETUP_DISABLE_AUTOSUSPEND) usb_enable_autosuspend(interface_to_usbdev(intf)); } /* lock the shutdown (disconnect) task and autoresume */ Loading sound/usb/quirks.c +10 −1 Original line number Diff line number Diff line Loading @@ -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 */ } Loading Loading @@ -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; } Loading Loading @@ -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 Loading sound/usb/usbaudio.h +1 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading
sound/hda/intel-nhlt.c +5 −0 Original line number Diff line number Diff line Loading @@ -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)) { Loading
sound/pci/hda/patch_conexant.c +45 −17 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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, }; Loading Loading @@ -654,31 +671,36 @@ static int cxt_gpio_micmute_update(struct led_classdev *led_cdev, return 0; } static void cxt_fixup_mute_led_gpio(struct hda_codec *codec, const struct hda_fixup *fix, int action) static void cxt_setup_mute_led(struct hda_codec *codec, unsigned int mute, unsigned int mic_mute) { 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; 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; } 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); } static void cxt_fixup_mute_led_gpio(struct hda_codec *codec, const struct hda_fixup *fix, int action) { 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[] = { Loading Loading @@ -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, Loading Loading @@ -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), Loading Loading @@ -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" }, {} }; Loading
sound/usb/card.c +5 −0 Original line number Diff line number Diff line Loading @@ -830,6 +830,8 @@ static int usb_audio_probe(struct usb_interface *intf, snd_media_device_create(chip, intf); } chip->quirk_type = quirk->type; usb_chip[chip->index] = chip; chip->intf[chip->num_interfaces] = intf; chip->num_interfaces++; Loading Loading @@ -912,6 +914,9 @@ static void usb_audio_disconnect(struct usb_interface *intf) } else { mutex_unlock(®ister_mutex); } if (chip->quirk_type & QUIRK_SETUP_DISABLE_AUTOSUSPEND) usb_enable_autosuspend(interface_to_usbdev(intf)); } /* lock the shutdown (disconnect) task and autoresume */ Loading
sound/usb/quirks.c +10 −1 Original line number Diff line number Diff line Loading @@ -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 */ } Loading Loading @@ -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; } Loading Loading @@ -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 Loading
sound/usb/usbaudio.h +1 −0 Original line number Diff line number Diff line Loading @@ -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; Loading