From cda6cea915eacd463cf85ad37d99e71faadf382f Mon Sep 17 00:00:00 2001 From: Hang Cheng Date: Wed, 27 Jun 2018 16:26:07 +0800 Subject: [PATCH] hdmirx: add afifo threshold pass status for audio PD#168492: hdmirx: add afifo threshold pass status for audio when HDMI in,audio will check the fifo empty count to see if the hdmirx fifo is empty,then audio hal will mute the dirty data to avoid noise. Change-Id: I37e19d1490c560ca9fb38ffa2c3c03793e81c9ae Signed-off-by: Hang Cheng --- .../media/vin/tvin/hdmirx/hdmi_rx_hw.c | 3 + .../media/vin/tvin/hdmirx/hdmi_rx_hw.h | 5 +- .../amlogic/media/frame_provider/tvin/tvin.h | 2 + sound/soc/amlogic/meson/tv.c | 67 +++++++++++++------ 4 files changed, 53 insertions(+), 24 deletions(-) diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c index 2ebda5bf83bb..3ee1ab0fa006 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c @@ -746,6 +746,9 @@ void rx_get_audio_status(struct rx_audio_stat_s *aud_sts) aud_sts->aud_sr = rx.aud_info.real_sr; aud_sts->aud_channel_cnt = rx.aud_info.channel_count; aud_sts->aud_type = rx.aud_info.coding_type; + aud_sts->afifo_thres_pass = + ((hdmirx_rd_dwc(DWC_AUD_FIFO_STS) & + THS_PASS_STS) == 0) ? false : true; } else { memset(aud_sts, 0, sizeof(struct rx_audio_stat_s)); diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h index 021d298a28e6..d70df95dfa0b 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h @@ -487,8 +487,9 @@ #define DWC_AUD_PAO_CTRL (0x264UL) /** Register address: audio FIFO status */ #define DWC_AUD_FIFO_STS (0x27CUL) - #define OVERFL_STS _BIT(4) - #define UNDERFL_STS _BIT(3) +#define OVERFL_STS _BIT(4) +#define UNDERFL_STS _BIT(3) +#define THS_PASS_STS _BIT(2) #define DWC_AUDPLL_GEN_CTS (0x280UL) #define DWC_AUDPLL_GEN_N (0x284UL) diff --git a/include/linux/amlogic/media/frame_provider/tvin/tvin.h b/include/linux/amlogic/media/frame_provider/tvin/tvin.h index 2a1735a106a2..2984c50e2e11 100644 --- a/include/linux/amlogic/media/frame_provider/tvin/tvin.h +++ b/include/linux/amlogic/media/frame_provider/tvin/tvin.h @@ -480,6 +480,8 @@ struct rx_audio_stat_s { /*10: Dolby Digital Plus, 11: DTS-HD,*/ /*12: MAT (MLP), 13: DST, 14: WMA Pro*/ int aud_type; + /* indicate if audio fifo start threshold is crossed */ + bool afifo_thres_pass; }; extern int adc_set_pll_cntl(bool on, unsigned int module_sel, void *pDtvPara); diff --git a/sound/soc/amlogic/meson/tv.c b/sound/soc/amlogic/meson/tv.c index 4e88609cd0a7..69fd5ef4943d 100644 --- a/sound/soc/amlogic/meson/tv.c +++ b/sound/soc/amlogic/meson/tv.c @@ -63,7 +63,35 @@ #define AML_EQ_PARAM_LENGTH 100 #define AML_DRC_PARAM_LENGTH 12 #define AML_REG_BYTES 4 +#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI +static int hdmiin_fifo_disable_count; +/* copy from drivers/amlogic/tvin/hdmirx/hdmirx_drv.h */ +struct hdmi_in_audio_status { + /*audio packets received*/ + bool aud_rcv_flag; + /*audio stable status*/ + bool aud_stb_flag; + /*audio sample rate*/ + int aud_sr; + /*audio channel count*/ + /*0: refer to stream header,*/ + /*1: 2ch, 2: 3ch, 3: 4ch, 4: 5ch,*/ + /*5: 6ch, 6: 7ch, 7: 8ch*/ + int aud_channel_cnt; + /*audio coding type*/ + /*0: refer to stream header, 1: IEC60958 PCM,*/ + /*2: AC-3, 3: MPEG1 (Layers 1 and 2),*/ + /*4: MP3 (MPEG1 Layer 3), 5: MPEG2 (multichannel),*/ + /*6: AAC, 7: DTS, 8: ATRAC, 9: One Bit Audio,*/ + /*10: Dolby Digital Plus, 11: DTS-HD,*/ + /*12: MAT (MLP), 13: DST, 14: WMA Pro*/ + int aud_type; + /* indicate if audio FIFO start threshold is crossed */ + bool afifo_thres_pass; +}; + +#endif static u32 aml_EQ_table[AML_EQ_PARAM_LENGTH] = { /*channel 1 param*/ 0x800000, 0x00, 0x00, 0x00, 0x00, /*eq_ch1_coef0*/ @@ -224,6 +252,22 @@ static int aml_spdif_audio_type_get_enum( break; } } + /* HDMI in,also check the hdmirx fifo status*/ +#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI + if (audio_in_source == 2) { + struct hdmi_in_audio_status aud_sts; + struct rx_audio_stat_s *rx_aud_sts; + + rx_aud_sts = (struct rx_audio_stat_s *)&aud_sts; + rx_get_audio_status(rx_aud_sts); + if (aud_sts.afifo_thres_pass == true) + hdmiin_fifo_disable_count = 0; + else + hdmiin_fifo_disable_count++; + if (hdmiin_fifo_disable_count > 200) + audio_type = 6/*PAUSE*/; + } +#endif ucontrol->value.enumerated.item[0] = audio_type; return 0; @@ -480,28 +524,7 @@ static int aml_get_atmos_audio_edid(struct snd_kcontrol *kcontrol, ucontrol->value.integer.value[0] = p_aml_audio->atmos_edid_enable; return 0; } -/* copy from drivers/amlogic/tvin/hdmirx/hdmirx_drv.h */ -struct hdmi_in_audio_status { - /*audio packets received*/ - bool aud_rcv_flag; - /*audio stable status*/ - bool aud_stb_flag; - /*audio sample rate*/ - int aud_sr; - /*audio channel count*/ - /*0: refer to stream header,*/ - /*1: 2ch, 2: 3ch, 3: 4ch, 4: 5ch,*/ - /*5: 6ch, 6: 7ch, 7: 8ch*/ - int aud_channel_cnt; - /*audio coding type*/ - /*0: refer to stream header, 1: IEC60958 PCM,*/ - /*2: AC-3, 3: MPEG1 (Layers 1 and 2),*/ - /*4: MP3 (MPEG1 Layer 3), 5: MPEG2 (multichannel),*/ - /*6: AAC, 7: DTS, 8: ATRAC, 9: One Bit Audio,*/ - /*10: Dolby Digital Plus, 11: DTS-HD,*/ - /*12: MAT (MLP), 13: DST, 14: WMA Pro*/ - int aud_type; -}; +; static const char *const hdmi_in_is_stable[] = { "false", "true"