From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
DVC controls some digital volume features. Some of them requests values for "each channels", but, some of them requests values for "feature". Current dvc.c is supporting Mute/Volume, and these have "each channels" settings. This patch adds rsnd_dvc_cfg_m and care about multiple settings for each channels.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/sh/rcar/dvc.c | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-)
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 2fbaf27..e4dd1d8 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -17,6 +17,12 @@
struct rsnd_dvc_cfg { unsigned int max; + unsigned int size; + u32 *val; +}; + +struct rsnd_dvc_cfg_m { + struct rsnd_dvc_cfg cfg; u32 val[RSND_DVC_CHANNELS]; };
@@ -24,8 +30,8 @@ struct rsnd_dvc { struct rsnd_dvc_platform_info *info; /* rcar_snd.h */ struct rsnd_mod mod; struct clk *clk; - struct rsnd_dvc_cfg volume; - struct rsnd_dvc_cfg mute; + struct rsnd_dvc_cfg_m volume; + struct rsnd_dvc_cfg_m mute; };
#define rsnd_mod_to_dvc(_mod) \ @@ -44,9 +50,8 @@ static void rsnd_dvc_volume_update(struct rsnd_mod *mod) u32 mute = 0; int i;
- for (i = 0; i < RSND_DVC_CHANNELS; i++) { - mute |= (!!dvc->mute.val[i]) << i; - } + for (i = 0; i < dvc->mute.cfg.size; i++) + mute |= (!!dvc->mute.cfg.val[i]) << i;
/* Enable DVC Register access */ rsnd_mod_write(mod, DVC_DVUER, 1); @@ -177,7 +182,7 @@ static int rsnd_dvc_volume_get(struct snd_kcontrol *kctrl, struct rsnd_dvc_cfg *cfg = (struct rsnd_dvc_cfg *)kctrl->private_value; int i;
- for (i = 0; i < RSND_DVC_CHANNELS; i++) + for (i = 0; i < cfg->size; i++) ucontrol->value.integer.value[i] = cfg->val[i];
return 0; @@ -190,7 +195,7 @@ static int rsnd_dvc_volume_put(struct snd_kcontrol *kctrl, struct rsnd_dvc_cfg *cfg = (struct rsnd_dvc_cfg *)kctrl->private_value; int i, change = 0;
- for (i = 0; i < RSND_DVC_CHANNELS; i++) { + for (i = 0; i < cfg->size; i++) { change |= (ucontrol->value.integer.value[i] != cfg->val[i]); cfg->val[i] = ucontrol->value.integer.value[i]; } @@ -230,6 +235,19 @@ static int __rsnd_dvc_pcm_new(struct rsnd_mod *mod, return 0; }
+static int _rsnd_dvc_pcm_new_m(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct snd_soc_pcm_runtime *rtd, + const unsigned char *name, + struct rsnd_dvc_cfg_m *private, + u32 max) +{ + private->cfg.max = max; + private->cfg.size = RSND_DVC_CHANNELS; + private->cfg.val = private->val; + return __rsnd_dvc_pcm_new(mod, rdai, rtd, name, &private->cfg); +} + static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, struct rsnd_dai *rdai, struct snd_soc_pcm_runtime *rtd) @@ -239,20 +257,18 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, int ret;
/* Volume */ - dvc->volume.max = 0x00800000 - 1; - ret = __rsnd_dvc_pcm_new(mod, rdai, rtd, + ret = _rsnd_dvc_pcm_new_m(mod, rdai, rtd, rsnd_dai_is_play(rdai, io) ? "DVC Out Playback Volume" : "DVC In Capture Volume", - &dvc->volume); + &dvc->volume, 0x00800000 - 1); if (ret < 0) return ret;
/* Mute */ - dvc->mute.max = 1; - ret = __rsnd_dvc_pcm_new(mod, rdai, rtd, + ret = _rsnd_dvc_pcm_new_m(mod, rdai, rtd, rsnd_dai_is_play(rdai, io) ? "DVC Out Mute Switch" : "DVC In Mute Switch", - &dvc->mute); + &dvc->mute, 1); if (ret < 0) return ret;