sound fixes for 5.7-rc2
One significant regression fix is for HD-audio buffer preallocation. In 5.6 it was set to non-prompt for x86 and forced to 0, but this turned out to be problematic for some applications, hence it gets reverted. Distros would need to restore CONFIG_SND_HDA_PREALLOC_SIZE value to the earlier values they've used in the past. Other than that, we've received quite a few small fixes for HD-audio and USB-audio. Most of them are for dealing with the broken TRX40 mobos and the runtime PM without HD-audio codecs. -----BEGIN PGP SIGNATURE----- iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAl6ZgMEOHHRpd2FpQHN1 c2UuZGUACgkQLtJE4w1nLE9xIg//W0CkSxsl3yp71o+8Gv+xEWSuOGZ6Gbu5q82e PXDODxiAUTvzaueQm+ufofQRYxepZfilLweyxyETT2beQeC20Ty+p+S4bEw1uA4Q NiCkGjJZ6EGxVIb3F1S6n2BMrRckRBFD2xoz6NTd9S/iwAv9dBkUFUit9WywjgOF XLj0UiTfydgJJ8JIeql6S0glu7Hr+itMcvb3zhIKhvSv0gjR2EFxM6vvl7X9sn8l b/RYwJmR0ixKSXSTYWOAyJxLETEwRDOVbkyxOMFwU7y/JaE3j6D8xEd7vnT96AmJ 7k9upgh5nRWMGEjIa4lp3ob7HhuMF9q99b2yUG6NsDvP3SffusM8MoDWJ04ULMle V2sJQQeMk20SuKlNBQfkui9lTbTG1iLRfIjPmJPUHrQNmo4v2P74iQy/7WuJwunK U1j0A6VJDkQmRp5WNk9tbkwcGLD7x0ZMfnA/fmulT50iU98Qc1ONfbmxDnOMekOC 5AckG3upHS6dlQS61LIK9QENkc1GGQRk7b2eKd7wihYLaQEcvq+6z9ywZiSelhSA 2hc3dAX7RaGR+f2VdWni6uuE+j/XhFblKHWkLlfvY9ESBJgX5s7qys7ogO8+mOfc 8fGyrYFz/bc3Z8ZHqkOPxhfaIHJYyPNR0AXTLCW5di/OZRXBjW6N7rhCHOM7K2YH uulsJDM= =2Ir9 -----END PGP SIGNATURE----- Merge tag 'sound-5.7-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound fixes from Takashi Iwai: "One significant regression fix is for HD-audio buffer preallocation. In 5.6 it was set to non-prompt for x86 and forced to 0, but this turned out to be problematic for some applications, hence it gets reverted. Distros would need to restore CONFIG_SND_HDA_PREALLOC_SIZE value to the earlier values they've used in the past. Other than that, we've received quite a few small fixes for HD-audio and USB-audio. Most of them are for dealing with the broken TRX40 mobos and the runtime PM without HD-audio codecs" * tag 'sound-5.7-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: hda: call runtime_allow() for all hda controllers ALSA: hda: Allow setting preallocation again for x86 ALSA: hda: Explicitly permit using autosuspend if runtime PM is supported ALSA: hda: Skip controller resume if not needed ALSA: hda: Keep the controller initialization even if no codecs found ALSA: hda: Release resources at error in delayed probe ALSA: hda: Honor PM disablement in PM freeze and thaw_noirq ops ALSA: hda: Don't release card at firmware loading error ALSA: usb-audio: Check mapping at creating connector controls, too ALSA: usb-audio: Don't create jack controls for PCM terminals ALSA: usb-audio: Don't override ignore_ctl_error value from the map ALSA: usb-audio: Filter error from connector kctl ops, too ALSA: hda/realtek - Enable the headset mic on Asus FX505DT ALSA: ctxfi: Remove unnecessary cast in kfree
This commit is contained in:
Коммит
c8a6552ff1
|
@ -494,6 +494,11 @@ void snd_hda_update_power_acct(struct hda_codec *codec);
|
|||
static inline void snd_hda_set_power_save(struct hda_bus *bus, int delay) {}
|
||||
#endif
|
||||
|
||||
static inline bool hda_codec_need_resume(struct hda_codec *codec)
|
||||
{
|
||||
return !codec->relaxed_resume && codec->jacktbl.used;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_HDA_PATCH_LOADER
|
||||
/*
|
||||
* patch firmware
|
||||
|
|
|
@ -21,16 +21,17 @@ config SND_HDA_EXT_CORE
|
|||
select SND_HDA_CORE
|
||||
|
||||
config SND_HDA_PREALLOC_SIZE
|
||||
int "Pre-allocated buffer size for HD-audio driver" if !SND_DMA_SGBUF
|
||||
int "Pre-allocated buffer size for HD-audio driver"
|
||||
range 0 32768
|
||||
default 0 if SND_DMA_SGBUF
|
||||
default 2048 if SND_DMA_SGBUF
|
||||
default 64 if !SND_DMA_SGBUF
|
||||
help
|
||||
Specifies the default pre-allocated buffer-size in kB for the
|
||||
HD-audio driver. A larger buffer (e.g. 2048) is preferred
|
||||
for systems using PulseAudio. The default 64 is chosen just
|
||||
for compatibility reasons.
|
||||
On x86 systems, the default is zero as we need no preallocation.
|
||||
On x86 systems, the default is 2048 as a reasonable value for
|
||||
most of modern systems.
|
||||
|
||||
Note that the pre-allocation size can be changed dynamically
|
||||
via a proc file (/proc/asound/card*/pcm*/sub*/prealloc), too.
|
||||
|
|
|
@ -168,7 +168,7 @@ static int src_get_rsc_ctrl_blk(void **rblk)
|
|||
|
||||
static int src_put_rsc_ctrl_blk(void *blk)
|
||||
{
|
||||
kfree((struct src_rsc_ctrl_blk *)blk);
|
||||
kfree(blk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -494,7 +494,7 @@ static int src_mgr_get_ctrl_blk(void **rblk)
|
|||
|
||||
static int src_mgr_put_ctrl_blk(void *blk)
|
||||
{
|
||||
kfree((struct src_mgr_ctrl_blk *)blk);
|
||||
kfree(blk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -515,7 +515,7 @@ static int srcimp_mgr_get_ctrl_blk(void **rblk)
|
|||
|
||||
static int srcimp_mgr_put_ctrl_blk(void *blk)
|
||||
{
|
||||
kfree((struct srcimp_mgr_ctrl_blk *)blk);
|
||||
kfree(blk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -702,7 +702,7 @@ static int amixer_rsc_get_ctrl_blk(void **rblk)
|
|||
|
||||
static int amixer_rsc_put_ctrl_blk(void *blk)
|
||||
{
|
||||
kfree((struct amixer_rsc_ctrl_blk *)blk);
|
||||
kfree(blk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -909,7 +909,7 @@ static int dai_get_ctrl_blk(void **rblk)
|
|||
|
||||
static int dai_put_ctrl_blk(void *blk)
|
||||
{
|
||||
kfree((struct dai_ctrl_blk *)blk);
|
||||
kfree(blk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -958,7 +958,7 @@ static int dao_get_ctrl_blk(void **rblk)
|
|||
|
||||
static int dao_put_ctrl_blk(void *blk)
|
||||
{
|
||||
kfree((struct dao_ctrl_blk *)blk);
|
||||
kfree(blk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1156,7 +1156,7 @@ static int daio_mgr_get_ctrl_blk(struct hw *hw, void **rblk)
|
|||
|
||||
static int daio_mgr_put_ctrl_blk(void *blk)
|
||||
{
|
||||
kfree((struct daio_mgr_ctrl_blk *)blk);
|
||||
kfree(blk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -2951,7 +2951,7 @@ static int hda_codec_runtime_resume(struct device *dev)
|
|||
static int hda_codec_force_resume(struct device *dev)
|
||||
{
|
||||
struct hda_codec *codec = dev_to_hda_codec(dev);
|
||||
bool forced_resume = !codec->relaxed_resume && codec->jacktbl.used;
|
||||
bool forced_resume = hda_codec_need_resume(codec);
|
||||
int ret;
|
||||
|
||||
/* The get/put pair below enforces the runtime resume even if the
|
||||
|
|
|
@ -1027,7 +1027,7 @@ static int azx_suspend(struct device *dev)
|
|||
chip = card->private_data;
|
||||
bus = azx_bus(chip);
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
|
||||
__azx_runtime_suspend(chip);
|
||||
pm_runtime_force_suspend(dev);
|
||||
if (bus->irq >= 0) {
|
||||
free_irq(bus->irq, chip);
|
||||
bus->irq = -1;
|
||||
|
@ -1044,7 +1044,9 @@ static int azx_suspend(struct device *dev)
|
|||
static int azx_resume(struct device *dev)
|
||||
{
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct hda_codec *codec;
|
||||
struct azx *chip;
|
||||
bool forced_resume = false;
|
||||
|
||||
if (!azx_is_pm_ready(card))
|
||||
return 0;
|
||||
|
@ -1055,7 +1057,20 @@ static int azx_resume(struct device *dev)
|
|||
chip->msi = 0;
|
||||
if (azx_acquire_irq(chip, 1) < 0)
|
||||
return -EIO;
|
||||
__azx_runtime_resume(chip, false);
|
||||
|
||||
/* check for the forced resume */
|
||||
list_for_each_codec(codec, &chip->bus) {
|
||||
if (hda_codec_need_resume(codec)) {
|
||||
forced_resume = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (forced_resume)
|
||||
pm_runtime_get_noresume(dev);
|
||||
pm_runtime_force_resume(dev);
|
||||
if (forced_resume)
|
||||
pm_runtime_put(dev);
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
|
||||
|
||||
trace_azx_resume(chip);
|
||||
|
@ -1071,6 +1086,8 @@ static int azx_freeze_noirq(struct device *dev)
|
|||
struct azx *chip = card->private_data;
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
|
||||
if (!azx_is_pm_ready(card))
|
||||
return 0;
|
||||
if (chip->driver_type == AZX_DRIVER_SKL)
|
||||
pci_set_power_state(pci, PCI_D3hot);
|
||||
|
||||
|
@ -1083,6 +1100,8 @@ static int azx_thaw_noirq(struct device *dev)
|
|||
struct azx *chip = card->private_data;
|
||||
struct pci_dev *pci = to_pci_dev(dev);
|
||||
|
||||
if (!azx_is_pm_ready(card))
|
||||
return 0;
|
||||
if (chip->driver_type == AZX_DRIVER_SKL)
|
||||
pci_set_power_state(pci, PCI_D0);
|
||||
|
||||
|
@ -1098,12 +1117,12 @@ static int azx_runtime_suspend(struct device *dev)
|
|||
if (!azx_is_pm_ready(card))
|
||||
return 0;
|
||||
chip = card->private_data;
|
||||
if (!azx_has_pm_runtime(chip))
|
||||
return 0;
|
||||
|
||||
/* enable controller wake up event */
|
||||
azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) |
|
||||
STATESTS_INT_MASK);
|
||||
if (snd_power_get_state(card) == SNDRV_CTL_POWER_D0) {
|
||||
azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) |
|
||||
STATESTS_INT_MASK);
|
||||
}
|
||||
|
||||
__azx_runtime_suspend(chip);
|
||||
trace_azx_runtime_suspend(chip);
|
||||
|
@ -1114,17 +1133,18 @@ static int azx_runtime_resume(struct device *dev)
|
|||
{
|
||||
struct snd_card *card = dev_get_drvdata(dev);
|
||||
struct azx *chip;
|
||||
bool from_rt = snd_power_get_state(card) == SNDRV_CTL_POWER_D0;
|
||||
|
||||
if (!azx_is_pm_ready(card))
|
||||
return 0;
|
||||
chip = card->private_data;
|
||||
if (!azx_has_pm_runtime(chip))
|
||||
return 0;
|
||||
__azx_runtime_resume(chip, true);
|
||||
__azx_runtime_resume(chip, from_rt);
|
||||
|
||||
/* disable controller Wake Up event*/
|
||||
azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) &
|
||||
~STATESTS_INT_MASK);
|
||||
if (from_rt) {
|
||||
azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) &
|
||||
~STATESTS_INT_MASK);
|
||||
}
|
||||
|
||||
trace_azx_runtime_resume(chip);
|
||||
return 0;
|
||||
|
@ -1199,10 +1219,8 @@ static void azx_vs_set_state(struct pci_dev *pci,
|
|||
if (!disabled) {
|
||||
dev_info(chip->card->dev,
|
||||
"Start delayed initialization\n");
|
||||
if (azx_probe_continue(chip) < 0) {
|
||||
if (azx_probe_continue(chip) < 0)
|
||||
dev_err(chip->card->dev, "initialization error\n");
|
||||
hda->init_failed = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dev_info(chip->card->dev, "%s via vga_switcheroo\n",
|
||||
|
@ -1335,12 +1353,15 @@ static int register_vga_switcheroo(struct azx *chip)
|
|||
/*
|
||||
* destructor
|
||||
*/
|
||||
static int azx_free(struct azx *chip)
|
||||
static void azx_free(struct azx *chip)
|
||||
{
|
||||
struct pci_dev *pci = chip->pci;
|
||||
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
|
||||
struct hdac_bus *bus = azx_bus(chip);
|
||||
|
||||
if (hda->freed)
|
||||
return;
|
||||
|
||||
if (azx_has_pm_runtime(chip) && chip->running)
|
||||
pm_runtime_get_noresume(&pci->dev);
|
||||
chip->running = 0;
|
||||
|
@ -1384,9 +1405,8 @@ static int azx_free(struct azx *chip)
|
|||
|
||||
if (chip->driver_caps & AZX_DCAPS_I915_COMPONENT)
|
||||
snd_hdac_i915_exit(bus);
|
||||
kfree(hda);
|
||||
|
||||
return 0;
|
||||
hda->freed = 1;
|
||||
}
|
||||
|
||||
static int azx_dev_disconnect(struct snd_device *device)
|
||||
|
@ -1402,7 +1422,8 @@ static int azx_dev_disconnect(struct snd_device *device)
|
|||
|
||||
static int azx_dev_free(struct snd_device *device)
|
||||
{
|
||||
return azx_free(device->device_data);
|
||||
azx_free(device->device_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_VGA_SWITCHEROO
|
||||
|
@ -1769,7 +1790,7 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
|
|||
if (err < 0)
|
||||
return err;
|
||||
|
||||
hda = kzalloc(sizeof(*hda), GFP_KERNEL);
|
||||
hda = devm_kzalloc(&pci->dev, sizeof(*hda), GFP_KERNEL);
|
||||
if (!hda) {
|
||||
pci_disable_device(pci);
|
||||
return -ENOMEM;
|
||||
|
@ -1810,7 +1831,6 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
|
|||
|
||||
err = azx_bus_init(chip, model[dev]);
|
||||
if (err < 0) {
|
||||
kfree(hda);
|
||||
pci_disable_device(pci);
|
||||
return err;
|
||||
}
|
||||
|
@ -2005,7 +2025,7 @@ static int azx_first_init(struct azx *chip)
|
|||
/* codec detection */
|
||||
if (!azx_bus(chip)->codec_mask) {
|
||||
dev_err(card->dev, "no codecs found!\n");
|
||||
return -ENODEV;
|
||||
/* keep running the rest for the runtime PM */
|
||||
}
|
||||
|
||||
if (azx_acquire_irq(chip, 0) < 0)
|
||||
|
@ -2027,24 +2047,15 @@ static void azx_firmware_cb(const struct firmware *fw, void *context)
|
|||
{
|
||||
struct snd_card *card = context;
|
||||
struct azx *chip = card->private_data;
|
||||
struct pci_dev *pci = chip->pci;
|
||||
|
||||
if (!fw) {
|
||||
dev_err(card->dev, "Cannot load firmware, aborting\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
chip->fw = fw;
|
||||
if (fw)
|
||||
chip->fw = fw;
|
||||
else
|
||||
dev_err(card->dev, "Cannot load firmware, continue without patching\n");
|
||||
if (!chip->disabled) {
|
||||
/* continue probing */
|
||||
if (azx_probe_continue(chip))
|
||||
goto error;
|
||||
azx_probe_continue(chip);
|
||||
}
|
||||
return; /* OK */
|
||||
|
||||
error:
|
||||
snd_card_free(card);
|
||||
pci_set_drvdata(pci, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2308,9 +2319,11 @@ static int azx_probe_continue(struct azx *chip)
|
|||
#endif
|
||||
|
||||
/* create codec instances */
|
||||
err = azx_probe_codecs(chip, azx_max_codecs[chip->driver_type]);
|
||||
if (err < 0)
|
||||
goto out_free;
|
||||
if (bus->codec_mask) {
|
||||
err = azx_probe_codecs(chip, azx_max_codecs[chip->driver_type]);
|
||||
if (err < 0)
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_HDA_PATCH_LOADER
|
||||
if (chip->fw) {
|
||||
|
@ -2324,7 +2337,7 @@ static int azx_probe_continue(struct azx *chip)
|
|||
#endif
|
||||
}
|
||||
#endif
|
||||
if ((probe_only[dev] & 1) == 0) {
|
||||
if (bus->codec_mask && !(probe_only[dev] & 1)) {
|
||||
err = azx_codec_configure(chip);
|
||||
if (err < 0)
|
||||
goto out_free;
|
||||
|
@ -2341,17 +2354,23 @@ static int azx_probe_continue(struct azx *chip)
|
|||
|
||||
set_default_power_save(chip);
|
||||
|
||||
if (azx_has_pm_runtime(chip))
|
||||
if (azx_has_pm_runtime(chip)) {
|
||||
pm_runtime_use_autosuspend(&pci->dev);
|
||||
pm_runtime_allow(&pci->dev);
|
||||
pm_runtime_put_autosuspend(&pci->dev);
|
||||
}
|
||||
|
||||
out_free:
|
||||
if (err < 0 || !hda->need_i915_power)
|
||||
if (err < 0) {
|
||||
azx_free(chip);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!hda->need_i915_power)
|
||||
display_power(chip, false);
|
||||
if (err < 0)
|
||||
hda->init_failed = 1;
|
||||
complete_all(&hda->probe_wait);
|
||||
to_hda_bus(bus)->bus_probing = 0;
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void azx_remove(struct pci_dev *pci)
|
||||
|
|
|
@ -27,6 +27,7 @@ struct hda_intel {
|
|||
unsigned int use_vga_switcheroo:1;
|
||||
unsigned int vga_switcheroo_registered:1;
|
||||
unsigned int init_failed:1; /* delayed init failed */
|
||||
unsigned int freed:1; /* resources already released */
|
||||
|
||||
bool need_i915_power:1; /* the hda controller needs i915 power */
|
||||
};
|
||||
|
|
|
@ -7378,6 +7378,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK),
|
||||
SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x18f1, "Asus FX505DT", ALC256_FIXUP_ASUS_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x19ce, "ASUS B9450FA", ALC294_FIXUP_ASUS_HPE),
|
||||
SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
|
||||
SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC),
|
||||
|
|
|
@ -1457,7 +1457,7 @@ error:
|
|||
usb_audio_err(chip,
|
||||
"cannot get connectors status: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
|
||||
UAC_GET_CUR, validx, idx, cval->val_type);
|
||||
return ret;
|
||||
return filter_error(cval, ret);
|
||||
}
|
||||
|
||||
ucontrol->value.integer.value[0] = val;
|
||||
|
@ -1771,11 +1771,15 @@ static void get_connector_control_name(struct usb_mixer_interface *mixer,
|
|||
|
||||
/* Build a mixer control for a UAC connector control (jack-detect) */
|
||||
static void build_connector_control(struct usb_mixer_interface *mixer,
|
||||
const struct usbmix_name_map *imap,
|
||||
struct usb_audio_term *term, bool is_input)
|
||||
{
|
||||
struct snd_kcontrol *kctl;
|
||||
struct usb_mixer_elem_info *cval;
|
||||
|
||||
if (check_ignored_ctl(find_map(imap, term->id, 0)))
|
||||
return;
|
||||
|
||||
cval = kzalloc(sizeof(*cval), GFP_KERNEL);
|
||||
if (!cval)
|
||||
return;
|
||||
|
@ -2109,8 +2113,9 @@ static int parse_audio_input_terminal(struct mixer_build *state, int unitid,
|
|||
check_input_term(state, term_id, &iterm);
|
||||
|
||||
/* Check for jack detection. */
|
||||
if (uac_v2v3_control_is_readable(bmctls, control))
|
||||
build_connector_control(state->mixer, &iterm, true);
|
||||
if ((iterm.type & 0xff00) != 0x0100 &&
|
||||
uac_v2v3_control_is_readable(bmctls, control))
|
||||
build_connector_control(state->mixer, state->map, &iterm, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3071,13 +3076,13 @@ static int snd_usb_mixer_controls_badd(struct usb_mixer_interface *mixer,
|
|||
memset(&iterm, 0, sizeof(iterm));
|
||||
iterm.id = UAC3_BADD_IT_ID4;
|
||||
iterm.type = UAC_BIDIR_TERMINAL_HEADSET;
|
||||
build_connector_control(mixer, &iterm, true);
|
||||
build_connector_control(mixer, map->map, &iterm, true);
|
||||
|
||||
/* Output Term - Insertion control */
|
||||
memset(&oterm, 0, sizeof(oterm));
|
||||
oterm.id = UAC3_BADD_OT_ID3;
|
||||
oterm.type = UAC_BIDIR_TERMINAL_HEADSET;
|
||||
build_connector_control(mixer, &oterm, false);
|
||||
build_connector_control(mixer, map->map, &oterm, false);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -3106,7 +3111,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
|
|||
if (map->id == state.chip->usb_id) {
|
||||
state.map = map->map;
|
||||
state.selector_map = map->selector_map;
|
||||
mixer->ignore_ctl_error = map->ignore_ctl_error;
|
||||
mixer->ignore_ctl_error |= map->ignore_ctl_error;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -3149,10 +3154,11 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
|
|||
if (err < 0 && err != -EINVAL)
|
||||
return err;
|
||||
|
||||
if (uac_v2v3_control_is_readable(le16_to_cpu(desc->bmControls),
|
||||
if ((state.oterm.type & 0xff00) != 0x0100 &&
|
||||
uac_v2v3_control_is_readable(le16_to_cpu(desc->bmControls),
|
||||
UAC2_TE_CONNECTOR)) {
|
||||
build_connector_control(state.mixer, &state.oterm,
|
||||
false);
|
||||
build_connector_control(state.mixer, state.map,
|
||||
&state.oterm, false);
|
||||
}
|
||||
} else { /* UAC_VERSION_3 */
|
||||
struct uac3_output_terminal_descriptor *desc = p;
|
||||
|
@ -3174,10 +3180,11 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
|
|||
if (err < 0 && err != -EINVAL)
|
||||
return err;
|
||||
|
||||
if (uac_v2v3_control_is_readable(le32_to_cpu(desc->bmControls),
|
||||
if ((state.oterm.type & 0xff00) != 0x0100 &&
|
||||
uac_v2v3_control_is_readable(le32_to_cpu(desc->bmControls),
|
||||
UAC3_TE_INSERTION)) {
|
||||
build_connector_control(state.mixer, &state.oterm,
|
||||
false);
|
||||
build_connector_control(state.mixer, state.map,
|
||||
&state.oterm, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -360,9 +360,11 @@ static const struct usbmix_name_map corsair_virtuoso_map[] = {
|
|||
};
|
||||
|
||||
/* Some mobos shipped with a dummy HD-audio show the invalid GET_MIN/GET_MAX
|
||||
* response for Input Gain Pad (id=19, control=12). Skip it.
|
||||
* response for Input Gain Pad (id=19, control=12) and the connector status
|
||||
* for SPDIF terminal (id=18). Skip them.
|
||||
*/
|
||||
static const struct usbmix_name_map asus_rog_map[] = {
|
||||
{ 18, NULL }, /* OT, connector control */
|
||||
{ 19, NULL, 12 }, /* FU, Input Gain Pad */
|
||||
{}
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче