aboutsummaryrefslogtreecommitdiffstats
path: root/patches.renesas/0306-ASoC-rsnd-add-MIX-Mixer-support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches.renesas/0306-ASoC-rsnd-add-MIX-Mixer-support.patch')
-rw-r--r--patches.renesas/0306-ASoC-rsnd-add-MIX-Mixer-support.patch611
1 files changed, 611 insertions, 0 deletions
diff --git a/patches.renesas/0306-ASoC-rsnd-add-MIX-Mixer-support.patch b/patches.renesas/0306-ASoC-rsnd-add-MIX-Mixer-support.patch
new file mode 100644
index 00000000000000..595bca2be5696f
--- /dev/null
+++ b/patches.renesas/0306-ASoC-rsnd-add-MIX-Mixer-support.patch
@@ -0,0 +1,611 @@
+From 91949d91db62cb7b7ce9704d37c4b24453d5afc5 Mon Sep 17 00:00:00 2001
+From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Date: Wed, 15 Jul 2015 07:17:36 +0000
+Subject: [PATCH 306/326] ASoC: rsnd: add MIX (Mixer) support
+
+This patch adds MIX (Mixer) initial support for rsnd driver.
+It is assuming that this MIX is used via DPCM.
+
+This is sample code for playback.
+
+ CPU0 : [MEM] -> [SRC1] -> [CTU02] -+
+ |
+ +-> [MIX0] -> [DVC0] -> [SSI0]
+ |
+ CPU1 : [MEM] -> [SRC2] -> [CTU03] -+
+
+ sound {
+ compatible = "renesas,rsrc-card";
+
+ ...
+
+ cpu@0 {
+ sound-dai = <&rcar_sound 0>;
+ };
+
+ cpu@1 {
+ sound-dai = <&rcar_sound 1>;
+ };
+
+ codec {
+ ...
+ };
+ };
+
+ rcar_sound {
+
+ ...
+
+ rcar_sound,dai {
+ dai0 {
+ playback = <&src1 &ctu02 &mix0 &dvc0 &ssi0>;
+ };
+ dai1 {
+ playback = <&src2 &ctu03 &mix0 &dvc0 &ssi0>;
+ };
+ };
+ };
+
+Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Tested-by: Keita Kobayashi <keita.kobayashi.ym@renesas.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+(cherry picked from commit 70fb10529f61c31c26397a02091177bedd23217d)
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+---
+ .../devicetree/bindings/sound/renesas,rsnd.txt | 8 +
+ include/sound/rcar_snd.h | 7 +
+ sound/soc/sh/rcar/Makefile | 2 +-
+ sound/soc/sh/rcar/core.c | 85 +++++++--
+ sound/soc/sh/rcar/dma.c | 5 +
+ sound/soc/sh/rcar/gen.c | 10 ++
+ sound/soc/sh/rcar/mix.c | 200 +++++++++++++++++++++
+ sound/soc/sh/rcar/rsnd.h | 29 +++
+ 8 files changed, 333 insertions(+), 13 deletions(-)
+ create mode 100644 sound/soc/sh/rcar/mix.c
+
+diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt
+index 278607de05de..1173395b5e5c 100644
+--- a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt
++++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt
+@@ -21,6 +21,9 @@ Required properties:
+ - rcar_sound,ctu : Should contain CTU feature.
+ The number of CTU subnode should be same as HW.
+ see below for detail.
++- rcar_sound,mix : Should contain MIX feature.
++ The number of MIX subnode should be same as HW.
++ see below for detail.
+ - rcar_sound,dvc : Should contain DVC feature.
+ The number of DVC subnode should be same as HW.
+ see below for detail.
+@@ -93,6 +96,11 @@ rcar_sound: sound@ec500000 {
+ };
+ };
+
++ rcar_sound,mix {
++ mix0: mix@0 { };
++ mix1: mix@1 { };
++ };
++
+ rcar_sound,ctu {
+ ctu00: ctu@0 { };
+ ctu01: ctu@1 { };
+diff --git a/include/sound/rcar_snd.h b/include/sound/rcar_snd.h
+index 8f9303093ab9..bb7b2ebfee7b 100644
+--- a/include/sound/rcar_snd.h
++++ b/include/sound/rcar_snd.h
+@@ -65,6 +65,10 @@ struct rsnd_ctu_platform_info {
+ u32 flags;
+ };
+
++struct rsnd_mix_platform_info {
++ u32 flags;
++};
++
+ struct rsnd_dvc_platform_info {
+ u32 flags;
+ };
+@@ -73,6 +77,7 @@ struct rsnd_dai_path_info {
+ struct rsnd_ssi_platform_info *ssi;
+ struct rsnd_src_platform_info *src;
+ struct rsnd_ctu_platform_info *ctu;
++ struct rsnd_mix_platform_info *mix;
+ struct rsnd_dvc_platform_info *dvc;
+ };
+
+@@ -100,6 +105,8 @@ struct rcar_snd_info {
+ int src_info_nr;
+ struct rsnd_ctu_platform_info *ctu_info;
+ int ctu_info_nr;
++ struct rsnd_mix_platform_info *mix_info;
++ int mix_info_nr;
+ struct rsnd_dvc_platform_info *dvc_info;
+ int dvc_info_nr;
+ struct rsnd_dai_platform_info *dai_info;
+diff --git a/sound/soc/sh/rcar/Makefile b/sound/soc/sh/rcar/Makefile
+index 7c4730a81c4a..8b258501aa35 100644
+--- a/sound/soc/sh/rcar/Makefile
++++ b/sound/soc/sh/rcar/Makefile
+@@ -1,4 +1,4 @@
+-snd-soc-rcar-objs := core.o gen.o dma.o adg.o ssi.o src.o ctu.o dvc.o
++snd-soc-rcar-objs := core.o gen.o dma.o adg.o ssi.o src.o ctu.o mix.o dvc.o
+ obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o
+
+ snd-soc-rsrc-card-objs := rsrc-card.o
+diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
+index 63ae7bbfd1dc..927a7b02123b 100644
+--- a/sound/soc/sh/rcar/core.c
++++ b/sound/soc/sh/rcar/core.c
+@@ -605,23 +605,74 @@ static const struct snd_soc_dai_ops rsnd_soc_dai_ops = {
+ void rsnd_path_parse(struct rsnd_priv *priv,
+ struct rsnd_dai_stream *io)
+ {
+- struct rsnd_mod *src = rsnd_io_to_mod_src(io);
+ struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
+- int src_id = rsnd_mod_id(src);
+- u32 path[] = {
+- [0] = 0x30000,
+- [1] = 0x30001,
+- [2] = 0x40000,
+- [3] = 0x10000,
+- [4] = 0x20000,
+- [5] = 0x40100
+- };
++ 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 device *dev = rsnd_priv_to_dev(priv);
++ u32 data;
+
+ /* Gen1 is not supported */
+ if (rsnd_is_gen1(priv))
+ return;
+
+- rsnd_mod_write(dvc, CMD_ROUTE_SLCT, path[src_id]);
++ 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;
++ }
++
++ dev_dbg(dev, "ctu/mix path = 0x%08x", data);
++
++ rsnd_mod_write(cmd, CMD_ROUTE_SLCT, data);
++
++ rsnd_mod_write(cmd, CMD_CTRL, 0x10);
+ }
+
+ static int rsnd_path_init(struct rsnd_priv *priv,
+@@ -656,6 +707,11 @@ static int rsnd_path_init(struct rsnd_priv *priv,
+ if (ret < 0)
+ return ret;
+
++ /* MIX */
++ ret = rsnd_path_add(priv, io, mix);
++ if (ret < 0)
++ return ret;
++
+ /* DVC */
+ ret = rsnd_path_add(priv, io, dvc);
+ if (ret < 0)
+@@ -672,13 +728,14 @@ static void rsnd_of_parse_dai(struct platform_device *pdev,
+ 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 *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, dvc_i;
++ int dai_i, ssi_i, src_i, ctu_i, mix_i, dvc_i;
+
+ if (!of_data)
+ return;
+@@ -705,6 +762,7 @@ static void rsnd_of_parse_dai(struct platform_device *pdev,
+ 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) \
+@@ -742,6 +800,7 @@ if (name##_node) { \
+ mod_parse(ssi);
+ mod_parse(src);
+ mod_parse(ctu);
++ mod_parse(mix);
+ mod_parse(dvc);
+
+ of_node_put(playback);
+@@ -1155,6 +1214,7 @@ static int rsnd_probe(struct platform_device *pdev)
+ rsnd_ssi_probe,
+ rsnd_src_probe,
+ rsnd_ctu_probe,
++ rsnd_mix_probe,
+ rsnd_dvc_probe,
+ rsnd_adg_probe,
+ rsnd_dai_probe,
+@@ -1251,6 +1311,7 @@ static int rsnd_remove(struct platform_device *pdev)
+ rsnd_ssi_remove,
+ rsnd_src_remove,
+ rsnd_ctu_remove,
++ rsnd_mix_remove,
+ rsnd_dvc_remove,
+ };
+ int ret = 0, i;
+diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c
+index 229b68d2cf70..305b12929853 100644
+--- a/sound/soc/sh/rcar/dma.c
++++ b/sound/soc/sh/rcar/dma.c
+@@ -427,6 +427,7 @@ rsnd_gen2_dma_addr(struct rsnd_dai_stream *io,
+ int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod);
+ int use_src = !!rsnd_io_to_mod_src(io);
+ int use_cmd = !!rsnd_io_to_mod_dvc(io) ||
++ !!rsnd_io_to_mod_mix(io) ||
+ !!rsnd_io_to_mod_ctu(io);
+ int id = rsnd_mod_id(mod);
+ struct dma_addr {
+@@ -506,6 +507,7 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma,
+ struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
+ struct rsnd_mod *src = rsnd_io_to_mod_src(io);
+ struct rsnd_mod *ctu = rsnd_io_to_mod_ctu(io);
++ struct rsnd_mod *mix = rsnd_io_to_mod_mix(io);
+ struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
+ struct rsnd_mod *mod[MOD_MAX];
+ struct rsnd_mod *mod_start, *mod_end;
+@@ -548,6 +550,9 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma,
+ } else if (ctu) {
+ mod[i] = ctu;
+ ctu = NULL;
++ } else if (mix) {
++ mod[i] = mix;
++ mix = NULL;
+ } else if (dvc) {
+ mod[i] = dvc;
+ dvc = NULL;
+diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
+index 41b75cd4e09b..f04d17bc6e3d 100644
+--- a/sound/soc/sh/rcar/gen.c
++++ b/sound/soc/sh/rcar/gen.c
+@@ -242,6 +242,16 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
+ RSND_GEN_M_REG(SRC_BSISR, 0x238, 0x40),
+ RSND_GEN_M_REG(CTU_CTUIR, 0x504, 0x100),
+ RSND_GEN_M_REG(CTU_ADINR, 0x508, 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),
++ RSND_GEN_M_REG(MIX_MIXMR, 0xd10, 0x40),
++ RSND_GEN_M_REG(MIX_MVPDR, 0xd14, 0x40),
++ RSND_GEN_M_REG(MIX_MDBAR, 0xd18, 0x40),
++ RSND_GEN_M_REG(MIX_MDBBR, 0xd1c, 0x40),
++ RSND_GEN_M_REG(MIX_MDBCR, 0xd20, 0x40),
++ RSND_GEN_M_REG(MIX_MDBDR, 0xd24, 0x40),
++ RSND_GEN_M_REG(MIX_MDBER, 0xd28, 0x40),
+ RSND_GEN_M_REG(DVC_SWRSR, 0xe00, 0x100),
+ RSND_GEN_M_REG(DVC_DVUIR, 0xe04, 0x100),
+ RSND_GEN_M_REG(DVC_ADINR, 0xe08, 0x100),
+diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c
+new file mode 100644
+index 000000000000..0d5c102db6f5
+--- /dev/null
++++ b/sound/soc/sh/rcar/mix.c
+@@ -0,0 +1,200 @@
++/*
++ * mix.c
++ *
++ * Copyright (c) 2015 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#include "rsnd.h"
++
++#define MIX_NAME_SIZE 16
++#define MIX_NAME "mix"
++
++struct rsnd_mix {
++ struct rsnd_mix_platform_info *info; /* rcar_snd.h */
++ struct rsnd_mod mod;
++};
++
++#define rsnd_mix_nr(priv) ((priv)->mix_nr)
++#define for_each_rsnd_mix(pos, priv, i) \
++ for ((i) = 0; \
++ ((i) < rsnd_mix_nr(priv)) && \
++ ((pos) = (struct rsnd_mix *)(priv)->mix + i); \
++ i++)
++
++
++static void rsnd_mix_soft_reset(struct rsnd_mod *mod)
++{
++ rsnd_mod_write(mod, MIX_SWRSR, 0);
++ rsnd_mod_write(mod, MIX_SWRSR, 1);
++}
++
++#define rsnd_mix_initialize_lock(mod) __rsnd_mix_initialize_lock(mod, 1)
++#define rsnd_mix_initialize_unlock(mod) __rsnd_mix_initialize_lock(mod, 0)
++static void __rsnd_mix_initialize_lock(struct rsnd_mod *mod, u32 enable)
++{
++ rsnd_mod_write(mod, MIX_MIXIR, enable);
++}
++
++static void rsnd_mix_volume_update(struct rsnd_dai_stream *io,
++ struct rsnd_mod *mod)
++{
++
++ /* Disable MIX dB setting */
++ rsnd_mod_write(mod, MIX_MDBER, 0);
++
++ rsnd_mod_write(mod, MIX_MDBAR, 0);
++ rsnd_mod_write(mod, MIX_MDBBR, 0);
++ rsnd_mod_write(mod, MIX_MDBCR, 0);
++ rsnd_mod_write(mod, MIX_MDBDR, 0);
++
++ /* Enable MIX dB setting */
++ rsnd_mod_write(mod, MIX_MDBER, 1);
++}
++
++static int rsnd_mix_init(struct rsnd_mod *mod,
++ struct rsnd_dai_stream *io,
++ struct rsnd_priv *priv)
++{
++ rsnd_mod_hw_start(mod);
++
++ rsnd_mix_soft_reset(mod);
++
++ rsnd_mix_initialize_lock(mod);
++
++ rsnd_mod_write(mod, MIX_ADINR, rsnd_get_adinr_chan(mod, io));
++
++ rsnd_path_parse(priv, io);
++
++ /* volume step */
++ rsnd_mod_write(mod, MIX_MIXMR, 0);
++ rsnd_mod_write(mod, MIX_MVPDR, 0);
++
++ rsnd_mix_volume_update(io, mod);
++
++ rsnd_mix_initialize_unlock(mod);
++
++ return 0;
++}
++
++static int rsnd_mix_quit(struct rsnd_mod *mod,
++ struct rsnd_dai_stream *io,
++ struct rsnd_priv *priv)
++{
++ rsnd_mod_hw_stop(mod);
++
++ return 0;
++}
++
++static struct rsnd_mod_ops rsnd_mix_ops = {
++ .name = MIX_NAME,
++ .init = rsnd_mix_init,
++ .quit = rsnd_mix_quit,
++};
++
++struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id)
++{
++ if (WARN_ON(id < 0 || id >= rsnd_mix_nr(priv)))
++ id = 0;
++
++ return &((struct rsnd_mix *)(priv->mix) + id)->mod;
++}
++
++static void rsnd_of_parse_mix(struct platform_device *pdev,
++ const struct rsnd_of_data *of_data,
++ struct rsnd_priv *priv)
++{
++ struct device_node *node;
++ struct rsnd_mix_platform_info *mix_info;
++ struct rcar_snd_info *info = rsnd_priv_to_info(priv);
++ struct device *dev = &pdev->dev;
++ int nr;
++
++ if (!of_data)
++ return;
++
++ node = of_get_child_by_name(dev->of_node, "rcar_sound,mix");
++ if (!node)
++ return;
++
++ nr = of_get_child_count(node);
++ if (!nr)
++ goto rsnd_of_parse_mix_end;
++
++ mix_info = devm_kzalloc(dev,
++ sizeof(struct rsnd_mix_platform_info) * nr,
++ GFP_KERNEL);
++ if (!mix_info) {
++ dev_err(dev, "mix info allocation error\n");
++ goto rsnd_of_parse_mix_end;
++ }
++
++ info->mix_info = mix_info;
++ info->mix_info_nr = nr;
++
++rsnd_of_parse_mix_end:
++ of_node_put(node);
++
++}
++
++int rsnd_mix_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_mix *mix;
++ struct clk *clk;
++ char name[MIX_NAME_SIZE];
++ int i, nr, ret;
++
++ /* This driver doesn't support Gen1 at this point */
++ if (rsnd_is_gen1(priv)) {
++ dev_warn(dev, "MIX is not supported on Gen1\n");
++ return -EINVAL;
++ }
++
++ rsnd_of_parse_mix(pdev, of_data, priv);
++
++ nr = info->mix_info_nr;
++ if (!nr)
++ return 0;
++
++ mix = devm_kzalloc(dev, sizeof(*mix) * nr, GFP_KERNEL);
++ if (!mix)
++ return -ENOMEM;
++
++ priv->mix_nr = nr;
++ priv->mix = mix;
++
++ for_each_rsnd_mix(mix, priv, i) {
++ snprintf(name, MIX_NAME_SIZE, "%s.%d",
++ MIX_NAME, i);
++
++ clk = devm_clk_get(dev, name);
++ if (IS_ERR(clk))
++ return PTR_ERR(clk);
++
++ mix->info = &info->mix_info[i];
++
++ ret = rsnd_mod_init(priv, &mix->mod, &rsnd_mix_ops,
++ clk, RSND_MOD_MIX, i);
++ if (ret)
++ return ret;
++ }
++
++ return 0;
++}
++
++void rsnd_mix_remove(struct platform_device *pdev,
++ struct rsnd_priv *priv)
++{
++ struct rsnd_mix *mix;
++ int i;
++
++ for_each_rsnd_mix(mix, priv, i) {
++ rsnd_mod_quit(&mix->mod);
++ }
++}
+diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
+index f2128a7cf259..7a0e52b4640a 100644
+--- a/sound/soc/sh/rcar/rsnd.h
++++ b/sound/soc/sh/rcar/rsnd.h
+@@ -49,6 +49,16 @@ enum rsnd_reg {
+ RSND_REG_CMD_ROUTE_SLCT,
+ RSND_REG_CTU_CTUIR,
+ RSND_REG_CTU_ADINR,
++ RSND_REG_MIX_SWRSR,
++ RSND_REG_MIX_MIXIR,
++ RSND_REG_MIX_ADINR,
++ RSND_REG_MIX_MIXMR,
++ RSND_REG_MIX_MVPDR,
++ RSND_REG_MIX_MDBAR,
++ RSND_REG_MIX_MDBBR,
++ RSND_REG_MIX_MDBCR,
++ RSND_REG_MIX_MDBDR,
++ RSND_REG_MIX_MDBER,
+ RSND_REG_DVC_SWRSR,
+ RSND_REG_DVC_DVUIR,
+ RSND_REG_DVC_ADINR,
+@@ -222,6 +232,7 @@ struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
+ */
+ enum rsnd_mod_type {
+ RSND_MOD_DVC = 0,
++ RSND_MOD_MIX,
+ RSND_MOD_CTU,
+ RSND_MOD_SRC,
+ RSND_MOD_SSI,
+@@ -355,6 +366,7 @@ struct rsnd_dai_stream {
+ #define rsnd_io_to_mod_ssi(io) rsnd_io_to_mod((io), RSND_MOD_SSI)
+ #define rsnd_io_to_mod_src(io) rsnd_io_to_mod((io), RSND_MOD_SRC)
+ #define rsnd_io_to_mod_ctu(io) rsnd_io_to_mod((io), RSND_MOD_CTU)
++#define rsnd_io_to_mod_mix(io) rsnd_io_to_mod((io), RSND_MOD_MIX)
+ #define rsnd_io_to_mod_dvc(io) rsnd_io_to_mod((io), RSND_MOD_DVC)
+ #define rsnd_io_to_rdai(io) ((io)->rdai)
+ #define rsnd_io_to_priv(io) (rsnd_rdai_to_priv(rsnd_io_to_rdai(io)))
+@@ -473,6 +485,12 @@ struct rsnd_priv {
+ int ctu_nr;
+
+ /*
++ * below value will be filled on rsnd_mix_probe()
++ */
++ void *mix;
++ int mix_nr;
++
++ /*
+ * below value will be filled on rsnd_dvc_probe()
+ */
+ void *dvc;
+@@ -589,6 +607,17 @@ void rsnd_ctu_remove(struct platform_device *pdev,
+ struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id);
+
+ /*
++ * R-Car MIX
++ */
++int rsnd_mix_probe(struct platform_device *pdev,
++ const struct rsnd_of_data *of_data,
++ struct rsnd_priv *priv);
++
++void rsnd_mix_remove(struct platform_device *pdev,
++ struct rsnd_priv *priv);
++struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id);
++
++/*
+ * R-Car DVC
+ */
+ int rsnd_dvc_probe(struct platform_device *pdev,
+--
+2.6.2
+