From d44962c1885e2e23722ac1986e7b660f8344ebba Mon Sep 17 00:00:00 2001 From: Shuai Li Date: Thu, 6 Jun 2019 17:25:03 +0800 Subject: [PATCH] audio: Add pcm slots configs [1/1] 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 --- arch/arm/boot/dts/amlogic/gxl_p212_1g.dts | 5 ++ .../arm/boot/dts/amlogic/gxl_p212_1g_buildroot.dts | 5 ++ arch/arm/boot/dts/amlogic/gxl_p212_1g_hd.dts | 5 ++ arch/arm/boot/dts/amlogic/gxl_p212_2g.dts | 5 ++ .../arm/boot/dts/amlogic/gxl_p212_2g_buildroot.dts | 5 ++ arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts | 5 ++ .../boot/dts/amlogic/gxl_p212_1g_buildroot.dts | 5 ++ arch/arm64/boot/dts/amlogic/gxl_p212_1g_hd.dts | 5 ++ arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts | 5 ++ .../boot/dts/amlogic/gxl_p212_2g_buildroot.dts | 5 ++ arch/arm64/boot/dts/amlogic/kvim_linux.dts | 5 ++ sound/soc/amlogic/meson/audio_hw_pcm.c | 87 ++++++++++++---------- sound/soc/amlogic/meson/audio_hw_pcm.h | 21 ++++-- sound/soc/amlogic/meson/pcm_dai.c | 66 ++++++++++++---- sound/soc/amlogic/meson/pcm_dai.h | 4 + 15 files changed, 172 insertions(+), 61 deletions(-) diff --git a/arch/arm/boot/dts/amlogic/gxl_p212_1g.dts b/arch/arm/boot/dts/amlogic/gxl_p212_1g.dts index 0edc324..40215ac 100644 --- a/arch/arm/boot/dts/amlogic/gxl_p212_1g.dts +++ b/arch/arm/boot/dts/amlogic/gxl_p212_1g.dts @@ -862,6 +862,11 @@ "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"; diff --git a/arch/arm/boot/dts/amlogic/gxl_p212_1g_buildroot.dts b/arch/arm/boot/dts/amlogic/gxl_p212_1g_buildroot.dts index 9efc128..9b6687b 100644 --- a/arch/arm/boot/dts/amlogic/gxl_p212_1g_buildroot.dts +++ b/arch/arm/boot/dts/amlogic/gxl_p212_1g_buildroot.dts @@ -828,6 +828,11 @@ "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"; diff --git a/arch/arm/boot/dts/amlogic/gxl_p212_1g_hd.dts b/arch/arm/boot/dts/amlogic/gxl_p212_1g_hd.dts index 868fa5d..3ca951f 100644 --- a/arch/arm/boot/dts/amlogic/gxl_p212_1g_hd.dts +++ b/arch/arm/boot/dts/amlogic/gxl_p212_1g_hd.dts @@ -848,6 +848,11 @@ "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"; diff --git a/arch/arm/boot/dts/amlogic/gxl_p212_2g.dts b/arch/arm/boot/dts/amlogic/gxl_p212_2g.dts index 336df90..32928512 100644 --- a/arch/arm/boot/dts/amlogic/gxl_p212_2g.dts +++ b/arch/arm/boot/dts/amlogic/gxl_p212_2g.dts @@ -869,6 +869,11 @@ "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"; diff --git a/arch/arm/boot/dts/amlogic/gxl_p212_2g_buildroot.dts b/arch/arm/boot/dts/amlogic/gxl_p212_2g_buildroot.dts index 5aadcac..a32d289 100644 --- a/arch/arm/boot/dts/amlogic/gxl_p212_2g_buildroot.dts +++ b/arch/arm/boot/dts/amlogic/gxl_p212_2g_buildroot.dts @@ -828,6 +828,11 @@ "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"; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts b/arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts index c4767fc..b24668a 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts @@ -858,6 +858,11 @@ "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"; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p212_1g_buildroot.dts b/arch/arm64/boot/dts/amlogic/gxl_p212_1g_buildroot.dts index 57c2412..d4233f4 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p212_1g_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p212_1g_buildroot.dts @@ -827,6 +827,11 @@ "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"; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p212_1g_hd.dts b/arch/arm64/boot/dts/amlogic/gxl_p212_1g_hd.dts index 85f64e4c..3e60766 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p212_1g_hd.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p212_1g_hd.dts @@ -847,6 +847,11 @@ "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"; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts b/arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts index 302ea68..0785aab 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts @@ -866,6 +866,11 @@ "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"; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p212_2g_buildroot.dts b/arch/arm64/boot/dts/amlogic/gxl_p212_2g_buildroot.dts index 8003e5d..a0fec90 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p212_2g_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p212_2g_buildroot.dts @@ -828,6 +828,11 @@ "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"; diff --git a/arch/arm64/boot/dts/amlogic/kvim_linux.dts b/arch/arm64/boot/dts/amlogic/kvim_linux.dts index 0b9c060..19a090c 100644 --- a/arch/arm64/boot/dts/amlogic/kvim_linux.dts +++ b/arch/arm64/boot/dts/amlogic/kvim_linux.dts @@ -785,6 +785,11 @@ "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"; diff --git a/sound/soc/amlogic/meson/audio_hw_pcm.c b/sound/soc/amlogic/meson/audio_hw_pcm.c index 72c0457..2587adb 100644 --- a/sound/soc/amlogic/meson/audio_hw_pcm.c +++ b/sound/soc/amlogic/meson/audio_hw_pcm.c @@ -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(); } diff --git a/sound/soc/amlogic/meson/audio_hw_pcm.h b/sound/soc/amlogic/meson/audio_hw_pcm.h index 58a3a49..f9e674b 100644 --- a/sound/soc/amlogic/meson/audio_hw_pcm.h +++ b/sound/soc/amlogic/meson/audio_hw_pcm.h @@ -23,8 +23,16 @@ #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 diff --git a/sound/soc/amlogic/meson/pcm_dai.c b/sound/soc/amlogic/meson/pcm_dai.c index 63b8835..9f09273 100644 --- a/sound/soc/amlogic/meson/pcm_dai.c +++ b/sound/soc/amlogic/meson/pcm_dai.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -34,10 +35,9 @@ #include "pcm_dai.h" #include "pcm.h" -#include "i2s.h" +//#include "i2s.h" #include "audio_hw_pcm.h" -#include #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, diff --git a/sound/soc/amlogic/meson/pcm_dai.h b/sound/soc/amlogic/meson/pcm_dai.h index 2a6b62b..b336594 100644 --- a/sound/soc/amlogic/meson/pcm_dai.h +++ b/sound/soc/amlogic/meson/pcm_dai.h @@ -18,10 +18,14 @@ #ifndef AML_DAI_H #define AML_DAI_H +#include +#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 -- 2.7.4