summaryrefslogtreecommitdiff
path: root/sound/soc/fsl
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r--sound/soc/fsl/Kconfig9
-rw-r--r--sound/soc/fsl/Makefile2
-rw-r--r--sound/soc/fsl/eukrea-tlv320.c6
-rw-r--r--sound/soc/fsl/fsl-asoc-card.c9
-rw-r--r--sound/soc/fsl/fsl_asrc.c6
-rw-r--r--sound/soc/fsl/fsl_aud2htx.c6
-rw-r--r--sound/soc/fsl/fsl_audmix.c6
-rw-r--r--sound/soc/fsl/fsl_dma.c6
-rw-r--r--sound/soc/fsl/fsl_easrc.c6
-rw-r--r--sound/soc/fsl/fsl_esai.c6
-rw-r--r--sound/soc/fsl/fsl_mqs.c20
-rw-r--r--sound/soc/fsl/fsl_qmc_audio.c735
-rw-r--r--sound/soc/fsl/fsl_rpmsg.c6
-rw-r--r--sound/soc/fsl/fsl_sai.c18
-rw-r--r--sound/soc/fsl/fsl_spdif.c6
-rw-r--r--sound/soc/fsl/fsl_ssi.c8
-rw-r--r--sound/soc/fsl/fsl_xcvr.c5
-rw-r--r--sound/soc/fsl/imx-audmix.c22
-rw-r--r--sound/soc/fsl/imx-audmux.c6
-rw-r--r--sound/soc/fsl/imx-card.c2
-rw-r--r--sound/soc/fsl/imx-es8328.c11
-rw-r--r--sound/soc/fsl/imx-pcm-rpmsg.c6
-rw-r--r--sound/soc/fsl/imx-sgtl5000.c6
-rw-r--r--sound/soc/fsl/imx-spdif.c11
-rw-r--r--sound/soc/fsl/mpc5200_psc_ac97.c5
-rw-r--r--sound/soc/fsl/mpc5200_psc_i2s.c5
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c6
-rw-r--r--sound/soc/fsl/p1022_ds.c6
-rw-r--r--sound/soc/fsl/p1022_rdk.c6
-rw-r--r--sound/soc/fsl/pcm030-audio-fabric.c6
30 files changed, 834 insertions, 124 deletions
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 33b67db8794e..725c530a3636 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -172,6 +172,15 @@ config SND_MPC52xx_DMA
config SND_SOC_POWERPC_DMA
tristate
+config SND_SOC_POWERPC_QMC_AUDIO
+ tristate "QMC ALSA SoC support"
+ depends on CPM_QMC
+ help
+ ALSA SoC Audio support using the Freescale QUICC Multichannel
+ Controller (QMC).
+ Say Y or M if you want to add support for SoC audio using Freescale
+ QMC.
+
comment "SoC Audio support for Freescale PPC boards:"
config SND_SOC_MPC8610_HPCD
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index b54beb1a66fa..8db7e97d0bd5 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -28,6 +28,7 @@ snd-soc-fsl-easrc-objs := fsl_easrc.o
snd-soc-fsl-xcvr-objs := fsl_xcvr.o
snd-soc-fsl-aud2htx-objs := fsl_aud2htx.o
snd-soc-fsl-rpmsg-objs := fsl_rpmsg.o
+snd-soc-fsl-qmc-audio-objs := fsl_qmc_audio.o
obj-$(CONFIG_SND_SOC_FSL_AUDMIX) += snd-soc-fsl-audmix.o
obj-$(CONFIG_SND_SOC_FSL_ASOC_CARD) += snd-soc-fsl-asoc-card.o
@@ -44,6 +45,7 @@ obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o
obj-$(CONFIG_SND_SOC_FSL_XCVR) += snd-soc-fsl-xcvr.o
obj-$(CONFIG_SND_SOC_FSL_AUD2HTX) += snd-soc-fsl-aud2htx.o
obj-$(CONFIG_SND_SOC_FSL_RPMSG) += snd-soc-fsl-rpmsg.o
+obj-$(CONFIG_SND_SOC_POWERPC_QMC_AUDIO) += snd-soc-fsl-qmc-audio.o
# MPC5200 Platform Support
obj-$(CONFIG_SND_MPC52xx_DMA) += mpc5200_dma.o
diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c
index 9af4c4a35eb1..e65a85feba78 100644
--- a/sound/soc/fsl/eukrea-tlv320.c
+++ b/sound/soc/fsl/eukrea-tlv320.c
@@ -205,11 +205,9 @@ err:
return ret;
}
-static int eukrea_tlv320_remove(struct platform_device *pdev)
+static void eukrea_tlv320_remove(struct platform_device *pdev)
{
snd_soc_unregister_card(&eukrea_tlv320);
-
- return 0;
}
static const struct of_device_id imx_tlv320_dt_ids[] = {
@@ -224,7 +222,7 @@ static struct platform_driver eukrea_tlv320_driver = {
.of_match_table = imx_tlv320_dt_ids,
},
.probe = eukrea_tlv320_probe,
- .remove = eukrea_tlv320_remove,
+ .remove_new = eukrea_tlv320_remove,
};
module_platform_driver(eukrea_tlv320_driver);
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index cdfca9fd1eb0..40870668ee24 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -28,6 +28,8 @@
#include "../codecs/wm8994.h"
#include "../codecs/tlv320aic31xx.h"
+#define DRIVER_NAME "fsl-asoc-card"
+
#define CS427x_SYSCLK_MCLK 0
#define RX 0
@@ -607,6 +609,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
priv->card.dapm_routes = audio_map;
priv->card.num_dapm_routes = ARRAY_SIZE(audio_map);
+ priv->card.driver_name = DRIVER_NAME;
/* Diversify the card configurations */
if (of_device_is_compatible(np, "fsl,imx-audio-cs42888")) {
codec_dai_name = "cs42888";
@@ -855,7 +858,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
ret = devm_snd_soc_register_card(&pdev->dev, &priv->card);
if (ret) {
- dev_err_probe(&pdev->dev, ret, "snd_soc_register_card failed: %d\n", ret);
+ dev_err_probe(&pdev->dev, ret, "snd_soc_register_card failed\n");
goto asrc_fail;
}
@@ -915,7 +918,7 @@ MODULE_DEVICE_TABLE(of, fsl_asoc_card_dt_ids);
static struct platform_driver fsl_asoc_card_driver = {
.probe = fsl_asoc_card_probe,
.driver = {
- .name = "fsl-asoc-card",
+ .name = DRIVER_NAME,
.pm = &snd_soc_pm_ops,
.of_match_table = fsl_asoc_card_dt_ids,
},
@@ -924,5 +927,5 @@ module_platform_driver(fsl_asoc_card_driver);
MODULE_DESCRIPTION("Freescale Generic ASoC Sound Card driver with ASRC");
MODULE_AUTHOR("Nicolin Chen <nicoleotsuka@gmail.com>");
-MODULE_ALIAS("platform:fsl-asoc-card");
+MODULE_ALIAS("platform:" DRIVER_NAME);
MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index e16e7b3fa96c..adb8a59de2bd 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -1252,13 +1252,11 @@ err_pm_disable:
return ret;
}
-static int fsl_asrc_remove(struct platform_device *pdev)
+static void fsl_asrc_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
fsl_asrc_runtime_suspend(&pdev->dev);
-
- return 0;
}
static int fsl_asrc_runtime_resume(struct device *dev)
@@ -1394,7 +1392,7 @@ MODULE_DEVICE_TABLE(of, fsl_asrc_ids);
static struct platform_driver fsl_asrc_driver = {
.probe = fsl_asrc_probe,
- .remove = fsl_asrc_remove,
+ .remove_new = fsl_asrc_remove,
.driver = {
.name = "fsl-asrc",
.of_match_table = fsl_asrc_ids,
diff --git a/sound/soc/fsl/fsl_aud2htx.c b/sound/soc/fsl/fsl_aud2htx.c
index 1e421d9a03fb..46b0c5dcc4a5 100644
--- a/sound/soc/fsl/fsl_aud2htx.c
+++ b/sound/soc/fsl/fsl_aud2htx.c
@@ -257,11 +257,9 @@ static int fsl_aud2htx_probe(struct platform_device *pdev)
return ret;
}
-static int fsl_aud2htx_remove(struct platform_device *pdev)
+static void fsl_aud2htx_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static int __maybe_unused fsl_aud2htx_runtime_suspend(struct device *dev)
@@ -300,7 +298,7 @@ static const struct dev_pm_ops fsl_aud2htx_pm_ops = {
static struct platform_driver fsl_aud2htx_driver = {
.probe = fsl_aud2htx_probe,
- .remove = fsl_aud2htx_remove,
+ .remove_new = fsl_aud2htx_remove,
.driver = {
.name = "fsl-aud2htx",
.pm = &fsl_aud2htx_pm_ops,
diff --git a/sound/soc/fsl/fsl_audmix.c b/sound/soc/fsl/fsl_audmix.c
index 672148dd4b23..0ab2c1962117 100644
--- a/sound/soc/fsl/fsl_audmix.c
+++ b/sound/soc/fsl/fsl_audmix.c
@@ -506,7 +506,7 @@ err_disable_pm:
return ret;
}
-static int fsl_audmix_remove(struct platform_device *pdev)
+static void fsl_audmix_remove(struct platform_device *pdev)
{
struct fsl_audmix *priv = dev_get_drvdata(&pdev->dev);
@@ -514,8 +514,6 @@ static int fsl_audmix_remove(struct platform_device *pdev)
if (priv->pdev)
platform_device_unregister(priv->pdev);
-
- return 0;
}
#ifdef CONFIG_PM
@@ -558,7 +556,7 @@ static const struct dev_pm_ops fsl_audmix_pm = {
static struct platform_driver fsl_audmix_driver = {
.probe = fsl_audmix_probe,
- .remove = fsl_audmix_remove,
+ .remove_new = fsl_audmix_remove,
.driver = {
.name = "fsl-audmix",
.of_match_table = fsl_audmix_ids,
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index 808fb61a7a0f..963f9774c883 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -890,15 +890,13 @@ static int fsl_soc_dma_probe(struct platform_device *pdev)
return 0;
}
-static int fsl_soc_dma_remove(struct platform_device *pdev)
+static void fsl_soc_dma_remove(struct platform_device *pdev)
{
struct dma_object *dma = dev_get_drvdata(&pdev->dev);
iounmap(dma->channel);
irq_dispose_mapping(dma->irq);
kfree(dma);
-
- return 0;
}
static const struct of_device_id fsl_soc_dma_ids[] = {
@@ -913,7 +911,7 @@ static struct platform_driver fsl_soc_dma_driver = {
.of_match_table = fsl_soc_dma_ids,
},
.probe = fsl_soc_dma_probe,
- .remove = fsl_soc_dma_remove,
+ .remove_new = fsl_soc_dma_remove,
};
module_platform_driver(fsl_soc_dma_driver);
diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c
index 3153d19136b2..670cbdb361b6 100644
--- a/sound/soc/fsl/fsl_easrc.c
+++ b/sound/soc/fsl/fsl_easrc.c
@@ -1979,11 +1979,9 @@ static int fsl_easrc_probe(struct platform_device *pdev)
return 0;
}
-static int fsl_easrc_remove(struct platform_device *pdev)
+static void fsl_easrc_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
static __maybe_unused int fsl_easrc_runtime_suspend(struct device *dev)
@@ -2093,7 +2091,7 @@ static const struct dev_pm_ops fsl_easrc_pm_ops = {
static struct platform_driver fsl_easrc_driver = {
.probe = fsl_easrc_probe,
- .remove = fsl_easrc_remove,
+ .remove_new = fsl_easrc_remove,
.driver = {
.name = "fsl-easrc",
.pm = &fsl_easrc_pm_ops,
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index 17fefd27ec90..936f0cd4b06d 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -1101,7 +1101,7 @@ err_pm_disable:
return ret;
}
-static int fsl_esai_remove(struct platform_device *pdev)
+static void fsl_esai_remove(struct platform_device *pdev)
{
struct fsl_esai *esai_priv = platform_get_drvdata(pdev);
@@ -1110,8 +1110,6 @@ static int fsl_esai_remove(struct platform_device *pdev)
fsl_esai_runtime_suspend(&pdev->dev);
cancel_work_sync(&esai_priv->work);
-
- return 0;
}
static const struct of_device_id fsl_esai_dt_ids[] = {
@@ -1200,7 +1198,7 @@ static const struct dev_pm_ops fsl_esai_pm_ops = {
static struct platform_driver fsl_esai_driver = {
.probe = fsl_esai_probe,
- .remove = fsl_esai_remove,
+ .remove_new = fsl_esai_remove,
.driver = {
.name = "fsl-esai-dai",
.pm = &fsl_esai_pm_ops,
diff --git a/sound/soc/fsl/fsl_mqs.c b/sound/soc/fsl/fsl_mqs.c
index 4922e6795b73..49ae7f6267d3 100644
--- a/sound/soc/fsl/fsl_mqs.c
+++ b/sound/soc/fsl/fsl_mqs.c
@@ -210,10 +210,10 @@ static int fsl_mqs_probe(struct platform_device *pdev)
}
mqs_priv->regmap = syscon_node_to_regmap(gpr_np);
+ of_node_put(gpr_np);
if (IS_ERR(mqs_priv->regmap)) {
dev_err(&pdev->dev, "failed to get gpr regmap\n");
- ret = PTR_ERR(mqs_priv->regmap);
- goto err_free_gpr_np;
+ return PTR_ERR(mqs_priv->regmap);
}
} else {
regs = devm_platform_ioremap_resource(pdev, 0);
@@ -242,8 +242,7 @@ static int fsl_mqs_probe(struct platform_device *pdev)
if (IS_ERR(mqs_priv->mclk)) {
dev_err(&pdev->dev, "failed to get the clock: %ld\n",
PTR_ERR(mqs_priv->mclk));
- ret = PTR_ERR(mqs_priv->mclk);
- goto err_free_gpr_np;
+ return PTR_ERR(mqs_priv->mclk);
}
dev_set_drvdata(&pdev->dev, mqs_priv);
@@ -252,19 +251,14 @@ static int fsl_mqs_probe(struct platform_device *pdev)
ret = devm_snd_soc_register_component(&pdev->dev, &soc_codec_fsl_mqs,
&fsl_mqs_dai, 1);
if (ret)
- goto err_free_gpr_np;
- return 0;
-
-err_free_gpr_np:
- of_node_put(gpr_np);
+ return ret;
- return ret;
+ return 0;
}
-static int fsl_mqs_remove(struct platform_device *pdev)
+static void fsl_mqs_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
- return 0;
}
#ifdef CONFIG_PM
@@ -360,7 +354,7 @@ MODULE_DEVICE_TABLE(of, fsl_mqs_dt_ids);
static struct platform_driver fsl_mqs_driver = {
.probe = fsl_mqs_probe,
- .remove = fsl_mqs_remove,
+ .remove_new = fsl_mqs_remove,
.driver = {
.name = "fsl-mqs",
.of_match_table = fsl_mqs_dt_ids,
diff --git a/sound/soc/fsl/fsl_qmc_audio.c b/sound/soc/fsl/fsl_qmc_audio.c
new file mode 100644
index 000000000000..7cbb8e4758cc
--- /dev/null
+++ b/sound/soc/fsl/fsl_qmc_audio.c
@@ -0,0 +1,735 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ALSA SoC using the QUICC Multichannel Controller (QMC)
+ *
+ * Copyright 2022 CS GROUP France
+ *
+ * Author: Herve Codina <herve.codina@bootlin.com>
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <soc/fsl/qe/qmc.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+struct qmc_dai {
+ char *name;
+ int id;
+ struct device *dev;
+ struct qmc_chan *qmc_chan;
+ unsigned int nb_tx_ts;
+ unsigned int nb_rx_ts;
+};
+
+struct qmc_audio {
+ struct device *dev;
+ unsigned int num_dais;
+ struct qmc_dai *dais;
+ struct snd_soc_dai_driver *dai_drivers;
+};
+
+struct qmc_dai_prtd {
+ struct qmc_dai *qmc_dai;
+ dma_addr_t dma_buffer_start;
+ dma_addr_t period_ptr_submitted;
+ dma_addr_t period_ptr_ended;
+ dma_addr_t dma_buffer_end;
+ size_t period_size;
+ struct snd_pcm_substream *substream;
+};
+
+static int qmc_audio_pcm_construct(struct snd_soc_component *component,
+ struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_card *card = rtd->card->snd_card;
+ int ret;
+
+ ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
+ if (ret)
+ return ret;
+
+ snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, card->dev,
+ 64*1024, 64*1024);
+ return 0;
+}
+
+static int qmc_audio_pcm_hw_params(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct qmc_dai_prtd *prtd = substream->runtime->private_data;
+
+ prtd->dma_buffer_start = runtime->dma_addr;
+ prtd->dma_buffer_end = runtime->dma_addr + params_buffer_bytes(params);
+ prtd->period_size = params_period_bytes(params);
+ prtd->period_ptr_submitted = prtd->dma_buffer_start;
+ prtd->period_ptr_ended = prtd->dma_buffer_start;
+ prtd->substream = substream;
+
+ return 0;
+}
+
+static void qmc_audio_pcm_write_complete(void *context)
+{
+ struct qmc_dai_prtd *prtd = context;
+ int ret;
+
+ prtd->period_ptr_ended += prtd->period_size;
+ if (prtd->period_ptr_ended >= prtd->dma_buffer_end)
+ prtd->period_ptr_ended = prtd->dma_buffer_start;
+
+ prtd->period_ptr_submitted += prtd->period_size;
+ if (prtd->period_ptr_submitted >= prtd->dma_buffer_end)
+ prtd->period_ptr_submitted = prtd->dma_buffer_start;
+
+ ret = qmc_chan_write_submit(prtd->qmc_dai->qmc_chan,
+ prtd->period_ptr_submitted, prtd->period_size,
+ qmc_audio_pcm_write_complete, prtd);
+ if (ret) {
+ dev_err(prtd->qmc_dai->dev, "write_submit failed %d\n",
+ ret);
+ }
+
+ snd_pcm_period_elapsed(prtd->substream);
+}
+
+static void qmc_audio_pcm_read_complete(void *context, size_t length)
+{
+ struct qmc_dai_prtd *prtd = context;
+ int ret;
+
+ if (length != prtd->period_size) {
+ dev_err(prtd->qmc_dai->dev, "read complete length = %zu, exp %zu\n",
+ length, prtd->period_size);
+ }
+
+ prtd->period_ptr_ended += prtd->period_size;
+ if (prtd->period_ptr_ended >= prtd->dma_buffer_end)
+ prtd->period_ptr_ended = prtd->dma_buffer_start;
+
+ prtd->period_ptr_submitted += prtd->period_size;
+ if (prtd->period_ptr_submitted >= prtd->dma_buffer_end)
+ prtd->period_ptr_submitted = prtd->dma_buffer_start;
+
+ ret = qmc_chan_read_submit(prtd->qmc_dai->qmc_chan,
+ prtd->period_ptr_submitted, prtd->period_size,
+ qmc_audio_pcm_read_complete, prtd);
+ if (ret) {
+ dev_err(prtd->qmc_dai->dev, "read_submit failed %d\n",
+ ret);
+ }
+
+ snd_pcm_period_elapsed(prtd->substream);
+}
+
+static int qmc_audio_pcm_trigger(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream, int cmd)
+{
+ struct qmc_dai_prtd *prtd = substream->runtime->private_data;
+ int ret;
+
+ if (!prtd->qmc_dai) {
+ dev_err(component->dev, "qmc_dai is not set\n");
+ return -EINVAL;
+ }
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ /* Submit first chunk ... */
+ ret = qmc_chan_write_submit(prtd->qmc_dai->qmc_chan,
+ prtd->period_ptr_submitted, prtd->period_size,
+ qmc_audio_pcm_write_complete, prtd);
+ if (ret) {
+ dev_err(component->dev, "write_submit failed %d\n",
+ ret);
+ return ret;
+ }
+
+ /* ... prepare next one ... */
+ prtd->period_ptr_submitted += prtd->period_size;
+ if (prtd->period_ptr_submitted >= prtd->dma_buffer_end)
+ prtd->period_ptr_submitted = prtd->dma_buffer_start;
+
+ /* ... and send it */
+ ret = qmc_chan_write_submit(prtd->qmc_dai->qmc_chan,
+ prtd->period_ptr_submitted, prtd->period_size,
+ qmc_audio_pcm_write_complete, prtd);
+ if (ret) {
+ dev_err(component->dev, "write_submit failed %d\n",
+ ret);
+ return ret;
+ }
+ } else {
+ /* Submit first chunk ... */
+ ret = qmc_chan_read_submit(prtd->qmc_dai->qmc_chan,
+ prtd->period_ptr_submitted, prtd->period_size,
+ qmc_audio_pcm_read_complete, prtd);
+ if (ret) {
+ dev_err(component->dev, "read_submit failed %d\n",
+ ret);
+ return ret;
+ }
+
+ /* ... prepare next one ... */
+ prtd->period_ptr_submitted += prtd->period_size;
+ if (prtd->period_ptr_submitted >= prtd->dma_buffer_end)
+ prtd->period_ptr_submitted = prtd->dma_buffer_start;
+
+ /* ... and send it */
+ ret = qmc_chan_read_submit(prtd->qmc_dai->qmc_chan,
+ prtd->period_ptr_submitted, prtd->period_size,
+ qmc_audio_pcm_read_complete, prtd);
+ if (ret) {
+ dev_err(component->dev, "write_submit failed %d\n",
+ ret);
+ return ret;
+ }
+ }
+ break;
+
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ break;
+
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static snd_pcm_uframes_t qmc_audio_pcm_pointer(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct qmc_dai_prtd *prtd = substream->runtime->private_data;
+
+ return bytes_to_frames(substream->runtime,
+ prtd->period_ptr_ended - prtd->dma_buffer_start);
+}
+
+static int qmc_audio_of_xlate_dai_name(struct snd_soc_component *component,
+ const struct of_phandle_args *args,
+ const char **dai_name)
+{
+ struct qmc_audio *qmc_audio = dev_get_drvdata(component->dev);
+ struct snd_soc_dai_driver *dai_driver;
+ int id = args->args[0];
+ int i;
+
+ for (i = 0; i < qmc_audio->num_dais; i++) {
+ dai_driver = qmc_audio->dai_drivers + i;
+ if (dai_driver->id == id) {
+ *dai_name = dai_driver->name;
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static const struct snd_pcm_hardware qmc_audio_pcm_hardware = {
+ .info = SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_PAUSE,
+ .period_bytes_min = 32,
+ .period_bytes_max = 64*1024,
+ .periods_min = 2,
+ .periods_max = 2*1024,
+ .buffer_bytes_max = 64*1024,
+};
+
+static int qmc_audio_pcm_open(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct qmc_dai_prtd *prtd;
+ int ret;
+
+ snd_soc_set_runtime_hwparams(substream, &qmc_audio_pcm_hardware);
+
+ /* ensure that buffer size is a multiple of period size */
+ ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+ if (ret < 0)
+ return ret;
+
+ prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
+ if (prtd == NULL)
+ return -ENOMEM;
+
+ runtime->private_data = prtd;
+
+ return 0;
+}
+
+static int qmc_audio_pcm_close(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct qmc_dai_prtd *prtd = substream->runtime->private_data;
+
+ kfree(prtd);
+ return 0;
+}
+
+static const struct snd_soc_component_driver qmc_audio_soc_platform = {
+ .open = qmc_audio_pcm_open,
+ .close = qmc_audio_pcm_close,
+ .hw_params = qmc_audio_pcm_hw_params,
+ .trigger = qmc_audio_pcm_trigger,
+ .pointer = qmc_audio_pcm_pointer,
+ .pcm_construct = qmc_audio_pcm_construct,
+ .of_xlate_dai_name = qmc_audio_of_xlate_dai_name,
+};
+
+static unsigned int qmc_dai_get_index(struct snd_soc_dai *dai)
+{
+ struct qmc_audio *qmc_audio = snd_soc_dai_get_drvdata(dai);
+
+ return dai->driver - qmc_audio->dai_drivers;
+}
+
+static struct qmc_dai *qmc_dai_get_data(struct snd_soc_dai *dai)
+{
+ struct qmc_audio *qmc_audio = snd_soc_dai_get_drvdata(dai);
+ unsigned int index;
+
+ index = qmc_dai_get_index(dai);
+ if (index > qmc_audio->num_dais)
+ return NULL;
+
+ return qmc_audio->dais + index;
+}
+
+/*
+ * The constraints for format/channel is to match with the number of 8bit
+ * time-slots available.
+ */
+static int qmc_dai_hw_rule_channels_by_format(struct qmc_dai *qmc_dai,
+ struct snd_pcm_hw_params *params,
+ unsigned int nb_ts)
+{
+ struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+ snd_pcm_format_t format = params_format(params);
+ struct snd_interval ch = {0};
+
+ switch (snd_pcm_format_physical_width(format)) {
+ case 8:
+ ch.max = nb_ts;
+ break;
+ case 16:
+ ch.max = nb_ts/2;
+ break;
+ case 32:
+ ch.max = nb_ts/4;
+ break;
+ case 64:
+ ch.max = nb_ts/8;
+ break;
+ default:
+ dev_err(qmc_dai->dev, "format physical width %u not supported\n",
+ snd_pcm_format_physical_width(format));
+ return -EINVAL;
+ }
+
+ ch.min = ch.max ? 1 : 0;
+
+ return snd_interval_refine(c, &ch);
+}
+
+static int qmc_dai_hw_rule_playback_channels_by_format(struct snd_pcm_hw_params *params,
+ struct snd_pcm_hw_rule *rule)
+{
+ struct qmc_dai *qmc_dai = rule->private;
+
+ return qmc_dai_hw_rule_channels_by_format(qmc_dai, params, qmc_dai->nb_tx_ts);
+}
+
+static int qmc_dai_hw_rule_capture_channels_by_format(
+ struct snd_pcm_hw_params *params,
+ struct snd_pcm_hw_rule *rule)
+{
+ struct qmc_dai *qmc_dai = rule->private;
+
+ return qmc_dai_hw_rule_channels_by_format(qmc_dai, params, qmc_dai->nb_rx_ts);
+}
+
+static int qmc_dai_hw_rule_format_by_channels(struct qmc_dai *qmc_dai,
+ struct snd_pcm_hw_params *params,
+ unsigned int nb_ts)
+{
+ struct snd_mask *f_old = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+ unsigned int channels = params_channels(params);
+ unsigned int slot_width;
+ struct snd_mask f_new;
+ unsigned int i;
+
+ if (!channels || channels > nb_ts) {
+ dev_err(qmc_dai->dev, "channels %u not supported\n",
+ nb_ts);
+ return -EINVAL;
+ }
+
+ slot_width = (nb_ts / channels) * 8;
+
+ snd_mask_none(&f_new);
+ for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
+ if (snd_mask_test(f_old, i)) {
+ if (snd_pcm_format_physical_width(i) <= slot_width)
+ snd_mask_set(&f_new, i);
+ }
+ }
+
+ return snd_mask_refine(f_old, &f_new);
+}
+
+static int qmc_dai_hw_rule_playback_format_by_channels(
+ struct snd_pcm_hw_params *params,
+ struct snd_pcm_hw_rule *rule)
+{
+ struct qmc_dai *qmc_dai = rule->private;
+
+ return qmc_dai_hw_rule_format_by_channels(qmc_dai, params, qmc_dai->nb_tx_ts);
+}
+
+static int qmc_dai_hw_rule_capture_format_by_channels(
+ struct snd_pcm_hw_params *params,
+ struct snd_pcm_hw_rule *rule)
+{
+ struct qmc_dai *qmc_dai = rule->private;
+
+ return qmc_dai_hw_rule_format_by_channels(qmc_dai, params, qmc_dai->nb_rx_ts);
+}
+
+static int qmc_dai_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct qmc_dai_prtd *prtd = substream->runtime->private_data;
+ snd_pcm_hw_rule_func_t hw_rule_channels_by_format;
+ snd_pcm_hw_rule_func_t hw_rule_format_by_channels;
+ struct qmc_dai *qmc_dai;
+ unsigned int frame_bits;
+ int ret;
+
+ qmc_dai = qmc_dai_get_data(dai);
+ if (!qmc_dai) {
+ dev_err(dai->dev, "Invalid dai\n");
+ return -EINVAL;
+ }
+
+ prtd->qmc_dai = qmc_dai;
+
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ hw_rule_channels_by_format = qmc_dai_hw_rule_capture_channels_by_format;
+ hw_rule_format_by_channels = qmc_dai_hw_rule_capture_format_by_channels;
+ frame_bits = qmc_dai->nb_rx_ts * 8;
+ } else {
+ hw_rule_channels_by_format = qmc_dai_hw_rule_playback_channels_by_format;
+ hw_rule_format_by_channels = qmc_dai_hw_rule_playback_format_by_channels;
+ frame_bits = qmc_dai->nb_tx_ts * 8;
+ }
+
+ ret = snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+ hw_rule_channels_by_format, qmc_dai,
+ SNDRV_PCM_HW_PARAM_FORMAT, -1);
+ if (ret) {
+ dev_err(dai->dev, "Failed to add channels rule (%d)\n", ret);
+ return ret;
+ }
+
+ ret = snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
+ hw_rule_format_by_channels, qmc_dai,
+ SNDRV_PCM_HW_PARAM_CHANNELS, -1);
+ if (ret) {
+ dev_err(dai->dev, "Failed to add format rule (%d)\n", ret);
+ return ret;
+ }
+
+ ret = snd_pcm_hw_constraint_single(substream->runtime,
+ SNDRV_PCM_HW_PARAM_FRAME_BITS,
+ frame_bits);
+ if (ret < 0) {
+ dev_err(dai->dev, "Failed to add frame_bits constraint (%d)\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int qmc_dai_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct qmc_chan_param chan_param = {0};
+ struct qmc_dai *qmc_dai;
+ int ret;
+
+ qmc_dai = qmc_dai_get_data(dai);
+ if (!qmc_dai) {
+ dev_err(dai->dev, "Invalid dai\n");
+ return -EINVAL;
+ }
+
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ chan_param.mode = QMC_TRANSPARENT;
+ chan_param.transp.max_rx_buf_size = params_period_bytes(params);
+ ret = qmc_chan_set_param(qmc_dai->qmc_chan, &chan_param);
+ if (ret) {
+ dev_err(dai->dev, "set param failed %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int qmc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+{
+ struct qmc_dai *qmc_dai;
+ int direction;
+ int ret;
+
+ qmc_dai = qmc_dai_get_data(dai);
+ if (!qmc_dai) {
+ dev_err(dai->dev, "Invalid dai\n");
+ return -EINVAL;
+ }
+
+ direction = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+ QMC_CHAN_WRITE : QMC_CHAN_READ;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ ret = qmc_chan_start(qmc_dai->qmc_chan, direction);
+ if (ret)
+ return ret;
+ break;
+
+ case SNDRV_PCM_TRIGGER_STOP:
+ ret = qmc_chan_stop(qmc_dai->qmc_chan, direction);
+ if (ret)
+ return ret;
+ ret = qmc_chan_reset(qmc_dai->qmc_chan, direction);
+ if (ret)
+ return ret;
+ break;
+
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ ret = qmc_chan_stop(qmc_dai->qmc_chan, direction);
+ if (ret)
+ return ret;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static const struct snd_soc_dai_ops qmc_dai_ops = {
+ .startup = qmc_dai_startup,
+ .trigger = qmc_dai_trigger,
+ .hw_params = qmc_dai_hw_params,
+};
+
+static u64 qmc_audio_formats(u8 nb_ts)
+{
+ u64 formats;
+ unsigned int chan_width;
+ unsigned int format_width;
+ int i;
+
+ if (!nb_ts)
+ return 0;
+
+ formats = 0;
+ chan_width = nb_ts * 8;
+ for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
+ /*
+ * Support format other than little-endian (ie big-endian or
+ * without endianness such as 8bit formats)
+ */
+ if (snd_pcm_format_little_endian(i) == 1)
+ continue;
+
+ /* Support physical width multiple of 8bit */
+ format_width = snd_pcm_format_physical_width(i);
+ if (format_width == 0 || format_width % 8)
+ continue;
+
+ /*
+ * And support physical width that can fit N times in the
+ * channel
+ */
+ if (format_width > chan_width || chan_width % format_width)
+ continue;
+
+ formats |= (1ULL << i);
+ }
+ return formats;
+}
+
+static int qmc_audio_dai_parse(struct qmc_audio *qmc_audio, struct device_node *np,
+ struct qmc_dai *qmc_dai, struct snd_soc_dai_driver *qmc_soc_dai_driver)
+{
+ struct qmc_chan_info info;
+ u32 val;
+ int ret;
+
+ qmc_dai->dev = qmc_audio->dev;
+
+ ret = of_property_read_u32(np, "reg", &val);
+ if (ret) {
+ dev_err(qmc_audio->dev, "%pOF: failed to read reg\n", np);
+ return ret;
+ }
+ qmc_dai->id = val;
+
+ qmc_dai->name = devm_kasprintf(qmc_audio->dev, GFP_KERNEL, "%s.%d",
+ np->parent->name, qmc_dai->id);
+
+ qmc_dai->qmc_chan = devm_qmc_chan_get_byphandle(qmc_audio->dev, np,
+ "fsl,qmc-chan");
+ if (IS_ERR(qmc_dai->qmc_chan)) {
+ ret = PTR_ERR(qmc_dai->qmc_chan);
+ return dev_err_probe(qmc_audio->dev, ret,
+ "dai %d get QMC channel failed\n", qmc_dai->id);
+ }
+
+ qmc_soc_dai_driver->id = qmc_dai->id;
+ qmc_soc_dai_driver->name = qmc_dai->name;
+
+ ret = qmc_chan_get_info(qmc_dai->qmc_chan, &info);
+ if (ret) {
+ dev_err(qmc_audio->dev, "dai %d get QMC channel info failed %d\n",
+ qmc_dai->id, ret);
+ return ret;
+ }
+ dev_info(qmc_audio->dev, "dai %d QMC channel mode %d, nb_tx_ts %u, nb_rx_ts %u\n",
+ qmc_dai->id, info.mode, info.nb_tx_ts, info.nb_rx_ts);
+
+ if (info.mode != QMC_TRANSPARENT) {
+ dev_err(qmc_audio->dev, "dai %d QMC chan mode %d is not QMC_TRANSPARENT\n",
+ qmc_dai->id, info.mode);
+ return -EINVAL;
+ }
+ qmc_dai->nb_tx_ts = info.nb_tx_ts;
+ qmc_dai->nb_rx_ts = info.nb_rx_ts;
+
+ qmc_soc_dai_driver->playback.channels_min = 0;
+ qmc_soc_dai_driver->playback.channels_max = 0;
+ if (qmc_dai->nb_tx_ts) {
+ qmc_soc_dai_driver->playback.channels_min = 1;
+ qmc_soc_dai_driver->playback.channels_max = qmc_dai->nb_tx_ts;
+ }
+ qmc_soc_dai_driver->playback.formats = qmc_audio_formats(qmc_dai->nb_tx_ts);
+
+ qmc_soc_dai_driver->capture.channels_min = 0;
+ qmc_soc_dai_driver->capture.channels_max = 0;
+ if (qmc_dai->nb_rx_ts) {
+ qmc_soc_dai_driver->capture.channels_min = 1;
+ qmc_soc_dai_driver->capture.channels_max = qmc_dai->nb_rx_ts;
+ }
+ qmc_soc_dai_driver->capture.formats = qmc_audio_formats(qmc_dai->nb_rx_ts);
+
+ qmc_soc_dai_driver->playback.rates = snd_pcm_rate_to_rate_bit(info.tx_fs_rate);
+ qmc_soc_dai_driver->playback.rate_min = info.tx_fs_rate;
+ qmc_soc_dai_driver->playback.rate_max = info.tx_fs_rate;
+ qmc_soc_dai_driver->capture.rates = snd_pcm_rate_to_rate_bit(info.rx_fs_rate);
+ qmc_soc_dai_driver->capture.rate_min = info.rx_fs_rate;
+ qmc_soc_dai_driver->capture.rate_max = info.rx_fs_rate;
+
+ qmc_soc_dai_driver->ops = &qmc_dai_ops;
+
+ return 0;
+}
+
+static int qmc_audio_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct qmc_audio *qmc_audio;
+ struct device_node *child;
+ unsigned int i;
+ int ret;
+
+ qmc_audio = devm_kzalloc(&pdev->dev, sizeof(*qmc_audio), GFP_KERNEL);
+ if (!qmc_audio)
+ return -ENOMEM;
+
+ qmc_audio->dev = &pdev->dev;
+
+ qmc_audio->num_dais = of_get_available_child_count(np);
+ if (qmc_audio->num_dais) {
+ qmc_audio->dais = devm_kcalloc(&pdev->dev, qmc_audio->num_dais,
+ sizeof(*qmc_audio->dais),
+ GFP_KERNEL);
+ if (!qmc_audio->dais)
+ return -ENOMEM;
+
+ qmc_audio->dai_drivers = devm_kcalloc(&pdev->dev, qmc_audio->num_dais,
+ sizeof(*qmc_audio->dai_drivers),
+ GFP_KERNEL);
+ if (!qmc_audio->dai_drivers)
+ return -ENOMEM;
+ }
+
+ i = 0;
+ for_each_available_child_of_node(np, child) {
+ ret = qmc_audio_dai_parse(qmc_audio, child,
+ qmc_audio->dais + i,
+ qmc_audio->dai_drivers + i);
+ if (ret) {
+ of_node_put(child);
+ return ret;
+ }
+ i++;
+ }
+
+
+ platform_set_drvdata(pdev, qmc_audio);
+
+ ret = devm_snd_soc_register_component(qmc_audio->dev,
+ &qmc_audio_soc_platform,
+ qmc_audio->dai_drivers,
+ qmc_audio->num_dais);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static const struct of_device_id qmc_audio_id_table[] = {
+ { .compatible = "fsl,qmc-audio" },
+ {} /* sentinel */
+};
+MODULE_DEVICE_TABLE(of, qmc_audio_id_table);
+
+static struct platform_driver qmc_audio_driver = {
+ .driver = {
+ .name = "fsl-qmc-audio",
+ .of_match_table = of_match_ptr(qmc_audio_id_table),
+ },
+ .probe = qmc_audio_probe,
+};
+module_platform_driver(qmc_audio_driver);
+
+MODULE_AUTHOR("Herve Codina <herve.codina@bootlin.com>");
+MODULE_DESCRIPTION("CPM/QE QMC audio driver");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/fsl_rpmsg.c b/sound/soc/fsl/fsl_rpmsg.c
index 46c7868a2653..15b48b5ea856 100644
--- a/sound/soc/fsl/fsl_rpmsg.c
+++ b/sound/soc/fsl/fsl_rpmsg.c
@@ -247,14 +247,12 @@ static int fsl_rpmsg_probe(struct platform_device *pdev)
return 0;
}
-static int fsl_rpmsg_remove(struct platform_device *pdev)
+static void fsl_rpmsg_remove(struct platform_device *pdev)
{
struct fsl_rpmsg *rpmsg = platform_get_drvdata(pdev);
if (rpmsg->card_pdev)
platform_device_unregister(rpmsg->card_pdev);
-
- return 0;
}
#ifdef CONFIG_PM
@@ -302,7 +300,7 @@ static const struct dev_pm_ops fsl_rpmsg_pm_ops = {
static struct platform_driver fsl_rpmsg_driver = {
.probe = fsl_rpmsg_probe,
- .remove = fsl_rpmsg_remove,
+ .remove_new = fsl_rpmsg_remove,
.driver = {
.name = "fsl_rpmsg",
.pm = &fsl_rpmsg_pm_ops,
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 1b197478b3d9..07d13dca852e 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -1380,18 +1380,18 @@ static int fsl_sai_probe(struct platform_device *pdev)
sai->cpu_dai_drv.symmetric_channels = 1;
sai->cpu_dai_drv.symmetric_sample_bits = 1;
- if (of_find_property(np, "fsl,sai-synchronous-rx", NULL) &&
- of_find_property(np, "fsl,sai-asynchronous", NULL)) {
+ if (of_property_read_bool(np, "fsl,sai-synchronous-rx") &&
+ of_property_read_bool(np, "fsl,sai-asynchronous")) {
/* error out if both synchronous and asynchronous are present */
dev_err(dev, "invalid binding for synchronous mode\n");
return -EINVAL;
}
- if (of_find_property(np, "fsl,sai-synchronous-rx", NULL)) {
+ if (of_property_read_bool(np, "fsl,sai-synchronous-rx")) {
/* Sync Rx with Tx */
sai->synchronous[RX] = false;
sai->synchronous[TX] = true;
- } else if (of_find_property(np, "fsl,sai-asynchronous", NULL)) {
+ } else if (of_property_read_bool(np, "fsl,sai-asynchronous")) {
/* Discard all settings for asynchronous mode */
sai->synchronous[RX] = false;
sai->synchronous[TX] = false;
@@ -1400,7 +1400,7 @@ static int fsl_sai_probe(struct platform_device *pdev)
sai->cpu_dai_drv.symmetric_sample_bits = 0;
}
- if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) &&
+ if (of_property_read_bool(np, "fsl,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)) {
@@ -1443,7 +1443,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_find_property(np, "fsl,sai-mclk-direction-output", NULL) &&
+ if (of_property_read_bool(np, "fsl,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);
@@ -1489,13 +1489,11 @@ err_pm_disable:
return ret;
}
-static int fsl_sai_remove(struct platform_device *pdev)
+static void fsl_sai_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
fsl_sai_runtime_suspend(&pdev->dev);
-
- return 0;
}
static const struct fsl_sai_soc_data fsl_sai_vf610_data = {
@@ -1696,7 +1694,7 @@ static const struct dev_pm_ops fsl_sai_pm_ops = {
static struct platform_driver fsl_sai_driver = {
.probe = fsl_sai_probe,
- .remove = fsl_sai_remove,
+ .remove_new = fsl_sai_remove,
.driver = {
.name = "fsl-sai",
.pm = &fsl_sai_pm_ops,
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 275aba8e0c46..015c3708aa04 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -1659,11 +1659,9 @@ err_pm_disable:
return ret;
}
-static int fsl_spdif_remove(struct platform_device *pdev)
+static void fsl_spdif_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
-
- return 0;
}
#ifdef CONFIG_PM
@@ -1765,7 +1763,7 @@ static struct platform_driver fsl_spdif_driver = {
.pm = &fsl_spdif_pm,
},
.probe = fsl_spdif_probe,
- .remove = fsl_spdif_remove,
+ .remove_new = fsl_spdif_remove,
};
module_platform_driver(fsl_spdif_driver);
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 46a53551b955..53ed3701b0b0 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -1447,7 +1447,7 @@ static int fsl_ssi_probe_from_dt(struct fsl_ssi *ssi)
return -EINVAL;
}
strcpy(ssi->card_name, "ac97-codec");
- } else if (!of_find_property(np, "fsl,ssi-asynchronous", NULL)) {
+ } else if (!of_property_read_bool(np, "fsl,ssi-asynchronous")) {
/*
* In synchronous mode, STCK and STFS ports are used by RX
* as well. So the software should limit the sample rates,
@@ -1671,7 +1671,7 @@ error_ac97_ops:
return ret;
}
-static int fsl_ssi_remove(struct platform_device *pdev)
+static void fsl_ssi_remove(struct platform_device *pdev)
{
struct fsl_ssi *ssi = dev_get_drvdata(&pdev->dev);
@@ -1690,8 +1690,6 @@ static int fsl_ssi_remove(struct platform_device *pdev)
snd_soc_set_ac97_ops(NULL);
mutex_destroy(&ssi->ac97_reg_lock);
}
-
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -1737,7 +1735,7 @@ static struct platform_driver fsl_ssi_driver = {
.pm = &fsl_ssi_pm,
},
.probe = fsl_ssi_probe,
- .remove = fsl_ssi_remove,
+ .remove_new = fsl_ssi_remove,
};
module_platform_driver(fsl_ssi_driver);
diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c
index 2a78243df752..318fe77683f5 100644
--- a/sound/soc/fsl/fsl_xcvr.c
+++ b/sound/soc/fsl/fsl_xcvr.c
@@ -1339,10 +1339,9 @@ static int fsl_xcvr_probe(struct platform_device *pdev)
return ret;
}
-static int fsl_xcvr_remove(struct platform_device *pdev)
+static void fsl_xcvr_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
- return 0;
}
static __maybe_unused int fsl_xcvr_runtime_suspend(struct device *dev)
@@ -1478,7 +1477,7 @@ static struct platform_driver fsl_xcvr_driver = {
.pm = &fsl_xcvr_pm_ops,
.of_match_table = fsl_xcvr_dt_ids,
},
- .remove = fsl_xcvr_remove,
+ .remove_new = fsl_xcvr_remove,
};
module_platform_driver(fsl_xcvr_driver);
diff --git a/sound/soc/fsl/imx-audmix.c b/sound/soc/fsl/imx-audmix.c
index 1292a845c424..b2c5aca92c6b 100644
--- a/sound/soc/fsl/imx-audmix.c
+++ b/sound/soc/fsl/imx-audmix.c
@@ -207,8 +207,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/Platform x 2 */
- dlc = devm_kcalloc(&pdev->dev, 6, sizeof(*dlc), GFP_KERNEL);
+ /* for CPU/Codec x 2 */
+ dlc = devm_kcalloc(&pdev->dev, 4, sizeof(*dlc), GFP_KERNEL);
if (!dlc)
return -ENOMEM;
@@ -238,9 +238,13 @@ static int imx_audmix_probe(struct platform_device *pdev)
dai_name, "CPU-Capture");
}
- priv->dai[i].cpus = &dlc[0];
- priv->dai[i].codecs = &dlc[1];
- priv->dai[i].platforms = &dlc[2];
+ /*
+ * CPU == Platform
+ * platform is using soc-generic-dmaengine-pcm
+ */
+ priv->dai[i].cpus =
+ priv->dai[i].platforms = &dlc[0];
+ priv->dai[i].codecs = &dlc[1];
priv->dai[i].num_cpus = 1;
priv->dai[i].num_codecs = 1;
@@ -252,7 +256,6 @@ static int imx_audmix_probe(struct platform_device *pdev)
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].platforms->of_node = args.np;
priv->dai[i].dynamic = 1;
priv->dai[i].dpcm_playback = 1;
priv->dai[i].dpcm_capture = (i == 0 ? 1 : 0);
@@ -267,20 +270,17 @@ static int imx_audmix_probe(struct platform_device *pdev)
be_cp = devm_kasprintf(&pdev->dev, GFP_KERNEL,
"AUDMIX-Capture-%d", i);
- priv->dai[num_dai + i].cpus = &dlc[3];
- priv->dai[num_dai + i].codecs = &dlc[4];
- priv->dai[num_dai + i].platforms = &dlc[5];
+ priv->dai[num_dai + i].cpus = &dlc[2];
+ priv->dai[num_dai + i].codecs = &dlc[3];
priv->dai[num_dai + i].num_cpus = 1;
priv->dai[num_dai + i].num_codecs = 1;
- priv->dai[num_dai + i].num_platforms = 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].platforms->name = "snd-soc-dummy";
priv->dai[num_dai + i].no_pcm = 1;
priv->dai[num_dai + i].dpcm_playback = 1;
priv->dai[num_dai + i].dpcm_capture = 1;
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index 582f1e2431ee..be003a117b39 100644
--- a/sound/soc/fsl/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
@@ -315,12 +315,10 @@ static int imx_audmux_probe(struct platform_device *pdev)
return 0;
}
-static int imx_audmux_remove(struct platform_device *pdev)
+static void imx_audmux_remove(struct platform_device *pdev)
{
if (audmux_type == IMX31_AUDMUX)
audmux_debugfs_remove();
-
- return 0;
}
#ifdef CONFIG_PM_SLEEP
@@ -359,7 +357,7 @@ static const struct dev_pm_ops imx_audmux_pm = {
static struct platform_driver imx_audmux_driver = {
.probe = imx_audmux_probe,
- .remove = imx_audmux_remove,
+ .remove_new = imx_audmux_remove,
.driver = {
.name = DRIVER_NAME,
.pm = &imx_audmux_pm,
diff --git a/sound/soc/fsl/imx-card.c b/sound/soc/fsl/imx-card.c
index 3f128ced4180..64a4d7e9db60 100644
--- a/sound/soc/fsl/imx-card.c
+++ b/sound/soc/fsl/imx-card.c
@@ -563,7 +563,7 @@ static int imx_card_parse_of(struct imx_card_data *data)
link_data->cpu_sysclk_id = FSL_SAI_CLK_MAST1;
/* sai may support mclk/bclk = 1 */
- if (of_find_property(np, "fsl,mclk-equal-bclk", NULL)) {
+ if (of_property_read_bool(np, "fsl,mclk-equal-bclk")) {
link_data->one2one_ratio = true;
} else {
int i;
diff --git a/sound/soc/fsl/imx-es8328.c b/sound/soc/fsl/imx-es8328.c
index b80c57362fb8..85bd36fb68a2 100644
--- a/sound/soc/fsl/imx-es8328.c
+++ b/sound/soc/fsl/imx-es8328.c
@@ -149,7 +149,7 @@ static int imx_es8328_probe(struct platform_device *pdev)
goto put_device;
}
- comp = devm_kzalloc(dev, 3 * sizeof(*comp), GFP_KERNEL);
+ comp = devm_kzalloc(dev, 2 * sizeof(*comp), GFP_KERNEL);
if (!comp) {
ret = -ENOMEM;
goto put_device;
@@ -159,9 +159,13 @@ static int imx_es8328_probe(struct platform_device *pdev)
data->jack_gpio = of_get_named_gpio(pdev->dev.of_node, "jack-gpio", 0);
- data->dai.cpus = &comp[0];
+ /*
+ * CPU == Platform
+ * platform is using soc-generic-dmaengine-pcm
+ */
+ data->dai.cpus =
+ data->dai.platforms = &comp[0];
data->dai.codecs = &comp[1];
- data->dai.platforms = &comp[2];
data->dai.num_cpus = 1;
data->dai.num_codecs = 1;
@@ -172,7 +176,6 @@ static int imx_es8328_probe(struct platform_device *pdev)
data->dai.codecs->dai_name = "es8328-hifi-analog";
data->dai.codecs->of_node = codec_np;
data->dai.cpus->of_node = ssi_np;
- data->dai.platforms->of_node = ssi_np;
data->dai.init = &imx_es8328_dai_init;
data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBP_CFP;
diff --git a/sound/soc/fsl/imx-pcm-rpmsg.c b/sound/soc/fsl/imx-pcm-rpmsg.c
index 6614b3447649..765dad607bf6 100644
--- a/sound/soc/fsl/imx-pcm-rpmsg.c
+++ b/sound/soc/fsl/imx-pcm-rpmsg.c
@@ -743,14 +743,12 @@ fail:
return ret;
}
-static int imx_rpmsg_pcm_remove(struct platform_device *pdev)
+static void imx_rpmsg_pcm_remove(struct platform_device *pdev)
{
struct rpmsg_info *info = platform_get_drvdata(pdev);
if (info->rpmsg_wq)
destroy_workqueue(info->rpmsg_wq);
-
- return 0;
}
#ifdef CONFIG_PM
@@ -821,7 +819,7 @@ static const struct dev_pm_ops imx_rpmsg_pcm_pm_ops = {
static struct platform_driver imx_pcm_rpmsg_driver = {
.probe = imx_rpmsg_pcm_probe,
- .remove = imx_rpmsg_pcm_remove,
+ .remove_new = imx_rpmsg_pcm_remove,
.driver = {
.name = IMX_PCM_DRV_NAME,
.pm = &imx_rpmsg_pcm_pm_ops,
diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c
index 580a0d963f0e..26c22783927b 100644
--- a/sound/soc/fsl/imx-sgtl5000.c
+++ b/sound/soc/fsl/imx-sgtl5000.c
@@ -193,14 +193,12 @@ fail:
return ret;
}
-static int imx_sgtl5000_remove(struct platform_device *pdev)
+static void imx_sgtl5000_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct imx_sgtl5000_data *data = snd_soc_card_get_drvdata(card);
clk_put(data->codec_clk);
-
- return 0;
}
static const struct of_device_id imx_sgtl5000_dt_ids[] = {
@@ -216,7 +214,7 @@ static struct platform_driver imx_sgtl5000_driver = {
.of_match_table = imx_sgtl5000_dt_ids,
},
.probe = imx_sgtl5000_probe,
- .remove = imx_sgtl5000_remove,
+ .remove_new = imx_sgtl5000_remove,
};
module_platform_driver(imx_sgtl5000_driver);
diff --git a/sound/soc/fsl/imx-spdif.c b/sound/soc/fsl/imx-spdif.c
index 4446fba755b9..ab978431ac98 100644
--- a/sound/soc/fsl/imx-spdif.c
+++ b/sound/soc/fsl/imx-spdif.c
@@ -26,15 +26,19 @@ static int imx_spdif_audio_probe(struct platform_device *pdev)
}
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
- comp = devm_kzalloc(&pdev->dev, 3 * sizeof(*comp), GFP_KERNEL);
+ comp = devm_kzalloc(&pdev->dev, 2 * sizeof(*comp), GFP_KERNEL);
if (!data || !comp) {
ret = -ENOMEM;
goto end;
}
- data->dai.cpus = &comp[0];
+ /*
+ * CPU == Platform
+ * platform is using soc-generic-dmaengine-pcm
+ */
+ data->dai.cpus =
+ data->dai.platforms = &comp[0];
data->dai.codecs = &comp[1];
- data->dai.platforms = &comp[2];
data->dai.num_cpus = 1;
data->dai.num_codecs = 1;
@@ -45,7 +49,6 @@ static int imx_spdif_audio_probe(struct platform_device *pdev)
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.platforms->of_node = spdif_np;
data->dai.playback_only = true;
data->dai.capture_only = true;
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c
index a082ae636a4f..40a4a2667394 100644
--- a/sound/soc/fsl/mpc5200_psc_ac97.c
+++ b/sound/soc/fsl/mpc5200_psc_ac97.c
@@ -311,12 +311,11 @@ static int psc_ac97_of_probe(struct platform_device *op)
return 0;
}
-static int psc_ac97_of_remove(struct platform_device *op)
+static void psc_ac97_of_remove(struct platform_device *op)
{
mpc5200_audio_dma_destroy(op);
snd_soc_unregister_component(&op->dev);
snd_soc_set_ac97_ops(NULL);
- return 0;
}
/* Match table for of_platform binding */
@@ -329,7 +328,7 @@ MODULE_DEVICE_TABLE(of, psc_ac97_match);
static struct platform_driver psc_ac97_driver = {
.probe = psc_ac97_of_probe,
- .remove = psc_ac97_of_remove,
+ .remove_new = psc_ac97_of_remove,
.driver = {
.name = "mpc5200-psc-ac97",
.of_match_table = psc_ac97_match,
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index 73f3e61f208a..413df413b5eb 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -210,11 +210,10 @@ static int psc_i2s_of_probe(struct platform_device *op)
}
-static int psc_i2s_of_remove(struct platform_device *op)
+static void psc_i2s_of_remove(struct platform_device *op)
{
mpc5200_audio_dma_destroy(op);
snd_soc_unregister_component(&op->dev);
- return 0;
}
/* Match table for of_platform binding */
@@ -227,7 +226,7 @@ MODULE_DEVICE_TABLE(of, psc_i2s_match);
static struct platform_driver psc_i2s_driver = {
.probe = psc_i2s_of_probe,
- .remove = psc_i2s_of_remove,
+ .remove_new = psc_i2s_of_remove,
.driver = {
.name = "mpc5200-psc-i2s",
.of_match_table = psc_i2s_match,
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index e71a992fbf93..ea2076ea8afe 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -387,7 +387,7 @@ error_alloc:
*
* This function is called when the platform device is removed.
*/
-static int mpc8610_hpcd_remove(struct platform_device *pdev)
+static void mpc8610_hpcd_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct mpc8610_hpcd_data *machine_data =
@@ -395,13 +395,11 @@ static int mpc8610_hpcd_remove(struct platform_device *pdev)
snd_soc_unregister_card(card);
kfree(machine_data);
-
- return 0;
}
static struct platform_driver mpc8610_hpcd_driver = {
.probe = mpc8610_hpcd_probe,
- .remove = mpc8610_hpcd_remove,
+ .remove_new = mpc8610_hpcd_remove,
.driver = {
/* The name must match 'compatible' property in the device tree,
* in lowercase letters.
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
index b45742931b0d..0b1418abeb9c 100644
--- a/sound/soc/fsl/p1022_ds.c
+++ b/sound/soc/fsl/p1022_ds.c
@@ -396,7 +396,7 @@ error_put:
*
* This function is called when the platform device is removed.
*/
-static int p1022_ds_remove(struct platform_device *pdev)
+static void p1022_ds_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct machine_data *mdata =
@@ -404,13 +404,11 @@ static int p1022_ds_remove(struct platform_device *pdev)
snd_soc_unregister_card(card);
kfree(mdata);
-
- return 0;
}
static struct platform_driver p1022_ds_driver = {
.probe = p1022_ds_probe,
- .remove = p1022_ds_remove,
+ .remove_new = p1022_ds_remove,
.driver = {
/*
* The name must match 'compatible' property in the device tree,
diff --git a/sound/soc/fsl/p1022_rdk.c b/sound/soc/fsl/p1022_rdk.c
index b395adabe823..4d85b742114c 100644
--- a/sound/soc/fsl/p1022_rdk.c
+++ b/sound/soc/fsl/p1022_rdk.c
@@ -345,7 +345,7 @@ error_put:
*
* This function is called when the platform device is removed.
*/
-static int p1022_rdk_remove(struct platform_device *pdev)
+static void p1022_rdk_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct machine_data *mdata =
@@ -353,13 +353,11 @@ static int p1022_rdk_remove(struct platform_device *pdev)
snd_soc_unregister_card(card);
kfree(mdata);
-
- return 0;
}
static struct platform_driver p1022_rdk_driver = {
.probe = p1022_rdk_probe,
- .remove = p1022_rdk_remove,
+ .remove_new = p1022_rdk_remove,
.driver = {
/*
* The name must match 'compatible' property in the device tree,
diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c
index 997c3e66c636..d24c02e90878 100644
--- a/sound/soc/fsl/pcm030-audio-fabric.c
+++ b/sound/soc/fsl/pcm030-audio-fabric.c
@@ -109,14 +109,12 @@ static int pcm030_fabric_probe(struct platform_device *op)
}
-static int pcm030_fabric_remove(struct platform_device *op)
+static void pcm030_fabric_remove(struct platform_device *op)
{
struct pcm030_audio_data *pdata = platform_get_drvdata(op);
snd_soc_unregister_card(pdata->card);
platform_device_unregister(pdata->codec_device);
-
- return 0;
}
static const struct of_device_id pcm030_audio_match[] = {
@@ -127,7 +125,7 @@ MODULE_DEVICE_TABLE(of, pcm030_audio_match);
static struct platform_driver pcm030_fabric_driver = {
.probe = pcm030_fabric_probe,
- .remove = pcm030_fabric_remove,
+ .remove_new = pcm030_fabric_remove,
.driver = {
.name = DRV_NAME,
.of_match_table = pcm030_audio_match,