Loading sound/pci/hda/hda_generic.c +58 −21 Original line number Diff line number Diff line Loading @@ -2507,12 +2507,8 @@ static int create_out_jack_modes(struct hda_codec *codec, int num_pins, for (i = 0; i < num_pins; i++) { hda_nid_t pin = pins[i]; if (pin == spec->hp_mic_pin) { int ret = create_hp_mic_jack_mode(codec, pin); if (ret < 0) return ret; if (pin == spec->hp_mic_pin) continue; } if (get_out_jack_num_items(codec, pin) > 1) { struct snd_kcontrol_new *knew; char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; Loading Loading @@ -2765,7 +2761,7 @@ static int hp_mic_jack_mode_put(struct snd_kcontrol *kcontrol, val &= ~(AC_PINCTL_VREFEN | PIN_HP); val |= get_vref_idx(vref_caps, idx) | PIN_IN; } else val = snd_hda_get_default_vref(codec, nid); val = snd_hda_get_default_vref(codec, nid) | PIN_IN; } snd_hda_set_pin_ctl_cache(codec, nid, val); call_hp_automute(codec, NULL); Loading @@ -2785,9 +2781,6 @@ static int create_hp_mic_jack_mode(struct hda_codec *codec, hda_nid_t pin) struct hda_gen_spec *spec = codec->spec; struct snd_kcontrol_new *knew; if (get_out_jack_num_items(codec, pin) <= 1 && get_in_jack_num_items(codec, pin) <= 1) return 0; /* no need */ knew = snd_hda_gen_add_kctl(spec, "Headphone Mic Jack Mode", &hp_mic_jack_mode_enum); if (!knew) Loading Loading @@ -2816,6 +2809,42 @@ static int add_loopback_list(struct hda_gen_spec *spec, hda_nid_t mix, int idx) return 0; } /* return true if either a volume or a mute amp is found for the given * aamix path; the amp has to be either in the mixer node or its direct leaf */ static bool look_for_mix_leaf_ctls(struct hda_codec *codec, hda_nid_t mix_nid, hda_nid_t pin, unsigned int *mix_val, unsigned int *mute_val) { int idx, num_conns; const hda_nid_t *list; hda_nid_t nid; idx = snd_hda_get_conn_index(codec, mix_nid, pin, true); if (idx < 0) return false; *mix_val = *mute_val = 0; if (nid_has_volume(codec, mix_nid, HDA_INPUT)) *mix_val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT); if (nid_has_mute(codec, mix_nid, HDA_INPUT)) *mute_val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT); if (*mix_val && *mute_val) return true; /* check leaf node */ num_conns = snd_hda_get_conn_list(codec, mix_nid, &list); if (num_conns < idx) return false; nid = list[idx]; if (!*mix_val && nid_has_volume(codec, nid, HDA_OUTPUT)) *mix_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); if (!*mute_val && nid_has_mute(codec, nid, HDA_OUTPUT)) *mute_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); return *mix_val || *mute_val; } /* create input playback/capture controls for the given pin */ static int new_analog_input(struct hda_codec *codec, int input_idx, hda_nid_t pin, const char *ctlname, int ctlidx, Loading @@ -2823,12 +2852,11 @@ static int new_analog_input(struct hda_codec *codec, int input_idx, { struct hda_gen_spec *spec = codec->spec; struct nid_path *path; unsigned int val; unsigned int mix_val, mute_val; int err, idx; if (!nid_has_volume(codec, mix_nid, HDA_INPUT) && !nid_has_mute(codec, mix_nid, HDA_INPUT)) return 0; /* no need for analog loopback */ if (!look_for_mix_leaf_ctls(codec, mix_nid, pin, &mix_val, &mute_val)) return 0; path = snd_hda_add_new_path(codec, pin, mix_nid, 0); if (!path) Loading @@ -2837,20 +2865,18 @@ static int new_analog_input(struct hda_codec *codec, int input_idx, spec->loopback_paths[input_idx] = snd_hda_get_path_idx(codec, path); idx = path->idx[path->depth - 1]; if (nid_has_volume(codec, mix_nid, HDA_INPUT)) { val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT); err = __add_pb_vol_ctrl(spec, HDA_CTL_WIDGET_VOL, ctlname, ctlidx, val); if (mix_val) { err = __add_pb_vol_ctrl(spec, HDA_CTL_WIDGET_VOL, ctlname, ctlidx, mix_val); if (err < 0) return err; path->ctls[NID_PATH_VOL_CTL] = val; path->ctls[NID_PATH_VOL_CTL] = mix_val; } if (nid_has_mute(codec, mix_nid, HDA_INPUT)) { val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT); err = __add_pb_sw_ctrl(spec, HDA_CTL_WIDGET_MUTE, ctlname, ctlidx, val); if (mute_val) { err = __add_pb_sw_ctrl(spec, HDA_CTL_WIDGET_MUTE, ctlname, ctlidx, mute_val); if (err < 0) return err; path->ctls[NID_PATH_MUTE_CTL] = val; path->ctls[NID_PATH_MUTE_CTL] = mute_val; } path->active = true; Loading Loading @@ -4384,6 +4410,17 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec, if (err < 0) return err; /* create "Headphone Mic Jack Mode" if no input selection is * available (or user specifies add_jack_modes hint) */ if (spec->hp_mic_pin && (spec->auto_mic || spec->input_mux.num_items == 1 || spec->add_jack_modes)) { err = create_hp_mic_jack_mode(codec, spec->hp_mic_pin); if (err < 0) return err; } if (spec->add_jack_modes) { if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { err = create_out_jack_modes(codec, cfg->line_outs, Loading sound/pci/hda/patch_conexant.c +23 −0 Original line number Diff line number Diff line Loading @@ -3244,9 +3244,29 @@ enum { #if IS_ENABLED(CONFIG_THINKPAD_ACPI) #include <linux/thinkpad_acpi.h> #include <acpi/acpi.h> static int (*led_set_func)(int, bool); static acpi_status acpi_check_cb(acpi_handle handle, u32 lvl, void *context, void **rv) { bool *found = context; *found = true; return AE_OK; } static bool is_thinkpad(struct hda_codec *codec) { bool found = false; if (codec->subsystem_id >> 16 != 0x17aa) return false; if (ACPI_SUCCESS(acpi_get_devices("LEN0068", acpi_check_cb, &found, NULL)) && found) return true; found = false; return ACPI_SUCCESS(acpi_get_devices("IBM0068", acpi_check_cb, &found, NULL)) && found; } static void update_tpacpi_mute_led(void *private_data, int enabled) { struct hda_codec *codec = private_data; Loading Loading @@ -3279,6 +3299,8 @@ static void cxt_fixup_thinkpad_acpi(struct hda_codec *codec, bool removefunc = false; if (action == HDA_FIXUP_ACT_PROBE) { if (!is_thinkpad(codec)) return; if (!led_set_func) led_set_func = symbol_request(tpacpi_led_set); if (!led_set_func) { Loading Loading @@ -3494,6 +3516,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC), SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", CXT_FIXUP_THINKPAD_ACPI), SND_PCI_QUIRK(0x1c06, 0x2011, "Lemote A1004", CXT_PINCFG_LEMOTE_A1004), SND_PCI_QUIRK(0x1c06, 0x2012, "Lemote A1205", CXT_PINCFG_LEMOTE_A1205), {} Loading sound/pci/hda/patch_realtek.c +9 −2 Original line number Diff line number Diff line Loading @@ -3798,6 +3798,7 @@ enum { ALC271_FIXUP_HP_GATE_MIC_JACK, ALC269_FIXUP_ACER_AC700, ALC269_FIXUP_LIMIT_INT_MIC_BOOST, ALC269VB_FIXUP_ASUS_ZENBOOK, ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED, ALC269VB_FIXUP_ORDISSIMO_EVE2, ALC283_FIXUP_CHROME_BOOK, Loading Loading @@ -4075,6 +4076,12 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC269_FIXUP_THINKPAD_ACPI, }, [ALC269VB_FIXUP_ASUS_ZENBOOK] = { .type = HDA_FIXUP_FUNC, .v.func = alc269_fixup_limit_int_mic_boost, .chained = true, .chain_id = ALC269VB_FIXUP_DMIC, }, [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = { .type = HDA_FIXUP_FUNC, .v.func = alc269_fixup_limit_int_mic_boost, Loading Loading @@ -4189,8 +4196,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC), SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_DMIC), SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK), SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), Loading sound/usb/endpoint.c +15 −1 Original line number Diff line number Diff line Loading @@ -636,8 +636,22 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep, if (usb_pipein(ep->pipe) || snd_usb_endpoint_implicit_feedback_sink(ep)) { urb_packs = packs_per_ms; /* * Wireless devices can poll at a max rate of once per 4ms. * For dataintervals less than 5, increase the packet count to * allow the host controller to use bursting to fill in the * gaps. */ if (snd_usb_get_speed(ep->chip->dev) == USB_SPEED_WIRELESS) { int interval = ep->datainterval; while (interval < 5) { urb_packs <<= 1; ++interval; } } /* make capture URBs <= 1 ms and smaller than a period */ urb_packs = min(max_packs_per_urb, packs_per_ms); urb_packs = min(max_packs_per_urb, urb_packs); while (urb_packs > 1 && urb_packs * maxsize >= period_bytes) urb_packs >>= 1; ep->nurbs = MAX_URBS; Loading Loading
sound/pci/hda/hda_generic.c +58 −21 Original line number Diff line number Diff line Loading @@ -2507,12 +2507,8 @@ static int create_out_jack_modes(struct hda_codec *codec, int num_pins, for (i = 0; i < num_pins; i++) { hda_nid_t pin = pins[i]; if (pin == spec->hp_mic_pin) { int ret = create_hp_mic_jack_mode(codec, pin); if (ret < 0) return ret; if (pin == spec->hp_mic_pin) continue; } if (get_out_jack_num_items(codec, pin) > 1) { struct snd_kcontrol_new *knew; char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; Loading Loading @@ -2765,7 +2761,7 @@ static int hp_mic_jack_mode_put(struct snd_kcontrol *kcontrol, val &= ~(AC_PINCTL_VREFEN | PIN_HP); val |= get_vref_idx(vref_caps, idx) | PIN_IN; } else val = snd_hda_get_default_vref(codec, nid); val = snd_hda_get_default_vref(codec, nid) | PIN_IN; } snd_hda_set_pin_ctl_cache(codec, nid, val); call_hp_automute(codec, NULL); Loading @@ -2785,9 +2781,6 @@ static int create_hp_mic_jack_mode(struct hda_codec *codec, hda_nid_t pin) struct hda_gen_spec *spec = codec->spec; struct snd_kcontrol_new *knew; if (get_out_jack_num_items(codec, pin) <= 1 && get_in_jack_num_items(codec, pin) <= 1) return 0; /* no need */ knew = snd_hda_gen_add_kctl(spec, "Headphone Mic Jack Mode", &hp_mic_jack_mode_enum); if (!knew) Loading Loading @@ -2816,6 +2809,42 @@ static int add_loopback_list(struct hda_gen_spec *spec, hda_nid_t mix, int idx) return 0; } /* return true if either a volume or a mute amp is found for the given * aamix path; the amp has to be either in the mixer node or its direct leaf */ static bool look_for_mix_leaf_ctls(struct hda_codec *codec, hda_nid_t mix_nid, hda_nid_t pin, unsigned int *mix_val, unsigned int *mute_val) { int idx, num_conns; const hda_nid_t *list; hda_nid_t nid; idx = snd_hda_get_conn_index(codec, mix_nid, pin, true); if (idx < 0) return false; *mix_val = *mute_val = 0; if (nid_has_volume(codec, mix_nid, HDA_INPUT)) *mix_val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT); if (nid_has_mute(codec, mix_nid, HDA_INPUT)) *mute_val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT); if (*mix_val && *mute_val) return true; /* check leaf node */ num_conns = snd_hda_get_conn_list(codec, mix_nid, &list); if (num_conns < idx) return false; nid = list[idx]; if (!*mix_val && nid_has_volume(codec, nid, HDA_OUTPUT)) *mix_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); if (!*mute_val && nid_has_mute(codec, nid, HDA_OUTPUT)) *mute_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); return *mix_val || *mute_val; } /* create input playback/capture controls for the given pin */ static int new_analog_input(struct hda_codec *codec, int input_idx, hda_nid_t pin, const char *ctlname, int ctlidx, Loading @@ -2823,12 +2852,11 @@ static int new_analog_input(struct hda_codec *codec, int input_idx, { struct hda_gen_spec *spec = codec->spec; struct nid_path *path; unsigned int val; unsigned int mix_val, mute_val; int err, idx; if (!nid_has_volume(codec, mix_nid, HDA_INPUT) && !nid_has_mute(codec, mix_nid, HDA_INPUT)) return 0; /* no need for analog loopback */ if (!look_for_mix_leaf_ctls(codec, mix_nid, pin, &mix_val, &mute_val)) return 0; path = snd_hda_add_new_path(codec, pin, mix_nid, 0); if (!path) Loading @@ -2837,20 +2865,18 @@ static int new_analog_input(struct hda_codec *codec, int input_idx, spec->loopback_paths[input_idx] = snd_hda_get_path_idx(codec, path); idx = path->idx[path->depth - 1]; if (nid_has_volume(codec, mix_nid, HDA_INPUT)) { val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT); err = __add_pb_vol_ctrl(spec, HDA_CTL_WIDGET_VOL, ctlname, ctlidx, val); if (mix_val) { err = __add_pb_vol_ctrl(spec, HDA_CTL_WIDGET_VOL, ctlname, ctlidx, mix_val); if (err < 0) return err; path->ctls[NID_PATH_VOL_CTL] = val; path->ctls[NID_PATH_VOL_CTL] = mix_val; } if (nid_has_mute(codec, mix_nid, HDA_INPUT)) { val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT); err = __add_pb_sw_ctrl(spec, HDA_CTL_WIDGET_MUTE, ctlname, ctlidx, val); if (mute_val) { err = __add_pb_sw_ctrl(spec, HDA_CTL_WIDGET_MUTE, ctlname, ctlidx, mute_val); if (err < 0) return err; path->ctls[NID_PATH_MUTE_CTL] = val; path->ctls[NID_PATH_MUTE_CTL] = mute_val; } path->active = true; Loading Loading @@ -4384,6 +4410,17 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec, if (err < 0) return err; /* create "Headphone Mic Jack Mode" if no input selection is * available (or user specifies add_jack_modes hint) */ if (spec->hp_mic_pin && (spec->auto_mic || spec->input_mux.num_items == 1 || spec->add_jack_modes)) { err = create_hp_mic_jack_mode(codec, spec->hp_mic_pin); if (err < 0) return err; } if (spec->add_jack_modes) { if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { err = create_out_jack_modes(codec, cfg->line_outs, Loading
sound/pci/hda/patch_conexant.c +23 −0 Original line number Diff line number Diff line Loading @@ -3244,9 +3244,29 @@ enum { #if IS_ENABLED(CONFIG_THINKPAD_ACPI) #include <linux/thinkpad_acpi.h> #include <acpi/acpi.h> static int (*led_set_func)(int, bool); static acpi_status acpi_check_cb(acpi_handle handle, u32 lvl, void *context, void **rv) { bool *found = context; *found = true; return AE_OK; } static bool is_thinkpad(struct hda_codec *codec) { bool found = false; if (codec->subsystem_id >> 16 != 0x17aa) return false; if (ACPI_SUCCESS(acpi_get_devices("LEN0068", acpi_check_cb, &found, NULL)) && found) return true; found = false; return ACPI_SUCCESS(acpi_get_devices("IBM0068", acpi_check_cb, &found, NULL)) && found; } static void update_tpacpi_mute_led(void *private_data, int enabled) { struct hda_codec *codec = private_data; Loading Loading @@ -3279,6 +3299,8 @@ static void cxt_fixup_thinkpad_acpi(struct hda_codec *codec, bool removefunc = false; if (action == HDA_FIXUP_ACT_PROBE) { if (!is_thinkpad(codec)) return; if (!led_set_func) led_set_func = symbol_request(tpacpi_led_set); if (!led_set_func) { Loading Loading @@ -3494,6 +3516,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC), SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", CXT_FIXUP_THINKPAD_ACPI), SND_PCI_QUIRK(0x1c06, 0x2011, "Lemote A1004", CXT_PINCFG_LEMOTE_A1004), SND_PCI_QUIRK(0x1c06, 0x2012, "Lemote A1205", CXT_PINCFG_LEMOTE_A1205), {} Loading
sound/pci/hda/patch_realtek.c +9 −2 Original line number Diff line number Diff line Loading @@ -3798,6 +3798,7 @@ enum { ALC271_FIXUP_HP_GATE_MIC_JACK, ALC269_FIXUP_ACER_AC700, ALC269_FIXUP_LIMIT_INT_MIC_BOOST, ALC269VB_FIXUP_ASUS_ZENBOOK, ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED, ALC269VB_FIXUP_ORDISSIMO_EVE2, ALC283_FIXUP_CHROME_BOOK, Loading Loading @@ -4075,6 +4076,12 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC269_FIXUP_THINKPAD_ACPI, }, [ALC269VB_FIXUP_ASUS_ZENBOOK] = { .type = HDA_FIXUP_FUNC, .v.func = alc269_fixup_limit_int_mic_boost, .chained = true, .chain_id = ALC269VB_FIXUP_DMIC, }, [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = { .type = HDA_FIXUP_FUNC, .v.func = alc269_fixup_limit_int_mic_boost, Loading Loading @@ -4189,8 +4196,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC), SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_DMIC), SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK), SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), Loading
sound/usb/endpoint.c +15 −1 Original line number Diff line number Diff line Loading @@ -636,8 +636,22 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep, if (usb_pipein(ep->pipe) || snd_usb_endpoint_implicit_feedback_sink(ep)) { urb_packs = packs_per_ms; /* * Wireless devices can poll at a max rate of once per 4ms. * For dataintervals less than 5, increase the packet count to * allow the host controller to use bursting to fill in the * gaps. */ if (snd_usb_get_speed(ep->chip->dev) == USB_SPEED_WIRELESS) { int interval = ep->datainterval; while (interval < 5) { urb_packs <<= 1; ++interval; } } /* make capture URBs <= 1 ms and smaller than a period */ urb_packs = min(max_packs_per_urb, packs_per_ms); urb_packs = min(max_packs_per_urb, urb_packs); while (urb_packs > 1 && urb_packs * maxsize >= period_bytes) urb_packs >>= 1; ep->nurbs = MAX_URBS; Loading