| From 650204ded3703b5817bd4b6a77fa47d333c4f902 Mon Sep 17 00:00:00 2001 |
| From: Mark Brown <broonie@kernel.org> |
| Date: Tue, 1 Feb 2022 15:56:28 +0000 |
| Subject: ASoC: ops: Fix stereo change notifications in snd_soc_put_volsw_range() |
| |
| From: Mark Brown <broonie@kernel.org> |
| |
| commit 650204ded3703b5817bd4b6a77fa47d333c4f902 upstream. |
| |
| When writing out a stereo control we discard the change notification from |
| the first channel, meaning that events are only generated based on changes |
| to the second channel. Ensure that we report a change if either channel |
| has changed. |
| |
| Signed-off-by: Mark Brown <broonie@kernel.org> |
| Cc: stable@vger.kernel.org |
| Link: https://lore.kernel.org/r/20220201155629.120510-4-broonie@kernel.org |
| Signed-off-by: Mark Brown <broonie@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| sound/soc/soc-ops.c | 15 ++++++++++----- |
| 1 file changed, 10 insertions(+), 5 deletions(-) |
| |
| --- a/sound/soc/soc-ops.c |
| +++ b/sound/soc/soc-ops.c |
| @@ -523,7 +523,7 @@ int snd_soc_put_volsw_range(struct snd_k |
| unsigned int mask = (1 << fls(max)) - 1; |
| unsigned int invert = mc->invert; |
| unsigned int val, val_mask; |
| - int ret; |
| + int err, ret; |
| |
| if (invert) |
| val = (max - ucontrol->value.integer.value[0]) & mask; |
| @@ -532,9 +532,10 @@ int snd_soc_put_volsw_range(struct snd_k |
| val_mask = mask << shift; |
| val = val << shift; |
| |
| - ret = snd_soc_component_update_bits(component, reg, val_mask, val); |
| - if (ret < 0) |
| - return ret; |
| + err = snd_soc_component_update_bits(component, reg, val_mask, val); |
| + if (err < 0) |
| + return err; |
| + ret = err; |
| |
| if (snd_soc_volsw_is_stereo(mc)) { |
| if (invert) |
| @@ -544,8 +545,12 @@ int snd_soc_put_volsw_range(struct snd_k |
| val_mask = mask << shift; |
| val = val << shift; |
| |
| - ret = snd_soc_component_update_bits(component, rreg, val_mask, |
| + err = snd_soc_component_update_bits(component, rreg, val_mask, |
| val); |
| + /* Don't discard any error code or drop change flag */ |
| + if (ret == 0 || err < 0) { |
| + ret = err; |
| + } |
| } |
| |
| return ret; |