]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'topic/update-bits' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorMark Brown <broonie@kernel.org>
Wed, 2 Mar 2016 03:58:58 +0000 (12:58 +0900)
committerMark Brown <broonie@kernel.org>
Wed, 2 Mar 2016 03:58:58 +0000 (12:58 +0900)
1  2 
sound/soc/sh/rcar/core.c
sound/soc/sh/rcar/gen.c
sound/soc/sh/rcar/src.c

diff --combined sound/soc/sh/rcar/core.c
index 7bc5b724fbf5331bc64f61e21a556f1c55aaa005,02b4b085b8d77f57398a13c35214a49445d1ed77..21e13b3a356fbb402cfc7ed6350005f88a483c25
@@@ -138,22 -138,12 +138,22 @@@ struct dma_chan *rsnd_mod_dma_req(struc
        return mod->ops->dma_req(io, mod);
  }
  
 +u32 *rsnd_mod_get_status(struct rsnd_dai_stream *io,
 +                       struct rsnd_mod *mod,
 +                       enum rsnd_mod_type type)
 +{
 +      return &mod->status;
 +}
 +
  int rsnd_mod_init(struct rsnd_priv *priv,
                  struct rsnd_mod *mod,
 -                 struct rsnd_mod_ops *ops,
 -                 struct clk *clk,
 -                 enum rsnd_mod_type type,
 -                 int id)
 +                struct rsnd_mod_ops *ops,
 +                struct clk *clk,
 +                u32* (*get_status)(struct rsnd_dai_stream *io,
 +                                   struct rsnd_mod *mod,
 +                                   enum rsnd_mod_type type),
 +                enum rsnd_mod_type type,
 +                int id)
  {
        int ret = clk_prepare(clk);
  
        mod->type       = type;
        mod->clk        = clk;
        mod->priv       = priv;
 +      mod->get_status = get_status;
  
        return ret;
  }
@@@ -174,7 -163,6 +174,7 @@@ void rsnd_mod_quit(struct rsnd_mod *mod
  {
        if (mod->clk)
                clk_unprepare(mod->clk);
 +      mod->clk = NULL;
  }
  
  void rsnd_mod_interrupt(struct rsnd_mod *mod,
@@@ -230,7 -218,7 +230,7 @@@ int rsnd_get_slot_width(struct rsnd_dai
        int chan = runtime->channels;
  
        /* Multi channel Mode */
 -      if (rsnd_ssi_multi_slaves(io))
 +      if (rsnd_ssi_multi_slaves_runtime(io))
                chan /= rsnd_get_slot_num(io);
  
        /* TDM Extend Mode needs 8ch */
@@@ -336,73 -324,31 +336,73 @@@ u32 rsnd_get_dalign(struct rsnd_mod *mo
        struct rsnd_priv *priv = rsnd_mod_to_priv(mod);         \
        struct rsnd_mod *mod = (io)->mod[idx];                  \
        struct device *dev = rsnd_priv_to_dev(priv);            \
 -      u32 *status = (io)->mod_status + idx;                   \
 +      u32 *status = mod->get_status(io, mod, idx);                    \
        u32 mask = 0xF << __rsnd_mod_shift_##func;                      \
        u8 val  = (*status >> __rsnd_mod_shift_##func) & 0xF;           \
        u8 add  = ((val + __rsnd_mod_add_##func) & 0xF);                \
        int ret = 0;                                                    \
        int call = (val == __rsnd_mod_call_##func) && (mod)->ops->func; \
 -      *status = (*status & ~mask) +                                   \
 -              (add << __rsnd_mod_shift_##func);                       \
 +      if (add == 0xF)                                                 \
 +              call = 0;                                               \
 +      else                                                            \
 +              *status = (*status & ~mask) +                           \
 +                      (add << __rsnd_mod_shift_##func);               \
        dev_dbg(dev, "%s[%d]\t0x%08x %s\n",                             \
                rsnd_mod_name(mod), rsnd_mod_id(mod),                   \
                *status, call ? #func : "");                            \
        if (call)                                                       \
                ret = (mod)->ops->func(mod, io, param);                 \
 +      if (ret)                                                        \
 +              dev_dbg(dev, "%s[%d] : rsnd_mod_call error %d\n",       \
 +                      rsnd_mod_name(mod), rsnd_mod_id(mod), ret);     \
        ret;                                                            \
  })
  
 +static enum rsnd_mod_type rsnd_mod_sequence[][RSND_MOD_MAX] = {
 +      {
 +              /* CAPTURE */
 +              RSND_MOD_AUDMAPP,
 +              RSND_MOD_AUDMA,
 +              RSND_MOD_DVC,
 +              RSND_MOD_MIX,
 +              RSND_MOD_CTU,
 +              RSND_MOD_CMD,
 +              RSND_MOD_SRC,
 +              RSND_MOD_SSIU,
 +              RSND_MOD_SSIM3,
 +              RSND_MOD_SSIM2,
 +              RSND_MOD_SSIM1,
 +              RSND_MOD_SSIP,
 +              RSND_MOD_SSI,
 +      }, {
 +              /* PLAYBACK */
 +              RSND_MOD_AUDMAPP,
 +              RSND_MOD_AUDMA,
 +              RSND_MOD_SSIM3,
 +              RSND_MOD_SSIM2,
 +              RSND_MOD_SSIM1,
 +              RSND_MOD_SSIP,
 +              RSND_MOD_SSI,
 +              RSND_MOD_SSIU,
 +              RSND_MOD_DVC,
 +              RSND_MOD_MIX,
 +              RSND_MOD_CTU,
 +              RSND_MOD_CMD,
 +              RSND_MOD_SRC,
 +      },
 +};
 +
  #define rsnd_dai_call(fn, io, param...)                               \
  ({                                                            \
        struct rsnd_mod *mod;                                   \
 +      int type, is_play = rsnd_io_is_play(io);                \
        int ret = 0, i;                                         \
        for (i = 0; i < RSND_MOD_MAX; i++) {                    \
 -              mod = (io)->mod[i];                             \
 +              type = rsnd_mod_sequence[is_play][i];           \
 +              mod = (io)->mod[type];                          \
                if (!mod)                                       \
                        continue;                               \
 -              ret |= rsnd_mod_call(i, io, fn, param);         \
 +              ret |= rsnd_mod_call(type, io, fn, param);      \
        }                                                       \
        ret;                                                    \
  })
@@@ -417,9 -363,6 +417,9 @@@ int rsnd_dai_connect(struct rsnd_mod *m
        if (!mod)
                return -EIO;
  
 +      if (io->mod[type] == mod)
 +              return 0;
 +
        if (io->mod[type])
                return -EINVAL;
  
@@@ -568,16 -511,9 +568,16 @@@ static int rsnd_soc_dai_trigger(struct 
                ret = rsnd_dai_call(start, io, priv);
                if (ret < 0)
                        goto dai_trigger_end;
 +
 +              ret = rsnd_dai_call(irq, io, priv, 1);
 +              if (ret < 0)
 +                      goto dai_trigger_end;
 +
                break;
        case SNDRV_PCM_TRIGGER_STOP:
 -              ret = rsnd_dai_call(stop, io, priv);
 +              ret = rsnd_dai_call(irq, io, priv, 0);
 +
 +              ret |= rsnd_dai_call(stop, io, priv);
  
                ret |= rsnd_dai_call(quit, io, priv);
  
@@@ -941,14 -877,13 +941,13 @@@ static int __rsnd_kctrl_new(struct rsnd
                            void (*update)(struct rsnd_dai_stream *io,
                                           struct rsnd_mod *mod))
  {
-       struct snd_soc_card *soc_card = rtd->card;
        struct snd_card *card = rtd->card->snd_card;
        struct snd_kcontrol *kctrl;
        struct snd_kcontrol_new knew = {
                .iface          = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name           = name,
                .info           = rsnd_kctrl_info,
-               .index          = rtd - soc_card->rtd,
+               .index          = rtd->num,
                .get            = rsnd_kctrl_get,
                .put            = rsnd_kctrl_put,
                .private_value  = (unsigned long)cfg,
@@@ -988,7 -923,7 +987,7 @@@ int rsnd_kctrl_new_m(struct rsnd_mod *m
                     int ch_size,
                     u32 max)
  {
 -      if (ch_size > RSND_DVC_CHANNELS)
 +      if (ch_size > RSND_MAX_CHANNELS)
                return -EINVAL;
  
        _cfg->cfg.max   = max;
diff --combined sound/soc/sh/rcar/gen.c
index b6e487e060192ee1f27776388fb411d97d6dea5a,ea24247eba73c2fffc8bfdb4c56f2c6d7c9268c5..271d29adac68d2b3b010f588378c00a70a08d589
@@@ -251,7 -251,7 +251,7 @@@ static int rsnd_gen2_probe(struct rsnd_
                RSND_GEN_S_REG(SCU_SYS_STATUS0, 0x1c8),
                RSND_GEN_S_REG(SCU_SYS_INT_EN0, 0x1cc),
                RSND_GEN_S_REG(SCU_SYS_STATUS1, 0x1d0),
-               RSND_GEN_S_REG(SCU_SYS_INT_EN1, 0x1c4),
+               RSND_GEN_S_REG(SCU_SYS_INT_EN1, 0x1d4),
                RSND_GEN_M_REG(SRC_SWRSR,       0x200,  0x40),
                RSND_GEN_M_REG(SRC_SRCIR,       0x204,  0x40),
                RSND_GEN_M_REG(SRC_ADINR,       0x214,  0x40),
                RSND_GEN_M_REG(SRC_SRCCR,       0x224,  0x40),
                RSND_GEN_M_REG(SRC_BSDSR,       0x22c,  0x40),
                RSND_GEN_M_REG(SRC_BSISR,       0x238,  0x40),
 +              RSND_GEN_M_REG(CTU_SWRSR,       0x500,  0x100),
                RSND_GEN_M_REG(CTU_CTUIR,       0x504,  0x100),
                RSND_GEN_M_REG(CTU_ADINR,       0x508,  0x100),
 +              RSND_GEN_M_REG(CTU_CPMDR,       0x510,  0x100),
 +              RSND_GEN_M_REG(CTU_SCMDR,       0x514,  0x100),
 +              RSND_GEN_M_REG(CTU_SV00R,       0x518,  0x100),
 +              RSND_GEN_M_REG(CTU_SV01R,       0x51c,  0x100),
 +              RSND_GEN_M_REG(CTU_SV02R,       0x520,  0x100),
 +              RSND_GEN_M_REG(CTU_SV03R,       0x524,  0x100),
 +              RSND_GEN_M_REG(CTU_SV04R,       0x528,  0x100),
 +              RSND_GEN_M_REG(CTU_SV05R,       0x52c,  0x100),
 +              RSND_GEN_M_REG(CTU_SV06R,       0x530,  0x100),
 +              RSND_GEN_M_REG(CTU_SV07R,       0x534,  0x100),
 +              RSND_GEN_M_REG(CTU_SV10R,       0x538,  0x100),
 +              RSND_GEN_M_REG(CTU_SV11R,       0x53c,  0x100),
 +              RSND_GEN_M_REG(CTU_SV12R,       0x540,  0x100),
 +              RSND_GEN_M_REG(CTU_SV13R,       0x544,  0x100),
 +              RSND_GEN_M_REG(CTU_SV14R,       0x548,  0x100),
 +              RSND_GEN_M_REG(CTU_SV15R,       0x54c,  0x100),
 +              RSND_GEN_M_REG(CTU_SV16R,       0x550,  0x100),
 +              RSND_GEN_M_REG(CTU_SV17R,       0x554,  0x100),
 +              RSND_GEN_M_REG(CTU_SV20R,       0x558,  0x100),
 +              RSND_GEN_M_REG(CTU_SV21R,       0x55c,  0x100),
 +              RSND_GEN_M_REG(CTU_SV22R,       0x560,  0x100),
 +              RSND_GEN_M_REG(CTU_SV23R,       0x564,  0x100),
 +              RSND_GEN_M_REG(CTU_SV24R,       0x568,  0x100),
 +              RSND_GEN_M_REG(CTU_SV25R,       0x56c,  0x100),
 +              RSND_GEN_M_REG(CTU_SV26R,       0x570,  0x100),
 +              RSND_GEN_M_REG(CTU_SV27R,       0x574,  0x100),
 +              RSND_GEN_M_REG(CTU_SV30R,       0x578,  0x100),
 +              RSND_GEN_M_REG(CTU_SV31R,       0x57c,  0x100),
 +              RSND_GEN_M_REG(CTU_SV32R,       0x580,  0x100),
 +              RSND_GEN_M_REG(CTU_SV33R,       0x584,  0x100),
 +              RSND_GEN_M_REG(CTU_SV34R,       0x588,  0x100),
 +              RSND_GEN_M_REG(CTU_SV35R,       0x58c,  0x100),
 +              RSND_GEN_M_REG(CTU_SV36R,       0x590,  0x100),
 +              RSND_GEN_M_REG(CTU_SV37R,       0x594,  0x100),
                RSND_GEN_M_REG(MIX_SWRSR,       0xd00,  0x40),
                RSND_GEN_M_REG(MIX_MIXIR,       0xd04,  0x40),
                RSND_GEN_M_REG(MIX_ADINR,       0xd08,  0x40),
diff --combined sound/soc/sh/rcar/src.c
index dab0954196b7f1734e94a9da6de02e4cb99b59b3,5eda056d9f20ed8ef3137da612c63ae9d2cba067..03c6314871ff6846f3a34bcb3f8a6f61eee418af
@@@ -25,6 -25,7 +25,6 @@@ struct rsnd_src 
        struct rsnd_kctrl_cfg_s sen;  /* sync convert enable */
        struct rsnd_kctrl_cfg_s sync; /* sync convert */
        u32 convert_rate; /* sampling rate convert */
 -      int err;
        int irq;
  };
  
@@@ -249,8 -250,6 +249,8 @@@ static void rsnd_src_set_convert_rate(s
                break;
        }
  
 +      rsnd_mod_write(mod, SRC_ROUTE_MODE0, route);
 +
        rsnd_mod_write(mod, SRC_SRCIR, 1);      /* initialize */
        rsnd_mod_write(mod, SRC_ADINR, adinr);
        rsnd_mod_write(mod, SRC_IFSCR, ifscr);
        rsnd_mod_write(mod, SRC_BSISR, bsisr);
        rsnd_mod_write(mod, SRC_SRCIR, 0);      /* cancel initialize */
  
 -      rsnd_mod_write(mod, SRC_ROUTE_MODE0, route);
        rsnd_mod_write(mod, SRC_I_BUSIF_MODE, 1);
        rsnd_mod_write(mod, SRC_O_BUSIF_MODE, 1);
        rsnd_mod_write(mod, SRC_BUSIF_DALIGN, rsnd_get_dalign(mod, io));
                rsnd_adg_set_convert_timing_gen2(mod, io);
  }
  
 -#define rsnd_src_irq_enable(mod)  rsnd_src_irq_ctrol(mod, 1)
 -#define rsnd_src_irq_disable(mod) rsnd_src_irq_ctrol(mod, 0)
 -static void rsnd_src_irq_ctrol(struct rsnd_mod *mod, int enable)
 +static int rsnd_src_irq(struct rsnd_mod *mod,
 +                      struct rsnd_dai_stream *io,
 +                      struct rsnd_priv *priv,
 +                      int enable)
  {
        struct rsnd_src *src = rsnd_mod_to_src(mod);
        u32 sys_int_val, int_val, sys_int_mask;
        rsnd_mod_write(mod, SRC_INT_ENABLE0, int_val);
        rsnd_mod_bset(mod, SCU_SYS_INT_EN0, sys_int_mask, sys_int_val);
        rsnd_mod_bset(mod, SCU_SYS_INT_EN1, sys_int_mask, sys_int_val);
 +
 +      return 0;
  }
  
  static void rsnd_src_status_clear(struct rsnd_mod *mod)
        rsnd_mod_bset(mod, SCU_SYS_STATUS1, val, val);
  }
  
 -static bool rsnd_src_record_error(struct rsnd_mod *mod)
 +static bool rsnd_src_error_occurred(struct rsnd_mod *mod)
  {
        struct rsnd_src *src = rsnd_mod_to_src(mod);
        u32 val0, val1;
                val0 = val0 & 0xffff;
  
        if ((rsnd_mod_read(mod, SCU_SYS_STATUS0) & val0) ||
 -          (rsnd_mod_read(mod, SCU_SYS_STATUS1) & val1)) {
 -              struct rsnd_src *src = rsnd_mod_to_src(mod);
 -
 -              src->err++;
 +          (rsnd_mod_read(mod, SCU_SYS_STATUS1) & val1))
                ret = true;
 -      }
  
        return ret;
  }
@@@ -366,7 -367,11 +366,7 @@@ static int rsnd_src_stop(struct rsnd_mo
                         struct rsnd_dai_stream *io,
                         struct rsnd_priv *priv)
  {
 -      /*
 -       * stop SRC output only
 -       * see rsnd_src_quit
 -       */
 -      rsnd_mod_write(mod, SRC_CTRL, 0x01);
 +      rsnd_mod_write(mod, SRC_CTRL, 0);
  
        return 0;
  }
@@@ -385,6 -390,10 +385,6 @@@ static int rsnd_src_init(struct rsnd_mo
  
        rsnd_src_status_clear(mod);
  
 -      rsnd_src_irq_enable(mod);
 -
 -      src->err = 0;
 -
        /* reset sync convert_rate */
        src->sync.val = 0;
  
@@@ -396,11 -405,21 +396,11 @@@ static int rsnd_src_quit(struct rsnd_mo
                         struct rsnd_priv *priv)
  {
        struct rsnd_src *src = rsnd_mod_to_src(mod);
 -      struct device *dev = rsnd_priv_to_dev(priv);
 -
 -      rsnd_src_irq_disable(mod);
 -
 -      /* stop both out/in */
 -      rsnd_mod_write(mod, SRC_CTRL, 0);
  
        rsnd_src_halt(mod);
  
        rsnd_mod_power_off(mod);
  
 -      if (src->err)
 -              dev_warn(dev, "%s[%d] under/over flow err = %d\n",
 -                       rsnd_mod_name(mod), rsnd_mod_id(mod), src->err);
 -
        src->convert_rate = 0;
  
        /* reset sync convert_rate */
@@@ -413,7 -432,8 +413,7 @@@ static void __rsnd_src_interrupt(struc
                                 struct rsnd_dai_stream *io)
  {
        struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
 -      struct rsnd_src *src = rsnd_mod_to_src(mod);
 -      struct device *dev = rsnd_priv_to_dev(priv);
 +      bool stop = false;
  
        spin_lock(&priv->lock);
  
        if (!rsnd_io_is_working(io))
                goto rsnd_src_interrupt_out;
  
 -      if (rsnd_src_record_error(mod)) {
 -
 -              dev_dbg(dev, "%s[%d] restart\n",
 -                      rsnd_mod_name(mod), rsnd_mod_id(mod));
 -
 -              rsnd_src_stop(mod, io, priv);
 -              rsnd_src_start(mod, io, priv);
 -      }
 -
 -      if (src->err > 1024) {
 -              rsnd_src_irq_disable(mod);
 -
 -              dev_warn(dev, "no more %s[%d] restart\n",
 -                       rsnd_mod_name(mod), rsnd_mod_id(mod));
 -      }
 +      if (rsnd_src_error_occurred(mod))
 +              stop = true;
  
        rsnd_src_status_clear(mod);
  rsnd_src_interrupt_out:
  
        spin_unlock(&priv->lock);
 +
 +      if (stop)
 +              snd_pcm_stop_xrun(io->substream);
  }
  
  static irqreturn_t rsnd_src_interrupt(int irq, void *data)
@@@ -455,7 -485,7 +455,7 @@@ static int rsnd_src_probe_(struct rsnd_
                /*
                 * IRQ is not supported on non-DT
                 * see
 -               *      rsnd_src_irq_enable()
 +               *      rsnd_src_irq()
                 */
                ret = devm_request_irq(dev, irq,
                                       rsnd_src_interrupt,
                        return ret;
        }
  
 -      src->dma = rsnd_dma_attach(io, mod, 0);
 -      if (IS_ERR(src->dma))
 -              return PTR_ERR(src->dma);
 +      ret = rsnd_dma_attach(io, mod, &src->dma, 0);
  
        return ret;
  }
@@@ -475,6 -507,7 +475,7 @@@ static int rsnd_src_pcm_new(struct rsnd
                            struct snd_soc_pcm_runtime *rtd)
  {
        struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
+       struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
        struct rsnd_src *src = rsnd_mod_to_src(mod);
        int ret;
  
        if (!rsnd_rdai_is_clk_master(rdai))
                return 0;
  
+       /*
+        * SRC In doesn't work if DVC was enabled
+        */
+       if (dvc && !rsnd_io_is_play(io))
+               return 0;
        /*
         * enable sync convert
         */
@@@ -518,7 -557,6 +525,7 @@@ static struct rsnd_mod_ops rsnd_src_op
        .quit   = rsnd_src_quit,
        .start  = rsnd_src_start,
        .stop   = rsnd_src_stop,
 +      .irq    = rsnd_src_irq,
        .hw_params = rsnd_src_hw_params,
        .pcm_new = rsnd_src_pcm_new,
  };
@@@ -584,8 -622,7 +591,8 @@@ int rsnd_src_probe(struct rsnd_priv *pr
                }
  
                ret = rsnd_mod_init(priv, rsnd_mod_get(src),
 -                                  &rsnd_src_ops, clk, RSND_MOD_SRC, i);
 +                                  &rsnd_src_ops, clk, rsnd_mod_get_status,
 +                                  RSND_MOD_SRC, i);
                if (ret)
                        goto rsnd_src_probe_done;