diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-24 02:09:41 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-24 02:09:41 -0500 |
commit | b64f26c62dc6e29d98bd72854ac582bb66113331 (patch) | |
tree | 85c4619b2ba0f459d6b36bedbc7741ea8a294107 | |
parent | c353bfc6ebc1073f2f0af72a15f8f18db7193d2e (diff) | |
parent | 9ceace3c9c18c67676e75141032a65a8e01f9a7a (diff) |
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.h | 4 | ||||
-rw-r--r-- | sound/core/pcm_lib.c | 6 | ||||
-rw-r--r-- | sound/core/timer_compat.c | 12 | ||||
-rw-r--r-- | sound/core/vmaster.c | 6 | ||||
-rw-r--r-- | sound/hda/hdmi_chmap.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.c | 10 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 3 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 9 | ||||
-rw-r--r-- | sound/soc/intel/Kconfig | 5 | ||||
-rw-r--r-- | sound/usb/clock.c | 9 | ||||
-rw-r--r-- | sound/usb/mixer.c | 26 |
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, | |||
249 | void snd_ctl_sync_vmaster(struct snd_kcontrol *kctl, bool hook_only); | 249 | void snd_ctl_sync_vmaster(struct snd_kcontrol *kctl, bool hook_only); |
250 | #define snd_ctl_sync_vmaster_hook(kctl) snd_ctl_sync_vmaster(kctl, true) | 250 | #define snd_ctl_sync_vmaster_hook(kctl) snd_ctl_sync_vmaster(kctl, true) |
251 | int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl, | 251 | int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl, |
252 | int (*func)(struct snd_kcontrol *, void *), | 252 | int (*func)(struct snd_kcontrol *vslave, |
253 | struct snd_kcontrol *slave, | ||
254 | void *arg), | ||
253 | void *arg); | 255 | void *arg); |
254 | 256 | ||
255 | /* | 257 | /* |
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, | |||
248 | runtime->rate); | 248 | runtime->rate); |
249 | *audio_tstamp = ns_to_timespec(audio_nsecs); | 249 | *audio_tstamp = ns_to_timespec(audio_nsecs); |
250 | } | 250 | } |
251 | runtime->status->audio_tstamp = *audio_tstamp; | 251 | if (!timespec_equal(&runtime->status->audio_tstamp, audio_tstamp)) { |
252 | runtime->status->tstamp = *curr_tstamp; | 252 | runtime->status->audio_tstamp = *audio_tstamp; |
253 | runtime->status->tstamp = *curr_tstamp; | ||
254 | } | ||
253 | 255 | ||
254 | /* | 256 | /* |
255 | * re-take a driver timestamp to let apps detect if the reference tstamp | 257 | * 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, | |||
66 | struct snd_timer *t; | 66 | struct snd_timer *t; |
67 | 67 | ||
68 | tu = file->private_data; | 68 | tu = file->private_data; |
69 | if (snd_BUG_ON(!tu->timeri)) | 69 | if (!tu->timeri) |
70 | return -ENXIO; | 70 | return -EBADFD; |
71 | t = tu->timeri->timer; | 71 | t = tu->timeri->timer; |
72 | if (snd_BUG_ON(!t)) | 72 | if (!t) |
73 | return -ENXIO; | 73 | return -EBADFD; |
74 | memset(&info, 0, sizeof(info)); | 74 | memset(&info, 0, sizeof(info)); |
75 | info.card = t->card ? t->card->number : -1; | 75 | info.card = t->card ? t->card->number : -1; |
76 | if (t->hw.flags & SNDRV_TIMER_HW_SLAVE) | 76 | if (t->hw.flags & SNDRV_TIMER_HW_SLAVE) |
@@ -99,8 +99,8 @@ static int snd_timer_user_status_compat(struct file *file, | |||
99 | struct snd_timer_status32 status; | 99 | struct snd_timer_status32 status; |
100 | 100 | ||
101 | tu = file->private_data; | 101 | tu = file->private_data; |
102 | if (snd_BUG_ON(!tu->timeri)) | 102 | if (!tu->timeri) |
103 | return -ENXIO; | 103 | return -EBADFD; |
104 | memset(&status, 0, sizeof(status)); | 104 | memset(&status, 0, sizeof(status)); |
105 | status.tstamp.tv_sec = tu->tstamp.tv_sec; | 105 | status.tstamp.tv_sec = tu->tstamp.tv_sec; |
106 | status.tstamp.tv_nsec = tu->tstamp.tv_nsec; | 106 | 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); | |||
495 | * Returns 0 if successful, or a negative error code. | 495 | * Returns 0 if successful, or a negative error code. |
496 | */ | 496 | */ |
497 | int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl, | 497 | int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl, |
498 | int (*func)(struct snd_kcontrol *, void *), | 498 | int (*func)(struct snd_kcontrol *vslave, |
499 | struct snd_kcontrol *slave, | ||
500 | void *arg), | ||
499 | void *arg) | 501 | void *arg) |
500 | { | 502 | { |
501 | struct link_master *master; | 503 | struct link_master *master; |
@@ -507,7 +509,7 @@ int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl, | |||
507 | if (err < 0) | 509 | if (err < 0) |
508 | return err; | 510 | return err; |
509 | list_for_each_entry(slave, &master->slaves, list) { | 511 | list_for_each_entry(slave, &master->slaves, list) { |
510 | err = func(&slave->slave, arg); | 512 | err = func(slave->kctl, &slave->slave, arg); |
511 | if (err < 0) | 513 | if (err < 0) |
512 | return err; | 514 | return err; |
513 | } | 515 | } |
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, | |||
746 | memset(pcm_chmap, 0, sizeof(pcm_chmap)); | 746 | memset(pcm_chmap, 0, sizeof(pcm_chmap)); |
747 | chmap->ops.get_chmap(chmap->hdac, pcm_idx, pcm_chmap); | 747 | chmap->ops.get_chmap(chmap->hdac, pcm_idx, pcm_chmap); |
748 | 748 | ||
749 | for (i = 0; i < sizeof(chmap); i++) | 749 | for (i = 0; i < ARRAY_SIZE(pcm_chmap); i++) |
750 | ucontrol->value.integer.value[i] = pcm_chmap[i]; | 750 | ucontrol->value.integer.value[i] = pcm_chmap[i]; |
751 | 751 | ||
752 | return 0; | 752 | 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 { | |||
1823 | }; | 1823 | }; |
1824 | 1824 | ||
1825 | /* initialize the slave volume with 0dB via snd_ctl_apply_vmaster_slaves() */ | 1825 | /* initialize the slave volume with 0dB via snd_ctl_apply_vmaster_slaves() */ |
1826 | static int init_slave_0dB(struct snd_kcontrol *kctl, void *_arg) | 1826 | static int init_slave_0dB(struct snd_kcontrol *slave, |
1827 | struct snd_kcontrol *kctl, | ||
1828 | void *_arg) | ||
1827 | { | 1829 | { |
1828 | struct slave_init_arg *arg = _arg; | 1830 | struct slave_init_arg *arg = _arg; |
1829 | int _tlv[4]; | 1831 | int _tlv[4]; |
@@ -1860,7 +1862,7 @@ static int init_slave_0dB(struct snd_kcontrol *kctl, void *_arg) | |||
1860 | arg->step = step; | 1862 | arg->step = step; |
1861 | val = -tlv[2] / step; | 1863 | val = -tlv[2] / step; |
1862 | if (val > 0) { | 1864 | if (val > 0) { |
1863 | put_kctl_with_value(kctl, val); | 1865 | put_kctl_with_value(slave, val); |
1864 | return val; | 1866 | return val; |
1865 | } | 1867 | } |
1866 | 1868 | ||
@@ -1868,7 +1870,9 @@ static int init_slave_0dB(struct snd_kcontrol *kctl, void *_arg) | |||
1868 | } | 1870 | } |
1869 | 1871 | ||
1870 | /* unmute the slave via snd_ctl_apply_vmaster_slaves() */ | 1872 | /* unmute the slave via snd_ctl_apply_vmaster_slaves() */ |
1871 | static int init_slave_unmute(struct snd_kcontrol *slave, void *_arg) | 1873 | static int init_slave_unmute(struct snd_kcontrol *slave, |
1874 | struct snd_kcontrol *kctl, | ||
1875 | void *_arg) | ||
1872 | { | 1876 | { |
1873 | return put_kctl_with_value(slave, 1); | 1877 | return put_kctl_with_value(slave, 1); |
1874 | } | 1878 | } |
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[] = { | |||
2463 | /* AMD Hudson */ | 2463 | /* AMD Hudson */ |
2464 | { PCI_DEVICE(0x1022, 0x780d), | 2464 | { PCI_DEVICE(0x1022, 0x780d), |
2465 | .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB }, | 2465 | .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB }, |
2466 | /* AMD Raven */ | ||
2467 | { PCI_DEVICE(0x1022, 0x15e3), | ||
2468 | .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB }, | ||
2466 | /* ATI HDMI */ | 2469 | /* ATI HDMI */ |
2467 | { PCI_DEVICE(0x1002, 0x0002), | 2470 | { PCI_DEVICE(0x1002, 0x0002), |
2468 | .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS }, | 2471 | .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) | |||
341 | case 0x10ec0299: | 341 | case 0x10ec0299: |
342 | alc_update_coef_idx(codec, 0x10, 1<<9, 0); | 342 | alc_update_coef_idx(codec, 0x10, 1<<9, 0); |
343 | break; | 343 | break; |
344 | case 0x10ec0275: | ||
345 | alc_update_coef_idx(codec, 0xe, 0, 1<<0); | ||
346 | break; | ||
344 | case 0x10ec0293: | 347 | case 0x10ec0293: |
345 | alc_update_coef_idx(codec, 0xa, 1<<13, 0); | 348 | alc_update_coef_idx(codec, 0xa, 1<<13, 0); |
346 | break; | 349 | break; |
@@ -6452,6 +6455,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { | |||
6452 | ALC225_STANDARD_PINS, | 6455 | ALC225_STANDARD_PINS, |
6453 | {0x12, 0xb7a60130}, | 6456 | {0x12, 0xb7a60130}, |
6454 | {0x1b, 0x90170110}), | 6457 | {0x1b, 0x90170110}), |
6458 | SND_HDA_PIN_QUIRK(0x10ec0233, 0x8086, "Intel NUC Skull Canyon", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, | ||
6459 | {0x1b, 0x01111010}, | ||
6460 | {0x1e, 0x01451130}, | ||
6461 | {0x21, 0x02211020}), | ||
6455 | SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | 6462 | SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, |
6456 | {0x12, 0x90a60140}, | 6463 | {0x12, 0x90a60140}, |
6457 | {0x14, 0x90170110}, | 6464 | {0x14, 0x90170110}, |
@@ -6887,7 +6894,7 @@ static int patch_alc269(struct hda_codec *codec) | |||
6887 | case 0x10ec0703: | 6894 | case 0x10ec0703: |
6888 | spec->codec_variant = ALC269_TYPE_ALC700; | 6895 | spec->codec_variant = ALC269_TYPE_ALC700; |
6889 | spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */ | 6896 | spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */ |
6890 | alc_update_coef_idx(codec, 0x4a, 0, 1 << 15); /* Combo jack auto trigger control */ | 6897 | alc_update_coef_idx(codec, 0x4a, 1 << 15, 0); /* Combo jack auto trigger control */ |
6891 | break; | 6898 | break; |
6892 | 6899 | ||
6893 | } | 6900 | } |
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 | |||
34 | depends on X86 || COMPILE_TEST | 34 | depends on X86 || COMPILE_TEST |
35 | select SND_SOC_INTEL_MACH | 35 | select SND_SOC_INTEL_MACH |
36 | select SND_SOC_INTEL_COMMON | 36 | select SND_SOC_INTEL_COMMON |
37 | help | ||
38 | Intel ASoC Audio Drivers. If you have a Intel machine that | ||
39 | has audio controller with a DSP and I2S or DMIC port, then | ||
40 | enable this option by saying Y or M | ||
41 | If unsure select "N". | ||
37 | 42 | ||
38 | config SND_SOC_INTEL_HASWELL | 43 | config SND_SOC_INTEL_HASWELL |
39 | tristate "Intel ASoC SST driver for Haswell/Broadwell" | 44 | 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 * | |||
43 | while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, | 43 | while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, |
44 | ctrl_iface->extralen, | 44 | ctrl_iface->extralen, |
45 | cs, UAC2_CLOCK_SOURCE))) { | 45 | cs, UAC2_CLOCK_SOURCE))) { |
46 | if (cs->bClockID == clock_id) | 46 | if (cs->bLength >= sizeof(*cs) && cs->bClockID == clock_id) |
47 | return cs; | 47 | return cs; |
48 | } | 48 | } |
49 | 49 | ||
@@ -59,8 +59,11 @@ static struct uac_clock_selector_descriptor * | |||
59 | while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, | 59 | while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, |
60 | ctrl_iface->extralen, | 60 | ctrl_iface->extralen, |
61 | cs, UAC2_CLOCK_SELECTOR))) { | 61 | cs, UAC2_CLOCK_SELECTOR))) { |
62 | if (cs->bClockID == clock_id) | 62 | if (cs->bLength >= sizeof(*cs) && cs->bClockID == clock_id) { |
63 | if (cs->bLength < 5 + cs->bNrInPins) | ||
64 | return NULL; | ||
63 | return cs; | 65 | return cs; |
66 | } | ||
64 | } | 67 | } |
65 | 68 | ||
66 | return NULL; | 69 | return NULL; |
@@ -75,7 +78,7 @@ static struct uac_clock_multiplier_descriptor * | |||
75 | while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, | 78 | while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra, |
76 | ctrl_iface->extralen, | 79 | ctrl_iface->extralen, |
77 | cs, UAC2_CLOCK_MULTIPLIER))) { | 80 | cs, UAC2_CLOCK_MULTIPLIER))) { |
78 | if (cs->bClockID == clock_id) | 81 | if (cs->bLength >= sizeof(*cs) && cs->bClockID == clock_id) |
79 | return cs; | 82 | return cs; |
80 | } | 83 | } |
81 | 84 | ||
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, | |||
1469 | __u8 *bmaControls; | 1469 | __u8 *bmaControls; |
1470 | 1470 | ||
1471 | if (state->mixer->protocol == UAC_VERSION_1) { | 1471 | if (state->mixer->protocol == UAC_VERSION_1) { |
1472 | if (hdr->bLength < 7) { | ||
1473 | usb_audio_err(state->chip, | ||
1474 | "unit %u: invalid UAC_FEATURE_UNIT descriptor\n", | ||
1475 | unitid); | ||
1476 | return -EINVAL; | ||
1477 | } | ||
1472 | csize = hdr->bControlSize; | 1478 | csize = hdr->bControlSize; |
1473 | if (!csize) { | 1479 | if (csize <= 1) { |
1474 | usb_audio_dbg(state->chip, | 1480 | usb_audio_dbg(state->chip, |
1475 | "unit %u: invalid bControlSize == 0\n", | 1481 | "unit %u: invalid bControlSize <= 1\n", |
1476 | unitid); | 1482 | unitid); |
1477 | return -EINVAL; | 1483 | return -EINVAL; |
1478 | } | 1484 | } |
@@ -1486,6 +1492,12 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, | |||
1486 | } | 1492 | } |
1487 | } else { | 1493 | } else { |
1488 | struct uac2_feature_unit_descriptor *ftr = _ftr; | 1494 | struct uac2_feature_unit_descriptor *ftr = _ftr; |
1495 | if (hdr->bLength < 6) { | ||
1496 | usb_audio_err(state->chip, | ||
1497 | "unit %u: invalid UAC_FEATURE_UNIT descriptor\n", | ||
1498 | unitid); | ||
1499 | return -EINVAL; | ||
1500 | } | ||
1489 | csize = 4; | 1501 | csize = 4; |
1490 | channels = (hdr->bLength - 6) / 4 - 1; | 1502 | channels = (hdr->bLength - 6) / 4 - 1; |
1491 | bmaControls = ftr->bmaControls; | 1503 | bmaControls = ftr->bmaControls; |
@@ -2086,7 +2098,8 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, | |||
2086 | const struct usbmix_name_map *map; | 2098 | const struct usbmix_name_map *map; |
2087 | char **namelist; | 2099 | char **namelist; |
2088 | 2100 | ||
2089 | if (!desc->bNrInPins || desc->bLength < 5 + desc->bNrInPins) { | 2101 | if (desc->bLength < 5 || !desc->bNrInPins || |
2102 | desc->bLength < 5 + desc->bNrInPins) { | ||
2090 | usb_audio_err(state->chip, | 2103 | usb_audio_err(state->chip, |
2091 | "invalid SELECTOR UNIT descriptor %d\n", unitid); | 2104 | "invalid SELECTOR UNIT descriptor %d\n", unitid); |
2092 | return -EINVAL; | 2105 | return -EINVAL; |
@@ -2330,9 +2343,14 @@ void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid) | |||
2330 | { | 2343 | { |
2331 | struct usb_mixer_elem_list *list; | 2344 | struct usb_mixer_elem_list *list; |
2332 | 2345 | ||
2333 | for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem) | 2346 | for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem) { |
2347 | struct usb_mixer_elem_info *info = | ||
2348 | (struct usb_mixer_elem_info *)list; | ||
2349 | /* invalidate cache, so the value is read from the device */ | ||
2350 | info->cached = 0; | ||
2334 | snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE, | 2351 | snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE, |
2335 | &list->kctl->id); | 2352 | &list->kctl->id); |
2353 | } | ||
2336 | } | 2354 | } |
2337 | 2355 | ||
2338 | static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer, | 2356 | static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer, |