[alsa-devel] [PATCH 0/2] ASoC: rsnd: adds Mute support
Hi Mark
These patch adds Mute support to Renesas R-Car sound
Kuninori Morimoto (2): ASoC: rsnd: tidyup DVC control method ASoC: rsnd: enable Mute control on DVC
sound/soc/sh/rcar/dvc.c | 93 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 30 deletions(-)
Best regards --- Kuninori Morimoto
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
DVC can use Volume and Mute control, and these control methods doesn't have much difference. This patch cleanup current method, and it will be used for Mute control.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/sh/rcar/dvc.c | 59 +++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 25 deletions(-)
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 9096fb0..12a0a20 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -20,7 +20,7 @@ struct rsnd_dvc { struct rsnd_dvc_platform_info *info; /* rcar_snd.h */ struct rsnd_mod mod; struct clk *clk; - long volume[RSND_DVC_VOLUME_NUM]; + u8 volume[RSND_DVC_VOLUME_NUM]; };
#define rsnd_mod_to_dvc(_mod) \ @@ -151,12 +151,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) { - struct rsnd_mod *mod = snd_kcontrol_chip(kctrl); - struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); + u8 *val = (u8 *)kctrl->private_value; int i;
for (i = 0; i < RSND_DVC_VOLUME_NUM; i++) - ucontrol->value.integer.value[i] = dvc->volume[i]; + ucontrol->value.integer.value[i] = val[i];
return 0; } @@ -165,47 +164,38 @@ static int rsnd_dvc_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *ucontrol) { struct rsnd_mod *mod = snd_kcontrol_chip(kctrl); - struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); + u8 *val = (u8 *)kctrl->private_value; int i, change = 0;
for (i = 0; i < RSND_DVC_VOLUME_NUM; i++) { - if (ucontrol->value.integer.value[i] < 0 || - ucontrol->value.integer.value[i] > RSND_DVC_VOLUME_MAX) - return -EINVAL; - - change |= (ucontrol->value.integer.value[i] != dvc->volume[i]); + change |= (ucontrol->value.integer.value[i] != val[i]); + val[i] = ucontrol->value.integer.value[i]; }
- if (change) { - for (i = 0; i < RSND_DVC_VOLUME_NUM; i++) - dvc->volume[i] = ucontrol->value.integer.value[i]; - + if (change) rsnd_dvc_volume_update(mod); - }
return change; }
-static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, - struct rsnd_dai *rdai, - struct snd_soc_pcm_runtime *rtd) +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_dai_stream *io = rsnd_mod_to_io(mod); struct snd_card *card = rtd->card->snd_card; struct snd_kcontrol *kctrl; - static struct snd_kcontrol_new knew = { + struct snd_kcontrol_new knew = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = name, .info = rsnd_dvc_volume_info, .get = rsnd_dvc_volume_get, .put = rsnd_dvc_volume_put, + .private_value = (unsigned long)private, }; int ret;
- if (rsnd_dai_is_play(rdai, io)) - knew.name = "Playback Volume"; - else - knew.name = "Capture Volume"; - kctrl = snd_ctl_new1(&knew, mod); if (!kctrl) return -ENOMEM; @@ -217,6 +207,25 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, return 0; }
+static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct snd_soc_pcm_runtime *rtd) +{ + struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); + struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); + int ret; + + /* Volume */ + ret = __rsnd_dvc_pcm_new(mod, rdai, rtd, + rsnd_dai_is_play(rdai, io) ? + "DVC Out Playback Volume" : "DVC In Capture Volume", + dvc->volume); + if (ret < 0) + return ret; + + return 0; +} + static struct rsnd_mod_ops rsnd_dvc_ops = { .name = DVC_NAME, .probe = rsnd_dvc_probe_gen2,
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
DVC can control Mute. This patch supports it.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/sh/rcar/dvc.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-)
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 12a0a20..3f44393 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -21,6 +21,7 @@ struct rsnd_dvc { struct rsnd_mod mod; struct clk *clk; u8 volume[RSND_DVC_VOLUME_NUM]; + u8 mute[RSND_DVC_VOLUME_NUM]; };
#define rsnd_mod_to_dvc(_mod) \ @@ -37,13 +38,18 @@ 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_VOLUME_NUM]; + u32 mute = 0; int i;
- for (i = 0; i < RSND_DVC_VOLUME_NUM; i++) + for (i = 0; i < RSND_DVC_VOLUME_NUM; i++) { vol[i] = max / RSND_DVC_VOLUME_MAX * dvc->volume[i]; + mute |= (!!dvc->mute[i]) << i; + }
rsnd_mod_write(mod, DVC_VOL0R, vol[0]); rsnd_mod_write(mod, DVC_VOL1R, vol[1]); + + rsnd_mod_write(mod, DVC_ZCMCR, mute); }
static int rsnd_dvc_probe_gen2(struct rsnd_mod *mod, @@ -96,8 +102,8 @@ static int rsnd_dvc_init(struct rsnd_mod *dvc_mod,
rsnd_mod_write(dvc_mod, DVC_ADINR, rsnd_get_adinr(dvc_mod));
- /* enable Volume */ - rsnd_mod_write(dvc_mod, DVC_DVUCR, 0x100); + /* enable Volume / Mute */ + rsnd_mod_write(dvc_mod, DVC_DVUCR, 0x101);
/* ch0/ch1 Volume */ rsnd_dvc_volume_update(dvc_mod); @@ -140,10 +146,20 @@ 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) { - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + struct rsnd_mod *mod = snd_kcontrol_chip(kctrl); + struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); + u8 *val = (u8 *)kctrl->private_value; + uinfo->count = RSND_DVC_VOLUME_NUM; uinfo->value.integer.min = 0; - uinfo->value.integer.max = RSND_DVC_VOLUME_MAX; + + if (val == dvc->volume) { + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->value.integer.max = RSND_DVC_VOLUME_MAX; + } else { + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->value.integer.max = 1; + }
return 0; } @@ -223,6 +239,14 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, if (ret < 0) return ret;
+ /* Mute */ + ret = __rsnd_dvc_pcm_new(mod, rdai, rtd, + rsnd_dai_is_play(rdai, io) ? + "DVC Out Mute Switch" : "DVC In Mute Switch", + dvc->mute); + if (ret < 0) + return ret; + return 0; }
participants (3)
-
Kuninori Morimoto
-
Kuninori Morimoto
-
Mark Brown