1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // mix.c 4 // 5 // Copyright (c) 2015 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 6 7 /* 8 * CTUn MIXn 9 * +------+ +------+ 10 * [SRC3 / SRC6] -> |CTU n0| -> [MIX n0| -> 11 * [SRC4 / SRC9] -> |CTU n1| -> [MIX n1| -> 12 * [SRC0 / SRC1] -> |CTU n2| -> [MIX n2| -> 13 * [SRC2 / SRC5] -> |CTU n3| -> [MIX n3| -> 14 * +------+ +------+ 15 * 16 * ex) 17 * DAI0 : playback = <&src0 &ctu02 &mix0 &dvc0 &ssi0>; 18 * DAI1 : playback = <&src2 &ctu03 &mix0 &dvc0 &ssi0>; 19 * 20 * MIX Volume 21 * amixer set "MIX",0 100% // DAI0 Volume 22 * amixer set "MIX",1 100% // DAI1 Volume 23 * 24 * Volume Ramp 25 * amixer set "MIX Ramp Up Rate" "0.125 dB/1 step" 26 * amixer set "MIX Ramp Down Rate" "4 dB/1 step" 27 * amixer set "MIX Ramp" on 28 * aplay xxx.wav & 29 * amixer set "MIX",0 80% // DAI0 Volume Down 30 * amixer set "MIX",1 100% // DAI1 Volume Up 31 */ 32 33 #include "rsnd.h" 34 35 #define MIX_NAME_SIZE 16 36 #define MIX_NAME "mix" 37 38 struct rsnd_mix { 39 struct rsnd_mod mod; 40 struct rsnd_kctrl_cfg_s volumeA; /* MDBAR */ 41 struct rsnd_kctrl_cfg_s volumeB; /* MDBBR */ 42 struct rsnd_kctrl_cfg_s volumeC; /* MDBCR */ 43 struct rsnd_kctrl_cfg_s volumeD; /* MDBDR */ 44 struct rsnd_kctrl_cfg_s ren; /* Ramp Enable */ 45 struct rsnd_kctrl_cfg_s rup; /* Ramp Rate Up */ 46 struct rsnd_kctrl_cfg_s rdw; /* Ramp Rate Down */ 47 u32 flags; 48 }; 49 50 #define ONCE_KCTRL_INITIALIZED (1 << 0) 51 #define HAS_VOLA (1 << 1) 52 #define HAS_VOLB (1 << 2) 53 #define HAS_VOLC (1 << 3) 54 #define HAS_VOLD (1 << 4) 55 56 #define VOL_MAX 0x3ff 57 58 #define rsnd_mod_to_mix(_mod) \ 59 container_of((_mod), struct rsnd_mix, mod) 60 61 #define rsnd_mix_get(priv, id) ((struct rsnd_mix *)(priv->mix) + id) 62 #define rsnd_mix_nr(priv) ((priv)->mix_nr) 63 #define for_each_rsnd_mix(pos, priv, i) \ 64 for ((i) = 0; \ 65 ((i) < rsnd_mix_nr(priv)) && \ 66 ((pos) = (struct rsnd_mix *)(priv)->mix + i); \ 67 i++) 68 69 static void rsnd_mix_activation(struct rsnd_mod *mod) 70 { 71 rsnd_mod_write(mod, MIX_SWRSR, 0); 72 rsnd_mod_write(mod, MIX_SWRSR, 1); 73 } 74 75 static void rsnd_mix_halt(struct rsnd_mod *mod) 76 { 77 rsnd_mod_write(mod, MIX_MIXIR, 1); 78 rsnd_mod_write(mod, MIX_SWRSR, 0); 79 } 80 81 #define rsnd_mix_get_vol(mix, X) \ 82 rsnd_flags_has(mix, HAS_VOL##X) ? \ 83 (VOL_MAX - rsnd_kctrl_vals(mix->volume##X)) : 0 84 static void rsnd_mix_volume_parameter(struct rsnd_dai_stream *io, 85 struct rsnd_mod *mod) 86 { 87 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 88 struct device *dev = rsnd_priv_to_dev(priv); 89 struct rsnd_mix *mix = rsnd_mod_to_mix(mod); 90 u32 volA = rsnd_mix_get_vol(mix, A); 91 u32 volB = rsnd_mix_get_vol(mix, B); 92 u32 volC = rsnd_mix_get_vol(mix, C); 93 u32 volD = rsnd_mix_get_vol(mix, D); 94 95 dev_dbg(dev, "MIX A/B/C/D = %02x/%02x/%02x/%02x\n", 96 volA, volB, volC, volD); 97 98 rsnd_mod_write(mod, MIX_MDBAR, volA); 99 rsnd_mod_write(mod, MIX_MDBBR, volB); 100 rsnd_mod_write(mod, MIX_MDBCR, volC); 101 rsnd_mod_write(mod, MIX_MDBDR, volD); 102 } 103 104 static void rsnd_mix_volume_init(struct rsnd_dai_stream *io, 105 struct rsnd_mod *mod) 106 { 107 struct rsnd_mix *mix = rsnd_mod_to_mix(mod); 108 109 rsnd_mod_write(mod, MIX_MIXIR, 1); 110 111 /* General Information */ 112 rsnd_mod_write(mod, MIX_ADINR, rsnd_runtime_channel_after_ctu(io)); 113 114 /* volume step */ 115 rsnd_mod_write(mod, MIX_MIXMR, rsnd_kctrl_vals(mix->ren)); 116 rsnd_mod_write(mod, MIX_MVPDR, rsnd_kctrl_vals(mix->rup) << 8 | 117 rsnd_kctrl_vals(mix->rdw)); 118 119 /* common volume parameter */ 120 rsnd_mix_volume_parameter(io, mod); 121 122 rsnd_mod_write(mod, MIX_MIXIR, 0); 123 } 124 125 static void rsnd_mix_volume_update(struct rsnd_dai_stream *io, 126 struct rsnd_mod *mod) 127 { 128 /* Disable MIX dB setting */ 129 rsnd_mod_write(mod, MIX_MDBER, 0); 130 131 /* common volume parameter */ 132 rsnd_mix_volume_parameter(io, mod); 133 134 /* Enable MIX dB setting */ 135 rsnd_mod_write(mod, MIX_MDBER, 1); 136 } 137 138 static int rsnd_mix_probe_(struct rsnd_mod *mod, 139 struct rsnd_dai_stream *io, 140 struct rsnd_priv *priv) 141 { 142 return rsnd_cmd_attach(io, rsnd_mod_id(mod)); 143 } 144 145 static int rsnd_mix_init(struct rsnd_mod *mod, 146 struct rsnd_dai_stream *io, 147 struct rsnd_priv *priv) 148 { 149 int ret; 150 151 ret = rsnd_mod_power_on(mod); 152 if (ret < 0) 153 return ret; 154 155 rsnd_mix_activation(mod); 156 157 rsnd_mix_volume_init(io, mod); 158 159 rsnd_mix_volume_update(io, mod); 160 161 return 0; 162 } 163 164 static int rsnd_mix_quit(struct rsnd_mod *mod, 165 struct rsnd_dai_stream *io, 166 struct rsnd_priv *priv) 167 { 168 rsnd_mix_halt(mod); 169 170 rsnd_mod_power_off(mod); 171 172 return 0; 173 } 174 175 static int rsnd_mix_pcm_new(struct rsnd_mod *mod, 176 struct rsnd_dai_stream *io, 177 struct snd_soc_pcm_runtime *rtd) 178 { 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; 184 int ret; 185 186 switch (rsnd_mod_id(src_mod)) { 187 case 3: 188 case 6: /* MDBAR */ 189 volume = &mix->volumeA; 190 rsnd_flags_set(mix, HAS_VOLA); 191 break; 192 case 4: 193 case 9: /* MDBBR */ 194 volume = &mix->volumeB; 195 rsnd_flags_set(mix, HAS_VOLB); 196 break; 197 case 0: 198 case 1: /* MDBCR */ 199 volume = &mix->volumeC; 200 rsnd_flags_set(mix, HAS_VOLC); 201 break; 202 case 2: 203 case 5: /* MDBDR */ 204 volume = &mix->volumeD; 205 rsnd_flags_set(mix, HAS_VOLD); 206 break; 207 default: 208 dev_err(dev, "unknown SRC is connected\n"); 209 return -EINVAL; 210 } 211 212 /* Volume */ 213 ret = rsnd_kctrl_new_s(mod, io, rtd, 214 "MIX Playback Volume", 215 rsnd_kctrl_accept_anytime, 216 rsnd_mix_volume_update, 217 volume, VOL_MAX); 218 if (ret < 0) 219 return ret; 220 rsnd_kctrl_vals(*volume) = VOL_MAX; 221 222 if (rsnd_flags_has(mix, ONCE_KCTRL_INITIALIZED)) 223 return ret; 224 225 /* Ramp */ 226 ret = rsnd_kctrl_new_s(mod, io, rtd, 227 "MIX Ramp Switch", 228 rsnd_kctrl_accept_anytime, 229 rsnd_mix_volume_update, 230 &mix->ren, 1); 231 if (ret < 0) 232 return ret; 233 234 ret = rsnd_kctrl_new_e(mod, io, rtd, 235 "MIX Ramp Up Rate", 236 rsnd_kctrl_accept_anytime, 237 rsnd_mix_volume_update, 238 &mix->rup, 239 volume_ramp_rate, 240 VOLUME_RAMP_MAX_MIX); 241 if (ret < 0) 242 return ret; 243 244 ret = rsnd_kctrl_new_e(mod, io, rtd, 245 "MIX Ramp Down Rate", 246 rsnd_kctrl_accept_anytime, 247 rsnd_mix_volume_update, 248 &mix->rdw, 249 volume_ramp_rate, 250 VOLUME_RAMP_MAX_MIX); 251 252 rsnd_flags_set(mix, ONCE_KCTRL_INITIALIZED); 253 254 return ret; 255 } 256 257 #ifdef CONFIG_DEBUG_FS 258 static void rsnd_mix_debug_info(struct seq_file *m, 259 struct rsnd_dai_stream *io, 260 struct rsnd_mod *mod) 261 { 262 rsnd_debugfs_mod_reg_show(m, mod, RSND_BASE_SCU, 263 0xd00 + rsnd_mod_id(mod) * 0x40, 0x30); 264 } 265 #define DEBUG_INFO .debug_info = rsnd_mix_debug_info 266 #else 267 #define DEBUG_INFO 268 #endif 269 270 static struct rsnd_mod_ops rsnd_mix_ops = { 271 .name = MIX_NAME, 272 .probe = rsnd_mix_probe_, 273 .init = rsnd_mix_init, 274 .quit = rsnd_mix_quit, 275 .pcm_new = rsnd_mix_pcm_new, 276 .get_status = rsnd_mod_get_status, 277 DEBUG_INFO 278 }; 279 280 struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id) 281 { 282 if (WARN_ON(id < 0 || id >= rsnd_mix_nr(priv))) 283 id = 0; 284 285 return rsnd_mod_get(rsnd_mix_get(priv, id)); 286 } 287 288 int rsnd_mix_probe(struct rsnd_priv *priv) 289 { 290 struct device_node *node; 291 struct device_node *np; 292 struct device *dev = rsnd_priv_to_dev(priv); 293 struct rsnd_mix *mix; 294 struct clk *clk; 295 char name[MIX_NAME_SIZE]; 296 int i, nr, ret; 297 298 node = rsnd_mix_of_node(priv); 299 if (!node) 300 return 0; /* not used is not error */ 301 302 nr = of_get_child_count(node); 303 if (!nr) { 304 ret = -EINVAL; 305 goto rsnd_mix_probe_done; 306 } 307 308 mix = devm_kcalloc(dev, nr, sizeof(*mix), GFP_KERNEL); 309 if (!mix) { 310 ret = -ENOMEM; 311 goto rsnd_mix_probe_done; 312 } 313 314 priv->mix_nr = nr; 315 priv->mix = mix; 316 317 i = 0; 318 ret = 0; 319 for_each_child_of_node(node, np) { 320 mix = rsnd_mix_get(priv, i); 321 322 snprintf(name, MIX_NAME_SIZE, "%s.%d", 323 MIX_NAME, i); 324 325 clk = devm_clk_get(dev, name); 326 if (IS_ERR(clk)) { 327 ret = PTR_ERR(clk); 328 of_node_put(np); 329 goto rsnd_mix_probe_done; 330 } 331 332 ret = rsnd_mod_init(priv, rsnd_mod_get(mix), &rsnd_mix_ops, 333 clk, RSND_MOD_MIX, i); 334 if (ret) { 335 of_node_put(np); 336 goto rsnd_mix_probe_done; 337 } 338 339 i++; 340 } 341 342 rsnd_mix_probe_done: 343 of_node_put(node); 344 345 return ret; 346 } 347 348 void rsnd_mix_remove(struct rsnd_priv *priv) 349 { 350 struct rsnd_mix *mix; 351 int i; 352 353 for_each_rsnd_mix(mix, priv, i) { 354 rsnd_mod_quit(rsnd_mod_get(mix)); 355 } 356 } 357