4 * Copyright (c) 2015 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
14 * [SRC3 / SRC6] -> |CTU n0| -> [MIX n0| ->
15 * [SRC4 / SRC9] -> |CTU n1| -> [MIX n1| ->
16 * [SRC0 / SRC1] -> |CTU n2| -> [MIX n2| ->
17 * [SRC2 / SRC5] -> |CTU n3| -> [MIX n3| ->
21 * DAI0 : playback = <&src0 &ctu02 &mix0 &dvc0 &ssi0>;
22 * DAI1 : playback = <&src2 &ctu03 &mix0 &dvc0 &ssi0>;
25 * amixer set "MIX",0 100% // DAI0 Volume
26 * amixer set "MIX",1 100% // DAI1 Volume
29 * amixer set "MIX Ramp Up Rate" "0.125 dB/1 step"
30 * amixer set "MIX Ramp Down Rate" "4 dB/1 step"
31 * amixer set "MIX Ramp" on
33 * amixer set "MIX",0 80% // DAI0 Volume Down
34 * amixer set "MIX",1 100% // DAI1 Volume Up
39 #define MIX_NAME_SIZE 16
40 #define MIX_NAME "mix"
44 struct rsnd_kctrl_cfg_s volumeA; /* MDBAR */
45 struct rsnd_kctrl_cfg_s volumeB; /* MDBBR */
46 struct rsnd_kctrl_cfg_s volumeC; /* MDBCR */
47 struct rsnd_kctrl_cfg_s volumeD; /* MDBDR */
48 struct rsnd_kctrl_cfg_s ren; /* Ramp Enable */
49 struct rsnd_kctrl_cfg_s rup; /* Ramp Rate Up */
50 struct rsnd_kctrl_cfg_s rdw; /* Ramp Rate Down */
54 #define ONCE_KCTRL_INITIALIZED (1 << 0)
55 #define HAS_VOLA (1 << 1)
56 #define HAS_VOLB (1 << 2)
57 #define HAS_VOLC (1 << 3)
58 #define HAS_VOLD (1 << 4)
62 #define rsnd_mod_to_mix(_mod) \
63 container_of((_mod), struct rsnd_mix, mod)
65 #define rsnd_mix_get(priv, id) ((struct rsnd_mix *)(priv->mix) + id)
66 #define rsnd_mix_nr(priv) ((priv)->mix_nr)
67 #define for_each_rsnd_mix(pos, priv, i) \
69 ((i) < rsnd_mix_nr(priv)) && \
70 ((pos) = (struct rsnd_mix *)(priv)->mix + i); \
73 static void rsnd_mix_activation(struct rsnd_mod *mod)
75 rsnd_mod_write(mod, MIX_SWRSR, 0);
76 rsnd_mod_write(mod, MIX_SWRSR, 1);
79 static void rsnd_mix_halt(struct rsnd_mod *mod)
81 rsnd_mod_write(mod, MIX_MIXIR, 1);
82 rsnd_mod_write(mod, MIX_SWRSR, 0);
85 #define rsnd_mix_get_vol(mix, X) \
86 rsnd_flags_has(mix, HAS_VOL##X) ? \
87 (VOL_MAX - rsnd_kctrl_vals(mix->volume##X)) : 0
88 static void rsnd_mix_volume_parameter(struct rsnd_dai_stream *io,
91 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
92 struct device *dev = rsnd_priv_to_dev(priv);
93 struct rsnd_mix *mix = rsnd_mod_to_mix(mod);
94 u32 volA = rsnd_mix_get_vol(mix, A);
95 u32 volB = rsnd_mix_get_vol(mix, B);
96 u32 volC = rsnd_mix_get_vol(mix, C);
97 u32 volD = rsnd_mix_get_vol(mix, D);
99 dev_dbg(dev, "MIX A/B/C/D = %02x/%02x/%02x/%02x\n",
100 volA, volB, volC, volD);
102 rsnd_mod_write(mod, MIX_MDBAR, volA);
103 rsnd_mod_write(mod, MIX_MDBBR, volB);
104 rsnd_mod_write(mod, MIX_MDBCR, volC);
105 rsnd_mod_write(mod, MIX_MDBDR, volD);
108 static void rsnd_mix_volume_init(struct rsnd_dai_stream *io,
109 struct rsnd_mod *mod)
111 struct rsnd_mix *mix = rsnd_mod_to_mix(mod);
113 rsnd_mod_write(mod, MIX_MIXIR, 1);
115 /* General Information */
116 rsnd_mod_write(mod, MIX_ADINR, rsnd_runtime_channel_after_ctu(io));
119 rsnd_mod_write(mod, MIX_MIXMR, rsnd_kctrl_vals(mix->ren));
120 rsnd_mod_write(mod, MIX_MVPDR, rsnd_kctrl_vals(mix->rup) << 8 |
121 rsnd_kctrl_vals(mix->rdw));
123 /* common volume parameter */
124 rsnd_mix_volume_parameter(io, mod);
126 rsnd_mod_write(mod, MIX_MIXIR, 0);
129 static void rsnd_mix_volume_update(struct rsnd_dai_stream *io,
130 struct rsnd_mod *mod)
132 /* Disable MIX dB setting */
133 rsnd_mod_write(mod, MIX_MDBER, 0);
135 /* common volume parameter */
136 rsnd_mix_volume_parameter(io, mod);
138 /* Enable MIX dB setting */
139 rsnd_mod_write(mod, MIX_MDBER, 1);
142 static int rsnd_mix_probe_(struct rsnd_mod *mod,
143 struct rsnd_dai_stream *io,
144 struct rsnd_priv *priv)
146 return rsnd_cmd_attach(io, rsnd_mod_id(mod));
149 static int rsnd_mix_init(struct rsnd_mod *mod,
150 struct rsnd_dai_stream *io,
151 struct rsnd_priv *priv)
153 rsnd_mod_power_on(mod);
155 rsnd_mix_activation(mod);
157 rsnd_mix_volume_init(io, mod);
159 rsnd_mix_volume_update(io, mod);
164 static int rsnd_mix_quit(struct rsnd_mod *mod,
165 struct rsnd_dai_stream *io,
166 struct rsnd_priv *priv)
170 rsnd_mod_power_off(mod);
175 static int rsnd_mix_pcm_new(struct rsnd_mod *mod,
176 struct rsnd_dai_stream *io,
177 struct snd_soc_pcm_runtime *rtd)
179 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
180 struct device *dev = rsnd_priv_to_dev(priv);
181 struct rsnd_mix *mix = rsnd_mod_to_mix(mod);
182 struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
183 struct rsnd_kctrl_cfg_s *volume;
186 switch (rsnd_mod_id(src_mod)) {
189 volume = &mix->volumeA;
190 rsnd_flags_set(mix, HAS_VOLA);
194 volume = &mix->volumeB;
195 rsnd_flags_set(mix, HAS_VOLB);
199 volume = &mix->volumeC;
200 rsnd_flags_set(mix, HAS_VOLC);
204 volume = &mix->volumeD;
205 rsnd_flags_set(mix, HAS_VOLD);
208 dev_err(dev, "unknown SRC is connected\n");
213 ret = rsnd_kctrl_new_s(mod, io, rtd,
214 "MIX Playback Volume",
215 rsnd_kctrl_accept_anytime,
216 rsnd_mix_volume_update,
220 rsnd_kctrl_vals(*volume) = VOL_MAX;
222 if (rsnd_flags_has(mix, ONCE_KCTRL_INITIALIZED))
226 ret = rsnd_kctrl_new_s(mod, io, rtd,
228 rsnd_kctrl_accept_anytime,
229 rsnd_mix_volume_update,
234 ret = rsnd_kctrl_new_e(mod, io, rtd,
236 rsnd_kctrl_accept_anytime,
237 rsnd_mix_volume_update,
240 VOLUME_RAMP_MAX_MIX);
244 ret = rsnd_kctrl_new_e(mod, io, rtd,
245 "MIX Ramp Down Rate",
246 rsnd_kctrl_accept_anytime,
247 rsnd_mix_volume_update,
250 VOLUME_RAMP_MAX_MIX);
252 rsnd_flags_set(mix, ONCE_KCTRL_INITIALIZED);
257 static struct rsnd_mod_ops rsnd_mix_ops = {
259 .probe = rsnd_mix_probe_,
260 .init = rsnd_mix_init,
261 .quit = rsnd_mix_quit,
262 .pcm_new = rsnd_mix_pcm_new,
265 struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id)
267 if (WARN_ON(id < 0 || id >= rsnd_mix_nr(priv)))
270 return rsnd_mod_get(rsnd_mix_get(priv, id));
273 int rsnd_mix_probe(struct rsnd_priv *priv)
275 struct device_node *node;
276 struct device_node *np;
277 struct device *dev = rsnd_priv_to_dev(priv);
278 struct rsnd_mix *mix;
280 char name[MIX_NAME_SIZE];
283 /* This driver doesn't support Gen1 at this point */
284 if (rsnd_is_gen1(priv))
287 node = rsnd_mix_of_node(priv);
289 return 0; /* not used is not error */
291 nr = of_get_child_count(node);
294 goto rsnd_mix_probe_done;
297 mix = devm_kzalloc(dev, sizeof(*mix) * nr, GFP_KERNEL);
300 goto rsnd_mix_probe_done;
308 for_each_child_of_node(node, np) {
309 mix = rsnd_mix_get(priv, i);
311 snprintf(name, MIX_NAME_SIZE, "%s.%d",
314 clk = devm_clk_get(dev, name);
318 goto rsnd_mix_probe_done;
321 ret = rsnd_mod_init(priv, rsnd_mod_get(mix), &rsnd_mix_ops,
322 clk, rsnd_mod_get_status, RSND_MOD_MIX, i);
325 goto rsnd_mix_probe_done;
337 void rsnd_mix_remove(struct rsnd_priv *priv)
339 struct rsnd_mix *mix;
342 for_each_rsnd_mix(mix, priv, i) {
343 rsnd_mod_quit(rsnd_mod_get(mix));