From e40bdb03d3cd7da66bd0bc1e40cbcfb49351265c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sat, 17 Mar 2018 22:40:18 +0100 Subject: ALSA: hda/realtek - Always immediately update mute LED with pin VREF Some HP laptops have a mute mute LED controlled by a pin VREF. The Realtek codec driver updates the VREF via vmaster hook by calling snd_hda_set_pin_ctl_cache(). This works fine as long as the driver is running in a normal mode. However, when the VREF change happens during the codec being in runtime PM suspend, the regmap access will skip and postpone the actual register change. This ends up with the unchanged LED status until the next runtime PM resume even if you change the Master mute switch. (Interestingly, the machine keeps the LED status even after the codec goes into D3 -- but it's another story.) For improving this usability, let the driver temporarily powering up / down only during the pin VREF change. This can be achieved easily by wrapping the call with snd_hda_power_up_pm() / *_down_pm(). Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=199073 Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 9af301c6bba2..5ef056f2aecc 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3596,8 +3596,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 &= ~AC_PINCTL_VREFEN; 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_power_down_pm(codec); + } } /* Make sure the led works even in runtime suspend */ -- cgit v1.2.3 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 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 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 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 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 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 From 9066ae7ff5d89c0b5daa271e2d573540097a94fa Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 26 Mar 2018 16:10:21 +0200 Subject: ALSA: pcm: Use dma_bytes as size parameter in dma_mmap_coherent() When trying to use the driver (e.g. aplay *.wav), the 4MiB DMA buffer will get mmapp'ed in 16KiB chunks. But this fails with the 2nd 16KiB area, as the page offset is outside of the VMA range (size), which is currently used as size parameter in snd_pcm_lib_default_mmap(). By using the DMA buffer size (dma_bytes) instead, the complete DMA buffer can be mmapp'ed and the issue is fixed. This issue was detected on an ARM platform (TI AM57xx) using the RME HDSP MADI PCIe soundcard. Fixes: 657b1989dacf ("ALSA: pcm - Use dma_mmap_coherent() if available") Signed-off-by: Stefan Roese Cc: Signed-off-by: Takashi Iwai --- sound/core/pcm_native.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 77ba50ddcf9e..d18b3982548b 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -3422,7 +3422,7 @@ int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream, area, substream->runtime->dma_area, substream->runtime->dma_addr, - area->vm_end - area->vm_start); + substream->runtime->dma_bytes); #endif /* CONFIG_X86 */ /* mmap with fault handler */ area->vm_ops = &snd_pcm_vm_ops_data_fault; -- cgit v1.2.3 From 5607dddbfca774fb38bffadcb077fe03aa4ac5c6 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 27 Mar 2018 16:07:52 +0300 Subject: ALSA: pcm: potential uninitialized return values Smatch complains that "tmp" can be uninitialized if we do a zero size write. Fixes: 02a5d6925cd3 ("ALSA: pcm: Avoid potential races between OSS ioctls and read/write") Signed-off-by: Dan Carpenter Cc: Signed-off-by: Takashi Iwai --- sound/core/oss/pcm_oss.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 02298c9c6020..441405081195 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -1326,7 +1326,7 @@ static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const cha static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const char __user *buf, size_t bytes) { size_t xfer = 0; - ssize_t tmp; + ssize_t tmp = 0; struct snd_pcm_runtime *runtime = substream->runtime; if (atomic_read(&substream->mmap_count)) @@ -1433,7 +1433,7 @@ static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf, static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __user *buf, size_t bytes) { size_t xfer = 0; - ssize_t tmp; + ssize_t tmp = 0; struct snd_pcm_runtime *runtime = substream->runtime; if (atomic_read(&substream->mmap_count)) -- cgit v1.2.3