cec: add the control of arc line[1/2]

PD#159184: cec: add the control of arc line

add audio control interface for switch

Change-Id: I7981451c449435e5974c8321d99fc6c31e66f957
Signed-off-by: hongmin hua <hongmin.hua@amlogic.com>
Signed-off-by: Zhe Wang <Zhe.Wang@amlogic.com>
This commit is contained in:
hongmin hua
2018-03-27 19:40:05 +08:00
committed by Yixun Lan
parent 8ab76fbd25
commit 659be832df
5 changed files with 312 additions and 9 deletions

View File

@@ -806,6 +806,18 @@ static void cec_clear_logical_addr(void)
udelay(100);
}
void cec_enable_arc_pin(bool enable)
{
/* select arc according arg */
if (enable)
hdmirx_wr_top(TOP_ARCTX_CNTL, 0x01);
else
hdmirx_wr_top(TOP_ARCTX_CNTL, 0x00);
CEC_INFO("set arc en:%d, reg:%lx\n",
enable, hdmirx_rd_top(TOP_ARCTX_CNTL));
}
EXPORT_SYMBOL(cec_enable_arc_pin);
int cec_rx_buf_check(void)
{
unsigned int rx_num_msg;
@@ -2312,13 +2324,8 @@ static long hdmitx_cec_ioctl(struct file *f,
break;
case CEC_IOC_SET_ARC_ENABLE:
/* select arc according arg */
if (arg)
hdmirx_wr_top(TOP_ARCTX_CNTL, 0x01);
else
hdmirx_wr_top(TOP_ARCTX_CNTL, 0x00);
CEC_INFO("set arc en:%ld, reg:%lx\n",
arg, hdmirx_rd_top(TOP_ARCTX_CNTL));
CEC_INFO("Ioc set arc pin\n");
cec_enable_arc_pin(arg);
break;
default:

View File

@@ -18,7 +18,7 @@
#ifndef __AO_CEC_H__
#define __AO_CEC_H__
#define CEC_DRIVER_VERSION "2018/03/09\n"
#define CEC_DRIVER_VERSION "2018/03/27\n"
#define CEC_FRAME_DELAY msecs_to_jiffies(400)
#define CEC_DEV_NAME "cec"

View File

@@ -327,5 +327,6 @@ enum cec_device_menu_state_e {
int cec_ll_tx(const unsigned char *msg, unsigned char len);
int cec_ll_rx(unsigned char *msg, unsigned char *len);
extern void cec_enable_arc_pin(bool enable);
#endif

View File

@@ -43,6 +43,9 @@
#include <linux/io.h>
#include <linux/amlogic/media/sound/aiu_regs.h>
#include <linux/amlogic/media/sound/audio_iomap.h>
#ifdef CONFIG_AMLOGIC_AO_CEC
#include <linux/amlogic/media/vout/hdmi_tx/hdmi_tx_cec_20.h>
#endif
#include "i2s.h"
#include "audio_hw.h"
@@ -422,6 +425,261 @@ static int set_internal_EQ_volume(
return 0;
}
#ifdef CONFIG_AMLOGIC_AO_CEC
/* call HDMI CEC API to enable arc audio */
static void aml_switch_arc_audio(bool enable)
{
cec_enable_arc_pin(enable);
}
static int aml_get_arc_audio(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
struct aml_audio_private_data *p_aml_audio;
p_aml_audio = snd_soc_card_get_drvdata(card);
ucontrol->value.integer.value[0] = p_aml_audio->arc_enable;
return 0;
}
static int aml_set_arc_audio(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
struct aml_audio_private_data *p_aml_audio;
bool enable = ucontrol->value.integer.value[0];
p_aml_audio = snd_soc_card_get_drvdata(card);
aml_switch_arc_audio(enable);
p_aml_audio->arc_enable = enable;
return 0;
}
#endif
#ifdef CONFIG_TVIN_HDMI
/* call HDMI CEC API to enable arc audio */
static int aml_set_atmos_audio_edid(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
struct aml_audio_private_data *p_aml_audio;
bool enable = ucontrol->value.integer.value[0];
p_aml_audio = snd_soc_card_get_drvdata(card);
rx_set_atmos_flag(enable);
p_aml_audio->atmos_edid_enable = enable;
return 0;
}
static int aml_get_atmos_audio_edid(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
struct aml_audio_private_data *p_aml_audio;
p_aml_audio = snd_soc_card_get_drvdata(card);
ucontrol->value.integer.value[0] = p_aml_audio->atmos_edid_enable;
return 0;
}
/* copy from drivers/amlogic/tvin/hdmirx/hdmirx_drv.h */
struct hdmi_in_audio_status {
/*audio packets received*/
bool aud_rcv_flag;
/*audio stable status*/
bool aud_stb_flag;
/*audio sample rate*/
int aud_sr;
/*audio channel count*/
/*0: refer to stream header,*/
/*1: 2ch, 2: 3ch, 3: 4ch, 4: 5ch,*/
/*5: 6ch, 6: 7ch, 7: 8ch*/
int aud_channel_cnt;
/*audio coding type*/
/*0: refer to stream header, 1: IEC60958 PCM,*/
/*2: AC-3, 3: MPEG1 (Layers 1 and 2),*/
/*4: MP3 (MPEG1 Layer 3), 5: MPEG2 (multichannel),*/
/*6: AAC, 7: DTS, 8: ATRAC, 9: One Bit Audio,*/
/*10: Dolby Digital Plus, 11: DTS-HD,*/
/*12: MAT (MLP), 13: DST, 14: WMA Pro*/
int aud_type;
};
static const char *const hdmi_in_is_stable[] = {
"false",
"true"
};
static const char *const hdmi_in_samplerate[] = {
"N/A",
"32000",
"44100",
"48000",
"88200",
"96000",
"176400",
"192000"
};
static const char *const hdmi_in_channels[] = {
"NONE",
"2",
"3",
"4",
"5",
"6",
"7",
"8"
};
enum HDMIIN_format {
REFER_TO_HEADER = 0,
LPCM = 1,
AC3,
MPEG1,
MP3,
MPEG2,
AAC,
DTS,
ATRAC,
ONE_BIT_AUDIO,
DDP,
DTS_HD,
MAT,
DST,
WMA_PRO
};
static const char * const hdmi_in_format[] = {
"REFER_TO_HEADER",
"LPCM",
"AC3",
"MPEG1",
"MP3",
"MPEG2",
"AAC",
"DTS",
"ATRAC",
"ONE_BIT_AUDIO",
"DDP",
"DTS_HD",
"MAT",
"DST",
"WMA_PRO"
};
static const struct soc_enum hdmi_in_status_enum[] = {
SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(hdmi_in_is_stable),
hdmi_in_is_stable),
SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(hdmi_in_samplerate),
hdmi_in_samplerate),
SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(hdmi_in_channels),
hdmi_in_channels),
SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(hdmi_in_format),
hdmi_in_format)
};
static int aml_get_hdmiin_audio_stable(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct hdmi_in_audio_status aud_sts;
struct rx_audio_stat_s *rx_aud_sts;
rx_aud_sts = (struct rx_audio_stat_s *)&aud_sts;
rx_get_audio_status(rx_aud_sts);
ucontrol->value.integer.value[0] = aud_sts.aud_rcv_flag;
return 0;
}
static int aml_get_hdmiin_audio_samplerate(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct hdmi_in_audio_status aud_sts;
struct rx_audio_stat_s *rx_aud_sts;
int val = 0;
rx_aud_sts = (struct rx_audio_stat_s *)&aud_sts;
rx_get_audio_status(rx_aud_sts);
switch (aud_sts.aud_sr) {
case 0:
val = 0;
break;
case 32000:
val = 1;
break;
case 44100:
val = 2;
break;
case 48000:
val = 3;
break;
case 88200:
val = 4;
break;
case 96000:
val = 5;
break;
case 176400:
val = 6;
break;
case 192000:
val = 7;
break;
default:
pr_err("HDMIRX samplerate not support: %d\n", aud_sts.aud_sr);
break;
}
ucontrol->value.integer.value[0] = val;
return 0;
}
static int aml_get_hdmiin_audio_channels(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct rx_audio_stat_s *rx_aud_sts;
struct hdmi_in_audio_status aud_sts;
rx_aud_sts = (struct rx_audio_stat_s *)&aud_sts;
rx_get_audio_status(rx_aud_sts);
if (aud_sts.aud_channel_cnt <= 7)
ucontrol->value.integer.value[0] = aud_sts.aud_channel_cnt;
return 0;
}
static int aml_get_hdmiin_audio_format(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct rx_audio_stat_s *rx_aud_sts;
struct hdmi_in_audio_status aud_sts;
rx_aud_sts = (struct rx_audio_stat_s *)&aud_sts;
rx_get_audio_status(rx_aud_sts);
if (aud_sts.aud_type <= 14)
ucontrol->value.integer.value[0] = aud_sts.aud_type;
return 0;
}
#endif /* CONFIG_TVIN_HDMI */
#ifdef CONFIG_AM_DVB
static const char *const atv_audio_is_stable[] = {
"false",
"true"
};
static const struct soc_enum atv_audio_status_enum =
SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(atv_audio_is_stable),
atv_audio_is_stable);
static int aml_get_atv_audio_stable(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
int state = 0;
aml_fe_get_atvaudio_state(&state);
ucontrol->value.integer.value[0] = state;
return 0;
}
#endif /* CONFIG_AM_DVB */
#ifdef CONFIG_TVIN_VDIN
static const char *const av_audio_is_stable[] = {
"false",
"true"
};
static const struct soc_enum av_audio_status_enum =
SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(av_audio_is_stable),
av_audio_is_stable);
static int aml_get_av_audio_stable(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
ucontrol->value.integer.value[0] = tvin_get_av_status();
return 0;
}
#endif /* CONFIG_TVIN_VDIN */
static const struct snd_kcontrol_new av_controls[] = {
SOC_ENUM_EXT("AudioIn Switch",
audio_in_switch_enum,
@@ -449,7 +707,38 @@ static const struct snd_kcontrol_new aml_tv_controls[] = {
hardware_resample_enum,
aml_hardware_resample_get_enum,
aml_hardware_resample_set_enum),
#ifdef CONFIG_AMLOGIC_AO_CEC
SOC_SINGLE_BOOL_EXT("HDMI ARC Switch", 0,
aml_get_arc_audio,
aml_set_arc_audio),
#endif
#ifdef CONFIG_TVIN_HDMI
SOC_ENUM_EXT("HDMIIN audio stable", hdmi_in_status_enum[0],
aml_get_hdmiin_audio_stable,
NULL),
SOC_ENUM_EXT("HDMIIN audio samplerate", hdmi_in_status_enum[1],
aml_get_hdmiin_audio_samplerate,
NULL),
SOC_ENUM_EXT("HDMIIN audio channels", hdmi_in_status_enum[2],
aml_get_hdmiin_audio_channels,
NULL),
SOC_ENUM_EXT("HDMIIN audio format", hdmi_in_status_enum[3],
aml_get_hdmiin_audio_format,
NULL),
SOC_SINGLE_BOOL_EXT("HDMI ATMOS EDID Switch", 0,
aml_get_atmos_audio_edid,
aml_set_atmos_audio_edid),
#endif
#ifdef CONFIG_AM_DVB
SOC_ENUM_EXT("ATV audio stable", atv_audio_status_enum,
aml_get_atv_audio_stable,
NULL),
#endif
#ifdef CONFIG_TVIN_VDIN
SOC_ENUM_EXT("AV audio stable", av_audio_status_enum,
aml_get_av_audio_stable,
NULL),
#endif
};
static int aml_get_eqdrc_reg(struct snd_kcontrol *kcontrol,

View File

@@ -68,6 +68,12 @@ struct aml_audio_private_data {
/* tv info */
struct aml_card_info *cardinfo;
#ifdef CONFIG_AMLOGIC_AO_CEC
int arc_enable;
#endif
#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI
int atmos_edid_enable;
#endif
};
struct codec_info {