Skip to content

Commit

Permalink
ASoC: Avoid recalculating the bitmask for SOC_ENUM controls
Browse files Browse the repository at this point in the history
For ENUM controls the bitmask is calculated based on the number of items.
Currently this is done each time the control is accessed. And while the
performance impact of this should be negligible we can easily do better. The
roundup_pow_of_two macro performs the same calculation which is currently done
manually, but it is also possible to use this macro with compile time constants
and so it can be used to initialize static data. So we can use it to initialize
the mask field of a ENUM control during its declaration.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Acked-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
  • Loading branch information
Lars-Peter Clausen authored and Mark Brown committed Sep 19, 2012
1 parent 4c2474c commit 86767b7
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 30 deletions.
4 changes: 3 additions & 1 deletion include/sound/soc.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/regmap.h>
#include <linux/log2.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/compress_driver.h>
Expand Down Expand Up @@ -160,7 +161,8 @@
.platform_max = xmax} }
#define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmax, xtexts) \
{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
.max = xmax, .texts = xtexts }
.max = xmax, .texts = xtexts, \
.mask = xmax ? roundup_pow_of_two(xmax) - 1 : 0}
#define SOC_ENUM_SINGLE(xreg, xshift, xmax, xtexts) \
SOC_ENUM_DOUBLE(xreg, xshift, xshift, xmax, xtexts)
#define SOC_ENUM_SINGLE_EXT(xmax, xtexts) \
Expand Down
8 changes: 3 additions & 5 deletions sound/soc/codecs/twl4030.c
Original file line number Diff line number Diff line change
Expand Up @@ -999,26 +999,24 @@ static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol,
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned short val;
unsigned short mask, bitmask;
unsigned short mask;

if (twl4030->configured) {
dev_err(codec->dev,
"operation mode cannot be changed on-the-fly\n");
return -EBUSY;
}

for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
;
if (ucontrol->value.enumerated.item[0] > e->max - 1)
return -EINVAL;

val = ucontrol->value.enumerated.item[0] << e->shift_l;
mask = (bitmask - 1) << e->shift_l;
mask = e->mask << e->shift_l;
if (e->shift_l != e->shift_r) {
if (ucontrol->value.enumerated.item[1] > e->max - 1)
return -EINVAL;
val |= ucontrol->value.enumerated.item[1] << e->shift_r;
mask |= (bitmask - 1) << e->shift_r;
mask |= e->mask << e->shift_r;
}

return snd_soc_update_bits(codec, e->reg, mask, val);
Expand Down
16 changes: 6 additions & 10 deletions sound/soc/soc-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2413,16 +2413,14 @@ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int val, bitmask;
unsigned int val;

for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
;
val = snd_soc_read(codec, e->reg);
ucontrol->value.enumerated.item[0]
= (val >> e->shift_l) & (bitmask - 1);
= (val >> e->shift_l) & e->mask;
if (e->shift_l != e->shift_r)
ucontrol->value.enumerated.item[1] =
(val >> e->shift_r) & (bitmask - 1);
(val >> e->shift_r) & e->mask;

return 0;
}
Expand All @@ -2443,19 +2441,17 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int val;
unsigned int mask, bitmask;
unsigned int mask;

for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
;
if (ucontrol->value.enumerated.item[0] > e->max - 1)
return -EINVAL;
val = ucontrol->value.enumerated.item[0] << e->shift_l;
mask = (bitmask - 1) << e->shift_l;
mask = e->mask << e->shift_l;
if (e->shift_l != e->shift_r) {
if (ucontrol->value.enumerated.item[1] > e->max - 1)
return -EINVAL;
val |= ucontrol->value.enumerated.item[1] << e->shift_r;
mask |= (bitmask - 1) << e->shift_r;
mask |= e->mask << e->shift_r;
}

return snd_soc_update_bits_locked(codec, e->reg, mask, val);
Expand Down
22 changes: 8 additions & 14 deletions sound/soc/soc-dapm.c
Original file line number Diff line number Diff line change
Expand Up @@ -355,12 +355,10 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
case snd_soc_dapm_mux: {
struct soc_enum *e = (struct soc_enum *)
w->kcontrol_news[i].private_value;
int val, item, bitmask;
int val, item;

for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
;
val = soc_widget_read(w, e->reg);
item = (val >> e->shift_l) & (bitmask - 1);
item = (val >> e->shift_l) & e->mask;

p->connect = 0;
for (i = 0; i < e->max; i++) {
Expand Down Expand Up @@ -2677,15 +2675,13 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
struct snd_soc_dapm_widget *widget = wlist->widgets[0];
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int val, bitmask;
unsigned int val;

for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
;
val = snd_soc_read(widget->codec, e->reg);
ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (bitmask - 1);
ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & e->mask;
if (e->shift_l != e->shift_r)
ucontrol->value.enumerated.item[1] =
(val >> e->shift_r) & (bitmask - 1);
(val >> e->shift_r) & e->mask;

return 0;
}
Expand All @@ -2709,22 +2705,20 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
struct snd_soc_card *card = codec->card;
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int val, mux, change;
unsigned int mask, bitmask;
unsigned int mask;
struct snd_soc_dapm_update update;
int wi;

for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
;
if (ucontrol->value.enumerated.item[0] > e->max - 1)
return -EINVAL;
mux = ucontrol->value.enumerated.item[0];
val = mux << e->shift_l;
mask = (bitmask - 1) << e->shift_l;
mask = e->mask << e->shift_l;
if (e->shift_l != e->shift_r) {
if (ucontrol->value.enumerated.item[1] > e->max - 1)
return -EINVAL;
val |= ucontrol->value.enumerated.item[1] << e->shift_r;
mask |= (bitmask - 1) << e->shift_r;
mask |= e->mask << e->shift_r;
}

mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
Expand Down

0 comments on commit 86767b7

Please sign in to comment.