hdmirx: optimize audio channel map
authorHang Cheng <hang.cheng@amlogic.com>
Mon, 23 Apr 2018 08:32:45 +0000 (16:32 +0800)
committerYixun Lan <yixun.lan@amlogic.com>
Wed, 25 Apr 2018 08:26:18 +0000 (01:26 -0700)
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 <hang.cheng@amlogic.com>
drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_drv.h
drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.c
drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_hw.h
drivers/amlogic/media/vin/tvin/hdmirx/hdmi_rx_wrapper.c

index a3e114b..4d5bd21 100644 (file)
@@ -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;
index 70f4189..92ab57e 100644 (file)
@@ -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)
index 7904479..021d298 100644 (file)
 #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 */
 /** 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);
 
index 8dca28c..8c24b68 100644 (file)
@@ -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",