ASoC: rsnd: add rsnd_runtime_channel_xxx()
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Thu, 25 Feb 2016 05:54:58 +0000 (05:54 +0000)
committerMark Brown <broonie@kernel.org>
Sat, 5 Mar 2016 04:27:27 +0000 (13:27 +0900)
Current SSI is supporting Normal SSI/Multi mode SSI/TDM mode SSI
and its behavior is based on input channels.
This input channel might be converted by CTU,
and SSI needs to be Multi SSI mode / TDM SSI mode if 6ch input

EX) 6ch input, CTU for 2ch, playback

 6ch    6ch    2ch    2ch    2ch     2ch
 -> SRC -> CTU -> MIX -> DVC -> SSIU -> SSI

EX) 6ch input, no CTU, Multi SSI, playback

 6ch    6ch    6ch    6ch    6ch     2ch
 -> SRC -> CTU -> MIX -> DVC -> SSIU -> SSI0/SSI1/SSI2

Current driver is using rsnd_get_adinr_chan() / rsnd_get_slot_width()
for this purpose, but it is complicated enough without meaning.
This patch adds new rsnd_runtime_channel_xxx() which is caring
CTU/Multi SSI.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sh/rcar/core.c
sound/soc/sh/rcar/ctu.c
sound/soc/sh/rcar/dvc.c
sound/soc/sh/rcar/mix.c
sound/soc/sh/rcar/rsnd.h
sound/soc/sh/rcar/src.c
sound/soc/sh/rcar/ssi.c
sound/soc/sh/rcar/ssiu.c

index 3a3dc2ff18c9e163e8347a554812c826a5523caa..3351a701c60ee3525b1b441908d7f8bcb628e8f0 100644 (file)
@@ -224,13 +224,36 @@ int rsnd_get_slot_num(struct rsnd_dai_stream *io)
        return rdai->slots_num;
 }
 
-int rsnd_get_slot_width(struct rsnd_dai_stream *io)
+int rsnd_runtime_channel_original(struct rsnd_dai_stream *io)
 {
        struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
-       int chan = runtime->channels;
 
-       /* Multi channel Mode */
-       if (rsnd_ssi_multi_slaves_runtime(io))
+       return runtime->channels;
+}
+
+int rsnd_runtime_channel_after_ctu(struct rsnd_dai_stream *io)
+{
+       int chan = rsnd_runtime_channel_original(io);
+       struct rsnd_mod *ctu_mod = rsnd_io_to_mod_ctu(io);
+
+       if (ctu_mod) {
+               u32 converted_chan = rsnd_ctu_converted_channel(ctu_mod);
+
+               if (converted_chan)
+                       return converted_chan;
+       }
+
+       return chan;
+}
+
+int rsnd_runtime_channel_for_ssi(struct rsnd_dai_stream *io)
+{
+       int chan = rsnd_io_is_play(io) ?
+               rsnd_runtime_channel_after_ctu(io) :
+               rsnd_runtime_channel_original(io);
+
+       /* Use Multi SSI */
+       if (rsnd_runtime_is_ssi_multi(io))
                chan /= rsnd_get_slot_num(io);
 
        /* TDM Extend Mode needs 8ch */
@@ -240,6 +263,21 @@ int rsnd_get_slot_width(struct rsnd_dai_stream *io)
        return chan;
 }
 
+int rsnd_runtime_is_ssi_multi(struct rsnd_dai_stream *io)
+{
+       int slots = rsnd_get_slot_num(io);
+       int chan = rsnd_io_is_play(io) ?
+               rsnd_runtime_channel_after_ctu(io) :
+               rsnd_runtime_channel_original(io);
+
+       return (chan >= 6) && (slots > 1);
+}
+
+int rsnd_runtime_is_ssi_tdm(struct rsnd_dai_stream *io)
+{
+       return rsnd_runtime_channel_for_ssi(io) >= 6;
+}
+
 /*
  *     ADINR function
  */
@@ -261,29 +299,6 @@ u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
        return 0;
 }
 
-u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
-{
-       struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
-       struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
-       struct device *dev = rsnd_priv_to_dev(priv);
-       u32 chan = runtime->channels;
-
-       switch (chan) {
-       case 1:
-       case 2:
-       case 4:
-       case 6:
-       case 8:
-               break;
-       default:
-               dev_warn(dev, "not supported channel\n");
-               chan = 0;
-               break;
-       }
-
-       return chan;
-}
-
 /*
  *     DALIGN function
  */
index 784515afefaffe71033b668a2d29db6c5c8f5c16..b326966ea407ce9d076140082176c085a67b5e37 100644 (file)
@@ -60,7 +60,7 @@ static void rsnd_ctu_value_init(struct rsnd_dai_stream *io,
 {
        rsnd_mod_write(mod, CTU_CTUIR, 1);
 
-       rsnd_mod_write(mod, CTU_ADINR, rsnd_get_adinr_chan(mod, io));
+       rsnd_mod_write(mod, CTU_ADINR, rsnd_runtime_channel_original(io));
 
        rsnd_mod_write(mod, CTU_CPMDR, 0);
        rsnd_mod_write(mod, CTU_SCMDR, 0);
index d757f131638587cd90e11451a6a5e67adba93e87..93b11e1c5d7f1a3c5c47ee2406ac1bc3582d19fb 100644 (file)
@@ -116,7 +116,7 @@ static void rsnd_dvc_volume_init(struct rsnd_dai_stream *io,
        u32 vrdbr = 0;
 
        adinr = rsnd_get_adinr_bit(mod, io) |
-               rsnd_get_adinr_chan(mod, io);
+               rsnd_runtime_channel_after_ctu(io);
 
        /* Enable Digital Volume, Zero Cross Mute Mode */
        dvucr |= 0x101;
index e0e337ad4206a7a114f7ab3d4caca96ccf923e5d..195fc7bb22afb6519fb574af7b28832d2defda6b 100644 (file)
@@ -51,7 +51,7 @@ static void rsnd_mix_volume_init(struct rsnd_dai_stream *io,
        rsnd_mod_write(mod, MIX_MIXIR, 1);
 
        /* General Information */
-       rsnd_mod_write(mod, MIX_ADINR, rsnd_get_adinr_chan(mod, io));
+       rsnd_mod_write(mod, MIX_ADINR, rsnd_runtime_channel_after_ctu(io));
 
        /* volume step */
        rsnd_mod_write(mod, MIX_MIXMR, 0);
index bbc89bd1e9188e1ceb636d3fdd24454f0568c405..ff53f96e500606cff6c72fe063b634464b9bd073 100644 (file)
@@ -193,7 +193,6 @@ void rsnd_force_write(struct rsnd_priv *priv, struct rsnd_mod *mod,
 void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg,
                    u32 mask, u32 data);
 u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
-u32 rsnd_get_adinr_chan(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
 u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
 
 /*
@@ -356,9 +355,14 @@ void rsnd_parse_connect_common(struct rsnd_dai *rdai,
 void rsnd_set_slot(struct rsnd_dai *rdai,
                   int slots, int slots_total);
 int rsnd_get_slot(struct rsnd_dai_stream *io);
-int rsnd_get_slot_width(struct rsnd_dai_stream *io);
 int rsnd_get_slot_num(struct rsnd_dai_stream *io);
 
+int rsnd_runtime_channel_original(struct rsnd_dai_stream *io);
+int rsnd_runtime_channel_after_ctu(struct rsnd_dai_stream *io);
+int rsnd_runtime_channel_for_ssi(struct rsnd_dai_stream *io);
+int rsnd_runtime_is_ssi_multi(struct rsnd_dai_stream *io);
+int rsnd_runtime_is_ssi_tdm(struct rsnd_dai_stream *io);
+
 /*
  *     R-Car sound DAI
  */
index 03c6314871ff6846f3a34bcb3f8a6f61eee418af..8e1177aea6b1e581b8d4018adf8832391c570f53 100644 (file)
@@ -205,7 +205,7 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
         *      SRC_ADINR
         */
        adinr = rsnd_get_adinr_bit(mod, io) |
-               rsnd_get_adinr_chan(mod, io);
+               rsnd_runtime_channel_original(io);
 
        /*
         *      SRC_IFSCR / SRC_IFSVR
index 0979db8af8f9d59b085705e865152e2026499f08..5404897553673450b5af201633f87ff24b89c71a 100644 (file)
@@ -180,11 +180,8 @@ static u32 rsnd_ssi_run_mods(struct rsnd_dai_stream *io)
 
 u32 rsnd_ssi_multi_slaves_runtime(struct rsnd_dai_stream *io)
 {
-       struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
-       u32 mask = rsnd_ssi_multi_slaves(io);
-
-       if (mask && (runtime->channels >= 6))
-               return mask;
+       if (rsnd_runtime_is_ssi_multi(io))
+               return rsnd_ssi_multi_slaves(io);
 
        return 0;
 }
@@ -198,7 +195,7 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod,
        struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
        struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
        struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io);
-       int slots = rsnd_get_slot_width(io);
+       int chan = rsnd_runtime_channel_for_ssi(io);
        int j, ret;
        int ssi_clk_mul_table[] = {
                1, 2, 4, 8, 16, 6, 12,
@@ -231,10 +228,10 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod,
 
                /*
                 * this driver is assuming that
-                * system word is 32bit x slots
+                * system word is 32bit x chan
                 * see rsnd_ssi_init()
                 */
-               main_rate = rate * 32 * slots * ssi_clk_mul_table[j];
+               main_rate = rate * 32 * chan * ssi_clk_mul_table[j];
 
                ret = rsnd_adg_ssi_clk_try_start(mod, main_rate);
                if (0 == ret) {
@@ -289,7 +286,7 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod,
        u32 wsr;
        int is_tdm;
 
-       is_tdm = (rsnd_get_slot_width(io) >= 6) ? 1 : 0;
+       is_tdm = rsnd_runtime_is_ssi_tdm(io);
 
        /*
         * always use 32bit system word.
index 0d964a0a3e31af5318878723602f68bd5e7ecee1..6f9b388ec5a8f0c2095a2a88e33d725244706b2e 100644 (file)
@@ -105,7 +105,7 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
        if (ret < 0)
                return ret;
 
-       if (rsnd_get_slot_width(io) >= 6) {
+       if (rsnd_runtime_is_ssi_tdm(io)) {
                /*
                 * TDM Extend Mode
                 * see
@@ -117,7 +117,9 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
        if (rsnd_ssi_use_busif(io)) {
                rsnd_mod_write(mod, SSI_BUSIF_ADINR,
                               rsnd_get_adinr_bit(mod, io) |
-                              rsnd_get_adinr_chan(mod, io));
+                              (rsnd_io_is_play(io) ?
+                               rsnd_runtime_channel_after_ctu(io) :
+                               rsnd_runtime_channel_original(io)));
                rsnd_mod_write(mod, SSI_BUSIF_MODE,  1);
                rsnd_mod_write(mod, SSI_BUSIF_DALIGN,
                               rsnd_get_dalign(mod, io));