aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sh
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2015-11-04 03:44:12 -0500
committerMark Brown <broonie@kernel.org>2015-11-16 05:09:29 -0500
commitca16cc61592377ebd48d5f22fd823b592c80038e (patch)
tree26ddf785098bbde7c5188dc484104d23c21be829 /sound/soc/sh
parentdcc5a7b3b069cca17f3c5254006c66b99e87ffd3 (diff)
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')
-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 651c057b2113..0dc8a2a99fa4 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)
70 rsnd_mod_write(mod, DVC_SWRSR, 1); 70 rsnd_mod_write(mod, DVC_SWRSR, 1);
71} 71}
72 72
73#define rsnd_dvc_initialize_lock(mod) __rsnd_dvc_initialize_lock(mod, 1) 73#define rsnd_dvc_get_vrpdr(dvc) (dvc->rup.val << 8 | dvc->rdown.val)
74#define rsnd_dvc_initialize_unlock(mod) __rsnd_dvc_initialize_lock(mod, 0) 74#define rsnd_dvc_get_vrdbr(dvc) (0x3ff - (dvc->volume.val[0] >> 13))
75static void __rsnd_dvc_initialize_lock(struct rsnd_mod *mod, u32 enable)
76{
77 rsnd_mod_write(mod, DVC_DVUIR, enable);
78}
79 75
80static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io, 76static void rsnd_dvc_volume_parameter(struct rsnd_dai_stream *io,
81 struct rsnd_mod *mod) 77 struct rsnd_mod *mod)
82{ 78{
83 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); 79 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
84 u32 val[RSND_DVC_CHANNELS]; 80 u32 val[RSND_DVC_CHANNELS];
85 u32 dvucr = 0;
86 u32 mute = 0;
87 int i; 81 int i;
88 82
89 for (i = 0; i < dvc->mute.cfg.size; i++) 83 /* Enable Ramp */
90 mute |= (!!dvc->mute.cfg.val[i]) << i; 84 if (dvc->ren.val)
85 for (i = 0; i < RSND_DVC_CHANNELS; i++)
86 val[i] = dvc->volume.cfg.max;
87 else
88 for (i = 0; i < RSND_DVC_CHANNELS; i++)
89 val[i] = dvc->volume.val[i];
91 90
92 /* Disable DVC Register access */ 91 /* Enable Digital Volume */
93 rsnd_mod_write(mod, DVC_DVUER, 0); 92 rsnd_mod_write(mod, DVC_VOL0R, val[0]);
93 rsnd_mod_write(mod, DVC_VOL1R, val[1]);
94}
95
96static void rsnd_dvc_volume_init(struct rsnd_dai_stream *io,
97 struct rsnd_mod *mod)
98{
99 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
100 u32 dvucr = 0;
101 u32 vrctr = 0;
102 u32 vrpdr = 0;
103 u32 vrdbr = 0;
104
105 /* Enable Digital Volume, Zero Cross Mute Mode */
106 dvucr |= 0x101;
94 107
95 /* Enable Ramp */ 108 /* Enable Ramp */
96 if (dvc->ren.val) { 109 if (dvc->ren.val) {
97 dvucr |= 0x10; 110 dvucr |= 0x10;
98 111
99 /* Digital Volume Max */
100 for (i = 0; i < RSND_DVC_CHANNELS; i++)
101 val[i] = dvc->volume.cfg.max;
102
103 rsnd_mod_write(mod, DVC_VRCTR, 0xff);
104 rsnd_mod_write(mod, DVC_VRPDR, dvc->rup.val << 8 |
105 dvc->rdown.val);
106 /* 112 /*
107 * FIXME !! 113 * FIXME !!
108 * use scale-downed Digital Volume 114 * use scale-downed Digital Volume
109 * as Volume Ramp 115 * as Volume Ramp
110 * 7F FFFF -> 3FF 116 * 7F FFFF -> 3FF
111 */ 117 */
112 rsnd_mod_write(mod, DVC_VRDBR, 118 vrctr = 0xff;
113 0x3ff - (dvc->volume.val[0] >> 13)); 119 vrpdr = rsnd_dvc_get_vrpdr(dvc);
114 120 vrdbr = rsnd_dvc_get_vrdbr(dvc);
115 } else {
116 for (i = 0; i < RSND_DVC_CHANNELS; i++)
117 val[i] = dvc->volume.val[i];
118 } 121 }
119 122
120 /* Enable Digital Volume */ 123 /* Initialize operation */
121 dvucr |= 0x100; 124 rsnd_mod_write(mod, DVC_DVUIR, 1);
122 rsnd_mod_write(mod, DVC_VOL0R, val[0]); 125
123 rsnd_mod_write(mod, DVC_VOL1R, val[1]); 126 /* General Information */
127 rsnd_mod_write(mod, DVC_ADINR, rsnd_get_adinr_bit(mod, io));
128 rsnd_mod_write(mod, DVC_DVUCR, dvucr);
129
130 /* Volume Ramp Parameter */
131 rsnd_mod_write(mod, DVC_VRCTR, vrctr);
132 rsnd_mod_write(mod, DVC_VRPDR, vrpdr);
133 rsnd_mod_write(mod, DVC_VRDBR, vrdbr);
134
135 /* Digital Volume Function Parameter */
136 rsnd_dvc_volume_parameter(io, mod);
137
138 /* cancel operation */
139 rsnd_mod_write(mod, DVC_DVUIR, 0);
140}
141
142static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io,
143 struct rsnd_mod *mod)
144{
145 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
146 u32 zcmcr = 0;
147 u32 vrpdr = 0;
148 u32 vrdbr = 0;
149 int i;
150
151 for (i = 0; i < dvc->mute.cfg.size; i++)
152 zcmcr |= (!!dvc->mute.cfg.val[i]) << i;
124 153
125 /* Enable Mute */ 154 if (dvc->ren.val) {
126 if (mute) { 155 vrpdr = rsnd_dvc_get_vrpdr(dvc);
127 dvucr |= 0x1; 156 vrdbr = rsnd_dvc_get_vrdbr(dvc);
128 rsnd_mod_write(mod, DVC_ZCMCR, mute);
129 } 157 }
130 158
131 rsnd_mod_write(mod, DVC_DVUCR, dvucr); 159 /* Disable DVC Register access */
160 rsnd_mod_write(mod, DVC_DVUER, 0);
161
162 /* Zero Cross Mute Function */
163 rsnd_mod_write(mod, DVC_ZCMCR, zcmcr);
164
165 /* Volume Ramp Function */
166 rsnd_mod_write(mod, DVC_VRPDR, vrpdr);
167 rsnd_mod_write(mod, DVC_VRDBR, vrdbr);
168 /* add DVC_VRWTR here */
169
170 /* Digital Volume Function Parameter */
171 rsnd_dvc_volume_parameter(io, mod);
132 172
133 /* Enable DVC Register access */ 173 /* Enable DVC Register access */
134 rsnd_mod_write(mod, DVC_DVUER, 1); 174 rsnd_mod_write(mod, DVC_DVUER, 1);
@@ -164,15 +204,10 @@ static int rsnd_dvc_init(struct rsnd_mod *mod,
164 204
165 rsnd_dvc_soft_reset(mod); 205 rsnd_dvc_soft_reset(mod);
166 206
167 rsnd_dvc_initialize_lock(mod); 207 rsnd_dvc_volume_init(io, mod);
168 208
169 rsnd_mod_write(mod, DVC_ADINR, rsnd_get_adinr_bit(mod, io));
170
171 /* ch0/ch1 Volume */
172 rsnd_dvc_volume_update(io, mod); 209 rsnd_dvc_volume_update(io, mod);
173 210
174 rsnd_dvc_initialize_unlock(mod);
175
176 return 0; 211 return 0;
177} 212}
178 213