linux/sound/soc/sh/rcar/dvc.c
<<
>>
Prefs
   1/*
   2 * Renesas R-Car DVC support
   3 *
   4 * Copyright (C) 2014 Renesas Solutions Corp.
   5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 */
  11
  12/*
  13 * Playback Volume
  14 *      amixer set "DVC Out" 100%
  15 *
  16 * Capture Volume
  17 *      amixer set "DVC In" 100%
  18 *
  19 * Playback Mute
  20 *      amixer set "DVC Out Mute" on
  21 *
  22 * Capture Mute
  23 *      amixer set "DVC In Mute" on
  24 *
  25 * Volume Ramp
  26 *      amixer set "DVC Out Ramp Up Rate"   "0.125 dB/64 steps"
  27 *      amixer set "DVC Out Ramp Down Rate" "0.125 dB/512 steps"
  28 *      amixer set "DVC Out Ramp" on
  29 *      aplay xxx.wav &
  30 *      amixer set "DVC Out"  80%  // Volume Down
  31 *      amixer set "DVC Out" 100%  // Volume Up
  32 */
  33
  34#include "rsnd.h"
  35
  36#define RSND_DVC_NAME_SIZE      16
  37
  38#define DVC_NAME "dvc"
  39
  40struct rsnd_dvc {
  41        struct rsnd_mod mod;
  42        struct rsnd_kctrl_cfg_m volume;
  43        struct rsnd_kctrl_cfg_m mute;
  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 rdown;  /* Ramp Rate Down */
  47        u32 flags;
  48};
  49
  50#define KCTRL_INITIALIZED       (1 << 0)
  51
  52#define rsnd_dvc_get(priv, id) ((struct rsnd_dvc *)(priv->dvc) + id)
  53#define rsnd_dvc_nr(priv) ((priv)->dvc_nr)
  54
  55#define rsnd_mod_to_dvc(_mod)   \
  56        container_of((_mod), struct rsnd_dvc, mod)
  57
  58#define for_each_rsnd_dvc(pos, priv, i)                         \
  59        for ((i) = 0;                                           \
  60             ((i) < rsnd_dvc_nr(priv)) &&                       \
  61             ((pos) = (struct rsnd_dvc *)(priv)->dvc + i);      \
  62             i++)
  63
  64static void rsnd_dvc_activation(struct rsnd_mod *mod)
  65{
  66        rsnd_mod_write(mod, DVC_SWRSR, 0);
  67        rsnd_mod_write(mod, DVC_SWRSR, 1);
  68}
  69
  70static void rsnd_dvc_halt(struct rsnd_mod *mod)
  71{
  72        rsnd_mod_write(mod, DVC_DVUIR, 1);
  73        rsnd_mod_write(mod, DVC_SWRSR, 0);
  74}
  75
  76#define rsnd_dvc_get_vrpdr(dvc) (rsnd_kctrl_vals(dvc->rup) << 8 | \
  77                                 rsnd_kctrl_vals(dvc->rdown))
  78#define rsnd_dvc_get_vrdbr(dvc) (0x3ff - (rsnd_kctrl_valm(dvc->volume, 0) >> 13))
  79
  80static void rsnd_dvc_volume_parameter(struct rsnd_dai_stream *io,
  81                                              struct rsnd_mod *mod)
  82{
  83        struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
  84        u32 val[RSND_MAX_CHANNELS];
  85        int i;
  86
  87        /* Enable Ramp */
  88        if (rsnd_kctrl_vals(dvc->ren))
  89                for (i = 0; i < RSND_MAX_CHANNELS; i++)
  90                        val[i] = rsnd_kctrl_max(dvc->volume);
  91        else
  92                for (i = 0; i < RSND_MAX_CHANNELS; i++)
  93                        val[i] = rsnd_kctrl_valm(dvc->volume, i);
  94
  95        /* Enable Digital Volume */
  96        rsnd_mod_write(mod, DVC_VOL0R, val[0]);
  97        rsnd_mod_write(mod, DVC_VOL1R, val[1]);
  98        rsnd_mod_write(mod, DVC_VOL2R, val[2]);
  99        rsnd_mod_write(mod, DVC_VOL3R, val[3]);
 100        rsnd_mod_write(mod, DVC_VOL4R, val[4]);
 101        rsnd_mod_write(mod, DVC_VOL5R, val[5]);
 102        rsnd_mod_write(mod, DVC_VOL6R, val[6]);
 103        rsnd_mod_write(mod, DVC_VOL7R, val[7]);
 104}
 105
 106static void rsnd_dvc_volume_init(struct rsnd_dai_stream *io,
 107                                 struct rsnd_mod *mod)
 108{
 109        struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
 110        u32 adinr = 0;
 111        u32 dvucr = 0;
 112        u32 vrctr = 0;
 113        u32 vrpdr = 0;
 114        u32 vrdbr = 0;
 115
 116        adinr = rsnd_get_adinr_bit(mod, io) |
 117                rsnd_runtime_channel_after_ctu(io);
 118
 119        /* Enable Digital Volume, Zero Cross Mute Mode */
 120        dvucr |= 0x101;
 121
 122        /* Enable Ramp */
 123        if (rsnd_kctrl_vals(dvc->ren)) {
 124                dvucr |= 0x10;
 125
 126                /*
 127                 * FIXME !!
 128                 * use scale-downed Digital Volume
 129                 * as Volume Ramp
 130                 * 7F FFFF -> 3FF
 131                 */
 132                vrctr = 0xff;
 133                vrpdr = rsnd_dvc_get_vrpdr(dvc);
 134                vrdbr = rsnd_dvc_get_vrdbr(dvc);
 135        }
 136
 137        /* Initialize operation */
 138        rsnd_mod_write(mod, DVC_DVUIR, 1);
 139
 140        /* General Information */
 141        rsnd_mod_write(mod, DVC_ADINR, adinr);
 142        rsnd_mod_write(mod, DVC_DVUCR, dvucr);
 143
 144        /* Volume Ramp Parameter */
 145        rsnd_mod_write(mod, DVC_VRCTR, vrctr);
 146        rsnd_mod_write(mod, DVC_VRPDR, vrpdr);
 147        rsnd_mod_write(mod, DVC_VRDBR, vrdbr);
 148
 149        /* Digital Volume Function Parameter */
 150        rsnd_dvc_volume_parameter(io, mod);
 151
 152        /* cancel operation */
 153        rsnd_mod_write(mod, DVC_DVUIR, 0);
 154}
 155
 156static void rsnd_dvc_volume_update(struct rsnd_dai_stream *io,
 157                                   struct rsnd_mod *mod)
 158{
 159        struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
 160        u32 zcmcr = 0;
 161        u32 vrpdr = 0;
 162        u32 vrdbr = 0;
 163        int i;
 164
 165        for (i = 0; i < rsnd_kctrl_size(dvc->mute); i++)
 166                zcmcr |= (!!rsnd_kctrl_valm(dvc->mute, i)) << i;
 167
 168        if (rsnd_kctrl_vals(dvc->ren)) {
 169                vrpdr = rsnd_dvc_get_vrpdr(dvc);
 170                vrdbr = rsnd_dvc_get_vrdbr(dvc);
 171        }
 172
 173        /* Disable DVC Register access */
 174        rsnd_mod_write(mod, DVC_DVUER, 0);
 175
 176        /* Zero Cross Mute Function */
 177        rsnd_mod_write(mod, DVC_ZCMCR, zcmcr);
 178
 179        /* Volume Ramp Function */
 180        rsnd_mod_write(mod, DVC_VRPDR, vrpdr);
 181        rsnd_mod_write(mod, DVC_VRDBR, vrdbr);
 182        /* add DVC_VRWTR here */
 183
 184        /* Digital Volume Function Parameter */
 185        rsnd_dvc_volume_parameter(io, mod);
 186
 187        /* Enable DVC Register access */
 188        rsnd_mod_write(mod, DVC_DVUER, 1);
 189}
 190
 191static int rsnd_dvc_probe_(struct rsnd_mod *mod,
 192                           struct rsnd_dai_stream *io,
 193                           struct rsnd_priv *priv)
 194{
 195        return rsnd_cmd_attach(io, rsnd_mod_id(mod));
 196}
 197
 198static int rsnd_dvc_init(struct rsnd_mod *mod,
 199                         struct rsnd_dai_stream *io,
 200                         struct rsnd_priv *priv)
 201{
 202        rsnd_mod_power_on(mod);
 203
 204        rsnd_dvc_activation(mod);
 205
 206        rsnd_dvc_volume_init(io, mod);
 207
 208        rsnd_dvc_volume_update(io, mod);
 209
 210        return 0;
 211}
 212
 213static int rsnd_dvc_quit(struct rsnd_mod *mod,
 214                         struct rsnd_dai_stream *io,
 215                         struct rsnd_priv *priv)
 216{
 217        rsnd_dvc_halt(mod);
 218
 219        rsnd_mod_power_off(mod);
 220
 221        return 0;
 222}
 223
 224static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
 225                            struct rsnd_dai_stream *io,
 226                            struct snd_soc_pcm_runtime *rtd)
 227{
 228        struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod);
 229        struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
 230        int is_play = rsnd_io_is_play(io);
 231        int channels = rsnd_rdai_channels_get(rdai);
 232        int ret;
 233
 234        if (rsnd_flags_has(dvc, KCTRL_INITIALIZED))
 235                return 0;
 236
 237        /* Volume */
 238        ret = rsnd_kctrl_new_m(mod, io, rtd,
 239                        is_play ?
 240                        "DVC Out Playback Volume" : "DVC In Capture Volume",
 241                        rsnd_kctrl_accept_anytime,
 242                        rsnd_dvc_volume_update,
 243                        &dvc->volume, channels,
 244                        0x00800000 - 1);
 245        if (ret < 0)
 246                return ret;
 247
 248        /* Mute */
 249        ret = rsnd_kctrl_new_m(mod, io, rtd,
 250                        is_play ?
 251                        "DVC Out Mute Switch" : "DVC In Mute Switch",
 252                        rsnd_kctrl_accept_anytime,
 253                        rsnd_dvc_volume_update,
 254                        &dvc->mute, channels,
 255                        1);
 256        if (ret < 0)
 257                return ret;
 258
 259        /* Ramp */
 260        ret = rsnd_kctrl_new_s(mod, io, rtd,
 261                        is_play ?
 262                        "DVC Out Ramp Switch" : "DVC In Ramp Switch",
 263                        rsnd_kctrl_accept_anytime,
 264                        rsnd_dvc_volume_update,
 265                        &dvc->ren, 1);
 266        if (ret < 0)
 267                return ret;
 268
 269        ret = rsnd_kctrl_new_e(mod, io, rtd,
 270                        is_play ?
 271                        "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate",
 272                        rsnd_kctrl_accept_anytime,
 273                        rsnd_dvc_volume_update,
 274                        &dvc->rup,
 275                        volume_ramp_rate,
 276                        VOLUME_RAMP_MAX_DVC);
 277        if (ret < 0)
 278                return ret;
 279
 280        ret = rsnd_kctrl_new_e(mod, io, rtd,
 281                        is_play ?
 282                        "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate",
 283                        rsnd_kctrl_accept_anytime,
 284                        rsnd_dvc_volume_update,
 285                        &dvc->rdown,
 286                        volume_ramp_rate,
 287                        VOLUME_RAMP_MAX_DVC);
 288
 289        if (ret < 0)
 290                return ret;
 291
 292        rsnd_flags_set(dvc, KCTRL_INITIALIZED);
 293
 294        return 0;
 295}
 296
 297static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_dai_stream *io,
 298                                         struct rsnd_mod *mod)
 299{
 300        struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
 301
 302        return rsnd_dma_request_channel(rsnd_dvc_of_node(priv),
 303                                        mod, "tx");
 304}
 305
 306static struct rsnd_mod_ops rsnd_dvc_ops = {
 307        .name           = DVC_NAME,
 308        .dma_req        = rsnd_dvc_dma_req,
 309        .probe          = rsnd_dvc_probe_,
 310        .init           = rsnd_dvc_init,
 311        .quit           = rsnd_dvc_quit,
 312        .pcm_new        = rsnd_dvc_pcm_new,
 313};
 314
 315struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id)
 316{
 317        if (WARN_ON(id < 0 || id >= rsnd_dvc_nr(priv)))
 318                id = 0;
 319
 320        return rsnd_mod_get(rsnd_dvc_get(priv, id));
 321}
 322
 323int rsnd_dvc_probe(struct rsnd_priv *priv)
 324{
 325        struct device_node *node;
 326        struct device_node *np;
 327        struct device *dev = rsnd_priv_to_dev(priv);
 328        struct rsnd_dvc *dvc;
 329        struct clk *clk;
 330        char name[RSND_DVC_NAME_SIZE];
 331        int i, nr, ret;
 332
 333        /* This driver doesn't support Gen1 at this point */
 334        if (rsnd_is_gen1(priv))
 335                return 0;
 336
 337        node = rsnd_dvc_of_node(priv);
 338        if (!node)
 339                return 0; /* not used is not error */
 340
 341        nr = of_get_child_count(node);
 342        if (!nr) {
 343                ret = -EINVAL;
 344                goto rsnd_dvc_probe_done;
 345        }
 346
 347        dvc     = devm_kcalloc(dev, nr, sizeof(*dvc), GFP_KERNEL);
 348        if (!dvc) {
 349                ret = -ENOMEM;
 350                goto rsnd_dvc_probe_done;
 351        }
 352
 353        priv->dvc_nr    = nr;
 354        priv->dvc       = dvc;
 355
 356        i = 0;
 357        ret = 0;
 358        for_each_child_of_node(node, np) {
 359                dvc = rsnd_dvc_get(priv, i);
 360
 361                snprintf(name, RSND_DVC_NAME_SIZE, "%s.%d",
 362                         DVC_NAME, i);
 363
 364                clk = devm_clk_get(dev, name);
 365                if (IS_ERR(clk)) {
 366                        ret = PTR_ERR(clk);
 367                        of_node_put(np);
 368                        goto rsnd_dvc_probe_done;
 369                }
 370
 371                ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops,
 372                                    clk, rsnd_mod_get_status, RSND_MOD_DVC, i);
 373                if (ret) {
 374                        of_node_put(np);
 375                        goto rsnd_dvc_probe_done;
 376                }
 377
 378                i++;
 379        }
 380
 381rsnd_dvc_probe_done:
 382        of_node_put(node);
 383
 384        return ret;
 385}
 386
 387void rsnd_dvc_remove(struct rsnd_priv *priv)
 388{
 389        struct rsnd_dvc *dvc;
 390        int i;
 391
 392        for_each_rsnd_dvc(dvc, priv, i) {
 393                rsnd_mod_quit(rsnd_mod_get(dvc));
 394        }
 395}
 396