Commit 3539cacf authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Mark Brown

ASoC: rsnd: Add Volume Ramp support

This patch adds Volume Ramp to Renesas sound driver.

amixer set "DVC Out" 100%
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" on
aplay xxx.wav &
amixer set "DVC Out"  80%  // Volume Down
amixer set "DVC Out" 100%  // Volume Up
Signed-off-by: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent d3a76823
...@@ -38,6 +38,9 @@ struct rsnd_dvc { ...@@ -38,6 +38,9 @@ struct rsnd_dvc {
struct clk *clk; struct clk *clk;
struct rsnd_dvc_cfg_m volume; struct rsnd_dvc_cfg_m volume;
struct rsnd_dvc_cfg_m mute; 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 */
}; };
#define rsnd_mod_to_dvc(_mod) \ #define rsnd_mod_to_dvc(_mod) \
...@@ -49,9 +52,37 @@ struct rsnd_dvc { ...@@ -49,9 +52,37 @@ struct rsnd_dvc {
((pos) = (struct rsnd_dvc *)(priv)->dvc + i); \ ((pos) = (struct rsnd_dvc *)(priv)->dvc + i); \
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) 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 val[RSND_DVC_CHANNELS];
u32 dvucr = 0; u32 dvucr = 0;
u32 mute = 0; u32 mute = 0;
int i; int i;
...@@ -62,10 +93,35 @@ static void rsnd_dvc_volume_update(struct rsnd_mod *mod) ...@@ -62,10 +93,35 @@ static void rsnd_dvc_volume_update(struct rsnd_mod *mod)
/* Disable DVC Register access */ /* Disable DVC Register access */
rsnd_mod_write(mod, DVC_DVUER, 0); rsnd_mod_write(mod, DVC_DVUER, 0);
/* Enable Ramp */
if (dvc->ren.val) {
dvucr |= 0x10;
/* Digital Volume Max */
for (i = 0; i < RSND_DVC_CHANNELS; i++)
val[i] = dvc->volume.cfg.max;
rsnd_mod_write(mod, DVC_VRCTR, 0xff);
rsnd_mod_write(mod, DVC_VRPDR, dvc->rup.val << 8 |
dvc->rdown.val);
/*
* FIXME !!
* use scale-downed Digital Volume
* as Volume Ramp
* 7F FFFF -> 3FF
*/
rsnd_mod_write(mod, DVC_VRDBR,
0x3ff - (dvc->volume.val[0] >> 13));
} else {
for (i = 0; i < RSND_DVC_CHANNELS; i++)
val[i] = dvc->volume.val[i];
}
/* Enable Digital Volume */ /* Enable Digital Volume */
dvucr = 0x100; dvucr |= 0x100;
rsnd_mod_write(mod, DVC_VOL0R, dvc->volume.val[0]); rsnd_mod_write(mod, DVC_VOL0R, val[0]);
rsnd_mod_write(mod, DVC_VOL1R, dvc->volume.val[1]); rsnd_mod_write(mod, DVC_VOL1R, val[1]);
/* Enable Mute */ /* Enable Mute */
if (mute) { if (mute) {
...@@ -324,6 +380,31 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, ...@@ -324,6 +380,31 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
if (ret < 0) if (ret < 0)
return ret; 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;
return 0; return 0;
} }
......
...@@ -324,6 +324,9 @@ static int rsnd_gen2_probe(struct platform_device *pdev, ...@@ -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_ADINR, 0xe08, 0x100),
RSND_GEN_M_REG(DVC_DVUCR, 0xe10, 0x100), RSND_GEN_M_REG(DVC_DVUCR, 0xe10, 0x100),
RSND_GEN_M_REG(DVC_ZCMCR, 0xe14, 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_VOL0R, 0xe28, 0x100),
RSND_GEN_M_REG(DVC_VOL1R, 0xe2c, 0x100), RSND_GEN_M_REG(DVC_VOL1R, 0xe2c, 0x100),
RSND_GEN_M_REG(DVC_DVUER, 0xe48, 0x100), RSND_GEN_M_REG(DVC_DVUER, 0xe48, 0x100),
......
...@@ -91,6 +91,9 @@ enum rsnd_reg { ...@@ -91,6 +91,9 @@ enum rsnd_reg {
RSND_REG_SHARE20, RSND_REG_SHARE20,
RSND_REG_SHARE21, RSND_REG_SHARE21,
RSND_REG_SHARE22, RSND_REG_SHARE22,
RSND_REG_SHARE23,
RSND_REG_SHARE24,
RSND_REG_SHARE25,
RSND_REG_MAX, RSND_REG_MAX,
}; };
...@@ -129,6 +132,9 @@ enum rsnd_reg { ...@@ -129,6 +132,9 @@ enum rsnd_reg {
#define RSND_REG_CMD_CTRL RSND_REG_SHARE20 #define RSND_REG_CMD_CTRL RSND_REG_SHARE20
#define RSND_REG_CMDOUT_TIMSEL RSND_REG_SHARE21 #define RSND_REG_CMDOUT_TIMSEL RSND_REG_SHARE21
#define RSND_REG_BUSIF_DALIGN RSND_REG_SHARE22 #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_of_data;
struct rsnd_priv; struct rsnd_priv;
......
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