Skip to content

Commit eb2caa8

Browse files
morimotoDinh Nguyen
authored andcommitted
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 <[email protected]> Tested-by: Keita Kobayashi <[email protected]> Signed-off-by: Mark Brown <[email protected]> (cherry picked from commit 70fb105) Signed-off-by: Simon Horman <[email protected]>
1 parent 59137a4 commit eb2caa8

File tree

8 files changed

+333
-13
lines changed

8 files changed

+333
-13
lines changed

Documentation/devicetree/bindings/sound/renesas,rsnd.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ Required properties:
2121
- rcar_sound,ctu : Should contain CTU feature.
2222
The number of CTU subnode should be same as HW.
2323
see below for detail.
24+
- rcar_sound,mix : Should contain MIX feature.
25+
The number of MIX subnode should be same as HW.
26+
see below for detail.
2427
- rcar_sound,dvc : Should contain DVC feature.
2528
The number of DVC subnode should be same as HW.
2629
see below for detail.
@@ -93,6 +96,11 @@ rcar_sound: sound@ec500000 {
9396
};
9497
};
9598

99+
rcar_sound,mix {
100+
mix0: mix@0 { };
101+
mix1: mix@1 { };
102+
};
103+
96104
rcar_sound,ctu {
97105
ctu00: ctu@0 { };
98106
ctu01: ctu@1 { };

include/sound/rcar_snd.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ struct rsnd_ctu_platform_info {
6565
u32 flags;
6666
};
6767

68+
struct rsnd_mix_platform_info {
69+
u32 flags;
70+
};
71+
6872
struct rsnd_dvc_platform_info {
6973
u32 flags;
7074
};
@@ -73,6 +77,7 @@ struct rsnd_dai_path_info {
7377
struct rsnd_ssi_platform_info *ssi;
7478
struct rsnd_src_platform_info *src;
7579
struct rsnd_ctu_platform_info *ctu;
80+
struct rsnd_mix_platform_info *mix;
7681
struct rsnd_dvc_platform_info *dvc;
7782
};
7883

@@ -100,6 +105,8 @@ struct rcar_snd_info {
100105
int src_info_nr;
101106
struct rsnd_ctu_platform_info *ctu_info;
102107
int ctu_info_nr;
108+
struct rsnd_mix_platform_info *mix_info;
109+
int mix_info_nr;
103110
struct rsnd_dvc_platform_info *dvc_info;
104111
int dvc_info_nr;
105112
struct rsnd_dai_platform_info *dai_info;

sound/soc/sh/rcar/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
snd-soc-rcar-objs := core.o gen.o dma.o adg.o ssi.o src.o ctu.o dvc.o
1+
snd-soc-rcar-objs := core.o gen.o dma.o adg.o ssi.o src.o ctu.o mix.o dvc.o
22
obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o
33

44
snd-soc-rsrc-card-objs := rsrc-card.o

sound/soc/sh/rcar/core.c

Lines changed: 73 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -605,23 +605,74 @@ static const struct snd_soc_dai_ops rsnd_soc_dai_ops = {
605605
void rsnd_path_parse(struct rsnd_priv *priv,
606606
struct rsnd_dai_stream *io)
607607
{
608-
struct rsnd_mod *src = rsnd_io_to_mod_src(io);
609608
struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
610-
int src_id = rsnd_mod_id(src);
611-
u32 path[] = {
612-
[0] = 0x30000,
613-
[1] = 0x30001,
614-
[2] = 0x40000,
615-
[3] = 0x10000,
616-
[4] = 0x20000,
617-
[5] = 0x40100
618-
};
609+
struct rsnd_mod *mix = rsnd_io_to_mod_mix(io);
610+
struct rsnd_mod *src = rsnd_io_to_mod_src(io);
611+
struct rsnd_mod *cmd;
612+
struct device *dev = rsnd_priv_to_dev(priv);
613+
u32 data;
619614

620615
/* Gen1 is not supported */
621616
if (rsnd_is_gen1(priv))
622617
return;
623618

624-
rsnd_mod_write(dvc, CMD_ROUTE_SLCT, path[src_id]);
619+
if (!mix && !dvc)
620+
return;
621+
622+
if (mix) {
623+
struct rsnd_dai *rdai;
624+
int i;
625+
u32 path[] = {
626+
[0] = 0,
627+
[1] = 1 << 0,
628+
[2] = 0,
629+
[3] = 0,
630+
[4] = 0,
631+
[5] = 1 << 8
632+
};
633+
634+
/*
635+
* it is assuming that integrater is well understanding about
636+
* data path. Here doesn't check impossible connection,
637+
* like src2 + src5
638+
*/
639+
data = 0;
640+
for_each_rsnd_dai(rdai, priv, i) {
641+
io = &rdai->playback;
642+
if (mix == rsnd_io_to_mod_mix(io))
643+
data |= path[rsnd_mod_id(src)];
644+
645+
io = &rdai->capture;
646+
if (mix == rsnd_io_to_mod_mix(io))
647+
data |= path[rsnd_mod_id(src)];
648+
}
649+
650+
/*
651+
* We can't use ctu = rsnd_io_ctu() here.
652+
* Since, ID of dvc/mix are 0 or 1 (= same as CMD number)
653+
* but ctu IDs are 0 - 7 (= CTU00 - CTU13)
654+
*/
655+
cmd = mix;
656+
} else {
657+
u32 path[] = {
658+
[0] = 0x30000,
659+
[1] = 0x30001,
660+
[2] = 0x40000,
661+
[3] = 0x10000,
662+
[4] = 0x20000,
663+
[5] = 0x40100
664+
};
665+
666+
data = path[rsnd_mod_id(src)];
667+
668+
cmd = dvc;
669+
}
670+
671+
dev_dbg(dev, "ctu/mix path = 0x%08x", data);
672+
673+
rsnd_mod_write(cmd, CMD_ROUTE_SLCT, data);
674+
675+
rsnd_mod_write(cmd, CMD_CTRL, 0x10);
625676
}
626677

627678
static int rsnd_path_init(struct rsnd_priv *priv,
@@ -656,6 +707,11 @@ static int rsnd_path_init(struct rsnd_priv *priv,
656707
if (ret < 0)
657708
return ret;
658709

710+
/* MIX */
711+
ret = rsnd_path_add(priv, io, mix);
712+
if (ret < 0)
713+
return ret;
714+
659715
/* DVC */
660716
ret = rsnd_path_add(priv, io, dvc);
661717
if (ret < 0)
@@ -672,13 +728,14 @@ static void rsnd_of_parse_dai(struct platform_device *pdev,
672728
struct device_node *ssi_node, *ssi_np;
673729
struct device_node *src_node, *src_np;
674730
struct device_node *ctu_node, *ctu_np;
731+
struct device_node *mix_node, *mix_np;
675732
struct device_node *dvc_node, *dvc_np;
676733
struct device_node *playback, *capture;
677734
struct rsnd_dai_platform_info *dai_info;
678735
struct rcar_snd_info *info = rsnd_priv_to_info(priv);
679736
struct device *dev = &pdev->dev;
680737
int nr, i;
681-
int dai_i, ssi_i, src_i, ctu_i, dvc_i;
738+
int dai_i, ssi_i, src_i, ctu_i, mix_i, dvc_i;
682739

683740
if (!of_data)
684741
return;
@@ -705,6 +762,7 @@ static void rsnd_of_parse_dai(struct platform_device *pdev,
705762
ssi_node = of_get_child_by_name(dev->of_node, "rcar_sound,ssi");
706763
src_node = of_get_child_by_name(dev->of_node, "rcar_sound,src");
707764
ctu_node = of_get_child_by_name(dev->of_node, "rcar_sound,ctu");
765+
mix_node = of_get_child_by_name(dev->of_node, "rcar_sound,mix");
708766
dvc_node = of_get_child_by_name(dev->of_node, "rcar_sound,dvc");
709767

710768
#define mod_parse(name) \
@@ -742,6 +800,7 @@ if (name##_node) { \
742800
mod_parse(ssi);
743801
mod_parse(src);
744802
mod_parse(ctu);
803+
mod_parse(mix);
745804
mod_parse(dvc);
746805

747806
of_node_put(playback);
@@ -1155,6 +1214,7 @@ static int rsnd_probe(struct platform_device *pdev)
11551214
rsnd_ssi_probe,
11561215
rsnd_src_probe,
11571216
rsnd_ctu_probe,
1217+
rsnd_mix_probe,
11581218
rsnd_dvc_probe,
11591219
rsnd_adg_probe,
11601220
rsnd_dai_probe,
@@ -1251,6 +1311,7 @@ static int rsnd_remove(struct platform_device *pdev)
12511311
rsnd_ssi_remove,
12521312
rsnd_src_remove,
12531313
rsnd_ctu_remove,
1314+
rsnd_mix_remove,
12541315
rsnd_dvc_remove,
12551316
};
12561317
int ret = 0, i;

sound/soc/sh/rcar/dma.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,7 @@ rsnd_gen2_dma_addr(struct rsnd_dai_stream *io,
427427
int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod);
428428
int use_src = !!rsnd_io_to_mod_src(io);
429429
int use_cmd = !!rsnd_io_to_mod_dvc(io) ||
430+
!!rsnd_io_to_mod_mix(io) ||
430431
!!rsnd_io_to_mod_ctu(io);
431432
int id = rsnd_mod_id(mod);
432433
struct dma_addr {
@@ -506,6 +507,7 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma,
506507
struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
507508
struct rsnd_mod *src = rsnd_io_to_mod_src(io);
508509
struct rsnd_mod *ctu = rsnd_io_to_mod_ctu(io);
510+
struct rsnd_mod *mix = rsnd_io_to_mod_mix(io);
509511
struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
510512
struct rsnd_mod *mod[MOD_MAX];
511513
struct rsnd_mod *mod_start, *mod_end;
@@ -548,6 +550,9 @@ static void rsnd_dma_of_path(struct rsnd_dma *dma,
548550
} else if (ctu) {
549551
mod[i] = ctu;
550552
ctu = NULL;
553+
} else if (mix) {
554+
mod[i] = mix;
555+
mix = NULL;
551556
} else if (dvc) {
552557
mod[i] = dvc;
553558
dvc = NULL;

sound/soc/sh/rcar/gen.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,16 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
242242
RSND_GEN_M_REG(SRC_BSISR, 0x238, 0x40),
243243
RSND_GEN_M_REG(CTU_CTUIR, 0x504, 0x100),
244244
RSND_GEN_M_REG(CTU_ADINR, 0x508, 0x100),
245+
RSND_GEN_M_REG(MIX_SWRSR, 0xd00, 0x40),
246+
RSND_GEN_M_REG(MIX_MIXIR, 0xd04, 0x40),
247+
RSND_GEN_M_REG(MIX_ADINR, 0xd08, 0x40),
248+
RSND_GEN_M_REG(MIX_MIXMR, 0xd10, 0x40),
249+
RSND_GEN_M_REG(MIX_MVPDR, 0xd14, 0x40),
250+
RSND_GEN_M_REG(MIX_MDBAR, 0xd18, 0x40),
251+
RSND_GEN_M_REG(MIX_MDBBR, 0xd1c, 0x40),
252+
RSND_GEN_M_REG(MIX_MDBCR, 0xd20, 0x40),
253+
RSND_GEN_M_REG(MIX_MDBDR, 0xd24, 0x40),
254+
RSND_GEN_M_REG(MIX_MDBER, 0xd28, 0x40),
245255
RSND_GEN_M_REG(DVC_SWRSR, 0xe00, 0x100),
246256
RSND_GEN_M_REG(DVC_DVUIR, 0xe04, 0x100),
247257
RSND_GEN_M_REG(DVC_ADINR, 0xe08, 0x100),

0 commit comments

Comments
 (0)