summaryrefslogtreecommitdiffstats
path: root/sound/soc/fsl
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r--sound/soc/fsl/fsl-asoc-card.c22
-rw-r--r--sound/soc/fsl/fsl_sai.c24
-rw-r--r--sound/soc/fsl/fsl_sai.h2
-rw-r--r--sound/soc/fsl/imx-audmix.c24
-rw-r--r--sound/soc/fsl/imx-card.c25
-rw-r--r--sound/soc/fsl/imx-rpmsg.c6
-rw-r--r--sound/soc/fsl/imx-spdif.c8
7 files changed, 67 insertions, 44 deletions
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 40870668ee24..76b5bfc288fd 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -27,6 +27,7 @@
#include "../codecs/wm8960.h"
#include "../codecs/wm8994.h"
#include "../codecs/tlv320aic31xx.h"
+#include "../codecs/nau8822.h"
#define DRIVER_NAME "fsl-asoc-card"
@@ -47,6 +48,7 @@
* @pll_id: PLL id for set_pll()
*/
struct codec_priv {
+ struct clk *mclk;
unsigned long mclk_freq;
unsigned long free_freq;
u32 mclk_id;
@@ -60,6 +62,7 @@ struct codec_priv {
* @sysclk_dir: SYSCLK directions for set_sysclk()
* @sysclk_id: SYSCLK ids for set_sysclk()
* @slot_width: Slot width of each frame
+ * @slot_num: Number of slots of each frame
*
* Note: [1] for tx and [0] for rx
*/
@@ -68,6 +71,7 @@ struct cpu_priv {
u32 sysclk_dir[2];
u32 sysclk_id[2];
u32 slot_width;
+ u32 slot_num;
};
/**
@@ -189,7 +193,11 @@ static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream,
}
if (cpu_priv->slot_width) {
- ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2,
+ if (!cpu_priv->slot_num)
+ cpu_priv->slot_num = 2;
+
+ ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3,
+ cpu_priv->slot_num,
cpu_priv->slot_width);
if (ret && ret != -ENOTSUPP) {
dev_err(dev, "failed to set TDM slot for cpu dai\n");
@@ -524,6 +532,9 @@ static int fsl_asoc_card_late_probe(struct snd_soc_card *card)
return ret;
}
+ if (!IS_ERR_OR_NULL(codec_priv->mclk))
+ clk_prepare_enable(codec_priv->mclk);
+
return 0;
}
@@ -686,6 +697,14 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
priv->codec_priv.free_freq = priv->codec_priv.mclk_freq;
priv->card.dapm_routes = NULL;
priv->card.num_dapm_routes = 0;
+ } else if (of_device_is_compatible(np, "fsl,imx-audio-nau8822")) {
+ codec_dai_name = "nau8822-hifi";
+ priv->codec_priv.mclk_id = NAU8822_CLK_MCLK;
+ priv->codec_priv.fll_id = NAU8822_CLK_PLL;
+ priv->codec_priv.pll_id = NAU8822_CLK_PLL;
+ priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM;
+ if (codec_dev)
+ priv->codec_priv.mclk = devm_clk_get(codec_dev, NULL);
} else {
dev_err(&pdev->dev, "unknown Device Tree compatible\n");
ret = -EINVAL;
@@ -911,6 +930,7 @@ static const struct of_device_id fsl_asoc_card_dt_ids[] = {
{ .compatible = "fsl,imx-audio-wm8524", },
{ .compatible = "fsl,imx-audio-si476x", },
{ .compatible = "fsl,imx-audio-wm8958", },
+ { .compatible = "fsl,imx-audio-nau8822", },
{}
};
MODULE_DEVICE_TABLE(of, fsl_asoc_card_dt_ids);
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index e3105d48fb65..5e09f634c61b 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -1407,7 +1407,9 @@ static int fsl_sai_probe(struct platform_device *pdev)
sai->cpu_dai_drv.symmetric_sample_bits = 0;
}
- if (of_property_read_bool(np, "fsl,sai-mclk-direction-output") &&
+ sai->mclk_direction_output = of_property_read_bool(np, "fsl,sai-mclk-direction-output");
+
+ if (sai->mclk_direction_output &&
of_device_is_compatible(np, "fsl,imx6ul-sai")) {
gpr = syscon_regmap_lookup_by_compatible("fsl,imx6ul-iomuxc-gpr");
if (IS_ERR(gpr)) {
@@ -1450,7 +1452,7 @@ static int fsl_sai_probe(struct platform_device *pdev)
dev_warn(dev, "Error reading SAI version: %d\n", ret);
/* Select MCLK direction */
- if (of_property_read_bool(np, "fsl,sai-mclk-direction-output") &&
+ if (sai->mclk_direction_output &&
sai->soc_data->max_register >= FSL_SAI_MCTL) {
regmap_update_bits(sai->regmap, FSL_SAI_MCTL,
FSL_SAI_MCTL_MCLK_EN, FSL_SAI_MCTL_MCLK_EN);
@@ -1569,6 +1571,17 @@ static const struct fsl_sai_soc_data fsl_sai_imx8mm_data = {
.max_register = FSL_SAI_MCTL,
};
+static const struct fsl_sai_soc_data fsl_sai_imx8mn_data = {
+ .use_imx_pcm = true,
+ .use_edma = false,
+ .fifo_depth = 128,
+ .reg_offset = 8,
+ .mclk0_is_mclk1 = false,
+ .pins = 8,
+ .flags = 0,
+ .max_register = FSL_SAI_MDIV,
+};
+
static const struct fsl_sai_soc_data fsl_sai_imx8mp_data = {
.use_imx_pcm = true,
.use_edma = false,
@@ -1578,6 +1591,7 @@ static const struct fsl_sai_soc_data fsl_sai_imx8mp_data = {
.pins = 8,
.flags = 0,
.max_register = FSL_SAI_MDIV,
+ .mclk_with_tere = true,
};
static const struct fsl_sai_soc_data fsl_sai_imx8ulp_data = {
@@ -1613,7 +1627,7 @@ static const struct of_device_id fsl_sai_ids[] = {
{ .compatible = "fsl,imx8mm-sai", .data = &fsl_sai_imx8mm_data },
{ .compatible = "fsl,imx8mp-sai", .data = &fsl_sai_imx8mp_data },
{ .compatible = "fsl,imx8ulp-sai", .data = &fsl_sai_imx8ulp_data },
- { .compatible = "fsl,imx8mn-sai", .data = &fsl_sai_imx8mp_data },
+ { .compatible = "fsl,imx8mn-sai", .data = &fsl_sai_imx8mn_data },
{ .compatible = "fsl,imx93-sai", .data = &fsl_sai_imx93_data },
{ /* sentinel */ }
};
@@ -1678,6 +1692,10 @@ static int fsl_sai_runtime_resume(struct device *dev)
if (ret)
goto disable_rx_clk;
+ if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output)
+ regmap_update_bits(sai->regmap, FSL_SAI_TCSR(ofs),
+ FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
+
return 0;
disable_rx_clk:
diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h
index a53c4f0e25fa..8254c3547b87 100644
--- a/sound/soc/fsl/fsl_sai.h
+++ b/sound/soc/fsl/fsl_sai.h
@@ -231,6 +231,7 @@ struct fsl_sai_soc_data {
bool use_imx_pcm;
bool use_edma;
bool mclk0_is_mclk1;
+ bool mclk_with_tere;
unsigned int fifo_depth;
unsigned int pins;
unsigned int reg_offset;
@@ -288,6 +289,7 @@ struct fsl_sai {
bool synchronous[2];
struct fsl_sai_dl_cfg *dl_cfg;
unsigned int dl_cfg_cnt;
+ bool mclk_direction_output;
unsigned int mclk_id[2];
unsigned int mclk_streams;
diff --git a/sound/soc/fsl/imx-audmix.c b/sound/soc/fsl/imx-audmix.c
index b2c5aca92c6b..0b58df56f4da 100644
--- a/sound/soc/fsl/imx-audmix.c
+++ b/sound/soc/fsl/imx-audmix.c
@@ -15,7 +15,6 @@
#include <linux/clk.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
-#include <linux/pm_runtime.h>
#include "fsl_sai.h"
#include "fsl_audmix.h"
@@ -207,8 +206,8 @@ static int imx_audmix_probe(struct platform_device *pdev)
for (i = 0; i < num_dai; i++) {
struct snd_soc_dai_link_component *dlc;
- /* for CPU/Codec x 2 */
- dlc = devm_kcalloc(&pdev->dev, 4, sizeof(*dlc), GFP_KERNEL);
+ /* for CPU x 2 */
+ dlc = devm_kcalloc(&pdev->dev, 2, sizeof(*dlc), GFP_KERNEL);
if (!dlc)
return -ENOMEM;
@@ -228,6 +227,8 @@ static int imx_audmix_probe(struct platform_device *pdev)
dai_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s%s",
fe_name_pref, args.np->full_name + 1);
+ if (!dai_name)
+ return -ENOMEM;
dev_info(pdev->dev.parent, "DAI FE name:%s\n", dai_name);
@@ -236,6 +237,8 @@ static int imx_audmix_probe(struct platform_device *pdev)
capture_dai_name =
devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s %s",
dai_name, "CPU-Capture");
+ if (!capture_dai_name)
+ return -ENOMEM;
}
/*
@@ -244,7 +247,7 @@ static int imx_audmix_probe(struct platform_device *pdev)
*/
priv->dai[i].cpus =
priv->dai[i].platforms = &dlc[0];
- priv->dai[i].codecs = &dlc[1];
+ priv->dai[i].codecs = &asoc_dummy_dlc;
priv->dai[i].num_cpus = 1;
priv->dai[i].num_codecs = 1;
@@ -252,8 +255,6 @@ static int imx_audmix_probe(struct platform_device *pdev)
priv->dai[i].name = dai_name;
priv->dai[i].stream_name = "HiFi-AUDMIX-FE";
- priv->dai[i].codecs->dai_name = "snd-soc-dummy-dai";
- priv->dai[i].codecs->name = "snd-soc-dummy";
priv->dai[i].cpus->of_node = args.np;
priv->dai[i].cpus->dai_name = dev_name(&cpu_pdev->dev);
priv->dai[i].dynamic = 1;
@@ -269,16 +270,16 @@ static int imx_audmix_probe(struct platform_device *pdev)
"AUDMIX-Playback-%d", i);
be_cp = devm_kasprintf(&pdev->dev, GFP_KERNEL,
"AUDMIX-Capture-%d", i);
+ if (!be_name || !be_pb || !be_cp)
+ return -ENOMEM;
- priv->dai[num_dai + i].cpus = &dlc[2];
- priv->dai[num_dai + i].codecs = &dlc[3];
+ priv->dai[num_dai + i].cpus = &dlc[1];
+ priv->dai[num_dai + i].codecs = &asoc_dummy_dlc;
priv->dai[num_dai + i].num_cpus = 1;
priv->dai[num_dai + i].num_codecs = 1;
priv->dai[num_dai + i].name = be_name;
- priv->dai[num_dai + i].codecs->dai_name = "snd-soc-dummy-dai";
- priv->dai[num_dai + i].codecs->name = "snd-soc-dummy";
priv->dai[num_dai + i].cpus->of_node = audmix_np;
priv->dai[num_dai + i].cpus->dai_name = be_name;
priv->dai[num_dai + i].no_pcm = 1;
@@ -293,6 +294,9 @@ static int imx_audmix_probe(struct platform_device *pdev)
priv->dapm_routes[i].source =
devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s %s",
dai_name, "CPU-Playback");
+ if (!priv->dapm_routes[i].source)
+ return -ENOMEM;
+
priv->dapm_routes[i].sink = be_pb;
priv->dapm_routes[num_dai + i].source = be_pb;
priv->dapm_routes[num_dai + i].sink = be_cp;
diff --git a/sound/soc/fsl/imx-card.c b/sound/soc/fsl/imx-card.c
index 64a4d7e9db60..356a0bc3b126 100644
--- a/sound/soc/fsl/imx-card.c
+++ b/sound/soc/fsl/imx-card.c
@@ -551,10 +551,10 @@ static int imx_card_parse_of(struct imx_card_data *data)
goto err;
}
- ret = of_parse_phandle_with_args(cpu, "sound-dai",
- "#sound-dai-cells", 0, &args);
+ ret = snd_soc_of_get_dlc(cpu, &args, link->cpus, 0);
if (ret) {
- dev_err(card->dev, "%s: error getting cpu phandle\n", link->name);
+ dev_err_probe(card->dev, ret,
+ "%s: error getting cpu dai info\n", link->name);
goto err;
}
@@ -582,17 +582,9 @@ static int imx_card_parse_of(struct imx_card_data *data)
}
}
- link->cpus->of_node = args.np;
link->platforms->of_node = link->cpus->of_node;
link->id = args.args[0];
- ret = snd_soc_of_get_dai_name(cpu, &link->cpus->dai_name);
- if (ret) {
- dev_err_probe(card->dev, ret,
- "%s: error getting cpu dai name\n", link->name);
- goto err;
- }
-
codec = of_get_child_by_name(np, "codec");
if (codec) {
ret = snd_soc_of_get_dai_link_codecs(dev, codec, link);
@@ -615,17 +607,8 @@ static int imx_card_parse_of(struct imx_card_data *data)
plat_data->type = CODEC_AK5552;
} else {
- dlc = devm_kzalloc(dev, sizeof(*dlc), GFP_KERNEL);
- if (!dlc) {
- ret = -ENOMEM;
- goto err;
- }
-
- link->codecs = dlc;
+ link->codecs = &asoc_dummy_dlc;
link->num_codecs = 1;
-
- link->codecs->dai_name = "snd-soc-dummy-dai";
- link->codecs->name = "snd-soc-dummy";
}
if (!strncmp(link->name, "HiFi-ASRC-FE", 12)) {
diff --git a/sound/soc/fsl/imx-rpmsg.c b/sound/soc/fsl/imx-rpmsg.c
index 89178106fe2c..3c7b95db2eac 100644
--- a/sound/soc/fsl/imx-rpmsg.c
+++ b/sound/soc/fsl/imx-rpmsg.c
@@ -92,13 +92,11 @@ static int imx_rpmsg_probe(struct platform_device *pdev)
/* Optional codec node */
ret = of_parse_phandle_with_fixed_args(np, "audio-codec", 0, 0, &args);
if (ret) {
- data->dai.codecs->dai_name = "snd-soc-dummy-dai";
- data->dai.codecs->name = "snd-soc-dummy";
+ *data->dai.codecs = asoc_dummy_dlc;
} else {
struct clk *clk;
- data->dai.codecs->of_node = args.np;
- ret = snd_soc_get_dai_name(&args, &data->dai.codecs->dai_name);
+ ret = snd_soc_get_dlc(&args, data->dai.codecs);
if (ret) {
dev_err(&pdev->dev, "Unable to get codec_dai_name\n");
goto fail;
diff --git a/sound/soc/fsl/imx-spdif.c b/sound/soc/fsl/imx-spdif.c
index ab978431ac98..44463f92e522 100644
--- a/sound/soc/fsl/imx-spdif.c
+++ b/sound/soc/fsl/imx-spdif.c
@@ -26,7 +26,7 @@ static int imx_spdif_audio_probe(struct platform_device *pdev)
}
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
- comp = devm_kzalloc(&pdev->dev, 2 * sizeof(*comp), GFP_KERNEL);
+ comp = devm_kzalloc(&pdev->dev, sizeof(*comp), GFP_KERNEL);
if (!data || !comp) {
ret = -ENOMEM;
goto end;
@@ -37,8 +37,8 @@ static int imx_spdif_audio_probe(struct platform_device *pdev)
* platform is using soc-generic-dmaengine-pcm
*/
data->dai.cpus =
- data->dai.platforms = &comp[0];
- data->dai.codecs = &comp[1];
+ data->dai.platforms = comp;
+ data->dai.codecs = &asoc_dummy_dlc;
data->dai.num_cpus = 1;
data->dai.num_codecs = 1;
@@ -46,8 +46,6 @@ static int imx_spdif_audio_probe(struct platform_device *pdev)
data->dai.name = "S/PDIF PCM";
data->dai.stream_name = "S/PDIF PCM";
- data->dai.codecs->dai_name = "snd-soc-dummy-dai";
- data->dai.codecs->name = "snd-soc-dummy";
data->dai.cpus->of_node = spdif_np;
data->dai.playback_only = true;
data->dai.capture_only = true;