--- v3
+++ v1
@@ -19,11 +19,11 @@
---
sound/soc/tegra/Kconfig | 12 +
sound/soc/tegra/Makefile | 2 +
- sound/soc/tegra/tegra210_admaif.c | 884 ++++++++++++++++++++++++++++++++++++++
+ sound/soc/tegra/tegra210_admaif.c | 896 ++++++++++++++++++++++++++++++++++++++
sound/soc/tegra/tegra210_admaif.h | 164 +++++++
- sound/soc/tegra/tegra_pcm.c | 222 +++++++++-
+ sound/soc/tegra/tegra_pcm.c | 224 +++++++++-
sound/soc/tegra/tegra_pcm.h | 23 +-
- 6 files changed, 1305 insertions(+), 2 deletions(-)
+ 6 files changed, 1319 insertions(+), 2 deletions(-)
create mode 100644 sound/soc/tegra/tegra210_admaif.c
create mode 100644 sound/soc/tegra/tegra210_admaif.h
@@ -51,10 +51,10 @@
tristate "SoC Audio support for Tegra boards using an RT5640 codec"
depends on SND_SOC_TEGRA && I2C && GPIOLIB
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
-index 336c4c7..60040a0 100644
+index 7ad8169..1033464 100644
--- a/sound/soc/tegra/Makefile
+++ b/sound/soc/tegra/Makefile
-@@ -12,6 +12,7 @@ snd-soc-tegra210-ahub-objs := tegra210_ahub.o
+@@ -13,6 +13,7 @@ snd-soc-tegra210-ahub-objs := tegra210_ahub.o
snd-soc-tegra210-dmic-objs := tegra210_dmic.o
snd-soc-tegra210-i2s-objs := tegra210_i2s.o
snd-soc-tegra186-dspk-objs := tegra186_dspk.o
@@ -62,7 +62,7 @@
obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-pcm.o
obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-utils.o
-@@ -25,6 +26,7 @@ obj-$(CONFIG_SND_SOC_TEGRA210_DMIC) += snd-soc-tegra210-dmic.o
+@@ -27,6 +28,7 @@ obj-$(CONFIG_SND_SOC_TEGRA210_DMIC) += snd-soc-tegra210-dmic.o
obj-$(CONFIG_SND_SOC_TEGRA210_AHUB) += snd-soc-tegra210-ahub.o
obj-$(CONFIG_SND_SOC_TEGRA210_I2S) += snd-soc-tegra210-i2s.o
obj-$(CONFIG_SND_SOC_TEGRA186_DSPK) += snd-soc-tegra186-dspk.o
@@ -72,10 +72,10 @@
snd-soc-tegra-rt5640-objs := tegra_rt5640.o
diff --git a/sound/soc/tegra/tegra210_admaif.c b/sound/soc/tegra/tegra210_admaif.c
new file mode 100644
-index 0000000..01f2249
+index 0000000..278700f
--- /dev/null
+++ b/sound/soc/tegra/tegra210_admaif.c
-@@ -0,0 +1,884 @@
+@@ -0,0 +1,896 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * tegra210_admaif.c - Tegra ADMAIF driver
@@ -84,18 +84,20 @@
+ *
+ */
+
-+#include <linux/clk.h>
++#include <linux/platform_device.h>
++#include <linux/pm_runtime.h>
++#include <linux/of_platform.h>
+#include <linux/device.h>
+#include <linux/module.h>
-+#include <linux/of_platform.h>
-+#include <linux/platform_device.h>
-+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
++#include <linux/clk.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include "tegra210_admaif.h"
++#include "tegra_pcm.h"
+#include "tegra_cif.h"
-+#include "tegra_pcm.h"
++
++#define DRV_NAME "tegra210-admaif"
+
+#define CH_REG(offset, reg, id) \
+ ((offset) + (reg) + (TEGRA_ADMAIF_CHANNEL_REG_STRIDE * (id)))
@@ -105,15 +107,15 @@
+#define CH_RX_REG(reg, id) CH_REG(admaif->soc_data->rx_base, reg, id)
+
+#define REG_DEFAULTS(id, rx_ctrl, tx_ctrl, tx_base, rx_base) \
-+ { CH_REG(rx_base, TEGRA_ADMAIF_RX_INT_MASK, id), 0x00000001 }, \
-+ { CH_REG(rx_base, TEGRA_ADMAIF_CH_ACIF_RX_CTRL, id), 0x00007700 }, \
-+ { CH_REG(rx_base, TEGRA_ADMAIF_RX_FIFO_CTRL, id), rx_ctrl }, \
-+ { CH_REG(tx_base, TEGRA_ADMAIF_TX_INT_MASK, id), 0x00000001 }, \
-+ { CH_REG(tx_base, TEGRA_ADMAIF_CH_ACIF_TX_CTRL, id), 0x00007700 }, \
-+ { CH_REG(tx_base, TEGRA_ADMAIF_TX_FIFO_CTRL, id), tx_ctrl }
++ { CH_REG(rx_base, TEGRA_ADMAIF_RX_INT_MASK, id), 0x00000001}, \
++ { CH_REG(rx_base, TEGRA_ADMAIF_CH_ACIF_RX_CTRL, id), 0x00007700}, \
++ { CH_REG(rx_base, TEGRA_ADMAIF_RX_FIFO_CTRL, id), rx_ctrl}, \
++ { CH_REG(tx_base, TEGRA_ADMAIF_TX_INT_MASK, id), 0x00000001}, \
++ { CH_REG(tx_base, TEGRA_ADMAIF_CH_ACIF_TX_CTRL, id), 0x00007700}, \
++ { CH_REG(tx_base, TEGRA_ADMAIF_TX_FIFO_CTRL, id), tx_ctrl}
+
+#define ADMAIF_REG_DEFAULTS(id, chip) \
-+ REG_DEFAULTS((id) - 1, \
++ REG_DEFAULTS((id - 1), \
+ chip ## _ADMAIF_RX ## id ## _FIFO_CTRL_REG_DEFAULT, \
+ chip ## _ADMAIF_TX ## id ## _FIFO_CTRL_REG_DEFAULT, \
+ chip ## _ADMAIF_TX_BASE, \
@@ -144,7 +146,7 @@
+};
+
+static const struct reg_default tegra210_admaif_reg_defaults[] = {
-+ {(TEGRA_ADMAIF_GLOBAL_CG_0 + TEGRA210_ADMAIF_GLOBAL_BASE), 0x00000003},
++ {(TEGRA_ADMAIF_GLOBAL_CG_0+TEGRA210_ADMAIF_GLOBAL_BASE), 0x00000003},
+ ADMAIF_REG_DEFAULTS(1, TEGRA210),
+ ADMAIF_REG_DEFAULTS(2, TEGRA210),
+ ADMAIF_REG_DEFAULTS(3, TEGRA210),
@@ -433,7 +435,7 @@
+ struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai);
+ unsigned int enable_reg, status_reg, reset_reg, mask, val;
+ char *dir_name;
-+ int err, enable;
++ int ret, enable;
+
+ switch (direction) {
+ case SNDRV_PCM_STREAM_PLAYBACK:
@@ -460,23 +462,23 @@
+ regmap_update_bits(admaif->regmap, enable_reg, mask, ~enable);
+
+ /* Wait until ADMAIF TX/RX status is disabled */
-+ err = regmap_read_poll_timeout_atomic(admaif->regmap, status_reg, val,
++ ret = regmap_read_poll_timeout_atomic(admaif->regmap, status_reg, val,
+ !(val & enable), 10, 10000);
-+ if (err < 0)
++ if (ret < 0)
+ dev_warn(dai->dev, "timeout: failed to disable ADMAIF%d_%s\n",
-+ dai->id + 1, dir_name);
++ dai->id + 1, dir_name);
+
+ /* SW reset */
+ regmap_update_bits(admaif->regmap, reset_reg, SW_RESET_MASK, SW_RESET);
+
+ /* Wait till SW reset is complete */
-+ err = regmap_read_poll_timeout_atomic(admaif->regmap, reset_reg, val,
++ ret = regmap_read_poll_timeout_atomic(admaif->regmap, reset_reg, val,
+ !(val & SW_RESET_MASK & SW_RESET),
+ 10, 10000);
-+ if (err) {
++ if (ret < 0) {
+ dev_err(dai->dev, "timeout: SW reset failed for ADMAIF%d_%s\n",
+ dai->id + 1, dir_name);
-+ return err;
++ return ret;
+ }
+
+ return 0;
@@ -485,11 +487,11 @@
+static int tegra_admaif_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+{
-+ int err;
-+
-+ err = snd_dmaengine_pcm_trigger(substream, cmd);
-+ if (err)
-+ return err;
++ int ret;
++
++ ret = snd_dmaengine_pcm_trigger(substream, cmd);
++ if (ret < 0)
++ return ret;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
@@ -505,7 +507,7 @@
+ }
+}
+
-+static const struct snd_soc_dai_ops tegra_admaif_dai_ops = {
++static struct snd_soc_dai_ops tegra_admaif_dai_ops = {
+ .hw_params = tegra_admaif_hw_params,
+ .trigger = tegra_admaif_trigger,
+};
@@ -759,6 +761,7 @@
+};
+
+static const struct snd_soc_component_driver tegra210_admaif_cmpnt = {
++ .name = DRV_NAME,
+ .controls = tegra210_admaif_controls,
+ .num_controls = ARRAY_SIZE(tegra210_admaif_controls),
+ .pcm_construct = tegra_pcm_construct,
@@ -772,6 +775,7 @@
+};
+
+static const struct snd_soc_component_driver tegra186_admaif_cmpnt = {
++ .name = DRV_NAME,
+ .controls = tegra186_admaif_controls,
+ .num_controls = ARRAY_SIZE(tegra186_admaif_controls),
+ .pcm_construct = tegra_pcm_construct,
@@ -794,7 +798,7 @@
+ .rx_base = TEGRA210_ADMAIF_RX_BASE,
+};
+
-+static const struct tegra_admaif_soc_data soc_data_tegra186 = {
++static struct tegra_admaif_soc_data soc_data_tegra186 = {
+ .num_ch = TEGRA186_ADMAIF_CHANNEL_COUNT,
+ .cmpnt = &tegra186_admaif_cmpnt,
+ .dais = tegra186_admaif_cmpnt_dais,
@@ -804,26 +808,32 @@
+ .rx_base = TEGRA186_ADMAIF_RX_BASE,
+};
+
++
+static const struct of_device_id tegra_admaif_of_match[] = {
+ { .compatible = "nvidia,tegra210-admaif", .data = &soc_data_tegra210 },
+ { .compatible = "nvidia,tegra186-admaif", .data = &soc_data_tegra186 },
+ {},
+};
-+MODULE_DEVICE_TABLE(of, tegra_admaif_of_match);
+
+static int tegra_admaif_probe(struct platform_device *pdev)
+{
++ const struct of_device_id *match;
+ struct tegra_admaif *admaif;
+ void __iomem *regs;
+ struct resource *res;
-+ int err, i;
-+
-+ admaif = devm_kzalloc(&pdev->dev, sizeof(*admaif), GFP_KERNEL);
++ int ret, i;
++
++ match = of_match_device(tegra_admaif_of_match, &pdev->dev);
++ if (!match) {
++ dev_err(&pdev->dev, "error: No device match found\n");
++ return -ENODEV;
++ }
++
++ admaif = devm_kcalloc(&pdev->dev, 1, sizeof(*admaif), GFP_KERNEL);
+ if (!admaif)
+ return -ENOMEM;
+
-+ admaif->soc_data = of_device_get_match_data(&pdev->dev);
-+
++ admaif->soc_data = (struct tegra_admaif_soc_data *)match->data;
+ dev_set_drvdata(&pdev->dev, admaif);
+
+ admaif->capture_dma_data =
@@ -869,7 +879,6 @@
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+
+ regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(regs))
+ return PTR_ERR(regs);
@@ -896,11 +905,11 @@
+ admaif->playback_dma_data[i].addr_width = 32;
+
+ if (of_property_read_string_index(pdev->dev.of_node,
-+ "dma-names", (i * 2) + 1,
++ "dma-names",
++ (i * 2) + 1,
+ &admaif->playback_dma_data[i].chan_name) < 0) {
+ dev_err(&pdev->dev,
+ "missing property nvidia,dma-names\n");
-+
+ return -ENODEV;
+ }
+
@@ -912,19 +921,18 @@
+ &admaif->capture_dma_data[i].chan_name) < 0) {
+ dev_err(&pdev->dev,
+ "missing property nvidia,dma-names\n");
-+
+ return -ENODEV;
+ }
+ }
+
-+ err = devm_snd_soc_register_component(&pdev->dev,
++ ret = devm_snd_soc_register_component(&pdev->dev,
+ admaif->soc_data->cmpnt,
+ admaif->soc_data->dais,
+ admaif->soc_data->num_ch);
-+ if (err) {
-+ dev_err(&pdev->dev,
-+ "can't register ADMAIF component, err: %d\n", err);
-+ return err;
++ if (ret != 0) {
++ dev_err(&pdev->dev, "could not register component, err: %d\n",
++ ret);
++ return ret;
+ }
+
+ pm_runtime_enable(&pdev->dev);
@@ -935,6 +943,8 @@
+static int tegra_admaif_remove(struct platform_device *pdev)
+{
+ pm_runtime_disable(&pdev->dev);
++ if (!pm_runtime_status_suspended(&pdev->dev))
++ tegra_admaif_runtime_suspend(&pdev->dev);
+
+ return 0;
+}
@@ -942,15 +952,16 @@
+static const struct dev_pm_ops tegra_admaif_pm_ops = {
+ SET_RUNTIME_PM_OPS(tegra_admaif_runtime_suspend,
+ tegra_admaif_runtime_resume, NULL)
-+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
-+ pm_runtime_force_resume)
++ SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
++ pm_runtime_force_resume)
+};
+
+static struct platform_driver tegra_admaif_driver = {
+ .probe = tegra_admaif_probe,
+ .remove = tegra_admaif_remove,
+ .driver = {
-+ .name = "tegra210-admaif",
++ .name = DRV_NAME,
++ .owner = THIS_MODULE,
+ .of_match_table = tegra_admaif_of_match,
+ .pm = &tegra_admaif_pm_ops,
+ },
@@ -960,9 +971,10 @@
+MODULE_AUTHOR("Songhee Baek <sbaek-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>");
+MODULE_DESCRIPTION("Tegra210 ASoC ADMAIF driver");
+MODULE_LICENSE("GPL v2");
++MODULE_DEVICE_TABLE(of, tegra_admaif_of_match);
diff --git a/sound/soc/tegra/tegra210_admaif.h b/sound/soc/tegra/tegra210_admaif.h
new file mode 100644
-index 0000000..e9622d1
+index 0000000..1743c0a
--- /dev/null
+++ b/sound/soc/tegra/tegra210_admaif.h
@@ -0,0 +1,164 @@
@@ -1020,17 +1032,17 @@
+#define TEGRA_ADMAIF_TX_FIFO_WRITE 0x2c
+/* Bit fields */
+#define PACK8_EN_SHIFT 31
-+#define PACK8_EN_MASK BIT(PACK8_EN_SHIFT)
-+#define PACK8_EN BIT(PACK8_EN_SHIFT)
++#define PACK8_EN_MASK (1 << PACK8_EN_SHIFT)
++#define PACK8_EN (1 << PACK8_EN_SHIFT)
+#define PACK16_EN_SHIFT 30
-+#define PACK16_EN_MASK BIT(PACK16_EN_SHIFT)
-+#define PACK16_EN BIT(PACK16_EN_SHIFT)
++#define PACK16_EN_MASK (1 << PACK16_EN_SHIFT)
++#define PACK16_EN (1 << PACK16_EN_SHIFT)
+#define TX_ENABLE_SHIFT 0
-+#define TX_ENABLE_MASK BIT(TX_ENABLE_SHIFT)
-+#define TX_ENABLE BIT(TX_ENABLE_SHIFT)
++#define TX_ENABLE_MASK (1 << TX_ENABLE_SHIFT)
++#define TX_ENABLE (1 << TX_ENABLE_SHIFT)
+#define RX_ENABLE_SHIFT 0
-+#define RX_ENABLE_MASK BIT(RX_ENABLE_SHIFT)
-+#define RX_ENABLE BIT(RX_ENABLE_SHIFT)
++#define RX_ENABLE_MASK (1 << RX_ENABLE_SHIFT)
++#define RX_ENABLE (1 << RX_ENABLE_SHIFT)
+#define SW_RESET_MASK 1
+#define SW_RESET 1
+/* Default values - Tegra210 */
@@ -1131,7 +1143,7 @@
+
+#endif
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
-index f246df8..52d4054 100644
+index f246df8..497a54d 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -16,12 +16,12 @@
@@ -1148,7 +1160,7 @@
#include "tegra_pcm.h"
static const struct snd_pcm_hardware tegra_pcm_hardware = {
-@@ -67,6 +67,226 @@ void tegra_pcm_platform_unregister(struct device *dev)
+@@ -67,6 +67,228 @@ void tegra_pcm_platform_unregister(struct device *dev)
}
EXPORT_SYMBOL_GPL(tegra_pcm_platform_unregister);
@@ -1330,21 +1342,23 @@
+}
+
+static int tegra_pcm_dma_allocate(struct snd_soc_pcm_runtime *rtd,
-+ size_t size)
++ size_t size)
+{
+ struct snd_pcm *pcm = rtd->pcm;
+ int ret = 0;
+
+ if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
+ ret = tegra_pcm_preallocate_dma_buffer(pcm,
-+ SNDRV_PCM_STREAM_PLAYBACK, size);
++ SNDRV_PCM_STREAM_PLAYBACK,
++ size);
+ if (ret)
+ goto err;
+ }
+
+ if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
+ ret = tegra_pcm_preallocate_dma_buffer(pcm,
-+ SNDRV_PCM_STREAM_CAPTURE, size);
++ SNDRV_PCM_STREAM_CAPTURE,
++ size);
+ if (ret)
+ goto err_free_play;
+ }