[alsa-devel] [PATCH 6/6 v3] ASoC: rsnd: Add Volume Ramp support
Kuninori Morimoto
kuninori.morimoto.gx at gmail.com
Wed Nov 5 05:29:53 CET 2014
From: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
This patch adds Volume Ramp to Renesas sound driver.
Below sample indicates
Mute -> Volume 100% -> Mute.
Here,
- Mute (= Normal Volume x 0%)
- Volume 100% (= Normal Volume x 100%)
amixer set "DVC Out" 100% // = Normal Volume
amixer set "DVC Out Ramp Up Rate" "0.125 dB/64 steps"
amixer set "DVC Out Ramp Down Rate" "0.125 dB/512 steps"
amixer set "DVC Out Ramp" 0% // Mute = Normal Volume x 0%
amixer set "DVC Out Ramp" on // Volume Ramp ON
aplay xxx.wav &
amixer set "DVC Out Ramp" 100% // Mute to Normal Volume x 100%
amixer set "DVC Out Ramp" 0% // Normal Volume x 100% to Mute
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
---
v2 -> v3
- use enumerated list
- it is using datasheet words (= xxx dB / yy step)
sound/soc/sh/rcar/dvc.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++
sound/soc/sh/rcar/gen.c | 3 ++
sound/soc/sh/rcar/rsnd.h | 6 ++++
3 files changed, 83 insertions(+)
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c
index 8504f6b..0b38f888 100644
--- a/sound/soc/sh/rcar/dvc.c
+++ b/sound/soc/sh/rcar/dvc.c
@@ -38,6 +38,10 @@ struct rsnd_dvc {
struct clk *clk;
struct rsnd_dvc_cfg_m volume;
struct rsnd_dvc_cfg_m mute;
+ struct rsnd_dvc_cfg_s ren; /* Ramp Enable */
+ struct rsnd_dvc_cfg_s rup; /* Ramp Rate Up */
+ struct rsnd_dvc_cfg_s rdown; /* Ramp Rate Down */
+ struct rsnd_dvc_cfg_s rvol; /* Ramp Volume */
};
#define rsnd_mod_to_dvc(_mod) \
@@ -49,6 +53,33 @@ struct rsnd_dvc {
((pos) = (struct rsnd_dvc *)(priv)->dvc + i); \
i++)
+static const char const *dvc_ramp_rate[] = {
+ "128 dB/1 step", /* 00000 */
+ "64 dB/1 step", /* 00001 */
+ "32 dB/1 step", /* 00010 */
+ "16 dB/1 step", /* 00011 */
+ "8 dB/1 step", /* 00100 */
+ "4 dB/1 step", /* 00101 */
+ "2 dB/1 step", /* 00110 */
+ "1 dB/1 step", /* 00111 */
+ "0.5 dB/1 step", /* 01000 */
+ "0.25 dB/1 step", /* 01001 */
+ "0.125 dB/1 step", /* 01010 */
+ "0.125 dB/2 steps", /* 01011 */
+ "0.125 dB/4 steps", /* 01100 */
+ "0.125 dB/8 steps", /* 01101 */
+ "0.125 dB/16 steps", /* 01110 */
+ "0.125 dB/32 steps", /* 01111 */
+ "0.125 dB/64 steps", /* 10000 */
+ "0.125 dB/128 steps", /* 10001 */
+ "0.125 dB/256 steps", /* 10010 */
+ "0.125 dB/512 steps", /* 10011 */
+ "0.125 dB/1024 steps", /* 10100 */
+ "0.125 dB/2048 steps", /* 10101 */
+ "0.125 dB/4096 steps", /* 10110 */
+ "0.125 dB/8192 steps", /* 10111 */
+};
+
static void rsnd_dvc_volume_update(struct rsnd_mod *mod)
{
struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
@@ -67,6 +98,17 @@ static void rsnd_dvc_volume_update(struct rsnd_mod *mod)
rsnd_mod_write(mod, DVC_VOL0R, dvc->volume.val[0]);
rsnd_mod_write(mod, DVC_VOL1R, dvc->volume.val[1]);
+ /* Enable Ramp */
+ if (dvc->ren.val) {
+ dvucr |= 0x10;
+ rsnd_mod_write(mod, DVC_VRCTR, 0xff);
+ rsnd_mod_write(mod, DVC_VRPDR, dvc->rup.val << 8 |
+ dvc->rdown.val);
+ /* use inverted value for user experience */
+ rsnd_mod_write(mod, DVC_VRDBR, dvc->rvol.cfg.max -
+ dvc->rvol.val);
+ }
+
/* Enable Mute */
if (mute) {
dvucr |= 0x1;
@@ -323,6 +365,38 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
if (ret < 0)
return ret;
+ /* Ramp */
+ ret = _rsnd_dvc_pcm_new_s(mod, rdai, rtd,
+ rsnd_dai_is_play(rdai, io) ?
+ "DVC Out Ramp Switch" : "DVC In Ramp Switch",
+ &dvc->ren, 1);
+ if (ret < 0)
+ return ret;
+
+ ret = _rsnd_dvc_pcm_new_e(mod, rdai, rtd,
+ rsnd_dai_is_play(rdai, io) ?
+ "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate",
+ &dvc->rup,
+ dvc_ramp_rate, ARRAY_SIZE(dvc_ramp_rate));
+ if (ret < 0)
+ return ret;
+
+ ret = _rsnd_dvc_pcm_new_e(mod, rdai, rtd,
+ rsnd_dai_is_play(rdai, io) ?
+ "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate",
+ &dvc->rdown,
+ dvc_ramp_rate, ARRAY_SIZE(dvc_ramp_rate));
+
+ if (ret < 0)
+ return ret;
+
+ ret = _rsnd_dvc_pcm_new_s(mod, rdai, rtd,
+ rsnd_dai_is_play(rdai, io) ?
+ "DVC Out Ramp Volume" : "DVC In Ramp Volume",
+ &dvc->rvol, 0x3ff);
+ if (ret < 0)
+ return ret;
+
return 0;
}
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index 61dee68..4cb3202 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -324,6 +324,9 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
RSND_GEN_M_REG(DVC_ADINR, 0xe08, 0x100),
RSND_GEN_M_REG(DVC_DVUCR, 0xe10, 0x100),
RSND_GEN_M_REG(DVC_ZCMCR, 0xe14, 0x100),
+ RSND_GEN_M_REG(DVC_VRCTR, 0xe18, 0x100),
+ RSND_GEN_M_REG(DVC_VRPDR, 0xe1c, 0x100),
+ RSND_GEN_M_REG(DVC_VRDBR, 0xe20, 0x100),
RSND_GEN_M_REG(DVC_VOL0R, 0xe28, 0x100),
RSND_GEN_M_REG(DVC_VOL1R, 0xe2c, 0x100),
RSND_GEN_M_REG(DVC_DVUER, 0xe48, 0x100),
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index d119adf..ed44ca8 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -91,6 +91,9 @@ enum rsnd_reg {
RSND_REG_SHARE20,
RSND_REG_SHARE21,
RSND_REG_SHARE22,
+ RSND_REG_SHARE23,
+ RSND_REG_SHARE24,
+ RSND_REG_SHARE25,
RSND_REG_MAX,
};
@@ -129,6 +132,9 @@ enum rsnd_reg {
#define RSND_REG_CMD_CTRL RSND_REG_SHARE20
#define RSND_REG_CMDOUT_TIMSEL RSND_REG_SHARE21
#define RSND_REG_BUSIF_DALIGN RSND_REG_SHARE22
+#define RSND_REG_DVC_VRCTR RSND_REG_SHARE23
+#define RSND_REG_DVC_VRPDR RSND_REG_SHARE24
+#define RSND_REG_DVC_VRDBR RSND_REG_SHARE25
struct rsnd_of_data;
struct rsnd_priv;
--
1.7.9.5
More information about the Alsa-devel
mailing list