audio: auge: add sound card for sm1 [2/2]
authorXing Wang <xing.wang@amlogic.com>
Wed, 20 Mar 2019 14:44:51 +0000 (22:44 +0800)
committerJianxiong Pan <jianxiong.pan@amlogic.com>
Fri, 29 Mar 2019 12:23:06 +0000 (20:23 +0800)
PD#SWPL-6151

Problem:
sound card for sm1

Solution:
add sound card for sm1

Verify:
ac200

Change-Id: I4f65472af7a8399fb6fe003db608158e11bed566
Signed-off-by: Xing Wang <xing.wang@amlogic.com>
27 files changed:
MAINTAINERS
sound/soc/amlogic/auge/Makefile
sound/soc/amlogic/auge/audio_clks.c
sound/soc/amlogic/auge/audio_clks.h
sound/soc/amlogic/auge/audio_utils.c
sound/soc/amlogic/auge/ddr_mngr.c
sound/soc/amlogic/auge/ddr_mngr.h
sound/soc/amlogic/auge/earc.c [new file with mode: 0644]
sound/soc/amlogic/auge/earc_hw.c [new file with mode: 0644]
sound/soc/amlogic/auge/earc_hw.h [new file with mode: 0644]
sound/soc/amlogic/auge/iomap.c
sound/soc/amlogic/auge/iomap.h
sound/soc/amlogic/auge/loopback_hw.c
sound/soc/amlogic/auge/pdm.c
sound/soc/amlogic/auge/pdm.h
sound/soc/amlogic/auge/pdm_hw.c
sound/soc/amlogic/auge/pdm_hw.h
sound/soc/amlogic/auge/pdm_match_table.c [new file with mode: 0644]
sound/soc/amlogic/auge/regs.h
sound/soc/amlogic/auge/sm1,clocks.c [new file with mode: 0644]
sound/soc/amlogic/auge/spdif.c
sound/soc/amlogic/auge/spdif_match_table.c [new file with mode: 0644]
sound/soc/amlogic/auge/tdm.c
sound/soc/amlogic/auge/tdm_hw.c
sound/soc/amlogic/auge/tdm_hw.h
sound/soc/amlogic/auge/tdm_match_table.c [new file with mode: 0644]
sound/soc/amlogic/auge/vad_dev.c

index 5b081ac..0223b36 100644 (file)
@@ -14686,7 +14686,7 @@ AMLOGIC TL1 NEW EQDRC
 AMLOGIC TL1 MIXER CONTROLS
 AMLOGIC TL1 VAD DRIVER
 AMLOGIC SM1 SOUND CARD
-M:     Xing Wang <xing.wang@amlogic.com
+M:     Xing Wang <xing.wang@amlogic.com>
 F:     arch/arm/boot/dts/amlogic/tl1_pxp.dts
 F:     include/dt-bindings/clock/amlogic,tl1-audio-clk.h
 F:     include/dt-bindings/clock/amlogic,sm1-audio-clk.h
index 4cf47be..91825bf 100644 (file)
@@ -4,6 +4,7 @@ obj-$(CONFIG_AMLOGIC_SND_SOC_AUGE)      += audio_controller.o \
                                                axg,clocks.o \
                                                g12a,clocks.o \
                                                tl1,clocks.o \
+                                               sm1,clocks.o \
                                                card.o \
                                                card_utils.o \
                                                tdm.o \
@@ -32,4 +33,6 @@ obj-$(CONFIG_AMLOGIC_SND_SOC_AUGE)    += audio_controller.o \
                                                frhdmirx_hw.o \
                                                vad.o \
                                                vad_hw.o \
-                                               vad_dev.o
+                                               vad_dev.o \
+                                               earc.o \
+                                               earc_hw.o
index 1f0dd6f..e02f2a5 100644 (file)
@@ -36,6 +36,10 @@ static const struct of_device_id audio_clocks_of_match[] = {
                .compatible = "amlogic, tl1-audio-clocks",
                .data       = &tl1_audio_clks_init,
        },
+       {
+               .compatible = "amlogic, sm1-audio-clocks",
+               .data           = &sm1_audio_clks_init,
+       },
        {},
 };
 MODULE_DEVICE_TABLE(of, audio_clocks_of_match);
index 359fbfc..56a0a67 100644 (file)
@@ -93,6 +93,7 @@ struct audio_clk_init {
 extern struct audio_clk_init axg_audio_clks_init;
 extern struct audio_clk_init g12a_audio_clks_init;
 extern struct audio_clk_init tl1_audio_clks_init;
+extern struct audio_clk_init sm1_audio_clks_init;
 
 struct clk_chipinfo {
        /* force clock source as oscin(24M) */
index 2301428..aa2c827 100644 (file)
@@ -711,6 +711,9 @@ static int tdmout_c_binv_set_enum(
        SND_ENUM(xname, type, CTRL0, xenum, xshift, xmask)
 
 #define SND_SWAP(xname, type, xenum, xshift, xmask)   \
+       SND_ENUM(xname, type, SWAP0, xenum, xshift, xmask)
+
+#define SND_SPDIFOUT_SWAP(xname, type, xenum, xshift, xmask)   \
        SND_ENUM(xname, type, SWAP, xenum, xshift, xmask)
 
 #define TDM_MASK(xname, type, func)   \
@@ -992,9 +995,9 @@ static const struct snd_kcontrol_new snd_auge_controls[] = {
                                spdif_channel_status_enum),
 
        /*SPDIFOUT swap*/
-       SND_SWAP("SPDIFOUT Lane0 Left Channel Swap",
+       SND_SPDIFOUT_SWAP("SPDIFOUT Lane0 Left Channel Swap",
                SPDIFOUT, out_swap_channel_enum, 0, 0x7),
-       SND_SWAP("SPDIFOUT Lane0 Right Channel Swap",
+       SND_SPDIFOUT_SWAP("SPDIFOUT Lane0 Right Channel Swap",
                SPDIFOUT, out_swap_channel_enum, 4, 0x7),
        /*SPDIFOUT mixer*/
        SND_MIX("SPDIFOUT Mixer Channel",
index 5c22860..636c905 100644 (file)
@@ -1376,7 +1376,7 @@ static const char *const toddr_src_sel_texts[] = {
        "TDMIN_A", "TDMIN_B", "TDMIN_C", "SPDIFIN",
        "PDMIN", "FRATV", "TDMIN_LB", "LOOPBACK_A",
        "FRHDMIRX", "LOOPBACK_B", "SPDIFIN_LB",
-       "RESERVED", "RESERVED", "RESERVED", "RESERVED",
+       "EARCRX_DMAC", "RESERVED", "RESERVED", "RESERVED",
        "VAD"
 };
 
@@ -1500,6 +1500,15 @@ static struct ddr_chipinfo tl1_ddr_chipinfo = {
        .wakeup                = 2,
 };
 
+static struct ddr_chipinfo sm1_ddr_chipinfo = {
+       .same_src_fn           = true,
+       .ugt                   = true,
+       .src_sel_ctrl          = true,
+       .asrc_src_sel_ctrl     = true,
+       .fifo_num              = 4,
+       .wakeup                = 2,
+};
+
 static const struct of_device_id aml_ddr_mngr_device_id[] = {
        {
                .compatible = "amlogic, axg-audio-ddr-manager",
@@ -1513,6 +1522,10 @@ static const struct of_device_id aml_ddr_mngr_device_id[] = {
                .compatible = "amlogic, tl1-audio-ddr-manager",
                .data       = &tl1_ddr_chipinfo,
        },
+       {
+               .compatible = "amlogic, sm1-audio-ddr-manager",
+               .data       = &sm1_ddr_chipinfo,
+       },
        {},
 };
 MODULE_DEVICE_TABLE(of, aml_ddr_mngr_device_id);
@@ -1576,6 +1589,8 @@ static int aml_ddr_mngr_platform_probe(struct platform_device *pdev)
                && (p_ddr_chipinfo->fifo_num == 4)) {
                toddrs[DDR_D].irq = platform_get_irq_byname(pdev, "toddr_d");
                frddrs[DDR_D].irq = platform_get_irq_byname(pdev, "frddr_d");
+               if (toddrs[DDR_D].irq < 0 || frddrs[DDR_D].irq < 0)
+                       dev_err(&pdev->dev, "check irq for DDR_D\n");
                ddr_num = p_ddr_chipinfo->fifo_num;
        }
 
index 203c0b4..cfb92ee 100644 (file)
@@ -53,6 +53,7 @@ enum toddr_src {
        FRHDMIRX, /* from tl1 chipset*/
        LOOPBACK_B,
        SPDIFIN_LB,
+       EARCRX_DMAC, /* from sm1 chipset */
        VAD,
 };
 
diff --git a/sound/soc/amlogic/auge/earc.c b/sound/soc/amlogic/auge/earc.c
new file mode 100644 (file)
index 0000000..124ac69
--- /dev/null
@@ -0,0 +1,792 @@
+/*
+ * sound/soc/amlogic/auge/earc.c
+ *
+ * Copyright (C) 2019 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * Audio External Input/Out drirver
+ * such as fratv, frhdmirx
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/ioctl.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/clk.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/initval.h>
+#include <sound/control.h>
+#include <sound/soc.h>
+#include <sound/pcm_params.h>
+
+#include "ddr_mngr.h"
+#include "earc_hw.h"
+
+#define DRV_NAME "EARC"
+
+struct earc {
+       struct aml_audio_controller *actrl;
+       struct device *dev;
+
+       struct clk *clk_rx_gate;
+       struct clk *clk_rx_cmdc;
+       struct clk *clk_rx_dmac;
+       struct clk *clk_rx_cmdc_srcpll;
+       struct clk *clk_rx_dmac_srcpll;
+       struct clk *clk_tx_gate;
+       struct clk *clk_tx_cmdc;
+       struct clk *clk_tx_dmac;
+       struct clk *clk_tx_cmdc_srcpll;
+       struct clk *clk_tx_dmac_srcpll;
+
+       struct toddr *tddr;
+       struct frddr *fddr;
+
+       int irq_rx_cmdc;
+       int irq_rx_dmac;
+       int irq_tx_cmdc;
+       int irq_tx_dmac;
+
+       int sysclk_freq;
+};
+
+#define PREALLOC_BUFFER_MAX    (256 * 1024)
+
+#define EARC_RATES      (SNDRV_PCM_RATE_8000_192000)
+#define EARC_FORMATS    (SNDRV_PCM_FMTBIT_S16_LE |\
+                       SNDRV_PCM_FMTBIT_S24_LE |\
+                       SNDRV_PCM_FMTBIT_S32_LE)
+
+static const struct snd_pcm_hardware earc_hardware = {
+       .info =
+               SNDRV_PCM_INFO_MMAP |
+               SNDRV_PCM_INFO_MMAP_VALID |
+               SNDRV_PCM_INFO_INTERLEAVED |
+               SNDRV_PCM_INFO_BLOCK_TRANSFER |
+               SNDRV_PCM_INFO_PAUSE,
+
+       .formats = EARC_FORMATS,
+
+       .period_bytes_min = 64,
+       .period_bytes_max = 128 * 1024,
+       .periods_min = 2,
+       .periods_max = 1024,
+       .buffer_bytes_max = 256 * 1024,
+
+       .rate_min = 8000,
+       .rate_max = 192000,
+       .channels_min = 1,
+       .channels_max = 32,
+};
+
+static irqreturn_t earc_ddr_isr(int irq, void *devid)
+{
+       struct snd_pcm_substream *substream =
+               (struct snd_pcm_substream *)devid;
+
+       if (!snd_pcm_running(substream))
+               return IRQ_HANDLED;
+
+       snd_pcm_period_elapsed(substream);
+
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t earc_rx_cmdc_isr(int irq, void *devid)
+{
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t earc_rx_dmac_isr(int irq, void *devid)
+{
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t earc_tx_cmdc_isr(int irq, void *devid)
+{
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t earc_tx_dmac_isr(int irq, void *devid)
+{
+       return IRQ_HANDLED;
+}
+
+static int earc_open(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct device *dev = rtd->platform->dev;
+       struct earc *p_earc;
+       int ret = 0;
+
+       pr_info("asoc debug: %s-%d\n", __func__, __LINE__);
+
+       p_earc = (struct earc *)dev_get_drvdata(dev);
+
+       snd_soc_set_runtime_hwparams(substream, &earc_hardware);
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               p_earc->fddr = aml_audio_register_frddr(dev,
+                       p_earc->actrl,
+                       earc_ddr_isr, substream);
+               if (p_earc->fddr == NULL) {
+                       dev_err(dev, "failed to claim from ddr\n");
+                       return -ENXIO;
+               }
+               if (p_earc->irq_tx_cmdc > 0) {
+                       ret = request_irq(p_earc->irq_tx_cmdc,
+                                       earc_tx_cmdc_isr, 0, "tx_cmdc",
+                                       p_earc);
+                       if (ret) {
+                               dev_err(p_earc->dev, "failed to claim irq_tx_cmdc %u\n",
+                                                       p_earc->irq_tx_cmdc);
+                               return ret;
+                       }
+               }
+               if (p_earc->irq_tx_dmac > 0) {
+                       ret = request_irq(p_earc->irq_tx_dmac,
+                                       earc_tx_dmac_isr, 0, "tx_dmac",
+                                       p_earc);
+                       if (ret) {
+                               dev_err(p_earc->dev, "failed to claim irq_tx_dmac %u\n",
+                                                       p_earc->irq_tx_dmac);
+                               return ret;
+                       }
+               }
+       } else {
+               p_earc->tddr = aml_audio_register_toddr(dev,
+                       p_earc->actrl,
+                       earc_ddr_isr, substream);
+               if (p_earc->tddr == NULL) {
+                       dev_err(dev, "failed to claim to ddr\n");
+                       return -ENXIO;
+               }
+
+               ret = request_irq(p_earc->irq_rx_cmdc,
+                               earc_rx_cmdc_isr, 0, "rx_cmdc",
+                               p_earc);
+               if (ret) {
+                       dev_err(p_earc->dev, "failed to claim irq_rx_cmdc %u\n",
+                                               p_earc->irq_rx_cmdc);
+                       return ret;
+               }
+               ret = request_irq(p_earc->irq_rx_dmac,
+                               earc_rx_dmac_isr, 0, "rx_dmac",
+                               p_earc);
+               if (ret) {
+                       dev_err(p_earc->dev, "failed to claim rx_dmac %u\n",
+                                               p_earc->irq_rx_dmac);
+                       return ret;
+               }
+       }
+
+       runtime->private_data = p_earc;
+
+       return 0;
+}
+
+static int earc_close(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct earc *p_earc = runtime->private_data;
+
+       pr_info("asoc debug: %s-%d\n", __func__, __LINE__);
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               aml_audio_unregister_frddr(p_earc->dev, substream);
+
+               if (p_earc->irq_tx_cmdc > 0)
+                       free_irq(p_earc->irq_tx_cmdc, p_earc);
+
+               if (p_earc->irq_tx_dmac > 0)
+                       free_irq(p_earc->irq_tx_dmac, p_earc);
+       } else {
+               aml_audio_unregister_toddr(p_earc->dev, substream);
+               free_irq(p_earc->irq_rx_cmdc, p_earc);
+               free_irq(p_earc->irq_rx_dmac, p_earc);
+       }
+       runtime->private_data = NULL;
+
+       return 0;
+}
+
+static int earc_hw_params(struct snd_pcm_substream *substream,
+                        struct snd_pcm_hw_params *hw_params)
+{
+       return snd_pcm_lib_malloc_pages(substream,
+                       params_buffer_bytes(hw_params));
+}
+
+static int earc_hw_free(struct snd_pcm_substream *substream)
+{
+       snd_pcm_lib_free_pages(substream);
+
+       return 0;
+}
+
+static int earc_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+       return 0;
+}
+
+static int earc_prepare(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct earc *p_earc = runtime->private_data;
+       unsigned int start_addr, end_addr, int_addr;
+
+       start_addr = runtime->dma_addr;
+       end_addr = start_addr + runtime->dma_bytes - 8;
+       int_addr = frames_to_bytes(runtime, runtime->period_size) / 8;
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               struct frddr *fr = p_earc->fddr;
+
+               aml_frddr_set_buf(fr, start_addr, end_addr);
+               aml_frddr_set_intrpt(fr, int_addr);
+       } else {
+               struct toddr *to = p_earc->tddr;
+
+               aml_toddr_set_buf(to, start_addr, end_addr);
+               aml_toddr_set_intrpt(to, int_addr);
+       }
+
+       return 0;
+}
+
+static snd_pcm_uframes_t earc_pointer(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct earc *p_earc = runtime->private_data;
+       unsigned int addr, start_addr;
+       snd_pcm_uframes_t frames;
+
+       start_addr = runtime->dma_addr;
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               addr = aml_frddr_get_position(p_earc->fddr);
+       else
+               addr = aml_toddr_get_position(p_earc->tddr);
+
+       frames = bytes_to_frames(runtime, addr - start_addr);
+       if (frames > runtime->buffer_size)
+               frames = 0;
+
+       return frames;
+}
+
+int earc_silence(struct snd_pcm_substream *substream, int channel,
+                   snd_pcm_uframes_t pos, snd_pcm_uframes_t count)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       char *ppos;
+       int n;
+
+       n = frames_to_bytes(runtime, count);
+       ppos = runtime->dma_area + frames_to_bytes(runtime, pos);
+       memset(ppos, 0, n);
+
+       return 0;
+}
+
+static int earc_mmap(struct snd_pcm_substream *substream,
+                       struct vm_area_struct *vma)
+{
+       return snd_pcm_lib_default_mmap(substream, vma);
+}
+
+static struct snd_pcm_ops earc_ops = {
+       .open      = earc_open,
+       .close     = earc_close,
+       .ioctl     = snd_pcm_lib_ioctl,
+       .hw_params = earc_hw_params,
+       .hw_free   = earc_hw_free,
+       .prepare   = earc_prepare,
+       .trigger   = earc_trigger,
+       .pointer   = earc_pointer,
+       .silence   = earc_silence,
+       .mmap      = earc_mmap,
+};
+
+static int earc_new(struct snd_soc_pcm_runtime *rtd)
+{
+       return snd_pcm_lib_preallocate_pages_for_all(
+                       rtd->pcm, SNDRV_DMA_TYPE_DEV,
+                       rtd->card->snd_card->dev,
+                       PREALLOC_BUFFER_MAX,
+                       PREALLOC_BUFFER_MAX);
+}
+
+struct snd_soc_platform_driver earc_platform = {
+       .ops = &earc_ops,
+       .pcm_new = earc_new,
+};
+
+static int earc_dai_probe(struct snd_soc_dai *cpu_dai)
+{
+       pr_info("asoc debug: %s-%d\n", __func__, __LINE__);
+
+       return 0;
+}
+
+static int earc_dai_remove(struct snd_soc_dai *cpu_dai)
+{
+       return 0;
+}
+
+static int earc_dai_prepare(
+       struct snd_pcm_substream *substream,
+       struct snd_soc_dai *cpu_dai)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct earc *p_earc = snd_soc_dai_get_drvdata(cpu_dai);
+       unsigned int bit_depth = snd_pcm_format_width(runtime->format);
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               struct frddr *fr = p_earc->fddr;
+               enum frddr_dest dst = frddr_src_get();
+
+               pr_info("%s Expected frddr dst:%s\n",
+                       __func__,
+                       frddr_src_get_str(dst));
+
+               aml_frddr_select_dst(fr, dst);
+               aml_frddr_set_fifos(fr, 0x40, 0x20);
+       } else {
+               struct toddr *to = p_earc->tddr;
+               unsigned int msb = 0, lsb = 0, toddr_type = 0;
+               unsigned int src = EARCRX_DMAC;
+               struct toddr_fmt fmt;
+
+               if (bit_depth == 24)
+                       toddr_type = 4;
+               else
+                       toddr_type = 0;
+
+               pr_info("%s Expected toddr src:%s\n",
+                       __func__,
+                       toddr_src_get_str(src));
+
+               msb = bit_depth - 1;
+
+               pr_info("%s m:%d, n:%d\n", __func__, msb, lsb);
+
+               fmt.type      = toddr_type;
+               fmt.msb       = msb;
+               fmt.lsb       = lsb;
+               fmt.endian    = 0;
+               fmt.bit_depth = bit_depth;
+               fmt.ch_num    = runtime->channels;
+               fmt.rate      = runtime->rate;
+
+               aml_toddr_select_src(to, src);
+               aml_toddr_set_format(to, &fmt);
+               aml_toddr_set_fifos(to, 0x40);
+
+               earcrx_cmdc_init();
+               earcrx_dmac_init();
+               earc_arc_init();
+
+       }
+
+       return 0;
+}
+
+static int earc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
+                              struct snd_soc_dai *cpu_dai)
+{
+       struct earc *p_earc = snd_soc_dai_get_drvdata(cpu_dai);
+
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+       case SNDRV_PCM_TRIGGER_RESUME:
+       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+                       dev_info(substream->pcm->card->dev, "eARC/ARC TX enable\n");
+
+                       aml_frddr_enable(p_earc->fddr, true);
+               } else {
+                       dev_info(substream->pcm->card->dev, "eARC/ARC RX enable\n");
+
+                       aml_toddr_enable(p_earc->tddr, true);
+               }
+               break;
+       case SNDRV_PCM_TRIGGER_STOP:
+       case SNDRV_PCM_TRIGGER_SUSPEND:
+       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+                       dev_info(substream->pcm->card->dev, "eARC/ARC TX disable\n");
+
+                       aml_frddr_enable(p_earc->fddr, false);
+               } else {
+                       dev_info(substream->pcm->card->dev, "eARC/ARC RX disable\n");
+
+                       aml_toddr_enable(p_earc->tddr, false);
+               }
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int earc_dai_hw_params(
+               struct snd_pcm_substream *substream,
+               struct snd_pcm_hw_params *params,
+               struct snd_soc_dai *cpu_dai)
+{
+       struct earc *p_earc = snd_soc_dai_get_drvdata(cpu_dai);
+       unsigned int rate = params_rate(params);
+       int ret = 0;
+
+       pr_info("%s:rate:%d, sysclk:%d\n",
+               __func__,
+               rate,
+               p_earc->sysclk_freq);
+
+       return ret;
+}
+
+static int earc_dai_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
+{
+       struct earc *p_earc = snd_soc_dai_get_drvdata(cpu_dai);
+
+       pr_info("asoc earc_dai_set_fmt, %#x, %p\n", fmt, p_earc);
+
+       return 0;
+}
+
+static int earc_dai_set_sysclk(struct snd_soc_dai *cpu_dai,
+                               int clk_id, unsigned int freq, int dir)
+{
+       struct earc *p_earc = snd_soc_dai_get_drvdata(cpu_dai);
+
+       p_earc->sysclk_freq = freq;
+       pr_info("earc_dai_set_sysclk, %d, %d, %d\n",
+                       clk_id, freq, dir);
+
+       clk_set_rate(p_earc->clk_rx_cmdc, 2000000);
+       clk_set_rate(p_earc->clk_rx_dmac, 24576000);
+
+       pr_info("earc rx cmdc clk:%lu rx dmac clk:%lu\n",
+               clk_get_rate(p_earc->clk_rx_cmdc),
+               clk_get_rate(p_earc->clk_rx_dmac));
+
+       return 0;
+}
+
+static int earc_dai_startup(
+       struct snd_pcm_substream *substream,
+       struct snd_soc_dai *cpu_dai)
+{
+       struct earc *p_earc = snd_soc_dai_get_drvdata(cpu_dai);
+       int ret;
+
+       /* enable clock gate */
+       if (!IS_ERR(p_earc->clk_rx_gate)) {
+               ret = clk_prepare_enable(p_earc->clk_rx_gate);
+               if (ret) {
+                       pr_err("Can't enable earc rx_gate: %d\n", ret);
+                       goto err;
+               }
+       }
+
+       audiobus_update_bits(EE_AUDIO_CLK_GATE_EN1, 0x1 << 6, 0x1 << 6);
+
+       /* enable clock */
+       if (!IS_ERR(p_earc->clk_rx_cmdc)) {
+               ret = clk_prepare_enable(p_earc->clk_rx_cmdc);
+               if (ret) {
+                       pr_err("Can't enable earc clk_rx_cmdc: %d\n", ret);
+                       goto err;
+               }
+       }
+       if (!IS_ERR(p_earc->clk_rx_dmac)) {
+               ret = clk_prepare_enable(p_earc->clk_rx_dmac);
+               if (ret) {
+                       pr_err("Can't enable earc clk_rx_dmac: %d\n", ret);
+                       goto err;
+               }
+       }
+       if (!IS_ERR(p_earc->clk_tx_cmdc)) {
+               ret = clk_prepare_enable(p_earc->clk_tx_cmdc);
+               if (ret) {
+                       pr_err("Can't enable earc clk_tx_cmdc: %d\n", ret);
+                       goto err;
+               }
+       }
+       if (!IS_ERR(p_earc->clk_tx_dmac)) {
+               ret = clk_prepare_enable(p_earc->clk_tx_dmac);
+               if (ret) {
+                       pr_err("Can't enable earc clk_tx_dmac: %d\n", ret);
+                       goto err;
+               }
+       }
+
+       return 0;
+err:
+       pr_err("failed enable clock\n");
+       return -EINVAL;
+}
+
+
+static void earc_dai_shutdown(
+       struct snd_pcm_substream *substream,
+       struct snd_soc_dai *cpu_dai)
+{
+       struct earc *p_earc = snd_soc_dai_get_drvdata(cpu_dai);
+
+       /* disable clock and gate */
+       if (!IS_ERR(p_earc->clk_rx_cmdc))
+               clk_disable_unprepare(p_earc->clk_rx_cmdc);
+       if (!IS_ERR(p_earc->clk_rx_dmac))
+               clk_disable_unprepare(p_earc->clk_rx_dmac);
+       if (!IS_ERR(p_earc->clk_tx_cmdc))
+               clk_disable_unprepare(p_earc->clk_tx_cmdc);
+       if (!IS_ERR(p_earc->clk_tx_dmac))
+               clk_disable_unprepare(p_earc->clk_tx_dmac);
+       if (!IS_ERR(p_earc->clk_rx_gate))
+               clk_disable_unprepare(p_earc->clk_rx_gate);
+
+       audiobus_update_bits(EE_AUDIO_CLK_GATE_EN1, 0x1 << 6, 0x0 << 6);
+}
+
+static struct snd_soc_dai_ops earc_dai_ops = {
+       .prepare    = earc_dai_prepare,
+       .trigger    = earc_dai_trigger,
+       .hw_params  = earc_dai_hw_params,
+       .set_fmt    = earc_dai_set_fmt,
+       .set_sysclk = earc_dai_set_sysclk,
+       .startup        = earc_dai_startup,
+       .shutdown       = earc_dai_shutdown,
+};
+
+static struct snd_soc_dai_driver earc_dai[] = {
+       {
+               .name     = "EARC/ARC",
+               .id       = 0,
+               .probe    = earc_dai_probe,
+               .remove   = earc_dai_remove,
+               .playback = {
+                     .channels_min = 1,
+                     .channels_max = 32,
+                     .rates        = EARC_RATES,
+                     .formats      = EARC_FORMATS,
+               },
+               .capture = {
+                    .channels_min = 1,
+                    .channels_max = 32,
+                    .rates        = EARC_RATES,
+                    .formats      = EARC_FORMATS,
+               },
+               .ops    = &earc_dai_ops,
+       },
+};
+
+static const struct snd_kcontrol_new earc_controls[] = {
+
+
+};
+
+static const struct snd_soc_component_driver earc_component = {
+       .controls       = earc_controls,
+       .num_controls   = ARRAY_SIZE(earc_controls),
+       .name           = DRV_NAME,
+};
+
+static const struct of_device_id earc_device_id[] = {
+       {
+               .compatible = "amlogic, sm1-snd-earc",
+       },
+       {},
+};
+
+MODULE_DEVICE_TABLE(of, earc_device_id);
+
+static int earc_platform_probe(struct platform_device *pdev)
+{
+       struct device_node *node = pdev->dev.of_node;
+       struct device_node *node_prt = NULL;
+       struct platform_device *pdev_parent;
+       struct device *dev = &pdev->dev;
+       struct aml_audio_controller *actrl = NULL;
+       struct earc *p_earc = NULL;
+       int ret = 0;
+
+
+       p_earc = devm_kzalloc(dev, sizeof(struct earc), GFP_KERNEL);
+       if (!p_earc)
+               return -ENOMEM;
+
+       p_earc->dev = dev;
+       dev_set_drvdata(dev, p_earc);
+
+       /* get audio controller */
+       node_prt = of_get_parent(node);
+       if (node_prt == NULL)
+               return -ENXIO;
+
+       pdev_parent = of_find_device_by_node(node_prt);
+       of_node_put(node_prt);
+       actrl = (struct aml_audio_controller *)
+                       platform_get_drvdata(pdev_parent);
+       p_earc->actrl = actrl;
+
+       /* clock gate */
+       p_earc->clk_rx_gate = devm_clk_get(&pdev->dev, "rx_gate");
+       if (IS_ERR(p_earc->clk_rx_gate)) {
+               dev_err(&pdev->dev,
+                       "Can't get earc gate\n");
+               return PTR_ERR(p_earc->clk_rx_gate);
+       }
+       /* RX */
+       p_earc->clk_rx_cmdc = devm_clk_get(&pdev->dev, "rx_cmdc");
+       if (IS_ERR(p_earc->clk_rx_cmdc)) {
+               dev_err(&pdev->dev,
+                       "Can't get clk_rx_cmdc\n");
+               return PTR_ERR(p_earc->clk_rx_cmdc);
+       }
+       p_earc->clk_rx_dmac = devm_clk_get(&pdev->dev, "rx_dmac");
+       if (IS_ERR(p_earc->clk_rx_dmac)) {
+               dev_err(&pdev->dev,
+                       "Can't get clk_rx_dmac\n");
+               return PTR_ERR(p_earc->clk_rx_dmac);
+       }
+       p_earc->clk_rx_cmdc_srcpll = devm_clk_get(&pdev->dev, "rx_cmdc_srcpll");
+       if (IS_ERR(p_earc->clk_rx_cmdc_srcpll)) {
+               dev_err(&pdev->dev,
+                       "Can't get clk_rx_cmdc_srcpll\n");
+               return PTR_ERR(p_earc->clk_rx_cmdc_srcpll);
+       }
+       p_earc->clk_rx_dmac_srcpll = devm_clk_get(&pdev->dev, "rx_dmac_srcpll");
+       if (IS_ERR(p_earc->clk_rx_dmac_srcpll)) {
+               dev_err(&pdev->dev,
+                       "Can't get clk_rx_dmac_srcpll\n");
+               return PTR_ERR(p_earc->clk_rx_dmac_srcpll);
+       }
+       ret = clk_set_parent(p_earc->clk_rx_cmdc, p_earc->clk_rx_cmdc_srcpll);
+       if (ret) {
+               dev_err(dev,
+                       "Can't set clk_rx_cmdc parent clock\n");
+               ret = PTR_ERR(p_earc->clk_rx_cmdc);
+               return ret;
+       }
+       ret = clk_set_parent(p_earc->clk_rx_dmac, p_earc->clk_rx_dmac_srcpll);
+       if (ret) {
+               dev_err(dev,
+                       "Can't set clk_rx_dmac parent clock\n");
+               ret = PTR_ERR(p_earc->clk_rx_dmac);
+               return ret;
+       }
+
+       /* TX */
+       p_earc->clk_tx_cmdc = devm_clk_get(&pdev->dev, "tx_cmdc");
+       if (IS_ERR(p_earc->clk_tx_cmdc)) {
+               dev_err(&pdev->dev,
+                       "Check whether support eARC TX\n");
+       }
+       p_earc->clk_tx_dmac = devm_clk_get(&pdev->dev, "tx_dmac");
+       if (IS_ERR(p_earc->clk_tx_dmac)) {
+               dev_err(&pdev->dev,
+                       "Check whether support eARC TX\n");
+       }
+       p_earc->clk_tx_cmdc_srcpll = devm_clk_get(&pdev->dev, "tx_cmdc_srcpll");
+       if (IS_ERR(p_earc->clk_tx_cmdc_srcpll)) {
+               dev_err(&pdev->dev,
+                       "Check whether support eARC TX\n");
+       }
+       p_earc->clk_tx_dmac_srcpll = devm_clk_get(&pdev->dev, "tx_dmac_srcpll");
+       if (IS_ERR(p_earc->clk_tx_dmac_srcpll)) {
+               dev_err(&pdev->dev,
+                       "Check whether support eARC TX\n");
+       }
+       if (!IS_ERR(p_earc->clk_tx_cmdc) &&
+               !IS_ERR(p_earc->clk_tx_cmdc_srcpll)) {
+               ret = clk_set_parent(p_earc->clk_tx_cmdc,
+                               p_earc->clk_tx_cmdc_srcpll);
+               if (ret) {
+                       dev_err(dev,
+                               "Can't set clk_tx_cmdc parent clock\n");
+                       ret = PTR_ERR(p_earc->clk_tx_cmdc);
+                       return ret;
+               }
+       }
+       if (!IS_ERR(p_earc->clk_tx_dmac) &&
+               !IS_ERR(p_earc->clk_tx_dmac_srcpll)) {
+               ret = clk_set_parent(p_earc->clk_tx_dmac,
+                               p_earc->clk_tx_dmac_srcpll);
+               if (ret) {
+                       dev_err(dev,
+                               "Can't set clk_tx_dmac parent clock\n");
+                       ret = PTR_ERR(p_earc->clk_tx_dmac);
+                       return ret;
+               }
+       }
+
+       /* irqs */
+       p_earc->irq_rx_cmdc =
+               platform_get_irq_byname(pdev, "rx_cmdc");
+       if (p_earc->irq_rx_cmdc < 0) {
+               dev_err(dev, "platform get irq rx_cmdc failed\n");
+               return p_earc->irq_rx_cmdc;
+       }
+       p_earc->irq_rx_dmac =
+               platform_get_irq_byname(pdev, "rx_dmac");
+       if (p_earc->irq_rx_dmac < 0) {
+               dev_err(dev, "platform get irq rx_dmac failed\n");
+               return p_earc->irq_rx_dmac;
+       }
+       p_earc->irq_tx_cmdc =
+               platform_get_irq_byname(pdev, "tx_cmdc");
+       if (p_earc->irq_tx_cmdc < 0)
+               dev_err(dev, "platform get irq tx_cmdc failed, Check whether support eARC TX\n");
+       p_earc->irq_tx_dmac =
+               platform_get_irq_byname(pdev, "tx_dmac");
+       if (p_earc->irq_tx_dmac < 0)
+               dev_err(dev, "platform get irq tx_dmac failed, Check whether support eARC TX\n");
+
+       ret = snd_soc_register_component(&pdev->dev,
+                               &earc_component,
+                               earc_dai,
+                               ARRAY_SIZE(earc_dai));
+       if (ret) {
+               dev_err(&pdev->dev,
+                       "snd_soc_register_component failed\n");
+               return ret;
+       }
+
+       pr_info("%s, register soc platform\n", __func__);
+
+       return devm_snd_soc_register_platform(dev, &earc_platform);
+}
+
+struct platform_driver earc_driver = {
+       .driver = {
+               .name           = DRV_NAME,
+               .of_match_table = earc_device_id,
+       },
+       .probe = earc_platform_probe,
+};
+module_platform_driver(earc_driver);
+
+MODULE_AUTHOR("Amlogic, Inc.");
+MODULE_DESCRIPTION("Amlogic eARC/ARC TX/RX ASoc driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("Platform:" DRV_NAME);
+MODULE_DEVICE_TABLE(of, earc_device_id);
diff --git a/sound/soc/amlogic/auge/earc_hw.c b/sound/soc/amlogic/auge/earc_hw.c
new file mode 100644 (file)
index 0000000..2974d4e
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * sound/soc/amlogic/auge/earc_hw.c
+ *
+ * Copyright (C) 2019 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+#include <linux/types.h>
+
+#include "earc_hw.h"
+
+
+void earcrx_cmdc_init(void)
+{
+       /* set irq mask */
+       earcrx_top_write(EARCRX_CMDC_INT_MASK,
+               (0 << 15) |  /* idle2_int */
+               (0 << 14) |  /* idle1_int */
+               (0 << 13) |  /* disc2_int */
+               (0 << 12) |  /* disc1_int */
+               (0 << 11) |  /* earc_int */
+               (1 << 10) |  /* hb_status_int */
+               (0 <<  9) |  /* losthb_int */
+               (0 <<  8) |  /* timeout_int */
+               (0 <<  7) |  /* status_ch_int */
+               (0 <<  6) |  /* int_rec_invalid_id */
+               (0 <<  5) |  /* int_rec_invalid_offset */
+               (0 <<  4) |  /* int_rec_unexp */
+               (0 <<  3) |  /* int_rec_ecc_err */
+               (0 <<  2) |  /* int_rec_parity_err */
+               (0 <<  1) |  /* int_recv_packet */
+               (0 <<  0)         /* int_rec_time_out */
+               );
+}
+
+void earcrx_dmac_init(void)
+{
+       earcrx_dmac_write(EARCRX_DMAC_TOP_CTRL0, 1 << 31); /* reg_top_work_en */
+       earcrx_dmac_write(EARCRX_DMAC_SYNC_CTRL0,
+               (1 << 31)       |        /* reg_work_en */
+               (1 << 30)       |        /* reg_rst_afifo_out_n */
+               (1 << 29)       |        /* reg_rst_afifo_in_n */
+               (1 << 16)       |        /* reg_ana_buf_data_sel_en */
+               (3 << 12)       |        /* reg_ana_buf_data_sel */
+               (7 << 8)        |        /* reg_ana_clr_cnt */
+               (7 << 4)                 /* reg_ana_set_cnt */
+               );
+       earcrx_dmac_write(EARCRX_ERR_CORRECT_CTRL0,
+               (1 << 29) | /* reg_rst_afifo_out_n */
+               (1 << 28)       /* reg_rst_afifo_in_n */
+               );
+       earcrx_dmac_write(EARCRX_DMAC_UBIT_CTRL0,
+               (1 << 31)  | /* reg_work_enable */
+               (47 << 16) | /* reg_fifo_thd */
+               (1 << 12)  | /* reg_user_lr */
+               (29 << 0)       /* reg_data_bit */
+               );
+       earcrx_dmac_write(EARCRX_ANA_RST_CTRL0, 1 << 31);
+       earcrx_dmac_write(EARCRX_ERR_CORRECT_CTRL0, 1 << 31); /* reg_work_en */
+}
+
+void earc_arc_init(void)
+{
+       earcrx_dmac_write(EARCRX_SPDIFIN_CTRL0,
+               (1 << 31) | /* reg_work_en */
+               (1 << 30) | /* reg_chnum_sel */
+               (1 << 25) | /* reg_findpapb_en */
+               (0xFFF<<12) /* reg_nonpcm2pcm_th */
+               );
+       earcrx_dmac_write(EARCRX_SPDIFIN_CTRL2,
+               (1 << 14) | /* reg_earc_auto */
+               (1 << 13)  /* reg_earcin_papb_lr */
+               );
+       earcrx_dmac_write(EARCRX_SPDIFIN_CTRL3,
+               (0xEC37<<16) | /* reg_earc_pa_value */
+               (0x5A5A<<0)    /* reg_earc_pb_value */
+               );
+}
diff --git a/sound/soc/amlogic/auge/earc_hw.h b/sound/soc/amlogic/auge/earc_hw.h
new file mode 100644 (file)
index 0000000..aeb0107
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * sound/soc/amlogic/auge/earc_hw.h
+ *
+ * Copyright (C) 2019 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+#ifndef __EARC_HW_H__
+#define __EARC_HW_H__
+
+#include "regs.h"
+#include "iomap.h"
+
+extern void earcrx_cmdc_init(void);
+extern void earcrx_dmac_init(void);
+extern void earc_arc_init(void);
+#endif
index 58bef78..e196591 100644 (file)
@@ -231,6 +231,87 @@ void vad_update_bits(unsigned int reg,
 }
 EXPORT_SYMBOL(vad_update_bits);
 
+int earcrx_cmdc_read(unsigned int reg)
+{
+       int ret, val = 0;
+
+       ret = aml_snd_read(IO_EARCRX_CMDC, reg, &val);
+
+       if (ret) {
+               pr_err("read audio reg %x error %d\n", reg, ret);
+               return -1;
+       }
+       return val;
+}
+EXPORT_SYMBOL(earcrx_cmdc_read);
+
+void earcrx_cmdc_write(unsigned int reg, unsigned int val)
+{
+       aml_snd_write(IO_EARCRX_CMDC, reg, val);
+}
+EXPORT_SYMBOL(earcrx_cmdc_write);
+
+void earcrx_cmdc_update_bits(unsigned int reg,
+               unsigned int mask, unsigned int val)
+{
+       aml_snd_update_bits(IO_EARCRX_CMDC, reg, mask, val);
+}
+EXPORT_SYMBOL(earcrx_cmdc_update_bits);
+
+int earcrx_dmac_read(unsigned int reg)
+{
+       int ret, val = 0;
+
+       ret = aml_snd_read(IO_EARCRX_DMAC, reg, &val);
+
+       if (ret) {
+               pr_err("read audio reg %x error %d\n", reg, ret);
+               return -1;
+       }
+       return val;
+}
+EXPORT_SYMBOL(earcrx_dmac_read);
+
+void earcrx_dmac_write(unsigned int reg, unsigned int val)
+{
+       aml_snd_write(IO_EARCRX_DMAC, reg, val);
+}
+EXPORT_SYMBOL(earcrx_dmac_write);
+
+void earcrx_dmac_update_bits(unsigned int reg,
+               unsigned int mask, unsigned int val)
+{
+       aml_snd_update_bits(IO_EARCRX_DMAC, reg, mask, val);
+}
+EXPORT_SYMBOL(earcrx_dmac_update_bits);
+
+int earcrx_top_read(unsigned int reg)
+{
+       int ret, val = 0;
+
+       ret = aml_snd_read(IO_EARCRX_TOP, reg, &val);
+
+       if (ret) {
+               pr_err("read audio reg %x error %d\n", reg, ret);
+               return -1;
+       }
+       return val;
+}
+EXPORT_SYMBOL(earcrx_top_read);
+
+void earcrx_top_write(unsigned int reg, unsigned int val)
+{
+       aml_snd_write(IO_EARCRX_TOP, reg, val);
+}
+EXPORT_SYMBOL(earcrx_top_write);
+
+void earcrx_top_update_bits(unsigned int reg,
+               unsigned int mask, unsigned int val)
+{
+       aml_snd_update_bits(IO_EARCRX_TOP, reg, mask, val);
+}
+EXPORT_SYMBOL(earcrx_top_update_bits);
+
 static int snd_iomap_probe(struct platform_device *pdev)
 {
        struct resource res;
index ae3c928..07b8b54 100644 (file)
@@ -25,6 +25,9 @@ enum{
        IO_EQDRC_BUS,
        IO_RESET,
        IO_VAD,
+       IO_EARCRX_CMDC,
+       IO_EARCRX_DMAC,
+       IO_EARCRX_TOP,
 
        IO_MAX,
 };
@@ -58,4 +61,17 @@ extern int vad_read(unsigned int reg);
 extern void vad_write(unsigned int reg, unsigned int val);
 extern void vad_update_bits(unsigned int reg,
                unsigned int mask, unsigned int val);
+
+extern int earcrx_cmdc_read(unsigned int reg);
+extern void earcrx_cmdc_write(unsigned int reg, unsigned int val);
+extern void earcrx_cmdc_update_bits(unsigned int reg,
+               unsigned int mask, unsigned int val);
+extern int earcrx_dmac_read(unsigned int reg);
+extern void earcrx_dmac_write(unsigned int reg, unsigned int val);
+extern void earcrx_dmac_update_bits(unsigned int reg,
+               unsigned int mask, unsigned int val);
+extern int earcrx_top_read(unsigned int reg);
+extern void earcrx_top_write(unsigned int reg, unsigned int val);
+extern void earcrx_top_update_bits(unsigned int reg,
+               unsigned int mask, unsigned int val);
 #endif
index 6e4538c..15144b9 100644 (file)
@@ -71,8 +71,8 @@ void datalb_ctrl(struct loopback_cfg *lb_cfg)
 
        if (id >= 0 && id <= 2) {
                /* tdmout_a, tdmout_b, tdmout_c */
-               reg_base = EE_AUDIO_TDMOUT_A_SWAP;
-               offset = EE_AUDIO_TDMOUT_B_SWAP - EE_AUDIO_TDMOUT_A_SWAP;
+               reg_base = EE_AUDIO_TDMOUT_A_SWAP0;
+               offset = EE_AUDIO_TDMOUT_B_SWAP0 - EE_AUDIO_TDMOUT_A_SWAP0;
        } else if (id < 6) {
                /*lb_cfg->datalb_src for pad tdm in,
                 *pad from tdmin_a, tdmin_b, tdmin_c
@@ -115,8 +115,8 @@ void datalb_ctrl(struct loopback_cfg *lb_cfg)
                audiobus_write(
                        reg,
                        lb_cfg->datalb_chmask);
-               reg_base = EE_AUDIO_TDMIN_A_SWAP;
-               offset = EE_AUDIO_TDMIN_B_SWAP - EE_AUDIO_TDMIN_A_SWAP;
+               reg_base = EE_AUDIO_TDMIN_A_SWAP0;
+               offset = EE_AUDIO_TDMIN_B_SWAP0 - EE_AUDIO_TDMIN_A_SWAP0;
        } else {
                pr_err("unsupport datalb_src\n");
                return;
@@ -124,7 +124,7 @@ void datalb_ctrl(struct loopback_cfg *lb_cfg)
 
        if (lb_cfg->datain_datalb_total > 8) {
                audiobus_write(
-                               EE_AUDIO_TDMIN_LB_SWAP,
+                               EE_AUDIO_TDMIN_LB_SWAP0,
                                lb_cfg->datalb_chswap);
 
                audiobus_write(EE_AUDIO_TDMIN_LB_MASK0, 3);
@@ -134,7 +134,7 @@ void datalb_ctrl(struct loopback_cfg *lb_cfg)
        } else {
                /*swap same as tdmout */
                reg = reg_base + offset * id;
-               audiobus_write(EE_AUDIO_TDMIN_LB_SWAP,
+               audiobus_write(EE_AUDIO_TDMIN_LB_SWAP0,
                                audiobus_read(reg));
 
                /*mask same as datalb*/
index 717289e..744bc97 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "pdm.h"
 #include "pdm_hw.h"
+#include "pdm_match_table.c"
 #include "audio_io.h"
 #include "iomap.h"
 #include "regs.h"
@@ -166,6 +167,46 @@ static int pdm_dclk_set_enum(
        return 0;
 }
 
+static const char *const pdm_train_texts[] = {
+       "Disabled",
+       "Enable",
+};
+
+static const struct soc_enum pdm_train_enum =
+       SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(pdm_train_texts),
+                       pdm_train_texts);
+
+static int pdm_train_get_enum(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+       struct aml_pdm *p_pdm = snd_soc_dai_get_drvdata(cpu_dai);
+
+       ucontrol->value.enumerated.item[0] = p_pdm->train_en;
+
+       return 0;
+}
+
+static int pdm_train_set_enum(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+       struct aml_pdm *p_pdm = snd_soc_dai_get_drvdata(cpu_dai);
+
+       if (!p_pdm->chipinfo ||
+               !p_pdm->chipinfo->train ||
+               (p_pdm->train_en == ucontrol->value.enumerated.item[0]))
+               return 0;
+
+       p_pdm->train_en = ucontrol->value.enumerated.item[0];
+
+       if (p_pdm->clk_on)
+               pdm_train_en(p_pdm->train_en);
+
+       return 0;
+}
 
 static const struct snd_kcontrol_new snd_pdm_controls[] = {
        /* which set */
@@ -184,7 +225,13 @@ static const struct snd_kcontrol_new snd_pdm_controls[] = {
                     pdm_dclk_enum,
                     pdm_dclk_get_enum,
                     pdm_dclk_set_enum),
+
+       SOC_ENUM_EXT("PDM Train",
+                    pdm_train_enum,
+                    pdm_train_get_enum,
+                    pdm_train_set_enum),
 };
+
 #if 0
 static int pdm_mute_val_info(struct snd_kcontrol *kcontrol,
                struct snd_ctl_elem_info *uinfo)
@@ -332,11 +379,19 @@ static irqreturn_t aml_pdm_isr_handler(int irq, void *data)
 {
        struct snd_pcm_substream *substream =
                (struct snd_pcm_substream *)data;
+       int train_sts = pdm_train_sts();
 
        pr_debug("%s\n", __func__);
 
        snd_pcm_period_elapsed(substream);
 
+       if (train_sts) {
+               pr_debug("%s train result:0x%x\n",
+                       __func__,
+                       train_sts);
+               pdm_train_clr();
+       }
+
        return IRQ_HANDLED;
 }
 
@@ -842,6 +897,9 @@ int aml_pdm_dai_startup(struct snd_pcm_substream *substream,
                pdm_running_create_controls(card, p_pdm);
        }
 #endif
+
+       p_pdm->clk_on = true;
+
        return 0;
 err:
        pr_err("failed enable clock\n");
@@ -860,6 +918,8 @@ void aml_pdm_dai_shutdown(struct snd_pcm_substream *substream,
        }
 #endif
 
+       p_pdm->clk_on = false;
+
        /* disable clock and gate */
        clk_disable_unprepare(p_pdm->clk_pdm_dclk);
        clk_disable_unprepare(p_pdm->clk_pdm_sysclk);
@@ -897,32 +957,6 @@ static const struct snd_soc_component_driver aml_pdm_component = {
        .name = DRV_NAME,
 };
 
-static struct pdm_chipinfo g12a_pdm_chipinfo = {
-       .mute_fn         = true,
-       .truncate_data   = false,
-};
-
-static struct pdm_chipinfo tl1_pdm_chipinfo = {
-       .mute_fn         = true,
-       .truncate_data   = false,
-};
-
-static const struct of_device_id aml_pdm_device_id[] = {
-       {
-               .compatible = "amlogic, axg-snd-pdm",
-       },
-       {
-               .compatible = "amlogic, g12a-snd-pdm",
-               .data       = &g12a_pdm_chipinfo,
-       },
-       {
-               .compatible = "amlogic, tl1-snd-pdm",
-               .data       = &tl1_pdm_chipinfo,
-       },
-       {}
-};
-MODULE_DEVICE_TABLE(of, aml_pdm_device_id);
-
 static int snd_soc_of_get_slot_mask(
        struct device_node *np,
        const char *prop_name,
index 43100b8..39bf6ab 100644 (file)
@@ -54,6 +54,8 @@ struct pdm_chipinfo {
        bool mute_fn;
        /* truncate invalid data when filter init */
        bool truncate_data;
+       /* train */
+       bool train;
 };
 
 struct aml_pdm {
@@ -78,12 +80,16 @@ struct aml_pdm {
        int dclk_idx;
        /* PCM or Raw Data */
        int bypass;
-       /* PDM clk on/off */
-       bool clk_on;
 
        /* lane mask in, each lane carries two channels */
        int lane_mask_in;
 
+       /* PDM clk on/off, only clk on, pdm registers can be accessed */
+       bool clk_on;
+
+       /* train */
+       bool train_en;
+
        struct pdm_chipinfo *chipinfo;
        struct snd_kcontrol *controls[PDM_RUN_MAX];
 };
index d814c04..1b4d2e1 100644 (file)
@@ -487,3 +487,24 @@ void pdm_init_truncate_data(int freq)
 
        aml_pdm_write(PDM_MASK_NUM, mask_val);
 }
+
+void pdm_train_en(bool en)
+{
+       aml_pdm_update_bits(PDM_CTRL,
+               0x1 << 19,
+               en << 19);
+}
+
+void pdm_train_clr(void)
+{
+       aml_pdm_update_bits(PDM_CTRL,
+               0x1 << 18,
+               0x1 << 18);
+}
+
+int pdm_train_sts(void)
+{
+       int val = aml_pdm_read(PDM_STS);
+
+       return ((val >> 4) & 0xff);
+}
index b7ad473..b1d8424 100644 (file)
@@ -50,6 +50,10 @@ extern void pdm_set_mute_channel(int mute_chmask);
 
 extern void pdm_init_truncate_data(int freq);
 
+extern void pdm_train_en(bool en);
+extern void pdm_train_clr(void);
+extern int pdm_train_sts(void);
+
 extern int pdm_hcic_shift_gain;
 extern int pdm_dclk;
 
diff --git a/sound/soc/amlogic/auge/pdm_match_table.c b/sound/soc/amlogic/auge/pdm_match_table.c
new file mode 100644 (file)
index 0000000..850b509
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * sound/soc/amlogic/auge/pdm_match_table.c
+ *
+ * Copyright (C) 2019 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+static struct pdm_chipinfo g12a_pdm_chipinfo = {
+       .mute_fn         = true,
+       .truncate_data   = false,
+};
+
+static struct pdm_chipinfo tl1_pdm_chipinfo = {
+       .mute_fn         = true,
+       .truncate_data   = false,
+};
+
+static struct pdm_chipinfo sm1_pdm_chipinfo = {
+       .mute_fn         = true,
+       .truncate_data   = false,
+       .train           = true,
+};
+
+static const struct of_device_id aml_pdm_device_id[] = {
+       {
+               .compatible = "amlogic, axg-snd-pdm",
+       },
+       {
+               .compatible = "amlogic, g12a-snd-pdm",
+               .data       = &g12a_pdm_chipinfo,
+       },
+       {
+               .compatible = "amlogic, tl1-snd-pdm",
+               .data       = &tl1_pdm_chipinfo,
+       },
+       {
+               .compatible = "amlogic, sm1-snd-pdm",
+               .data           = &sm1_pdm_chipinfo,
+       },
+
+       {}
+};
+MODULE_DEVICE_TABLE(of, aml_pdm_device_id);
index 7bf3d4e..2a97ec1 100644 (file)
@@ -108,6 +108,10 @@ enum clk_sel {
 #define EE_AUDIO_CLK_SPDIFIN_LB_CTRL       0x02f
 #define EE_AUDIO_CLK_EQDRC_CTRL0           0x030
 #define EE_AUDIO_VAD_CLK_CTRL              0x031
+#define EE_AUDIO_EARCTX_CMDC_CLK_CTRL      0x032
+#define EE_AUDIO_EARCTX_DMAC_CLK_CTRL      0x033
+#define EE_AUDIO_EARCRX_CMDC_CLK_CTRL      0x034
+#define EE_AUDIO_EARCRX_DMAC_CLK_CTRL      0x035
 
 /*
  *     AUDIO TODDR
@@ -204,56 +208,93 @@ enum clk_sel {
 #define EE_AUDIO_LB_STS                    0x0b6
 
 #define EE_AUDIO_TDMIN_A_CTRL              0x0c0
-#define EE_AUDIO_TDMIN_A_SWAP              0x0c1
+#define EE_AUDIO_TDMIN_A_SWAP0             0x0c1
+#define EE_AUDIO_TDMIN_A_SWAP1             0x260
 #define EE_AUDIO_TDMIN_A_MASK0             0x0c2
 #define EE_AUDIO_TDMIN_A_MASK1             0x0c3
 #define EE_AUDIO_TDMIN_A_MASK2             0x0c4
 #define EE_AUDIO_TDMIN_A_MASK3             0x0c5
+#define EE_AUDIO_TDMIN_A_MASK4             0x261
+#define EE_AUDIO_TDMIN_A_MASK5             0x262
+#define EE_AUDIO_TDMIN_A_MASK6             0x263
+#define EE_AUDIO_TDMIN_A_MASK7             0x264
 #define EE_AUDIO_TDMIN_A_STAT              0x0c6
 #define EE_AUDIO_TDMIN_A_MUTE_VAL          0x0c7
 #define EE_AUDIO_TDMIN_A_MUTE0             0x0c8
 #define EE_AUDIO_TDMIN_A_MUTE1             0x0c9
 #define EE_AUDIO_TDMIN_A_MUTE2             0x0ca
 #define EE_AUDIO_TDMIN_A_MUTE3             0x0cb
+#define EE_AUDIO_TDMIN_A_MUTE4             0x265
+#define EE_AUDIO_TDMIN_A_MUTE5             0x266
+#define EE_AUDIO_TDMIN_A_MUTE6             0x267
+#define EE_AUDIO_TDMIN_A_MUTE7             0x268
 
 #define EE_AUDIO_TDMIN_B_CTRL              0x0d0
-#define EE_AUDIO_TDMIN_B_SWAP              0x0d1
+#define EE_AUDIO_TDMIN_B_SWAP0             0x0d1
+#define EE_AUDIO_TDMIN_B_SWAP1             0x270
 #define EE_AUDIO_TDMIN_B_MASK0             0x0d2
 #define EE_AUDIO_TDMIN_B_MASK1             0x0d3
 #define EE_AUDIO_TDMIN_B_MASK2             0x0d4
 #define EE_AUDIO_TDMIN_B_MASK3             0x0d5
+#define EE_AUDIO_TDMIN_B_MASK4             0x271
+#define EE_AUDIO_TDMIN_B_MASK5             0x272
+#define EE_AUDIO_TDMIN_B_MASK6             0x273
+#define EE_AUDIO_TDMIN_B_MASK7             0x274
 #define EE_AUDIO_TDMIN_B_STAT              0x0d6
 #define EE_AUDIO_TDMIN_B_MUTE_VAL          0x0d7
 #define EE_AUDIO_TDMIN_B_MUTE0             0x0d8
 #define EE_AUDIO_TDMIN_B_MUTE1             0x0d9
 #define EE_AUDIO_TDMIN_B_MUTE2             0x0da
 #define EE_AUDIO_TDMIN_B_MUTE3             0x0db
+#define EE_AUDIO_TDMIN_B_MUTE4             0x275
+#define EE_AUDIO_TDMIN_B_MUTE5             0x276
+#define EE_AUDIO_TDMIN_B_MUTE6             0x277
+#define EE_AUDIO_TDMIN_B_MUTE7             0x278
 
 #define EE_AUDIO_TDMIN_C_CTRL              0x0e0
+#define EE_AUDIO_TDMIN_C_SWAP0             0x0e1
+#define EE_AUDIO_TDMIN_C_SWAP1             0x280
 #define EE_AUDIO_TDMIN_C_SWAP              0x0e1
 #define EE_AUDIO_TDMIN_C_MASK0             0x0e2
 #define EE_AUDIO_TDMIN_C_MASK1             0x0e3
 #define EE_AUDIO_TDMIN_C_MASK2             0x0e4
 #define EE_AUDIO_TDMIN_C_MASK3             0x0e5
+#define EE_AUDIO_TDMIN_C_MASK4             0x281
+#define EE_AUDIO_TDMIN_C_MASK5             0x282
+#define EE_AUDIO_TDMIN_C_MASK6             0x283
+#define EE_AUDIO_TDMIN_C_MASK7             0x284
 #define EE_AUDIO_TDMIN_C_STAT              0x0e6
 #define EE_AUDIO_TDMIN_C_MUTE_VAL          0x0e7
 #define EE_AUDIO_TDMIN_C_MUTE0             0x0e8
 #define EE_AUDIO_TDMIN_C_MUTE1             0x0e9
 #define EE_AUDIO_TDMIN_C_MUTE2             0x0ea
 #define EE_AUDIO_TDMIN_C_MUTE3             0x0eb
+#define EE_AUDIO_TDMIN_C_MUTE4             0x285
+#define EE_AUDIO_TDMIN_C_MUTE5             0x286
+#define EE_AUDIO_TDMIN_C_MUTE6             0x287
+#define EE_AUDIO_TDMIN_C_MUTE7             0x288
 
 #define EE_AUDIO_TDMIN_LB_CTRL             0x0f0
-#define EE_AUDIO_TDMIN_LB_SWAP             0x0f1
+#define EE_AUDIO_TDMIN_LB_SWAP0            0x0f1
+#define EE_AUDIO_TDMIN_LB_SWAP1            0x290
 #define EE_AUDIO_TDMIN_LB_MASK0            0x0f2
 #define EE_AUDIO_TDMIN_LB_MASK1            0x0f3
 #define EE_AUDIO_TDMIN_LB_MASK2            0x0f4
 #define EE_AUDIO_TDMIN_LB_MASK3            0x0f5
+#define EE_AUDIO_TDMIN_LB_MASK4            0x291
+#define EE_AUDIO_TDMIN_LB_MASK5            0x292
+#define EE_AUDIO_TDMIN_LB_MASK6            0x293
+#define EE_AUDIO_TDMIN_LB_MASK7            0x294
 #define EE_AUDIO_TDMIN_LB_STAT             0x0f6
 #define EE_AUDIO_TDMIN_LB_MUTE_VAL         0x0f7
 #define EE_AUDIO_TDMIN_LB_MUTE0            0x0f8
 #define EE_AUDIO_TDMIN_LB_MUTE1            0x0f9
 #define EE_AUDIO_TDMIN_LB_MUTE2            0x0fa
 #define EE_AUDIO_TDMIN_LB_MUTE3            0x0fb
+#define EE_AUDIO_TDMIN_LB_MUTE4            0x295
+#define EE_AUDIO_TDMIN_LB_MUTE5            0x296
+#define EE_AUDIO_TDMIN_LB_MUTE6            0x297
+#define EE_AUDIO_TDMIN_LB_MUTE7            0x298
 
 /*
  *     AUDIO OUTPUT
@@ -315,53 +356,89 @@ enum clk_sel {
 
 #define EE_AUDIO_TDMOUT_A_CTRL0            0x140
 #define EE_AUDIO_TDMOUT_A_CTRL1            0x141
-#define EE_AUDIO_TDMOUT_A_SWAP             0x142
+#define EE_AUDIO_TDMOUT_A_CTRL2            0x2a0
+#define EE_AUDIO_TDMOUT_A_SWAP0            0x142
+#define EE_AUDIO_TDMOUT_A_SWAP1            0x2a1
 #define EE_AUDIO_TDMOUT_A_MASK0            0x143
 #define EE_AUDIO_TDMOUT_A_MASK1            0x144
 #define EE_AUDIO_TDMOUT_A_MASK2            0x145
 #define EE_AUDIO_TDMOUT_A_MASK3            0x146
+#define EE_AUDIO_TDMOUT_A_MASK4            0x2a4
+#define EE_AUDIO_TDMOUT_A_MASK5            0x2a5
+#define EE_AUDIO_TDMOUT_A_MASK6            0x2a6
+#define EE_AUDIO_TDMOUT_A_MASK7            0x2a7
 #define EE_AUDIO_TDMOUT_A_STAT             0x147
 #define EE_AUDIO_TDMOUT_A_GAIN0            0x148
 #define EE_AUDIO_TDMOUT_A_GAIN1            0x149
+#define EE_AUDIO_TDMOUT_A_GAIN2            0x2a2
+#define EE_AUDIO_TDMOUT_A_GAIN3            0x2a3
 #define EE_AUDIO_TDMOUT_A_MUTE_VAL         0x14a
 #define EE_AUDIO_TDMOUT_A_MUTE0            0x14b
 #define EE_AUDIO_TDMOUT_A_MUTE1            0x14c
 #define EE_AUDIO_TDMOUT_A_MUTE2            0x14d
 #define EE_AUDIO_TDMOUT_A_MUTE3            0x14e
+#define EE_AUDIO_TDMOUT_A_MUTE4            0x2a8
+#define EE_AUDIO_TDMOUT_A_MUTE5            0x2a9
+#define EE_AUDIO_TDMOUT_A_MUTE6            0x2aa
+#define EE_AUDIO_TDMOUT_A_MUTE7            0x2ab
 #define EE_AUDIO_TDMOUT_A_MASK_VAL         0x14f
 
 #define EE_AUDIO_TDMOUT_B_CTRL0            0x150
 #define EE_AUDIO_TDMOUT_B_CTRL1            0x151
-#define EE_AUDIO_TDMOUT_B_SWAP             0x152
+#define EE_AUDIO_TDMOUT_B_CTRL2            0x2b0
+#define EE_AUDIO_TDMOUT_B_SWAP0            0x152
+#define EE_AUDIO_TDMOUT_B_SWAP1            0x2b1
 #define EE_AUDIO_TDMOUT_B_MASK0            0x153
 #define EE_AUDIO_TDMOUT_B_MASK1            0x154
 #define EE_AUDIO_TDMOUT_B_MASK2            0x155
 #define EE_AUDIO_TDMOUT_B_MASK3            0x156
+#define EE_AUDIO_TDMOUT_B_MASK4            0x2b4
+#define EE_AUDIO_TDMOUT_B_MASK5            0x2b5
+#define EE_AUDIO_TDMOUT_B_MASK6            0x2b6
+#define EE_AUDIO_TDMOUT_B_MASK7            0x2b7
 #define EE_AUDIO_TDMOUT_B_STAT             0x157
 #define EE_AUDIO_TDMOUT_B_GAIN0            0x158
 #define EE_AUDIO_TDMOUT_B_GAIN1            0x159
+#define EE_AUDIO_TDMOUT_B_GAIN2            0x2b2
+#define EE_AUDIO_TDMOUT_B_GAIN3            0x2b3
 #define EE_AUDIO_TDMOUT_B_MUTE_VAL         0x15a
 #define EE_AUDIO_TDMOUT_B_MUTE0            0x15b
 #define EE_AUDIO_TDMOUT_B_MUTE1            0x15c
 #define EE_AUDIO_TDMOUT_B_MUTE2            0x15d
 #define EE_AUDIO_TDMOUT_B_MUTE3            0x15e
+#define EE_AUDIO_TDMOUT_B_MUTE4            0x2b8
+#define EE_AUDIO_TDMOUT_B_MUTE5            0x2b9
+#define EE_AUDIO_TDMOUT_B_MUTE6            0x2ba
+#define EE_AUDIO_TDMOUT_B_MUTE7            0x2bb
 #define EE_AUDIO_TDMOUT_B_MASK_VAL         0x15f
 
 #define EE_AUDIO_TDMOUT_C_CTRL0            0x160
 #define EE_AUDIO_TDMOUT_C_CTRL1            0x161
-#define EE_AUDIO_TDMOUT_C_SWAP             0x162
+#define EE_AUDIO_TDMOUT_C_CTRL2            0x2c0
+#define EE_AUDIO_TDMOUT_C_SWAP0            0x162
+#define EE_AUDIO_TDMOUT_C_SWAP1            0x2c1
 #define EE_AUDIO_TDMOUT_C_MASK0            0x163
 #define EE_AUDIO_TDMOUT_C_MASK1            0x164
 #define EE_AUDIO_TDMOUT_C_MASK2            0x165
 #define EE_AUDIO_TDMOUT_C_MASK3            0x166
+#define EE_AUDIO_TDMOUT_C_MASK4            0x2c4
+#define EE_AUDIO_TDMOUT_C_MASK5            0x2c5
+#define EE_AUDIO_TDMOUT_C_MASK6            0x2c6
+#define EE_AUDIO_TDMOUT_C_MASK7            0x2c7
 #define EE_AUDIO_TDMOUT_C_STAT             0x167
 #define EE_AUDIO_TDMOUT_C_GAIN0            0x168
 #define EE_AUDIO_TDMOUT_C_GAIN1            0x169
+#define EE_AUDIO_TDMOUT_C_GAIN2            0x2c2
+#define EE_AUDIO_TDMOUT_C_GAIN3            0x2c3
 #define EE_AUDIO_TDMOUT_C_MUTE_VAL         0x16a
 #define EE_AUDIO_TDMOUT_C_MUTE0            0x16b
 #define EE_AUDIO_TDMOUT_C_MUTE1            0x16c
 #define EE_AUDIO_TDMOUT_C_MUTE2            0x16d
 #define EE_AUDIO_TDMOUT_C_MUTE3            0x16e
+#define EE_AUDIO_TDMOUT_C_MUTE4            0x2c8
+#define EE_AUDIO_TDMOUT_C_MUTE5            0x2c9
+#define EE_AUDIO_TDMOUT_C_MUTE6            0x2ca
+#define EE_AUDIO_TDMOUT_C_MUTE7            0x2cb
 #define EE_AUDIO_TDMOUT_C_MASK_VAL         0x16f
 
 /*
@@ -847,4 +924,184 @@ enum clk_sel {
 #define VAD_IN_SEL1                        0x030
 #define VAD_TO_DDR                         0x031
 
+/*
+ * eARC
+ */
+/* eARC RX CMDC */
+#define EARC_RX_CMDC_TOP_CTRL0             0x000
+#define EARC_RX_CMDC_TOP_CTRL1             0x001
+#define EARC_RX_CMDC_TOP_CTRL2             0x002
+#define EARC_RX_CMDC_TIMER_CTRL0           0x003
+#define EARC_RX_CMDC_TIMER_CTRL1           0x004
+#define EARC_RX_CMDC_TIMER_CTRL2           0x005
+#define EARC_RX_CMDC_TIMER_CTRL3           0x006
+#define EARC_RX_CMDC_VSM_CTRL0             0x007
+#define EARC_RX_CMDC_VSM_CTRL1             0x008
+#define EARC_RX_CMDC_VSM_CTRL2             0x009
+#define EARC_RX_CMDC_VSM_CTRL3             0x00a
+#define EARC_RX_CMDC_VSM_CTRL4             0x00b
+#define EARC_RX_CMDC_VSM_CTRL5             0x00c
+#define EARC_RX_CMDC_VSM_CTRL6             0x00d
+#define EARC_RX_CMDC_VSM_CTRL7             0x00e
+#define EARC_RX_CMDC_VSM_CTRL8             0x00f
+#define EARC_RX_CMDC_VSM_CTRL9             0x010
+#define EARC_RX_CMDC_SENDER_CTRL0          0x011
+#define EARC_RX_CMDC_PACKET_CTRL0          0x012
+#define EARC_RX_CMDC_PACKET_CTRL1          0x013
+#define EARC_RX_CMDC_PACKET_CTRL2          0x014
+#define EARC_RX_CMDC_PACKET_CTRL3          0x015
+#define EARC_RX_CMDC_PACKET_CTRL4          0x016
+#define EARC_RX_CMDC_PACKET_CTRL5          0x017
+#define EARC_RX_CMDC_PACKET_CTRL6          0x018
+#define EARC_RX_CMDC_BIPHASE_CTRL0         0x019
+#define EARC_RX_CMDC_BIPHASE_CTRL1         0x01a
+#define EARC_RX_CMDC_BIPHASE_CTRL2         0x01b
+#define EARC_RX_CMDC_BIPHASE_CTRL3         0x01c
+#define EARC_RX_CMDC_DEVICE_ID_CTRL        0x01d
+#define EARC_RX_CMDC_DEVICE_WDATA          0x01e
+#define EARC_RX_CMDC_DEVICE_RDATA          0x01f
+#define EARC_RX_ANA_CTRL0                  0x020
+#define EARC_RX_ANA_CTRL1                  0x021
+#define EARC_RX_ANA_CTRL2                  0x022
+#define EARC_RX_ANA_CTRL3                  0x023
+#define EARC_RX_ANA_CTRL4                  0x024
+#define EARC_RX_ANA_CTRL5                  0x025
+#define EARC_RX_ANA_STAT0                  0x026
+#define EARC_RX_CMDC_STATUS0               0x027
+#define EARC_RX_CMDC_STATUS1               0x028
+#define EARC_RX_CMDC_STATUS2               0x029
+#define EARC_RX_CMDC_STATUS3               0x02a
+#define EARC_RX_CMDC_STATUS4               0x02b
+#define EARC_RX_CMDC_STATUS5               0x02c
+#define EARC_RX_CMDC_STATUS6               0x02d
+/* eARC TX CMDC */
+#define EARC_TX_CMDC_TOP_CTRL0             0x030
+#define EARC_TX_CMDC_TOP_CTRL1             0x031
+#define EARC_TX_CMDC_TOP_CTRL2             0x032
+#define EARC_TX_CMDC_TIMER_CTRL0           0x033
+#define EARC_TX_CMDC_TIMER_CTRL1           0x034
+#define EARC_TX_CMDC_TIMER_CTRL2           0x035
+#define EARC_TX_CMDC_TIMER_CTRL3           0x036
+#define EARC_TX_CMDC_VSM_CTRL0             0x037
+#define EARC_TX_CMDC_VSM_CTRL1             0x038
+#define EARC_TX_CMDC_VSM_CTRL2             0x039
+#define EARC_TX_CMDC_VSM_CTRL3             0x03a
+#define EARC_TX_CMDC_VSM_CTRL4             0x03b
+#define EARC_TX_CMDC_VSM_CTRL5             0x03c
+#define EARC_TX_CMDC_VSM_CTRL6             0x03d
+#define EARC_TX_CMDC_VSM_CTRL7             0x03e
+#define EARC_TX_CMDC_VSM_CTRL8             0x03f
+#define EARC_TX_CMDC_VSM_CTRL9             0x041
+#define EARC_TX_CMDC_SENDER_CTRL0          0x042
+#define EARC_TX_CMDC_PACKET_CTRL0          0x043
+#define EARC_TX_CMDC_PACKET_CTRL1          0x044
+#define EARC_TX_CMDC_PACKET_CTRL2          0x045
+#define EARC_TX_CMDC_PACKET_CTRL3          0x046
+#define EARC_TX_CMDC_PACKET_CTRL4          0x047
+#define EARC_TX_CMDC_PACKET_CTRL5          0x048
+#define EARC_TX_CMDC_PACKET_CTRL6          0x049
+#define EARC_TX_CMDC_BIPHASE_CTRL0         0x04a
+#define EARC_TX_CMDC_BIPHASE_CTRL1         0x04b
+#define EARC_TX_CMDC_BIPHASE_CTRL2         0x04c
+#define EARC_TX_CMDC_BIPHASE_CTRL3         0x04d
+#define EARC_TX_CMDC_DEVICE_ID_CTRL        0x04e
+#define EARC_TX_CMDC_DEVICE_WDATA          0x04f
+#define EARC_TX_CMDC_DEVICE_RDATA          0x050
+#define EARC_TX_CMDC_MASTER_CTRL           0x051
+#define EARC_TX_ANA_CTRL0                  0x052
+#define EARC_TX_ANA_CTRL1                  0x053
+#define EARC_TX_ANA_CTRL2                  0x054
+#define EARC_TX_ANA_CTRL3                  0x055
+#define EARC_TX_ANA_CTRL4                  0x056
+#define EARC_TX_ANA_CTRL5                  0x057
+#define EARC_TX_ANA_STAT0                  0x058
+#define EARC_TX_CMDC_STATUS0               0x059
+#define EARC_TX_CMDC_STATUS1               0x05a
+#define EARC_TX_CMDC_STATUS2               0x05b
+#define EARC_TX_CMDC_STATUS3               0x05c
+#define EARC_TX_CMDC_STATUS4               0x05d
+#define EARC_TX_CMDC_STATUS5               0x05e
+#define EARC_TX_CMDC_STATUS6               0x05f
+/* eARC RX DMAC */
+#define EARCRX_DMAC_TOP_CTRL0              0x000
+#define EARCRX_DMAC_SYNC_CTRL0             0x001
+#define EARCRX_DMAC_SYNC_STAT0             0x002
+#define EARCRX_SPDIFIN_SAMPLE_CTRL0        0x003
+#define EARCRX_SPDIFIN_SAMPLE_CTRL1        0x004
+#define EARCRX_SPDIFIN_SAMPLE_CTRL2        0x005
+#define EARCRX_SPDIFIN_SAMPLE_CTRL3        0x006
+#define EARCRX_SPDIFIN_SAMPLE_CTRL4        0x007
+#define EARCRX_SPDIFIN_SAMPLE_CTRL5        0x008
+#define EARCRX_SPDIFIN_SAMPLE_STAT0        0x009
+#define EARCRX_SPDIFIN_SAMPLE_STAT1        0x00a
+#define EARCRX_SPDIFIN_MUTE_VAL            0x00b
+#define EARCRX_SPDIFIN_CTRL0               0x00c
+#define EARCRX_SPDIFIN_CTRL1               0x00d
+#define EARCRX_SPDIFIN_CTRL2               0x00e
+#define EARCRX_SPDIFIN_CTRL3               0x00f
+#define EARCRX_SPDIFIN_STAT0               0x010
+#define EARCRX_SPDIFIN_STAT1               0x011
+#define EARCRX_SPDIFIN_STAT2               0x012
+#define EARCRX_DMAC_UBIT_CTRL0             0x013
+#define EARCRX_IU_RDATA                    0x014
+#define EARCRX_DMAC_UBIT_STAT0             0x015
+#define EARCRX_ERR_CORRECT_CTRL0           0x016
+#define EARCRX_ERR_CORRECT_STAT0           0x017
+#define EARCRX_ANA_RST_CTRL0               0x018
+#define EARCRX_ANA_RST_CTRL1               0x019
+/* eARC TX DMAC */
+#define EARCTX_DMAC_TOP_CTRL0              0x000
+#define EARCTX_MUTE_VAL                    0x001
+#define EARCTX_SPDIFOUT_GAIN0              0x002
+#define EARCTX_SPDIFOUT_GAIN1              0x003
+#define EARCTX_SPDIFOUT_CTRL0              0x004
+#define EARCTX_SPDIFOUT_CTRL1              0x005
+#define EARCTX_SPDIFOUT_PREAMB             0x006
+#define EARCTX_SPDIFOUT_SWAP               0x007
+#define EARCTX_ERR_CORRT_CTRL0             0x008
+#define EARCTX_ERR_CORRT_CTRL1             0x009
+#define EARCTX_ERR_CORRT_CTRL2             0x00a
+#define EARCTX_ERR_CORRT_CTRL3             0x00b
+#define EARCTX_ERR_CORRT_CTRL4             0x00c
+#define EARCTX_ERR_CORRT_STAT0             0x00d
+#define EARCTX_SPDIFOUT_CHSTS0             0x00e
+#define EARCTX_SPDIFOUT_CHSTS1             0x00f
+#define EARCTX_SPDIFOUT_CHSTS2             0x010
+#define EARCTX_SPDIFOUT_CHSTS3             0x011
+#define EARCTX_SPDIFOUT_CHSTS4             0x012
+#define EARCTX_SPDIFOUT_CHSTS5             0x013
+#define EARCTX_SPDIFOUT_CHSTS6             0x014
+#define EARCTX_SPDIFOUT_CHSTS7             0x015
+#define EARCTX_SPDIFOUT_CHSTS8             0x016
+#define EARCTX_SPDIFOUT_CHSTS9             0x017
+#define EARCTX_SPDIFOUT_CHSTSA             0x018
+#define EARCTX_SPDIFOUT_CHSTSB             0x019
+#define EARCTX_FE_CTRL0                    0x01a
+#define EARCTX_FE_STAT0                    0x01b
+#define EARCTX_SPDIFOUT_STAT               0x01c
+/* eARC RX */
+#define EARCRX_TOP_CTRL0                   0x000
+#define EARCRX_DMAC_INT_MASK               0x001
+#define EARCRX_DMAC_INT_PENDING            0x002
+#define EARCRX_CMDC_INT_MASK               0x003
+#define EARCRX_CMDC_INT_PENDING            0x004
+#define EARCRX_ANA_CTRL0                   0x005
+#define EARCRX_ANA_CTRL1                   0x006
+#define EARCRX_ANA_STAT0                   0x007
+#define EARCRX_PLL_CTRL0                   0x008
+#define EARCRX_PLL_CTRL1                   0x009
+#define EARCRX_PLL_CTRL2                   0x00a
+#define EARCRX_PLL_CTRL3                   0x00b
+#define EARCRX_PLL_STAT0                   0x00c
+/* eARC TX */
+#define EARCTX_TOP_CTRL0                   0x000
+#define EARCTX_DMAC_INT_MASK               0x001
+#define EARCTX_DMAC_INT_PENDING            0x002
+#define EARCTX_CMDC_INT_MASK               0x003
+#define EARCTX_CMDC_INT_PENDING            0x004
+#define EARCTX_ANA_CTRL0                   0x005
+#define EARCTX_ANA_CTRL1                   0x006
+#define EARCTX_ANA_CTRL2                   0x007
+#define EARCTX_ANA_STAT0                   0x008
+
 #endif
diff --git a/sound/soc/amlogic/auge/sm1,clocks.c b/sound/soc/amlogic/auge/sm1,clocks.c
new file mode 100644 (file)
index 0000000..762186e
--- /dev/null
@@ -0,0 +1,376 @@
+/*
+ * sound/soc/amlogic/auge/sm1,clocks.c
+ *
+ * Copyright (C) 2019 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+#undef pr_fmt
+#define pr_fmt(fmt) "sm1_audio_clocks: " fmt
+
+#include <dt-bindings/clock/amlogic,sm1-audio-clk.h>
+
+#include "audio_clks.h"
+#include "regs.h"
+
+static spinlock_t aclk_lock;
+
+static const char *const mclk_parent_names[] = {
+       "mpll0", "mpll1", "mpll2", "mpll3", "hifi_pll",
+       "fclk_div3", "fclk_div4", "fclk_div5"};
+
+static const char *const audioclk_parent_names[] = {
+       "mclk_a", "mclk_b", "mclk_c", "mclk_d", "mclk_e",
+       "mclk_f", "i_slv_sclk_a", "i_slv_sclk_b", "i_slv_sclk_c",
+       "i_slv_sclk_d", "i_slv_sclk_e", "i_slv_sclk_f", "i_slv_sclk_g",
+       "i_slv_sclk_h", "i_slv_sclk_i", "i_slv_sclk_j"};
+
+CLOCK_GATE(audio_ddr_arb, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 0);
+CLOCK_GATE(audio_pdm, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 1);
+CLOCK_GATE(audio_tdmina, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 2);
+CLOCK_GATE(audio_tdminb, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 3);
+CLOCK_GATE(audio_tdminc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 4);
+CLOCK_GATE(audio_tdminlb, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 5);
+CLOCK_GATE(audio_tdmouta, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 6);
+CLOCK_GATE(audio_tdmoutb, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 7);
+CLOCK_GATE(audio_tdmoutc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 8);
+CLOCK_GATE(audio_frddra, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 9);
+CLOCK_GATE(audio_frddrb, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 10);
+CLOCK_GATE(audio_frddrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 11);
+CLOCK_GATE(audio_toddra, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 12);
+CLOCK_GATE(audio_toddrb, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 13);
+CLOCK_GATE(audio_toddrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 14);
+CLOCK_GATE(audio_loopbacka, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 15);
+CLOCK_GATE(audio_spdifin, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 16);
+CLOCK_GATE(audio_spdifout, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 17);
+CLOCK_GATE(audio_resamplea, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 18);
+CLOCK_GATE(audio_reserved0, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 19);
+CLOCK_GATE(audio_toram, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 20);
+CLOCK_GATE(audio_spdifoutb, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 21);
+CLOCK_GATE(audio_eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 22);
+CLOCK_GATE(audio_reserved1, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 23);
+CLOCK_GATE(audio_reserved2, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 24);
+CLOCK_GATE(audio_reserved3, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 25);
+CLOCK_GATE(audio_resampleb, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 26);
+CLOCK_GATE(audio_tovad, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 27);
+CLOCK_GATE(audio_audiolocker, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 28);
+CLOCK_GATE(audio_spdifin_lb, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 29);
+CLOCK_GATE(audio_reserved4, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 30);
+CLOCK_GATE(audio_reserved5, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN0), 31);
+
+CLOCK_GATE(audio_frddrd, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN1), 0);
+CLOCK_GATE(audio_toddrd, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN1), 1);
+CLOCK_GATE(audio_loopbackb, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN1), 2);
+CLOCK_GATE(audio_earc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_GATE_EN1), 6);
+
+static struct clk_gate *sm1_audio_clk_gates[] = {
+       &audio_ddr_arb,
+       &audio_pdm,
+       &audio_tdmina,
+       &audio_tdminb,
+       &audio_tdminc,
+       &audio_tdminlb,
+       &audio_tdmouta,
+       &audio_tdmoutb,
+       &audio_tdmoutc,
+       &audio_frddra,
+       &audio_frddrb,
+       &audio_frddrc,
+       &audio_toddra,
+       &audio_toddrb,
+       &audio_toddrc,
+       &audio_loopbacka,
+       &audio_spdifin,
+       &audio_spdifout,
+       &audio_resamplea,
+       &audio_reserved0,
+       &audio_toram,
+       &audio_spdifoutb,
+       &audio_eqdrc,
+       &audio_reserved1,
+       &audio_reserved2,
+       &audio_reserved3,
+       &audio_resampleb,
+       &audio_tovad,
+       &audio_audiolocker,
+       &audio_spdifin_lb,
+       &audio_reserved4,
+       &audio_reserved5,
+
+       &audio_frddrd,
+       &audio_toddrd,
+       &audio_loopbackb,
+       &audio_earc,
+};
+
+/* Array of all clocks provided by this provider */
+static struct clk_hw *sm1_audio_clk_hws[] = {
+       [CLKID_AUDIO_GATE_DDR_ARB]     = &audio_ddr_arb.hw,
+       [CLKID_AUDIO_GATE_PDM]         = &audio_pdm.hw,
+       [CLKID_AUDIO_GATE_TDMINA]      = &audio_tdmina.hw,
+       [CLKID_AUDIO_GATE_TDMINB]      = &audio_tdminb.hw,
+       [CLKID_AUDIO_GATE_TDMINC]      = &audio_tdminc.hw,
+       [CLKID_AUDIO_GATE_TDMINLB]     = &audio_tdminlb.hw,
+       [CLKID_AUDIO_GATE_TDMOUTA]     = &audio_tdmouta.hw,
+       [CLKID_AUDIO_GATE_TDMOUTB]     = &audio_tdmoutb.hw,
+       [CLKID_AUDIO_GATE_TDMOUTC]     = &audio_tdmoutc.hw,
+       [CLKID_AUDIO_GATE_FRDDRA]      = &audio_frddra.hw,
+       [CLKID_AUDIO_GATE_FRDDRB]      = &audio_frddrb.hw,
+       [CLKID_AUDIO_GATE_FRDDRC]      = &audio_frddrc.hw,
+       [CLKID_AUDIO_GATE_TODDRA]      = &audio_toddra.hw,
+       [CLKID_AUDIO_GATE_TODDRB]      = &audio_toddrb.hw,
+       [CLKID_AUDIO_GATE_TODDRC]      = &audio_toddrc.hw,
+       [CLKID_AUDIO_GATE_LOOPBACKA]   = &audio_loopbacka.hw,
+       [CLKID_AUDIO_GATE_SPDIFIN]     = &audio_spdifin.hw,
+       [CLKID_AUDIO_GATE_SPDIFOUT_A]  = &audio_spdifout.hw,
+       [CLKID_AUDIO_GATE_RESAMPLEA]   = &audio_resamplea.hw,
+       [CLKID_AUDIO_GATE_RESERVED0]   = &audio_reserved0.hw,
+       [CLKID_AUDIO_GATE_TORAM]       = &audio_toram.hw,
+       [CLKID_AUDIO_GATE_SPDIFOUT_B]  = &audio_spdifoutb.hw,
+       [CLKID_AUDIO_GATE_EQDRC]       = &audio_eqdrc.hw,
+       [CLKID_AUDIO_GATE_RESERVED1]   = &audio_reserved1.hw,
+       [CLKID_AUDIO_GATE_RESERVED2]   = &audio_reserved2.hw,
+       [CLKID_AUDIO_GATE_RESERVED3]   = &audio_reserved3.hw,
+       [CLKID_AUDIO_GATE_RESAMPLEB]   = &audio_resampleb.hw,
+       [CLKID_AUDIO_GATE_TOVAD]       = &audio_tovad.hw,
+       [CLKID_AUDIO_GATE_AUDIOLOCKER] = &audio_audiolocker.hw,
+       [CLKID_AUDIO_GATE_SPDIFIN_LB]  = &audio_spdifin_lb.hw,
+       [CLKID_AUDIO_GATE_RESERVED4]   = &audio_reserved4.hw,
+       [CLKID_AUDIO_GATE_RESERVED5]   = &audio_reserved5.hw,
+
+       [CLKID_AUDIO_GATE_FRDDRD]      = &audio_frddrd.hw,
+       [CLKID_AUDIO_GATE_TODDRD]      = &audio_toddrd.hw,
+       [CLKID_AUDIO_GATE_LOOPBACKB]   = &audio_loopbackb.hw,
+       [CLKID_AUDIO_GATE_EARCRX]      = &audio_earc.hw,
+};
+
+static int sm1_clk_gates_init(struct clk **clks, void __iomem *iobase)
+{
+       int clkid;
+
+       if (ARRAY_SIZE(sm1_audio_clk_gates) != MCLK_BASE) {
+               pr_err("check clk gates number\n");
+               return -EINVAL;
+       }
+
+       for (clkid = 0; clkid < MCLK_BASE; clkid++) {
+               sm1_audio_clk_gates[clkid]->reg = iobase;
+               clks[clkid] = clk_register(NULL, sm1_audio_clk_hws[clkid]);
+               WARN_ON(IS_ERR_OR_NULL(clks[clkid]));
+       }
+
+       return 0;
+}
+
+/* mclk_a */
+CLOCK_COM_MUX(mclk_a, AUD_ADDR_OFFSET(EE_AUDIO_MCLK_A_CTRL(1)), 0x7, 24);
+CLOCK_COM_DIV(mclk_a, AUD_ADDR_OFFSET(EE_AUDIO_MCLK_A_CTRL(1)), 0, 16);
+CLOCK_COM_GATE(mclk_a, AUD_ADDR_OFFSET(EE_AUDIO_MCLK_A_CTRL(1)), 31);
+/* mclk_b */
+CLOCK_COM_MUX(mclk_b, AUD_ADDR_OFFSET(EE_AUDIO_MCLK_B_CTRL(1)), 0x7, 24);
+CLOCK_COM_DIV(mclk_b, AUD_ADDR_OFFSET(EE_AUDIO_MCLK_B_CTRL(1)), 0, 16);
+CLOCK_COM_GATE(mclk_b, AUD_ADDR_OFFSET(EE_AUDIO_MCLK_B_CTRL(1)), 31);
+/* mclk_c */
+CLOCK_COM_MUX(mclk_c, AUD_ADDR_OFFSET(EE_AUDIO_MCLK_C_CTRL(1)), 0x7, 24);
+CLOCK_COM_DIV(mclk_c, AUD_ADDR_OFFSET(EE_AUDIO_MCLK_C_CTRL(1)), 0, 16);
+CLOCK_COM_GATE(mclk_c, AUD_ADDR_OFFSET(EE_AUDIO_MCLK_C_CTRL(1)), 31);
+/* mclk_d */
+CLOCK_COM_MUX(mclk_d, AUD_ADDR_OFFSET(EE_AUDIO_MCLK_D_CTRL(1)), 0x7, 24);
+CLOCK_COM_DIV(mclk_d, AUD_ADDR_OFFSET(EE_AUDIO_MCLK_D_CTRL(1)), 0, 16);
+CLOCK_COM_GATE(mclk_d, AUD_ADDR_OFFSET(EE_AUDIO_MCLK_D_CTRL(1)), 31);
+/* mclk_e */
+CLOCK_COM_MUX(mclk_e, AUD_ADDR_OFFSET(EE_AUDIO_MCLK_E_CTRL(1)), 0x7, 24);
+CLOCK_COM_DIV(mclk_e, AUD_ADDR_OFFSET(EE_AUDIO_MCLK_E_CTRL(1)), 0, 16);
+CLOCK_COM_GATE(mclk_e, AUD_ADDR_OFFSET(EE_AUDIO_MCLK_E_CTRL(1)), 31);
+/* mclk_f */
+CLOCK_COM_MUX(mclk_f, AUD_ADDR_OFFSET(EE_AUDIO_MCLK_F_CTRL(1)), 0x7, 24);
+CLOCK_COM_DIV(mclk_f, AUD_ADDR_OFFSET(EE_AUDIO_MCLK_F_CTRL(1)), 0, 16);
+CLOCK_COM_GATE(mclk_f, AUD_ADDR_OFFSET(EE_AUDIO_MCLK_F_CTRL(1)), 31);
+/* spdifin */
+CLOCK_COM_MUX(spdifin, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFIN_CTRL), 0x7, 24);
+CLOCK_COM_DIV(spdifin, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFIN_CTRL), 0, 8);
+CLOCK_COM_GATE(spdifin, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFIN_CTRL), 31);
+/* spdifout */
+CLOCK_COM_MUX(spdifout, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_CTRL), 0x7, 24);
+CLOCK_COM_DIV(spdifout, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_CTRL), 0, 10);
+CLOCK_COM_GATE(spdifout, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_CTRL), 31);
+/* audio resample_a */
+CLOCK_COM_MUX(resample_a,
+       AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLEA_CTRL), 0xf, 24);
+CLOCK_COM_DIV(resample_a, AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLEA_CTRL), 0, 8);
+CLOCK_COM_GATE(resample_a, AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLEA_CTRL), 31);
+/* audio locker_out */
+CLOCK_COM_MUX(locker_out, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 0xf, 24);
+CLOCK_COM_DIV(locker_out, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 16, 8);
+CLOCK_COM_GATE(locker_out, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 31);
+/* audio locker_in */
+CLOCK_COM_MUX(locker_in, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 0xf, 8);
+CLOCK_COM_DIV(locker_in, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 0, 8);
+CLOCK_COM_GATE(locker_in, AUD_ADDR_OFFSET(EE_AUDIO_CLK_LOCKER_CTRL), 15);
+/* pdmin0 */
+CLOCK_COM_MUX(pdmin0, AUD_ADDR_OFFSET(EE_AUDIO_CLK_PDMIN_CTRL0), 0x7, 24);
+CLOCK_COM_DIV(pdmin0, AUD_ADDR_OFFSET(EE_AUDIO_CLK_PDMIN_CTRL0), 0, 16);
+CLOCK_COM_GATE(pdmin0, AUD_ADDR_OFFSET(EE_AUDIO_CLK_PDMIN_CTRL0), 31);
+/* pdmin1 */
+CLOCK_COM_MUX(pdmin1, AUD_ADDR_OFFSET(EE_AUDIO_CLK_PDMIN_CTRL1), 0x7, 24);
+CLOCK_COM_DIV(pdmin1, AUD_ADDR_OFFSET(EE_AUDIO_CLK_PDMIN_CTRL1), 0, 16);
+CLOCK_COM_GATE(pdmin1, AUD_ADDR_OFFSET(EE_AUDIO_CLK_PDMIN_CTRL1), 31);
+/* spdifout b*/
+CLOCK_COM_MUX(spdifout_b,
+       AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_B_CTRL), 0x7, 24);
+CLOCK_COM_DIV(spdifout_b, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_B_CTRL), 0, 10);
+CLOCK_COM_GATE(spdifout_b, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_B_CTRL), 31);
+/* audio resample_b */
+CLOCK_COM_MUX(resample_b,
+       AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLEB_CTRL), 0xf, 24);
+CLOCK_COM_DIV(resample_b, AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLEB_CTRL), 0, 8);
+CLOCK_COM_GATE(resample_b, AUD_ADDR_OFFSET(EE_AUDIO_CLK_RESAMPLEB_CTRL), 31);
+/* spdifin_lb, div is a fake */
+CLOCK_COM_MUX(spdifin_lb,
+       AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_B_CTRL), 0x1, 30);
+CLOCK_COM_DIV(spdifin_lb, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_B_CTRL), 0, 29);
+CLOCK_COM_GATE(spdifin_lb, AUD_ADDR_OFFSET(EE_AUDIO_CLK_SPDIFOUT_B_CTRL), 31);
+/* audio eqdrc  */
+CLOCK_COM_MUX(eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_EQDRC_CTRL0), 0x7, 24);
+CLOCK_COM_DIV(eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_EQDRC_CTRL0), 0, 16);
+CLOCK_COM_GATE(eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_EQDRC_CTRL0), 31);
+/* audio vad  */
+CLOCK_COM_MUX(vad, AUD_ADDR_OFFSET(EE_AUDIO_VAD_CLK_CTRL), 0x7, 24);
+CLOCK_COM_DIV(vad, AUD_ADDR_OFFSET(EE_AUDIO_VAD_CLK_CTRL), 0, 16);
+CLOCK_COM_GATE(vad, AUD_ADDR_OFFSET(EE_AUDIO_VAD_CLK_CTRL), 31);
+/* EARC TX CMDC */
+CLOCK_COM_MUX(earctx_cmdc,
+       AUD_ADDR_OFFSET(EE_AUDIO_EARCTX_CMDC_CLK_CTRL), 0x7, 24);
+CLOCK_COM_DIV(earctx_cmdc,
+       AUD_ADDR_OFFSET(EE_AUDIO_EARCTX_CMDC_CLK_CTRL), 0, 16);
+CLOCK_COM_GATE(earctx_cmdc,
+       AUD_ADDR_OFFSET(EE_AUDIO_EARCTX_CMDC_CLK_CTRL), 31);
+/* EARC TX DMAC */
+CLOCK_COM_MUX(earctx_dmac,
+       AUD_ADDR_OFFSET(EE_AUDIO_EARCTX_DMAC_CLK_CTRL), 0x7, 24);
+CLOCK_COM_DIV(earctx_dmac,
+       AUD_ADDR_OFFSET(EE_AUDIO_EARCTX_DMAC_CLK_CTRL), 0, 16);
+CLOCK_COM_GATE(earctx_dmac,
+       AUD_ADDR_OFFSET(EE_AUDIO_EARCTX_DMAC_CLK_CTRL), 31);
+/* EARC RX CMDC */
+CLOCK_COM_MUX(earcrx_cmdc,
+       AUD_ADDR_OFFSET(EE_AUDIO_EARCRX_CMDC_CLK_CTRL), 0x7, 24);
+CLOCK_COM_DIV(earcrx_cmdc,
+       AUD_ADDR_OFFSET(EE_AUDIO_EARCRX_CMDC_CLK_CTRL), 0, 16);
+CLOCK_COM_GATE(earcrx_cmdc,
+       AUD_ADDR_OFFSET(EE_AUDIO_EARCRX_CMDC_CLK_CTRL), 31);
+/* EARC RX DMAC */
+CLOCK_COM_MUX(earcrx_dmac,
+       AUD_ADDR_OFFSET(EE_AUDIO_EARCRX_DMAC_CLK_CTRL), 0x7, 24);
+CLOCK_COM_DIV(earcrx_dmac,
+       AUD_ADDR_OFFSET(EE_AUDIO_EARCRX_DMAC_CLK_CTRL), 0, 16);
+CLOCK_COM_GATE(earcrx_dmac,
+       AUD_ADDR_OFFSET(EE_AUDIO_EARCRX_DMAC_CLK_CTRL), 31);
+
+static int sm1_clks_init(struct clk **clks, void __iomem *iobase)
+{
+       IOMAP_COM_CLK(mclk_a, iobase);
+       clks[CLKID_AUDIO_MCLK_A] = REGISTER_CLK_COM(mclk_a);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_MCLK_A]));
+
+       IOMAP_COM_CLK(mclk_b, iobase);
+       clks[CLKID_AUDIO_MCLK_B] = REGISTER_CLK_COM(mclk_b);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_MCLK_B]));
+
+       IOMAP_COM_CLK(mclk_c, iobase);
+       clks[CLKID_AUDIO_MCLK_C] = REGISTER_CLK_COM(mclk_c);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_MCLK_C]));
+
+       IOMAP_COM_CLK(mclk_d, iobase);
+       clks[CLKID_AUDIO_MCLK_D] = REGISTER_CLK_COM(mclk_d);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_MCLK_D]));
+
+       IOMAP_COM_CLK(mclk_e, iobase);
+       clks[CLKID_AUDIO_MCLK_E] = REGISTER_CLK_COM(mclk_e);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_MCLK_E]));
+
+       IOMAP_COM_CLK(mclk_f, iobase);
+       clks[CLKID_AUDIO_MCLK_F] = REGISTER_CLK_COM(mclk_f);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_MCLK_F]));
+
+       IOMAP_COM_CLK(spdifin, iobase);
+       clks[CLKID_AUDIO_SPDIFIN] = REGISTER_CLK_COM(spdifin);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_SPDIFIN]));
+
+       IOMAP_COM_CLK(spdifout, iobase);
+       clks[CLKID_AUDIO_SPDIFOUT_A] = REGISTER_CLK_COM(spdifout);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_SPDIFOUT_A]));
+
+       IOMAP_COM_CLK(resample_a, iobase);
+       clks[CLKID_AUDIO_RESAMPLE_A] = REGISTER_AUDIOCLK_COM(resample_a);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_RESAMPLE_A]));
+
+       IOMAP_COM_CLK(locker_out, iobase);
+       clks[CLKID_AUDIO_LOCKER_OUT] = REGISTER_AUDIOCLK_COM(locker_out);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_LOCKER_OUT]));
+
+       IOMAP_COM_CLK(locker_in, iobase);
+       clks[CLKID_AUDIO_LOCKER_IN] = REGISTER_AUDIOCLK_COM(locker_in);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_LOCKER_IN]));
+
+       IOMAP_COM_CLK(pdmin0, iobase);
+       clks[CLKID_AUDIO_PDMIN0] = REGISTER_CLK_COM(pdmin0);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_PDMIN0]));
+
+       IOMAP_COM_CLK(pdmin1, iobase);
+       clks[CLKID_AUDIO_PDMIN1] = REGISTER_CLK_COM(pdmin1);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_PDMIN1]));
+
+       IOMAP_COM_CLK(spdifout_b, iobase);
+       clks[CLKID_AUDIO_SPDIFOUT_B] = REGISTER_CLK_COM(spdifout_b);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_SPDIFOUT_B]));
+
+       IOMAP_COM_CLK(resample_b, iobase);
+       clks[CLKID_AUDIO_RESAMPLE_B] = REGISTER_AUDIOCLK_COM(resample_b);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_RESAMPLE_B]));
+
+       IOMAP_COM_CLK(spdifin_lb, iobase);
+       clks[CLKID_AUDIO_SPDIFIN_LB] = REGISTER_CLK_COM(spdifin_lb);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_SPDIFIN_LB]));
+
+       IOMAP_COM_CLK(eqdrc, iobase);
+       clks[CLKID_AUDIO_EQDRC] = REGISTER_CLK_COM(eqdrc);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_EQDRC]));
+
+       IOMAP_COM_CLK(vad, iobase);
+       clks[CLKID_AUDIO_VAD] = REGISTER_CLK_COM(vad);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_AUDIO_VAD]));
+
+       IOMAP_COM_CLK(earctx_cmdc, iobase);
+       clks[CLKID_EARCTX_CMDC] = REGISTER_CLK_COM(earctx_cmdc);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_EARCTX_CMDC]));
+
+       IOMAP_COM_CLK(earctx_dmac, iobase);
+       clks[CLKID_EARCTX_DMAC] = REGISTER_CLK_COM(earctx_dmac);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_EARCTX_DMAC]));
+
+       IOMAP_COM_CLK(earcrx_cmdc, iobase);
+       clks[CLKID_EARCRX_CMDC] = REGISTER_CLK_COM(earcrx_cmdc);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_EARCRX_CMDC]));
+
+       IOMAP_COM_CLK(earcrx_dmac, iobase);
+       clks[CLKID_EARCRX_DMAC] = REGISTER_CLK_COM(earcrx_dmac);
+       WARN_ON(IS_ERR_OR_NULL(clks[CLKID_EARCRX_DMAC]));
+
+       return 0;
+}
+
+struct audio_clk_init sm1_audio_clks_init = {
+       .clk_num   = NUM_AUDIO_CLKS,
+       .clk_gates = sm1_clk_gates_init,
+       .clks      = sm1_clks_init,
+};
index 31757ef..5f7bb93 100644 (file)
 #include <sound/soc.h>
 #include <sound/pcm_params.h>
 
-
 #include "ddr_mngr.h"
 #include "spdif_hw.h"
+#include "spdif_match_table.c"
 #include "audio_utils.h"
 #include "resample.h"
 #include "resample_hw.h"
 
-#define DRV_NAME "aml_spdif"
-
-#define SPDIF_A        0
-#define SPDIF_B        1
+#define DRV_NAME "snd_spdif"
 
 /* Debug by PTM when bringup */
 /*#define __PTM_SPDIF_CLK__*/
 static int aml_dai_set_spdif_sysclk(struct snd_soc_dai *cpu_dai,
                                int clk_id, unsigned int freq, int dir);
 
-struct spdif_chipinfo {
-       unsigned int id;
-
-       /* add ch_cnt to ch_num */
-       bool chnum_en;
-       /*
-        * axg, clear all irq bits
-        * after axg, such as g12a, clear each bits
-        * Reg_clr_interrupt[7:0] for each bit of irq_status[7:0];
-        */
-       bool clr_irq_all_bits;
-       /* no PaPb irq */
-       bool irq_no_papb;
-       /* reg_hold_start_en; 1: add delay to match TDM out when share buff; */
-       bool hold_start;
-       /* eq/drc */
-       bool eq_drc_en;
-       /* pc, pd interrupt is separated. */
-       bool pcpd_separated;
-       /* same source, spdif re-enable */
-       bool same_src_spdif_reen;
-};
-
 enum SPDIF_SRC {
        SPDIFIN_PAD = 0,
        SPDIFOUT,
@@ -1531,70 +1505,6 @@ static int aml_spdif_parse_of(struct platform_device *pdev)
        return 0;
 }
 
-struct spdif_chipinfo axg_spdif_chipinfo = {
-       .id               = SPDIF_A,
-       .irq_no_papb      = true,
-       .clr_irq_all_bits = true,
-       .pcpd_separated   = true,
-};
-
-struct spdif_chipinfo g12a_spdif_a_chipinfo = {
-       .id             = SPDIF_A,
-       .chnum_en       = true,
-       .hold_start     = true,
-       .eq_drc_en      = true,
-       .pcpd_separated = true,
-};
-
-struct spdif_chipinfo g12a_spdif_b_chipinfo = {
-       .id             = SPDIF_B,
-       .chnum_en       = true,
-       .hold_start     = true,
-       .eq_drc_en      = true,
-       .pcpd_separated = true,
-};
-
-struct spdif_chipinfo tl1_spdif_a_chipinfo = {
-       .id           = SPDIF_A,
-       .chnum_en     = true,
-       .hold_start   = true,
-       .eq_drc_en    = true,
-       .same_src_spdif_reen = true,
-};
-
-struct spdif_chipinfo tl1_spdif_b_chipinfo = {
-       .id           = SPDIF_B,
-       .chnum_en     = true,
-       .hold_start   = true,
-       .eq_drc_en    = true,
-       .same_src_spdif_reen = true,
-};
-
-static const struct of_device_id aml_spdif_device_id[] = {
-       {
-               .compatible = "amlogic, axg-snd-spdif",
-               .data       = &axg_spdif_chipinfo,
-       },
-       {
-               .compatible = "amlogic, g12a-snd-spdif-a",
-               .data       = &g12a_spdif_a_chipinfo,
-       },
-       {
-               .compatible = "amlogic, g12a-snd-spdif-b",
-               .data       = &g12a_spdif_b_chipinfo,
-       },
-       {
-               .compatible = "amlogic, tl1-snd-spdif-a",
-               .data       = &tl1_spdif_a_chipinfo,
-       },
-       {
-               .compatible = "amlogic, tl1-snd-spdif-b",
-               .data       = &tl1_spdif_b_chipinfo,
-       },
-       {},
-};
-MODULE_DEVICE_TABLE(of, aml_spdif_device_id);
-
 static int aml_spdif_platform_probe(struct platform_device *pdev)
 {
        struct device_node *node = pdev->dev.of_node;
diff --git a/sound/soc/amlogic/auge/spdif_match_table.c b/sound/soc/amlogic/auge/spdif_match_table.c
new file mode 100644 (file)
index 0000000..0253015
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * sound/soc/amlogic/auge/spdif_match_table.c
+ *
+ * Copyright (C) 2019 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#define SPDIF_A        0
+#define SPDIF_B        1
+
+struct spdif_chipinfo {
+       unsigned int id;
+
+       /* add ch_cnt to ch_num */
+       bool chnum_en;
+       /*
+        * axg, clear all irq bits
+        * after axg, such as g12a, clear each bits
+        * Reg_clr_interrupt[7:0] for each bit of irq_status[7:0];
+        */
+       bool clr_irq_all_bits;
+       /* no PaPb irq */
+       bool irq_no_papb;
+       /* reg_hold_start_en; 1: add delay to match TDM out when share buff; */
+       bool hold_start;
+       /* eq/drc */
+       bool eq_drc_en;
+       /* pc, pd interrupt is separated. */
+       bool pcpd_separated;
+       /* same source, spdif re-enable */
+       bool same_src_spdif_reen;
+};
+
+struct spdif_chipinfo axg_spdif_chipinfo = {
+       .id               = SPDIF_A,
+       .irq_no_papb      = true,
+       .clr_irq_all_bits = true,
+       .pcpd_separated   = true,
+};
+
+struct spdif_chipinfo g12a_spdif_a_chipinfo = {
+       .id             = SPDIF_A,
+       .chnum_en       = true,
+       .hold_start     = true,
+       .eq_drc_en      = true,
+       .pcpd_separated = true,
+};
+
+struct spdif_chipinfo g12a_spdif_b_chipinfo = {
+       .id             = SPDIF_B,
+       .chnum_en       = true,
+       .hold_start     = true,
+       .eq_drc_en      = true,
+       .pcpd_separated = true,
+};
+
+struct spdif_chipinfo tl1_spdif_a_chipinfo = {
+       .id           = SPDIF_A,
+       .chnum_en     = true,
+       .hold_start   = true,
+       .eq_drc_en    = true,
+};
+
+struct spdif_chipinfo tl1_spdif_b_chipinfo = {
+       .id           = SPDIF_B,
+       .chnum_en     = true,
+       .hold_start   = true,
+       .eq_drc_en    = true,
+};
+
+struct spdif_chipinfo sm1_spdif_a_chipinfo = {
+       .id           = SPDIF_A,
+       .chnum_en     = true,
+       .hold_start   = true,
+       .eq_drc_en    = true,
+};
+
+struct spdif_chipinfo sm1_spdif_b_chipinfo = {
+       .id           = SPDIF_B,
+       .chnum_en     = true,
+       .hold_start   = true,
+       .eq_drc_en    = true,
+};
+
+static const struct of_device_id aml_spdif_device_id[] = {
+       {
+               .compatible = "amlogic, axg-snd-spdif",
+               .data       = &axg_spdif_chipinfo,
+       },
+       {
+               .compatible = "amlogic, g12a-snd-spdif-a",
+               .data       = &g12a_spdif_a_chipinfo,
+       },
+       {
+               .compatible = "amlogic, g12a-snd-spdif-b",
+               .data       = &g12a_spdif_b_chipinfo,
+       },
+       {
+               .compatible = "amlogic, tl1-snd-spdif-a",
+               .data       = &tl1_spdif_a_chipinfo,
+       },
+       {
+               .compatible = "amlogic, tl1-snd-spdif-b",
+               .data       = &tl1_spdif_b_chipinfo,
+       },
+       {
+               .compatible = "amlogic, sm1-snd-spdif-a",
+               .data           = &sm1_spdif_a_chipinfo,
+       },
+       {
+               .compatible = "amlogic, sm1-snd-spdif-b",
+               .data           = &sm1_spdif_b_chipinfo,
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, aml_spdif_device_id);
index 1a27094..c1a98cf 100644 (file)
 #include "vad.h"
 #include "spdif_hw.h"
 
-/*#define __PTM_TDM_CLK__*/
+#include "tdm_match_table.c"
 
+/*#define __PTM_TDM_CLK__*/
 
-#define DRV_NAME "aml_tdm"
 
-#define TDM_A  0
-#define TDM_B  1
-#define TDM_C  2
-#define LANE_MAX 4
+#define DRV_NAME "snd_tdm"
 
 static int aml_dai_set_tdm_sysclk(struct snd_soc_dai *cpu_dai,
                                int clk_id, unsigned int freq, int dir);
@@ -78,29 +75,6 @@ static void dump_pcm_setting(struct pcm_setting *setting)
        pr_debug("\tlane_lb_mask_in(%#x)\n", setting->lane_lb_mask_in);
 }
 
-struct tdm_chipinfo {
-       /* device id */
-       unsigned int id;
-
-       /* no eco, sclk_ws_inv for out */
-       bool sclk_ws_inv;
-
-       /* output en (oe) for pinmux */
-       bool oe_fn;
-
-       /* clk pad */
-       bool clk_pad_ctl;
-
-       /* same source */
-       bool same_src_fn;
-
-       /* same source, spdif re-enable */
-       bool same_src_spdif_reen;
-
-       /* ACODEC_ADC function */
-       bool adc_fn;
-};
-
 struct aml_tdm {
        struct pcm_setting setting;
        struct pinctrl *pin_ctl;
@@ -123,6 +97,7 @@ struct aml_tdm {
        int samesource_sel;
        /* share buffer lane setting from DTS */
        int lane_ss;
+       int mclk_pad;
        /* virtual link for i2s to hdmitx */
        int i2s2hdmitx;
        int acodec_adc;
@@ -131,6 +106,7 @@ struct aml_tdm {
        uint last_fmt;
 
        bool en_share;
+       unsigned int lane_cnt;
 };
 
 static const struct snd_pcm_hardware aml_tdm_hardware = {
@@ -724,6 +700,7 @@ static int aml_tdm_set_lanes(struct aml_tdm *p_tdm,
        unsigned int lane_mask;
        unsigned int set_num = 0;
        unsigned int i;
+       //unsigned int swap0_val = 0, swap1_val = 0, lane_chs = 0;
 
        pr_debug("asoc channels:%d, slots:%d\n", channels, setting->slots);
 
@@ -735,6 +712,7 @@ static int aml_tdm_set_lanes(struct aml_tdm *p_tdm,
                return -EINVAL;
        }
 
+#if 1
        if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
                // set lanes mask acordingly
                if (p_tdm->chipinfo
@@ -752,7 +730,7 @@ static int aml_tdm_set_lanes(struct aml_tdm *p_tdm,
                }
                swap_val = 0x76543210;
                aml_tdm_set_lane_channel_swap(p_tdm->actrl,
-                       stream, p_tdm->id, swap_val);
+                       stream, p_tdm->id, swap_val, 0x0);
        } else {
                if (p_tdm->chipinfo
                        && p_tdm->chipinfo->oe_fn
@@ -774,29 +752,83 @@ static int aml_tdm_set_lanes(struct aml_tdm *p_tdm,
                }
 
                aml_tdm_set_lane_channel_swap(p_tdm->actrl,
-                       stream, p_tdm->id, swap_val);
+                       stream, p_tdm->id, swap_val, 0x0);
        }
 
+#else
+       if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               if (p_tdm->chipinfo
+                       && p_tdm->chipinfo->oe_fn
+                       && p_tdm->setting.lane_oe_mask_out)
+                       lane_mask = setting->lane_oe_mask_out;
+               else
+                       lane_mask = setting->lane_mask_out;
+       } else {
+               if (p_tdm->chipinfo
+                       && p_tdm->chipinfo->oe_fn
+                       && p_tdm->setting.lane_oe_mask_in)
+                       lane_mask = setting->lane_oe_mask_in;
+               else
+                       lane_mask = setting->lane_mask_in;
+       }
 
+       /* lane mask */
+       for (i = 0; i < 4; i++) {
+               if (((1 << i) & lane_mask) && lanes) {
+                       aml_tdm_set_channel_mask(p_tdm->actrl,
+                               stream, p_tdm->id, i, setting->tx_mask);
+                       lanes--;
+               }
+       }
+
+       /* channel swap */
+       for (i = 0; i < p_tdm->lane_cnt; i++) {
+               if ((1 << i) & lane_mask) {
+                       swap0_val |= (1 << (2 * i)) - 1;
+                       lane_chs += 1;
+                       if (lane_chs >= channels)
+                               break;
+                       swap0_val |= (1 << (2 * i + 1)) - 1;
+                       lane_chs += 1;
+                       if (lane_chs >= channels)
+                               break;
+
+                       if (i >= LANE_MAX1) {
+                               swap1_val |= (1 << (2 * (i - LANE_MAX1))) - 1;
+                               lane_chs += 1;
+                               if (lane_chs >= channels)
+                                       break;
+                               swap1_val |= (1 << (2 * (i - LANE_MAX1) + 1))
+                                                               - 1;
+                               lane_chs += 1;
+                               if (lane_chs >= channels)
+                                       break;
+                       }
+               }
+       }
+       aml_tdm_set_lane_channel_swap(p_tdm->actrl,
+               stream, p_tdm->id, swap0_val, swap1_val);
+#endif
        return 0;
 }
 
 static int aml_tdm_set_clk_pad(struct aml_tdm *p_tdm)
 {
-       unsigned int mpad, mclk_sel;
-
-       // TODO: update pad
-       if (p_tdm->id >= 1) {
-               mpad = p_tdm->id - 1;
-               mclk_sel = p_tdm->id;
-       } else {
-               mpad = 0;
-               mclk_sel = 0;
-       }
+       int mpad_offset = 0;
+       /* mclk pad
+        * does mclk need?
+        * mclk from which mclk source,  mclk_a/b/c/d/e/f
+        * mclk pad controlled by dts, mclk source according to id
+        */
+       if (p_tdm->chipinfo && (!p_tdm->chipinfo->mclkpad_no_offset))
+               mpad_offset = 1;
 
-       /* clk pad */
-       aml_tdm_clk_pad_select(p_tdm->actrl, mpad, mclk_sel,
-               p_tdm->id, p_tdm->clk_sel);
+       aml_tdm_clk_pad_select(p_tdm->actrl,
+               p_tdm->mclk_pad,
+               mpad_offset,
+               p_tdm->id,
+               p_tdm->id,
+               p_tdm->clk_sel);
 
        return 0;
 }
@@ -833,7 +865,7 @@ static int aml_dai_tdm_hw_params(struct snd_pcm_substream *substream,
        if (ret)
                return ret;
 
-       if (p_tdm->chipinfo && p_tdm->chipinfo->clk_pad_ctl) {
+       if (p_tdm->chipinfo && (!p_tdm->chipinfo->no_mclkpad_ctrl)) {
                ret = aml_tdm_set_clk_pad(p_tdm);
                if (ret)
                        return ret;
@@ -870,7 +902,7 @@ static int aml_dai_tdm_hw_params(struct snd_pcm_substream *substream,
        }
 
        if (!p_tdm->contns_clk && !IS_ERR(p_tdm->mclk)) {
-               pr_debug("%s(), enable mclk for %s", __func__, cpu_dai->name);
+               pr_debug("%s(), enable mclk for %s\n", __func__, cpu_dai->name);
                ret = clk_prepare_enable(p_tdm->mclk);
                if (ret) {
                        pr_err("Can't enable mclk: %d\n", ret);
@@ -1298,113 +1330,6 @@ static const struct snd_soc_component_driver aml_tdm_component = {
        .name              = DRV_NAME,
 };
 
-struct tdm_chipinfo axg_tdma_chipinfo = {
-       .id          = TDM_A,
-};
-
-struct tdm_chipinfo axg_tdmb_chipinfo = {
-       .id          = TDM_B,
-};
-
-struct tdm_chipinfo axg_tdmc_chipinfo = {
-       .id          = TDM_C,
-};
-
-struct tdm_chipinfo g12a_tdma_chipinfo = {
-       .id          = TDM_A,
-       .sclk_ws_inv = true,
-       .oe_fn       = true,
-       .clk_pad_ctl = true,
-       .same_src_fn = true,
-};
-
-struct tdm_chipinfo g12a_tdmb_chipinfo = {
-       .id          = TDM_B,
-       .sclk_ws_inv = true,
-       .oe_fn       = true,
-       .clk_pad_ctl = true,
-       .same_src_fn = true,
-};
-
-struct tdm_chipinfo g12a_tdmc_chipinfo = {
-       .id          = TDM_C,
-       .sclk_ws_inv = true,
-       .oe_fn       = true,
-       .clk_pad_ctl = true,
-       .same_src_fn = true,
-};
-
-struct tdm_chipinfo tl1_tdma_chipinfo = {
-       .id          = TDM_A,
-       .sclk_ws_inv = true,
-       .oe_fn       = true,
-       .clk_pad_ctl = true,
-       .same_src_fn = true,
-       .adc_fn      = true,
-       .same_src_spdif_reen = true,
-};
-
-struct tdm_chipinfo tl1_tdmb_chipinfo = {
-       .id          = TDM_B,
-       .sclk_ws_inv = true,
-       .oe_fn       = true,
-       .clk_pad_ctl = true,
-       .same_src_fn = true,
-       .adc_fn      = true,
-       .same_src_spdif_reen = true,
-};
-
-struct tdm_chipinfo tl1_tdmc_chipinfo = {
-       .id          = TDM_C,
-       .sclk_ws_inv = true,
-       .oe_fn       = true,
-       .clk_pad_ctl = true,
-       .same_src_fn = true,
-       .adc_fn      = true,
-       .same_src_spdif_reen = true,
-};
-
-static const struct of_device_id aml_tdm_device_id[] = {
-       {
-               .compatible = "amlogic, axg-snd-tdma",
-               .data       = &axg_tdma_chipinfo,
-       },
-       {
-               .compatible = "amlogic, axg-snd-tdmb",
-               .data       = &axg_tdmb_chipinfo,
-       },
-       {
-               .compatible = "amlogic, axg-snd-tdmc",
-               .data       = &axg_tdmc_chipinfo,
-       },
-       {
-               .compatible = "amlogic, g12a-snd-tdma",
-               .data       = &g12a_tdma_chipinfo,
-       },
-       {
-               .compatible = "amlogic, g12a-snd-tdmb",
-               .data       = &g12a_tdmb_chipinfo,
-       },
-       {
-               .compatible = "amlogic, g12a-snd-tdmc",
-               .data       = &g12a_tdmc_chipinfo,
-       },
-       {
-               .compatible = "amlogic, tl1-snd-tdma",
-               .data       = &tl1_tdma_chipinfo,
-       },
-       {
-               .compatible = "amlogic, tl1-snd-tdmb",
-               .data       = &tl1_tdmb_chipinfo,
-       },
-       {
-               .compatible = "amlogic, tl1-snd-tdmc",
-               .data       = &tl1_tdmc_chipinfo,
-       },
-       {},
-};
-MODULE_DEVICE_TABLE(of, aml_tdm_device_id);
-
 static int check_channel_mask(const char *str)
 {
        int ret = -1;
@@ -1474,6 +1399,10 @@ static int aml_tdm_platform_probe(struct platform_device *pdev)
        }
        p_tdm->chipinfo = p_chipinfo;
        p_tdm->id = p_chipinfo->id;
+       if (!p_chipinfo->lane_cnt)
+               p_chipinfo->lane_cnt = LANE_MAX1;
+       else
+               p_tdm->lane_cnt = p_chipinfo->lane_cnt;
        pr_info("%s, tdm ID = %u\n", __func__, p_tdm->id);
 
        /* get audio controller */
@@ -1605,6 +1534,12 @@ static int aml_tdm_platform_probe(struct platform_device *pdev)
                /*return PTR_ERR(p_tdm->pin_ctl);*/
        }
 
+       /* mclk pad ctrl */
+       ret = of_property_read_u32(node, "mclk_pad",
+                       &p_tdm->mclk_pad);
+       if (ret < 0)
+               p_tdm->mclk_pad = -1; /* not use mclk in defalut. */
+
        p_tdm->dev = dev;
        /* For debug to disable share buffer */
        p_tdm->en_share = 1;
index a685e58..c3d9863 100644 (file)
@@ -545,10 +545,20 @@ void aml_tdm_set_channel_mask(
        unsigned int offset, reg;
 
        if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               offset = EE_AUDIO_TDMOUT_B_MASK0 - EE_AUDIO_TDMOUT_A_MASK0;
+               if (lane >= LANE_MAX1)
+                       offset = EE_AUDIO_TDMOUT_B_MASK4
+                               - EE_AUDIO_TDMOUT_A_MASK4;
+               else
+                       offset = EE_AUDIO_TDMOUT_B_MASK0
+                               - EE_AUDIO_TDMOUT_A_MASK0;
                reg = EE_AUDIO_TDMOUT_A_MASK0 + offset * index;
        } else {
-               offset = EE_AUDIO_TDMIN_B_MASK0 - EE_AUDIO_TDMIN_A_MASK0;
+               if (lane >= LANE_MAX1)
+                       offset = EE_AUDIO_TDMIN_B_MASK4
+                               - EE_AUDIO_TDMIN_A_MASK4;
+               else
+                       offset = EE_AUDIO_TDMIN_B_MASK0
+                               - EE_AUDIO_TDMIN_A_MASK0;
                reg = EE_AUDIO_TDMIN_A_MASK0 + offset * index;
        }
 
@@ -557,27 +567,39 @@ void aml_tdm_set_channel_mask(
 
 void aml_tdm_set_lane_channel_swap(
        struct aml_audio_controller *actrl,
-       int stream, int index, int swap)
+       int stream, int index, int swap0, int swap1)
 {
        unsigned int offset, reg;
 
-       if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               // set lanes mask acordingly
-               offset = EE_AUDIO_TDMOUT_B_MASK0 - EE_AUDIO_TDMOUT_A_MASK0;
-               reg = EE_AUDIO_TDMOUT_A_MASK0 + offset * index;
+       pr_debug("\t %s swap0 = %#x, swap1 = %#x\n",
+               (stream == SNDRV_PCM_STREAM_PLAYBACK) ? "tdmout" : "tdmin",
+               swap0,
+               swap1);
 
-               pr_debug("\ttdmout swap val = %#x\n", swap);
-               offset = EE_AUDIO_TDMOUT_B_SWAP - EE_AUDIO_TDMOUT_A_SWAP;
-               reg = EE_AUDIO_TDMOUT_A_SWAP + offset * index;
-               aml_audiobus_write(actrl, reg, swap);
+       if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               offset = EE_AUDIO_TDMOUT_B_SWAP0
+                       - EE_AUDIO_TDMOUT_A_SWAP0;
+               reg = EE_AUDIO_TDMOUT_A_SWAP0 + offset * index;
+               aml_audiobus_write(actrl, reg, swap0);
+
+               if (swap1) {
+                       offset = EE_AUDIO_TDMOUT_B_SWAP1
+                               - EE_AUDIO_TDMOUT_A_SWAP1;
+                       reg = EE_AUDIO_TDMOUT_A_SWAP1 + offset * index;
+                       aml_audiobus_write(actrl, reg, swap1);
+               }
        } else {
-               offset = EE_AUDIO_TDMIN_B_MASK0 - EE_AUDIO_TDMIN_A_MASK0;
-               reg = EE_AUDIO_TDMIN_A_MASK0 + offset * index;
-
-               pr_debug("\ttdmin swap val = %#x\n", swap);
-               offset = EE_AUDIO_TDMIN_B_SWAP - EE_AUDIO_TDMIN_A_SWAP;
-               reg = EE_AUDIO_TDMIN_A_SWAP + offset * index;
-               aml_audiobus_write(actrl, reg, swap);
+               offset = EE_AUDIO_TDMIN_B_SWAP0
+                       - EE_AUDIO_TDMIN_A_SWAP0;
+               reg = EE_AUDIO_TDMIN_A_SWAP0 + offset * index;
+               aml_audiobus_write(actrl, reg, swap0);
+
+               if (swap1) {
+                       offset = EE_AUDIO_TDMIN_B_SWAP1
+                               - EE_AUDIO_TDMIN_A_SWAP1;
+                       reg = EE_AUDIO_TDMIN_A_SWAP1 + offset * index;
+                       aml_audiobus_write(actrl, reg, swap1);
+               }
        }
 }
 
@@ -649,27 +671,39 @@ void aml_tdmout_enable_gain(int tdmout_id, int en)
 
 void aml_tdm_clk_pad_select(
        struct aml_audio_controller *actrl,
-       int mpad, int mclk_sel,
+       int mpad, int mpad_offset, int mclk_sel,
        int tdm_index, int clk_sel)
 {
        unsigned int reg, mask_offset, val_offset;
 
-       // TODO: fix mclk
-       if (mpad == 0) {
-               mask_offset = 0x7 << 0;
-               val_offset = mclk_sel << 0;
-       } else if (mpad == 1) {
-               mask_offset = 0x7 << 4;
-               val_offset = mclk_sel << 4;
-       } else {
-               pr_err("unknown tdm mpad:%d\n", mpad);
-               return;
-       }
-       reg = EE_AUDIO_MST_PAD_CTRL0(0);
-       aml_audiobus_update_bits(actrl, reg,
-               mask_offset, val_offset);
+       if (mpad >= 0) {
+               switch (mpad) {
+               case 0:
+                       mask_offset = 0x7 << 0;
+                       val_offset = mclk_sel << 0;
+                       break;
+               case 1:
+                       mask_offset = 0x7 << 4;
+                       val_offset = mclk_sel << 4;
+                       break;
+               default:
+                       mask_offset = 0;
+                       val_offset = 0;
+                       pr_info("unknown tdm mpad:%d\n", mpad);
+                       break;
+               }
 
-       reg = EE_AUDIO_MST_PAD_CTRL1(0);
+               reg = EE_AUDIO_MST_PAD_CTRL0(mpad_offset);
+               if (actrl)
+                       aml_audiobus_update_bits(actrl, reg,
+                               mask_offset, val_offset);
+               else
+                       audiobus_update_bits(reg,
+                               mask_offset, val_offset);
+       } else
+               pr_warn("mclk is not configured\n");
+
+       reg = EE_AUDIO_MST_PAD_CTRL1(mpad_offset);
        switch (tdm_index) {
        case 0:
                mask_offset = 0x7 << 16 | 0x7 << 0;
@@ -684,12 +718,15 @@ void aml_tdm_clk_pad_select(
                val_offset = clk_sel << 24 | clk_sel << 8;
                break;
        default:
-               pr_err("unknown tdm index:%d\n", tdm_index);
+               pr_err("unknown mclk pad, tdm index:%d\n", tdm_index);
                return;
        }
-       aml_audiobus_update_bits(actrl, reg,
-               mask_offset, val_offset);
-
+       if (actrl)
+               aml_audiobus_update_bits(actrl, reg,
+                       mask_offset, val_offset);
+       else
+               audiobus_update_bits(reg,
+                       mask_offset, val_offset);
 }
 
 void i2s_to_hdmitx_ctrl(int tdm_index)
index 2c5fe03..dc12289 100644 (file)
 #include "audio_io.h"
 #include "regs.h"
 
+#define TDM_A  0
+#define TDM_B  1
+#define TDM_C  2
+
+#define LANE_MAX0 2
+#define LANE_MAX1 4
+#define LANE_MAX2 6
+#define LANE_MAX3 8
+
 //     TODO: fix me, now based by tl1
 enum tdmin_src {
        PAD_TDMINA_DIN = 0,
@@ -118,7 +127,7 @@ extern void aml_tdm_set_channel_mask(
 
 extern void aml_tdm_set_lane_channel_swap(
        struct aml_audio_controller *actrl,
-       int stream, int index, int swap);
+       int stream, int index, int swap0, int swap1);
 
 extern void aml_tdm_set_bclk_ratio(
        struct aml_audio_controller *actrl,
@@ -139,7 +148,7 @@ extern void aml_tdmout_get_aed_info(int tdmout_id,
 
 extern void aml_tdm_clk_pad_select(
        struct aml_audio_controller *actrl,
-       int mpad, int mclk_sel,
+       int mpad, int mpad_offset, int mclk_sel,
        int tdm_index, int clk_sel);
 
 extern void i2s_to_hdmitx_ctrl(int tdm_index);
diff --git a/sound/soc/amlogic/auge/tdm_match_table.c b/sound/soc/amlogic/auge/tdm_match_table.c
new file mode 100644 (file)
index 0000000..fd56921
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * sound/soc/amlogic/auge/tdm_match_table.c
+ *
+ * Copyright (C) 2019 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+struct tdm_chipinfo {
+       /* device id */
+       unsigned int id;
+
+       /* lane max count */
+       unsigned int lane_cnt;
+
+       /* no eco, sclk_ws_inv for out */
+       bool sclk_ws_inv;
+
+       /* output en (oe) for pinmux */
+       bool oe_fn;
+
+       /* clk pad */
+       bool no_mclkpad_ctrl;
+
+       /* same source */
+       bool same_src_fn;
+
+       /* same source, spdif re-enable */
+       bool same_src_spdif_reen;
+
+       /* ACODEC_ADC function */
+       bool adc_fn;
+
+       /* mclk pad offset */
+       bool mclkpad_no_offset;
+};
+
+
+struct tdm_chipinfo axg_tdma_chipinfo = {
+       .id          = TDM_A,
+       .no_mclkpad_ctrl = true,
+};
+
+struct tdm_chipinfo axg_tdmb_chipinfo = {
+       .id          = TDM_B,
+       .no_mclkpad_ctrl = true,
+};
+
+struct tdm_chipinfo axg_tdmc_chipinfo = {
+       .id          = TDM_C,
+       .no_mclkpad_ctrl = true,
+};
+
+struct tdm_chipinfo g12a_tdma_chipinfo = {
+       .id          = TDM_A,
+       .sclk_ws_inv = true,
+       .oe_fn       = true,
+       .same_src_fn = true,
+       .mclkpad_no_offset = true,
+};
+
+struct tdm_chipinfo g12a_tdmb_chipinfo = {
+       .id          = TDM_B,
+       .sclk_ws_inv = true,
+       .oe_fn       = true,
+       .same_src_fn = true,
+       .mclkpad_no_offset = true,
+};
+
+struct tdm_chipinfo g12a_tdmc_chipinfo = {
+       .id          = TDM_C,
+       .sclk_ws_inv = true,
+       .oe_fn       = true,
+       .same_src_fn = true,
+       .mclkpad_no_offset = true,
+};
+
+struct tdm_chipinfo tl1_tdma_chipinfo = {
+       .id          = TDM_A,
+       .sclk_ws_inv = true,
+       .oe_fn       = true,
+       .same_src_fn = true,
+       .adc_fn      = true,
+};
+
+struct tdm_chipinfo tl1_tdmb_chipinfo = {
+       .id          = TDM_B,
+       .sclk_ws_inv = true,
+       .oe_fn       = true,
+       .same_src_fn = true,
+       .adc_fn      = true,
+};
+
+struct tdm_chipinfo tl1_tdmc_chipinfo = {
+       .id          = TDM_C,
+       .sclk_ws_inv = true,
+       .oe_fn       = true,
+       .same_src_fn = true,
+       .adc_fn      = true,
+};
+
+struct tdm_chipinfo sm1_tdma_chipinfo = {
+       .id          = TDM_A,
+       .sclk_ws_inv = true,
+       .oe_fn       = true,
+       .same_src_fn = true,
+       .lane_cnt    = LANE_MAX0,
+};
+
+struct tdm_chipinfo sm1_tdmb_chipinfo = {
+       .id          = TDM_B,
+       .sclk_ws_inv = true,
+       .oe_fn       = true,
+       .same_src_fn = true,
+       .lane_cnt    = LANE_MAX3,
+};
+
+struct tdm_chipinfo sm1_tdmc_chipinfo = {
+       .id          = TDM_C,
+       .sclk_ws_inv = true,
+       .oe_fn       = true,
+       .same_src_fn = true,
+       .lane_cnt    = LANE_MAX1,
+};
+
+static const struct of_device_id aml_tdm_device_id[] = {
+       {
+               .compatible = "amlogic, axg-snd-tdma",
+               .data       = &axg_tdma_chipinfo,
+       },
+       {
+               .compatible = "amlogic, axg-snd-tdmb",
+               .data       = &axg_tdmb_chipinfo,
+       },
+       {
+               .compatible = "amlogic, axg-snd-tdmc",
+               .data       = &axg_tdmc_chipinfo,
+       },
+       {
+               .compatible = "amlogic, g12a-snd-tdma",
+               .data       = &g12a_tdma_chipinfo,
+       },
+       {
+               .compatible = "amlogic, g12a-snd-tdmb",
+               .data       = &g12a_tdmb_chipinfo,
+       },
+       {
+               .compatible = "amlogic, g12a-snd-tdmc",
+               .data       = &g12a_tdmc_chipinfo,
+       },
+       {
+               .compatible = "amlogic, tl1-snd-tdma",
+               .data       = &tl1_tdma_chipinfo,
+       },
+       {
+               .compatible = "amlogic, tl1-snd-tdmb",
+               .data       = &tl1_tdmb_chipinfo,
+       },
+       {
+               .compatible = "amlogic, tl1-snd-tdmc",
+               .data       = &tl1_tdmc_chipinfo,
+       },
+       {
+               .compatible = "amlogic, sm1-snd-tdma",
+               .data           = &sm1_tdma_chipinfo,
+       },
+       {
+               .compatible = "amlogic, sm1-snd-tdmb",
+               .data           = &sm1_tdmb_chipinfo,
+       },
+       {
+               .compatible = "amlogic, sm1-snd-tdmc",
+               .data           = &sm1_tdmc_chipinfo,
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, aml_tdm_device_id);
index 9af6860..1786326 100644 (file)
@@ -155,7 +155,7 @@ static int __init vad_init(void)
                goto err2;
        }
 
-       pr_info("Register %s", DRV_NAME);
+       pr_info("Register %s\n", DRV_NAME);
 
        return 0;
 err2: