Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // Renesas R-Car DVC support
0004 //
0005 // Copyright (C) 2014 Renesas Solutions Corp.
0006 // Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
0007 
0008 /*
0009  * Playback Volume
0010  *  amixer set "DVC Out" 100%
0011  *
0012  * Capture Volume
0013  *  amixer set "DVC In" 100%
0014  *
0015  * Playback Mute
0016  *  amixer set "DVC Out Mute" on
0017  *
0018  * Capture Mute
0019  *  amixer set "DVC In Mute" on
0020  *
0021  * Volume Ramp
0022  *  amixer set "DVC Out Ramp Up Rate"   "0.125 dB/64 steps"
0023  *  amixer set "DVC Out Ramp Down Rate" "0.125 dB/512 steps"
0024  *  amixer set "DVC Out Ramp" on
0025  *  aplay xxx.wav &
0026  *  amixer set "DVC Out"  80%  // Volume Down
0027  *  amixer set "DVC Out" 100%  // Volume Up
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;    /* Ramp Enable */
0041     struct rsnd_kctrl_cfg_s rup;    /* Ramp Rate Up */
0042     struct rsnd_kctrl_cfg_s rdown;  /* Ramp Rate Down */
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     /* Enable Ramp */
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     /* Enable Digital Volume */
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     /* Enable Digital Volume, Zero Cross Mute Mode */
0107     dvucr |= 0x101;
0108 
0109     /* Enable Ramp */
0110     if (rsnd_kctrl_vals(dvc->ren)) {
0111         dvucr |= 0x10;
0112 
0113         /*
0114          * FIXME !!
0115          * use scale-downed Digital Volume
0116          * as Volume Ramp
0117          * 7F FFFF -> 3FF
0118          */
0119         vrctr = 0xff;
0120         vrpdr = rsnd_dvc_get_vrpdr(dvc);
0121         vrdbr = rsnd_dvc_get_vrdbr(dvc);
0122     }
0123 
0124     /* Initialize operation */
0125     rsnd_mod_write(mod, DVC_DVUIR, 1);
0126 
0127     /* General Information */
0128     rsnd_mod_write(mod, DVC_ADINR, adinr);
0129     rsnd_mod_write(mod, DVC_DVUCR, dvucr);
0130 
0131     /* Volume Ramp Parameter */
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     /* Digital Volume Function Parameter */
0137     rsnd_dvc_volume_parameter(io, mod);
0138 
0139     /* cancel operation */
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     /* Disable DVC Register access */
0161     rsnd_mod_write(mod, DVC_DVUER, 0);
0162 
0163     /* Zero Cross Mute Function */
0164     rsnd_mod_write(mod, DVC_ZCMCR, zcmcr);
0165 
0166     /* Volume Ramp Function */
0167     rsnd_mod_write(mod, DVC_VRPDR, vrpdr);
0168     rsnd_mod_write(mod, DVC_VRDBR, vrdbr);
0169     /* add DVC_VRWTR here */
0170 
0171     /* Digital Volume Function Parameter */
0172     rsnd_dvc_volume_parameter(io, mod);
0173 
0174     /* Enable DVC Register access */
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     /* Volume */
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     /* Mute */
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     /* Ramp */
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     /* This driver doesn't support Gen1 at this point */
0331     if (rsnd_is_gen1(priv))
0332         return 0;
0333 
0334     node = rsnd_dvc_of_node(priv);
0335     if (!node)
0336         return 0; /* not used is not error */
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 }