Merge remote-tracking branches 'asoc/topic/pxa', 'asoc/topic/qcom', 'asoc/topic/rcar...
authorMark Brown <broonie@kernel.org>
Wed, 23 Dec 2015 00:23:46 +0000 (00:23 +0000)
committerMark Brown <broonie@kernel.org>
Wed, 23 Dec 2015 00:23:46 +0000 (00:23 +0000)
1  2  3  4  5  6 
sound/soc/codecs/Kconfig
sound/soc/codecs/Makefile
sound/soc/sh/rcar/core.c
sound/soc/sh/rcar/gen.c
sound/soc/sh/rcar/rsrc-card.c
sound/soc/sh/rcar/src.c

@@@@@@@ -59,8 -58,7 -57,6 -58,7 -58,7 -58,7 +59,8 @@@@@@@ config SND_SOC_ALL_CODEC
        select SND_SOC_CX20442 if TTY
        select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI
        select SND_SOC_DA7213 if I2C
 +++++  select SND_SOC_DA7218 if I2C
  +     select SND_SOC_DA7219 if I2C
        select SND_SOC_DA732X if I2C
        select SND_SOC_DA9055 if I2C
        select SND_SOC_DMIC
        select SND_SOC_ES8328_SPI if SPI_MASTER
        select SND_SOC_ES8328_I2C if I2C
        select SND_SOC_GTM601
 +++++  select SND_SOC_HDAC_HDMI
        select SND_SOC_ICS43432
++++ +  select SND_SOC_INNO_RK3036
        select SND_SOC_ISABELLE if I2C
        select SND_SOC_JZ4740_CODEC
        select SND_SOC_LM4857 if I2C
@@@@@@@ -204,8 -198,7 -195,6 -198,7 -199,7 -198,7 +205,8 @@@@@@@ config SND_SOC_ARIZON
        default y if SND_SOC_WM5102=y
        default y if SND_SOC_WM5110=y
        default y if SND_SOC_WM8997=y
  +     default y if SND_SOC_WM8998=y
 +++++  default m if SND_SOC_CS47L24=m
        default m if SND_SOC_WM5102=m
        default m if SND_SOC_WM5110=m
        default m if SND_SOC_WM8997=m
@@@@@@@ -452,12 -439,9 -430,6 -439,9 -440,9 -439,9 +453,12 @@@@@@@ config SND_SOC_DA721
      config SND_SOC_DA7213
              tristate
      
 +++++config SND_SOC_DA7218
 +++++  tristate
 +++++
  +   config SND_SOC_DA7219
  +           tristate
  +   
      config SND_SOC_DA732X
              tristate
      
@@@@@@@ -51,8 -50,7 -49,6 -50,7 -50,7 -50,7 +51,8 @@@@@@@ snd-soc-cs47l24-objs := cs47l24.
      snd-soc-cx20442-objs := cx20442.o
      snd-soc-da7210-objs := da7210.o
      snd-soc-da7213-objs := da7213.o
 +++++snd-soc-da7218-objs := da7218.o
  +   snd-soc-da7219-objs := da7219.o da7219-aad.o
      snd-soc-da732x-objs := da732x.o
      snd-soc-da9055-objs := da9055.o
      snd-soc-bt-sco-objs := bt-sco.o
@@@@@@@ -61,8 -59,7 -57,7 -59,7 -59,8 -59,7 +61,9 @@@@@@@ snd-soc-es8328-objs := es8328.
      snd-soc-es8328-i2c-objs := es8328-i2c.o
      snd-soc-es8328-spi-objs := es8328-spi.o
      snd-soc-gtm601-objs := gtm601.o
 +++++snd-soc-hdac-hdmi-objs := hdac_hdmi.o
      snd-soc-ics43432-objs := ics43432.o
++++ +snd-soc-inno-rk3036-objs := inno_rk3036.o
      snd-soc-isabelle-objs := isabelle.o
      snd-soc-jz4740-codec-objs := jz4740.o
      snd-soc-l3-objs := l3.o
@@@@@@@ -252,8 -245,7 -241,6 -245,7 -246,7 -245,7 +253,8 @@@@@@@ obj-$(CONFIG_SND_SOC_CS47L24)  += snd-so
      obj-$(CONFIG_SND_SOC_CX20442)     += snd-soc-cx20442.o
      obj-$(CONFIG_SND_SOC_DA7210)      += snd-soc-da7210.o
      obj-$(CONFIG_SND_SOC_DA7213)      += snd-soc-da7213.o
 +++++obj-$(CONFIG_SND_SOC_DA7218)      += snd-soc-da7218.o
  +   obj-$(CONFIG_SND_SOC_DA7219)      += snd-soc-da7219.o
      obj-$(CONFIG_SND_SOC_DA732X)      += snd-soc-da732x.o
      obj-$(CONFIG_SND_SOC_DA9055)      += snd-soc-da9055.o
      obj-$(CONFIG_SND_SOC_BT_SCO)      += snd-soc-bt-sco.o
@@@@@@@ -262,8 -254,7 -249,7 -254,7 -255,8 -254,7 +263,9 @@@@@@@ obj-$(CONFIG_SND_SOC_ES8328)   += snd-soc
      obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o
      obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o
      obj-$(CONFIG_SND_SOC_GTM601)    += snd-soc-gtm601.o
 +++++obj-$(CONFIG_SND_SOC_HDAC_HDMI) += snd-soc-hdac-hdmi.o
      obj-$(CONFIG_SND_SOC_ICS43432)    += snd-soc-ics43432.o
++++ +obj-$(CONFIG_SND_SOC_INNO_RK3036) += snd-soc-inno-rk3036.o
      obj-$(CONFIG_SND_SOC_ISABELLE)    += snd-soc-isabelle.o
      obj-$(CONFIG_SND_SOC_JZ4740_CODEC)        += snd-soc-jz4740-codec.o
      obj-$(CONFIG_SND_SOC_L3)  += snd-soc-l3.o
      #define RSND_RATES SNDRV_PCM_RATE_8000_96000
      #define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
      
--- --static const struct rsnd_of_data rsnd_of_data_gen1 = {
--- --  .flags = RSND_GEN1,
--- --};
--- --
--- --static const struct rsnd_of_data rsnd_of_data_gen2 = {
--- --  .flags = RSND_GEN2,
--- --};
--- --
      static const struct of_device_id rsnd_of_match[] = {
--- --  { .compatible = "renesas,rcar_sound-gen1", .data = &rsnd_of_data_gen1 },
--- --  { .compatible = "renesas,rcar_sound-gen2", .data = &rsnd_of_data_gen2 },
--  --  { .compatible = "renesas,rcar_sound-gen3", .data = &rsnd_of_data_gen2 }, /* gen2 compatible */
+++ ++  { .compatible = "renesas,rcar_sound-gen1", .data = (void *)RSND_GEN1 },
+++ ++  { .compatible = "renesas,rcar_sound-gen2", .data = (void *)RSND_GEN2 },
+++ ++  { .compatible = "renesas,rcar_sound-gen3", .data = (void *)RSND_GEN2 }, /* gen2 compatible */
        {},
      };
      MODULE_DEVICE_TABLE(of, rsnd_of_match);
      
      /*
--- -- *        rsnd_platform functions
+++ ++ *        rsnd_mod functions
       */
--- --#define rsnd_platform_call(priv, dai, func, param...)     \
--- --  (!(priv->info->func) ? 0 :              \
--- --   priv->info->func(param))
--  --
--  --#define rsnd_is_enable_path(io, name) \
--  --  ((io)->info ? (io)->info->name : NULL)
--  --#define rsnd_info_id(priv, io, name) \
--  --  ((io)->info->name - priv->info->name##_info)
--  --
  +   void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type)
  +   {
  +     if (mod->type != type) {
  +             struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
  +             struct device *dev = rsnd_priv_to_dev(priv);
      
  -   #define rsnd_is_enable_path(io, name) \
  -     ((io)->info ? (io)->info->name : NULL)
  -   #define rsnd_info_id(priv, io, name) \
  -     ((io)->info->name - priv->info->name##_info)
  +             dev_warn(dev, "%s[%d] is not your expected module\n",
  +                      rsnd_mod_name(mod), rsnd_mod_id(mod));
  +     }
  +   }
      
--- --/*
--- -- *        rsnd_mod functions
--- -- */
      char *rsnd_mod_name(struct rsnd_mod *mod)
      {
        if (!mod || !mod->ops)
@@@@@@@ -300,22 -300,22 -288,24 -319,24 -300,22 -300,22 +319,24 @@@@@@@ u32 rsnd_get_dalign(struct rsnd_mod *mo
      /*
       *        rsnd_dai functions
       */
--  --#define rsnd_mod_call(mod, io, func, param...)                    \
  -   #define __rsnd_mod_call(mod, io, func, param...)          \
+++ ++#define rsnd_mod_call(idx, io, func, param...)                    \
      ({                                                                \
        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 mask = 0xF << __rsnd_mod_shift_##func;                      \
--- --  u8 val  = (mod->status >> __rsnd_mod_shift_##func) & 0xF;       \
+++ ++  u8 val  = (*status >> __rsnd_mod_shift_##func) & 0xF;           \
        u8 add  = ((val + __rsnd_mod_add_##func) & 0xF);                \
        int ret = 0;                                                    \
  -     int called = 0;                                                 \
  -     if (val == __rsnd_mod_call_##func) {                            \
  -             called = 1;                                             \
  -             ret = (mod)->ops->func(mod, io, param);                 \
  -     }                                                               \
  -     mod->status = (mod->status & ~mask) +                           \
  +     int call = (val == __rsnd_mod_call_##func) && (mod)->ops->func; \
--  --  mod->status = (mod->status & ~mask) +                           \
+++ ++  *status = (*status & ~mask) +                                   \
                (add << __rsnd_mod_shift_##func);                       \
  -     dev_dbg(dev, "%s[%d] 0x%08x %s\n",                              \
  -             rsnd_mod_name(mod), rsnd_mod_id(mod), mod->status,      \
  -             called ? #func : "");                                   \
  +     dev_dbg(dev, "%s[%d]\t0x%08x %s\n",                             \
  +             rsnd_mod_name(mod), rsnd_mod_id(mod),                   \
--  --          mod->status, call ? #func : "");                        \
+++ ++          *status, call ? #func : "");                            \
  +     if (call)                                                       \
  +             ret = (mod)->ops->func(mod, io, param);                 \
        ret;                                                            \
      })
      
                mod = (io)->mod[i];                             \
                if (!mod)                                       \
                        continue;                               \
--  --          ret |= rsnd_mod_call(mod, io, fn, param);       \
  -             ret = rsnd_mod_call(mod, io, fn, param);        \
  -             if (ret < 0)                                    \
  -                     break;                                  \
+++ ++          ret |= rsnd_mod_call(i, io, fn, param);         \
        }                                                       \
        ret;                                                    \
      })
@@@@@@@ -493,11 -493,11 -490,17 -514,9 -493,11 -493,11 +514,9 @@@@@@@ static int rsnd_soc_dai_trigger(struct 
                break;
        case SNDRV_PCM_TRIGGER_STOP:
                ret = rsnd_dai_call(stop, io, priv);
  -             if (ret < 0)
  -                     goto dai_trigger_end;
  -   
  -             ret = rsnd_dai_call(quit, io, priv);
  -             if (ret < 0)
  -                     goto dai_trigger_end;
      
  -             ret = rsnd_platform_call(priv, dai, stop, ssi_id);
  -             if (ret < 0)
  -                     goto dai_trigger_end;
  +             ret |= rsnd_dai_call(quit, io, priv);
      
--  --          ret |= rsnd_platform_call(priv, dai, stop, ssi_id);
--  --
                rsnd_dai_stream_quit(io);
                break;
        default:
@@@@@@@ -567,220 -567,220 -570,220 -586,90 -567,220 -567,220 +586,90 @@@@@@@ static int rsnd_soc_dai_set_fmt(struct 
        return 0;
      }
      
--- --static const struct snd_soc_dai_ops rsnd_soc_dai_ops = {
--- --  .trigger        = rsnd_soc_dai_trigger,
--- --  .set_fmt        = rsnd_soc_dai_set_fmt,
--- --};
--- --
--- --#define rsnd_path_add(priv, io, type)                             \
--- --({                                                                \
--- --  struct rsnd_mod *mod;                                   \
--- --  int ret = 0;                                            \
--- --  int id = -1;                                            \
--- --                                                          \
--- --  if (rsnd_is_enable_path(io, type)) {                    \
--- --          id = rsnd_info_id(priv, io, type);              \
--- --          if (id >= 0) {                                  \
--- --                  mod = rsnd_##type##_mod_get(priv, id);  \
--- --                  ret = rsnd_dai_connect(mod, io);        \
--- --          }                                               \
--- --  }                                                       \
--- --  ret;                                                    \
--- --})
--- --
--- --#define rsnd_path_remove(priv, io, type)                  \
--- --{                                                         \
--- --  struct rsnd_mod *mod;                                   \
--- --  int id = -1;                                            \
--- --                                                          \
--- --  if (rsnd_is_enable_path(io, type)) {                    \
--- --          id = rsnd_info_id(priv, io, type);              \
--- --          if (id >= 0) {                                  \
--- --                  mod = rsnd_##type##_mod_get(priv, id);  \
--- --                  rsnd_dai_disconnect(mod, io);           \
--- --          }                                               \
--- --  }                                                       \
--- --}
--- --
--- --void rsnd_path_parse(struct rsnd_priv *priv,
--- --               struct rsnd_dai_stream *io)
+++ ++static int rsnd_soc_set_dai_tdm_slot(struct snd_soc_dai *dai,
+++ ++                               u32 tx_mask, u32 rx_mask,
+++ ++                               int slots, int slot_width)
      {
--- --  struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
--- --  struct rsnd_mod *mix = rsnd_io_to_mod_mix(io);
--- --  struct rsnd_mod *src = rsnd_io_to_mod_src(io);
--- --  struct rsnd_mod *cmd;
+++ ++  struct rsnd_priv *priv = rsnd_dai_to_priv(dai);
+++ ++  struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
        struct device *dev = rsnd_priv_to_dev(priv);
--- --  u32 data;
  -   
  -     /* Gen1 is not supported */
  -     if (rsnd_is_gen1(priv))
  -             return;
  -   
  -     if (!mix && !dvc)
  -             return;
  -   
  -     if (mix) {
  -             struct rsnd_dai *rdai;
  -             int i;
  -             u32 path[] = {
  -                     [0] = 0,
  -                     [1] = 1 << 0,
  -                     [2] = 0,
  -                     [3] = 0,
  -                     [4] = 0,
  -                     [5] = 1 << 8
  -             };
  -   
  -             /*
  -              * it is assuming that integrater is well understanding about
  -              * data path. Here doesn't check impossible connection,
  -              * like src2 + src5
  -              */
  -             data = 0;
  -             for_each_rsnd_dai(rdai, priv, i) {
  -                     io = &rdai->playback;
  -                     if (mix == rsnd_io_to_mod_mix(io))
  -                             data |= path[rsnd_mod_id(src)];
  -   
  -                     io = &rdai->capture;
  -                     if (mix == rsnd_io_to_mod_mix(io))
  -                             data |= path[rsnd_mod_id(src)];
  -             }
      
--  --  /* Gen1 is not supported */
--  --  if (rsnd_is_gen1(priv))
--  --          return;
--  --
--  --  if (!mix && !dvc)
--  --          return;
--  --
--  --  if (mix) {
--  --          struct rsnd_dai *rdai;
--  --          int i;
--  --          u32 path[] = {
--  --                  [0] = 0,
--  --                  [1] = 1 << 0,
--  --                  [2] = 0,
--  --                  [3] = 0,
--  --                  [4] = 0,
--  --                  [5] = 1 << 8
--  --          };
--  --
--  --          /*
--  --           * it is assuming that integrater is well understanding about
--  --           * data path. Here doesn't check impossible connection,
--  --           * like src2 + src5
--  --           */
--  --          data = 0;
--  --          for_each_rsnd_dai(rdai, priv, i) {
--  --                  io = &rdai->playback;
--  --                  if (mix == rsnd_io_to_mod_mix(io))
--  --                          data |= path[rsnd_mod_id(src)];
--  --
--  --                  io = &rdai->capture;
--  --                  if (mix == rsnd_io_to_mod_mix(io))
--  --                          data |= path[rsnd_mod_id(src)];
--  --          }
--  --
--- --          /*
--- --           * We can't use ctu = rsnd_io_ctu() here.
--- --           * Since, ID of dvc/mix are 0 or 1 (= same as CMD number)
--- --           * but ctu IDs are 0 - 7 (= CTU00 - CTU13)
--- --           */
--- --          cmd = mix;
--- --  } else {
--- --          u32 path[] = {
--- --                  [0] = 0x30000,
--- --                  [1] = 0x30001,
--- --                  [2] = 0x40000,
--- --                  [3] = 0x10000,
--- --                  [4] = 0x20000,
--- --                  [5] = 0x40100
--- --          };
--- --
--- --          data = path[rsnd_mod_id(src)];
--- --
--- --          cmd = dvc;
+++ ++  switch (slots) {
+++ ++  case 6:
+++ ++          /* TDM Extend Mode */
+++ ++          rsnd_set_slot(rdai, slots, 1);
+++ ++          break;
+++ ++  default:
+++ ++          dev_err(dev, "unsupported TDM slots (%d)\n", slots);
+++ ++          return -EINVAL;
        }
      
--- --  dev_dbg(dev, "ctu/mix path = 0x%08x", data);
--- --
--- --  rsnd_mod_write(cmd, CMD_ROUTE_SLCT, data);
--- --
--- --  rsnd_mod_write(cmd, CMD_CTRL, 0x10);
+++ ++  return 0;
      }
      
--- --static int rsnd_path_init(struct rsnd_priv *priv,
--- --                    struct rsnd_dai *rdai,
--- --                    struct rsnd_dai_stream *io)
--- --{
--- --  int ret;
--- --
--- --  /*
--- --   * Gen1 is created by SRU/SSI, and this SRU is base module of
--- --   * Gen2's SCU/SSIU/SSI. (Gen2 SCU/SSIU came from SRU)
--- --   *
--- --   * Easy image is..
--- --   *      Gen1 SRU = Gen2 SCU + SSIU + etc
--- --   *
--- --   * Gen2 SCU path is very flexible, but, Gen1 SRU (SCU parts) is
--- --   * using fixed path.
--- --   */
--- --
--- --  /* SSI */
--- --  ret = rsnd_path_add(priv, io, ssi);
--- --  if (ret < 0)
--- --          return ret;
--- --
--- --  /* SRC */
--- --  ret = rsnd_path_add(priv, io, src);
--- --  if (ret < 0)
--- --          return ret;
+++ ++static const struct snd_soc_dai_ops rsnd_soc_dai_ops = {
+++ ++  .trigger        = rsnd_soc_dai_trigger,
+++ ++  .set_fmt        = rsnd_soc_dai_set_fmt,
+++ ++  .set_tdm_slot   = rsnd_soc_set_dai_tdm_slot,
+++ ++};
      
--- --  /* CTU */
--- --  ret = rsnd_path_add(priv, io, ctu);
--- --  if (ret < 0)
--- --          return ret;
+++ ++void rsnd_parse_connect_common(struct rsnd_dai *rdai,
+++ ++          struct rsnd_mod* (*mod_get)(struct rsnd_priv *priv, int id),
+++ ++          struct device_node *node,
+++ ++          struct device_node *playback,
+++ ++          struct device_node *capture)
+++ ++{
+++ ++  struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai);
+++ ++  struct device_node *np;
+++ ++  struct rsnd_mod *mod;
+++ ++  int i;
      
--- --  /* MIX */
--- --  ret = rsnd_path_add(priv, io, mix);
--- --  if (ret < 0)
--- --          return ret;
+++ ++  if (!node)
+++ ++          return;
      
--- --  /* DVC */
--- --  ret = rsnd_path_add(priv, io, dvc);
--- --  if (ret < 0)
--- --          return ret;
+++ ++  i = 0;
+++ ++  for_each_child_of_node(node, np) {
+++ ++          mod = mod_get(priv, i);
+++ ++          if (np == playback)
+++ ++                  rsnd_dai_connect(mod, &rdai->playback, mod->type);
+++ ++          if (np == capture)
+++ ++                  rsnd_dai_connect(mod, &rdai->capture, mod->type);
+++ ++          i++;
+++ ++  }
      
--- --  return ret;
+++ ++  of_node_put(node);
      }
      
--- --static void rsnd_of_parse_dai(struct platform_device *pdev,
--- --                        const struct rsnd_of_data *of_data,
--- --                        struct rsnd_priv *priv)
+++ ++static int rsnd_dai_probe(struct rsnd_priv *priv)
      {
--- --  struct device_node *dai_node,   *dai_np;
--- --  struct device_node *ssi_node,   *ssi_np;
--- --  struct device_node *src_node,   *src_np;
--- --  struct device_node *ctu_node,   *ctu_np;
--- --  struct device_node *mix_node,   *mix_np;
--- --  struct device_node *dvc_node,   *dvc_np;
+++ ++  struct device_node *dai_node;
+++ ++  struct device_node *dai_np;
        struct device_node *playback, *capture;
--- --  struct rsnd_dai_platform_info *dai_info;
--- --  struct rcar_snd_info *info = rsnd_priv_to_info(priv);
--- --  struct device *dev = &pdev->dev;
--- --  int nr, i;
--- --  int dai_i, ssi_i, src_i, ctu_i, mix_i, dvc_i;
--- --
--- --  if (!of_data)
--- --          return;
--- --
--- --  dai_node = of_get_child_by_name(dev->of_node, "rcar_sound,dai");
--- --  if (!dai_node)
--- --          return;
+++ ++  struct rsnd_dai_stream *io_playback;
+++ ++  struct rsnd_dai_stream *io_capture;
+++ ++  struct snd_soc_dai_driver *rdrv, *drv;
+++ ++  struct rsnd_dai *rdai;
+++ ++  struct device *dev = rsnd_priv_to_dev(priv);
+++ ++  int nr, dai_i, io_i;
+++ ++  int ret;
      
+++ ++  dai_node = rsnd_dai_of_node(priv);
        nr = of_get_child_count(dai_node);
--- --  if (!nr)
--- --          return;
+++ ++  if (!nr) {
+++ ++          ret = -EINVAL;
+++ ++          goto rsnd_dai_probe_done;
+++ ++  }
      
--- --  dai_info = devm_kzalloc(dev,
--- --                          sizeof(struct rsnd_dai_platform_info) * nr,
--- --                          GFP_KERNEL);
--- --  if (!dai_info) {
--- --          dev_err(dev, "dai info allocation error\n");
--- --          return;
+++ ++  rdrv = devm_kzalloc(dev, sizeof(*rdrv) * nr, GFP_KERNEL);
+++ ++  rdai = devm_kzalloc(dev, sizeof(*rdai) * nr, GFP_KERNEL);
+++ ++  if (!rdrv || !rdai) {
+++ ++          ret = -ENOMEM;
+++ ++          goto rsnd_dai_probe_done;
        }
      
--- --  info->dai_info_nr       = nr;
--- --  info->dai_info          = dai_info;
--- --
--- --  ssi_node = of_get_child_by_name(dev->of_node, "rcar_sound,ssi");
--- --  src_node = of_get_child_by_name(dev->of_node, "rcar_sound,src");
--- --  ctu_node = of_get_child_by_name(dev->of_node, "rcar_sound,ctu");
--- --  mix_node = of_get_child_by_name(dev->of_node, "rcar_sound,mix");
--- --  dvc_node = of_get_child_by_name(dev->of_node, "rcar_sound,dvc");
--- --
--- --#define mod_parse(name)                                                   \
--- --if (name##_node) {                                                        \
--- --  struct rsnd_##name##_platform_info *name##_info;                \
--- --                                                                  \
--- --  name##_i = 0;                                                   \
--- --  for_each_child_of_node(name##_node, name##_np) {                \
--- --          name##_info = info->name##_info + name##_i;             \
--- --                                                                  \
--- --          if (name##_np == playback)                              \
--- --                  dai_info->playback.name = name##_info;          \
--- --          if (name##_np == capture)                               \
--- --                  dai_info->capture.name = name##_info;           \
--- --                                                                  \
--- --          name##_i++;                                             \
--- --  }                                                               \
--- --}
+++ ++  priv->rdai_nr   = nr;
+++ ++  priv->daidrv    = rdrv;
+++ ++  priv->rdai      = rdai;
      
        /*
         * parse all dai
                }
      
                dai_i++;
--- --  }
--- --}
--- --
--- --static int rsnd_dai_probe(struct platform_device *pdev,
--- --                    const struct rsnd_of_data *of_data,
--- --                    struct rsnd_priv *priv)
--- --{
--- --  struct snd_soc_dai_driver *drv;
--- --  struct rcar_snd_info *info = rsnd_priv_to_info(priv);
--- --  struct rsnd_dai *rdai;
--- --  struct rsnd_ssi_platform_info *pmod, *cmod;
--- --  struct device *dev = rsnd_priv_to_dev(priv);
--- --  int dai_nr;
--- --  int i;
--  --
--  --  rsnd_of_parse_dai(pdev, of_data, priv);
      
  -     rsnd_of_parse_dai(pdev, of_data, priv);
  -   
--- --  dai_nr = info->dai_info_nr;
--- --  if (!dai_nr) {
--- --          dev_err(dev, "no dai\n");
--- --          return -EIO;
+++ ++          dev_dbg(dev, "%s (%s/%s)\n", rdai->name,
+++ ++                  rsnd_io_to_mod_ssi(io_playback) ? "play"    : " -- ",
+++ ++                  rsnd_io_to_mod_ssi(io_capture) ? "capture" : "  --   ");
        }
      
--- --  drv  = devm_kzalloc(dev, sizeof(*drv)  * dai_nr, GFP_KERNEL);
--- --  rdai = devm_kzalloc(dev, sizeof(*rdai) * dai_nr, GFP_KERNEL);
--- --  if (!drv || !rdai) {
--- --          dev_err(dev, "dai allocate failed\n");
--- --          return -ENOMEM;
--- --  }
--- --
--- --  priv->rdai_nr   = dai_nr;
--- --  priv->daidrv    = drv;
--- --  priv->rdai      = rdai;
+++ ++  ret = 0;
      
--- --  for (i = 0; i < dai_nr; i++) {
+++ ++rsnd_dai_probe_done:
+++ ++  of_node_put(dai_node);
      
--- --          pmod = info->dai_info[i].playback.ssi;
--- --          cmod = info->dai_info[i].capture.ssi;
--- --
--- --          /*
--- --           *      init rsnd_dai
--- --           */
--- --          snprintf(rdai[i].name, RSND_DAI_NAME_SIZE, "rsnd-dai.%d", i);
--- --          rdai[i].priv = priv;
--- --
--- --          /*
--- --           *      init snd_soc_dai_driver
--- --           */
--- --          drv[i].name     = rdai[i].name;
--- --          drv[i].ops      = &rsnd_soc_dai_ops;
--- --          if (pmod) {
--- --                  snprintf(rdai[i].playback.name, RSND_DAI_NAME_SIZE,
--- --                           "DAI%d Playback", i);
--- --
--- --                  drv[i].playback.rates           = RSND_RATES;
--- --                  drv[i].playback.formats         = RSND_FMTS;
--- --                  drv[i].playback.channels_min    = 2;
--- --                  drv[i].playback.channels_max    = 2;
--- --                  drv[i].playback.stream_name     = rdai[i].playback.name;
--- --
--- --                  rdai[i].playback.info = &info->dai_info[i].playback;
--- --                  rdai[i].playback.rdai = rdai + i;
--- --                  rsnd_path_init(priv, &rdai[i], &rdai[i].playback);
--- --          }
--- --          if (cmod) {
--- --                  snprintf(rdai[i].capture.name, RSND_DAI_NAME_SIZE,
--- --                           "DAI%d Capture", i);
--- --
--- --                  drv[i].capture.rates            = RSND_RATES;
--- --                  drv[i].capture.formats          = RSND_FMTS;
--- --                  drv[i].capture.channels_min     = 2;
--- --                  drv[i].capture.channels_max     = 2;
--- --                  drv[i].capture.stream_name      = rdai[i].capture.name;
--- --
--- --                  rdai[i].capture.info = &info->dai_info[i].capture;
--- --                  rdai[i].capture.rdai = rdai + i;
--- --                  rsnd_path_init(priv, &rdai[i], &rdai[i].capture);
--- --          }
--- --
--- --          dev_dbg(dev, "%s (%s/%s)\n", rdai[i].name,
--- --                  pmod ? "play"    : " -- ",
--- --                  cmod ? "capture" : "  --   ");
--- --  }
--- --
--- --  return 0;
+++ ++  return ret;
      }
      
      /*
@@@@@@@ -1220,12 -1221,12 -1224,21 -1072,6 -1221,12 -1221,12 +1071,6 @@@@@@@ static int rsnd_probe(struct platform_d
        };
        int ret, i;
      
--  --  info = devm_kzalloc(&pdev->dev, sizeof(struct rcar_snd_info),
--  --                      GFP_KERNEL);
--  --  if (!info)
--  --          return -ENOMEM;
--  --  of_data = of_id->data;
  -     info = NULL;
  -     of_data = NULL;
  -     if (of_id) {
  -             info = devm_kzalloc(&pdev->dev,
  -                                 sizeof(struct rcar_snd_info), GFP_KERNEL);
  -             of_data = of_id->data;
  -     } else {
  -             info = pdev->dev.platform_data;
  -     }
  -   
  -     if (!info) {
  -             dev_err(dev, "driver needs R-Car sound information\n");
  -             return -ENODEV;
  -     }
--- --
        /*
         *      init priv data
         */
      #include "rsnd.h"
      
      struct rsnd_gen {
  -     void __iomem *base[RSND_BASE_MAX];
  -   
        struct rsnd_gen_ops *ops;
      
  +     /* RSND_BASE_MAX base */
  +     void __iomem *base[RSND_BASE_MAX];
  +     phys_addr_t res[RSND_BASE_MAX];
        struct regmap *regmap[RSND_BASE_MAX];
  +   
  +     /* RSND_REG_MAX base */
        struct regmap_field *regs[RSND_REG_MAX];
  -     phys_addr_t res[RSND_REG_MAX];
+++ ++  const char *reg_name[RSND_REG_MAX];
      };
      
      #define rsnd_priv_to_gen(p)       ((struct rsnd_gen *)(p)->gen)
@@@@@@@ -81,11 -81,11 -79,11 -85,12 -81,11 -81,11 +85,12 @@@@@@@ u32 rsnd_read(struct rsnd_priv *priv
        if (!rsnd_is_accessible_reg(priv, gen, reg))
                return 0;
      
  -     dev_dbg(dev, "r %s[%d] - %4d : %08x\n",
  -             rsnd_mod_name(mod), rsnd_mod_id(mod), reg, val);
  -   
        regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val);
      
--  --  dev_dbg(dev, "r %s[%d] - %4d : %08x\n",
--  --          rsnd_mod_name(mod), rsnd_mod_id(mod), reg, val);
+++ ++  dev_dbg(dev, "r %s[%d] - %-18s (%4d) : %08x\n",
+++ ++          rsnd_mod_name(mod), rsnd_mod_id(mod),
+++ ++          rsnd_reg_name(gen, reg), reg, val);
  +   
        return val;
      }
      
@@@@@@@ -201,8 -201,8 -198,7 -210,9 -201,8 -201,8 +210,9 @@@@@@@ static int _rsnd_gen_regmap_init(struc
                if (IS_ERR(regs))
                        return PTR_ERR(regs);
      
  +             /* RSND_REG_MAX base */
                gen->regs[conf[i].idx] = regs;
+++ ++          gen->reg_name[conf[i].idx] = conf[i].reg_name;
        }
      
        return 0;
Simple merge
@@@@@@@ -143,99 -143,99 -143,99 -93,6 -143,99 -143,99 +93,6 @@@@@@@ static struct dma_chan *rsnd_src_dma_re
                                        is_play ? "rx" : "tx");
      }
      
--- --int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
--- --                  struct rsnd_dai_stream *io,
--- --                  int use_busif)
--- --{
--- --  struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
--- --  int ssi_id = rsnd_mod_id(ssi_mod);
--- --
--- --  /*
--- --   * SSI_MODE0
--- --   */
--- --  rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id),
--- --                !use_busif << ssi_id);
--- --
--- --  /*
--- --   * SSI_MODE1
--- --   */
--  --  if (rsnd_ssi_is_pin_sharing(io)) {
  -     if (rsnd_ssi_is_pin_sharing(ssi_mod)) {
--- --          int shift = -1;
--- --          switch (ssi_id) {
--- --          case 1:
--- --                  shift = 0;
--- --                  break;
--- --          case 2:
--- --                  shift = 2;
--- --                  break;
--- --          case 4:
--- --                  shift = 16;
--- --                  break;
--- --          }
--- --
--- --          if (shift >= 0)
--- --                  rsnd_mod_bset(ssi_mod, SSI_MODE1,
--- --                                0x3 << shift,
--- --                                rsnd_rdai_is_clk_master(rdai) ?
--- --                                0x2 << shift : 0x1 << shift);
--- --  }
--- --
--- --  /*
--- --   * DMA settings for SSIU
--- --   */
--- --  if (use_busif) {
--- --          u32 val = rsnd_get_dalign(ssi_mod, io);
--- --
--- --          rsnd_mod_write(ssi_mod, SSI_BUSIF_ADINR,
--- --                         rsnd_get_adinr_bit(ssi_mod, io));
--- --          rsnd_mod_write(ssi_mod, SSI_BUSIF_MODE,  1);
--- --          rsnd_mod_write(ssi_mod, SSI_CTRL, 0x1);
--- --
--- --          rsnd_mod_write(ssi_mod, SSI_BUSIF_DALIGN, val);
--- --  }
--- --
--- --  return 0;
--- --}
--- --
--- --int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod,
--- --                 struct rsnd_dai_stream *io)
--- --{
--- --  /*
--- --   * DMA settings for SSIU
--- --   */
--- --  rsnd_mod_write(ssi_mod, SSI_CTRL, 0);
--- --
--- --  return 0;
--- --}
--- --
--- --int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod)
--- --{
--- --  struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
--- --
--- --  if (rsnd_is_gen1(priv))
--- --          return 0;
--- --
--- --  /* enable SSI interrupt if Gen2 */
--- --  rsnd_mod_write(ssi_mod, SSI_INT_ENABLE,
--- --                 rsnd_ssi_is_dma_mode(ssi_mod) ?
--- --                 0x0e000000 : 0x0f000000);
--- --
--- --  return 0;
--- --}
--- --
--- --int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod)
--- --{
--- --  struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
--- --
--- --  if (rsnd_is_gen1(priv))
--- --          return 0;
--- --
--- --  /* disable SSI interrupt if Gen2 */
--- --  rsnd_mod_write(ssi_mod, SSI_INT_ENABLE, 0x00000000);
--- --
--- --  return 0;
--- --}
--- --
      static u32 rsnd_src_convert_rate(struct rsnd_dai_stream *io,
                                 struct rsnd_src *src)
      {
@@@@@@@ -347,151 -347,151 -347,151 -173,80 -347,151 -347,151 +173,80 @@@@@@@ static int rsnd_src_hw_params(struct rs
        return 0;
      }
      
--- --static int rsnd_src_init(struct rsnd_mod *mod,
--- --                   struct rsnd_priv *priv)
--- --{
--- --  struct rsnd_src *src = rsnd_mod_to_src(mod);
--- --
--  --  rsnd_mod_power_on(mod);
  -     rsnd_mod_hw_start(mod);
--- --
--- --  rsnd_src_soft_reset(mod);
--- --
--- --  rsnd_src_initialize_lock(mod);
--- --
--- --  src->err = 0;
--- --
--- --  /* reset sync convert_rate */
--- --  src->sync.val = 0;
--- --
--- --  return 0;
--- --}
--- --
--- --static int rsnd_src_quit(struct rsnd_mod *mod,
--- --                   struct rsnd_dai_stream *io,
--- --                   struct rsnd_priv *priv)
+++ ++static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
+++ ++                                struct rsnd_mod *mod)
      {
--- --  struct rsnd_src *src = rsnd_mod_to_src(mod);
+++ ++  struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
        struct device *dev = rsnd_priv_to_dev(priv);
+++ ++  struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
+++ ++  struct rsnd_src *src = rsnd_mod_to_src(mod);
+++ ++  u32 convert_rate = rsnd_src_convert_rate(io, src);
+++ ++  u32 ifscr, fsrate, adinr;
+++ ++  u32 cr, route;
+++ ++  u32 bsdsr, bsisr;
+++ ++  uint ratio;
      
--  --  rsnd_mod_power_off(mod);
  -     rsnd_mod_hw_stop(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 */
--- --  src->sync.val = 0;
--- --
--- --  return 0;
--- --}
--- --
--- --static int rsnd_src_start(struct rsnd_mod *mod)
--- --{
--- --  rsnd_src_initialize_unlock(mod);
--- --
--- --  return 0;
--- --}
--- --
--- --static int rsnd_src_stop(struct rsnd_mod *mod)
--- --{
--- --  /* nothing to do */
--- --  return 0;
--- --}
+++ ++  if (!runtime)
+++ ++          return;
      
--- --/*
--- -- *                Gen1 functions
--- -- */
--- --static int rsnd_src_set_route_gen1(struct rsnd_dai_stream *io,
--- --                             struct rsnd_mod *mod)
--- --{
--- --  struct src_route_config {
--- --          u32 mask;
--- --          int shift;
--- --  } routes[] = {
--- --          { 0xF,  0, }, /* 0 */
--- --          { 0xF,  4, }, /* 1 */
--- --          { 0xF,  8, }, /* 2 */
--- --          { 0x7, 12, }, /* 3 */
--- --          { 0x7, 16, }, /* 4 */
--- --          { 0x7, 20, }, /* 5 */
--- --          { 0x7, 24, }, /* 6 */
--- --          { 0x3, 28, }, /* 7 */
--- --          { 0x3, 30, }, /* 8 */
--- --  };
--- --  u32 mask;
--- --  u32 val;
--- --  int id;
+++ ++  /* 6 - 1/6 are very enough ratio for SRC_BSDSR */
+++ ++  if (!convert_rate)
+++ ++          ratio = 0;
+++ ++  else if (convert_rate > runtime->rate)
+++ ++          ratio = 100 * convert_rate / runtime->rate;
+++ ++  else
+++ ++          ratio = 100 * runtime->rate / convert_rate;
      
--- --  id = rsnd_mod_id(mod);
--- --  if (id < 0 || id >= ARRAY_SIZE(routes))
--- --          return -EIO;
+++ ++  if (ratio > 600) {
+++ ++          dev_err(dev, "FSO/FSI ratio error\n");
+++ ++          return;
+++ ++  }
      
        /*
--- --   * SRC_ROUTE_SELECT
+++ ++   *      SRC_ADINR
         */
--- --  val = rsnd_io_is_play(io) ? 0x1 : 0x2;
--- --  val = val               << routes[id].shift;
--- --  mask = routes[id].mask  << routes[id].shift;
--- --
--- --  rsnd_mod_bset(mod, SRC_ROUTE_SEL, mask, val);
--- --
--- --  return 0;
--- --}
--- --
--- --static int rsnd_src_set_convert_timing_gen1(struct rsnd_dai_stream *io,
--- --                                      struct rsnd_mod *mod)
--- --{
--- --  struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
--- --  struct rsnd_src *src = rsnd_mod_to_src(mod);
--- --  struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
--- --  u32 convert_rate = rsnd_src_convert_rate(io, src);
--- --  u32 mask;
--- --  u32 val;
--- --  int shift;
--- --  int id = rsnd_mod_id(mod);
--- --  int ret;
+++ ++  adinr = rsnd_get_adinr_bit(mod, io) |
+++ ++          rsnd_get_adinr_chan(mod, io);
      
        /*
--- --   * SRC_TIMING_SELECT
+++ ++   *      SRC_IFSCR / SRC_IFSVR
         */
--- --  shift   = (id % 4) * 8;
--- --  mask    = 0x1F << shift;
+++ ++  ifscr = 0;
+++ ++  fsrate = 0;
+++ ++  if (convert_rate) {
+++ ++          ifscr = 1;
+++ ++          fsrate = 0x0400000 / convert_rate * runtime->rate;
+++ ++  }
      
        /*
--- --   * ADG is used as source clock if SRC was used,
--- --   * then, SSI WS is used as destination clock.
--- --   * SSI WS is used as source clock if SRC is not used
--- --   * (when playback, source/destination become reverse when capture)
+++ ++   *      SRC_SRCCR / SRC_ROUTE_MODE0
         */
--- --  ret = 0;
+++ ++  cr      = 0x00011110;
+++ ++  route   = 0x0;
        if (convert_rate) {
--- --          /* use ADG */
--- --          val = 0;
--- --          ret = rsnd_adg_set_convert_clk_gen1(priv, mod,
--- --                                              runtime->rate,
--- --                                              convert_rate);
--- --  } else if (8 == id) {
--- --          /* use SSI WS, but SRU8 is special */
--- --          val = id << shift;
--- --  } else {
--- --          /* use SSI WS */
--- --          val = (id + 1) << shift;
--- --  }
+++ ++          route   = 0x1;
      
--- --  if (ret < 0)
--- --          return ret;
+++ ++          if (rsnd_enable_sync_convert(src)) {
+++ ++                  cr |= 0x1;
+++ ++                  route |= rsnd_io_is_play(io) ?
+++ ++                          (0x1 << 24) : (0x1 << 25);
+++ ++          }
+++ ++  }
      
--- --  switch (id / 4) {
--- --  case 0:
--- --          rsnd_mod_bset(mod, SRC_TMG_SEL0, mask, val);
--- --          break;
--- --  case 1:
--- --          rsnd_mod_bset(mod, SRC_TMG_SEL1, mask, val);
+++ ++  /*
+++ ++   * SRC_BSDSR / SRC_BSISR
+++ ++   */
+++ ++  switch (rsnd_mod_id(mod)) {
+++ ++  case 5:
+++ ++  case 6:
+++ ++  case 7:
+++ ++  case 8:
+++ ++          bsdsr = 0x02400000; /* 6 - 1/6 */
+++ ++          bsisr = 0x00100060; /* 6 - 1/6 */
                break;
--- --  case 2:
--- --          rsnd_mod_bset(mod, SRC_TMG_SEL2, mask, val);
+++ ++  default:
+++ ++          bsdsr = 0x01800000; /* 6 - 1/6 */
+++ ++          bsisr = 0x00100060 ;/* 6 - 1/6 */
                break;
        }
      
@@@@@@@ -687,138 -687,138 -687,138 -376,105 -687,138 -687,138 +376,105 @@@@@@@ static int rsnd_src_stop(struct rsnd_mo
        return 0;
      }
      
--- --static int _rsnd_src_stop_gen2(struct rsnd_mod *mod)
+++ ++static int rsnd_src_init(struct rsnd_mod *mod,
+++ ++                   struct rsnd_dai_stream *io,
+++ ++                   struct rsnd_priv *priv)
      {
--- --  rsnd_src_irq_disable_gen2(mod);
+++ ++  struct rsnd_src *src = rsnd_mod_to_src(mod);
      
--- --  rsnd_mod_write(mod, SRC_CTRL, 0);
+++ ++  rsnd_mod_power_on(mod);
+ +   
 -  --  rsnd_src_error_record_gen2(mod);
+++ ++  rsnd_src_activation(mod);
++  ++
  -     rsnd_src_error_record_gen2(mod);
+++ ++  rsnd_src_set_convert_rate(io, mod);
 ++ ++
-       rsnd_src_error_record_gen2(mod);
+++ ++  rsnd_src_status_clear(mod);
+++ ++
+++ ++  rsnd_src_irq_enable(mod);
+++ ++
+++ ++  src->err = 0;
 ++ ++
-       return rsnd_src_stop(mod);
+++ ++  /* reset sync convert_rate */
+++ ++  src->sync.val = 0;
+     
 -- --  return rsnd_src_stop(mod);
+++ ++  return 0;
      }
      
--- --static void __rsnd_src_interrupt_gen2(struct rsnd_mod *mod,
--- --                                struct rsnd_dai_stream *io)
+++ ++static int rsnd_src_quit(struct rsnd_mod *mod,
+++ ++                   struct rsnd_dai_stream *io,
+++ ++                   struct rsnd_priv *priv)
      {
--- --  struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
- -   
- -     spin_lock(&priv->lock);
+++ ++  struct rsnd_src *src = rsnd_mod_to_src(mod);
+++ ++  struct device *dev = rsnd_priv_to_dev(priv);
      
- -     /* ignore all cases if not working */
- -     if (!rsnd_io_is_working(io))
- -             goto rsnd_src_interrupt_gen2_out;
 -  --  spin_lock(&priv->lock);
+++ ++  rsnd_src_irq_disable(mod);
      
- -     if (rsnd_src_error_record_gen2(mod)) {
- -             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);
 -  --  /* ignore all cases if not working */
 -  --  if (!rsnd_io_is_working(io))
 -  --          goto rsnd_src_interrupt_gen2_out;
+++ ++  /* stop both out/in */
+++ ++  rsnd_mod_write(mod, SRC_CTRL, 0);
      
- -             dev_dbg(dev, "%s[%d] restart\n",
- -                     rsnd_mod_name(mod), rsnd_mod_id(mod));
 -  --  if (rsnd_src_error_record_gen2(mod)) {
 -  --          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);
+++ ++  rsnd_src_halt(mod);
      
 -  --          dev_dbg(dev, "%s[%d] restart\n",
 -  --                  rsnd_mod_name(mod), rsnd_mod_id(mod));
 -  --
--- --          _rsnd_src_stop_gen2(mod);
--- --          if (src->err < 1024)
--- --                  _rsnd_src_start_gen2(mod, io);
--- --          else
--- --                  dev_warn(dev, "no more SRC restart\n");
--- --  }
+++ ++  rsnd_mod_power_off(mod);
      
--- --rsnd_src_interrupt_gen2_out:
--- --  spin_unlock(&priv->lock);
--- --}
+++ ++  if (src->err)
+++ ++          dev_warn(dev, "%s[%d] under/over flow err = %d\n",
+++ ++                   rsnd_mod_name(mod), rsnd_mod_id(mod), src->err);
      
--- --static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data)
--- --{
--- --  struct rsnd_mod *mod = data;
+++ ++  src->convert_rate = 0;
      
--- --  rsnd_mod_interrupt(mod, __rsnd_src_interrupt_gen2);
+++ ++  /* reset sync convert_rate */
+++ ++  src->sync.val = 0;
      
--- --  return IRQ_HANDLED;
+++ ++  return 0;
      }
      
--- --static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod,
--- --                                    struct rsnd_dai_stream *io)
+++ ++static void __rsnd_src_interrupt(struct rsnd_mod *mod,
+++ ++                           struct rsnd_dai_stream *io)
      {
        struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
--- --  struct device *dev = rsnd_priv_to_dev(priv);
--- --  struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
        struct rsnd_src *src = rsnd_mod_to_src(mod);
--- --  u32 convert_rate = rsnd_src_convert_rate(io, src);
--- --  u32 cr, route;
--- --  uint ratio;
--- --  int ret;
+++ ++  struct device *dev = rsnd_priv_to_dev(priv);
      
--- --  /* 6 - 1/6 are very enough ratio for SRC_BSDSR */
--- --  if (!convert_rate)
--- --          ratio = 0;
--- --  else if (convert_rate > runtime->rate)
--- --          ratio = 100 * convert_rate / runtime->rate;
--- --  else
--- --          ratio = 100 * runtime->rate / convert_rate;
+++ ++  spin_lock(&priv->lock);
      
--- --  if (ratio > 600) {
--- --          dev_err(dev, "FSO/FSI ratio error\n");
--- --          return -EINVAL;
--- --  }
+++ ++  /* ignore all cases if not working */
+++ ++  if (!rsnd_io_is_working(io))
+++ ++          goto rsnd_src_interrupt_out;
      
--- --  ret = rsnd_src_set_convert_rate(mod, io);
--- --  if (ret < 0)
--- --          return ret;
+++ ++  if (rsnd_src_record_error(mod)) {
      
--- --  cr      = 0x00011110;
--- --  route   = 0x0;
--- --  if (convert_rate) {
--- --          route   = 0x1;
+++ ++          dev_dbg(dev, "%s[%d] restart\n",
+++ ++                  rsnd_mod_name(mod), rsnd_mod_id(mod));
      
--- --          if (rsnd_enable_sync_convert(src)) {
--- --                  cr |= 0x1;
--- --                  route |= rsnd_io_is_play(io) ?
--- --                          (0x1 << 24) : (0x1 << 25);
--- --          }
+++ ++          rsnd_src_stop(mod, io, priv);
+++ ++          rsnd_src_start(mod, io, priv);
        }
      
--- --  rsnd_mod_write(mod, SRC_SRCCR, cr);
--- --  rsnd_mod_write(mod, SRC_ROUTE_MODE0, route);
+++ ++  if (src->err > 1024) {
+++ ++          rsnd_src_irq_disable(mod);
      
--- --  switch (rsnd_mod_id(mod)) {
--- --  case 5:
--- --  case 6:
--- --  case 7:
--- --  case 8:
--- --          rsnd_mod_write(mod, SRC_BSDSR, 0x02400000);
--- --          break;
--- --  default:
--- --          rsnd_mod_write(mod, SRC_BSDSR, 0x01800000);
--- --          break;
+++ ++          dev_warn(dev, "no more %s[%d] restart\n",
+++ ++                   rsnd_mod_name(mod), rsnd_mod_id(mod));
        }
      
--- --  rsnd_mod_write(mod, SRC_BSISR, 0x00100060);
+++ ++  rsnd_src_status_clear(mod);
+++ ++rsnd_src_interrupt_out:
      
--- --  return 0;
+++ ++  spin_unlock(&priv->lock);
      }
      
--- --static int rsnd_src_set_convert_timing_gen2(struct rsnd_dai_stream *io,
--- --                                      struct rsnd_mod *mod)
+++ ++static irqreturn_t rsnd_src_interrupt(int irq, void *data)
      {
--- --  struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
--- --  struct rsnd_src *src = rsnd_mod_to_src(mod);
--- --  u32 convert_rate = rsnd_src_convert_rate(io, src);
--- --  int ret;
+++ ++  struct rsnd_mod *mod = data;
      
--- --  if (convert_rate)
--- --          ret = rsnd_adg_set_convert_clk_gen2(mod, io,
--- --                                              runtime->rate,
--- --                                              convert_rate);
--- --  else
--- --          ret = rsnd_adg_set_convert_timing_gen2(mod, io);
+++ ++  rsnd_mod_interrupt(mod, __rsnd_src_interrupt);
      
--- --  return ret;
+++ ++  return IRQ_HANDLED;
      }
      
--- --static int rsnd_src_probe_gen2(struct rsnd_mod *mod,
--- --                         struct rsnd_dai_stream *io,
--- --                         struct rsnd_priv *priv)
+++ ++static int rsnd_src_probe_(struct rsnd_mod *mod,
+++ ++                     struct rsnd_dai_stream *io,
+++ ++                     struct rsnd_priv *priv)
      {
        struct rsnd_src *src = rsnd_mod_to_src(mod);
        struct device *dev = rsnd_priv_to_dev(priv);
        return ret;
      }
      
--- --static int rsnd_src_remove_gen2(struct rsnd_mod *mod,
--- --                          struct rsnd_dai_stream *io,
--- --                          struct rsnd_priv *priv)
--- --{
--- --  rsnd_dma_quit(io, rsnd_mod_to_dma(mod));
--- --
--- --  return 0;
--- --}
--- --
--- --static int rsnd_src_init_gen2(struct rsnd_mod *mod,
--- --                        struct rsnd_dai_stream *io,
--- --                        struct rsnd_priv *priv)
--- --{
--- --  int ret;
--- --
--- --  ret = rsnd_src_init(mod, priv);
--- --  if (ret < 0)
--- --          return ret;
--- --
--- --  ret = rsnd_src_set_convert_rate_gen2(mod, io);
--- --  if (ret < 0)
--- --          return ret;
--- --
--- --  ret = rsnd_src_set_convert_timing_gen2(io, mod);
--- --  if (ret < 0)
--- --          return ret;
--- --
--- --  return 0;
--- --}
--- --
--- --static int rsnd_src_start_gen2(struct rsnd_mod *mod,
--- --                         struct rsnd_dai_stream *io,
--- --                         struct rsnd_priv *priv)
--- --{
--- --  rsnd_dma_start(io, rsnd_mod_to_dma(mod));
--- --
--- --  return _rsnd_src_start_gen2(mod, io);
--- --}
--- --
--- --static int rsnd_src_stop_gen2(struct rsnd_mod *mod,
--- --                        struct rsnd_dai_stream *io,
--- --                        struct rsnd_priv *priv)
--- --{
--- --  int ret;
--- --
--- --  ret = _rsnd_src_stop_gen2(mod);
--- --
--- --  rsnd_dma_stop(io, rsnd_mod_to_dma(mod));
--- --
--- --  return ret;
--- --}
--- --
--- --static void rsnd_src_reconvert_update(struct rsnd_dai_stream *io,
--- --                                struct rsnd_mod *mod)
--- --{
--- --  struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
--- --  struct rsnd_src *src = rsnd_mod_to_src(mod);
--- --  u32 convert_rate = rsnd_src_convert_rate(io, src);
--- --  u32 fsrate;
--- --
--- --  if (!runtime)
--- --          return;
--- --
--- --  if (!convert_rate)
--- --          convert_rate = runtime->rate;
--- --
--- --  fsrate = 0x0400000 / convert_rate * runtime->rate;
--- --
--- --  /* update IFS */
--- --  rsnd_mod_write(mod, SRC_IFSVR, fsrate);
--- --}
--- --
--  --static int rsnd_src_pcm_new_gen2(struct rsnd_mod *mod,
++  ++static int rsnd_src_pcm_new(struct rsnd_mod *mod,
                            struct rsnd_dai_stream *io,
                            struct snd_soc_pcm_runtime *rtd)
      {
  -     struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
        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;
      
         */
      
        /*
  -      * Gen1 is not supported
  +      * SRC sync convert needs clock master
         */
  -     if (rsnd_is_gen1(priv))
  +     if (!rsnd_rdai_is_clk_master(rdai))
                return 0;
      
  -      * SRC sync convert needs clock master
 + +++  /*
  -     if (!rsnd_rdai_is_clk_master(rdai))
 +++++   * SRC In doesn't work if DVC was enabled
 + +++   */
 +++++  if (dvc && !rsnd_io_is_play(io))
 + +++          return 0;
 + +++
        /*
         * enable sync convert
         */
        return ret;
      }
      
--- --static struct rsnd_mod_ops rsnd_src_gen2_ops = {
+++ ++static struct rsnd_mod_ops rsnd_src_ops = {
        .name   = SRC_NAME,
        .dma_req = rsnd_src_dma_req,
--- --  .probe  = rsnd_src_probe_gen2,
--- --  .remove = rsnd_src_remove_gen2,
--- --  .init   = rsnd_src_init_gen2,
+++ ++  .probe  = rsnd_src_probe_,
+++ ++  .init   = rsnd_src_init,
        .quit   = rsnd_src_quit,
--- --  .start  = rsnd_src_start_gen2,
--- --  .stop   = rsnd_src_stop_gen2,
+++ ++  .start  = rsnd_src_start,
+++ ++  .stop   = rsnd_src_stop,
        .hw_params = rsnd_src_hw_params,
--  --  .pcm_new = rsnd_src_pcm_new_gen2,
++  ++  .pcm_new = rsnd_src_pcm_new,
      };
      
      struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
        if (WARN_ON(id < 0 || id >= rsnd_src_nr(priv)))
                id = 0;
      
--  --  return rsnd_mod_get((struct rsnd_src *)(priv->src) + id);
  -     return &((struct rsnd_src *)(priv->src) + id)->mod;
+++ ++  return rsnd_mod_get(rsnd_src_get(priv, id));
      }
      
--- --static void rsnd_of_parse_src(struct platform_device *pdev,
--- --                        const struct rsnd_of_data *of_data,
--- --                        struct rsnd_priv *priv)
+++ ++int rsnd_src_probe(struct rsnd_priv *priv)
      {
--- --  struct device_node *src_node;
+++ ++  struct device_node *node;
        struct device_node *np;
--- --  struct rcar_snd_info *info = rsnd_priv_to_info(priv);
--- --  struct rsnd_src_platform_info *src_info;
--- --  struct device *dev = &pdev->dev;
--- --  int nr, i;
--- --
--- --  if (!of_data)
--- --          return;
--- --
--- --  src_node = rsnd_src_of_node(priv);
--- --  if (!src_node)
--- --          return;
--- --
--- --  nr = of_get_child_count(src_node);
--- --  if (!nr)
--- --          goto rsnd_of_parse_src_end;
--- --
--- --  src_info = devm_kzalloc(dev,
--- --                          sizeof(struct rsnd_src_platform_info) * nr,
--- --                          GFP_KERNEL);
--- --  if (!src_info) {
--- --          dev_err(dev, "src info allocation error\n");
--- --          goto rsnd_of_parse_src_end;
--- --  }
--- --
--- --  info->src_info          = src_info;
--- --  info->src_info_nr       = nr;
--- --
--- --  i = 0;
--- --  for_each_child_of_node(src_node, np) {
--- --          src_info[i].irq = irq_of_parse_and_map(np, 0);
--- --
--- --          i++;
--- --  }
--- --
--- --rsnd_of_parse_src_end:
--- --  of_node_put(src_node);
--- --}
--- --
--- --int rsnd_src_probe(struct platform_device *pdev,
--- --             const struct rsnd_of_data *of_data,
--- --             struct rsnd_priv *priv)
--- --{
--- --  struct rcar_snd_info *info = rsnd_priv_to_info(priv);
        struct device *dev = rsnd_priv_to_dev(priv);
        struct rsnd_src *src;
--- --  struct rsnd_mod_ops *ops;
        struct clk *clk;
        char name[RSND_SRC_NAME_SIZE];
        int i, nr, ret;
      
--- --  ops = NULL;
--  --  if (rsnd_is_gen1(priv)) {
--  --          ops = &rsnd_src_gen1_ops;
--  --          dev_warn(dev, "Gen1 support will be removed soon\n");
--  --  }
--  --  if (rsnd_is_gen2(priv))
--  --          ops = &rsnd_src_gen2_ops;
--  --  if (!ops) {
--  --          dev_err(dev, "unknown Generation\n");
--  --          return -EIO;
--  --  }
+++ ++  /* This driver doesn't support Gen1 at this point */
++  ++  if (rsnd_is_gen1(priv))
  -             ops = &rsnd_src_gen1_ops;
  -     if (rsnd_is_gen2(priv))
  -             ops = &rsnd_src_gen2_ops;
  -     if (!ops) {
  -             dev_err(dev, "unknown Generation\n");
  -             return -EIO;
  -     }
+++ ++          return 0;
      
--- --  rsnd_of_parse_src(pdev, of_data, priv);
+++ ++  node = rsnd_src_of_node(priv);
+++ ++  if (!node)
+++ ++          return 0; /* not used is not error */
      
--- --  /*
--- --   * init SRC
--- --   */
--- --  nr      = info->src_info_nr;
--- --  if (!nr)
--- --          return 0;
+++ ++  nr = of_get_child_count(node);
+++ ++  if (!nr) {
+++ ++          ret = -EINVAL;
+++ ++          goto rsnd_src_probe_done;
+++ ++  }
      
        src     = devm_kzalloc(dev, sizeof(*src) * nr, GFP_KERNEL);
--- --  if (!src)
--- --          return -ENOMEM;
+++ ++  if (!src) {
+++ ++          ret = -ENOMEM;
+++ ++          goto rsnd_src_probe_done;
+++ ++  }
      
        priv->src_nr    = nr;
        priv->src       = src;
                snprintf(name, RSND_SRC_NAME_SIZE, "%s.%d",
                         SRC_NAME, i);
      
--- --          clk = devm_clk_get(dev, name);
--- --          if (IS_ERR(clk))
--- --                  return PTR_ERR(clk);
+++ ++          src->irq = irq_of_parse_and_map(np, 0);
+++ ++          if (!src->irq) {
+++ ++                  ret = -EINVAL;
+++ ++                  goto rsnd_src_probe_done;
+++ ++          }
      
--- --          src->info = &info->src_info[i];
+++ ++          clk = devm_clk_get(dev, name);
+++ ++          if (IS_ERR(clk)) {
+++ ++                  ret = PTR_ERR(clk);
+++ ++                  goto rsnd_src_probe_done;
+++ ++          }
      
--  --          ret = rsnd_mod_init(priv, rsnd_mod_get(src), ops, clk, RSND_MOD_SRC, i);
  -             ret = rsnd_mod_init(priv, &src->mod, ops, clk, RSND_MOD_SRC, i);
+++ ++          ret = rsnd_mod_init(priv, rsnd_mod_get(src),
+++ ++                              &rsnd_src_ops, clk, RSND_MOD_SRC, i);
                if (ret)
--- --                  return ret;
+++ ++                  goto rsnd_src_probe_done;
+++ ++
+++ ++          i++;
        }
      
--- --  return 0;
+++ ++  ret = 0;
+++ ++
+++ ++rsnd_src_probe_done:
+++ ++  of_node_put(node);
+++ ++
+++ ++  return ret;
      }
      
--- --void rsnd_src_remove(struct platform_device *pdev,
--- --               struct rsnd_priv *priv)
+++ ++void rsnd_src_remove(struct rsnd_priv *priv)
      {
        struct rsnd_src *src;
        int i;