forked from Minki/linux
sound fixes for 3.15-rc5
A bunch of small fixes for USB-audio and HD-audio, where most of them are for regressions: USB-audio PM fixes, ratelimit annoyance fix, HDMI offline state fix, and a couple of device-specific quirks. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJTa5LaAAoJEGwxgFQ9KSmkabEQAINXU3tKZffB8+wu5SG/ZkWx 07vFKLPdYHk/9Q4FboGTZbS6eXqZka4x5QH6t8GbdpPG2q3xQL/MjzfSVf4jg2IB 6uh1Ng47dYr08rHXuwFYHAYbeWSet2uERRO+k0WClnsS+Y/IO/38Fnr3xfgwTQEJ YRhz3ck0mgk8v08D3f+6Nb12WX36wxfQh00K8fRUBNBI5OchXNPymrIoI0rvWrbt WVUIVUk2x+z6Sa8cg2+VPHOrSE/Anxjeejz7iaq1t+BCwcGiQRunGkkzS5wxxPxD j3yb2bwy1O3AdBPBSZJruNIdwTgWHomENaowQE/Y9SwvCDy1thIHrQZZkZxh4vVB uAHfeBHh8hsHZXHAIkR+JH2fZOHXBgiMFNuw634NAox1/ShRbtZBMoovlBl7rrKv Ikgodj6AInrdXfoFj2d80dURV7145PpfC5KRZ5f6Xn+/DGEipHqXbq3W4vLyzGhP hzybfKTiQzlrcuyYAJFBo1NFM1utk1VSqO+X7k3tjHre5Z3jOKLrzOwxOavrD7i3 81bUpeXqP0wSJWz3MBGHP1MSSRm9FhCWZhGe1pXKxsxZISTFQKGaqBaq28TliJ7z LDGcP6rv8uEbHV4sSxuVe6Vo/nzxTeteo3WQlLgrhBC9PJmjQ4TBY3CJjWdLY7nT KiYvHWF7zRjFqwQ0VUns =OCny -----END PGP SIGNATURE----- Merge tag 'sound-3.15-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound fixes from Takashi Iwai: "A bunch of small fixes for USB-audio and HD-audio, where most of them are for regressions: USB-audio PM fixes, ratelimit annoyance fix, HDMI offline state fix, and a couple of device-specific quirks" * tag 'sound-3.15-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: hda - hdmi: Set converter channel count even without sink ALSA: usb-audio: work around corrupted TEAC UD-H01 feedback data ALSA: usb-audio: Fix deadlocks at resuming ALSA: usb-audio: Save mixer status only once at suspend ALSA: usb-audio: Prevent printk ratelimiting from spamming kernel log while DEBUG not defined ALSA: hda - add headset mic detect quirk for a Dell laptop
This commit is contained in:
commit
c6c96d7bba
@ -1127,8 +1127,10 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec,
|
|||||||
AMP_OUT_UNMUTE);
|
AMP_OUT_UNMUTE);
|
||||||
|
|
||||||
eld = &per_pin->sink_eld;
|
eld = &per_pin->sink_eld;
|
||||||
if (!eld->monitor_present)
|
if (!eld->monitor_present) {
|
||||||
|
hdmi_set_channel_count(codec, per_pin->cvt_nid, channels);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!non_pcm && per_pin->chmap_set)
|
if (!non_pcm && per_pin->chmap_set)
|
||||||
ca = hdmi_manual_channel_allocation(channels, per_pin->chmap);
|
ca = hdmi_manual_channel_allocation(channels, per_pin->chmap);
|
||||||
|
@ -4622,6 +4622,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
|||||||
SND_PCI_QUIRK(0x1028, 0x0668, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1028, 0x0668, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1028, 0x0669, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1028, 0x0669, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1028, 0x0674, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1028, 0x0674, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||||
|
SND_PCI_QUIRK(0x1028, 0x067e, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1028, 0x067f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1028, 0x067f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
|
||||||
SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
|
SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
|
||||||
|
@ -651,7 +651,7 @@ int snd_usb_autoresume(struct snd_usb_audio *chip)
|
|||||||
int err = -ENODEV;
|
int err = -ENODEV;
|
||||||
|
|
||||||
down_read(&chip->shutdown_rwsem);
|
down_read(&chip->shutdown_rwsem);
|
||||||
if (chip->probing)
|
if (chip->probing && chip->in_pm)
|
||||||
err = 0;
|
err = 0;
|
||||||
else if (!chip->shutdown)
|
else if (!chip->shutdown)
|
||||||
err = usb_autopm_get_interface(chip->pm_intf);
|
err = usb_autopm_get_interface(chip->pm_intf);
|
||||||
@ -663,7 +663,7 @@ int snd_usb_autoresume(struct snd_usb_audio *chip)
|
|||||||
void snd_usb_autosuspend(struct snd_usb_audio *chip)
|
void snd_usb_autosuspend(struct snd_usb_audio *chip)
|
||||||
{
|
{
|
||||||
down_read(&chip->shutdown_rwsem);
|
down_read(&chip->shutdown_rwsem);
|
||||||
if (!chip->shutdown && !chip->probing)
|
if (!chip->shutdown && !chip->probing && !chip->in_pm)
|
||||||
usb_autopm_put_interface(chip->pm_intf);
|
usb_autopm_put_interface(chip->pm_intf);
|
||||||
up_read(&chip->shutdown_rwsem);
|
up_read(&chip->shutdown_rwsem);
|
||||||
}
|
}
|
||||||
@ -695,8 +695,9 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
|
|||||||
chip->autosuspended = 1;
|
chip->autosuspended = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry(mixer, &chip->mixer_list, list)
|
if (chip->num_suspended_intf == 1)
|
||||||
snd_usb_mixer_suspend(mixer);
|
list_for_each_entry(mixer, &chip->mixer_list, list)
|
||||||
|
snd_usb_mixer_suspend(mixer);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -711,6 +712,8 @@ static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume)
|
|||||||
return 0;
|
return 0;
|
||||||
if (--chip->num_suspended_intf)
|
if (--chip->num_suspended_intf)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
chip->in_pm = 1;
|
||||||
/*
|
/*
|
||||||
* ALSA leaves material resumption to user space
|
* ALSA leaves material resumption to user space
|
||||||
* we just notify and restart the mixers
|
* we just notify and restart the mixers
|
||||||
@ -726,6 +729,7 @@ static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume)
|
|||||||
chip->autosuspended = 0;
|
chip->autosuspended = 0;
|
||||||
|
|
||||||
err_out:
|
err_out:
|
||||||
|
chip->in_pm = 0;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +92,7 @@ struct snd_usb_endpoint {
|
|||||||
unsigned int curframesize; /* current packet size in frames (for capture) */
|
unsigned int curframesize; /* current packet size in frames (for capture) */
|
||||||
unsigned int syncmaxsize; /* sync endpoint packet size */
|
unsigned int syncmaxsize; /* sync endpoint packet size */
|
||||||
unsigned int fill_max:1; /* fill max packet size always */
|
unsigned int fill_max:1; /* fill max packet size always */
|
||||||
|
unsigned int udh01_fb_quirk:1; /* corrupted feedback data */
|
||||||
unsigned int datainterval; /* log_2 of data packet interval */
|
unsigned int datainterval; /* log_2 of data packet interval */
|
||||||
unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */
|
unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */
|
||||||
unsigned char silence_value;
|
unsigned char silence_value;
|
||||||
|
@ -471,6 +471,10 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip,
|
|||||||
ep->syncinterval = 3;
|
ep->syncinterval = 3;
|
||||||
|
|
||||||
ep->syncmaxsize = le16_to_cpu(get_endpoint(alts, 1)->wMaxPacketSize);
|
ep->syncmaxsize = le16_to_cpu(get_endpoint(alts, 1)->wMaxPacketSize);
|
||||||
|
|
||||||
|
if (chip->usb_id == USB_ID(0x0644, 0x8038) /* TEAC UD-H01 */ &&
|
||||||
|
ep->syncmaxsize == 4)
|
||||||
|
ep->udh01_fb_quirk = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_add_tail(&ep->list, &chip->ep_list);
|
list_add_tail(&ep->list, &chip->ep_list);
|
||||||
@ -1105,7 +1109,16 @@ void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep,
|
|||||||
if (f == 0)
|
if (f == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (unlikely(ep->freqshift == INT_MIN)) {
|
if (unlikely(sender->udh01_fb_quirk)) {
|
||||||
|
/*
|
||||||
|
* The TEAC UD-H01 firmware sometimes changes the feedback value
|
||||||
|
* by +/- 0x1.0000.
|
||||||
|
*/
|
||||||
|
if (f < ep->freqn - 0x8000)
|
||||||
|
f += 0x10000;
|
||||||
|
else if (f > ep->freqn + 0x8000)
|
||||||
|
f -= 0x10000;
|
||||||
|
} else if (unlikely(ep->freqshift == INT_MIN)) {
|
||||||
/*
|
/*
|
||||||
* The first time we see a feedback value, determine its format
|
* The first time we see a feedback value, determine its format
|
||||||
* by shifting it left or right until it matches the nominal
|
* by shifting it left or right until it matches the nominal
|
||||||
|
@ -1501,9 +1501,8 @@ static void retire_playback_urb(struct snd_usb_substream *subs,
|
|||||||
* The error should be lower than 2ms since the estimate relies
|
* The error should be lower than 2ms since the estimate relies
|
||||||
* on two reads of a counter updated every ms.
|
* on two reads of a counter updated every ms.
|
||||||
*/
|
*/
|
||||||
if (printk_ratelimit() &&
|
if (abs(est_delay - subs->last_delay) * 1000 > runtime->rate * 2)
|
||||||
abs(est_delay - subs->last_delay) * 1000 > runtime->rate * 2)
|
dev_dbg_ratelimited(&subs->dev->dev,
|
||||||
dev_dbg(&subs->dev->dev,
|
|
||||||
"delay: estimated %d, actual %d\n",
|
"delay: estimated %d, actual %d\n",
|
||||||
est_delay, subs->last_delay);
|
est_delay, subs->last_delay);
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ struct snd_usb_audio {
|
|||||||
struct rw_semaphore shutdown_rwsem;
|
struct rw_semaphore shutdown_rwsem;
|
||||||
unsigned int shutdown:1;
|
unsigned int shutdown:1;
|
||||||
unsigned int probing:1;
|
unsigned int probing:1;
|
||||||
|
unsigned int in_pm:1;
|
||||||
unsigned int autosuspended:1;
|
unsigned int autosuspended:1;
|
||||||
unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */
|
unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user