Skip to content

Commit ed33606

Browse files
charleskeepaxbroonie
authored andcommitted
ASoC: ops: Add control to register value helper
Add a helper function to convert from control values to register values that can replace a lot of the duplicated code in the various put handlers. This also fixes a small issue in snd_soc_put_volsw where the value is converted to a control value before doing the invert, but the invert is done against the register max which will result in incorrect values for inverted controls with a non-zero minimum. Signed-off-by: Charles Keepax <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 1522aac commit ed33606

File tree

1 file changed

+43
-54
lines changed

1 file changed

+43
-54
lines changed

sound/soc/soc-ops.c

Lines changed: 43 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,20 @@ static int soc_mixer_reg_to_ctl(struct soc_mixer_control *mc, unsigned int reg_v
126126
return val & mask;
127127
}
128128

129+
static unsigned int soc_mixer_ctl_to_reg(struct soc_mixer_control *mc, int val,
130+
unsigned int mask, unsigned int shift,
131+
int max)
132+
{
133+
unsigned int reg_val;
134+
135+
if (mc->invert)
136+
val = max - val;
137+
138+
reg_val = val + mc->min;
139+
140+
return (reg_val & mask) << shift;
141+
}
142+
129143
static int soc_mixer_valid_ctl(struct soc_mixer_control *mc, long val, int max)
130144
{
131145
if (val < 0)
@@ -292,43 +306,35 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
292306
(struct soc_mixer_control *)kcontrol->private_value;
293307
unsigned int reg = mc->reg;
294308
unsigned int reg2 = mc->rreg;
295-
unsigned int shift = mc->shift;
296-
unsigned int rshift = mc->rshift;
297-
int max = mc->max;
298-
int min = mc->min;
309+
int max = mc->max - mc->min;
299310
unsigned int mask = soc_mixer_mask(mc);
300-
unsigned int invert = mc->invert;
301311
int err, ret;
302312
bool type_2r = false;
303313
unsigned int val2 = 0;
304314
unsigned int val, val_mask;
305315

306-
ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[0],
307-
mc->max - mc->min);
316+
ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[0], max);
308317
if (ret)
309318
return ret;
310319

311-
val = ucontrol->value.integer.value[0];
312-
val = (val + min) & mask;
313-
if (invert)
314-
val = max - val;
315-
val_mask = mask << shift;
316-
val = val << shift;
320+
val = soc_mixer_ctl_to_reg(mc, ucontrol->value.integer.value[0],
321+
mask, mc->shift, max);
322+
val_mask = mask << mc->shift;
323+
317324
if (snd_soc_volsw_is_stereo(mc)) {
318-
ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[1],
319-
mc->max - mc->min);
325+
ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[1], max);
320326
if (ret)
321327
return ret;
322328

323-
val2 = ucontrol->value.integer.value[1];
324-
val2 = (val2 + min) & mask;
325-
if (invert)
326-
val2 = max - val2;
327329
if (reg == reg2) {
328-
val_mask |= mask << rshift;
329-
val |= val2 << rshift;
330+
val |= soc_mixer_ctl_to_reg(mc,
331+
ucontrol->value.integer.value[1],
332+
mask, mc->rshift, max);
333+
val_mask |= mask << mc->rshift;
330334
} else {
331-
val2 = val2 << shift;
335+
val2 = soc_mixer_ctl_to_reg(mc,
336+
ucontrol->value.integer.value[1],
337+
mask, mc->shift, max);
332338
type_2r = true;
333339
}
334340
}
@@ -404,10 +410,7 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
404410
(struct soc_mixer_control *)kcontrol->private_value;
405411
unsigned int reg = mc->reg;
406412
unsigned int reg2 = mc->rreg;
407-
unsigned int shift = mc->shift;
408-
unsigned int rshift = mc->rshift;
409413
unsigned int val, val_mask;
410-
int min = mc->min;
411414
unsigned int mask = soc_mixer_sx_mask(mc);
412415
int err = 0;
413416
int ret;
@@ -416,31 +419,27 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
416419
if (ret)
417420
return ret;
418421

419-
val = ucontrol->value.integer.value[0];
420-
val_mask = mask << shift;
421-
val = (val + min) & mask;
422-
val = val << shift;
422+
val = soc_mixer_ctl_to_reg(mc, ucontrol->value.integer.value[0],
423+
mask, mc->shift, mc->max);
424+
val_mask = mask << mc->shift;
423425

424426
err = snd_soc_component_update_bits(component, reg, val_mask, val);
425427
if (err < 0)
426428
return err;
427429
ret = err;
428430

429431
if (snd_soc_volsw_is_stereo(mc)) {
430-
unsigned int val2;
431-
432432
ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[1],
433433
mc->max);
434434
if (ret)
435435
return ret;
436436

437-
val2 = ucontrol->value.integer.value[1];
438-
val_mask = mask << rshift;
439-
val2 = (val2 + min) & mask;
440-
val2 = val2 << rshift;
437+
val = soc_mixer_ctl_to_reg(mc, ucontrol->value.integer.value[1],
438+
mask, mc->rshift, mc->max);
439+
val_mask = mask << mc->rshift;
441440

442441
err = snd_soc_component_update_bits(component, reg2, val_mask,
443-
val2);
442+
val);
444443

445444
/* Don't discard any error code or drop change flag */
446445
if (ret == 0 || err < 0)
@@ -498,25 +497,19 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol,
498497
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
499498
unsigned int reg = mc->reg;
500499
unsigned int rreg = mc->rreg;
501-
unsigned int shift = mc->shift;
502-
int min = mc->min;
503-
int max = mc->max;
500+
int max = mc->max - mc->min;
504501
unsigned int mask = soc_mixer_mask(mc);
505-
unsigned int invert = mc->invert;
506-
unsigned int val, val_mask;
502+
unsigned int val_mask = mask << mc->shift;
503+
unsigned int val;
507504
int err, ret;
508505

509506
ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[0],
510507
mc->max - mc->min);
511508
if (ret)
512509
return ret;
513510

514-
if (invert)
515-
val = (max - ucontrol->value.integer.value[0]) & mask;
516-
else
517-
val = ((ucontrol->value.integer.value[0] + min) & mask);
518-
val_mask = mask << shift;
519-
val = val << shift;
511+
val = soc_mixer_ctl_to_reg(mc, ucontrol->value.integer.value[0],
512+
mask, mc->shift, max);
520513

521514
err = snd_soc_component_update_bits(component, reg, val_mask, val);
522515
if (err < 0)
@@ -525,16 +518,12 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol,
525518

526519
if (snd_soc_volsw_is_stereo(mc)) {
527520
ret = soc_mixer_valid_ctl(mc, ucontrol->value.integer.value[1],
528-
mc->max - mc->min);
521+
max);
529522
if (ret)
530523
return ret;
531524

532-
if (invert)
533-
val = (max - ucontrol->value.integer.value[1]) & mask;
534-
else
535-
val = ((ucontrol->value.integer.value[1] + min) & mask);
536-
val_mask = mask << shift;
537-
val = val << shift;
525+
val = soc_mixer_ctl_to_reg(mc, ucontrol->value.integer.value[1],
526+
mask, mc->shift, max);
538527

539528
err = snd_soc_component_update_bits(component, rreg, val_mask,
540529
val);

0 commit comments

Comments
 (0)