summaryrefslogtreecommitdiff
path: root/sound/soc/sh/rcar/dvc.c
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2015-11-04 08:44:12 (GMT)
committerMark Brown <broonie@kernel.org>2015-11-16 10:09:29 (GMT)
commitca16cc61592377ebd48d5f22fd823b592c80038e (patch)
tree26ddf785098bbde7c5188dc484104d23c21be829 /sound/soc/sh/rcar/dvc.c
parentdcc5a7b3b069cca17f3c5254006c66b99e87ffd3 (diff)
downloadlinux-ca16cc61592377ebd48d5f22fd823b592c80038e.tar.xz
ASoC: rsnd: DVC settings matches to datasheet
Current DVC settings order was rough. This patch makes it match to datasheet. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sh/rcar/dvc.c')
-rw-r--r--sound/soc/sh/rcar/dvc.c119
1 files changed, 77 insertions, 42 deletions
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c
index 651c057..0dc8a2a 100644
--- a/sound/soc/sh/rcar/dvc.c
+++ b/sound/soc/sh/rcar/dvc.c
@@ -70,65 +70,105 @@ static void rsnd_dvc_soft_reset(struct rsnd_mod *mod)
rsnd_mod_write(mod, DVC_SWRSR, 1);
}
-#define rsnd_dvc_initialize_lock(mod) __rsnd_dvc_initialize_lock(mod, 1)
-#define rsnd_dvc_initialize_unlock(mod) __rsnd_dvc_initialize_lock(mod, 0)
-static void __rsnd_dvc_initialize_lock(struct rsnd_mod *mod, u32 enable)
-{
- rsnd_mod_write(mod, DVC_DVUIR, enable);
-}
+#define rsnd_dvc_get_vrpdr(dvc) (dvc->rup.val << 8 | dvc->rdown.val)
+#define rsnd_dvc_get_vrdbr(dvc) (0x3ff - (dvc->volume.val[0] >> 13))
-static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io,
- struct rsnd_mod *mod)
+static void rsnd_dvc_volume_parameter(struct rsnd_dai_stream *io,
+ struct rsnd_mod *mod)
{
struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
u32 val[RSND_DVC_CHANNELS];
- u32 dvucr = 0;
- u32 mute = 0;
int i;
- for (i = 0; i < dvc->mute.cfg.size; i++)
- mute |= (!!dvc->mute.cfg.val[i]) << i;
+ /* Enable Ramp */
+ if (dvc->ren.val)
+ for (i = 0; i < RSND_DVC_CHANNELS; i++)
+ val[i] = dvc->volume.cfg.max;
+ else
+ for (i = 0; i < RSND_DVC_CHANNELS; i++)
+ val[i] = dvc->volume.val[i];
- /* Disable DVC Register access */
- rsnd_mod_write(mod, DVC_DVUER, 0);
+ /* Enable Digital Volume */
+ rsnd_mod_write(mod, DVC_VOL0R, val[0]);
+ rsnd_mod_write(mod, DVC_VOL1R, val[1]);
+}
+
+static void rsnd_dvc_volume_init(struct rsnd_dai_stream *io,
+ struct rsnd_mod *mod)
+{
+ struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
+ u32 dvucr = 0;
+ u32 vrctr = 0;
+ u32 vrpdr = 0;
+ u32 vrdbr = 0;
+
+ /* Enable Digital Volume, Zero Cross Mute Mode */
+ dvucr |= 0x101;
/* 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];
+ vrctr = 0xff;
+ vrpdr = rsnd_dvc_get_vrpdr(dvc);
+ vrdbr = rsnd_dvc_get_vrdbr(dvc);
}
- /* Enable Digital Volume */
- dvucr |= 0x100;
- rsnd_mod_write(mod, DVC_VOL0R, val[0]);
- rsnd_mod_write(mod, DVC_VOL1R, val[1]);
+ /* Initialize operation */
+ rsnd_mod_write(mod, DVC_DVUIR, 1);
+
+ /* General Information */
+ rsnd_mod_write(mod, DVC_ADINR, rsnd_get_adinr_bit(mod, io));
+ rsnd_mod_write(mod, DVC_DVUCR, dvucr);
+
+ /* Volume Ramp Parameter */
+ rsnd_mod_write(mod, DVC_VRCTR, vrctr);
+ rsnd_mod_write(mod, DVC_VRPDR, vrpdr);
+ rsnd_mod_write(mod, DVC_VRDBR, vrdbr);
+
+ /* Digital Volume Function Parameter */
+ rsnd_dvc_volume_parameter(io, mod);
+
+ /* cancel operation */
+ rsnd_mod_write(mod, DVC_DVUIR, 0);
+}
+
+static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io,
+ struct rsnd_mod *mod)
+{
+ struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
+ u32 zcmcr = 0;
+ u32 vrpdr = 0;
+ u32 vrdbr = 0;
+ int i;
+
+ for (i = 0; i < dvc->mute.cfg.size; i++)
+ zcmcr |= (!!dvc->mute.cfg.val[i]) << i;
- /* Enable Mute */
- if (mute) {
- dvucr |= 0x1;
- rsnd_mod_write(mod, DVC_ZCMCR, mute);
+ if (dvc->ren.val) {
+ vrpdr = rsnd_dvc_get_vrpdr(dvc);
+ vrdbr = rsnd_dvc_get_vrdbr(dvc);
}
- rsnd_mod_write(mod, DVC_DVUCR, dvucr);
+ /* Disable DVC Register access */
+ rsnd_mod_write(mod, DVC_DVUER, 0);
+
+ /* Zero Cross Mute Function */
+ rsnd_mod_write(mod, DVC_ZCMCR, zcmcr);
+
+ /* Volume Ramp Function */
+ rsnd_mod_write(mod, DVC_VRPDR, vrpdr);
+ rsnd_mod_write(mod, DVC_VRDBR, vrdbr);
+ /* add DVC_VRWTR here */
+
+ /* Digital Volume Function Parameter */
+ rsnd_dvc_volume_parameter(io, mod);
/* Enable DVC Register access */
rsnd_mod_write(mod, DVC_DVUER, 1);
@@ -164,15 +204,10 @@ static int rsnd_dvc_init(struct rsnd_mod *mod,
rsnd_dvc_soft_reset(mod);
- rsnd_dvc_initialize_lock(mod);
+ rsnd_dvc_volume_init(io, mod);
- rsnd_mod_write(mod, DVC_ADINR, rsnd_get_adinr_bit(mod, io));
-
- /* ch0/ch1 Volume */
rsnd_dvc_volume_update(io, mod);
- rsnd_dvc_initialize_unlock(mod);
-
return 0;
}