mirror of
https://github.com/hardkernel/kernel_common_drivers.git
synced 2026-06-25 12:03:48 +09:00
audio: don't send dts data for AVRs which don't support dts format [1/1]
PD#SWPL-193936 Problem: For AVRs which don't support dts format, if send some dts data, it will no sound, and 't recovery. When spdif dual output dts when audio output devices is speaker, audio output devices switch from speaker to arc, the beginning data format is still dts. Solution: For AVRs which don't support dts format, so can't send dts data. If the data format is still dts, then unmute it later and audio hal will change the output data format later. Verify: t6d Change-Id: Ia03bd62648058ef0797b9bd95794118ce52a3366 Signed-off-by: jian zhou <jian.zhou@amlogic.com>
This commit is contained in:
committed by
gerrit autosubmit
parent
c543fc5a7a
commit
ca92eadacb
@@ -268,6 +268,7 @@
|
||||
/*spdif clk tuning enable*/
|
||||
clk_tuning_enable = <1>;
|
||||
suspend-clk-off = <1>;
|
||||
is_arc = <1>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
@@ -268,6 +268,7 @@
|
||||
/*spdif clk tuning enable*/
|
||||
clk_tuning_enable = <1>;
|
||||
suspend-clk-off = <1>;
|
||||
is_arc = <1>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
@@ -109,6 +109,7 @@ struct aml_spdif {
|
||||
struct regulator *regulator_vcc3v3;
|
||||
struct regulator *regulator_vcc5v;
|
||||
int suspend_clk_off;
|
||||
int is_arc;
|
||||
bool earc_use_48k;
|
||||
/* Standardization value by normal setting */
|
||||
unsigned int standard_sysclk;
|
||||
@@ -116,6 +117,7 @@ struct aml_spdif {
|
||||
/* stream ready to read audio type */
|
||||
bool rx_stable;
|
||||
struct delayed_work rx_stable_dwork;
|
||||
struct delayed_work mute_work;
|
||||
};
|
||||
|
||||
unsigned int get_spdif_source_l_config(int id)
|
||||
@@ -153,8 +155,7 @@ void aml_spdifout_enable(int spdif_id, bool is_enable, bool reenable)
|
||||
int spdif_reg_mute = 0;
|
||||
|
||||
if (!is_enable)
|
||||
aml_spdifout_mute_without_actrl(p_spdif->id, false, true,
|
||||
p_spdif->chipinfo->gain_ver);
|
||||
aml_spdifout_mute_without_actrl(p_spdif->id, false, true);
|
||||
|
||||
spdifout_enable(spdif_id, is_enable, reenable);
|
||||
|
||||
@@ -162,8 +163,7 @@ void aml_spdifout_enable(int spdif_id, bool is_enable, bool reenable)
|
||||
udelay(9);
|
||||
if (p_spdif->spdif_soft_mute)
|
||||
spdif_reg_mute = p_spdif->mute;
|
||||
aml_spdifout_mute_without_actrl(p_spdif->id, true, spdif_reg_mute,
|
||||
p_spdif->chipinfo->gain_ver);
|
||||
aml_spdifout_mute_without_actrl(p_spdif->id, true, spdif_reg_mute);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -409,8 +409,7 @@ static void ss_mute(int samesource_sel, bool mute)
|
||||
struct aml_spdif *p_spdif = ops->private;
|
||||
if (p_spdif->spdif_soft_mute)
|
||||
spdif_reg_mute = p_spdif->mute;
|
||||
aml_spdifout_mute_without_actrl(samesource_sel - 3, !mute, spdif_reg_mute,
|
||||
p_spdif->chipinfo->gain_ver);
|
||||
aml_spdifout_mute_without_actrl(samesource_sel - 3, !mute, spdif_reg_mute);
|
||||
|
||||
if (p_spdif->samesource_sel != SHAREBUFFER_NONE &&
|
||||
get_samesrc_ops(p_spdif->samesource_sel) &&
|
||||
@@ -686,6 +685,15 @@ static int aml_audio_get_spdif_mute(struct snd_kcontrol *kcontrol,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mute_work_func(struct work_struct *p_work)
|
||||
{
|
||||
struct aml_spdif *p_spdif = container_of(to_delayed_work(p_work),
|
||||
struct aml_spdif, mute_work);
|
||||
|
||||
if (aml_spdif_out_get_mute(p_spdif->actrl, p_spdif->id) != p_spdif->mute)
|
||||
aml_spdif_out_mute(p_spdif->actrl, p_spdif->id, p_spdif->mute);
|
||||
}
|
||||
|
||||
static int aml_audio_set_spdif_mute(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
@@ -713,10 +721,18 @@ static int aml_audio_set_spdif_mute(struct snd_kcontrol *kcontrol,
|
||||
pinctrl_select_state(p_spdif->pin_ctl, state);
|
||||
}
|
||||
} else {
|
||||
int gain_ver = p_spdif->chipinfo->gain_ver;
|
||||
|
||||
if (aml_spdif_out_get_mute(p_spdif->actrl, p_spdif->id, gain_ver) != mute)
|
||||
aml_spdif_out_mute(p_spdif->actrl, p_spdif->id, mute, gain_ver);
|
||||
/* for avrs which don't support dts format, so can't send dts data.
|
||||
* when spdif dual output dts when audio output devices is speaker,
|
||||
* audio output devices switch from speaker to arc, if the data
|
||||
* format is still dts, then unmute it later and audio hal will
|
||||
* change the output data format later.
|
||||
*/
|
||||
if (p_spdif->is_arc && !mute && p_spdif->codec_type == AUD_CODEC_TYPE_DTS) {
|
||||
schedule_delayed_work(&p_spdif->mute_work, msecs_to_jiffies(30));
|
||||
} else {
|
||||
if (aml_spdif_out_get_mute(p_spdif->actrl, p_spdif->id) != mute)
|
||||
aml_spdif_out_mute(p_spdif->actrl, p_spdif->id, mute);
|
||||
}
|
||||
}
|
||||
|
||||
p_spdif->mute = mute;
|
||||
@@ -1535,8 +1551,7 @@ static int aml_dai_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
udelay(100);
|
||||
if (p_spdif->spdif_soft_mute)
|
||||
spdif_reg_mute = p_spdif->mute;
|
||||
aml_spdifout_mute_without_actrl(p_spdif->id, true, spdif_reg_mute,
|
||||
p_spdif->chipinfo->gain_ver);
|
||||
aml_spdifout_mute_without_actrl(p_spdif->id, true, spdif_reg_mute);
|
||||
if (p_spdif->samesource_sel != SHAREBUFFER_NONE)
|
||||
spdif_sharebuffer_mute(p_spdif, false);
|
||||
} else {
|
||||
@@ -1566,8 +1581,7 @@ static int aml_dai_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
* only mute, ensure spdif outputs zero data.
|
||||
*/
|
||||
if (p_spdif->clk_cont) {
|
||||
aml_spdifout_mute_without_actrl(p_spdif->id, false, true,
|
||||
p_spdif->chipinfo->gain_ver);
|
||||
aml_spdifout_mute_without_actrl(p_spdif->id, false, true);
|
||||
if (p_spdif->samesource_sel != SHAREBUFFER_NONE)
|
||||
spdif_sharebuffer_mute(p_spdif, true);
|
||||
} else {
|
||||
@@ -2224,6 +2238,10 @@ static int aml_spdif_platform_probe(struct platform_device *pdev)
|
||||
if (ret < 0)
|
||||
dev_err(&pdev->dev, "Can't retrieve suspend-clk-off\n");
|
||||
|
||||
ret = of_property_read_u32(node, "is_arc", &aml_spdif->is_arc);
|
||||
if (ret < 0)
|
||||
dev_dbg(&pdev->dev, "Can't retrieve is_arc\n");
|
||||
|
||||
/* get audio controller */
|
||||
node_prt = of_get_parent(node);
|
||||
if (!node_prt)
|
||||
@@ -2247,6 +2265,8 @@ static int aml_spdif_platform_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
spdif_priv[aml_spdif->id] = aml_spdif;
|
||||
if (aml_spdif->is_arc)
|
||||
INIT_DELAYED_WORK(&aml_spdif->mute_work, mute_work_func);
|
||||
if (aml_spdif->id == 0)
|
||||
INIT_DELAYED_WORK(&aml_spdif->rx_stable_dwork, rx_stable_dwork_func);
|
||||
|
||||
|
||||
@@ -52,90 +52,41 @@ void aml_spdif_enable(struct aml_audio_controller *actrl,
|
||||
}
|
||||
}
|
||||
|
||||
int aml_spdif_out_get_mute(struct aml_audio_controller *actrl, int index, int gain_ver)
|
||||
int aml_spdif_out_get_mute(struct aml_audio_controller *actrl, int index)
|
||||
{
|
||||
unsigned int offset, reg;
|
||||
bool mute, gain_mute = false;
|
||||
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
|
||||
reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * index;
|
||||
mute = !!(aml_audiobus_read(actrl, reg) & (0x3 << 21));
|
||||
|
||||
if (gain_ver == GAIN_VER3) {
|
||||
/* gain enable is mute state */
|
||||
offset = EE_AUDIO_SPDIFOUT_B_GAIN_EN - EE_AUDIO_SPDIFOUT_GAIN_EN;
|
||||
reg = EE_AUDIO_SPDIFOUT_GAIN_EN + offset * index;
|
||||
gain_mute = !!(aml_audiobus_read(actrl, reg) & 0xf);
|
||||
}
|
||||
|
||||
return mute || gain_mute;
|
||||
return !!(aml_audiobus_read(actrl, reg) & (0x3 << 21));
|
||||
}
|
||||
|
||||
/* only mute reg, keep get data from frddr */
|
||||
void aml_spdif_out_mute(struct aml_audio_controller *actrl,
|
||||
int index, bool is_mute, int gain_ver)
|
||||
int index, bool is_mute)
|
||||
{
|
||||
int mute_lr = 0;
|
||||
unsigned int offset, reg;
|
||||
|
||||
if (gain_ver == GAIN_VER3) {
|
||||
unsigned int offset1, reg1;
|
||||
if (is_mute)
|
||||
mute_lr = 0x3;
|
||||
|
||||
offset = EE_AUDIO_SPDIFOUT_B_GAIN_EN - EE_AUDIO_SPDIFOUT_GAIN_EN;
|
||||
reg = EE_AUDIO_SPDIFOUT_GAIN_EN + offset * index;
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
|
||||
reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * index;
|
||||
|
||||
offset1 = EE_AUDIO_SPDIFOUT_B_GAIN0 - EE_AUDIO_SPDIFOUT_GAIN0;
|
||||
reg1 = EE_AUDIO_SPDIFOUT_GAIN0 + offset * index;
|
||||
|
||||
if (is_mute) {
|
||||
/* set gain enable 1, and gain value 0 */
|
||||
aml_audiobus_write(actrl, reg, 0xf);
|
||||
aml_audiobus_write(actrl, reg1, 0);
|
||||
} else {
|
||||
/* set gain enable 0 gain value 255 */
|
||||
aml_audiobus_write(actrl, reg, 0);
|
||||
aml_audiobus_write(actrl, reg1, 0xffffffff);
|
||||
|
||||
/* need reg unmute */
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
|
||||
reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * index;
|
||||
|
||||
aml_audiobus_update_bits(actrl, reg, 0x3 << 21, 0 << 21);
|
||||
}
|
||||
} else {
|
||||
int mute_lr = 0;
|
||||
|
||||
if (is_mute)
|
||||
mute_lr = 0x3;
|
||||
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
|
||||
reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * index;
|
||||
|
||||
aml_audiobus_update_bits(actrl, reg, 0x3 << 21, mute_lr << 21);
|
||||
}
|
||||
aml_audiobus_update_bits(actrl, reg, 0x3 << 21, mute_lr << 21);
|
||||
}
|
||||
|
||||
/* for stream trigger, need stop get data from frddr,
|
||||
* otherwise, it will channel swap from tdm 8 channels.
|
||||
*/
|
||||
void aml_spdifout_mute_without_actrl(int index, bool start, bool is_mute, int gain_ver)
|
||||
void aml_spdifout_mute_without_actrl(int index, bool start, bool is_mute)
|
||||
{
|
||||
unsigned int offset, reg;
|
||||
int mute_lr = 0;
|
||||
|
||||
if (is_mute) {
|
||||
if (is_mute)
|
||||
mute_lr = 0x3;
|
||||
} else {
|
||||
if (gain_ver == GAIN_VER3) {
|
||||
/* unmute case, set gain enable 0 and gain value as 255 */
|
||||
offset = EE_AUDIO_SPDIFOUT_B_GAIN_EN - EE_AUDIO_SPDIFOUT_GAIN_EN;
|
||||
reg = EE_AUDIO_SPDIFOUT_GAIN_EN + offset * index;
|
||||
audiobus_write(reg, 0);
|
||||
|
||||
offset = EE_AUDIO_SPDIFOUT_B_GAIN0 - EE_AUDIO_SPDIFOUT_GAIN0;
|
||||
reg = EE_AUDIO_SPDIFOUT_GAIN0 + offset * index;
|
||||
audiobus_write(reg, 0xffffffff);
|
||||
}
|
||||
}
|
||||
|
||||
offset = EE_AUDIO_SPDIFOUT_B_CTRL0 - EE_AUDIO_SPDIFOUT_CTRL0;
|
||||
reg = EE_AUDIO_SPDIFOUT_CTRL0 + offset * index;
|
||||
|
||||
@@ -18,11 +18,11 @@ void aml_spdif_enable(struct aml_audio_controller *actrl,
|
||||
int index,
|
||||
bool is_enable);
|
||||
|
||||
void aml_spdifout_mute_without_actrl(int index, bool start, bool is_mute, int gain_ver);
|
||||
void aml_spdifout_mute_without_actrl(int index, bool start, bool is_mute);
|
||||
|
||||
int aml_spdif_out_get_mute(struct aml_audio_controller *actrl, int index, int gain_ver);
|
||||
int aml_spdif_out_get_mute(struct aml_audio_controller *actrl, int index);
|
||||
void aml_spdif_out_mute(struct aml_audio_controller *actrl,
|
||||
int index, bool is_mute, int gain_ver);
|
||||
int index, bool is_mute);
|
||||
|
||||
void aml_spdif_arb_config(struct aml_audio_controller *actrl, bool use_arb);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user