audio: auge: add HDMIRX SPDIF in support [1/2]

PD#SWPL-2956

Problem:
HDMI in DTS/Dolby input has noise when treated to LPCM

Solution:
By default,we are using PAO mode for HDMIRX,but we have not
enabled the PaPb search for 61937 raw data input, after add
that, we can detect the raw data, but it can not by clear when
switch from NONE-LPCM to NONE-LPCM, need add IRQ function to
clear that by sw.we enabled spdif in from HDMIRX, which is  the same
design as txl/txlx.we can get the Pc information now.
also we add a new interface to set spdif in source when hdmirx input.

Verify:
x301

Change-Id: I3c4e8b387308ef862a069c29d15b8b5a9e865564
Signed-off-by: Jian Xu <jian.xu@amlogic.com>
This commit is contained in:
Jian Xu
2018-12-19 11:19:51 +08:00
committed by Jianxin Pan
parent 8dfdb019ef
commit b315b2ba0b
7 changed files with 149 additions and 23 deletions

View File

@@ -613,6 +613,72 @@ static int frhdmirx_set_mode(
return 0;
}
#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI
/* spdif in audio format detect: LPCM or NONE-LPCM */
struct sppdif_audio_info {
unsigned char aud_type;
/*IEC61937 package presamble Pc value*/
short pc;
char *aud_type_str;
};
static const char *const spdif_audio_type_texts[] = {
"LPCM",
"AC3",
"EAC3",
"DTS",
"DTS-HD",
"TRUEHD",
"PAUSE"
};
static const struct sppdif_audio_info type_texts[] = {
{0, 0, "LPCM"},
{1, 0x1, "AC3"},
{2, 0x15, "EAC3"},
{3, 0xb, "DTS-I"},
{3, 0x0c, "DTS-II"},
{3, 0x0d, "DTS-III"},
{3, 0x11, "DTS-IV"},
{4, 0, "DTS-HD"},
{5, 0x16, "TRUEHD"},
{6, 0x103, "PAUSE"},
{6, 0x003, "PAUSE"},
{6, 0x100, "PAUSE"},
};
static const struct soc_enum hdmirx_audio_type_enum =
SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(spdif_audio_type_texts),
spdif_audio_type_texts);
static int hdmiin_check_audio_type(void)
{
int total_num = sizeof(type_texts)/sizeof(struct sppdif_audio_info);
int pc = frhdmirx_get_chan_status_pc();
int audio_type = 0;
int i;
for (i = 0; i < total_num; i++) {
if (pc == type_texts[i].pc) {
audio_type = type_texts[i].aud_type;
break;
}
}
pr_debug("%s audio type:%d\n", __func__, audio_type);
return audio_type;
}
static int hdmirx_audio_type_get_enum(
struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
ucontrol->value.enumerated.item[0] =
hdmiin_check_audio_type();
return 0;
}
#endif
static const struct snd_kcontrol_new extn_controls[] = {
/* Out */
@@ -664,6 +730,10 @@ static const struct snd_kcontrol_new extn_controls[] = {
0,
aml_get_atmos_audio_edid,
aml_set_atmos_audio_edid),
SOC_ENUM_EXT("HDMIIN Audio Type",
hdmirx_audio_type_enum,
hdmirx_audio_type_get_enum,
NULL),
#endif
};
@@ -723,8 +793,8 @@ static int extn_platform_probe(struct platform_device *pdev)
/* Default ARC SRC */
p_extn->arc_src = 1;
/* Default: PAO mode */
p_extn->hdmirx_mode = 1;
/* Default: SPDIF in mode */
p_extn->hdmirx_mode = 0;
ret = snd_soc_register_component(&pdev->dev,
&extn_component,

View File

@@ -84,7 +84,11 @@ void frhdmirx_ctrl(int channels, int src)
/* PAO mode */
if (src) {
audiobus_write(EE_AUDIO_FRHDMIRX_CTRL0,
0x1 << 23 | 0x1 << 22 | 0x1 << 7);
0x1 << 23 | /* slect pao mode */
0x1 << 22 | /* capture input by fall edge*/
0x1 << 7 | /* start sending ch num info out */
0x1 << 8 | /* start detect PAPB */
0x1 << 6 /* chan status sel: pao pc/pd value */);
return;
}
@@ -101,7 +105,7 @@ void frhdmirx_ctrl(int channels, int src)
0x1 << 30 | /* chnum_sel */
lane_mask << 24 | /* chnum_sel */
0x1 << 22 | /* clk_inv */
0x0 << 11 /* req_sel, Sync 4 spdifin by which */
0x0 << 11 /* req_sel, Sync 4 spdifin by which */
);
/* nonpcm2pcm_th */
@@ -110,3 +114,14 @@ void frhdmirx_ctrl(int channels, int src)
/* enable irq bits */
frhdmirx_enable_irq_bits(channels, src);
}
unsigned int frhdmirx_get_chan_status_pc(void)
{
unsigned int val;
val = audiobus_read(EE_AUDIO_FRHDMIRX_STAT1);
return (val >> 16) & 0xff;
}

View File

@@ -20,5 +20,5 @@
extern void frhdmirx_enable(bool enable);
extern void frhdmirx_src_select(int src);
extern void frhdmirx_ctrl(int channels, int src);
extern unsigned int frhdmirx_get_chan_status_pc(void);
#endif

View File

@@ -253,6 +253,7 @@ static int spdifin_audio_type_get_enum(
/* For fake */
static bool is_mute;
static int spdifin_src;
static int aml_audio_set_spdif_mute(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -268,6 +269,36 @@ static int aml_audio_get_spdif_mute(struct snd_kcontrol *kcontrol,
return 0;
}
static const char *const spdifin_src_texts[] = {
"spdifin pad", "spdifout", "N/A", "HDMIRX"
};
const struct soc_enum spdifin_src_enum =
SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(spdifin_src_texts),
spdifin_src_texts);
int spdifin_source_get_enum(
struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
ucontrol->value.enumerated.item[0] = spdifin_src;
return 0;
}
int spdifin_source_set_enum(
struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
int src = ucontrol->value.enumerated.item[0];
if (src > 3) {
pr_err("bad parameter for spdifin src set\n");
return -1;
}
spdifin_set_src(src);
spdifin_src = src;
return 0;
}
static const struct snd_kcontrol_new snd_spdif_controls[] = {
@@ -288,6 +319,10 @@ static const struct snd_kcontrol_new snd_spdif_controls[] = {
SOC_SINGLE_BOOL_EXT("Audio spdif mute",
0, aml_audio_get_spdif_mute,
aml_audio_set_spdif_mute),
SOC_ENUM_EXT("Audio spdifin source",
spdifin_src_enum,
spdifin_source_get_enum,
spdifin_source_set_enum),
};
@@ -556,7 +591,7 @@ static void spdifin_status_event(struct aml_spdif *p_spdif)
pr_info("Pd changed\n");
} else {
if (intrpt_status & 0x8)
pr_info("CH status changed\n");
pr_debug("CH status changed\n");
if (intrpt_status & 0x10) {
int val = spdifin_get_ch_status0to31();

View File

@@ -528,6 +528,11 @@ int spdifin_get_audio_type(void)
return (val >> 16) & 0xff;
}
void spdifin_set_src(int src)
{
audiobus_update_bits(EE_AUDIO_SPDIFIN_CTRL0, 0x3 << 4, src << 4);
}
void spdif_set_channel_status_info(
struct iec958_chsts *chsts, int spdif_id)
{

View File

@@ -88,4 +88,5 @@ extern void spdif_set_channel_status_info(
extern void spdifout_play_with_zerodata(unsigned int spdif_id);
extern void spdifout_play_with_zerodata_free(unsigned int spdif_id);
extern void spdifin_set_src(int src);
#endif

View File

@@ -55,22 +55,22 @@ static void dump_pcm_setting(struct pcm_setting *setting)
if (setting == NULL)
return;
pr_info("dump_pcm_setting(%p)\n", setting);
pr_info("\tpcm_mode(%d)\n", setting->pcm_mode);
pr_info("\tsysclk(%d)\n", setting->sysclk);
pr_info("\tsysclk_bclk_ratio(%d)\n", setting->sysclk_bclk_ratio);
pr_info("\tbclk(%d)\n", setting->bclk);
pr_info("\tbclk_lrclk_ratio(%d)\n", setting->bclk_lrclk_ratio);
pr_info("\tlrclk(%d)\n", setting->lrclk);
pr_info("\ttx_mask(%#x)\n", setting->tx_mask);
pr_info("\trx_mask(%#x)\n", setting->rx_mask);
pr_info("\tslots(%d)\n", setting->slots);
pr_info("\tslot_width(%d)\n", setting->slot_width);
pr_info("\tlane_mask_in(%#x)\n", setting->lane_mask_in);
pr_info("\tlane_mask_out(%#x)\n", setting->lane_mask_out);
pr_info("\tlane_oe_mask_in(%#x)\n", setting->lane_oe_mask_in);
pr_info("\tlane_oe_mask_out(%#x)\n", setting->lane_oe_mask_out);
pr_info("\tlane_lb_mask_in(%#x)\n", setting->lane_lb_mask_in);
pr_debug("dump_pcm_setting(%p)\n", setting);
pr_debug("\tpcm_mode(%d)\n", setting->pcm_mode);
pr_debug("\tsysclk(%d)\n", setting->sysclk);
pr_debug("\tsysclk_bclk_ratio(%d)\n", setting->sysclk_bclk_ratio);
pr_debug("\tbclk(%d)\n", setting->bclk);
pr_debug("\tbclk_lrclk_ratio(%d)\n", setting->bclk_lrclk_ratio);
pr_debug("\tlrclk(%d)\n", setting->lrclk);
pr_debug("\ttx_mask(%#x)\n", setting->tx_mask);
pr_debug("\trx_mask(%#x)\n", setting->rx_mask);
pr_debug("\tslots(%d)\n", setting->slots);
pr_debug("\tslot_width(%d)\n", setting->slot_width);
pr_debug("\tlane_mask_in(%#x)\n", setting->lane_mask_in);
pr_debug("\tlane_mask_out(%#x)\n", setting->lane_mask_out);
pr_debug("\tlane_oe_mask_in(%#x)\n", setting->lane_oe_mask_in);
pr_debug("\tlane_oe_mask_out(%#x)\n", setting->lane_oe_mask_out);
pr_debug("\tlane_lb_mask_in(%#x)\n", setting->lane_lb_mask_in);
}
struct tdm_chipinfo {
@@ -844,7 +844,7 @@ static int aml_dai_set_tdm_sysclk(struct snd_soc_dai *cpu_dai,
clk_set_rate(p_tdm->clk, freq * ratio);
clk_set_rate(p_tdm->mclk, freq);
pr_info("set mclk:%d, mpll:%d, get mclk:%lu, mpll:%lu\n",
pr_debug("set mclk:%d, mpll:%d, get mclk:%lu, mpll:%lu\n",
freq,
freq * ratio,
clk_get_rate(p_tdm->mclk),