audio: Add pcm slots configs [1/1]
authorShuai Li <shuai.li@amlogic.com>
Thu, 6 Jun 2019 09:25:03 +0000 (17:25 +0800)
committerNick Xie <nick@khadas.com>
Mon, 5 Aug 2019 07:10:53 +0000 (15:10 +0800)
PD#SWPL-4711

Problem:
BT pcm record doesn't work.

Solution:
Add pcm configs in DTS.

Verify:
ampere

Change-Id: I87c2cb62fb803527da089c5a2aea33752939e000
Signed-off-by: Shuai Li <shuai.li@amlogic.com>
15 files changed:
arch/arm/boot/dts/amlogic/gxl_p212_1g.dts
arch/arm/boot/dts/amlogic/gxl_p212_1g_buildroot.dts
arch/arm/boot/dts/amlogic/gxl_p212_1g_hd.dts
arch/arm/boot/dts/amlogic/gxl_p212_2g.dts
arch/arm/boot/dts/amlogic/gxl_p212_2g_buildroot.dts
arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts
arch/arm64/boot/dts/amlogic/gxl_p212_1g_buildroot.dts
arch/arm64/boot/dts/amlogic/gxl_p212_1g_hd.dts
arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts
arch/arm64/boot/dts/amlogic/gxl_p212_2g_buildroot.dts
arch/arm64/boot/dts/amlogic/kvim_linux.dts
sound/soc/amlogic/meson/audio_hw_pcm.c
sound/soc/amlogic/meson/audio_hw_pcm.h
sound/soc/amlogic/meson/pcm_dai.c
sound/soc/amlogic/meson/pcm_dai.h

index 0edc324..40215ac 100644 (file)
                        "pcm_mclk",
                        "pcm_sclk";
                pcm_mode = <1>; /* 0=slave mode, 1=master mode */
+               dai-format = "dsp_a";
+               dai-tdm-slot-tx-mask = <1>;
+               dai-tdm-slot-rx-mask = <1>;
+               dai-tdm-slot-num = <2>;
+               dai-tdm-slot-width = <16>;
        };
        i2s_plat: i2s_platform {
                compatible = "amlogic, aml-i2s";
index 9efc128..9b6687b 100644 (file)
                        "pcm_mclk",
                        "pcm_sclk";
                pcm_mode = <1>; /* 0=slave mode, 1=master mode */
+               dai-format = "dsp_a";
+               dai-tdm-slot-tx-mask = <1>;
+               dai-tdm-slot-rx-mask = <1>;
+               dai-tdm-slot-num = <2>;
+               dai-tdm-slot-width = <16>;
        };
        i2s_plat: i2s_platform {
                compatible = "amlogic, aml-i2s";
index 868fa5d..3ca951f 100644 (file)
                        "pcm_mclk",
                        "pcm_sclk";
                pcm_mode = <1>; /* 0=slave mode, 1=master mode */
+               dai-format = "dsp_a";
+               dai-tdm-slot-tx-mask = <1>;
+               dai-tdm-slot-rx-mask = <1>;
+               dai-tdm-slot-num = <2>;
+               dai-tdm-slot-width = <16>;
        };
        i2s_plat: i2s_platform {
                compatible = "amlogic, aml-i2s";
index 336df90..3292851 100644 (file)
                        "pcm_mclk",
                        "pcm_sclk";
                pcm_mode = <1>; /* 0=slave mode, 1=master mode */
+               dai-format = "dsp_a";
+               dai-tdm-slot-tx-mask = <1>;
+               dai-tdm-slot-rx-mask = <1>;
+               dai-tdm-slot-num = <2>;
+               dai-tdm-slot-width = <16>;
        };
        i2s_plat: i2s_platform {
                compatible = "amlogic, aml-i2s";
index 5aadcac..a32d289 100644 (file)
                        "pcm_mclk",
                        "pcm_sclk";
                pcm_mode = <1>; /* 0=slave mode, 1=master mode */
+               dai-format = "dsp_a";
+               dai-tdm-slot-tx-mask = <1>;
+               dai-tdm-slot-rx-mask = <1>;
+               dai-tdm-slot-num = <2>;
+               dai-tdm-slot-width = <16>;
        };
        i2s_plat: i2s_platform {
                compatible = "amlogic, aml-i2s";
index c4767fc..b24668a 100644 (file)
                        "pcm_mclk",
                        "pcm_sclk";
                pcm_mode = <1>; /* 0=slave mode, 1=master mode */
+               dai-format = "dsp_a";
+               dai-tdm-slot-tx-mask = <1>;
+               dai-tdm-slot-rx-mask = <1>;
+               dai-tdm-slot-num = <2>;
+               dai-tdm-slot-width = <16>;
        };
        i2s_plat: i2s_platform {
                compatible = "amlogic, aml-i2s";
index 57c2412..d4233f4 100644 (file)
                        "pcm_mclk",
                        "pcm_sclk";
                pcm_mode = <1>; /* 0=slave mode, 1=master mode */
+               dai-format = "dsp_a";
+               dai-tdm-slot-tx-mask = <1>;
+               dai-tdm-slot-rx-mask = <1>;
+               dai-tdm-slot-num = <2>;
+               dai-tdm-slot-width = <16>;
        };
        i2s_plat: i2s_platform {
                compatible = "amlogic, aml-i2s";
index 85f64e4..3e60766 100644 (file)
                        "pcm_mclk",
                        "pcm_sclk";
                pcm_mode = <1>; /* 0=slave mode, 1=master mode */
+               dai-format = "dsp_a";
+               dai-tdm-slot-tx-mask = <1>;
+               dai-tdm-slot-rx-mask = <1>;
+               dai-tdm-slot-num = <2>;
+               dai-tdm-slot-width = <16>;
        };
        i2s_plat: i2s_platform {
                compatible = "amlogic, aml-i2s";
index 302ea68..0785aab 100644 (file)
                        "pcm_mclk",
                        "pcm_sclk";
                pcm_mode = <1>; /* 0=slave mode, 1=master mode */
+               dai-format = "dsp_a";
+               dai-tdm-slot-tx-mask = <1>;
+               dai-tdm-slot-rx-mask = <1>;
+               dai-tdm-slot-num = <2>;
+               dai-tdm-slot-width = <16>;
        };
        i2s_plat: i2s_platform {
                compatible = "amlogic, aml-i2s";
index 8003e5d..a0fec90 100644 (file)
                        "pcm_mclk",
                        "pcm_sclk";
                pcm_mode = <1>; /* 0=slave mode, 1=master mode */
+               dai-format = "dsp_a";
+               dai-tdm-slot-tx-mask = <1>;
+               dai-tdm-slot-rx-mask = <1>;
+               dai-tdm-slot-num = <2>;
+               dai-tdm-slot-width = <16>;
        };
        i2s_plat: i2s_platform {
                compatible = "amlogic, aml-i2s";
index 0b9c060..19a090c 100644 (file)
                        "pcm_mclk",
                        "pcm_sclk";
                pcm_mode = <1>; /* 0=slave mode, 1=master mode */
+               dai-format = "dsp_a";
+               dai-tdm-slot-tx-mask = <1>;
+               dai-tdm-slot-rx-mask = <1>;
+               dai-tdm-slot-num = <2>;
+               dai-tdm-slot-width = <16>;
        };
        i2s_plat: i2s_platform {
                compatible = "amlogic, aml-i2s";
index 72c0457..2587adb 100644 (file)
@@ -58,15 +58,6 @@ static int valid_channel[] = {
 /* counter for pcm clk used */
 static int aml_pcm_clk_count;
 
-static unsigned int aml_pcm_format = SND_SOC_DAIFMT_DSP_B;
-
-void aml_set_pcm_format(int pcm_mode)
-{
-       pr_info(" %s, pcm format:0x%x\n", __func__, pcm_mode);
-
-       aml_pcm_format = pcm_mode;
-}
-
 static uint32_t aml_audin_read_bits(uint32_t reg, const uint32_t start,
                                   const uint32_t len)
 {
@@ -94,16 +85,18 @@ static void pcm_in_register_show(void)
                  aml_audin_read(PCMIN_CTRL1));
 }
 
-void pcm_master_in_enable(struct snd_pcm_substream *substream, int flag)
+void pcm_master_in_enable(struct snd_pcm_substream *substream,
+               struct tdm_config cfg, int enable)
 {
        unsigned int fs_offset;
+       unsigned int slots = cfg.slots;
 
-       if (aml_pcm_format == SND_SOC_DAIFMT_DSP_A)
+       if (cfg.fmt == SND_SOC_DAIFMT_DSP_A)
                fs_offset = 1;
        else {
                fs_offset = 0;
 
-               if (aml_pcm_format != SND_SOC_DAIFMT_DSP_B)
+               if (cfg.fmt != SND_SOC_DAIFMT_DSP_B)
                        pr_err("Unsupport DSP mode\n");
        }
 
@@ -127,13 +120,17 @@ RESET_FIFO:
        /* disable pcmin */
        aml_audin_update_bits(PCMIN_CTRL0, 1 << 31, 0 << 31);
 
-       if (flag) {
+       if (enable) {
                unsigned int pcm_mode = 1, pcm_wlen = 16;
                unsigned int num_slot = substream->runtime->channels;
                unsigned int valid_slot = valid_channel[num_slot - 1];
                unsigned int max_bits;
                unsigned int valid_bits;
 
+               /* if no slots is set, use the channel num */
+               if (slots == 0)
+                       slots = num_slot;
+
                /* whatever pcm out is enable */
                aml_pcm_clk_count++;
 
@@ -226,12 +223,12 @@ RESET_FIFO:
                        unsigned int bit_offset_s = 0, slot_offset_s = 0,
                                bit_offset_e = 0, slot_offset_e = 0;
 
-                       if (aml_pcm_format == SND_SOC_DAIFMT_DSP_A) {
+                       if (cfg.fmt == SND_SOC_DAIFMT_DSP_A) {
                                bit_offset_s = pcm_wlen - 1;
-                               slot_offset_s = num_slot - 1;
+                               slot_offset_s = slots - 1;
                                bit_offset_e = 0;
                                slot_offset_e = 0;
-                       } else if (aml_pcm_format == SND_SOC_DAIFMT_DSP_B) {
+                       } else if (cfg.fmt == SND_SOC_DAIFMT_DSP_B) {
                                bit_offset_s = 0;
                                slot_offset_s = 0;
                                bit_offset_e = 1;
@@ -248,7 +245,7 @@ RESET_FIFO:
                                /* underrun use mute constant */
                                (0 << 29) |
                                /* pcmo max slot number in one frame*/
-                               ((num_slot - 1) << 22) |
+                               ((slots - 1) << 22) |
                                /* pcmo max bit number in one slot*/
                                (valid_bits << 16) |
                                (valid_slot << 0)
@@ -286,21 +283,22 @@ RESET_FIFO:
                }
        }
 
-       pr_debug("PCMIN %s\n", flag ? "enable" : "disable");
+       pr_debug("PCMIN %s\n", enable ? "enable" : "disable");
        pcm_in_register_show();
 }
 
 
-void pcm_in_enable(struct snd_pcm_substream *substream, int flag)
+void pcm_in_enable(struct snd_pcm_substream *substream,
+               struct tdm_config cfg, int enable)
 {
        unsigned int fs_offset;
 
-       if (aml_pcm_format == SND_SOC_DAIFMT_DSP_A)
+       if (cfg.fmt == SND_SOC_DAIFMT_DSP_A)
                fs_offset = 1;
        else {
                fs_offset = 0;
 
-               if (aml_pcm_format != SND_SOC_DAIFMT_DSP_B)
+               if (cfg.fmt != SND_SOC_DAIFMT_DSP_B)
                        pr_err("Unsupport DSP mode\n");
        }
        /* reset fifo */
@@ -322,7 +320,7 @@ void pcm_in_enable(struct snd_pcm_substream *substream, int flag)
        /* disable pcmin */
        aml_audin_update_bits(PCMIN_CTRL0, 1 << 31, 0 << 31);
 
-       if (flag) {
+       if (enable) {
                unsigned int pcm_mode = 1;
                unsigned int num_slot = substream->runtime->channels;
                unsigned int valid_slot = valid_channel[num_slot - 1];
@@ -414,7 +412,7 @@ void pcm_in_enable(struct snd_pcm_substream *substream, int flag)
                        (1 << 0));      /* left justified */
        }
 
-       pr_debug("PCMIN %s\n", flag ? "enable" : "disable");
+       pr_debug("PCMIN %s\n", enable ? "enable" : "disable");
        pcm_in_register_show();
 }
 
@@ -505,7 +503,8 @@ static void pcm_out_register_show(void)
                  aml_audin_read(PCMOUT_CTRL3));
 }
 
-void pcm_master_out_enable(struct snd_pcm_substream *substream, int flag)
+void pcm_master_out_enable(struct snd_pcm_substream *substream,
+               struct tdm_config cfg,  int enable)
 {
        unsigned int pcm_mode = 1, pcm_wlen = 16;
        unsigned int num_slot = substream->runtime->channels;
@@ -513,6 +512,11 @@ void pcm_master_out_enable(struct snd_pcm_substream *substream, int flag)
        unsigned int valid_bits;
        unsigned int bit_offset_s = 0, slot_offset_s = 0,
                        bit_offset_e = 0, slot_offset_e = 0;
+       unsigned int slots = cfg.slots;
+
+       /* if no slots is set, use the channel num */
+       if (slots == 0)
+               slots = num_slot;
 
        switch (substream->runtime->format) {
        case SNDRV_PCM_FORMAT_S32_LE:
@@ -532,12 +536,12 @@ void pcm_master_out_enable(struct snd_pcm_substream *substream, int flag)
        pcm_mode = (pcm_wlen >> 3) - 1;
        valid_bits = pcm_wlen - 1;
 
-       if (aml_pcm_format == SND_SOC_DAIFMT_DSP_A) {
+       if (cfg.fmt == SND_SOC_DAIFMT_DSP_A) {
                bit_offset_s = pcm_wlen - 1;
-               slot_offset_s = num_slot - 1;
+               slot_offset_s = slots - 1;
                bit_offset_e = 0;
                slot_offset_e = 0;
-       } else if (aml_pcm_format == SND_SOC_DAIFMT_DSP_B) {
+       } else if (cfg.fmt == SND_SOC_DAIFMT_DSP_B) {
                bit_offset_s = 0;
                slot_offset_s = 0;
                bit_offset_e = 1;
@@ -545,10 +549,12 @@ void pcm_master_out_enable(struct snd_pcm_substream *substream, int flag)
        } else
                pr_err("Unsupport DSP mode\n");
 
-       pr_info("pcm master out, pcm mode:%d, valid bits:0x%x, valid slot:0x%x\n",
+       pr_info("%s(), mode:%d, valid bits:0x%x, valid slot:0x%x, slots:%d\n",
+               __func__,
                pcm_mode,
                valid_bits,
-               valid_slot);
+               valid_slot,
+               slots);
 
        /* reset fifo */
        aml_audin_update_bits(AUDOUT_CTRL, 1 << 30, 1 << 30);
@@ -564,7 +570,7 @@ void pcm_master_out_enable(struct snd_pcm_substream *substream, int flag)
                aml_audin_update_bits(PCMOUT_CTRL0, 1 << 31, 0 << 31);
        }
 
-       if (flag) {
+       if (enable) {
                /* set buffer start ptr end */
                aml_audin_write(AUDOUT_BUF0_STA, pcmout_buffer_addr);
                aml_audin_write(AUDOUT_BUF0_WPTR, pcmout_buffer_addr);
@@ -617,7 +623,7 @@ void pcm_master_out_enable(struct snd_pcm_substream *substream, int flag)
                        /* underrun use mute constant */
                        (0 << 29) |
                        /* pcmo max slot number in one frame */
-                       ((num_slot - 1) << 22) |
+                       ((slots - 1) << 22) |
                        /* pcmo max bit number in one slot */
                        (valid_bits << 16) |
                        /* pcmo valid slot. each bit for one slot */
@@ -680,11 +686,12 @@ void pcm_master_out_enable(struct snd_pcm_substream *substream, int flag)
                }
        }
 
-       pr_debug("PCMOUT %s\n", flag ? "enable" : "disable");
+       pr_debug("PCMOUT %s\n", enable ? "enable" : "disable");
        pcm_out_register_show();
 }
 
-void pcm_out_enable(struct snd_pcm_substream *substream, int flag)
+void pcm_out_enable(struct snd_pcm_substream *substream,
+               struct tdm_config cfg, int enable)
 {
        unsigned int pcm_mode = 1;
        unsigned int num_slot = substream->runtime->channels;
@@ -692,13 +699,13 @@ void pcm_out_enable(struct snd_pcm_substream *substream, int flag)
        unsigned int valid_bits = 0xf;
        unsigned int bit_offset_s, slot_offset_s, bit_offset_e, slot_offset_e;
 
-       if (aml_pcm_format == SND_SOC_DAIFMT_DSP_A) {
+       if (cfg.fmt == SND_SOC_DAIFMT_DSP_A) {
                bit_offset_s = 0xF;
                slot_offset_s = num_slot - 1;
                bit_offset_e = 0;
                slot_offset_e = 0;
        } else {
-               if (aml_pcm_format != SND_SOC_DAIFMT_DSP_B)
+               if (cfg.fmt != SND_SOC_DAIFMT_DSP_B)
                        pr_err("Unsupport DSP mode\n");
 
                bit_offset_s = 0;
@@ -711,7 +718,7 @@ void pcm_out_enable(struct snd_pcm_substream *substream, int flag)
        case SNDRV_PCM_FORMAT_S32_LE:
                pcm_mode = 3;
                valid_bits = 0x1f;
-               if (aml_pcm_format == SND_SOC_DAIFMT_DSP_A) {
+               if (cfg.fmt == SND_SOC_DAIFMT_DSP_A) {
                        bit_offset_s = 0xF;
                        slot_offset_s = (num_slot << 1) - 1;
                        bit_offset_e = 0;
@@ -721,7 +728,7 @@ void pcm_out_enable(struct snd_pcm_substream *substream, int flag)
        case SNDRV_PCM_FORMAT_S24_LE:
                pcm_mode = 2;
                valid_bits = 0x1f;
-               if (aml_pcm_format == SND_SOC_DAIFMT_DSP_A) {
+               if (cfg.fmt == SND_SOC_DAIFMT_DSP_A) {
                        bit_offset_s = 0xF;
                        slot_offset_s = (num_slot << 1) - 8 - 1;
                        bit_offset_e = 0;
@@ -735,7 +742,7 @@ void pcm_out_enable(struct snd_pcm_substream *substream, int flag)
        case SNDRV_PCM_FORMAT_S8:
                pcm_mode = 0;
                valid_bits = 0x7;
-               if (aml_pcm_format == SND_SOC_DAIFMT_DSP_A) {
+               if (cfg.fmt == SND_SOC_DAIFMT_DSP_A) {
                        bit_offset_s = 0x7;
                        slot_offset_s = (num_slot >> 1) - 1;
                        bit_offset_e = 0;
@@ -763,7 +770,7 @@ void pcm_out_enable(struct snd_pcm_substream *substream, int flag)
        /* disable pcmout */
        aml_audin_update_bits(PCMOUT_CTRL0, 1 << 31, 0 << 31);
 
-       if (flag) {
+       if (enable) {
                /* set buffer start ptr end */
                aml_audin_write(AUDOUT_BUF0_STA, pcmout_buffer_addr);
                aml_audin_write(AUDOUT_BUF0_WPTR, pcmout_buffer_addr);
@@ -848,7 +855,7 @@ void pcm_out_enable(struct snd_pcm_substream *substream, int flag)
                        (0 << 0));
        }
 
-       pr_debug("PCMOUT %s\n", flag ? "enable" : "disable");
+       pr_debug("PCMOUT %s\n", enable ? "enable" : "disable");
        pcm_out_register_show();
 }
 
index 58a3a49..f9e674b 100644 (file)
 
 #include "audio_hw.h"
 
-void aml_set_pcm_format(int pcm_mode);
-void pcm_in_enable(struct snd_pcm_substream *substream, int flag);
+struct tdm_config {
+       unsigned int fmt;
+       unsigned int tx_slot_mask;
+       unsigned int rx_slot_mask;
+       unsigned int slots;
+       unsigned int slot_width;
+};
+
+void pcm_in_enable(struct snd_pcm_substream *substream,
+               struct tdm_config cfg, int enable);
 void pcm_in_set_buf(unsigned int addr, unsigned int size);
 int  pcm_in_is_enable(void);
 unsigned int pcm_in_rd_ptr(void);
@@ -32,7 +40,8 @@ unsigned int pcm_in_wr_ptr(void);
 unsigned int pcm_in_set_rd_ptr(unsigned int value);
 unsigned int pcm_in_fifo_int(void);
 
-void pcm_out_enable(struct snd_pcm_substream *substream, int flag);
+void pcm_out_enable(struct snd_pcm_substream *substream,
+               struct tdm_config cfg, int enable);
 void pcm_out_mute(int flag);
 void pcm_out_set_buf(unsigned int addr, unsigned int size);
 int  pcm_out_is_enable(void);
@@ -41,6 +50,8 @@ unsigned int pcm_out_rd_ptr(void);
 unsigned int pcm_out_wr_ptr(void);
 unsigned int pcm_out_set_wr_ptr(unsigned int value);
 
-void pcm_master_in_enable(struct snd_pcm_substream *substream, int flag);
-void pcm_master_out_enable(struct snd_pcm_substream *substream, int flag);
+void pcm_master_in_enable(struct snd_pcm_substream *substream,
+               struct tdm_config cfg, int enable);
+void pcm_master_out_enable(struct snd_pcm_substream *substream,
+               struct tdm_config cfg, int enable);
 #endif
index 63b8835..9f09273 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/clk.h>
 #include <linux/gpio/consumer.h>
 #include <linux/pinctrl/consumer.h>
+#include <linux/of.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
 
 #include "pcm_dai.h"
 #include "pcm.h"
-#include "i2s.h"
+//#include "i2s.h"
 #include "audio_hw_pcm.h"
 
-#include <linux/of.h>
 
 #define DEV_NAME "aml-pcm-dai"
 
@@ -94,8 +94,13 @@ static int aml_pcm_dai_prepare(struct snd_pcm_substream *substream,
        struct aml_pcm_runtime_data *prtd = runtime->private_data;
        struct aml_pcm *pcm = snd_soc_dai_get_drvdata(dai);
        int mclk_rate, pcm_bit;
+       unsigned int slots = pcm->cfg.slots;
 
-       pr_debug("***Entered %s\n", __func__);
+       pr_debug("***Entered %s, slots %d\n", __func__, slots);
+
+       /* if no slots is set, use the channel num */
+       if (slots == 0)
+               slots = runtime->channels;
 
        /* set bclk */
        if (runtime->format == SNDRV_PCM_FORMAT_S32_LE)
@@ -105,12 +110,12 @@ static int aml_pcm_dai_prepare(struct snd_pcm_substream *substream,
        else
                pcm_bit = 16;
 
-       mclk_rate = runtime->rate * pcm_bit * runtime->channels;
-       pr_info("%s rate:%d, bits:%d, channels:%d, mclk:%d\n",
+       mclk_rate = runtime->rate * pcm_bit * slots;
+       pr_info("%s rate:%d, bits:%d, slots:%d, mclk:%d\n",
                __func__,
                runtime->rate,
                pcm_bit,
-               runtime->channels,
+               slots,
                mclk_rate);
 
        aml_pcm_set_clk(pcm, mclk_rate);
@@ -149,16 +154,16 @@ static int aml_pcm_dai_trigger(struct snd_pcm_substream *substream, int cmd,
                        pr_info("aiu pcm master stream %d enable\n\n",
                                substream->stream);
                        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-                               pcm_master_out_enable(substream, 1);
+                               pcm_master_out_enable(substream, pcm_p->cfg, 1);
                        else
-                               pcm_master_in_enable(substream, 1);
+                               pcm_master_in_enable(substream, pcm_p->cfg, 1);
                } else {
                        pr_info("aiu slave pcm stream %d enable\n\n",
                                substream->stream);
                        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-                               pcm_out_enable(substream, 1);
+                               pcm_out_enable(substream, pcm_p->cfg, 1);
                        else
-                               pcm_in_enable(substream, 1);
+                               pcm_in_enable(substream, pcm_p->cfg, 1);
                }
                break;
        case SNDRV_PCM_TRIGGER_STOP:
@@ -168,16 +173,16 @@ static int aml_pcm_dai_trigger(struct snd_pcm_substream *substream, int cmd,
                        pr_info("aiu master pcm stream %d disable\n\n",
                                substream->stream);
                        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-                               pcm_master_out_enable(substream, 0);
+                               pcm_master_out_enable(substream, pcm_p->cfg, 0);
                        else
-                               pcm_master_in_enable(substream, 0);
+                               pcm_master_in_enable(substream, pcm_p->cfg, 0);
                } else {
                        pr_info("aiu slave pcm stream %d disable\n\n",
                                substream->stream);
                        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-                               pcm_out_enable(substream, 0);
+                               pcm_out_enable(substream, pcm_p->cfg, 0);
                        else
-                               pcm_in_enable(substream, 0);
+                               pcm_in_enable(substream, pcm_p->cfg, 0);
                }
                break;
        default:
@@ -199,8 +204,6 @@ static int aml_pcm_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
        pr_debug("***Entered %s\n", __func__);
 
-       aml_set_pcm_format(fmt & SND_SOC_DAIFMT_FORMAT_MASK);
-
        return 0;
 }
 
@@ -265,6 +268,36 @@ static const struct snd_soc_component_driver aml_component = {
        .name = DEV_NAME,
 };
 
+static int parse_tdm_configs(struct device_node *node, struct aml_pcm *pcm_p)
+{
+       struct tdm_config *cfg = &pcm_p->cfg;
+       unsigned int fmt = 0;
+
+       fmt = snd_soc_of_parse_daifmt(node, NULL, NULL, NULL);
+       cfg->fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
+
+       snd_soc_of_parse_tdm_slot(node,
+                       &cfg->tx_slot_mask,
+                       &cfg->rx_slot_mask,
+                       &cfg->slots,
+                       &cfg->slot_width);
+       pr_info("tdm config: %#x, %#x, %d, %d\n",
+                       cfg->tx_slot_mask,
+                       cfg->rx_slot_mask,
+                       cfg->slots,
+                       cfg->slot_width);
+
+       if (cfg->fmt == 0)
+               cfg->fmt = SND_SOC_DAIFMT_DSP_A;
+
+       if (cfg->tx_slot_mask != cfg->rx_slot_mask) {
+               pr_info("%s(), rx equals to tx\n", __func__);
+               cfg->rx_slot_mask = cfg->tx_slot_mask;
+       }
+
+       return 0;
+}
+
 static int aml_pcm_dai_probe(struct platform_device *pdev)
 {
        struct pinctrl *pin_ctl;
@@ -335,6 +368,7 @@ static int aml_pcm_dai_probe(struct platform_device *pdev)
                        "Can't enable pcm clk_pcm_sync clock: %d\n", ret);
                        goto err;
                }
+               parse_tdm_configs((&pdev->dev)->of_node, pcm_p);
        }
 
        ret = snd_soc_register_component(&pdev->dev, &aml_component,
index 2a6b62b..b336594 100644 (file)
 #ifndef AML_DAI_H
 #define AML_DAI_H
 
+#include <sound/soc.h>
+#include "audio_hw_pcm.h"
+
 struct aml_pcm {
        struct clk *clk_mpll;
        struct clk *clk_pcm_mclk;
        struct clk *clk_pcm_sync;
        int pcm_mode;
+       struct tdm_config cfg;
 };
 #endif