mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
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: I369cc28931f34c78496a7fbc63559ae181944158 Signed-off-by: Xing Wang <xing.wang@amlogic.com>
This commit is contained in:
@@ -150,6 +150,9 @@ static irqreturn_t earc_rx_isr(int irq, void *data)
|
||||
struct earc *p_earc = (struct earc *)data;
|
||||
unsigned int status0 = earcrx_cdmc_get_irqs(p_earc->rx_top_map);
|
||||
|
||||
if (status0)
|
||||
earcrx_cdmc_clr_irqs(p_earc->rx_top_map, status0);
|
||||
|
||||
if (status0 & INT_EARCRX_CMDC_IDLE2) {
|
||||
earcrx_update_attend_event(p_earc,
|
||||
false, true);
|
||||
@@ -172,8 +175,10 @@ 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 & INT_EARCRX_CMDC_TIMEOUT) {
|
||||
@@ -183,12 +188,12 @@ static irqreturn_t earc_rx_isr(int irq, void *data)
|
||||
pr_debug("%s EARCRX_CMDC_TIMEOUT\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)
|
||||
@@ -203,9 +208,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;
|
||||
@@ -245,6 +247,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);
|
||||
@@ -286,12 +291,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)
|
||||
@@ -304,9 +309,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;
|
||||
@@ -759,6 +761,8 @@ static int earc_dai_startup(
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
earcrx_pll_refresh(p_earc->rx_top_map);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -885,6 +889,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]);
|
||||
@@ -892,6 +899,34 @@ static int earcrx_arc_set_enable(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int earctx_get_attend_type(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct earc *p_earc = dev_get_drvdata(component->dev);
|
||||
enum attend_type type =
|
||||
earctx_cmdc_get_attended_type(p_earc->tx_cmdc_map);
|
||||
|
||||
ucontrol->value.integer.value[0] = type;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int earctx_set_attend_type(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct earc *p_earc = dev_get_drvdata(component->dev);
|
||||
enum cmdc_st state = earctx_cmdc_get_state(p_earc->tx_cmdc_map);
|
||||
|
||||
if (state != CMDC_ST_IDLE2)
|
||||
return 0;
|
||||
|
||||
/* only support set cmdc from idle to ARC */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new earc_controls[] = {
|
||||
SOC_ENUM_EXT("eARC_RX attended type",
|
||||
attended_type_enum,
|
||||
@@ -902,6 +937,11 @@ static const struct snd_kcontrol_new earc_controls[] = {
|
||||
0,
|
||||
earcrx_arc_get_enable,
|
||||
earcrx_arc_set_enable),
|
||||
|
||||
SOC_ENUM_EXT("eARC_TX attended type",
|
||||
attended_type_enum,
|
||||
earctx_get_attend_type,
|
||||
earctx_set_attend_type),
|
||||
};
|
||||
|
||||
static const struct snd_soc_component_driver earc_component = {
|
||||
@@ -1049,7 +1089,8 @@ void earc_hdmirx_hpdst(int earc_port, bool st)
|
||||
earc_port,
|
||||
st ? "plugin" : "plugout");
|
||||
|
||||
earctx_cmdc_int_mask(p_earc->tx_top_map);
|
||||
if (st)
|
||||
earctx_cmdc_int_mask(p_earc->tx_top_map);
|
||||
earctx_cmdc_arc_connect(p_earc->tx_cmdc_map, st);
|
||||
earctx_cmdc_hpd_detect(p_earc->tx_top_map,
|
||||
p_earc->tx_cmdc_map,
|
||||
|
||||
@@ -20,6 +20,22 @@
|
||||
#include <linux/amlogic/media/sound/spdif_info.h>
|
||||
#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 */
|
||||
@@ -216,7 +232,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 +436,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 +534,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);
|
||||
|
||||
@@ -107,6 +107,7 @@ enum tx_hd_hdp_mux {
|
||||
GPIOW_5
|
||||
};
|
||||
|
||||
void earcrx_pll_refresh(struct regmap *top_map);
|
||||
void earcrx_cmdc_init(struct regmap *top_map);
|
||||
void earcrx_cmdc_arc_connect(struct regmap *cmdc_map, bool init);
|
||||
void earcrx_cmdc_hpd_detect(struct regmap *cmdc_map, bool st);
|
||||
@@ -132,6 +133,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);
|
||||
@@ -140,5 +143,4 @@ void earctx_enable(struct regmap *top_map,
|
||||
struct regmap *cmdc_map,
|
||||
struct regmap *dmac_map,
|
||||
bool enable);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -81,10 +81,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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user