Commit c8a6552f authored by Linus Torvalds's avatar Linus Torvalds

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
parents 7a56db02 9a641848
...@@ -494,6 +494,11 @@ void snd_hda_update_power_acct(struct hda_codec *codec); ...@@ -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) {} static inline void snd_hda_set_power_save(struct hda_bus *bus, int delay) {}
#endif #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 #ifdef CONFIG_SND_HDA_PATCH_LOADER
/* /*
* patch firmware * patch firmware
......
...@@ -21,16 +21,17 @@ config SND_HDA_EXT_CORE ...@@ -21,16 +21,17 @@ config SND_HDA_EXT_CORE
select SND_HDA_CORE select SND_HDA_CORE
config SND_HDA_PREALLOC_SIZE 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 range 0 32768
default 0 if SND_DMA_SGBUF default 2048 if SND_DMA_SGBUF
default 64 if !SND_DMA_SGBUF default 64 if !SND_DMA_SGBUF
help help
Specifies the default pre-allocated buffer-size in kB for the Specifies the default pre-allocated buffer-size in kB for the
HD-audio driver. A larger buffer (e.g. 2048) is preferred HD-audio driver. A larger buffer (e.g. 2048) is preferred
for systems using PulseAudio. The default 64 is chosen just for systems using PulseAudio. The default 64 is chosen just
for compatibility reasons. 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 Note that the pre-allocation size can be changed dynamically
via a proc file (/proc/asound/card*/pcm*/sub*/prealloc), too. via a proc file (/proc/asound/card*/pcm*/sub*/prealloc), too.
......
...@@ -168,7 +168,7 @@ static int src_get_rsc_ctrl_blk(void **rblk) ...@@ -168,7 +168,7 @@ static int src_get_rsc_ctrl_blk(void **rblk)
static int src_put_rsc_ctrl_blk(void *blk) static int src_put_rsc_ctrl_blk(void *blk)
{ {
kfree((struct src_rsc_ctrl_blk *)blk); kfree(blk);
return 0; return 0;
} }
...@@ -494,7 +494,7 @@ static int src_mgr_get_ctrl_blk(void **rblk) ...@@ -494,7 +494,7 @@ static int src_mgr_get_ctrl_blk(void **rblk)
static int src_mgr_put_ctrl_blk(void *blk) static int src_mgr_put_ctrl_blk(void *blk)
{ {
kfree((struct src_mgr_ctrl_blk *)blk); kfree(blk);
return 0; return 0;
} }
...@@ -515,7 +515,7 @@ static int srcimp_mgr_get_ctrl_blk(void **rblk) ...@@ -515,7 +515,7 @@ static int srcimp_mgr_get_ctrl_blk(void **rblk)
static int srcimp_mgr_put_ctrl_blk(void *blk) static int srcimp_mgr_put_ctrl_blk(void *blk)
{ {
kfree((struct srcimp_mgr_ctrl_blk *)blk); kfree(blk);
return 0; return 0;
} }
...@@ -702,7 +702,7 @@ static int amixer_rsc_get_ctrl_blk(void **rblk) ...@@ -702,7 +702,7 @@ static int amixer_rsc_get_ctrl_blk(void **rblk)
static int amixer_rsc_put_ctrl_blk(void *blk) static int amixer_rsc_put_ctrl_blk(void *blk)
{ {
kfree((struct amixer_rsc_ctrl_blk *)blk); kfree(blk);
return 0; return 0;
} }
...@@ -909,7 +909,7 @@ static int dai_get_ctrl_blk(void **rblk) ...@@ -909,7 +909,7 @@ static int dai_get_ctrl_blk(void **rblk)
static int dai_put_ctrl_blk(void *blk) static int dai_put_ctrl_blk(void *blk)
{ {
kfree((struct dai_ctrl_blk *)blk); kfree(blk);
return 0; return 0;
} }
...@@ -958,7 +958,7 @@ static int dao_get_ctrl_blk(void **rblk) ...@@ -958,7 +958,7 @@ static int dao_get_ctrl_blk(void **rblk)
static int dao_put_ctrl_blk(void *blk) static int dao_put_ctrl_blk(void *blk)
{ {
kfree((struct dao_ctrl_blk *)blk); kfree(blk);
return 0; return 0;
} }
...@@ -1156,7 +1156,7 @@ static int daio_mgr_get_ctrl_blk(struct hw *hw, void **rblk) ...@@ -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) static int daio_mgr_put_ctrl_blk(void *blk)
{ {
kfree((struct daio_mgr_ctrl_blk *)blk); kfree(blk);
return 0; return 0;
} }
......
...@@ -2951,7 +2951,7 @@ static int hda_codec_runtime_resume(struct device *dev) ...@@ -2951,7 +2951,7 @@ static int hda_codec_runtime_resume(struct device *dev)
static int hda_codec_force_resume(struct device *dev) static int hda_codec_force_resume(struct device *dev)
{ {
struct hda_codec *codec = dev_to_hda_codec(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; int ret;
/* The get/put pair below enforces the runtime resume even if the /* The get/put pair below enforces the runtime resume even if the
......
...@@ -1027,7 +1027,7 @@ static int azx_suspend(struct device *dev) ...@@ -1027,7 +1027,7 @@ static int azx_suspend(struct device *dev)
chip = card->private_data; chip = card->private_data;
bus = azx_bus(chip); bus = azx_bus(chip);
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
__azx_runtime_suspend(chip); pm_runtime_force_suspend(dev);
if (bus->irq >= 0) { if (bus->irq >= 0) {
free_irq(bus->irq, chip); free_irq(bus->irq, chip);
bus->irq = -1; bus->irq = -1;
...@@ -1044,7 +1044,9 @@ static int azx_suspend(struct device *dev) ...@@ -1044,7 +1044,9 @@ static int azx_suspend(struct device *dev)
static int azx_resume(struct device *dev) static int azx_resume(struct device *dev)
{ {
struct snd_card *card = dev_get_drvdata(dev); struct snd_card *card = dev_get_drvdata(dev);
struct hda_codec *codec;
struct azx *chip; struct azx *chip;
bool forced_resume = false;
if (!azx_is_pm_ready(card)) if (!azx_is_pm_ready(card))
return 0; return 0;
...@@ -1055,7 +1057,20 @@ static int azx_resume(struct device *dev) ...@@ -1055,7 +1057,20 @@ static int azx_resume(struct device *dev)
chip->msi = 0; chip->msi = 0;
if (azx_acquire_irq(chip, 1) < 0) if (azx_acquire_irq(chip, 1) < 0)
return -EIO; 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); snd_power_change_state(card, SNDRV_CTL_POWER_D0);
trace_azx_resume(chip); trace_azx_resume(chip);
...@@ -1071,6 +1086,8 @@ static int azx_freeze_noirq(struct device *dev) ...@@ -1071,6 +1086,8 @@ static int azx_freeze_noirq(struct device *dev)
struct azx *chip = card->private_data; struct azx *chip = card->private_data;
struct pci_dev *pci = to_pci_dev(dev); struct pci_dev *pci = to_pci_dev(dev);
if (!azx_is_pm_ready(card))
return 0;
if (chip->driver_type == AZX_DRIVER_SKL) if (chip->driver_type == AZX_DRIVER_SKL)
pci_set_power_state(pci, PCI_D3hot); pci_set_power_state(pci, PCI_D3hot);
...@@ -1083,6 +1100,8 @@ static int azx_thaw_noirq(struct device *dev) ...@@ -1083,6 +1100,8 @@ static int azx_thaw_noirq(struct device *dev)
struct azx *chip = card->private_data; struct azx *chip = card->private_data;
struct pci_dev *pci = to_pci_dev(dev); struct pci_dev *pci = to_pci_dev(dev);
if (!azx_is_pm_ready(card))
return 0;
if (chip->driver_type == AZX_DRIVER_SKL) if (chip->driver_type == AZX_DRIVER_SKL)
pci_set_power_state(pci, PCI_D0); pci_set_power_state(pci, PCI_D0);
...@@ -1098,12 +1117,12 @@ static int azx_runtime_suspend(struct device *dev) ...@@ -1098,12 +1117,12 @@ static int azx_runtime_suspend(struct device *dev)
if (!azx_is_pm_ready(card)) if (!azx_is_pm_ready(card))
return 0; return 0;
chip = card->private_data; chip = card->private_data;
if (!azx_has_pm_runtime(chip))
return 0;
/* enable controller wake up event */ /* enable controller wake up event */
azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) | if (snd_power_get_state(card) == SNDRV_CTL_POWER_D0) {
STATESTS_INT_MASK); azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) |
STATESTS_INT_MASK);
}
__azx_runtime_suspend(chip); __azx_runtime_suspend(chip);
trace_azx_runtime_suspend(chip); trace_azx_runtime_suspend(chip);
...@@ -1114,17 +1133,18 @@ static int azx_runtime_resume(struct device *dev) ...@@ -1114,17 +1133,18 @@ static int azx_runtime_resume(struct device *dev)
{ {
struct snd_card *card = dev_get_drvdata(dev); struct snd_card *card = dev_get_drvdata(dev);
struct azx *chip; struct azx *chip;
bool from_rt = snd_power_get_state(card) == SNDRV_CTL_POWER_D0;
if (!azx_is_pm_ready(card)) if (!azx_is_pm_ready(card))
return 0; return 0;
chip = card->private_data; chip = card->private_data;
if (!azx_has_pm_runtime(chip)) __azx_runtime_resume(chip, from_rt);
return 0;
__azx_runtime_resume(chip, true);
/* disable controller Wake Up event*/ /* disable controller Wake Up event*/
azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) & if (from_rt) {
~STATESTS_INT_MASK); azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) &
~STATESTS_INT_MASK);
}
trace_azx_runtime_resume(chip); trace_azx_runtime_resume(chip);
return 0; return 0;
...@@ -1199,10 +1219,8 @@ static void azx_vs_set_state(struct pci_dev *pci, ...@@ -1199,10 +1219,8 @@ static void azx_vs_set_state(struct pci_dev *pci,
if (!disabled) { if (!disabled) {
dev_info(chip->card->dev, dev_info(chip->card->dev,
"Start delayed initialization\n"); "Start delayed initialization\n");
if (azx_probe_continue(chip) < 0) { if (azx_probe_continue(chip) < 0)
dev_err(chip->card->dev, "initialization error\n"); dev_err(chip->card->dev, "initialization error\n");
hda->init_failed = true;
}
} }
} else { } else {
dev_info(chip->card->dev, "%s via vga_switcheroo\n", dev_info(chip->card->dev, "%s via vga_switcheroo\n",
...@@ -1335,12 +1353,15 @@ static int register_vga_switcheroo(struct azx *chip) ...@@ -1335,12 +1353,15 @@ static int register_vga_switcheroo(struct azx *chip)
/* /*
* destructor * destructor
*/ */
static int azx_free(struct azx *chip) static void azx_free(struct azx *chip)
{ {
struct pci_dev *pci = chip->pci; struct pci_dev *pci = chip->pci;
struct hda_intel *hda = container_of(chip, struct hda_intel, chip); struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
struct hdac_bus *bus = azx_bus(chip); struct hdac_bus *bus = azx_bus(chip);
if (hda->freed)
return;
if (azx_has_pm_runtime(chip) && chip->running) if (azx_has_pm_runtime(chip) && chip->running)
pm_runtime_get_noresume(&pci->dev); pm_runtime_get_noresume(&pci->dev);
chip->running = 0; chip->running = 0;
...@@ -1384,9 +1405,8 @@ static int azx_free(struct azx *chip) ...@@ -1384,9 +1405,8 @@ static int azx_free(struct azx *chip)
if (chip->driver_caps & AZX_DCAPS_I915_COMPONENT) if (chip->driver_caps & AZX_DCAPS_I915_COMPONENT)
snd_hdac_i915_exit(bus); snd_hdac_i915_exit(bus);
kfree(hda);
return 0; hda->freed = 1;
} }
static int azx_dev_disconnect(struct snd_device *device) static int azx_dev_disconnect(struct snd_device *device)
...@@ -1402,7 +1422,8 @@ 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) 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 #ifdef SUPPORT_VGA_SWITCHEROO
...@@ -1769,7 +1790,7 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci, ...@@ -1769,7 +1790,7 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
if (err < 0) if (err < 0)
return err; return err;
hda = kzalloc(sizeof(*hda), GFP_KERNEL); hda = devm_kzalloc(&pci->dev, sizeof(*hda), GFP_KERNEL);
if (!hda) { if (!hda) {
pci_disable_device(pci); pci_disable_device(pci);
return -ENOMEM; return -ENOMEM;
...@@ -1810,7 +1831,6 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci, ...@@ -1810,7 +1831,6 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
err = azx_bus_init(chip, model[dev]); err = azx_bus_init(chip, model[dev]);
if (err < 0) { if (err < 0) {
kfree(hda);
pci_disable_device(pci); pci_disable_device(pci);
return err; return err;
} }
...@@ -2005,7 +2025,7 @@ static int azx_first_init(struct azx *chip) ...@@ -2005,7 +2025,7 @@ static int azx_first_init(struct azx *chip)
/* codec detection */ /* codec detection */
if (!azx_bus(chip)->codec_mask) { if (!azx_bus(chip)->codec_mask) {
dev_err(card->dev, "no codecs found!\n"); 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) if (azx_acquire_irq(chip, 0) < 0)
...@@ -2027,24 +2047,15 @@ static void azx_firmware_cb(const struct firmware *fw, void *context) ...@@ -2027,24 +2047,15 @@ static void azx_firmware_cb(const struct firmware *fw, void *context)
{ {
struct snd_card *card = context; struct snd_card *card = context;
struct azx *chip = card->private_data; 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) { if (!chip->disabled) {
/* continue probing */ /* continue probing */
if (azx_probe_continue(chip)) azx_probe_continue(chip);
goto error;
} }
return; /* OK */
error:
snd_card_free(card);
pci_set_drvdata(pci, NULL);
} }
#endif #endif
...@@ -2308,9 +2319,11 @@ static int azx_probe_continue(struct azx *chip) ...@@ -2308,9 +2319,11 @@ static int azx_probe_continue(struct azx *chip)
#endif #endif
/* create codec instances */ /* create codec instances */
err = azx_probe_codecs(chip, azx_max_codecs[chip->driver_type]); if (bus->codec_mask) {
if (err < 0) err = azx_probe_codecs(chip, azx_max_codecs[chip->driver_type]);
goto out_free; if (err < 0)
goto out_free;
}
#ifdef CONFIG_SND_HDA_PATCH_LOADER #ifdef CONFIG_SND_HDA_PATCH_LOADER
if (chip->fw) { if (chip->fw) {
...@@ -2324,7 +2337,7 @@ static int azx_probe_continue(struct azx *chip) ...@@ -2324,7 +2337,7 @@ static int azx_probe_continue(struct azx *chip)
#endif #endif
} }
#endif #endif
if ((probe_only[dev] & 1) == 0) { if (bus->codec_mask && !(probe_only[dev] & 1)) {
err = azx_codec_configure(chip); err = azx_codec_configure(chip);
if (err < 0) if (err < 0)
goto out_free; goto out_free;
...@@ -2341,17 +2354,23 @@ static int azx_probe_continue(struct azx *chip) ...@@ -2341,17 +2354,23 @@ static int azx_probe_continue(struct azx *chip)
set_default_power_save(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); pm_runtime_put_autosuspend(&pci->dev);
}
out_free: 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); display_power(chip, false);
if (err < 0)
hda->init_failed = 1;
complete_all(&hda->probe_wait); complete_all(&hda->probe_wait);
to_hda_bus(bus)->bus_probing = 0; to_hda_bus(bus)->bus_probing = 0;
return err; return 0;
} }
static void azx_remove(struct pci_dev *pci) static void azx_remove(struct pci_dev *pci)
......
...@@ -27,6 +27,7 @@ struct hda_intel { ...@@ -27,6 +27,7 @@ struct hda_intel {
unsigned int use_vga_switcheroo:1; unsigned int use_vga_switcheroo:1;
unsigned int vga_switcheroo_registered:1; unsigned int vga_switcheroo_registered:1;
unsigned int init_failed:1; /* delayed init failed */ 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 */ bool need_i915_power:1; /* the hda controller needs i915 power */
}; };
......
...@@ -7378,6 +7378,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -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, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK), 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, 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, 0x19ce, "ASUS B9450FA", ALC294_FIXUP_ASUS_HPE),
SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC),
......
...@@ -1457,7 +1457,7 @@ static int mixer_ctl_connector_get(struct snd_kcontrol *kcontrol, ...@@ -1457,7 +1457,7 @@ static int mixer_ctl_connector_get(struct snd_kcontrol *kcontrol,
usb_audio_err(chip, usb_audio_err(chip,
"cannot get connectors status: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", "cannot get connectors status: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
UAC_GET_CUR, validx, idx, cval->val_type); UAC_GET_CUR, validx, idx, cval->val_type);
return ret; return filter_error(cval, ret);
} }
ucontrol->value.integer.value[0] = val; ucontrol->value.integer.value[0] = val;
...@@ -1771,11 +1771,15 @@ static void get_connector_control_name(struct usb_mixer_interface *mixer, ...@@ -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) */ /* Build a mixer control for a UAC connector control (jack-detect) */
static void build_connector_control(struct usb_mixer_interface *mixer, 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 usb_audio_term *term, bool is_input)
{ {
struct snd_kcontrol *kctl; struct snd_kcontrol *kctl;
struct usb_mixer_elem_info *cval; struct usb_mixer_elem_info *cval;
if (check_ignored_ctl(find_map(imap, term->id, 0)))
return;
cval = kzalloc(sizeof(*cval), GFP_KERNEL); cval = kzalloc(sizeof(*cval), GFP_KERNEL);
if (!cval) if (!cval)
return; return;
...@@ -2109,8 +2113,9 @@ static int parse_audio_input_terminal(struct mixer_build *state, int unitid, ...@@ -2109,8 +2113,9 @@ static int parse_audio_input_terminal(struct mixer_build *state, int unitid,
check_input_term(state, term_id, &iterm); check_input_term(state, term_id, &iterm);
/* Check for jack detection. */ /* Check for jack detection. */
if (uac_v2v3_control_is_readable(bmctls, control)) if ((iterm.type & 0xff00) != 0x0100 &&
build_connector_control(state->mixer, &iterm, true); uac_v2v3_control_is_readable(bmctls, control))
build_connector_control(state->mixer, state->map, &iterm, true);
return 0; return 0;
} }
...@@ -3071,13 +3076,13 @@ static int snd_usb_mixer_controls_badd(struct usb_mixer_interface *mixer, ...@@ -3071,13 +3076,13 @@ static int snd_usb_mixer_controls_badd(struct usb_mixer_interface *mixer,
memset(&iterm, 0, sizeof(iterm)); memset(&iterm, 0, sizeof(iterm));
iterm.id = UAC3_BADD_IT_ID4; iterm.id = UAC3_BADD_IT_ID4;
iterm.type = UAC_BIDIR_TERMINAL_HEADSET; iterm.type = UAC_BIDIR_TERMINAL_HEADSET;
build_connector_control(mixer, &iterm, true); build_connector_control(mixer, map->map, &iterm, true);
/* Output Term - Insertion control */ /* Output Term - Insertion control */
memset(&oterm, 0, sizeof(oterm)); memset(&oterm, 0, sizeof(oterm));
oterm.id = UAC3_BADD_OT_ID3; oterm.id = UAC3_BADD_OT_ID3;
oterm.type = UAC_BIDIR_TERMINAL_HEADSET; oterm.type = UAC_BIDIR_TERMINAL_HEADSET;
build_connector_control(mixer, &oterm, false); build_connector_control(mixer, map->map, &oterm, false);
} }
return 0; return 0;
...@@ -3106,7 +3111,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) ...@@ -3106,7 +3111,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
if (map->id == state.chip->usb_id) { if (map->id == state.chip->usb_id) {
state.map = map->map; state.map = map->map;
state.selector_map = map->selector_map; state.selector_map = map->selector_map;
mixer->ignore_ctl_error = map->ignore_ctl_error; mixer->ignore_ctl_error |= map->ignore_ctl_error;
break; break;
} }
} }
...@@ -3149,10 +3154,11 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) ...@@ -3149,10 +3154,11 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
if (err < 0 && err != -EINVAL) if (err < 0 && err != -EINVAL)
return err; 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)) { UAC2_TE_CONNECTOR)) {
build_connector_control(state.mixer, &state.oterm, build_connector_control(state.mixer, state.map,
false); &state.oterm, false);
} }
} else { /* UAC_VERSION_3 */ } else { /* UAC_VERSION_3 */
struct uac3_output_terminal_descriptor *desc = p; struct uac3_output_terminal_descriptor *desc = p;
...@@ -3174,10 +3180,11 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) ...@@ -3174,10 +3180,11 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
if (err < 0 && err != -EINVAL) if (err < 0 && err != -EINVAL)
return err; 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)) { UAC3_TE_INSERTION)) {
build_connector_control(state.mixer, &state.oterm, build_connector_control(state.mixer, state.map,
false); &state.oterm, false);
} }
} }
} }
......
...@@ -360,9 +360,11 @@ static const struct usbmix_name_map corsair_virtuoso_map[] = { ...@@ -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 /* 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[] = { static const struct usbmix_name_map asus_rog_map[] = {
{ 18, NULL }, /* OT, connector control */
{ 19, NULL, 12 }, /* FU, Input Gain Pad */ { 19, NULL, 12 }, /* FU, Input Gain Pad */
{} {}
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment