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 #include "rsnd.h"
0031
0032 #define RSND_DVC_NAME_SIZE 16
0033
0034 #define DVC_NAME "dvc"
0035
0036 struct rsnd_dvc {
0037 struct rsnd_mod mod;
0038 struct rsnd_kctrl_cfg_m volume;
0039 struct rsnd_kctrl_cfg_m mute;
0040 struct rsnd_kctrl_cfg_s ren;
0041 struct rsnd_kctrl_cfg_s rup;
0042 struct rsnd_kctrl_cfg_s rdown;
0043 };
0044
0045 #define rsnd_dvc_get(priv, id) ((struct rsnd_dvc *)(priv->dvc) + id)
0046 #define rsnd_dvc_nr(priv) ((priv)->dvc_nr)
0047
0048 #define rsnd_mod_to_dvc(_mod) \
0049 container_of((_mod), struct rsnd_dvc, mod)
0050
0051 #define for_each_rsnd_dvc(pos, priv, i) \
0052 for ((i) = 0; \
0053 ((i) < rsnd_dvc_nr(priv)) && \
0054 ((pos) = (struct rsnd_dvc *)(priv)->dvc + i); \
0055 i++)
0056
0057 static void rsnd_dvc_activation(struct rsnd_mod *mod)
0058 {
0059 rsnd_mod_write(mod, DVC_SWRSR, 0);
0060 rsnd_mod_write(mod, DVC_SWRSR, 1);
0061 }
0062
0063 static void rsnd_dvc_halt(struct rsnd_mod *mod)
0064 {
0065 rsnd_mod_write(mod, DVC_DVUIR, 1);
0066 rsnd_mod_write(mod, DVC_SWRSR, 0);
0067 }
0068
0069 #define rsnd_dvc_get_vrpdr(dvc) (rsnd_kctrl_vals(dvc->rup) << 8 | \
0070 rsnd_kctrl_vals(dvc->rdown))
0071 #define rsnd_dvc_get_vrdbr(dvc) (0x3ff - (rsnd_kctrl_valm(dvc->volume, 0) >> 13))
0072
0073 static void rsnd_dvc_volume_parameter(struct rsnd_dai_stream *io,
0074 struct rsnd_mod *mod)
0075 {
0076 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
0077 u32 val[RSND_MAX_CHANNELS];
0078 int i;
0079
0080
0081 if (rsnd_kctrl_vals(dvc->ren))
0082 for (i = 0; i < RSND_MAX_CHANNELS; i++)
0083 val[i] = rsnd_kctrl_max(dvc->volume);
0084 else
0085 for (i = 0; i < RSND_MAX_CHANNELS; i++)
0086 val[i] = rsnd_kctrl_valm(dvc->volume, i);
0087
0088
0089 for (i = 0; i < RSND_MAX_CHANNELS; i++)
0090 rsnd_mod_write(mod, DVC_VOLxR(i), val[i]);
0091 }
0092
0093 static void rsnd_dvc_volume_init(struct rsnd_dai_stream *io,
0094 struct rsnd_mod *mod)
0095 {
0096 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
0097 u32 adinr = 0;
0098 u32 dvucr = 0;
0099 u32 vrctr = 0;
0100 u32 vrpdr = 0;
0101 u32 vrdbr = 0;
0102
0103 adinr = rsnd_get_adinr_bit(mod, io) |
0104 rsnd_runtime_channel_after_ctu(io);
0105
0106
0107 dvucr |= 0x101;
0108
0109
0110 if (rsnd_kctrl_vals(dvc->ren)) {
0111 dvucr |= 0x10;
0112
0113
0114
0115
0116
0117
0118
0119 vrctr = 0xff;
0120 vrpdr = rsnd_dvc_get_vrpdr(dvc);
0121 vrdbr = rsnd_dvc_get_vrdbr(dvc);
0122 }
0123
0124
0125 rsnd_mod_write(mod, DVC_DVUIR, 1);
0126
0127
0128 rsnd_mod_write(mod, DVC_ADINR, adinr);
0129 rsnd_mod_write(mod, DVC_DVUCR, dvucr);
0130
0131
0132 rsnd_mod_write(mod, DVC_VRCTR, vrctr);
0133 rsnd_mod_write(mod, DVC_VRPDR, vrpdr);
0134 rsnd_mod_write(mod, DVC_VRDBR, vrdbr);
0135
0136
0137 rsnd_dvc_volume_parameter(io, mod);
0138
0139
0140 rsnd_mod_write(mod, DVC_DVUIR, 0);
0141 }
0142
0143 static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io,
0144 struct rsnd_mod *mod)
0145 {
0146 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
0147 u32 zcmcr = 0;
0148 u32 vrpdr = 0;
0149 u32 vrdbr = 0;
0150 int i;
0151
0152 for (i = 0; i < rsnd_kctrl_size(dvc->mute); i++)
0153 zcmcr |= (!!rsnd_kctrl_valm(dvc->mute, i)) << i;
0154
0155 if (rsnd_kctrl_vals(dvc->ren)) {
0156 vrpdr = rsnd_dvc_get_vrpdr(dvc);
0157 vrdbr = rsnd_dvc_get_vrdbr(dvc);
0158 }
0159
0160
0161 rsnd_mod_write(mod, DVC_DVUER, 0);
0162
0163
0164 rsnd_mod_write(mod, DVC_ZCMCR, zcmcr);
0165
0166
0167 rsnd_mod_write(mod, DVC_VRPDR, vrpdr);
0168 rsnd_mod_write(mod, DVC_VRDBR, vrdbr);
0169
0170
0171
0172 rsnd_dvc_volume_parameter(io, mod);
0173
0174
0175 rsnd_mod_write(mod, DVC_DVUER, 1);
0176 }
0177
0178 static int rsnd_dvc_probe_(struct rsnd_mod *mod,
0179 struct rsnd_dai_stream *io,
0180 struct rsnd_priv *priv)
0181 {
0182 return rsnd_cmd_attach(io, rsnd_mod_id(mod));
0183 }
0184
0185 static int rsnd_dvc_init(struct rsnd_mod *mod,
0186 struct rsnd_dai_stream *io,
0187 struct rsnd_priv *priv)
0188 {
0189 rsnd_mod_power_on(mod);
0190
0191 rsnd_dvc_activation(mod);
0192
0193 rsnd_dvc_volume_init(io, mod);
0194
0195 rsnd_dvc_volume_update(io, mod);
0196
0197 return 0;
0198 }
0199
0200 static int rsnd_dvc_quit(struct rsnd_mod *mod,
0201 struct rsnd_dai_stream *io,
0202 struct rsnd_priv *priv)
0203 {
0204 rsnd_dvc_halt(mod);
0205
0206 rsnd_mod_power_off(mod);
0207
0208 return 0;
0209 }
0210
0211 static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
0212 struct rsnd_dai_stream *io,
0213 struct snd_soc_pcm_runtime *rtd)
0214 {
0215 struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
0216 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
0217 int is_play = rsnd_io_is_play(io);
0218 int channels = rsnd_rdai_channels_get(rdai);
0219 int ret;
0220
0221
0222 ret = rsnd_kctrl_new_m(mod, io, rtd,
0223 is_play ?
0224 "DVC Out Playback Volume" : "DVC In Capture Volume",
0225 rsnd_kctrl_accept_anytime,
0226 rsnd_dvc_volume_update,
0227 &dvc->volume, channels,
0228 0x00800000 - 1);
0229 if (ret < 0)
0230 return ret;
0231
0232
0233 ret = rsnd_kctrl_new_m(mod, io, rtd,
0234 is_play ?
0235 "DVC Out Mute Switch" : "DVC In Mute Switch",
0236 rsnd_kctrl_accept_anytime,
0237 rsnd_dvc_volume_update,
0238 &dvc->mute, channels,
0239 1);
0240 if (ret < 0)
0241 return ret;
0242
0243
0244 ret = rsnd_kctrl_new_s(mod, io, rtd,
0245 is_play ?
0246 "DVC Out Ramp Switch" : "DVC In Ramp Switch",
0247 rsnd_kctrl_accept_anytime,
0248 rsnd_dvc_volume_update,
0249 &dvc->ren, 1);
0250 if (ret < 0)
0251 return ret;
0252
0253 ret = rsnd_kctrl_new_e(mod, io, rtd,
0254 is_play ?
0255 "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate",
0256 rsnd_kctrl_accept_anytime,
0257 rsnd_dvc_volume_update,
0258 &dvc->rup,
0259 volume_ramp_rate,
0260 VOLUME_RAMP_MAX_DVC);
0261 if (ret < 0)
0262 return ret;
0263
0264 ret = rsnd_kctrl_new_e(mod, io, rtd,
0265 is_play ?
0266 "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate",
0267 rsnd_kctrl_accept_anytime,
0268 rsnd_dvc_volume_update,
0269 &dvc->rdown,
0270 volume_ramp_rate,
0271 VOLUME_RAMP_MAX_DVC);
0272
0273 if (ret < 0)
0274 return ret;
0275
0276 return 0;
0277 }
0278
0279 static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_dai_stream *io,
0280 struct rsnd_mod *mod)
0281 {
0282 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
0283
0284 return rsnd_dma_request_channel(rsnd_dvc_of_node(priv),
0285 DVC_NAME, mod, "tx");
0286 }
0287
0288 #ifdef CONFIG_DEBUG_FS
0289 static void rsnd_dvc_debug_info(struct seq_file *m,
0290 struct rsnd_dai_stream *io,
0291 struct rsnd_mod *mod)
0292 {
0293 rsnd_debugfs_mod_reg_show(m, mod, RSND_GEN2_SCU,
0294 0xe00 + rsnd_mod_id(mod) * 0x100, 0x60);
0295 }
0296 #define DEBUG_INFO .debug_info = rsnd_dvc_debug_info
0297 #else
0298 #define DEBUG_INFO
0299 #endif
0300
0301 static struct rsnd_mod_ops rsnd_dvc_ops = {
0302 .name = DVC_NAME,
0303 .dma_req = rsnd_dvc_dma_req,
0304 .probe = rsnd_dvc_probe_,
0305 .init = rsnd_dvc_init,
0306 .quit = rsnd_dvc_quit,
0307 .pcm_new = rsnd_dvc_pcm_new,
0308 .get_status = rsnd_mod_get_status,
0309 DEBUG_INFO
0310 };
0311
0312 struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id)
0313 {
0314 if (WARN_ON(id < 0 || id >= rsnd_dvc_nr(priv)))
0315 id = 0;
0316
0317 return rsnd_mod_get(rsnd_dvc_get(priv, id));
0318 }
0319
0320 int rsnd_dvc_probe(struct rsnd_priv *priv)
0321 {
0322 struct device_node *node;
0323 struct device_node *np;
0324 struct device *dev = rsnd_priv_to_dev(priv);
0325 struct rsnd_dvc *dvc;
0326 struct clk *clk;
0327 char name[RSND_DVC_NAME_SIZE];
0328 int i, nr, ret;
0329
0330
0331 if (rsnd_is_gen1(priv))
0332 return 0;
0333
0334 node = rsnd_dvc_of_node(priv);
0335 if (!node)
0336 return 0;
0337
0338 nr = of_get_child_count(node);
0339 if (!nr) {
0340 ret = -EINVAL;
0341 goto rsnd_dvc_probe_done;
0342 }
0343
0344 dvc = devm_kcalloc(dev, nr, sizeof(*dvc), GFP_KERNEL);
0345 if (!dvc) {
0346 ret = -ENOMEM;
0347 goto rsnd_dvc_probe_done;
0348 }
0349
0350 priv->dvc_nr = nr;
0351 priv->dvc = dvc;
0352
0353 i = 0;
0354 ret = 0;
0355 for_each_child_of_node(node, np) {
0356 dvc = rsnd_dvc_get(priv, i);
0357
0358 snprintf(name, RSND_DVC_NAME_SIZE, "%s.%d",
0359 DVC_NAME, i);
0360
0361 clk = devm_clk_get(dev, name);
0362 if (IS_ERR(clk)) {
0363 ret = PTR_ERR(clk);
0364 of_node_put(np);
0365 goto rsnd_dvc_probe_done;
0366 }
0367
0368 ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops,
0369 clk, RSND_MOD_DVC, i);
0370 if (ret) {
0371 of_node_put(np);
0372 goto rsnd_dvc_probe_done;
0373 }
0374
0375 i++;
0376 }
0377
0378 rsnd_dvc_probe_done:
0379 of_node_put(node);
0380
0381 return ret;
0382 }
0383
0384 void rsnd_dvc_remove(struct rsnd_priv *priv)
0385 {
0386 struct rsnd_dvc *dvc;
0387 int i;
0388
0389 for_each_rsnd_dvc(dvc, priv, i) {
0390 rsnd_mod_quit(rsnd_mod_get(dvc));
0391 }
0392 }