0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 #include "rsnd.h"
0034
0035 #define MIX_NAME_SIZE 16
0036 #define MIX_NAME "mix"
0037
0038 struct rsnd_mix {
0039 struct rsnd_mod mod;
0040 struct rsnd_kctrl_cfg_s volumeA;
0041 struct rsnd_kctrl_cfg_s volumeB;
0042 struct rsnd_kctrl_cfg_s volumeC;
0043 struct rsnd_kctrl_cfg_s volumeD;
0044 struct rsnd_kctrl_cfg_s ren;
0045 struct rsnd_kctrl_cfg_s rup;
0046 struct rsnd_kctrl_cfg_s rdw;
0047 u32 flags;
0048 };
0049
0050 #define ONCE_KCTRL_INITIALIZED (1 << 0)
0051 #define HAS_VOLA (1 << 1)
0052 #define HAS_VOLB (1 << 2)
0053 #define HAS_VOLC (1 << 3)
0054 #define HAS_VOLD (1 << 4)
0055
0056 #define VOL_MAX 0x3ff
0057
0058 #define rsnd_mod_to_mix(_mod) \
0059 container_of((_mod), struct rsnd_mix, mod)
0060
0061 #define rsnd_mix_get(priv, id) ((struct rsnd_mix *)(priv->mix) + id)
0062 #define rsnd_mix_nr(priv) ((priv)->mix_nr)
0063 #define for_each_rsnd_mix(pos, priv, i) \
0064 for ((i) = 0; \
0065 ((i) < rsnd_mix_nr(priv)) && \
0066 ((pos) = (struct rsnd_mix *)(priv)->mix + i); \
0067 i++)
0068
0069 static void rsnd_mix_activation(struct rsnd_mod *mod)
0070 {
0071 rsnd_mod_write(mod, MIX_SWRSR, 0);
0072 rsnd_mod_write(mod, MIX_SWRSR, 1);
0073 }
0074
0075 static void rsnd_mix_halt(struct rsnd_mod *mod)
0076 {
0077 rsnd_mod_write(mod, MIX_MIXIR, 1);
0078 rsnd_mod_write(mod, MIX_SWRSR, 0);
0079 }
0080
0081 #define rsnd_mix_get_vol(mix, X) \
0082 rsnd_flags_has(mix, HAS_VOL##X) ? \
0083 (VOL_MAX - rsnd_kctrl_vals(mix->volume##X)) : 0
0084 static void rsnd_mix_volume_parameter(struct rsnd_dai_stream *io,
0085 struct rsnd_mod *mod)
0086 {
0087 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
0088 struct device *dev = rsnd_priv_to_dev(priv);
0089 struct rsnd_mix *mix = rsnd_mod_to_mix(mod);
0090 u32 volA = rsnd_mix_get_vol(mix, A);
0091 u32 volB = rsnd_mix_get_vol(mix, B);
0092 u32 volC = rsnd_mix_get_vol(mix, C);
0093 u32 volD = rsnd_mix_get_vol(mix, D);
0094
0095 dev_dbg(dev, "MIX A/B/C/D = %02x/%02x/%02x/%02x\n",
0096 volA, volB, volC, volD);
0097
0098 rsnd_mod_write(mod, MIX_MDBAR, volA);
0099 rsnd_mod_write(mod, MIX_MDBBR, volB);
0100 rsnd_mod_write(mod, MIX_MDBCR, volC);
0101 rsnd_mod_write(mod, MIX_MDBDR, volD);
0102 }
0103
0104 static void rsnd_mix_volume_init(struct rsnd_dai_stream *io,
0105 struct rsnd_mod *mod)
0106 {
0107 struct rsnd_mix *mix = rsnd_mod_to_mix(mod);
0108
0109 rsnd_mod_write(mod, MIX_MIXIR, 1);
0110
0111
0112 rsnd_mod_write(mod, MIX_ADINR, rsnd_runtime_channel_after_ctu(io));
0113
0114
0115 rsnd_mod_write(mod, MIX_MIXMR, rsnd_kctrl_vals(mix->ren));
0116 rsnd_mod_write(mod, MIX_MVPDR, rsnd_kctrl_vals(mix->rup) << 8 |
0117 rsnd_kctrl_vals(mix->rdw));
0118
0119
0120 rsnd_mix_volume_parameter(io, mod);
0121
0122 rsnd_mod_write(mod, MIX_MIXIR, 0);
0123 }
0124
0125 static void rsnd_mix_volume_update(struct rsnd_dai_stream *io,
0126 struct rsnd_mod *mod)
0127 {
0128
0129 rsnd_mod_write(mod, MIX_MDBER, 0);
0130
0131
0132 rsnd_mix_volume_parameter(io, mod);
0133
0134
0135 rsnd_mod_write(mod, MIX_MDBER, 1);
0136 }
0137
0138 static int rsnd_mix_probe_(struct rsnd_mod *mod,
0139 struct rsnd_dai_stream *io,
0140 struct rsnd_priv *priv)
0141 {
0142 return rsnd_cmd_attach(io, rsnd_mod_id(mod));
0143 }
0144
0145 static int rsnd_mix_init(struct rsnd_mod *mod,
0146 struct rsnd_dai_stream *io,
0147 struct rsnd_priv *priv)
0148 {
0149 rsnd_mod_power_on(mod);
0150
0151 rsnd_mix_activation(mod);
0152
0153 rsnd_mix_volume_init(io, mod);
0154
0155 rsnd_mix_volume_update(io, mod);
0156
0157 return 0;
0158 }
0159
0160 static int rsnd_mix_quit(struct rsnd_mod *mod,
0161 struct rsnd_dai_stream *io,
0162 struct rsnd_priv *priv)
0163 {
0164 rsnd_mix_halt(mod);
0165
0166 rsnd_mod_power_off(mod);
0167
0168 return 0;
0169 }
0170
0171 static int rsnd_mix_pcm_new(struct rsnd_mod *mod,
0172 struct rsnd_dai_stream *io,
0173 struct snd_soc_pcm_runtime *rtd)
0174 {
0175 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
0176 struct device *dev = rsnd_priv_to_dev(priv);
0177 struct rsnd_mix *mix = rsnd_mod_to_mix(mod);
0178 struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io);
0179 struct rsnd_kctrl_cfg_s *volume;
0180 int ret;
0181
0182 switch (rsnd_mod_id(src_mod)) {
0183 case 3:
0184 case 6:
0185 volume = &mix->volumeA;
0186 rsnd_flags_set(mix, HAS_VOLA);
0187 break;
0188 case 4:
0189 case 9:
0190 volume = &mix->volumeB;
0191 rsnd_flags_set(mix, HAS_VOLB);
0192 break;
0193 case 0:
0194 case 1:
0195 volume = &mix->volumeC;
0196 rsnd_flags_set(mix, HAS_VOLC);
0197 break;
0198 case 2:
0199 case 5:
0200 volume = &mix->volumeD;
0201 rsnd_flags_set(mix, HAS_VOLD);
0202 break;
0203 default:
0204 dev_err(dev, "unknown SRC is connected\n");
0205 return -EINVAL;
0206 }
0207
0208
0209 ret = rsnd_kctrl_new_s(mod, io, rtd,
0210 "MIX Playback Volume",
0211 rsnd_kctrl_accept_anytime,
0212 rsnd_mix_volume_update,
0213 volume, VOL_MAX);
0214 if (ret < 0)
0215 return ret;
0216 rsnd_kctrl_vals(*volume) = VOL_MAX;
0217
0218 if (rsnd_flags_has(mix, ONCE_KCTRL_INITIALIZED))
0219 return ret;
0220
0221
0222 ret = rsnd_kctrl_new_s(mod, io, rtd,
0223 "MIX Ramp Switch",
0224 rsnd_kctrl_accept_anytime,
0225 rsnd_mix_volume_update,
0226 &mix->ren, 1);
0227 if (ret < 0)
0228 return ret;
0229
0230 ret = rsnd_kctrl_new_e(mod, io, rtd,
0231 "MIX Ramp Up Rate",
0232 rsnd_kctrl_accept_anytime,
0233 rsnd_mix_volume_update,
0234 &mix->rup,
0235 volume_ramp_rate,
0236 VOLUME_RAMP_MAX_MIX);
0237 if (ret < 0)
0238 return ret;
0239
0240 ret = rsnd_kctrl_new_e(mod, io, rtd,
0241 "MIX Ramp Down Rate",
0242 rsnd_kctrl_accept_anytime,
0243 rsnd_mix_volume_update,
0244 &mix->rdw,
0245 volume_ramp_rate,
0246 VOLUME_RAMP_MAX_MIX);
0247
0248 rsnd_flags_set(mix, ONCE_KCTRL_INITIALIZED);
0249
0250 return ret;
0251 }
0252
0253 #ifdef CONFIG_DEBUG_FS
0254 static void rsnd_mix_debug_info(struct seq_file *m,
0255 struct rsnd_dai_stream *io,
0256 struct rsnd_mod *mod)
0257 {
0258 rsnd_debugfs_mod_reg_show(m, mod, RSND_GEN2_SCU,
0259 0xd00 + rsnd_mod_id(mod) * 0x40, 0x30);
0260 }
0261 #define DEBUG_INFO .debug_info = rsnd_mix_debug_info
0262 #else
0263 #define DEBUG_INFO
0264 #endif
0265
0266 static struct rsnd_mod_ops rsnd_mix_ops = {
0267 .name = MIX_NAME,
0268 .probe = rsnd_mix_probe_,
0269 .init = rsnd_mix_init,
0270 .quit = rsnd_mix_quit,
0271 .pcm_new = rsnd_mix_pcm_new,
0272 .get_status = rsnd_mod_get_status,
0273 DEBUG_INFO
0274 };
0275
0276 struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id)
0277 {
0278 if (WARN_ON(id < 0 || id >= rsnd_mix_nr(priv)))
0279 id = 0;
0280
0281 return rsnd_mod_get(rsnd_mix_get(priv, id));
0282 }
0283
0284 int rsnd_mix_probe(struct rsnd_priv *priv)
0285 {
0286 struct device_node *node;
0287 struct device_node *np;
0288 struct device *dev = rsnd_priv_to_dev(priv);
0289 struct rsnd_mix *mix;
0290 struct clk *clk;
0291 char name[MIX_NAME_SIZE];
0292 int i, nr, ret;
0293
0294
0295 if (rsnd_is_gen1(priv))
0296 return 0;
0297
0298 node = rsnd_mix_of_node(priv);
0299 if (!node)
0300 return 0;
0301
0302 nr = of_get_child_count(node);
0303 if (!nr) {
0304 ret = -EINVAL;
0305 goto rsnd_mix_probe_done;
0306 }
0307
0308 mix = devm_kcalloc(dev, nr, sizeof(*mix), GFP_KERNEL);
0309 if (!mix) {
0310 ret = -ENOMEM;
0311 goto rsnd_mix_probe_done;
0312 }
0313
0314 priv->mix_nr = nr;
0315 priv->mix = mix;
0316
0317 i = 0;
0318 ret = 0;
0319 for_each_child_of_node(node, np) {
0320 mix = rsnd_mix_get(priv, i);
0321
0322 snprintf(name, MIX_NAME_SIZE, "%s.%d",
0323 MIX_NAME, i);
0324
0325 clk = devm_clk_get(dev, name);
0326 if (IS_ERR(clk)) {
0327 ret = PTR_ERR(clk);
0328 of_node_put(np);
0329 goto rsnd_mix_probe_done;
0330 }
0331
0332 ret = rsnd_mod_init(priv, rsnd_mod_get(mix), &rsnd_mix_ops,
0333 clk, RSND_MOD_MIX, i);
0334 if (ret) {
0335 of_node_put(np);
0336 goto rsnd_mix_probe_done;
0337 }
0338
0339 i++;
0340 }
0341
0342 rsnd_mix_probe_done:
0343 of_node_put(node);
0344
0345 return ret;
0346 }
0347
0348 void rsnd_mix_remove(struct rsnd_priv *priv)
0349 {
0350 struct rsnd_mix *mix;
0351 int i;
0352
0353 for_each_rsnd_mix(mix, priv, i) {
0354 rsnd_mod_quit(rsnd_mod_get(mix));
0355 }
0356 }