Commit 618c2dc6 authored by Mark Brown's avatar Mark Brown

ASoC: ops: Fix stereo change notifications

Merge series from Mark Brown <broonie@kernel.org>:

The event generation coverage I just wrote shows that the generic ASoC
ops fail to generate events for stereo controls when only the first
channel is changed, we just return the status for the second channel and
discard that for the first.
parents 7fa5c33d 2b7c4636
...@@ -308,7 +308,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, ...@@ -308,7 +308,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
unsigned int sign_bit = mc->sign_bit; unsigned int sign_bit = mc->sign_bit;
unsigned int mask = (1 << fls(max)) - 1; unsigned int mask = (1 << fls(max)) - 1;
unsigned int invert = mc->invert; unsigned int invert = mc->invert;
int err; int err, ret;
bool type_2r = false; bool type_2r = false;
unsigned int val2 = 0; unsigned int val2 = 0;
unsigned int val, val_mask; unsigned int val, val_mask;
...@@ -350,12 +350,18 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, ...@@ -350,12 +350,18 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
err = snd_soc_component_update_bits(component, reg, val_mask, val); err = snd_soc_component_update_bits(component, reg, val_mask, val);
if (err < 0) if (err < 0)
return err; return err;
ret = err;
if (type_2r) if (type_2r) {
err = snd_soc_component_update_bits(component, reg2, val_mask, err = snd_soc_component_update_bits(component, reg2, val_mask,
val2); val2);
/* Don't discard any error code or drop change flag */
if (ret == 0 || err < 0) {
ret = err;
}
}
return err; return ret;
} }
EXPORT_SYMBOL_GPL(snd_soc_put_volsw); EXPORT_SYMBOL_GPL(snd_soc_put_volsw);
...@@ -421,6 +427,7 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, ...@@ -421,6 +427,7 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
int min = mc->min; int min = mc->min;
unsigned int mask = (1U << (fls(min + max) - 1)) - 1; unsigned int mask = (1U << (fls(min + max) - 1)) - 1;
int err = 0; int err = 0;
int ret;
unsigned int val, val_mask; unsigned int val, val_mask;
if (ucontrol->value.integer.value[0] < 0) if (ucontrol->value.integer.value[0] < 0)
...@@ -437,6 +444,7 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, ...@@ -437,6 +444,7 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
err = snd_soc_component_update_bits(component, reg, val_mask, val); err = snd_soc_component_update_bits(component, reg, val_mask, val);
if (err < 0) if (err < 0)
return err; return err;
ret = err;
if (snd_soc_volsw_is_stereo(mc)) { if (snd_soc_volsw_is_stereo(mc)) {
unsigned int val2; unsigned int val2;
...@@ -447,6 +455,11 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, ...@@ -447,6 +455,11 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
err = snd_soc_component_update_bits(component, reg2, val_mask, err = snd_soc_component_update_bits(component, reg2, val_mask,
val2); val2);
/* Don't discard any error code or drop change flag */
if (ret == 0 || err < 0) {
ret = err;
}
} }
return err; return err;
} }
...@@ -506,7 +519,7 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, ...@@ -506,7 +519,7 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol,
unsigned int mask = (1 << fls(max)) - 1; unsigned int mask = (1 << fls(max)) - 1;
unsigned int invert = mc->invert; unsigned int invert = mc->invert;
unsigned int val, val_mask; unsigned int val, val_mask;
int ret; int err, ret;
if (invert) if (invert)
val = (max - ucontrol->value.integer.value[0]) & mask; val = (max - ucontrol->value.integer.value[0]) & mask;
...@@ -515,9 +528,10 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, ...@@ -515,9 +528,10 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol,
val_mask = mask << shift; val_mask = mask << shift;
val = val << shift; val = val << shift;
ret = snd_soc_component_update_bits(component, reg, val_mask, val); err = snd_soc_component_update_bits(component, reg, val_mask, val);
if (ret < 0) if (err < 0)
return ret; return err;
ret = err;
if (snd_soc_volsw_is_stereo(mc)) { if (snd_soc_volsw_is_stereo(mc)) {
if (invert) if (invert)
...@@ -527,8 +541,12 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, ...@@ -527,8 +541,12 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol,
val_mask = mask << shift; val_mask = mask << shift;
val = val << 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); val);
/* Don't discard any error code or drop change flag */
if (ret == 0 || err < 0) {
ret = err;
}
} }
return ret; return ret;
...@@ -877,6 +895,7 @@ int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol, ...@@ -877,6 +895,7 @@ int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol,
unsigned long mask = (1UL<<mc->nbits)-1; unsigned long mask = (1UL<<mc->nbits)-1;
long max = mc->max; long max = mc->max;
long val = ucontrol->value.integer.value[0]; long val = ucontrol->value.integer.value[0];
int ret = 0;
unsigned int i; unsigned int i;
if (val < mc->min || val > mc->max) if (val < mc->min || val > mc->max)
...@@ -891,9 +910,11 @@ int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol, ...@@ -891,9 +910,11 @@ int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol,
regmask, regval); regmask, regval);
if (err < 0) if (err < 0)
return err; return err;
if (err > 0)
ret = err;
} }
return 0; return ret;
} }
EXPORT_SYMBOL_GPL(snd_soc_put_xr_sx); EXPORT_SYMBOL_GPL(snd_soc_put_xr_sx);
......
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