Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions arch/arm64/boot/dts/freescale/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mp-evk.dtb imx8mp-evk-rm67191.dtb imx8mp-evk-it626
imx8mp-evk-hifiberry-dac2.dtb imx8mp-evk-hifiberry-dacplusadc.dtb \
imx8mp-evk-usdhc1-m2.dtb imx8mp-evk-rm67199.dtb \
imx8mp-evk-dpdk.dtb imx8mp-evk-8mic-swpdm.dtb imx8mp-evk-revA3-8mic-revE.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-evk-sof-nocodec.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-navqp.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-ab2.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-navq.dtb imx8mp-navq-ov5640-ov5645.dtb imx8mp-navq-ov5647-ov5640.dtb
Expand Down
89 changes: 89 additions & 0 deletions arch/arm64/boot/dts/freescale/imx8mp-evk-sof-nocodec.dts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// SPDX-License-Identifier: GPL-2.0+
// Copyright NXP 2020

#include "imx8mp-evk.dts"

/delete-node/ &dsp_reserved_heap;
/delete-node/ &dsp_vdev0vring0;
/delete-node/ &dsp_vdev0vring1;
/delete-node/ &dsp_vdev0buffer;

/ {
compatible = "fsl,imx8mp-evk-nocodec", "fsl,imx8mp-evk", "fsl,imx8mp";

reserved-memory {
dsp_reserved: dsp@92400000 {
reg = <0 0x92400000 0 0x2000000>;
};
};

sound-wm8960 {
status = "disabled";
};

sound-micfil {
status = "disabled";
};

sof-nocodec {
compatible = "sof-audio-nocodec";
status = "okay";

sof,num-dai-drivers = <1>;
sof,dai-driver-names = "sai3";
sof,dai-playback-channels = <32>;
sof,dai-capture-channels = <32>;
};

};

&dsp {
compatible = "fsl,imx8mp-dsp";

pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai3>;

power-domains = <&audiomix_pd>;

clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_OCRAMA_IPG>,
<&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_DSP_ROOT>,
<&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_DSPDBG_ROOT>,
<&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_SAI3_IPG>,
<&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_SDMA3_ROOT>;

clock-names = "ipg", "ocram", "core",
"sai3_bus", "sdma3_root";

mbox-names = "txdb0", "txdb1", "rxdb0", "rxdb1";
mboxes = <&mu2 2 0>, <&mu2 2 1>,
<&mu2 3 0>, <&mu2 3 1>;
memory-region = <&dsp_reserved>;
/delete-property/ firmware-name;

tplg-name = "sof-imx8-nocodec.tplg";
machine-drv-name = "sof-nocodec";
status = "okay";

ports {
#address-cells = <1>;
#size-cells = <0>;

port@0 { reg = <0>; endpoint { /* not used */ }; };
};
};

&wm8960 {
status = "disabled";
};

&sai3 {
status = "disabled";
};

&sdma3 {
status = "disabled";
};

&easrc {
status = "disabled";
};
5 changes: 5 additions & 0 deletions sound/soc/sof/imx/imx8m.c
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,11 @@ static struct snd_sof_of_mach sof_imx8mp_machs[] = {
.sof_tplg_filename = "sof-imx8mp-wm8962.tplg",
.drv_name = "asoc-audio-graph-card2",
},
{
.compatible = "fsl,imx8mp-evk-nocodec",
.sof_tplg_filename = "sof-imx8-nocodec.tplg",
.drv_name = "sof-nocodec",
},
{
.compatible = "fsl,imx8mp-evk",
.sof_tplg_filename = "sof-imx8mp-wm8960.tplg",
Expand Down
103 changes: 97 additions & 6 deletions sound/soc/sof/nocodec.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,15 @@ static int sof_nocodec_bes_setup(struct device *dev,
links[i].id = i;
links[i].no_pcm = 1;
links[i].cpus->dai_name = drv[i].name;
links[i].platforms->name = dev_name(dev->parent);

if (!dev->of_node) {
links[i].platforms->name = dev_name(dev->parent);
links[i].platforms->of_node = NULL;
} else {
links[i].platforms->of_node = dev->of_node;
links[i].platforms->name = NULL;
}

if (drv[i].playback.channels_min)
links[i].dpcm_playback = 1;
if (drv[i].capture.channels_min)
Expand All @@ -75,6 +83,11 @@ static int sof_nocodec_setup(struct device *dev,
{
struct snd_soc_dai_link *links;

if (!dai_drivers) {
dev_err(dev, "ERROR: dai_drivers is NULL\n");
return -EINVAL;
}

/* create dummy BE dai_links */
links = devm_kcalloc(dev, num_dai_drivers, sizeof(struct snd_soc_dai_link), GFP_KERNEL);
if (!links)
Expand All @@ -83,29 +96,107 @@ static int sof_nocodec_setup(struct device *dev,
return sof_nocodec_bes_setup(dev, dai_drivers, links, num_dai_drivers, &sof_nocodec_card);
}

static int sof_nocodec_parse_dt_dai_info(struct device *dev,
u32 *num_dai_drivers,
struct snd_soc_dai_driver **dai_drivers)
{
struct device_node *np = dev->of_node;
const char *dai_name;
int playback_channels, capture_channels;
int ret, i;

ret = of_property_read_u32(np, "sof,num-dai-drivers", num_dai_drivers);
if (ret)
return ret;

*dai_drivers = devm_kcalloc(dev, *num_dai_drivers,
sizeof(struct snd_soc_dai_driver), GFP_KERNEL);
if (!*dai_drivers)
return -ENOMEM;

for (i = 0; i < *num_dai_drivers; i++) {

ret = of_property_read_string_index(np, "sof,dai-driver-names", i, &dai_name);
if (ret)
return ret;

ret = of_property_read_u32_index(np, "sof,dai-playback-channels", i, &playback_channels);
if (ret)
playback_channels = 0;

ret = of_property_read_u32_index(np, "sof,dai-capture-channels", i, &capture_channels);
if (ret)
capture_channels = 0;

(*dai_drivers)[i].name = devm_kstrdup(dev, dai_name, GFP_KERNEL);
if (!(*dai_drivers)[i].name)
return -ENOMEM;

(*dai_drivers)[i].id = i;

if (playback_channels > 0) {
(*dai_drivers)[i].playback.channels_min = 1;
(*dai_drivers)[i].playback.channels_max = 32;
}

if (capture_channels > 0) {
(*dai_drivers)[i].capture.channels_min = 1;
(*dai_drivers)[i].capture.channels_max = 32;
}

}

return 0;
}

static int sof_nocodec_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct snd_soc_card *card = &sof_nocodec_card;
struct snd_soc_acpi_mach *mach;
int ret;

card->dev = &pdev->dev;
card->dev = dev;
card->topology_shortname_created = true;
mach = pdev->dev.platform_data;

ret = sof_nocodec_setup(card->dev, mach->mach_params.num_dai_drivers,
mach->mach_params.dai_drivers);
if (dev->of_node) {
u32 num_dai_drivers = 0;
struct snd_soc_dai_driver *dai_drivers = NULL;

ret = sof_nocodec_parse_dt_dai_info(dev, &num_dai_drivers, &dai_drivers);

if (ret) {
dev_err(dev, "Failed to parse DT info: %d\n", ret);
return ret;
}

ret = sof_nocodec_setup(dev, num_dai_drivers, dai_drivers);
} else {
mach = dev->platform_data;

ret = sof_nocodec_setup(dev,
mach->mach_params.num_dai_drivers,
mach->mach_params.dai_drivers);
}

if (ret < 0)
return ret;

return devm_snd_soc_register_card(&pdev->dev, card);
return devm_snd_soc_register_card(dev, card);
}

static const struct of_device_id sof_nocodec_of_match[] = {
{ .compatible = "sof-audio-nocodec", },
{ },
};
MODULE_DEVICE_TABLE(of, sof_nocodec_of_match);

static struct platform_driver sof_nocodec_audio = {
.probe = sof_nocodec_probe,
.driver = {
.name = "sof-nocodec",
.pm = &snd_soc_pm_ops,
.of_match_table = sof_nocodec_of_match,
},
};
module_platform_driver(sof_nocodec_audio)
Expand Down