Skip to content

Commit 618c2dc

Browse files
committed
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.
2 parents 7fa5c33 + 2b7c463 commit 618c2dc

1 file changed

Lines changed: 31 additions & 10 deletions

File tree

sound/soc/soc-ops.c

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
308308
unsigned int sign_bit = mc->sign_bit;
309309
unsigned int mask = (1 << fls(max)) - 1;
310310
unsigned int invert = mc->invert;
311-
int err;
311+
int err, ret;
312312
bool type_2r = false;
313313
unsigned int val2 = 0;
314314
unsigned int val, val_mask;
@@ -350,12 +350,18 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
350350
err = snd_soc_component_update_bits(component, reg, val_mask, val);
351351
if (err < 0)
352352
return err;
353+
ret = err;
353354

354-
if (type_2r)
355+
if (type_2r) {
355356
err = snd_soc_component_update_bits(component, reg2, val_mask,
356-
val2);
357+
val2);
358+
/* Don't discard any error code or drop change flag */
359+
if (ret == 0 || err < 0) {
360+
ret = err;
361+
}
362+
}
357363

358-
return err;
364+
return ret;
359365
}
360366
EXPORT_SYMBOL_GPL(snd_soc_put_volsw);
361367

@@ -421,6 +427,7 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
421427
int min = mc->min;
422428
unsigned int mask = (1U << (fls(min + max) - 1)) - 1;
423429
int err = 0;
430+
int ret;
424431
unsigned int val, val_mask;
425432

426433
if (ucontrol->value.integer.value[0] < 0)
@@ -437,6 +444,7 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
437444
err = snd_soc_component_update_bits(component, reg, val_mask, val);
438445
if (err < 0)
439446
return err;
447+
ret = err;
440448

441449
if (snd_soc_volsw_is_stereo(mc)) {
442450
unsigned int val2;
@@ -447,6 +455,11 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
447455

448456
err = snd_soc_component_update_bits(component, reg2, val_mask,
449457
val2);
458+
459+
/* Don't discard any error code or drop change flag */
460+
if (ret == 0 || err < 0) {
461+
ret = err;
462+
}
450463
}
451464
return err;
452465
}
@@ -506,7 +519,7 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol,
506519
unsigned int mask = (1 << fls(max)) - 1;
507520
unsigned int invert = mc->invert;
508521
unsigned int val, val_mask;
509-
int ret;
522+
int err, ret;
510523

511524
if (invert)
512525
val = (max - ucontrol->value.integer.value[0]) & mask;
@@ -515,9 +528,10 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol,
515528
val_mask = mask << shift;
516529
val = val << shift;
517530

518-
ret = snd_soc_component_update_bits(component, reg, val_mask, val);
519-
if (ret < 0)
520-
return ret;
531+
err = snd_soc_component_update_bits(component, reg, val_mask, val);
532+
if (err < 0)
533+
return err;
534+
ret = err;
521535

522536
if (snd_soc_volsw_is_stereo(mc)) {
523537
if (invert)
@@ -527,8 +541,12 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol,
527541
val_mask = mask << shift;
528542
val = val << shift;
529543

530-
ret = snd_soc_component_update_bits(component, rreg, val_mask,
544+
err = snd_soc_component_update_bits(component, rreg, val_mask,
531545
val);
546+
/* Don't discard any error code or drop change flag */
547+
if (ret == 0 || err < 0) {
548+
ret = err;
549+
}
532550
}
533551

534552
return ret;
@@ -877,6 +895,7 @@ int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol,
877895
unsigned long mask = (1UL<<mc->nbits)-1;
878896
long max = mc->max;
879897
long val = ucontrol->value.integer.value[0];
898+
int ret = 0;
880899
unsigned int i;
881900

882901
if (val < mc->min || val > mc->max)
@@ -891,9 +910,11 @@ int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol,
891910
regmask, regval);
892911
if (err < 0)
893912
return err;
913+
if (err > 0)
914+
ret = err;
894915
}
895916

896-
return 0;
917+
return ret;
897918
}
898919
EXPORT_SYMBOL_GPL(snd_soc_put_xr_sx);
899920

0 commit comments

Comments
 (0)