Commit b64f26c6 authored by Linus Torvalds's avatar Linus Torvalds

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
parents c353bfc6 9ceace3c
...@@ -249,7 +249,9 @@ int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kctl, ...@@ -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); 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) #define snd_ctl_sync_vmaster_hook(kctl) snd_ctl_sync_vmaster(kctl, true)
int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl, 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); void *arg);
/* /*
......
...@@ -248,8 +248,10 @@ static void update_audio_tstamp(struct snd_pcm_substream *substream, ...@@ -248,8 +248,10 @@ static void update_audio_tstamp(struct snd_pcm_substream *substream,
runtime->rate); runtime->rate);
*audio_tstamp = ns_to_timespec(audio_nsecs); *audio_tstamp = ns_to_timespec(audio_nsecs);
} }
runtime->status->audio_tstamp = *audio_tstamp; if (!timespec_equal(&runtime->status->audio_tstamp, audio_tstamp)) {
runtime->status->tstamp = *curr_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 * re-take a driver timestamp to let apps detect if the reference tstamp
......
...@@ -66,11 +66,11 @@ static int snd_timer_user_info_compat(struct file *file, ...@@ -66,11 +66,11 @@ static int snd_timer_user_info_compat(struct file *file,
struct snd_timer *t; struct snd_timer *t;
tu = file->private_data; tu = file->private_data;
if (snd_BUG_ON(!tu->timeri)) if (!tu->timeri)
return -ENXIO; return -EBADFD;
t = tu->timeri->timer; t = tu->timeri->timer;
if (snd_BUG_ON(!t)) if (!t)
return -ENXIO; return -EBADFD;
memset(&info, 0, sizeof(info)); memset(&info, 0, sizeof(info));
info.card = t->card ? t->card->number : -1; info.card = t->card ? t->card->number : -1;
if (t->hw.flags & SNDRV_TIMER_HW_SLAVE) if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
...@@ -99,8 +99,8 @@ static int snd_timer_user_status_compat(struct file *file, ...@@ -99,8 +99,8 @@ static int snd_timer_user_status_compat(struct file *file,
struct snd_timer_status32 status; struct snd_timer_status32 status;
tu = file->private_data; tu = file->private_data;
if (snd_BUG_ON(!tu->timeri)) if (!tu->timeri)
return -ENXIO; return -EBADFD;
memset(&status, 0, sizeof(status)); memset(&status, 0, sizeof(status));
status.tstamp.tv_sec = tu->tstamp.tv_sec; status.tstamp.tv_sec = tu->tstamp.tv_sec;
status.tstamp.tv_nsec = tu->tstamp.tv_nsec; status.tstamp.tv_nsec = tu->tstamp.tv_nsec;
......
...@@ -495,7 +495,9 @@ EXPORT_SYMBOL_GPL(snd_ctl_sync_vmaster); ...@@ -495,7 +495,9 @@ EXPORT_SYMBOL_GPL(snd_ctl_sync_vmaster);
* Returns 0 if successful, or a negative error code. * Returns 0 if successful, or a negative error code.
*/ */
int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl, 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) void *arg)
{ {
struct link_master *master; struct link_master *master;
...@@ -507,7 +509,7 @@ int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl, ...@@ -507,7 +509,7 @@ int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl,
if (err < 0) if (err < 0)
return err; return err;
list_for_each_entry(slave, &master->slaves, list) { list_for_each_entry(slave, &master->slaves, list) {
err = func(&slave->slave, arg); err = func(slave->kctl, &slave->slave, arg);
if (err < 0) if (err < 0)
return err; return err;
} }
......
...@@ -746,7 +746,7 @@ static int hdmi_chmap_ctl_get(struct snd_kcontrol *kcontrol, ...@@ -746,7 +746,7 @@ static int hdmi_chmap_ctl_get(struct snd_kcontrol *kcontrol,
memset(pcm_chmap, 0, sizeof(pcm_chmap)); memset(pcm_chmap, 0, sizeof(pcm_chmap));
chmap->ops.get_chmap(chmap->hdac, pcm_idx, 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]; ucontrol->value.integer.value[i] = pcm_chmap[i];
return 0; return 0;
......
...@@ -1823,7 +1823,9 @@ struct slave_init_arg { ...@@ -1823,7 +1823,9 @@ struct slave_init_arg {
}; };
/* initialize the slave volume with 0dB via snd_ctl_apply_vmaster_slaves() */ /* 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; struct slave_init_arg *arg = _arg;
int _tlv[4]; int _tlv[4];
...@@ -1860,7 +1862,7 @@ static int init_slave_0dB(struct snd_kcontrol *kctl, void *_arg) ...@@ -1860,7 +1862,7 @@ static int init_slave_0dB(struct snd_kcontrol *kctl, void *_arg)
arg->step = step; arg->step = step;
val = -tlv[2] / step; val = -tlv[2] / step;
if (val > 0) { if (val > 0) {
put_kctl_with_value(kctl, val); put_kctl_with_value(slave, val);
return val; return val;
} }
...@@ -1868,7 +1870,9 @@ static int init_slave_0dB(struct snd_kcontrol *kctl, void *_arg) ...@@ -1868,7 +1870,9 @@ static int init_slave_0dB(struct snd_kcontrol *kctl, void *_arg)
} }
/* unmute the slave via snd_ctl_apply_vmaster_slaves() */ /* 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); return put_kctl_with_value(slave, 1);
} }
......
...@@ -2463,6 +2463,9 @@ static const struct pci_device_id azx_ids[] = { ...@@ -2463,6 +2463,9 @@ static const struct pci_device_id azx_ids[] = {
/* AMD Hudson */ /* AMD Hudson */
{ PCI_DEVICE(0x1022, 0x780d), { PCI_DEVICE(0x1022, 0x780d),
.driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB }, .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 */ /* ATI HDMI */
{ PCI_DEVICE(0x1002, 0x0002), { PCI_DEVICE(0x1002, 0x0002),
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS }, .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
......
...@@ -341,6 +341,9 @@ static void alc_fill_eapd_coef(struct hda_codec *codec) ...@@ -341,6 +341,9 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
case 0x10ec0299: case 0x10ec0299:
alc_update_coef_idx(codec, 0x10, 1<<9, 0); alc_update_coef_idx(codec, 0x10, 1<<9, 0);
break; break;
case 0x10ec0275:
alc_update_coef_idx(codec, 0xe, 0, 1<<0);
break;
case 0x10ec0293: case 0x10ec0293:
alc_update_coef_idx(codec, 0xa, 1<<13, 0); alc_update_coef_idx(codec, 0xa, 1<<13, 0);
break; break;
...@@ -6452,6 +6455,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { ...@@ -6452,6 +6455,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
ALC225_STANDARD_PINS, ALC225_STANDARD_PINS,
{0x12, 0xb7a60130}, {0x12, 0xb7a60130},
{0x1b, 0x90170110}), {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, SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
{0x12, 0x90a60140}, {0x12, 0x90a60140},
{0x14, 0x90170110}, {0x14, 0x90170110},
...@@ -6887,7 +6894,7 @@ static int patch_alc269(struct hda_codec *codec) ...@@ -6887,7 +6894,7 @@ static int patch_alc269(struct hda_codec *codec)
case 0x10ec0703: case 0x10ec0703:
spec->codec_variant = ALC269_TYPE_ALC700; spec->codec_variant = ALC269_TYPE_ALC700;
spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */ 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; break;
} }
......
...@@ -34,6 +34,11 @@ config SND_SOC_INTEL_SST_TOPLEVEL ...@@ -34,6 +34,11 @@ config SND_SOC_INTEL_SST_TOPLEVEL
depends on X86 || COMPILE_TEST depends on X86 || COMPILE_TEST
select SND_SOC_INTEL_MACH select SND_SOC_INTEL_MACH
select SND_SOC_INTEL_COMMON 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 config SND_SOC_INTEL_HASWELL
tristate "Intel ASoC SST driver for Haswell/Broadwell" tristate "Intel ASoC SST driver for Haswell/Broadwell"
......
...@@ -43,7 +43,7 @@ static struct uac_clock_source_descriptor * ...@@ -43,7 +43,7 @@ static struct uac_clock_source_descriptor *
while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
ctrl_iface->extralen, ctrl_iface->extralen,
cs, UAC2_CLOCK_SOURCE))) { cs, UAC2_CLOCK_SOURCE))) {
if (cs->bClockID == clock_id) if (cs->bLength >= sizeof(*cs) && cs->bClockID == clock_id)
return cs; return cs;
} }
...@@ -59,8 +59,11 @@ static struct uac_clock_selector_descriptor * ...@@ -59,8 +59,11 @@ static struct uac_clock_selector_descriptor *
while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
ctrl_iface->extralen, ctrl_iface->extralen,
cs, UAC2_CLOCK_SELECTOR))) { 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 cs;
}
} }
return NULL; return NULL;
...@@ -75,7 +78,7 @@ static struct uac_clock_multiplier_descriptor * ...@@ -75,7 +78,7 @@ static struct uac_clock_multiplier_descriptor *
while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
ctrl_iface->extralen, ctrl_iface->extralen,
cs, UAC2_CLOCK_MULTIPLIER))) { cs, UAC2_CLOCK_MULTIPLIER))) {
if (cs->bClockID == clock_id) if (cs->bLength >= sizeof(*cs) && cs->bClockID == clock_id)
return cs; return cs;
} }
......
...@@ -1469,10 +1469,16 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, ...@@ -1469,10 +1469,16 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
__u8 *bmaControls; __u8 *bmaControls;
if (state->mixer->protocol == UAC_VERSION_1) { 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; csize = hdr->bControlSize;
if (!csize) { if (csize <= 1) {
usb_audio_dbg(state->chip, usb_audio_dbg(state->chip,
"unit %u: invalid bControlSize == 0\n", "unit %u: invalid bControlSize <= 1\n",
unitid); unitid);
return -EINVAL; return -EINVAL;
} }
...@@ -1486,6 +1492,12 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, ...@@ -1486,6 +1492,12 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
} }
} else { } else {
struct uac2_feature_unit_descriptor *ftr = _ftr; 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; csize = 4;
channels = (hdr->bLength - 6) / 4 - 1; channels = (hdr->bLength - 6) / 4 - 1;
bmaControls = ftr->bmaControls; bmaControls = ftr->bmaControls;
...@@ -2086,7 +2098,8 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, ...@@ -2086,7 +2098,8 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid,
const struct usbmix_name_map *map; const struct usbmix_name_map *map;
char **namelist; 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, usb_audio_err(state->chip,
"invalid SELECTOR UNIT descriptor %d\n", unitid); "invalid SELECTOR UNIT descriptor %d\n", unitid);
return -EINVAL; return -EINVAL;
...@@ -2330,9 +2343,14 @@ void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid) ...@@ -2330,9 +2343,14 @@ void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid)
{ {
struct usb_mixer_elem_list *list; 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, snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
&list->kctl->id); &list->kctl->id);
}
} }
static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer, static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment