From a8d7bde23e7130686b76624b099f3e22dd38aef7 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 21 Mar 2018 10:06:13 +0100 Subject: ALSA: hda - Force polling mode on CFL for fixing codec communication We've observed too long probe time with Coffee Lake (CFL) machines, and the likely cause is some communication problem between the HD-audio controller and the codec chips. While the controller expects an IRQ wakeup for each codec response, it seems sometimes missing, and it takes one second for the controller driver to time out and read the response in the polling mode. Although we aren't sure about the real culprit yet, in this patch, we put a workaround by forcing the polling mode as default for CFL machines; the polling mode itself isn't too heavy, and much better than other workarounds initially suggested (e.g. disabling power-save), at least. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=199007 Fixes: e79b0006c45c ("ALSA: hda - Add Coffelake PCI ID") Reported-and-tested-by: Hui Wang Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index d5017adf9feb..c507c69029e3 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -375,6 +375,7 @@ enum { ((pci)->device == 0x160c)) #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[] = { [AZX_DRIVER_ICH] = "HDA Intel", @@ -1744,6 +1745,10 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci, else 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); if (err < 0) { kfree(hda); -- cgit v1.2.3-55-g7522 From f0ba9d699e5ca2bcd07f70185d18720c4f1b597c Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Fri, 16 Mar 2018 11:46:08 +0800 Subject: ALSA: hda/realtek - Fix Dell headset Mic can't record This platform was hardware fixed type for CTIA type for headset port. Assigned 0x19 verb will fix can't record issue. Signed-off-by: Kailang Yang Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5ef056f2aecc..619d1f92b6eb 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5501,6 +5501,7 @@ enum { ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, ALC298_FIXUP_TPT470_DOCK, ALC255_FIXUP_DUMMY_LINEOUT_VERB, + ALC255_FIXUP_DELL_HEADSET_MIC, }; static const struct hda_fixup alc269_fixups[] = { @@ -6361,6 +6362,13 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .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[] = { @@ -6415,6 +6423,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, 0x084b, "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, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), -- cgit v1.2.3-55-g7522 From 88d42b2b45d7208cc872c2c9dec0b1ae6c6008d7 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Wed, 14 Mar 2018 16:08:57 +0800 Subject: ALSA: hda/realtek - Fix speaker no sound after system resume It will have a chance speaker no sound after system resume. To toggle NID 0x53 index 0x2 bit 15 will solve this issue. This usage will also suitable with ALC256. Fixes: 4a219ef8f370 ("ALSA: hda/realtek - Add ALC256 HP depop function") Signed-off-by: Kailang Yang Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 619d1f92b6eb..aef1f52db7d9 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3130,6 +3130,8 @@ static void alc256_init(struct hda_codec *codec) 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, 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) @@ -7168,6 +7170,8 @@ static int patch_alc269(struct hda_codec *codec) break; case 0x10ec0257: spec->codec_variant = ALC269_TYPE_ALC257; + spec->shutup = alc256_shutup; + spec->init_hook = alc256_init; spec->gen.mixer_nid = 0; break; case 0x10ec0215: -- cgit v1.2.3-55-g7522 From 67a01afaf3d34893cf7d2ea19b34555d6abb7cb0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 22 Mar 2018 08:56:06 +0100 Subject: ALSA: aloop: Sync stale timer before release The aloop driver tries to stop the pending timer via timer_del() in the trigger callback and in the close callback. The former is correct, as it's an atomic operation, while the latter expects that the timer gets really removed and proceeds the resource releases after that. But timer_del() doesn't synchronize, hence the running timer may still access the released resources. A similar situation can be also seen in the prepare callback after trigger(STOP) where the prepare tries to re-initialize the things while a timer is still running. The problems like the above are seen indirectly in some syzkaller reports (although it's not 100% clear whether this is the only cause, as the race condition is quite narrow and not always easy to trigger). For addressing these issues, this patch adds the explicit alls of timer_del_sync() in some places, so that the pending timer is properly killed / synced. Cc: Signed-off-by: Takashi Iwai --- sound/drivers/aloop.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index 0333143a1fa7..0a08e63e9c66 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c @@ -192,6 +192,11 @@ static inline void loopback_timer_stop(struct loopback_pcm *dpcm) 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_CAPTURE (1 << SNDRV_PCM_STREAM_CAPTURE) #define CABLE_VALID_BOTH (CABLE_VALID_PLAYBACK|CABLE_VALID_CAPTURE) @@ -326,6 +331,8 @@ static int loopback_prepare(struct snd_pcm_substream *substream) struct loopback_cable *cable = dpcm->cable; int bps, salign; + loopback_timer_stop_sync(dpcm); + salign = (snd_pcm_format_width(runtime->format) * runtime->channels) / 8; bps = salign * runtime->rate; @@ -744,7 +751,7 @@ static int loopback_close(struct snd_pcm_substream *substream) struct loopback *loopback = substream->private_data; struct loopback_pcm *dpcm = substream->runtime->private_data; - loopback_timer_stop(dpcm); + loopback_timer_stop_sync(dpcm); mutex_lock(&loopback->cable_lock); free_cable(substream); mutex_unlock(&loopback->cable_lock); -- cgit v1.2.3-55-g7522 From 8e6b1a72a75bb5067ccb6b56d8ca4aa3a300a64e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 22 Mar 2018 10:40:27 +0100 Subject: ALSA: aloop: Fix access to not-yet-ready substream via cable In loopback_open() and loopback_close(), we assign and release the substream object to the corresponding cable in a racy way. It's neither locked nor done in the right position. The open callback assigns the substream before its preparation finishes, hence the other side of the cable may pick it up, which may lead to the invalid memory access. This patch addresses these: move the assignment to the end of the open callback, and wrap with cable->lock for avoiding concurrent accesses. Cc: Signed-off-by: Takashi Iwai --- sound/drivers/aloop.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index 0a08e63e9c66..1063a4377502 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c @@ -666,7 +666,9 @@ static void free_cable(struct snd_pcm_substream *substream) return; if (cable->streams[!substream->stream]) { /* other stream is still alive */ + spin_lock_irq(&cable->lock); cable->streams[substream->stream] = NULL; + spin_unlock_irq(&cable->lock); } else { /* free the cable */ loopback->cables[substream->number][dev] = NULL; @@ -705,7 +707,6 @@ static int loopback_open(struct snd_pcm_substream *substream) loopback->cables[substream->number][dev] = cable; } dpcm->cable = cable; - cable->streams[substream->stream] = dpcm; snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); @@ -737,6 +738,11 @@ static int loopback_open(struct snd_pcm_substream *substream) runtime->hw = loopback_pcm_hardware; else runtime->hw = cable->hw; + + spin_lock_irq(&cable->lock); + cable->streams[substream->stream] = dpcm; + spin_unlock_irq(&cable->lock); + unlock: if (err < 0) { free_cable(substream); -- cgit v1.2.3-55-g7522 From b00214865d65100163574ba250008f182cf90869 Mon Sep 17 00:00:00 2001 From: Nobutaka Okabe Date: Fri, 23 Mar 2018 19:49:44 +0900 Subject: ALSA: usb-audio: Add native DSD support for TEAC UD-301 Add native DSD support quirk for TEAC UD-301 DAC, by adding the PID/VID 0644:804a. Signed-off-by: Nobutaka Okabe Cc: Signed-off-by: Takashi Iwai --- sound/usb/quirks.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound') diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index ea8f3de92fa4..794224e1d6df 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1171,6 +1171,7 @@ static bool is_teac_dsd_dac(unsigned int id) switch (id) { case USB_ID(0x0644, 0x8043): /* TEAC UD-501/UD-503/NT-503 */ case USB_ID(0x0644, 0x8044): /* Esoteric D-05X */ + case USB_ID(0x0644, 0x804a): /* TEAC UD-301 */ return true; } return false; -- cgit v1.2.3-55-g7522