提交 8ce72017 编写于 作者: L Linus Torvalds

Merge tag 'sound-4.16-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
 "Things look calming down, but people were still busy to plaster over
  small holes:

   - Two fixes to harden against races in aloop driver

   - A correction of a long-standing bug in USB-audio UAC2 processing
     unit parser

   - As usual suspects, HD-audio: a workaround for Coffee Lake
     controller and a few other device-specific fixes

  All small and for stable"

* tag 'sound-4.16-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: aloop: Fix access to not-yet-ready substream via cable
  ALSA: aloop: Sync stale timer before release
  ALSA: hda/realtek - Fix speaker no sound after system resume
  ALSA: hda/realtek - Fix Dell headset Mic can't record
  ALSA: hda - Force polling mode on CFL for fixing codec communication
  ALSA: usb-audio: Fix parsing descriptor of UAC2 processing unit
  ALSA: hda/realtek - Always immediately update mute LED with pin VREF
...@@ -370,7 +370,7 @@ static inline __u8 uac_processing_unit_bControlSize(struct uac_processing_unit_d ...@@ -370,7 +370,7 @@ static inline __u8 uac_processing_unit_bControlSize(struct uac_processing_unit_d
{ {
return (protocol == UAC_VERSION_1) ? return (protocol == UAC_VERSION_1) ?
desc->baSourceID[desc->bNrInPins + 4] : desc->baSourceID[desc->bNrInPins + 4] :
desc->baSourceID[desc->bNrInPins + 6]; 2; /* in UAC2, this value is constant */
} }
static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_descriptor *desc, static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_descriptor *desc,
...@@ -378,7 +378,7 @@ static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_de ...@@ -378,7 +378,7 @@ static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_de
{ {
return (protocol == UAC_VERSION_1) ? return (protocol == UAC_VERSION_1) ?
&desc->baSourceID[desc->bNrInPins + 5] : &desc->baSourceID[desc->bNrInPins + 5] :
&desc->baSourceID[desc->bNrInPins + 7]; &desc->baSourceID[desc->bNrInPins + 6];
} }
static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_descriptor *desc, static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_descriptor *desc,
......
...@@ -192,6 +192,11 @@ static inline void loopback_timer_stop(struct loopback_pcm *dpcm) ...@@ -192,6 +192,11 @@ static inline void loopback_timer_stop(struct loopback_pcm *dpcm)
dpcm->timer.expires = 0; dpcm->timer.expires = 0;
} }
static inline void loopback_timer_stop_sync(struct loopback_pcm *dpcm)
{
del_timer_sync(&dpcm->timer);
}
#define CABLE_VALID_PLAYBACK (1 << SNDRV_PCM_STREAM_PLAYBACK) #define CABLE_VALID_PLAYBACK (1 << SNDRV_PCM_STREAM_PLAYBACK)
#define CABLE_VALID_CAPTURE (1 << SNDRV_PCM_STREAM_CAPTURE) #define CABLE_VALID_CAPTURE (1 << SNDRV_PCM_STREAM_CAPTURE)
#define CABLE_VALID_BOTH (CABLE_VALID_PLAYBACK|CABLE_VALID_CAPTURE) #define CABLE_VALID_BOTH (CABLE_VALID_PLAYBACK|CABLE_VALID_CAPTURE)
...@@ -326,6 +331,8 @@ static int loopback_prepare(struct snd_pcm_substream *substream) ...@@ -326,6 +331,8 @@ static int loopback_prepare(struct snd_pcm_substream *substream)
struct loopback_cable *cable = dpcm->cable; struct loopback_cable *cable = dpcm->cable;
int bps, salign; int bps, salign;
loopback_timer_stop_sync(dpcm);
salign = (snd_pcm_format_width(runtime->format) * salign = (snd_pcm_format_width(runtime->format) *
runtime->channels) / 8; runtime->channels) / 8;
bps = salign * runtime->rate; bps = salign * runtime->rate;
...@@ -659,7 +666,9 @@ static void free_cable(struct snd_pcm_substream *substream) ...@@ -659,7 +666,9 @@ static void free_cable(struct snd_pcm_substream *substream)
return; return;
if (cable->streams[!substream->stream]) { if (cable->streams[!substream->stream]) {
/* other stream is still alive */ /* other stream is still alive */
spin_lock_irq(&cable->lock);
cable->streams[substream->stream] = NULL; cable->streams[substream->stream] = NULL;
spin_unlock_irq(&cable->lock);
} else { } else {
/* free the cable */ /* free the cable */
loopback->cables[substream->number][dev] = NULL; loopback->cables[substream->number][dev] = NULL;
...@@ -698,7 +707,6 @@ static int loopback_open(struct snd_pcm_substream *substream) ...@@ -698,7 +707,6 @@ static int loopback_open(struct snd_pcm_substream *substream)
loopback->cables[substream->number][dev] = cable; loopback->cables[substream->number][dev] = cable;
} }
dpcm->cable = cable; dpcm->cable = cable;
cable->streams[substream->stream] = dpcm;
snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
...@@ -730,6 +738,11 @@ static int loopback_open(struct snd_pcm_substream *substream) ...@@ -730,6 +738,11 @@ static int loopback_open(struct snd_pcm_substream *substream)
runtime->hw = loopback_pcm_hardware; runtime->hw = loopback_pcm_hardware;
else else
runtime->hw = cable->hw; runtime->hw = cable->hw;
spin_lock_irq(&cable->lock);
cable->streams[substream->stream] = dpcm;
spin_unlock_irq(&cable->lock);
unlock: unlock:
if (err < 0) { if (err < 0) {
free_cable(substream); free_cable(substream);
...@@ -744,7 +757,7 @@ static int loopback_close(struct snd_pcm_substream *substream) ...@@ -744,7 +757,7 @@ static int loopback_close(struct snd_pcm_substream *substream)
struct loopback *loopback = substream->private_data; struct loopback *loopback = substream->private_data;
struct loopback_pcm *dpcm = substream->runtime->private_data; struct loopback_pcm *dpcm = substream->runtime->private_data;
loopback_timer_stop(dpcm); loopback_timer_stop_sync(dpcm);
mutex_lock(&loopback->cable_lock); mutex_lock(&loopback->cable_lock);
free_cable(substream); free_cable(substream);
mutex_unlock(&loopback->cable_lock); mutex_unlock(&loopback->cable_lock);
......
...@@ -375,6 +375,7 @@ enum { ...@@ -375,6 +375,7 @@ enum {
((pci)->device == 0x160c)) ((pci)->device == 0x160c))
#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98) #define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
#define IS_CFL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa348)
static char *driver_short_names[] = { static char *driver_short_names[] = {
[AZX_DRIVER_ICH] = "HDA Intel", [AZX_DRIVER_ICH] = "HDA Intel",
...@@ -1744,6 +1745,10 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci, ...@@ -1744,6 +1745,10 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
else else
chip->bdl_pos_adj = bdl_pos_adj[dev]; chip->bdl_pos_adj = bdl_pos_adj[dev];
/* Workaround for a communication error on CFL (bko#199007) */
if (IS_CFL(pci))
chip->polling_mode = 1;
err = azx_bus_init(chip, model[dev], &pci_hda_io_ops); err = azx_bus_init(chip, model[dev], &pci_hda_io_ops);
if (err < 0) { if (err < 0) {
kfree(hda); kfree(hda);
......
...@@ -3130,6 +3130,8 @@ static void alc256_init(struct hda_codec *codec) ...@@ -3130,6 +3130,8 @@ static void alc256_init(struct hda_codec *codec)
alc_update_coef_idx(codec, 0x46, 3 << 12, 0); alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */ alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 1 << 15); /* Clear bit */
alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 0 << 15);
} }
static void alc256_shutup(struct hda_codec *codec) static void alc256_shutup(struct hda_codec *codec)
...@@ -3596,8 +3598,12 @@ static void alc269_fixup_mic_mute_hook(void *private_data, int enabled) ...@@ -3596,8 +3598,12 @@ static void alc269_fixup_mic_mute_hook(void *private_data, int enabled)
pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid); pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid);
pinval &= ~AC_PINCTL_VREFEN; pinval &= ~AC_PINCTL_VREFEN;
pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80; pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80;
if (spec->mute_led_nid) if (spec->mute_led_nid) {
/* temporarily power up/down for setting VREF */
snd_hda_power_up_pm(codec);
snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval); snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval);
snd_hda_power_down_pm(codec);
}
} }
/* Make sure the led works even in runtime suspend */ /* Make sure the led works even in runtime suspend */
...@@ -5497,6 +5503,7 @@ enum { ...@@ -5497,6 +5503,7 @@ enum {
ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
ALC298_FIXUP_TPT470_DOCK, ALC298_FIXUP_TPT470_DOCK,
ALC255_FIXUP_DUMMY_LINEOUT_VERB, ALC255_FIXUP_DUMMY_LINEOUT_VERB,
ALC255_FIXUP_DELL_HEADSET_MIC,
}; };
static const struct hda_fixup alc269_fixups[] = { static const struct hda_fixup alc269_fixups[] = {
...@@ -6357,6 +6364,13 @@ static const struct hda_fixup alc269_fixups[] = { ...@@ -6357,6 +6364,13 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true, .chained = true,
.chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
}, },
[ALC255_FIXUP_DELL_HEADSET_MIC] = {
.type = HDA_FIXUP_PINS,
.v.pins = (const struct hda_pintbl[]) {
{ 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
{ }
},
},
}; };
static const struct snd_pci_quirk alc269_fixup_tbl[] = { static const struct snd_pci_quirk alc269_fixup_tbl[] = {
...@@ -6411,6 +6425,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -6411,6 +6425,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1028, 0x082a, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE), SND_PCI_QUIRK(0x1028, 0x082a, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
SND_PCI_QUIRK(0x1028, 0x084b, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB), SND_PCI_QUIRK(0x1028, 0x084b, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
SND_PCI_QUIRK(0x1028, 0x084e, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB), SND_PCI_QUIRK(0x1028, 0x084e, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB), SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB),
SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
...@@ -7154,6 +7170,8 @@ static int patch_alc269(struct hda_codec *codec) ...@@ -7154,6 +7170,8 @@ static int patch_alc269(struct hda_codec *codec)
break; break;
case 0x10ec0257: case 0x10ec0257:
spec->codec_variant = ALC269_TYPE_ALC257; spec->codec_variant = ALC269_TYPE_ALC257;
spec->shutup = alc256_shutup;
spec->init_hook = alc256_init;
spec->gen.mixer_nid = 0; spec->gen.mixer_nid = 0;
break; break;
case 0x10ec0215: case 0x10ec0215:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册