Commit 92b9a699 authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Mark Brown

ASoC: rsnd: add struct rsnd_dvc_cfg and control DVC settings

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: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 9960ce97
...@@ -11,17 +11,21 @@ ...@@ -11,17 +11,21 @@
#include "rsnd.h" #include "rsnd.h"
#define RSND_DVC_NAME_SIZE 16 #define RSND_DVC_NAME_SIZE 16
#define RSND_DVC_VOLUME_MAX 100
#define RSND_DVC_CHANNELS 2 #define RSND_DVC_CHANNELS 2
#define DVC_NAME "dvc" #define DVC_NAME "dvc"
struct rsnd_dvc_cfg {
unsigned int max;
u32 val[RSND_DVC_CHANNELS];
};
struct rsnd_dvc { struct rsnd_dvc {
struct rsnd_dvc_platform_info *info; /* rcar_snd.h */ struct rsnd_dvc_platform_info *info; /* rcar_snd.h */
struct rsnd_mod mod; struct rsnd_mod mod;
struct clk *clk; struct clk *clk;
u8 volume[RSND_DVC_CHANNELS]; struct rsnd_dvc_cfg volume;
u8 mute[RSND_DVC_CHANNELS]; struct rsnd_dvc_cfg mute;
}; };
#define rsnd_mod_to_dvc(_mod) \ #define rsnd_mod_to_dvc(_mod) \
...@@ -36,18 +40,15 @@ struct rsnd_dvc { ...@@ -36,18 +40,15 @@ struct rsnd_dvc {
static void rsnd_dvc_volume_update(struct rsnd_mod *mod) static void rsnd_dvc_volume_update(struct rsnd_mod *mod)
{ {
struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
u32 max = (0x00800000 - 1);
u32 vol[RSND_DVC_CHANNELS];
u32 mute = 0; u32 mute = 0;
int i; int i;
for (i = 0; i < RSND_DVC_CHANNELS; i++) { for (i = 0; i < RSND_DVC_CHANNELS; i++) {
vol[i] = max / RSND_DVC_VOLUME_MAX * dvc->volume[i]; mute |= (!!dvc->mute.val[i]) << i;
mute |= (!!dvc->mute[i]) << i;
} }
rsnd_mod_write(mod, DVC_VOL0R, vol[0]); rsnd_mod_write(mod, DVC_VOL0R, dvc->volume.val[0]);
rsnd_mod_write(mod, DVC_VOL1R, vol[1]); rsnd_mod_write(mod, DVC_VOL1R, dvc->volume.val[1]);
rsnd_mod_write(mod, DVC_ZCMCR, mute); rsnd_mod_write(mod, DVC_ZCMCR, mute);
} }
...@@ -146,20 +147,16 @@ static int rsnd_dvc_stop(struct rsnd_mod *mod, ...@@ -146,20 +147,16 @@ static int rsnd_dvc_stop(struct rsnd_mod *mod,
static int rsnd_dvc_volume_info(struct snd_kcontrol *kctrl, static int rsnd_dvc_volume_info(struct snd_kcontrol *kctrl,
struct snd_ctl_elem_info *uinfo) struct snd_ctl_elem_info *uinfo)
{ {
struct rsnd_mod *mod = snd_kcontrol_chip(kctrl); struct rsnd_dvc_cfg *cfg = (struct rsnd_dvc_cfg *)kctrl->private_value;
struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
u8 *val = (u8 *)kctrl->private_value;
uinfo->count = RSND_DVC_CHANNELS; uinfo->count = RSND_DVC_CHANNELS;
uinfo->value.integer.min = 0; uinfo->value.integer.min = 0;
uinfo->value.integer.max = cfg->max;
if (val == dvc->volume) { if (cfg->max == 1)
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->value.integer.max = RSND_DVC_VOLUME_MAX;
} else {
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
uinfo->value.integer.max = 1; else
} uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
return 0; return 0;
} }
...@@ -167,11 +164,11 @@ static int rsnd_dvc_volume_info(struct snd_kcontrol *kctrl, ...@@ -167,11 +164,11 @@ static int rsnd_dvc_volume_info(struct snd_kcontrol *kctrl,
static int rsnd_dvc_volume_get(struct snd_kcontrol *kctrl, static int rsnd_dvc_volume_get(struct snd_kcontrol *kctrl,
struct snd_ctl_elem_value *ucontrol) 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; int i;
for (i = 0; i < RSND_DVC_CHANNELS; 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; return 0;
} }
...@@ -180,12 +177,12 @@ static int rsnd_dvc_volume_put(struct snd_kcontrol *kctrl, ...@@ -180,12 +177,12 @@ static int rsnd_dvc_volume_put(struct snd_kcontrol *kctrl,
struct snd_ctl_elem_value *ucontrol) struct snd_ctl_elem_value *ucontrol)
{ {
struct rsnd_mod *mod = snd_kcontrol_chip(kctrl); 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; int i, change = 0;
for (i = 0; i < RSND_DVC_CHANNELS; i++) { for (i = 0; i < RSND_DVC_CHANNELS; i++) {
change |= (ucontrol->value.integer.value[i] != val[i]); change |= (ucontrol->value.integer.value[i] != cfg->val[i]);
val[i] = ucontrol->value.integer.value[i]; cfg->val[i] = ucontrol->value.integer.value[i];
} }
if (change) if (change)
...@@ -198,7 +195,7 @@ static int __rsnd_dvc_pcm_new(struct rsnd_mod *mod, ...@@ -198,7 +195,7 @@ static int __rsnd_dvc_pcm_new(struct rsnd_mod *mod,
struct rsnd_dai *rdai, struct rsnd_dai *rdai,
struct snd_soc_pcm_runtime *rtd, struct snd_soc_pcm_runtime *rtd,
const unsigned char *name, const unsigned char *name,
u8 *private) struct rsnd_dvc_cfg *private)
{ {
struct snd_card *card = rtd->card->snd_card; struct snd_card *card = rtd->card->snd_card;
struct snd_kcontrol *kctrl; struct snd_kcontrol *kctrl;
...@@ -232,18 +229,20 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, ...@@ -232,18 +229,20 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
int ret; int ret;
/* Volume */ /* Volume */
dvc->volume.max = 0x00800000 - 1;
ret = __rsnd_dvc_pcm_new(mod, rdai, rtd, ret = __rsnd_dvc_pcm_new(mod, rdai, rtd,
rsnd_dai_is_play(rdai, io) ? rsnd_dai_is_play(rdai, io) ?
"DVC Out Playback Volume" : "DVC In Capture Volume", "DVC Out Playback Volume" : "DVC In Capture Volume",
dvc->volume); &dvc->volume);
if (ret < 0) if (ret < 0)
return ret; return ret;
/* Mute */ /* Mute */
dvc->mute.max = 1;
ret = __rsnd_dvc_pcm_new(mod, rdai, rtd, ret = __rsnd_dvc_pcm_new(mod, rdai, rtd,
rsnd_dai_is_play(rdai, io) ? rsnd_dai_is_play(rdai, io) ?
"DVC Out Mute Switch" : "DVC In Mute Switch", "DVC Out Mute Switch" : "DVC In Mute Switch",
dvc->mute); &dvc->mute);
if (ret < 0) if (ret < 0)
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment