audio: auge: add lower power mode for PDM & vad [1/1]

PD#SWPL-3825

Problem:
VAD & PDM works in 24m clks for lowpower mode when in deep suspend

Solution:
support VAD & PDM in 24m sysclk, 768k dclk

Verify:
x301

Change-Id: Ic363337ee9b0eba0f890ae62b9e0cb6bb54dcd6a
Signed-off-by: Xing Wang <xing.wang@amlogic.com>
This commit is contained in:
Xing Wang
2019-01-19 16:05:46 +08:00
committed by Tao Zeng
parent 4f4b07abdb
commit 9eace31508
17 changed files with 227 additions and 44 deletions

View File

@@ -1429,7 +1429,6 @@
pinctrl-0 = <&spdifout_a>; pinctrl-0 = <&spdifout_a>;
pinctrl-1 = <&spdifout_a_mute>; pinctrl-1 = <&spdifout_a_mute>;
/* /*
* whether do asrc for pcm and resample a or b * whether do asrc for pcm and resample a or b
* if raw data, asrc is disabled automatically * if raw data, asrc is disabled automatically

View File

@@ -1651,7 +1651,7 @@
*/ */
level = <1>; level = <1>;
status = "disabled"; status = "okay";
}; };
loopbacka:loopback@0 { loopbacka:loopback@0 {

View File

@@ -1647,7 +1647,7 @@
*/ */
level = <1>; level = <1>;
status = "disabled"; status = "okay";
}; };
loopbacka:loopback@0 { loopbacka:loopback@0 {

View File

@@ -1646,7 +1646,7 @@
*/ */
level = <1>; level = <1>;
status = "disabled"; status = "okay";
}; };
loopbacka:loopback@0 { loopbacka:loopback@0 {

View File

@@ -1641,7 +1641,7 @@
*/ */
level = <1>; level = <1>;
status = "disabled"; status = "okay";
}; };
loopbacka:loopback@0 { loopbacka:loopback@0 {

View File

@@ -28,6 +28,8 @@
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/tlv.h> #include <sound/tlv.h>
#include <linux/amlogic/pm.h>
#include "pdm.h" #include "pdm.h"
#include "pdm_hw.h" #include "pdm_hw.h"
#include "pdm_match_table.c" #include "pdm_match_table.c"
@@ -230,6 +232,100 @@ static int pdm_bypass_set_enum(
return 0; return 0;
} }
static const char *const pdm_lowpower_texts[] = {
"PDM Normal Mode",
"PDM Low Power Mode",
};
static const struct soc_enum pdm_lowpower_enum =
SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(pdm_lowpower_texts),
pdm_lowpower_texts);
static void pdm_set_lowpower_mode(struct aml_pdm *p_pdm, bool isLowPower)
{
if (p_pdm->isLowPower == isLowPower)
return;
p_pdm->isLowPower = isLowPower;
if (p_pdm->clk_on) {
int osr, filter_mode, dclk_idx;
if (p_pdm->isLowPower) {
/* dclk for 768k */
dclk_idx = 2;
pr_info("%s force pdm sysclk to 24m, dclk 768k\n",
__func__);
} else
dclk_idx = p_pdm->dclk_idx;
clk_set_rate(p_pdm->clk_pdm_dclk,
pdm_dclkidx2rate(dclk_idx));
/* filter for pdm */
osr = pdm_get_ors(dclk_idx, p_pdm->rate);
if (!osr)
osr = 192;
filter_mode = p_pdm->isLowPower ? 4 : p_pdm->filter_mode;
aml_pdm_filter_ctrl(osr, filter_mode);
/* update sample count */
pdm_set_channel_ctrl(
pdm_get_sample_count(
p_pdm->isLowPower,
dclk_idx)
);
/* check to set pdm sysclk */
pdm_force_sysclk_to_oscin(p_pdm->isLowPower);
pr_info("\n%s, pdm_sysclk:%lu pdm_dclk:%lu, dclk_srcpll:%lu\n",
__func__,
clk_get_rate(p_pdm->clk_pdm_sysclk),
clk_get_rate(p_pdm->clk_pdm_dclk),
clk_get_rate(p_pdm->dclk_srcpll));
/* Check to set vad for Low Power */
if (vad_pdm_is_running())
vad_set_lowerpower_mode(p_pdm->isLowPower);
}
}
static int pdm_lowpower_get_enum(
struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct aml_pdm *p_pdm = dev_get_drvdata(component->dev);
if (!p_pdm)
return 0;
ucontrol->value.enumerated.item[0] = p_pdm->isLowPower;
return 0;
}
static int pdm_lowpower_set_enum(
struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct aml_pdm *p_pdm = dev_get_drvdata(component->dev);
bool isLowPower;
if (!p_pdm)
return 0;
isLowPower = (bool)ucontrol->value.enumerated.item[0];
pdm_set_lowpower_mode(p_pdm, isLowPower);
return 0;
}
static const char *const pdm_train_texts[] = { static const char *const pdm_train_texts[] = {
"Disabled", "Disabled",
"Enable", "Enable",
@@ -293,6 +389,11 @@ static const struct snd_kcontrol_new snd_pdm_controls[] = {
pdm_dclk_get_enum, pdm_dclk_get_enum,
pdm_dclk_set_enum), pdm_dclk_set_enum),
SOC_ENUM_EXT("PDM Low Power mode",
pdm_lowpower_enum,
pdm_lowpower_get_enum,
pdm_lowpower_set_enum),
SOC_ENUM_EXT("PDM Train", SOC_ENUM_EXT("PDM Train",
pdm_train_enum, pdm_train_enum,
pdm_train_get_enum, pdm_train_get_enum,
@@ -766,7 +867,7 @@ static int aml_pdm_dai_prepare(
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
struct toddr *to = p_pdm->tddr; struct toddr *to = p_pdm->tddr;
struct toddr_fmt fmt; struct toddr_fmt fmt;
unsigned int osr = 192, filter_mode; unsigned int osr = 192, filter_mode, dclk_idx;
struct pdm_info info; struct pdm_info info;
/* to ddr pdmin */ /* to ddr pdmin */
@@ -781,29 +882,41 @@ static int aml_pdm_dai_prepare(
aml_toddr_set_format(to, &fmt); aml_toddr_set_format(to, &fmt);
aml_toddr_set_fifos(to, 0x40); aml_toddr_set_fifos(to, 0x40);
info.bitdepth = bitwidth; /* force pdm sysclk to 24m */
info.channels = runtime->channels; if (p_pdm->isLowPower) {
info.lane_masks = p_pdm->lane_mask_in; /* dclk for 768k */
info.dclk_idx = p_pdm->dclk_idx; dclk_idx = 2;
info.bypass = p_pdm->bypass; filter_mode = 4;
info.sample_count = pdm_get_sample_count(p_pdm->isLowPower, pdm_force_sysclk_to_oscin(true);
p_pdm->dclk_idx); if (vad_pdm_is_running())
aml_pdm_ctrl(&info); vad_set_lowerpower_mode(true);
filter_mode = p_pdm->filter_mode; } else {
dclk_idx = p_pdm->dclk_idx;
filter_mode = p_pdm->filter_mode;
}
/* filter for pdm */ /* filter for pdm */
osr = pdm_get_ors(p_pdm->dclk_idx, runtime->rate); osr = pdm_get_ors(dclk_idx, runtime->rate);
if (!osr) if (!osr)
return -EINVAL; return -EINVAL;
pr_info("%s, pdm_dclk:%d, osr:%d, rate:%d filter mode:%d\n", pr_info("%s, pdm_dclk:%d, osr:%d, rate:%d filter mode:%d\n",
__func__, __func__,
pdm_dclkidx2rate(p_pdm->dclk_idx), pdm_dclkidx2rate(dclk_idx),
osr, osr,
runtime->rate, runtime->rate,
p_pdm->filter_mode); p_pdm->filter_mode);
info.bitdepth = bitwidth;
info.channels = runtime->channels;
info.lane_masks = p_pdm->lane_mask_in;
info.dclk_idx = dclk_idx;
info.bypass = p_pdm->bypass;
info.sample_count = pdm_get_sample_count(p_pdm->isLowPower,
dclk_idx);
aml_pdm_ctrl(&info);
aml_pdm_filter_ctrl(osr, filter_mode); aml_pdm_filter_ctrl(osr, filter_mode);
if (p_pdm->chipinfo && p_pdm->chipinfo->truncate_data) if (p_pdm->chipinfo && p_pdm->chipinfo->truncate_data)
@@ -871,6 +984,11 @@ static int aml_pdm_dai_set_sysclk(struct snd_soc_dai *cpu_dai,
{ {
struct aml_pdm *p_pdm = snd_soc_dai_get_drvdata(cpu_dai); struct aml_pdm *p_pdm = snd_soc_dai_get_drvdata(cpu_dai);
unsigned int sysclk_srcpll_freq, dclk_srcpll_freq; unsigned int sysclk_srcpll_freq, dclk_srcpll_freq;
unsigned int dclk_idx = p_pdm->dclk_idx;
/* lowpower, force dclk to 768k */
if (p_pdm->isLowPower)
dclk_idx = 2;
sysclk_srcpll_freq = clk_get_rate(p_pdm->sysclk_srcpll); sysclk_srcpll_freq = clk_get_rate(p_pdm->sysclk_srcpll);
dclk_srcpll_freq = clk_get_rate(p_pdm->dclk_srcpll); dclk_srcpll_freq = clk_get_rate(p_pdm->dclk_srcpll);
@@ -886,7 +1004,7 @@ static int aml_pdm_dai_set_sysclk(struct snd_soc_dai *cpu_dai,
clk_set_rate(p_pdm->dclk_srcpll, 24576000); clk_set_rate(p_pdm->dclk_srcpll, 24576000);
#endif #endif
clk_set_rate(p_pdm->clk_pdm_dclk, clk_set_rate(p_pdm->clk_pdm_dclk,
pdm_dclkidx2rate(p_pdm->dclk_idx)); pdm_dclkidx2rate(dclk_idx));
pr_info("\n%s, pdm_sysclk:%lu pdm_dclk:%lu, dclk_srcpll:%lu\n", pr_info("\n%s, pdm_sysclk:%lu pdm_dclk:%lu, dclk_srcpll:%lu\n",
__func__, __func__,
@@ -969,6 +1087,11 @@ void aml_pdm_dai_shutdown(struct snd_pcm_substream *substream,
p_pdm->clk_on = false; p_pdm->clk_on = false;
p_pdm->rate = 0; p_pdm->rate = 0;
if (p_pdm->isLowPower) {
pdm_force_sysclk_to_oscin(false);
vad_set_lowerpower_mode(false);
}
/* disable clock and gate */ /* disable clock and gate */
clk_disable_unprepare(p_pdm->clk_pdm_dclk); clk_disable_unprepare(p_pdm->clk_pdm_dclk);
clk_disable_unprepare(p_pdm->clk_pdm_sysclk); clk_disable_unprepare(p_pdm->clk_pdm_sysclk);
@@ -1145,6 +1268,8 @@ static int aml_pdm_platform_probe(struct platform_device *pdev)
/* defulat set 1 */ /* defulat set 1 */
p_pdm->filter_mode = 1; p_pdm->filter_mode = 1;
} }
pr_info("%s pdm filter mode from dts:%d\n",
__func__, p_pdm->filter_mode);
p_pdm->dev = dev; p_pdm->dev = dev;
dev_set_drvdata(&pdev->dev, p_pdm); dev_set_drvdata(&pdev->dev, p_pdm);
@@ -1181,23 +1306,55 @@ static int aml_pdm_platform_remove(struct platform_device *pdev)
snd_soc_unregister_component(&pdev->dev); snd_soc_unregister_component(&pdev->dev);
snd_soc_unregister_codec(&pdev->dev); snd_soc_unregister_platform(&pdev->dev);
return 0; return 0;
} }
static int pdm_platform_suspend(
struct platform_device *pdev, pm_message_t state)
{
struct aml_pdm *p_pdm = dev_get_drvdata(&pdev->dev);
/* whether in freeze */
if (is_pm_freeze_mode()
&& vad_pdm_is_running()) {
pr_info("%s, Entry in freeze\n", __func__);
pdm_set_lowpower_mode(p_pdm, true);
}
return 0;
}
static int pdm_platform_resume(
struct platform_device *pdev)
{
struct aml_pdm *p_pdm = dev_get_drvdata(&pdev->dev);
/* whether in freeze mode */
if (is_pm_freeze_mode()
&& vad_pdm_is_running()) {
pr_info("%s, Exist from freeze\n", __func__);
pdm_set_lowpower_mode(p_pdm, false);
}
return 0;
}
struct platform_driver aml_pdm_driver = { struct platform_driver aml_pdm_driver = {
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.of_match_table = of_match_ptr(aml_pdm_device_id), .of_match_table = of_match_ptr(aml_pdm_device_id),
}, },
.probe = aml_pdm_platform_probe, .probe = aml_pdm_platform_probe,
.remove = aml_pdm_platform_remove, .remove = aml_pdm_platform_remove,
.suspend = pdm_platform_suspend,
.resume = pdm_platform_resume,
}; };
module_platform_driver(aml_pdm_driver); module_platform_driver(aml_pdm_driver);
MODULE_AUTHOR("AMLogic, Inc."); MODULE_AUTHOR("AMLogic, Inc.");
MODULE_DESCRIPTION("Amlogic PDM ASoc driver"); MODULE_DESCRIPTION("Amlogic PDM ASoc driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");

View File

@@ -69,6 +69,10 @@ struct aml_pdm {
struct clk *clk_pdm_sysclk; struct clk *clk_pdm_sysclk;
struct clk *clk_pdm_dclk; struct clk *clk_pdm_dclk;
struct toddr *tddr; struct toddr *tddr;
struct pdm_chipinfo *chipinfo;
struct snd_kcontrol *controls[PDM_RUN_MAX];
/* sample rate */ /* sample rate */
int rate; int rate;
/* /*
@@ -93,9 +97,6 @@ struct aml_pdm {
/* low power mode, for dclk_sycpll to 24m */ /* low power mode, for dclk_sycpll to 24m */
bool isLowPower; bool isLowPower;
struct pdm_chipinfo *chipinfo;
struct snd_kcontrol *controls[PDM_RUN_MAX];
}; };
#endif /*__AML_PDM_H__*/ #endif /*__AML_PDM_H__*/

View File

@@ -59,6 +59,11 @@ void pdm_fifo_reset(void)
0x1 << 16); 0x1 << 16);
} }
void pdm_force_sysclk_to_oscin(bool force)
{
audiobus_update_bits(EE_AUDIO_CLK_PDMIN_CTRL1, 0x1 << 30, force << 30);
}
void pdm_set_channel_ctrl(int sample_count) void pdm_set_channel_ctrl(int sample_count)
{ {
aml_pdm_write(PDM_CHAN_CTRL, ((sample_count << 24) | aml_pdm_write(PDM_CHAN_CTRL, ((sample_count << 24) |
@@ -547,14 +552,16 @@ int pdm_get_ors(int dclk_idx, int sample_rate)
else if (sample_rate == 8000) else if (sample_rate == 8000)
osr = 128; osr = 128;
else else
pr_err("Not support rate:%d\n", sample_rate); pr_err("%s, Not support rate:%d\n",
__func__, sample_rate);
} else if (dclk_idx == 2) { } else if (dclk_idx == 2) {
if (sample_rate == 16000) if (sample_rate == 16000)
osr = 48; osr = 48;
else if (sample_rate == 8000) else if (sample_rate == 8000)
osr = 96; osr = 96;
else else
pr_err("Not support rate:%d\n", sample_rate); pr_err("%s, Not support rate:%d\n",
__func__, sample_rate);
} else { } else {
if (sample_rate == 96000) if (sample_rate == 96000)
osr = 32; osr = 32;
@@ -569,7 +576,8 @@ int pdm_get_ors(int dclk_idx, int sample_rate)
else if (sample_rate == 8000) else if (sample_rate == 8000)
osr = 384; osr = 384;
else else
pr_err("Not support rate:%d\n", sample_rate); pr_err("%s, Not support rate:%d\n",
__func__, sample_rate);
} }
return osr; return osr;

View File

@@ -34,6 +34,9 @@ struct pdm_info {
extern void aml_pdm_ctrl(struct pdm_info *info); extern void aml_pdm_ctrl(struct pdm_info *info);
extern void pdm_force_sysclk_to_oscin(bool force);
extern void pdm_set_channel_ctrl(int sample_count);
extern void aml_pdm_arb_config(struct aml_audio_controller *actrl); extern void aml_pdm_arb_config(struct aml_audio_controller *actrl);
extern int aml_pmd_set_HPF_filter_parameters(void *array); extern int aml_pmd_set_HPF_filter_parameters(void *array);

View File

@@ -107,7 +107,7 @@ enum clk_sel {
#define EE_AUDIO_CLK_RESAMPLEB_CTRL 0x02e #define EE_AUDIO_CLK_RESAMPLEB_CTRL 0x02e
#define EE_AUDIO_CLK_SPDIFIN_LB_CTRL 0x02f #define EE_AUDIO_CLK_SPDIFIN_LB_CTRL 0x02f
#define EE_AUDIO_CLK_EQDRC_CTRL0 0x030 #define EE_AUDIO_CLK_EQDRC_CTRL0 0x030
#define EE_AUDIO_VAD_CLK_CTRL 0x031 #define EE_AUDIO_CLK_VAD_CTRL 0x031
#define EE_AUDIO_EARCTX_CMDC_CLK_CTRL 0x032 #define EE_AUDIO_EARCTX_CMDC_CLK_CTRL 0x032
#define EE_AUDIO_EARCTX_DMAC_CLK_CTRL 0x033 #define EE_AUDIO_EARCTX_DMAC_CLK_CTRL 0x033
#define EE_AUDIO_EARCRX_CMDC_CLK_CTRL 0x034 #define EE_AUDIO_EARCRX_CMDC_CLK_CTRL 0x034

View File

@@ -244,9 +244,9 @@ CLOCK_COM_MUX(eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_EQDRC_CTRL0), 0x7, 24);
CLOCK_COM_DIV(eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_EQDRC_CTRL0), 0, 16); CLOCK_COM_DIV(eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_EQDRC_CTRL0), 0, 16);
CLOCK_COM_GATE(eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_EQDRC_CTRL0), 31); CLOCK_COM_GATE(eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_EQDRC_CTRL0), 31);
/* audio vad */ /* audio vad */
CLOCK_COM_MUX(vad, AUD_ADDR_OFFSET(EE_AUDIO_VAD_CLK_CTRL), 0x7, 24); CLOCK_COM_MUX(vad, AUD_ADDR_OFFSET(EE_AUDIO_CLK_VAD_CTRL), 0x7, 24);
CLOCK_COM_DIV(vad, AUD_ADDR_OFFSET(EE_AUDIO_VAD_CLK_CTRL), 0, 16); CLOCK_COM_DIV(vad, AUD_ADDR_OFFSET(EE_AUDIO_CLK_VAD_CTRL), 0, 16);
CLOCK_COM_GATE(vad, AUD_ADDR_OFFSET(EE_AUDIO_VAD_CLK_CTRL), 31); CLOCK_COM_GATE(vad, AUD_ADDR_OFFSET(EE_AUDIO_CLK_VAD_CTRL), 31);
/* EARC TX CMDC */ /* EARC TX CMDC */
CLOCK_COM_MUX(earctx_cmdc, CLOCK_COM_MUX(earctx_cmdc,
AUD_ADDR_OFFSET(EE_AUDIO_EARCTX_CMDC_CLK_CTRL), 0x7, 24); AUD_ADDR_OFFSET(EE_AUDIO_EARCTX_CMDC_CLK_CTRL), 0x7, 24);

View File

@@ -231,9 +231,9 @@ CLOCK_COM_MUX(eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_EQDRC_CTRL0), 0x7, 24);
CLOCK_COM_DIV(eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_EQDRC_CTRL0), 0, 16); CLOCK_COM_DIV(eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_EQDRC_CTRL0), 0, 16);
CLOCK_COM_GATE(eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_EQDRC_CTRL0), 31); CLOCK_COM_GATE(eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_EQDRC_CTRL0), 31);
/* audio vad */ /* audio vad */
CLOCK_COM_MUX(vad, AUD_ADDR_OFFSET(EE_AUDIO_VAD_CLK_CTRL), 0x7, 24); CLOCK_COM_MUX(vad, AUD_ADDR_OFFSET(EE_AUDIO_CLK_VAD_CTRL), 0x7, 24);
CLOCK_COM_DIV(vad, AUD_ADDR_OFFSET(EE_AUDIO_VAD_CLK_CTRL), 0, 16); CLOCK_COM_DIV(vad, AUD_ADDR_OFFSET(EE_AUDIO_CLK_VAD_CTRL), 0, 16);
CLOCK_COM_GATE(vad, AUD_ADDR_OFFSET(EE_AUDIO_VAD_CLK_CTRL), 31); CLOCK_COM_GATE(vad, AUD_ADDR_OFFSET(EE_AUDIO_CLK_VAD_CTRL), 31);
static int tl1_clks_init(struct clk **clks, void __iomem *iobase) static int tl1_clks_init(struct clk **clks, void __iomem *iobase)
{ {

View File

@@ -260,9 +260,9 @@ CLOCK_COM_MUX(eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_EQDRC_CTRL0), 0x7, 24);
CLOCK_COM_DIV(eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_EQDRC_CTRL0), 0, 16); CLOCK_COM_DIV(eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_EQDRC_CTRL0), 0, 16);
CLOCK_COM_GATE(eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_EQDRC_CTRL0), 31); CLOCK_COM_GATE(eqdrc, AUD_ADDR_OFFSET(EE_AUDIO_CLK_EQDRC_CTRL0), 31);
/* audio vad */ /* audio vad */
CLOCK_COM_MUX(vad, AUD_ADDR_OFFSET(EE_AUDIO_VAD_CLK_CTRL), 0x7, 24); CLOCK_COM_MUX(vad, AUD_ADDR_OFFSET(EE_AUDIO_CLK_VAD_CTRL), 0x7, 24);
CLOCK_COM_DIV(vad, AUD_ADDR_OFFSET(EE_AUDIO_VAD_CLK_CTRL), 0, 16); CLOCK_COM_DIV(vad, AUD_ADDR_OFFSET(EE_AUDIO_CLK_VAD_CTRL), 0, 16);
CLOCK_COM_GATE(vad, AUD_ADDR_OFFSET(EE_AUDIO_VAD_CLK_CTRL), 31); CLOCK_COM_GATE(vad, AUD_ADDR_OFFSET(EE_AUDIO_CLK_VAD_CTRL), 31);
/* EARC TX CMDC */ /* EARC TX CMDC */
CLOCK_COM_MUX(earctx_cmdc, CLOCK_COM_MUX(earctx_cmdc,
AUD_ADDR_OFFSET(EE_AUDIO_EARCTX_CMDC_CLK_CTRL), 0x7, 24); AUD_ADDR_OFFSET(EE_AUDIO_EARCTX_CMDC_CLK_CTRL), 0x7, 24);

View File

@@ -541,6 +541,11 @@ static void vad_deinit(struct vad *p_vad)
vad_set_clks(p_vad, false); vad_set_clks(p_vad, false);
} }
void vad_set_lowerpower_mode(bool isLowPower)
{
vad_force_clk_to_oscin(isLowPower);
}
void vad_update_buffer(int isvad) void vad_update_buffer(int isvad)
{ {
struct vad *p_vad = get_vad(); struct vad *p_vad = get_vad();
@@ -561,7 +566,7 @@ void vad_update_buffer(int isvad)
p_vad->start_last = tddr->start_addr; p_vad->start_last = tddr->start_addr;
p_vad->end_last = tddr->end_addr; p_vad->end_last = tddr->end_addr;
rd_th = 0x100; rd_th = 0x800;
pr_debug("Switch to VAD buffer\n"); pr_debug("Switch to VAD buffer\n");
pr_debug("\t ASAL start:%x, end:%x, bytes:%d\n", pr_debug("\t ASAL start:%x, end:%x, bytes:%d\n",
@@ -1003,7 +1008,8 @@ static int vad_platform_probe(struct platform_device *pdev)
return 0; return 0;
} }
int vad_platform_suspend(struct platform_device *pdev, pm_message_t state) static int vad_platform_suspend(
struct platform_device *pdev, pm_message_t state)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct vad *p_vad = dev_get_drvdata(dev); struct vad *p_vad = dev_get_drvdata(dev);
@@ -1022,7 +1028,8 @@ int vad_platform_suspend(struct platform_device *pdev, pm_message_t state)
return 0; return 0;
} }
int vad_platform_resume(struct platform_device *pdev) static int vad_platform_resume(
struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct vad *p_vad = dev_get_drvdata(dev); struct vad *p_vad = dev_get_drvdata(dev);

View File

@@ -44,4 +44,5 @@ extern void vad_set_trunk_data_readable(bool en);
extern int card_add_vad_kcontrols(struct snd_soc_card *card); extern int card_add_vad_kcontrols(struct snd_soc_card *card);
extern void vad_set_lowerpower_mode(bool isLowPower);
#endif #endif

View File

@@ -107,3 +107,8 @@ void vad_set_enable(bool enable)
vad_write(VAD_TOP_CTRL1, 0x0); vad_write(VAD_TOP_CTRL1, 0x0);
} }
} }
void vad_force_clk_to_oscin(bool force)
{
audiobus_update_bits(EE_AUDIO_CLK_VAD_CTRL, 0x1 << 30, force << 30);
}

View File

@@ -35,4 +35,6 @@ extern void vad_set_src(int src);
extern void vad_set_in(void); extern void vad_set_in(void);
extern void vad_set_enable(bool enable); extern void vad_set_enable(bool enable);
extern void vad_force_clk_to_oscin(bool force);
#endif #endif