These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / sound / soc / sh / rcar / src.c
index 3beb32e..68b439e 100644 (file)
@@ -30,6 +30,7 @@ struct rsnd_src {
 
 #define RSND_SRC_NAME_SIZE 16
 
+#define rsnd_src_nr(priv) ((priv)->src_nr)
 #define rsnd_enable_sync_convert(src) ((src)->sen.val)
 #define rsnd_src_of_node(priv) \
        of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,src")
@@ -117,10 +118,24 @@ struct rsnd_src {
 /*
  *             Gen1/Gen2 common functions
  */
-static struct dma_chan *rsnd_src_dma_req(struct rsnd_mod *mod)
+static void rsnd_src_soft_reset(struct rsnd_mod *mod)
+{
+       rsnd_mod_write(mod, SRC_SWRSR, 0);
+       rsnd_mod_write(mod, SRC_SWRSR, 1);
+}
+
+
+#define rsnd_src_initialize_lock(mod)  __rsnd_src_initialize_lock(mod, 1)
+#define rsnd_src_initialize_unlock(mod)        __rsnd_src_initialize_lock(mod, 0)
+static void __rsnd_src_initialize_lock(struct rsnd_mod *mod, u32 enable)
+{
+       rsnd_mod_write(mod, SRC_SRCIR, enable);
+}
+
+static struct dma_chan *rsnd_src_dma_req(struct rsnd_dai_stream *io,
+                                        struct rsnd_mod *mod)
 {
        struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
-       struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
        int is_play = rsnd_io_is_play(io);
 
        return rsnd_dma_request_channel(rsnd_src_of_node(priv),
@@ -129,11 +144,10 @@ static struct dma_chan *rsnd_src_dma_req(struct rsnd_mod *mod)
 }
 
 int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
+                       struct rsnd_dai_stream *io,
                        int use_busif)
 {
-       struct rsnd_dai_stream *io = rsnd_mod_to_io(ssi_mod);
        struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
-       struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
        int ssi_id = rsnd_mod_id(ssi_mod);
 
        /*
@@ -145,7 +159,7 @@ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
        /*
         * SSI_MODE1
         */
-       if (rsnd_ssi_is_pin_sharing(ssi_mod)) {
+       if (rsnd_ssi_is_pin_sharing(io)) {
                int shift = -1;
                switch (ssi_id) {
                case 1:
@@ -170,33 +184,21 @@ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
         * DMA settings for SSIU
         */
        if (use_busif) {
-               u32 val = 0x76543210;
-               u32 mask = ~0;
+               u32 val = rsnd_get_dalign(ssi_mod, io);
 
                rsnd_mod_write(ssi_mod, SSI_BUSIF_ADINR,
-                              rsnd_get_adinr(ssi_mod));
+                              rsnd_get_adinr_bit(ssi_mod, io));
                rsnd_mod_write(ssi_mod, SSI_BUSIF_MODE,  1);
                rsnd_mod_write(ssi_mod, SSI_CTRL, 0x1);
 
-               mask <<= runtime->channels * 4;
-               val = val & mask;
-
-               switch (runtime->sample_bits) {
-               case 16:
-                       val |= 0x67452301 & ~mask;
-                       break;
-               case 32:
-                       val |= 0x76543210 & ~mask;
-                       break;
-               }
-               rsnd_mod_write(ssi_mod, BUSIF_DALIGN, val);
-
+               rsnd_mod_write(ssi_mod, SSI_BUSIF_DALIGN, val);
        }
 
        return 0;
 }
 
-int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod)
+int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod,
+                      struct rsnd_dai_stream *io)
 {
        /*
         * DMA settings for SSIU
@@ -214,10 +216,9 @@ int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod)
                return 0;
 
        /* enable SSI interrupt if Gen2 */
-       if (rsnd_ssi_is_dma_mode(ssi_mod))
-               rsnd_mod_write(ssi_mod, INT_ENABLE, 0x0e000000);
-       else
-               rsnd_mod_write(ssi_mod, INT_ENABLE, 0x0f000000);
+       rsnd_mod_write(ssi_mod, SSI_INT_ENABLE,
+                      rsnd_ssi_is_dma_mode(ssi_mod) ?
+                      0x0e000000 : 0x0f000000);
 
        return 0;
 }
@@ -230,15 +231,14 @@ int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod)
                return 0;
 
        /* disable SSI interrupt if Gen2 */
-       rsnd_mod_write(ssi_mod, INT_ENABLE, 0x00000000);
+       rsnd_mod_write(ssi_mod, SSI_INT_ENABLE, 0x00000000);
 
        return 0;
 }
 
-static u32 rsnd_src_convert_rate(struct rsnd_src *src)
+static u32 rsnd_src_convert_rate(struct rsnd_dai_stream *io,
+                                struct rsnd_src *src)
 {
-       struct rsnd_mod *mod = &src->mod;
-       struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
        struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
        u32 convert_rate;
 
@@ -274,7 +274,7 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
                 * return convert rate if SRC is used,
                 * otherwise, return runtime->rate as usual
                 */
-               rate = rsnd_src_convert_rate(src);
+               rate = rsnd_src_convert_rate(io, src);
        }
 
        if (!rate)
@@ -283,23 +283,19 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
        return rate;
 }
 
-static int rsnd_src_set_convert_rate(struct rsnd_mod *mod)
+static int rsnd_src_set_convert_rate(struct rsnd_mod *mod,
+                                    struct rsnd_dai_stream *io)
 {
-       struct rsnd_dai_stream *io = rsnd_mod_to_io(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(src);
+       u32 convert_rate = rsnd_src_convert_rate(io, src);
        u32 fsrate = 0;
 
        if (convert_rate)
                fsrate = 0x0400000 / convert_rate * runtime->rate;
 
-       /* set/clear soft reset */
-       rsnd_mod_write(mod, SRC_SWRSR, 0);
-       rsnd_mod_write(mod, SRC_SWRSR, 1);
-
        /* Set channel number and output bit length */
-       rsnd_mod_write(mod, SRC_ADINR, rsnd_get_adinr(mod));
+       rsnd_mod_write(mod, SRC_ADINR, rsnd_get_adinr_bit(mod, io));
 
        /* Enable the initial value of IFS */
        if (fsrate) {
@@ -316,6 +312,7 @@ static int rsnd_src_set_convert_rate(struct rsnd_mod *mod)
 }
 
 static int rsnd_src_hw_params(struct rsnd_mod *mod,
+                             struct rsnd_dai_stream *io,
                              struct snd_pcm_substream *substream,
                              struct snd_pcm_hw_params *fe_params)
 {
@@ -355,29 +352,28 @@ static int rsnd_src_init(struct rsnd_mod *mod,
 {
        struct rsnd_src *src = rsnd_mod_to_src(mod);
 
-       rsnd_mod_hw_start(mod);
+       rsnd_mod_power_on(mod);
+
+       rsnd_src_soft_reset(mod);
+
+       rsnd_src_initialize_lock(mod);
 
        src->err = 0;
 
        /* reset sync convert_rate */
        src->sync.val = 0;
 
-       /*
-        * Initialize the operation of the SRC internal circuits
-        * see rsnd_src_start()
-        */
-       rsnd_mod_write(mod, SRC_SRCIR, 1);
-
        return 0;
 }
 
 static int rsnd_src_quit(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);
 
-       rsnd_mod_hw_stop(mod);
+       rsnd_mod_power_off(mod);
 
        if (src->err)
                dev_warn(dev, "%s[%d] under/over flow err = %d\n",
@@ -393,11 +389,7 @@ static int rsnd_src_quit(struct rsnd_mod *mod,
 
 static int rsnd_src_start(struct rsnd_mod *mod)
 {
-       /*
-        * Cancel the initialization and operate the SRC function
-        * see rsnd_src_init()
-        */
-       rsnd_mod_write(mod, SRC_SRCIR, 0);
+       rsnd_src_initialize_unlock(mod);
 
        return 0;
 }
@@ -411,9 +403,9 @@ static int rsnd_src_stop(struct rsnd_mod *mod)
 /*
  *             Gen1 functions
  */
-static int rsnd_src_set_route_gen1(struct rsnd_mod *mod)
+static int rsnd_src_set_route_gen1(struct rsnd_dai_stream *io,
+                                  struct rsnd_mod *mod)
 {
-       struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
        struct src_route_config {
                u32 mask;
                int shift;
@@ -448,13 +440,13 @@ static int rsnd_src_set_route_gen1(struct rsnd_mod *mod)
        return 0;
 }
 
-static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod)
+static int rsnd_src_set_convert_timing_gen1(struct rsnd_dai_stream *io,
+                                           struct rsnd_mod *mod)
 {
-       struct rsnd_dai_stream *io = rsnd_mod_to_io(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(src);
+       u32 convert_rate = rsnd_src_convert_rate(io, src);
        u32 mask;
        u32 val;
        int shift;
@@ -506,12 +498,13 @@ static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod)
        return 0;
 }
 
-static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod)
+static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod,
+                                         struct rsnd_dai_stream *io)
 {
        struct rsnd_src *src = rsnd_mod_to_src(mod);
        int ret;
 
-       ret = rsnd_src_set_convert_rate(mod);
+       ret = rsnd_src_set_convert_rate(mod, io);
        if (ret < 0)
                return ret;
 
@@ -523,7 +516,7 @@ static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod)
                       rsnd_mod_read(mod, SRC_IFSVR) / 100 * 98);
 
        /* Gen1/Gen2 are not compatible */
-       if (rsnd_src_convert_rate(src))
+       if (rsnd_src_convert_rate(io, src))
                rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1);
 
        /* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */
@@ -532,6 +525,7 @@ static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod)
 }
 
 static int rsnd_src_init_gen1(struct rsnd_mod *mod,
+                             struct rsnd_dai_stream *io,
                              struct rsnd_priv *priv)
 {
        int ret;
@@ -540,15 +534,15 @@ static int rsnd_src_init_gen1(struct rsnd_mod *mod,
        if (ret < 0)
                return ret;
 
-       ret = rsnd_src_set_route_gen1(mod);
+       ret = rsnd_src_set_route_gen1(io, mod);
        if (ret < 0)
                return ret;
 
-       ret = rsnd_src_set_convert_rate_gen1(mod);
+       ret = rsnd_src_set_convert_rate_gen1(mod, io);
        if (ret < 0)
                return ret;
 
-       ret = rsnd_src_set_convert_timing_gen1(mod);
+       ret = rsnd_src_set_convert_timing_gen1(io, mod);
        if (ret < 0)
                return ret;
 
@@ -556,6 +550,7 @@ static int rsnd_src_init_gen1(struct rsnd_mod *mod,
 }
 
 static int rsnd_src_start_gen1(struct rsnd_mod *mod,
+                              struct rsnd_dai_stream *io,
                               struct rsnd_priv *priv)
 {
        int id = rsnd_mod_id(mod);
@@ -566,6 +561,7 @@ static int rsnd_src_start_gen1(struct rsnd_mod *mod,
 }
 
 static int rsnd_src_stop_gen1(struct rsnd_mod *mod,
+                             struct rsnd_dai_stream *io,
                              struct rsnd_priv *priv)
 {
        int id = rsnd_mod_id(mod);
@@ -611,6 +607,14 @@ static void rsnd_src_irq_ctrol_gen2(struct rsnd_mod *mod, int enable)
                int_val = 0;
        }
 
+       /*
+        * WORKAROUND
+        *
+        * ignore over flow error when rsnd_enable_sync_convert()
+        */
+       if (rsnd_enable_sync_convert(src))
+               sys_int_val = sys_int_val & 0xffff;
+
        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);
@@ -626,11 +630,22 @@ static void rsnd_src_error_clear_gen2(struct rsnd_mod *mod)
 
 static bool rsnd_src_error_record_gen2(struct rsnd_mod *mod)
 {
-       u32 val = OUF_SRC(rsnd_mod_id(mod));
+       struct rsnd_src *src = rsnd_mod_to_src(mod);
+       u32 val0, val1;
        bool ret = false;
 
-       if ((rsnd_mod_read(mod, SCU_SYS_STATUS0) & val) ||
-           (rsnd_mod_read(mod, SCU_SYS_STATUS1) & val)) {
+       val0 = val1 = OUF_SRC(rsnd_mod_id(mod));
+
+       /*
+        * WORKAROUND
+        *
+        * ignore over flow error when rsnd_enable_sync_convert()
+        */
+       if (rsnd_enable_sync_convert(src))
+               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++;
@@ -643,10 +658,23 @@ static bool rsnd_src_error_record_gen2(struct rsnd_mod *mod)
        return ret;
 }
 
-static int _rsnd_src_start_gen2(struct rsnd_mod *mod)
+static int _rsnd_src_start_gen2(struct rsnd_mod *mod,
+                               struct rsnd_dai_stream *io)
 {
-       struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
-       u32 val = rsnd_io_to_mod_dvc(io) ? 0x01 : 0x11;
+       struct rsnd_src *src = rsnd_mod_to_src(mod);
+       u32 val;
+
+       val = rsnd_get_dalign(mod, io);
+
+       rsnd_mod_write(mod, SRC_BUSIF_DALIGN, val);
+
+       /*
+        * WORKAROUND
+        *
+        * Enable SRC output if you want to use sync convert together with DVC
+        */
+       val = (rsnd_io_to_mod_dvc(io) && !rsnd_enable_sync_convert(src)) ?
+               0x01 : 0x11;
 
        rsnd_mod_write(mod, SRC_CTRL, val);
 
@@ -670,13 +698,16 @@ static int _rsnd_src_stop_gen2(struct rsnd_mod *mod)
        return rsnd_src_stop(mod);
 }
 
-static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data)
+static void __rsnd_src_interrupt_gen2(struct rsnd_mod *mod,
+                                     struct rsnd_dai_stream *io)
 {
-       struct rsnd_mod *mod = data;
-       struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
+       struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
 
-       if (!io)
-               return IRQ_NONE;
+       spin_lock(&priv->lock);
+
+       /* ignore all cases if not working */
+       if (!rsnd_io_is_working(io))
+               goto rsnd_src_interrupt_gen2_out;
 
        if (rsnd_src_error_record_gen2(mod)) {
                struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
@@ -688,22 +719,32 @@ static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data)
 
                _rsnd_src_stop_gen2(mod);
                if (src->err < 1024)
-                       _rsnd_src_start_gen2(mod);
+                       _rsnd_src_start_gen2(mod, io);
                else
                        dev_warn(dev, "no more SRC restart\n");
        }
 
+rsnd_src_interrupt_gen2_out:
+       spin_unlock(&priv->lock);
+}
+
+static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data)
+{
+       struct rsnd_mod *mod = data;
+
+       rsnd_mod_interrupt(mod, __rsnd_src_interrupt_gen2);
+
        return IRQ_HANDLED;
 }
 
-static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod)
+static int rsnd_src_set_convert_rate_gen2(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 rsnd_dai_stream *io = rsnd_mod_to_io(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(src);
+       u32 convert_rate = rsnd_src_convert_rate(io, src);
        u32 cr, route;
        uint ratio;
        int ret;
@@ -721,7 +762,7 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod)
                return -EINVAL;
        }
 
-       ret = rsnd_src_set_convert_rate(mod);
+       ret = rsnd_src_set_convert_rate(mod, io);
        if (ret < 0)
                return ret;
 
@@ -757,12 +798,12 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod)
        return 0;
 }
 
-static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod)
+static int rsnd_src_set_convert_timing_gen2(struct rsnd_dai_stream *io,
+                                           struct rsnd_mod *mod)
 {
-       struct rsnd_dai_stream *io = rsnd_mod_to_io(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(src);
+       u32 convert_rate = rsnd_src_convert_rate(io, src);
        int ret;
 
        if (convert_rate)
@@ -776,6 +817,7 @@ static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod)
 }
 
 static int rsnd_src_probe_gen2(struct rsnd_mod *mod,
+                              struct rsnd_dai_stream *io,
                               struct rsnd_priv *priv)
 {
        struct rsnd_src *src = rsnd_mod_to_src(mod);
@@ -797,7 +839,7 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod,
                        return ret;
        }
 
-       ret = rsnd_dma_init(priv,
+       ret = rsnd_dma_init(io,
                            rsnd_mod_to_dma(mod),
                            src->info->dma_id);
 
@@ -805,14 +847,16 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod,
 }
 
 static int rsnd_src_remove_gen2(struct rsnd_mod *mod,
+                               struct rsnd_dai_stream *io,
                                struct rsnd_priv *priv)
 {
-       rsnd_dma_quit(rsnd_mod_to_dma(mod));
+       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;
@@ -821,11 +865,11 @@ static int rsnd_src_init_gen2(struct rsnd_mod *mod,
        if (ret < 0)
                return ret;
 
-       ret = rsnd_src_set_convert_rate_gen2(mod);
+       ret = rsnd_src_set_convert_rate_gen2(mod, io);
        if (ret < 0)
                return ret;
 
-       ret = rsnd_src_set_convert_timing_gen2(mod);
+       ret = rsnd_src_set_convert_timing_gen2(io, mod);
        if (ret < 0)
                return ret;
 
@@ -833,31 +877,33 @@ static int rsnd_src_init_gen2(struct rsnd_mod *mod,
 }
 
 static int rsnd_src_start_gen2(struct rsnd_mod *mod,
+                              struct rsnd_dai_stream *io,
                               struct rsnd_priv *priv)
 {
-       rsnd_dma_start(rsnd_mod_to_dma(mod));
+       rsnd_dma_start(io, rsnd_mod_to_dma(mod));
 
-       return _rsnd_src_start_gen2(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(rsnd_mod_to_dma(mod));
+       rsnd_dma_stop(io, rsnd_mod_to_dma(mod));
 
        return ret;
 }
 
-static void rsnd_src_reconvert_update(struct rsnd_mod *mod)
+static void rsnd_src_reconvert_update(struct rsnd_dai_stream *io,
+                                     struct rsnd_mod *mod)
 {
-       struct rsnd_dai_stream *io = rsnd_mod_to_io(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(src);
+       u32 convert_rate = rsnd_src_convert_rate(io, src);
        u32 fsrate;
 
        if (!runtime)
@@ -872,12 +918,12 @@ static void rsnd_src_reconvert_update(struct rsnd_mod *mod)
        rsnd_mod_write(mod, SRC_IFSVR, fsrate);
 }
 
-static int rsnd_src_pcm_new(struct rsnd_mod *mod,
+static int rsnd_src_pcm_new_gen2(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_stream *io = rsnd_mod_to_io(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;
 
@@ -885,12 +931,6 @@ static int rsnd_src_pcm_new(struct rsnd_mod *mod,
         * enable SRC sync convert if possible
         */
 
-       /*
-        * Gen1 is not supported
-        */
-       if (rsnd_is_gen1(priv))
-               return 0;
-
        /*
         * SRC sync convert needs clock master
         */
@@ -898,16 +938,15 @@ static int rsnd_src_pcm_new(struct rsnd_mod *mod,
                return 0;
 
        /*
-        * We can't use SRC sync convert
-        * if it has DVC
+        * SRC In doesn't work if DVC was enabled
         */
-       if (rsnd_io_to_mod_dvc(io))
+       if (dvc && !rsnd_io_is_play(io))
                return 0;
 
        /*
         * enable sync convert
         */
-       ret = rsnd_kctrl_new_s(mod, rtd,
+       ret = rsnd_kctrl_new_s(mod, io, rtd,
                               rsnd_io_is_play(io) ?
                               "SRC Out Rate Switch" :
                               "SRC In Rate Switch",
@@ -916,7 +955,7 @@ static int rsnd_src_pcm_new(struct rsnd_mod *mod,
        if (ret < 0)
                return ret;
 
-       ret = rsnd_kctrl_new_s(mod, rtd,
+       ret = rsnd_kctrl_new_s(mod, io, rtd,
                               rsnd_io_is_play(io) ?
                               "SRC Out Rate" :
                               "SRC In Rate",
@@ -936,7 +975,7 @@ static struct rsnd_mod_ops rsnd_src_gen2_ops = {
        .start  = rsnd_src_start_gen2,
        .stop   = rsnd_src_stop_gen2,
        .hw_params = rsnd_src_hw_params,
-       .pcm_new = rsnd_src_pcm_new,
+       .pcm_new = rsnd_src_pcm_new_gen2,
 };
 
 struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
@@ -944,7 +983,7 @@ 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 &((struct rsnd_src *)(priv->src) + id)->mod;
+       return rsnd_mod_get((struct rsnd_src *)(priv->src) + id);
 }
 
 static void rsnd_of_parse_src(struct platform_device *pdev,
@@ -1004,8 +1043,10 @@ int rsnd_src_probe(struct platform_device *pdev,
        int i, nr, ret;
 
        ops = NULL;
-       if (rsnd_is_gen1(priv))
+       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) {
@@ -1023,10 +1064,8 @@ int rsnd_src_probe(struct platform_device *pdev,
                return 0;
 
        src     = devm_kzalloc(dev, sizeof(*src) * nr, GFP_KERNEL);
-       if (!src) {
-               dev_err(dev, "SRC allocate failed\n");
+       if (!src)
                return -ENOMEM;
-       }
 
        priv->src_nr    = nr;
        priv->src       = src;
@@ -1041,7 +1080,7 @@ int rsnd_src_probe(struct platform_device *pdev,
 
                src->info = &info->src_info[i];
 
-               ret = rsnd_mod_init(&src->mod, ops, clk, RSND_MOD_SRC, i);
+               ret = rsnd_mod_init(priv, rsnd_mod_get(src), ops, clk, RSND_MOD_SRC, i);
                if (ret)
                        return ret;
        }
@@ -1056,6 +1095,6 @@ void rsnd_src_remove(struct platform_device *pdev,
        int i;
 
        for_each_rsnd_src(src, priv, i) {
-               rsnd_mod_quit(&src->mod);
+               rsnd_mod_quit(rsnd_mod_get(src));
        }
 }