Skip to content

Commit 4455f26

Browse files
Sugar Zhangbroonie
authored andcommitted
ASoC: rockchip: i2s: Make playback/capture optional
There are some controllers which support playback only or capture only. so, make it optional. and initial capability by 'dma-names' of DT. Signed-off-by: Sugar Zhang <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 1bf5684 commit 4455f26

File tree

1 file changed

+79
-50
lines changed

1 file changed

+79
-50
lines changed

sound/soc/rockchip/rockchip_i2s.c

Lines changed: 79 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ struct rk_i2s_dev {
4040
struct regmap *regmap;
4141
struct regmap *grf;
4242

43+
bool has_capture;
44+
bool has_playback;
45+
4346
/*
4447
* Used to indicate the tx/rx status.
4548
* I2S controller hopes to start the tx and rx together,
@@ -453,8 +456,9 @@ static int rockchip_i2s_dai_probe(struct snd_soc_dai *dai)
453456
{
454457
struct rk_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai);
455458

456-
dai->capture_dma_data = &i2s->capture_dma_data;
457-
dai->playback_dma_data = &i2s->playback_dma_data;
459+
snd_soc_dai_init_dma_data(dai,
460+
i2s->has_playback ? &i2s->playback_dma_data : NULL,
461+
i2s->has_capture ? &i2s->capture_dma_data : NULL);
458462

459463
return 0;
460464
}
@@ -469,28 +473,6 @@ static const struct snd_soc_dai_ops rockchip_i2s_dai_ops = {
469473

470474
static struct snd_soc_dai_driver rockchip_i2s_dai = {
471475
.probe = rockchip_i2s_dai_probe,
472-
.playback = {
473-
.stream_name = "Playback",
474-
.channels_min = 2,
475-
.channels_max = 8,
476-
.rates = SNDRV_PCM_RATE_8000_192000,
477-
.formats = (SNDRV_PCM_FMTBIT_S8 |
478-
SNDRV_PCM_FMTBIT_S16_LE |
479-
SNDRV_PCM_FMTBIT_S20_3LE |
480-
SNDRV_PCM_FMTBIT_S24_LE |
481-
SNDRV_PCM_FMTBIT_S32_LE),
482-
},
483-
.capture = {
484-
.stream_name = "Capture",
485-
.channels_min = 2,
486-
.channels_max = 2,
487-
.rates = SNDRV_PCM_RATE_8000_192000,
488-
.formats = (SNDRV_PCM_FMTBIT_S8 |
489-
SNDRV_PCM_FMTBIT_S16_LE |
490-
SNDRV_PCM_FMTBIT_S20_3LE |
491-
SNDRV_PCM_FMTBIT_S24_LE |
492-
SNDRV_PCM_FMTBIT_S32_LE),
493-
},
494476
.ops = &rockchip_i2s_dai_ops,
495477
.symmetric_rate = 1,
496478
};
@@ -595,16 +577,84 @@ static const struct of_device_id rockchip_i2s_match[] __maybe_unused = {
595577
{},
596578
};
597579

580+
static int rockchip_i2s_init_dai(struct rk_i2s_dev *i2s, struct resource *res,
581+
struct snd_soc_dai_driver **dp)
582+
{
583+
struct device_node *node = i2s->dev->of_node;
584+
struct snd_soc_dai_driver *dai;
585+
struct property *dma_names;
586+
const char *dma_name;
587+
unsigned int val;
588+
589+
of_property_for_each_string(node, "dma-names", dma_names, dma_name) {
590+
if (!strcmp(dma_name, "tx"))
591+
i2s->has_playback = true;
592+
if (!strcmp(dma_name, "rx"))
593+
i2s->has_capture = true;
594+
}
595+
596+
dai = devm_kmemdup(i2s->dev, &rockchip_i2s_dai,
597+
sizeof(*dai), GFP_KERNEL);
598+
if (!dai)
599+
return -ENOMEM;
600+
601+
if (i2s->has_playback) {
602+
dai->playback.stream_name = "Playback";
603+
dai->playback.channels_min = 2;
604+
dai->playback.channels_max = 8;
605+
dai->playback.rates = SNDRV_PCM_RATE_8000_192000;
606+
dai->playback.formats = SNDRV_PCM_FMTBIT_S8 |
607+
SNDRV_PCM_FMTBIT_S16_LE |
608+
SNDRV_PCM_FMTBIT_S20_3LE |
609+
SNDRV_PCM_FMTBIT_S24_LE |
610+
SNDRV_PCM_FMTBIT_S32_LE;
611+
612+
i2s->playback_dma_data.addr = res->start + I2S_TXDR;
613+
i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
614+
i2s->playback_dma_data.maxburst = 8;
615+
616+
if (!of_property_read_u32(node, "rockchip,playback-channels", &val)) {
617+
if (val >= 2 && val <= 8)
618+
dai->playback.channels_max = val;
619+
}
620+
}
621+
622+
if (i2s->has_capture) {
623+
dai->capture.stream_name = "Capture";
624+
dai->capture.channels_min = 2;
625+
dai->capture.channels_max = 8;
626+
dai->capture.rates = SNDRV_PCM_RATE_8000_192000;
627+
dai->capture.formats = SNDRV_PCM_FMTBIT_S8 |
628+
SNDRV_PCM_FMTBIT_S16_LE |
629+
SNDRV_PCM_FMTBIT_S20_3LE |
630+
SNDRV_PCM_FMTBIT_S24_LE |
631+
SNDRV_PCM_FMTBIT_S32_LE;
632+
633+
i2s->capture_dma_data.addr = res->start + I2S_RXDR;
634+
i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
635+
i2s->capture_dma_data.maxburst = 8;
636+
637+
if (!of_property_read_u32(node, "rockchip,capture-channels", &val)) {
638+
if (val >= 2 && val <= 8)
639+
dai->capture.channels_max = val;
640+
}
641+
}
642+
643+
if (dp)
644+
*dp = dai;
645+
646+
return 0;
647+
}
648+
598649
static int rockchip_i2s_probe(struct platform_device *pdev)
599650
{
600651
struct device_node *node = pdev->dev.of_node;
601652
const struct of_device_id *of_id;
602653
struct rk_i2s_dev *i2s;
603-
struct snd_soc_dai_driver *soc_dai;
654+
struct snd_soc_dai_driver *dai;
604655
struct resource *res;
605656
void __iomem *regs;
606657
int ret;
607-
int val;
608658

609659
i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
610660
if (!i2s)
@@ -651,14 +701,6 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
651701
return PTR_ERR(i2s->regmap);
652702
}
653703

654-
i2s->playback_dma_data.addr = res->start + I2S_TXDR;
655-
i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
656-
i2s->playback_dma_data.maxburst = 8;
657-
658-
i2s->capture_dma_data.addr = res->start + I2S_RXDR;
659-
i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
660-
i2s->capture_dma_data.maxburst = 8;
661-
662704
i2s->bclk_ratio = 64;
663705

664706
dev_set_drvdata(&pdev->dev, i2s);
@@ -670,26 +712,13 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
670712
goto err_pm_disable;
671713
}
672714

673-
soc_dai = devm_kmemdup(&pdev->dev, &rockchip_i2s_dai,
674-
sizeof(*soc_dai), GFP_KERNEL);
675-
if (!soc_dai) {
676-
ret = -ENOMEM;
715+
ret = rockchip_i2s_init_dai(i2s, res, &dai);
716+
if (ret)
677717
goto err_pm_disable;
678-
}
679-
680-
if (!of_property_read_u32(node, "rockchip,playback-channels", &val)) {
681-
if (val >= 2 && val <= 8)
682-
soc_dai->playback.channels_max = val;
683-
}
684-
685-
if (!of_property_read_u32(node, "rockchip,capture-channels", &val)) {
686-
if (val >= 2 && val <= 8)
687-
soc_dai->capture.channels_max = val;
688-
}
689718

690719
ret = devm_snd_soc_register_component(&pdev->dev,
691720
&rockchip_i2s_component,
692-
soc_dai, 1);
721+
dai, 1);
693722

694723
if (ret) {
695724
dev_err(&pdev->dev, "Could not register DAI\n");

0 commit comments

Comments
 (0)