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