ASoC: rsnd: add struct rsnd_dvc_cfg and control DVC settings
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Wed, 22 Oct 2014 01:14:14 +0000 (18:14 -0700)
committerSimon Horman <horms+renesas@verge.net.au>
Fri, 5 Dec 2014 04:21:50 +0000 (13:21 +0900)
DVC can control Digital Volume / Mute / Volume Ramp etc,
and these uses different max value.
Current driver is using fixed max value for each settings.
This patch adds new struct rsnd_dvc_cfg, and control these.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit 92b9a6991b2e3a4ccf5ffc956730d36835d53a79)
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
sound/soc/sh/rcar/dvc.c

index b5f95ad..deaf0fa 100644 (file)
 #include "rsnd.h"
 
 #define RSND_DVC_NAME_SIZE     16
-#define RSND_DVC_VOLUME_MAX    100
 #define RSND_DVC_CHANNELS      2
 
 #define DVC_NAME "dvc"
 
+struct rsnd_dvc_cfg {
+       unsigned int max;
+       u32 val[RSND_DVC_CHANNELS];
+};
+
 struct rsnd_dvc {
        struct rsnd_dvc_platform_info *info; /* rcar_snd.h */
        struct rsnd_mod mod;
        struct clk *clk;
-       u8 volume[RSND_DVC_CHANNELS];
-       u8 mute[RSND_DVC_CHANNELS];
+       struct rsnd_dvc_cfg volume;
+       struct rsnd_dvc_cfg mute;
 };
 
 #define rsnd_mod_to_dvc(_mod)  \
@@ -36,18 +40,15 @@ struct rsnd_dvc {
 static void rsnd_dvc_volume_update(struct rsnd_mod *mod)
 {
        struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
-       u32 max = (0x00800000 - 1);
-       u32 vol[RSND_DVC_CHANNELS];
        u32 mute = 0;
        int i;
 
        for (i = 0; i < RSND_DVC_CHANNELS; i++) {
-               vol[i] = max / RSND_DVC_VOLUME_MAX * dvc->volume[i];
-               mute |= (!!dvc->mute[i]) << i;
+               mute |= (!!dvc->mute.val[i]) << i;
        }
 
-       rsnd_mod_write(mod, DVC_VOL0R, vol[0]);
-       rsnd_mod_write(mod, DVC_VOL1R, vol[1]);
+       rsnd_mod_write(mod, DVC_VOL0R, dvc->volume.val[0]);
+       rsnd_mod_write(mod, DVC_VOL1R, dvc->volume.val[1]);
 
        rsnd_mod_write(mod, DVC_ZCMCR, mute);
 }
@@ -146,20 +147,16 @@ static int rsnd_dvc_stop(struct rsnd_mod *mod,
 static int rsnd_dvc_volume_info(struct snd_kcontrol *kctrl,
                               struct snd_ctl_elem_info *uinfo)
 {
-       struct rsnd_mod *mod = snd_kcontrol_chip(kctrl);
-       struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
-       u8 *val = (u8 *)kctrl->private_value;
+       struct rsnd_dvc_cfg *cfg = (struct rsnd_dvc_cfg *)kctrl->private_value;
 
        uinfo->count = RSND_DVC_CHANNELS;
        uinfo->value.integer.min = 0;
+       uinfo->value.integer.max = cfg->max;
 
-       if (val == dvc->volume) {
-               uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-               uinfo->value.integer.max = RSND_DVC_VOLUME_MAX;
-       } else {
+       if (cfg->max == 1)
                uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
-               uinfo->value.integer.max = 1;
-       }
+       else
+               uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 
        return 0;
 }
@@ -167,11 +164,11 @@ static int rsnd_dvc_volume_info(struct snd_kcontrol *kctrl,
 static int rsnd_dvc_volume_get(struct snd_kcontrol *kctrl,
                              struct snd_ctl_elem_value *ucontrol)
 {
-       u8 *val = (u8 *)kctrl->private_value;
+       struct rsnd_dvc_cfg *cfg = (struct rsnd_dvc_cfg *)kctrl->private_value;
        int i;
 
        for (i = 0; i < RSND_DVC_CHANNELS; i++)
-               ucontrol->value.integer.value[i] = val[i];
+               ucontrol->value.integer.value[i] = cfg->val[i];
 
        return 0;
 }
@@ -180,12 +177,12 @@ static int rsnd_dvc_volume_put(struct snd_kcontrol *kctrl,
                              struct snd_ctl_elem_value *ucontrol)
 {
        struct rsnd_mod *mod = snd_kcontrol_chip(kctrl);
-       u8 *val = (u8 *)kctrl->private_value;
+       struct rsnd_dvc_cfg *cfg = (struct rsnd_dvc_cfg *)kctrl->private_value;
        int i, change = 0;
 
        for (i = 0; i < RSND_DVC_CHANNELS; i++) {
-               change |= (ucontrol->value.integer.value[i] != val[i]);
-               val[i] = ucontrol->value.integer.value[i];
+               change |= (ucontrol->value.integer.value[i] != cfg->val[i]);
+               cfg->val[i] = ucontrol->value.integer.value[i];
        }
 
        if (change)
@@ -198,7 +195,7 @@ static int __rsnd_dvc_pcm_new(struct rsnd_mod *mod,
                              struct rsnd_dai *rdai,
                              struct snd_soc_pcm_runtime *rtd,
                              const unsigned char *name,
-                             u8 *private)
+                             struct rsnd_dvc_cfg *private)
 {
        struct snd_card *card = rtd->card->snd_card;
        struct snd_kcontrol *kctrl;
@@ -232,18 +229,20 @@ 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,
                        rsnd_dai_is_play(rdai, io) ?
                        "DVC Out Playback Volume" : "DVC In Capture Volume",
-                       dvc->volume);
+                       &dvc->volume);
        if (ret < 0)
                return ret;
 
        /* Mute */
+       dvc->mute.max = 1;
        ret = __rsnd_dvc_pcm_new(mod, rdai, rtd,
                        rsnd_dai_is_play(rdai, io) ?
                        "DVC Out Mute Switch" : "DVC In Mute Switch",
-                       dvc->mute);
+                       &dvc->mute);
        if (ret < 0)
                return ret;