From 4ef665a5f51fd2abbe0d89a01f649810793a7cb8 Mon Sep 17 00:00:00 2001 From: Hang Cheng Date: Mon, 23 Apr 2018 16:32:45 +0800 Subject: [PATCH] hdmirx: optimize audio channel map PD#154135: hdmirx: optimize audio channel map set audio channel map according to received audio subpackets layout and audio speaker allocation info. Change-Id: I9438b25d422704bed4dba3c19fbd215365c8996f Signed-off-by: Hang Cheng --- .../amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h | 6 ++- drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c | 28 +++++++++++-- drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h | 4 ++ .../media/vin/tvin/hdmirx/hdmi_rx_wrapper.c | 48 ++++++++++++++++++---- 4 files changed, 72 insertions(+), 14 deletions(-) diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h index a3e114b..4d5bd21 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h @@ -41,7 +41,7 @@ * * */ -#define RX_VER1 "ver.2018/04/12" +#define RX_VER1 "ver.2018/04/20" @@ -296,7 +296,9 @@ struct aud_info_s { int sample_frequency; int sample_size; int coding_extension; - int channel_allocation; + int auds_ch_alloc; + int auds_layout; + /* *int down_mix_inhibit; *int level_shift_value; 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 70f4189..92ab57e 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c @@ -88,6 +88,8 @@ int hdcp22_on; MODULE_PARM_DESC(hdcp22_on, "\n hdcp22_on\n"); module_param(hdcp22_on, int, 0664); +int aud_ch_map; + /*------------------------variable define end------------------------------*/ static int check_regmap_flag(unsigned int addr) @@ -738,8 +740,10 @@ void rx_get_audinfo(struct aud_info_s *audio_info) hdmirx_rd_bits_dwc(DWC_PDEC_AIF_PB0, SAMPLE_SIZE); audio_info->coding_extension = hdmirx_rd_bits_dwc(DWC_PDEC_AIF_PB0, AIF_DATA_BYTE_3); - audio_info->channel_allocation = + audio_info->auds_ch_alloc = hdmirx_rd_bits_dwc(DWC_PDEC_AIF_PB0, CH_SPEAK_ALLOC); + audio_info->auds_layout = + hdmirx_rd_bits_dwc(DWC_PDEC_STS, PD_AUD_LAYOUT); audio_info->aud_packet_received = hdmirx_rd_dwc(DWC_PDEC_AUD_STS) & @@ -1440,7 +1444,6 @@ void hdmirx_20_init(void) int hdmirx_audio_init(void) { /* 0=I2S 2-channel; 1=I2S 4 x 2-channel. */ - #define RX_8_CHANNEL 1 int err = 0; unsigned long data32 = 0; @@ -1489,7 +1492,7 @@ int hdmirx_audio_init(void) data32 = 0; data32 |= 0 << 8; data32 |= 1 << 7; - data32 |= (RX_8_CHANNEL ? 0x13:0x00) << 2; + data32 |= aud_ch_map << 2; data32 |= 1 << 0; hdmirx_wr_dwc(DWC_AUD_CHEXTR_CTRL, data32); @@ -2042,6 +2045,25 @@ void hdmirx_config_video(void) } /* + * hdmirx_config_audio - audio channel map + */ +void hdmirx_config_audio(void) +{ + /* if audio layout bit = 1, set audio channel map + * according to audio speaker allocation, if layout + * bit = 0, use ch1 & ch2 by default. + */ + if (rx.aud_info.auds_layout) { + hdmirx_wr_bits_dwc(DWC_AUD_CHEXTR_CTRL, + AUD_CH_MAP_CFG, + rx.aud_info.auds_ch_alloc); + } else { + hdmirx_wr_bits_dwc(DWC_AUD_CHEXTR_CTRL, + AUD_CH_MAP_CFG, 0); + } +} + +/* * clk_util_clk_msr */ static unsigned int clk_util_clk_msr(unsigned int clk_mux) 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 7904479..021d298 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h @@ -468,6 +468,7 @@ #define DWC_AUD_FIFO_FILLSTS (0x250UL) /** Register address: audio output interface configuration */ #define DWC_AUD_CHEXTR_CTRL (0x254UL) +#define AUD_CH_MAP_CFG MSK(5, 2) /** Register address: audio mute control */ #define DWC_AUD_MUTE_CTRL (0x258UL) /** Manual/automatic audio mute control */ @@ -605,6 +606,7 @@ /** Register address: packet decoder status, see packet interrupts */ #define PD_NEW_ENTRY MSK(1, 8) #define PD_TH_START MSK(1, 2) +#define PD_AUD_LAYOUT _BIT(11) #define DWC_PDEC_STS (0x360UL) /** Register address: Packet Decoder Audio Status*/ #define DWC_PDEC_AUD_STS (0x364UL) @@ -983,6 +985,7 @@ extern int pdec_ists_en; extern int pd_fifo_start_cnt; extern int md_ists_en; extern int eq_ref_voltage; +extern int aud_ch_map; extern void wr_reg_hhi(unsigned int offset, unsigned int val); extern unsigned int rd_reg_hhi(unsigned int offset); @@ -1057,6 +1060,7 @@ extern void hdmirx_phy_pddq(unsigned int enable); extern void rx_get_video_info(void); extern void hdmirx_set_video_mute(bool mute); extern void hdmirx_config_video(void); +extern void hdmirx_config_audio(void); extern void rx_get_audinfo(struct aud_info_s *audio_info); extern bool rx_clkrate_monitor(void); diff --git a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c index 8dca28c..8c24b68 100644 --- a/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c +++ b/drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c @@ -533,19 +533,28 @@ static uint32_t get_real_sample_rate(void) return ret_sr; } -static unsigned char is_sample_rate_stable(int sample_rate_pre, +static unsigned char is_sample_rate_change(int sample_rate_pre, int sample_rate_cur) { - unsigned char ret = 0; + unsigned char ret = 1; if (ABS(sample_rate_pre - sample_rate_cur) < AUD_SR_RANGE) - ret = 1; - + ret = 0; return ret; } + #endif +static unsigned char is_aud_ch_map_change(int pre, int cur) +{ + unsigned char ret = 0; + + if (pre != cur) + ret = 1; + return ret; +} + static const struct freq_ref_s freq_ref[] = { /* interlace 420 3d hac vac index */ /* 420mode */ @@ -1508,6 +1517,8 @@ int rx_set_global_variable(const char *buf, int size) #endif if (set_pr_var(tmpbuf, suspend_pddq_sel, value, &index, ret)) return pr_var(suspend_pddq_sel, index); + if (set_pr_var(tmpbuf, aud_ch_map, value, &index, ret)) + return pr_var(aud_ch_map, index); return 0; } @@ -1605,6 +1616,7 @@ void rx_get_global_variable(const char *buf) pr_var(sig_unstable_reset_hpd_max, i++); #endif pr_var(suspend_pddq_sel, i++); + pr_var(aud_ch_map, i++); } void skip_frame(void) @@ -1793,6 +1805,8 @@ void rx_err_monitor(void) */ void rx_main_state_machine(void) { + int pre_auds_ch_alloc; + switch (rx.state) { case FSM_5V_LOST: if (rx.cur_5v_sts) @@ -1919,6 +1933,8 @@ void rx_main_state_machine(void) //sizeof(struct aud_info_s)); //rx_set_eq_run_state(E_EQ_PASS); hdmirx_config_video(); + rx_get_audinfo(&rx.aud_info); + hdmirx_config_audio(); rx_aud_pll_ctl(1); hdmirx_audio_fifo_rst(); rx.stable_timestamp = rx.timestamp; @@ -1986,12 +2002,19 @@ void rx_main_state_machine(void) break; packet_update(); - + pre_auds_ch_alloc = rx.aud_info.auds_ch_alloc; rx_get_audinfo(&rx.aud_info); if (check_real_sr_change()) rx_audio_pll_sw_update(); - + if (is_aud_ch_map_change + (pre_auds_ch_alloc, rx.aud_info.auds_ch_alloc)) { + if (log_level & AUDIO_LOG) + dump_state(2); + hdmirx_config_audio(); + hdmirx_audio_fifo_rst(); + rx_audio_pll_sw_update(); + } if (is_aud_pll_error()) { rx.aud_sr_unstable_cnt++; if (rx.aud_sr_unstable_cnt > aud_sr_stb_max) { @@ -2028,6 +2051,7 @@ void rx_main_state_machine(void) { int pre_sample_rate; int aud_pll_sts; + int pre_auds_ch_alloc; if (clk_debug) rx_cable_clk_monitor(); @@ -2210,6 +2234,8 @@ void rx_main_state_machine(void) sizeof(struct aud_info_s)); //rx_set_eq_run_state(E_EQ_PASS); hdmirx_config_video(); + rx_get_audinfo(&rx.aud_info); + hdmirx_config_audio(); hdmirx_audio_fifo_rst(); rx_pr("STABLE->READY\n"); if (log_level & VIDEO_LOG) @@ -2299,12 +2325,15 @@ void rx_main_state_machine(void) break; pre_sample_rate = rx.aud_info.real_sr; + pre_auds_ch_alloc = rx.aud_info.auds_ch_alloc; rx_get_audinfo(&rx.aud_info); rx.aud_info.real_sr = get_real_sample_rate(); - if (!is_sample_rate_stable - (pre_sample_rate, rx.aud_info.real_sr)) { + if (is_sample_rate_change + (pre_sample_rate, rx.aud_info.real_sr) || + is_aud_ch_map_change + (pre_auds_ch_alloc, rx.aud_info.auds_ch_alloc)) { if (log_level & AUDIO_LOG) dump_state(2); rx.aud_sr_stable_cnt = 0; @@ -2324,6 +2353,7 @@ void rx_main_state_machine(void) if (log_level & AUDIO_LOG) rx_pr("afifo err\n"); } + hdmirx_config_audio(); hdmirx_audio_fifo_rst(); rx_pr("update audio\n"); rx_audio_pll_sw_update(); @@ -2521,7 +2551,7 @@ void dump_state(unsigned char enable) a.sample_frequency, a.sample_size); rx_pr(" CA=%u", - a.channel_allocation); + a.auds_ch_alloc); rx_pr(" CTS=%d, N=%d,", a.cts, a.n); rx_pr("recovery clock is %d\n", -- 2.7.4