From 27b3fa2f1be7798b4df0ae2aca2c4b474fb17fde Mon Sep 17 00:00:00 2001 From: Xing Wang Date: Wed, 23 Oct 2019 20:19:16 +0800 Subject: [PATCH] audio: auge: improve compatibility for eARC RX/TX connection [1/1] PD#SWPL-15189 Problem: 1. earc rx fails to connect to a sony tv 2. earc tx fails to connect to AVR-X4500H Solution: 1. reset earc_rx pll 2. reduce comma_th Verify: ab311 Change-Id: I162b9697d151b682df01093cdc086330a97f8fab Signed-off-by: Xing Wang --- sound/soc/amlogic/auge/earc.c | 50 +++++++++++++++++-------------- sound/soc/amlogic/auge/earc_hw.c | 39 +++++++++++++++++------- sound/soc/amlogic/auge/earc_hw.h | 2 ++ sound/soc/amlogic/auge/locker.c | 10 ++----- sound/soc/amlogic/auge/resample.c | 4 +-- 5 files changed, 62 insertions(+), 43 deletions(-) diff --git a/sound/soc/amlogic/auge/earc.c b/sound/soc/amlogic/auge/earc.c index d0bc788a8dce..e92dd264c19d 100644 --- a/sound/soc/amlogic/auge/earc.c +++ b/sound/soc/amlogic/auge/earc.c @@ -75,8 +75,8 @@ struct earc { struct extcon_dev *rx_edev; struct extcon_dev *tx_edev; - bool tx_dmac_clk_on; bool rx_dmac_clk_on; + bool tx_dmac_clk_on; }; static struct earc *s_earc; @@ -183,17 +183,19 @@ static irqreturn_t earc_rx_isr(int irq, void *data) pr_info("%s EARCRX_CMDC_EARC\n", __func__); } - if (status0 & INT_EARCRX_CMDC_HB_STATUS) - pr_debug("%s EARCRX_CMDC_HB_STATUS\n", __func__); + /* + * if (status0 & INT_EARCRX_CMDC_HB_STATUS) + * pr_debug("%s EARCRX_CMDC_HB_STATUS\n", __func__); + */ if (status0 & INT_EARCRX_CMDC_LOSTHB) pr_debug("%s EARCRX_CMDC_LOSTHB\n", __func__); - if (status0) - earcrx_cdmc_clr_irqs(p_earc->rx_top_map, status0); - if (p_earc->rx_dmac_clk_on) { unsigned int status1 = earcrx_dmac_get_irqs(p_earc->rx_top_map); + if (status1) + earcrx_dmac_clr_irqs(p_earc->rx_top_map, status1); + if (status1 & INT_ARCRX_BIPHASE_DECODE_C_FIND_PAPB) pr_debug("%s ARCRX_C_FIND_PAPB\n", __func__); if (status1 & INT_ARCRX_BIPHASE_DECODE_C_VALID_CHANGE) @@ -208,9 +210,6 @@ static irqreturn_t earc_rx_isr(int irq, void *data) pr_debug("%s ARCRX_I_SAMPLE_MODE_CHANGE\n", __func__); if (status1 & INT_ARCRX_BIPHASE_DECODE_R_PARITY_ERR) pr_debug("%s ARCRX_R_PARITY_ERR\n", __func__); - - if (status1) - earcrx_dmac_clr_irqs(p_earc->rx_top_map, status1); } return IRQ_HANDLED; @@ -221,25 +220,25 @@ static void earctx_update_attend_event(struct earc *p_earc, { if (state) { if (is_earc) { - extcon_set_state_sync(p_earc->rx_edev, + extcon_set_state_sync(p_earc->tx_edev, EXTCON_EARCTX_ATNDTYP_ARC, false); - extcon_set_state_sync(p_earc->rx_edev, + extcon_set_state_sync(p_earc->tx_edev, EXTCON_EARCTX_ATNDTYP_EARC, state); } else { - extcon_set_state_sync(p_earc->rx_edev, + extcon_set_state_sync(p_earc->tx_edev, EXTCON_EARCTX_ATNDTYP_ARC, state); - extcon_set_state_sync(p_earc->rx_edev, + extcon_set_state_sync(p_earc->tx_edev, EXTCON_EARCTX_ATNDTYP_EARC, false); } } else { - extcon_set_state_sync(p_earc->rx_edev, + extcon_set_state_sync(p_earc->tx_edev, EXTCON_EARCTX_ATNDTYP_ARC, state); - extcon_set_state_sync(p_earc->rx_edev, + extcon_set_state_sync(p_earc->tx_edev, EXTCON_EARCTX_ATNDTYP_EARC, state); } @@ -250,6 +249,9 @@ static irqreturn_t earc_tx_isr(int irq, void *data) struct earc *p_earc = (struct earc *)data; unsigned int status0 = earctx_cdmc_get_irqs(p_earc->tx_top_map); + if (status0) + earctx_cdmc_clr_irqs(p_earc->tx_top_map, status0); + if (status0 & INT_EARCTX_CMDC_IDLE2) { earctx_update_attend_event(p_earc, false, true); @@ -291,12 +293,12 @@ static irqreturn_t earc_tx_isr(int irq, void *data) if (status0 & INT_EARCTX_CMDC_RECV_UNEXP) pr_debug("%s EARCTX_CMDC_RECV_UNEXP\n", __func__); - if (status0) - earctx_cdmc_clr_irqs(p_earc->tx_top_map, status0); - if (p_earc->tx_dmac_clk_on) { unsigned int status1 = earctx_dmac_get_irqs(p_earc->tx_top_map); + if (status1) + earctx_dmac_clr_irqs(p_earc->tx_top_map, status1); + if (status1 & INT_EARCTX_FEM_C_HOLD_CLR) pr_debug("%s EARCTX_FEM_C_HOLD_CLR\n", __func__); if (status1 & INT_EARCTX_FEM_C_HOLD_START) @@ -309,9 +311,6 @@ static irqreturn_t earc_tx_isr(int irq, void *data) __func__); if (status1 & INT_EARCTX_ERRCORR_C_FIFO_EMPTY) pr_debug("%s EARCTX_ERRCORR_C_FIFO_EMPTY\n", __func__); - - if (status1) - earctx_dmac_clr_irqs(p_earc->tx_top_map, status1); } return IRQ_HANDLED; @@ -764,6 +763,8 @@ static int earc_dai_startup( goto err; } } + + earcrx_pll_refresh(p_earc->rx_top_map); } return 0; @@ -890,6 +891,9 @@ static int earcrx_arc_set_enable( struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct earc *p_earc = dev_get_drvdata(component->dev); + if (!p_earc) + return 0; + earcrx_cmdc_arc_connect( p_earc->rx_cmdc_map, (bool)ucontrol->value.integer.value[0]); @@ -1197,6 +1201,8 @@ void earc_hdmitx_hpdst(bool st) /* ensure clock gate */ audiobus_update_bits(EE_AUDIO_CLK_GATE_EN1, 0x1 << 6, 0x1 << 6); + earcrx_cmdc_arc_connect(p_earc->rx_cmdc_map, st); + earcrx_cmdc_hpd_detect(p_earc->rx_cmdc_map, st); } @@ -1249,7 +1255,7 @@ static int earctx_extcon_register(struct earc *p_earc) int ret = 0; /* earc or arc connect */ - p_earc->tx_edev = devm_extcon_dev_allocate(p_earc->dev, earcrx_extcon); + p_earc->tx_edev = devm_extcon_dev_allocate(p_earc->dev, earctx_extcon); if (IS_ERR(p_earc->tx_edev)) { pr_err("failed to allocate earc extcon!!!\n"); ret = -ENOMEM; diff --git a/sound/soc/amlogic/auge/earc_hw.c b/sound/soc/amlogic/auge/earc_hw.c index 80b25e0e9b20..14694c1452b0 100644 --- a/sound/soc/amlogic/auge/earc_hw.c +++ b/sound/soc/amlogic/auge/earc_hw.c @@ -20,6 +20,21 @@ #include #include "earc_hw.h" +void earcrx_pll_refresh(struct regmap *top_map) +{ + /* pll tdc mode */ + mmio_update_bits(top_map, EARCRX_PLL_CTRL3, + 0x1 << 15, 0x1 << 15); + + /* pll self reset */ + mmio_update_bits(top_map, EARCRX_PLL_CTRL0, + 0x1 << 29, 0x1 << 29); + mmio_update_bits(top_map, EARCRX_PLL_CTRL0, + 0x1 << 29, 0x0 << 29); + + mmio_update_bits(top_map, EARCRX_PLL_CTRL3, + 0x1 << 15, 0x0 << 15); +} void earcrx_cmdc_init(struct regmap *top_map) { /* set irq mask */ @@ -98,8 +113,8 @@ void earcrx_cmdc_hpd_detect(struct regmap *cmdc_map, bool st) mmio_update_bits(cmdc_map, EARC_RX_CMDC_VSM_CTRL0, 0x1 << 19 | 0xff << 0, - 0x1 << 19 | /* comma_cnt_rst */ - 0xff << 0 + 0x0 << 19 | /* comma_cnt_rst */ + 0xa << 0 ); } else { /* soft reset */ @@ -216,7 +231,8 @@ void earcrx_arc_init(struct regmap *dmac_map) 0x1 << 30 | /* reg_chnum_sel */ 0x1 << 25 | /* reg_findpapb_en */ 0x1 << 24 | /* nonpcm2pcm_th enable */ - 0xFFF << 12 /* reg_nonpcm2pcm_th */ + 0xFFF << 12 | /* reg_nonpcm2pcm_th */ + 0x1 << 2 /* reg_check_parity */ ); mmio_write(dmac_map, EARCRX_SPDIFIN_CTRL2, @@ -419,17 +435,10 @@ void earctx_cmdc_hpd_detect(struct regmap *top_map, 0x3 << 20 | 0x3 << 22 ); - /* no timeout */ - mmio_update_bits(cmdc_map, - EARC_TX_CMDC_VSM_CTRL5, - 0x3 << 0, - 0x1 << 1 - ); - mmio_update_bits(cmdc_map, EARC_TX_CMDC_VSM_CTRL1, 0xff << 0, - 0xa << 0 /* comma_cnt_th */ + 0x4 << 0 /* comma_cnt_th */ ); } else { /* soft reset */ @@ -524,6 +533,14 @@ void earctx_set_channel_status_info(struct regmap *dmac_map, ((chsts->chstat1_r >> 8) & 0xf) << 24 | chsts->chstat0_r); } +enum cmdc_st earctx_cmdc_get_state(struct regmap *cmdc_map) +{ + int val = mmio_read(cmdc_map, EARC_TX_CMDC_STATUS0); + enum cmdc_st state = (enum cmdc_st)(val & 0x7); + + return state; +} + enum attend_type earctx_cmdc_get_attended_type(struct regmap *cmdc_map) { int val = mmio_read(cmdc_map, EARC_TX_CMDC_STATUS0); diff --git a/sound/soc/amlogic/auge/earc_hw.h b/sound/soc/amlogic/auge/earc_hw.h index 8a06a8a76a14..d40120985ec4 100644 --- a/sound/soc/amlogic/auge/earc_hw.h +++ b/sound/soc/amlogic/auge/earc_hw.h @@ -151,6 +151,8 @@ void earctx_dmac_set_format(struct regmap *dmac_map, int frddr_idx, int msb, int frddr_type); void earctx_set_channel_status_info(struct regmap *dmac_map, struct iec958_chsts *chsts); +enum cmdc_st earctx_cmdc_get_state(struct regmap *cmdc_map); +enum attend_type earctx_cmdc_get_attended_type(struct regmap *cmdc_map); void earctx_cdmc_clr_irqs(struct regmap *top_map, int clr); int earctx_cdmc_get_irqs(struct regmap *top_map); void earctx_dmac_clr_irqs(struct regmap *top_map, int clr); diff --git a/sound/soc/amlogic/auge/locker.c b/sound/soc/amlogic/auge/locker.c index d41cc4ab6ca7..6a6fa3f91266 100644 --- a/sound/soc/amlogic/auge/locker.c +++ b/sound/soc/amlogic/auge/locker.c @@ -182,10 +182,8 @@ static DEVICE_ATTR(locker_enable, 0644, void audio_locker_set(int enable) { - if (!s_locker) { - pr_debug("audio locker is not init\n"); + if (!s_locker) return; - } s_locker->enable = enable; audiolocker_init(s_locker); @@ -193,10 +191,8 @@ void audio_locker_set(int enable) int audio_locker_get(void) { - if (!s_locker) { - pr_debug("audio locker is not init\n"); - return -1; - } + if (!s_locker) + return 0; return s_locker->enable; } diff --git a/sound/soc/amlogic/auge/resample.c b/sound/soc/amlogic/auge/resample.c index 75763e18b9df..f779a6d707a3 100644 --- a/sound/soc/amlogic/auge/resample.c +++ b/sound/soc/amlogic/auge/resample.c @@ -82,10 +82,8 @@ struct audioresample *get_audioresample(enum resample_idx id) p_resample = ((id == RESAMPLE_A) ? s_resample_a : s_resample_b); - if (!p_resample) { - pr_debug("Not init audio resample\n"); + if (!p_resample) return NULL; - } return p_resample; }