Skip to content

Commit 318e879

Browse files
charleskeepaxbroonie
authored andcommitted
ASoC: ops: Factor out common code from put callbacks
There are only two differences between snd_soc_put_volsw() and snd_soc_put_volsw_sx(). The maximum field is handled differently, and snd_soc_put_volsw() supports double controls with both values in the same register. Factor out the common code into a new helper and pass in the appropriate max value such that it is handled correctly for each control. Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Link: https://patch.msgid.link/20250318171459.3203730-13-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 9dfcafe commit 318e879

File tree

1 file changed

+53
-85
lines changed

1 file changed

+53
-85
lines changed

sound/soc/soc-ops.c

Lines changed: 53 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,57 @@ static int soc_info_volsw(struct snd_kcontrol *kcontrol,
192192
return 0;
193193
}
194194

195+
static int soc_put_volsw(struct snd_kcontrol *kcontrol,
196+
struct snd_ctl_elem_value *ucontrol,
197+
struct soc_mixer_control *mc, int mask, int max)
198+
{
199+
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
200+
unsigned int val1, val_mask;
201+
unsigned int val2 = 0;
202+
bool double_r = false;
203+
int ret;
204+
205+
ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[0], max);
206+
if (ret)
207+
return ret;
208+
209+
val1 = soc_mixer_ctl_to_reg(mc, ucontrol->value.integer.value[0],
210+
mask, mc->shift, max);
211+
val_mask = mask << mc->shift;
212+
213+
if (snd_soc_volsw_is_stereo(mc)) {
214+
ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[1], max);
215+
if (ret)
216+
return ret;
217+
218+
if (mc->reg == mc->rreg) {
219+
val1 |= soc_mixer_ctl_to_reg(mc,
220+
ucontrol->value.integer.value[1],
221+
mask, mc->rshift, max);
222+
val_mask |= mask << mc->rshift;
223+
} else {
224+
val2 = soc_mixer_ctl_to_reg(mc,
225+
ucontrol->value.integer.value[1],
226+
mask, mc->shift, max);
227+
double_r = true;
228+
}
229+
}
230+
231+
ret = snd_soc_component_update_bits(component, mc->reg, val_mask, val1);
232+
if (ret < 0)
233+
return ret;
234+
235+
if (double_r) {
236+
int err = snd_soc_component_update_bits(component, mc->rreg,
237+
val_mask, val2);
238+
/* Don't drop change flag */
239+
if (err)
240+
return err;
241+
}
242+
243+
return ret;
244+
}
245+
195246
/**
196247
* snd_soc_info_volsw - single mixer info callback with range.
197248
* @kcontrol: mixer control
@@ -289,57 +340,11 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw);
289340
int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
290341
struct snd_ctl_elem_value *ucontrol)
291342
{
292-
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
293343
struct soc_mixer_control *mc =
294344
(struct soc_mixer_control *)kcontrol->private_value;
295-
unsigned int reg = mc->reg;
296-
unsigned int reg2 = mc->rreg;
297-
int max = mc->max - mc->min;
298345
unsigned int mask = soc_mixer_mask(mc);
299-
int err, ret;
300-
bool type_2r = false;
301-
unsigned int val2 = 0;
302-
unsigned int val, val_mask;
303346

304-
ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[0], max);
305-
if (ret)
306-
return ret;
307-
308-
val = soc_mixer_ctl_to_reg(mc, ucontrol->value.integer.value[0],
309-
mask, mc->shift, max);
310-
val_mask = mask << mc->shift;
311-
312-
if (snd_soc_volsw_is_stereo(mc)) {
313-
ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[1], max);
314-
if (ret)
315-
return ret;
316-
317-
if (reg == reg2) {
318-
val |= soc_mixer_ctl_to_reg(mc,
319-
ucontrol->value.integer.value[1],
320-
mask, mc->rshift, max);
321-
val_mask |= mask << mc->rshift;
322-
} else {
323-
val2 = soc_mixer_ctl_to_reg(mc,
324-
ucontrol->value.integer.value[1],
325-
mask, mc->shift, max);
326-
type_2r = true;
327-
}
328-
}
329-
err = snd_soc_component_update_bits(component, reg, val_mask, val);
330-
if (err < 0)
331-
return err;
332-
ret = err;
333-
334-
if (type_2r) {
335-
err = snd_soc_component_update_bits(component, reg2, val_mask,
336-
val2);
337-
/* Don't discard any error code or drop change flag */
338-
if (ret == 0 || err < 0)
339-
ret = err;
340-
}
341-
342-
return ret;
347+
return soc_put_volsw(kcontrol, ucontrol, mc, mask, mc->max - mc->min);
343348
}
344349
EXPORT_SYMBOL_GPL(snd_soc_put_volsw);
345350

@@ -393,48 +398,11 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw_sx);
393398
int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
394399
struct snd_ctl_elem_value *ucontrol)
395400
{
396-
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
397401
struct soc_mixer_control *mc =
398402
(struct soc_mixer_control *)kcontrol->private_value;
399-
unsigned int reg = mc->reg;
400-
unsigned int reg2 = mc->rreg;
401-
unsigned int val, val_mask;
402403
unsigned int mask = soc_mixer_sx_mask(mc);
403-
int err = 0;
404-
int ret;
405-
406-
ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[0], mc->max);
407-
if (ret)
408-
return ret;
409-
410-
val = soc_mixer_ctl_to_reg(mc, ucontrol->value.integer.value[0],
411-
mask, mc->shift, mc->max);
412-
val_mask = mask << mc->shift;
413-
414-
err = snd_soc_component_update_bits(component, reg, val_mask, val);
415-
if (err < 0)
416-
return err;
417-
ret = err;
418404

419-
if (snd_soc_volsw_is_stereo(mc)) {
420-
ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[1],
421-
mc->max);
422-
if (ret)
423-
return ret;
424-
425-
val = soc_mixer_ctl_to_reg(mc, ucontrol->value.integer.value[1],
426-
mask, mc->rshift, mc->max);
427-
val_mask = mask << mc->rshift;
428-
429-
err = snd_soc_component_update_bits(component, reg2, val_mask,
430-
val);
431-
432-
/* Don't discard any error code or drop change flag */
433-
if (ret == 0 || err < 0)
434-
ret = err;
435-
}
436-
437-
return ret;
405+
return soc_put_volsw(kcontrol, ucontrol, mc, mask, mc->max);
438406
}
439407
EXPORT_SYMBOL_GPL(snd_soc_put_volsw_sx);
440408

0 commit comments

Comments
 (0)