summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-11-23 21:09:41 -1000
committerLinus Torvalds <torvalds@linux-foundation.org>2017-11-23 21:09:41 -1000
commitb64f26c62dc6e29d98bd72854ac582bb66113331 (patch)
tree85c4619b2ba0f459d6b36bedbc7741ea8a294107
parentc353bfc6ebc1073f2f0af72a15f8f18db7193d2e (diff)
parent9ceace3c9c18c67676e75141032a65a8e01f9a7a (diff)
downloadlinux-b64f26c62dc6e29d98bd72854ac582bb66113331.tar.bz2
Merge tag 'sound-fix-4.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai: "All commits found here are small fixes for regression or stable: - PCM timestamp behavior fix that could be seen as a regression - Remove spurious WARN_ON() from ALSA timer 32bit compat ioctl - HD-audio HDMI/DP channel mapping fix for 32bit archs - Fix the previous fix for HD-audio initialization code - More hardening USB-audio against malicious USB descriptors - HD-audio quirks/fixes (Realtek codec, AMD controller) - Missing help text for the recent Intel SST kconfig change" * tag 'sound-fix-4.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: hda: Add Raven PCI ID ALSA: hda/realtek - Fix ALC700 family no sound issue ALSA: hda - Fix yet remaining issue with vmaster 0dB initialization ALSA: usb-audio: Add sanity checks in v2 clock parsers ALSA: usb-audio: Fix potential zero-division at parsing FU ALSA: usb-audio: Fix potential out-of-bound access at parsing SU ALSA: usb-audio: Add sanity checks to FE parser ALSA: timer: Remove kernel warning at compat ioctl error paths ALSA: pcm: update tstamp only if audio_tstamp changed ALSA: hda/realtek: Add headset mic support for Intel NUC Skull Canyon ALSA: hda: Fix too short HDMI/DP chmap reporting ALSA: usb-audio: uac1: Invalidate ctl on interrupt ALSA: hda/realtek - Fix ALC275 no sound issue ASoC: Intel: Add help text for SND_SOC_INTEL_SST_TOPLEVEL
-rw-r--r--include/sound/control.h4
-rw-r--r--sound/core/pcm_lib.c6
-rw-r--r--sound/core/timer_compat.c12
-rw-r--r--sound/core/vmaster.c6
-rw-r--r--sound/hda/hdmi_chmap.c2
-rw-r--r--sound/pci/hda/hda_codec.c10
-rw-r--r--sound/pci/hda/hda_intel.c3
-rw-r--r--sound/pci/hda/patch_realtek.c9
-rw-r--r--sound/soc/intel/Kconfig5
-rw-r--r--sound/usb/clock.c9
-rw-r--r--sound/usb/mixer.c26
11 files changed, 69 insertions, 23 deletions
diff --git a/include/sound/control.h b/include/sound/control.h
index a1f1152bc687..ca13a44ae9d4 100644
--- a/include/sound/control.h
+++ b/include/sound/control.h
@@ -249,7 +249,9 @@ int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kctl,
void snd_ctl_sync_vmaster(struct snd_kcontrol *kctl, bool hook_only);
#define snd_ctl_sync_vmaster_hook(kctl) snd_ctl_sync_vmaster(kctl, true)
int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl,
- int (*func)(struct snd_kcontrol *, void *),
+ int (*func)(struct snd_kcontrol *vslave,
+ struct snd_kcontrol *slave,
+ void *arg),
void *arg);
/*
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index a93a4235a332..10e7ef7a8804 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -248,8 +248,10 @@ static void update_audio_tstamp(struct snd_pcm_substream *substream,
runtime->rate);
*audio_tstamp = ns_to_timespec(audio_nsecs);
}
- runtime->status->audio_tstamp = *audio_tstamp;
- runtime->status->tstamp = *curr_tstamp;
+ if (!timespec_equal(&runtime->status->audio_tstamp, audio_tstamp)) {
+ runtime->status->audio_tstamp = *audio_tstamp;
+ runtime->status->tstamp = *curr_tstamp;
+ }
/*
* re-take a driver timestamp to let apps detect if the reference tstamp
diff --git a/sound/core/timer_compat.c b/sound/core/timer_compat.c
index 59127b6ef39e..e00f7e399e46 100644
--- a/sound/core/timer_compat.c
+++ b/sound/core/timer_compat.c
@@ -66,11 +66,11 @@ static int snd_timer_user_info_compat(struct file *file,
struct snd_timer *t;
tu = file->private_data;
- if (snd_BUG_ON(!tu->timeri))
- return -ENXIO;
+ if (!tu->timeri)
+ return -EBADFD;
t = tu->timeri->timer;
- if (snd_BUG_ON(!t))
- return -ENXIO;
+ if (!t)
+ return -EBADFD;
memset(&info, 0, sizeof(info));
info.card = t->card ? t->card->number : -1;
if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
@@ -99,8 +99,8 @@ static int snd_timer_user_status_compat(struct file *file,
struct snd_timer_status32 status;
tu = file->private_data;
- if (snd_BUG_ON(!tu->timeri))
- return -ENXIO;
+ if (!tu->timeri)
+ return -EBADFD;
memset(&status, 0, sizeof(status));
status.tstamp.tv_sec = tu->tstamp.tv_sec;
status.tstamp.tv_nsec = tu->tstamp.tv_nsec;
diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c
index e43af18d4383..8632301489fa 100644
--- a/sound/core/vmaster.c
+++ b/sound/core/vmaster.c
@@ -495,7 +495,9 @@ EXPORT_SYMBOL_GPL(snd_ctl_sync_vmaster);
* Returns 0 if successful, or a negative error code.
*/
int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl,
- int (*func)(struct snd_kcontrol *, void *),
+ int (*func)(struct snd_kcontrol *vslave,
+ struct snd_kcontrol *slave,
+ void *arg),
void *arg)
{
struct link_master *master;
@@ -507,7 +509,7 @@ int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl,
if (err < 0)
return err;
list_for_each_entry(slave, &master->slaves, list) {
- err = func(&slave->slave, arg);
+ err = func(slave->kctl, &slave->slave, arg);
if (err < 0)
return err;
}
diff --git a/sound/hda/hdmi_chmap.c b/sound/hda/hdmi_chmap.c
index 81acc20c2535..f21633cd9b38 100644
--- a/sound/hda/hdmi_chmap.c
+++ b/sound/hda/hdmi_chmap.c
@@ -746,7 +746,7 @@ static int hdmi_chmap_ctl_get(struct snd_kcontrol *kcontrol,
memset(pcm_chmap, 0, sizeof(pcm_chmap));
chmap->ops.get_chmap(chmap->hdac, pcm_idx, pcm_chmap);
- for (i = 0; i < sizeof(chmap); i++)
+ for (i = 0; i < ARRAY_SIZE(pcm_chmap); i++)
ucontrol->value.integer.value[i] = pcm_chmap[i];
return 0;
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index c1f8e5479bf3..e018ecbf78a8 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1823,7 +1823,9 @@ struct slave_init_arg {
};
/* initialize the slave volume with 0dB via snd_ctl_apply_vmaster_slaves() */
-static int init_slave_0dB(struct snd_kcontrol *kctl, void *_arg)
+static int init_slave_0dB(struct snd_kcontrol *slave,
+ struct snd_kcontrol *kctl,
+ void *_arg)
{
struct slave_init_arg *arg = _arg;
int _tlv[4];
@@ -1860,7 +1862,7 @@ static int init_slave_0dB(struct snd_kcontrol *kctl, void *_arg)
arg->step = step;
val = -tlv[2] / step;
if (val > 0) {
- put_kctl_with_value(kctl, val);
+ put_kctl_with_value(slave, val);
return val;
}
@@ -1868,7 +1870,9 @@ static int init_slave_0dB(struct snd_kcontrol *kctl, void *_arg)
}
/* unmute the slave via snd_ctl_apply_vmaster_slaves() */
-static int init_slave_unmute(struct snd_kcontrol *slave, void *_arg)
+static int init_slave_unmute(struct snd_kcontrol *slave,
+ struct snd_kcontrol *kctl,
+ void *_arg)
{
return put_kctl_with_value(slave, 1);
}
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index f958d8d54d15..c71dcacea807 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -2463,6 +2463,9 @@ static const struct pci_device_id azx_ids[] = {
/* AMD Hudson */
{ PCI_DEVICE(0x1022, 0x780d),
.driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB },
+ /* AMD Raven */
+ { PCI_DEVICE(0x1022, 0x15e3),
+ .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB },
/* ATI HDMI */
{ PCI_DEVICE(0x1002, 0x0002),
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index db1a376e27c0..921a10eff43a 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -341,6 +341,9 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
case 0x10ec0299:
alc_update_coef_idx(codec, 0x10, 1<<9, 0);
break;
+ case 0x10ec0275:
+ alc_update_coef_idx(codec, 0xe, 0, 1<<0);
+ break;
case 0x10ec0293:
alc_update_coef_idx(codec, 0xa, 1<<13, 0);
break;
@@ -6452,6 +6455,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
ALC225_STANDARD_PINS,
{0x12, 0xb7a60130},
{0x1b, 0x90170110}),
+ SND_HDA_PIN_QUIRK(0x10ec0233, 0x8086, "Intel NUC Skull Canyon", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
+ {0x1b, 0x01111010},
+ {0x1e, 0x01451130},
+ {0x21, 0x02211020}),
SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
{0x12, 0x90a60140},
{0x14, 0x90170110},
@@ -6887,7 +6894,7 @@ static int patch_alc269(struct hda_codec *codec)
case 0x10ec0703:
spec->codec_variant = ALC269_TYPE_ALC700;
spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */
- alc_update_coef_idx(codec, 0x4a, 0, 1 << 15); /* Combo jack auto trigger control */
+ alc_update_coef_idx(codec, 0x4a, 1 << 15, 0); /* Combo jack auto trigger control */
break;
}
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index bb8be10b8437..7b49d04e3c60 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -34,6 +34,11 @@ config SND_SOC_INTEL_SST_TOPLEVEL
depends on X86 || COMPILE_TEST
select SND_SOC_INTEL_MACH
select SND_SOC_INTEL_COMMON
+ help
+ Intel ASoC Audio Drivers. If you have a Intel machine that
+ has audio controller with a DSP and I2S or DMIC port, then
+ enable this option by saying Y or M
+ If unsure select "N".
config SND_SOC_INTEL_HASWELL
tristate "Intel ASoC SST driver for Haswell/Broadwell"
diff --git a/sound/usb/clock.c b/sound/usb/clock.c
index 26dd5f20f149..eb3396ffba4c 100644
--- a/sound/usb/clock.c
+++ b/sound/usb/clock.c
@@ -43,7 +43,7 @@ static struct uac_clock_source_descriptor *
while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
ctrl_iface->extralen,
cs, UAC2_CLOCK_SOURCE))) {
- if (cs->bClockID == clock_id)
+ if (cs->bLength >= sizeof(*cs) && cs->bClockID == clock_id)
return cs;
}
@@ -59,8 +59,11 @@ static struct uac_clock_selector_descriptor *
while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
ctrl_iface->extralen,
cs, UAC2_CLOCK_SELECTOR))) {
- if (cs->bClockID == clock_id)
+ if (cs->bLength >= sizeof(*cs) && cs->bClockID == clock_id) {
+ if (cs->bLength < 5 + cs->bNrInPins)
+ return NULL;
return cs;
+ }
}
return NULL;
@@ -75,7 +78,7 @@ static struct uac_clock_multiplier_descriptor *
while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
ctrl_iface->extralen,
cs, UAC2_CLOCK_MULTIPLIER))) {
- if (cs->bClockID == clock_id)
+ if (cs->bLength >= sizeof(*cs) && cs->bClockID == clock_id)
return cs;
}
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 91bc8f18791e..0537c6322990 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -1469,10 +1469,16 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
__u8 *bmaControls;
if (state->mixer->protocol == UAC_VERSION_1) {
+ if (hdr->bLength < 7) {
+ usb_audio_err(state->chip,
+ "unit %u: invalid UAC_FEATURE_UNIT descriptor\n",
+ unitid);
+ return -EINVAL;
+ }
csize = hdr->bControlSize;
- if (!csize) {
+ if (csize <= 1) {
usb_audio_dbg(state->chip,
- "unit %u: invalid bControlSize == 0\n",
+ "unit %u: invalid bControlSize <= 1\n",
unitid);
return -EINVAL;
}
@@ -1486,6 +1492,12 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
}
} else {
struct uac2_feature_unit_descriptor *ftr = _ftr;
+ if (hdr->bLength < 6) {
+ usb_audio_err(state->chip,
+ "unit %u: invalid UAC_FEATURE_UNIT descriptor\n",
+ unitid);
+ return -EINVAL;
+ }
csize = 4;
channels = (hdr->bLength - 6) / 4 - 1;
bmaControls = ftr->bmaControls;
@@ -2086,7 +2098,8 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid,
const struct usbmix_name_map *map;
char **namelist;
- if (!desc->bNrInPins || desc->bLength < 5 + desc->bNrInPins) {
+ if (desc->bLength < 5 || !desc->bNrInPins ||
+ desc->bLength < 5 + desc->bNrInPins) {
usb_audio_err(state->chip,
"invalid SELECTOR UNIT descriptor %d\n", unitid);
return -EINVAL;
@@ -2330,9 +2343,14 @@ void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid)
{
struct usb_mixer_elem_list *list;
- for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem)
+ for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem) {
+ struct usb_mixer_elem_info *info =
+ (struct usb_mixer_elem_info *)list;
+ /* invalidate cache, so the value is read from the device */
+ info->cached = 0;
snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
&list->kctl->id);
+ }
}
static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer,