audio: clock only enable in runtime for power consumption

PD#146592: audio: clock only enable in runtime for power consumption

1. clocks for tdm in & out/spdif in & out/pdm in, only enable when runtime
2. remove unused codes

Change-Id: Ic75ab4557b9e1c26fa032a5b14a7a39ae53f6a06
Signed-off-by: Xing Wang <xing.wang@amlogic.com>
This commit is contained in:
Xing Wang
2017-06-27 23:22:01 +08:00
parent 189e32aa66
commit f048dbda0f
10 changed files with 229 additions and 243 deletions

View File

@@ -459,7 +459,6 @@
<1 1 1 1 1 1 1 1>;
dai-tdm-slot-num = <8>;
dai-tdm-slot-width = <32>;
system-clock-frequency = <24576000>;
};
tdmacodec: codec {
sound-dai = <&dummy_codec &dummy_codec>;
@@ -480,7 +479,6 @@
dai-tdm-slot-rx-mask = <1 1>;
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <32>;
system-clock-frequency = <12288000>;
};
codec {
prefix-names = "3101_A", "3101_B",
@@ -504,7 +502,6 @@
dai-tdm-slot-rx-mask = <1 1>;
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <32>;
system-clock-frequency = <12288000>;
};
codec {
prefix-names = "5707_A", "5707_B";
@@ -514,13 +511,7 @@
};
aml-audio-card,dai-link@3 {
format = "i2s";
mclk-fs = <256>;
continuous-clock;
//bitclock-inversion;
//frame-inversion;
bitclock-master = <&aml_pdm>;
frame-master = <&aml_pdm>;
cpu {
sound-dai = <&aml_pdm>;
};
@@ -530,12 +521,9 @@
};
aml-audio-card,dai-link@4 {
//format = "i2s";
mclk-fs = <128>;
continuous-clock;
cpu {
sound-dai = <&aml_spdif>;
system-clock-frequency = <12288000>;
};
codec {
sound-dai = <&dummy_codec>;

View File

@@ -343,7 +343,6 @@
dai-tdm-slot-rx-mask = <1 1>;
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <32>;
system-clock-frequency = <12288000>;
};
codec {
sound-dai = <&dummy_codec &dummy_codec>;
@@ -364,7 +363,6 @@
dai-tdm-slot-rx-mask = <1 1>;
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <32>;
system-clock-frequency = <12288000>;
};
codec {
sound-dai = <&tas5707_36 &tlv320adc3101_32>;
@@ -386,7 +384,6 @@
dai-tdm-slot-rx-mask = <1 1>;
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <32>;
system-clock-frequency = <12288000>;
};
codec {
sound-dai = <&dummy_codec>;
@@ -394,13 +391,7 @@
};
aml-audio-card,dai-link@3 {
format = "i2s";
mclk-fs = <256>;
continuous-clock;
//bitclock-inversion;
//frame-inversion;
bitclock-master = <&aml_pdm>;
frame-master = <&aml_pdm>;
cpu {
sound-dai = <&aml_pdm>;
};
@@ -410,12 +401,9 @@
};
/*aml-audio-card,dai-link@4 {
* //format = "i2s";
* mclk-fs = <128>;
* continuous-clock;
* cpu {
* sound-dai = <&aml_spdif>;
* system-clock-frequency = <12288000>;
* };
* codec {
* sound-dai = <&dummy_codec>;

View File

@@ -169,6 +169,8 @@ static int aml_card_hw_params(struct snd_pcm_substream *substream,
mclk_fs = dai_props->mclk_fs;
if (mclk_fs) {
struct aml_dai *aml_codec_dai = &dai_props->codec_dai;
struct aml_dai *aml_cpu_dai = &dai_props->cpu_dai;
mclk = params_rate(params) * mclk_fs;
for (i = 0; i < rtd->num_codecs; i++) {
@@ -179,12 +181,31 @@ static int aml_card_hw_params(struct snd_pcm_substream *substream,
if (ret && ret != -ENOTSUPP)
goto err;
ret = snd_soc_dai_set_tdm_slot(codec_dai,
aml_codec_dai->tx_slot_mask,
aml_codec_dai->rx_slot_mask,
aml_codec_dai->slots,
aml_codec_dai->slot_width);
if (ret && ret != -ENOTSUPP) {
pr_err("aml-card: set_tdm_slot error\n");
goto err;
}
}
ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
SND_SOC_CLOCK_OUT);
if (ret && ret != -ENOTSUPP)
goto err;
ret = snd_soc_dai_set_tdm_slot(cpu_dai,
aml_cpu_dai->tx_slot_mask,
aml_cpu_dai->rx_slot_mask,
aml_cpu_dai->slots,
aml_cpu_dai->slot_width);
if (ret && ret != -ENOTSUPP) {
pr_err("aml-card: set_tdm_slot error\n");
goto err;
}
}
return 0;
err:
@@ -200,23 +221,7 @@ static struct snd_soc_ops aml_card_ops = {
static int aml_card_dai_init(struct snd_soc_pcm_runtime *rtd)
{
struct aml_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
struct snd_soc_dai *codec = rtd->codec_dai;
struct snd_soc_dai *cpu = rtd->cpu_dai;
struct aml_dai_props *dai_props =
aml_priv_to_props(priv, rtd->num);
int ret, i;
for (i = 0; i < rtd->num_codecs; i++) {
codec = rtd->codec_dais[i];
ret = aml_card_init_dai(codec, &dai_props->codec_dai);
if (ret < 0)
return ret;
}
ret = aml_card_init_dai(cpu, &dai_props->cpu_dai);
if (ret < 0)
return ret;
int ret;
ret = aml_card_init_hp(rtd->card, &priv->hp_jack, PREFIX);
if (ret < 0)

View File

@@ -93,6 +93,33 @@ void aml_pdm_update_bits(unsigned int reg,
}
EXPORT_SYMBOL(aml_pdm_update_bits);
int audiobus_read(unsigned int reg)
{
int ret, val = 0;
ret = aml_snd_read(IO_AUDIO_BUS, reg, &val);
if (ret) {
pr_err("read audio reg %x error %d\n", reg, ret);
return -1;
}
return val;
}
EXPORT_SYMBOL(audiobus_read);
void audiobus_write(unsigned int reg, unsigned int val)
{
aml_snd_write(IO_AUDIO_BUS, reg, val);
}
EXPORT_SYMBOL(audiobus_write);
void audiobus_update_bits(unsigned int reg,
unsigned int mask, unsigned int val)
{
aml_snd_update_bits(IO_AUDIO_BUS, reg, mask, val);
}
EXPORT_SYMBOL(audiobus_update_bits);
static int snd_iomap_probe(struct platform_device *pdev)
{
struct resource res;

View File

@@ -32,4 +32,11 @@ extern void aml_pdm_write(unsigned int reg, unsigned int val);
extern void aml_pdm_update_bits(unsigned int reg,
unsigned int mask, unsigned int val);
extern int audiobus_read(unsigned int reg);
extern void audiobus_write(unsigned int reg, unsigned int val);
extern void audiobus_update_bits(unsigned int reg,
unsigned int mask, unsigned int val);
#endif

View File

@@ -133,47 +133,6 @@ static int pdm_hcic_shift_gain_set_enum(
return 0;
}
static int aml_pdm_cntrl_get_reg(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) {
struct soc_mixer_control *mixcntrl =
(struct soc_mixer_control *)kcontrol->private_value;
unsigned int reg = mixcntrl->reg;
unsigned int shift = mixcntrl->shift;
unsigned int max = mixcntrl->max;
unsigned int invert = mixcntrl->invert;
unsigned int value = (((unsigned int)
aml_pdm_read(reg))
>> shift) & max;
if (invert)
value = (~value) & max;
ucontrol->value.integer.value[0] = value;
return 0;
}
static int aml_pdm_cntrl_set_reg(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) {
struct soc_mixer_control *mixcntrl =
(struct soc_mixer_control *)kcontrol->private_value;
unsigned int reg = mixcntrl->reg;
unsigned int shift = mixcntrl->shift;
unsigned int max = mixcntrl->max;
unsigned int invert = mixcntrl->invert;
unsigned int value = ucontrol->value.integer.value[0];
unsigned int reg_value = (unsigned int)
aml_pdm_read(reg);
if (invert)
value = (~value) & mixcntrl->max;
max = ~(max << shift);
reg_value &= max;
reg_value |= (value << shift);
aml_pdm_write(reg, reg_value);
return 0;
}
static const struct snd_kcontrol_new snd_pdm_controls[] = {
/* which set */
SOC_ENUM_EXT("PDM Filter Mode",
@@ -181,13 +140,7 @@ static const struct snd_kcontrol_new snd_pdm_controls[] = {
aml_pdm_filter_mode_get_enum,
aml_pdm_filter_mode_set_enum),
/* hcis gain controls */
SOC_SINGLE_EXT("HCIC shift gain",
PDM_HCIC_CTRL1, 24, 0x3F, 0,
aml_pdm_cntrl_get_reg,
aml_pdm_cntrl_set_reg
),
/* fix HCIC shift gain according current dmic */
SOC_ENUM_EXT("HCIC shift gain from coeff",
pdm_hcic_shift_gain_enum,
pdm_hcic_shift_gain_get_enum,
@@ -455,13 +408,13 @@ EXPORT_SYMBOL_GPL(aml_soc_platform_pdm);
static int aml_pdm_dai_hw_params(
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
struct snd_soc_dai *cpu_dai)
{
return 0;
}
static int aml_pdm_dai_set_fmt(
struct snd_soc_dai *dai, unsigned int fmt)
struct snd_soc_dai *cpu_dai, unsigned int fmt)
{
return 0;
}
@@ -469,9 +422,9 @@ static int aml_pdm_dai_set_fmt(
static int aml_pdm_dai_prepare(
struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
struct snd_soc_dai *cpu_dai)
{
struct aml_pdm *p_pdm = snd_soc_dai_get_drvdata(dai);
struct aml_pdm *p_pdm = snd_soc_dai_get_drvdata(cpu_dai);
struct snd_pcm_runtime *runtime = substream->runtime;
unsigned int bitwidth;
unsigned int toddr_type, lsb;
@@ -536,9 +489,9 @@ static int aml_pdm_dai_prepare(
static int aml_pdm_dai_trigger(
struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai)
struct snd_soc_dai *cpu_dai)
{
struct aml_pdm *p_pdm = snd_soc_dai_get_drvdata(dai);
struct aml_pdm *p_pdm = snd_soc_dai_get_drvdata(cpu_dai);
pr_info("%s\n", __func__);
@@ -589,23 +542,11 @@ static int aml_pdm_dai_set_sysclk(struct snd_soc_dai *cpu_dai,
return 0;
}
static int aml_pdm_dai_set_bclk_ratio(struct snd_soc_dai *cpu_dai,
unsigned int ratio)
{
/* struct aml_pdm *p_pdm = snd_soc_dai_get_drvdata(cpu_dai);
*
* pr_info("%s ratio:%d\n", __func__, ratio);
* aml_pdm_set_bclk_ratio(p_pdm->actrl, ratio);
*/
return 0;
}
static int aml_pdm_dai_probe(struct snd_soc_dai *dai)
static int aml_pdm_dai_probe(struct snd_soc_dai *cpu_dai)
{
int ret = 0;
ret = snd_soc_add_dai_controls(dai, snd_pdm_controls,
ret = snd_soc_add_dai_controls(cpu_dai, snd_pdm_controls,
ARRAY_SIZE(snd_pdm_controls));
if (ret < 0) {
pr_err("%s, failed add snd pdm controls\n", __func__);
@@ -617,13 +558,63 @@ static int aml_pdm_dai_probe(struct snd_soc_dai *dai)
return 0;
}
int aml_pdm_dai_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct aml_pdm *p_pdm = snd_soc_dai_get_drvdata(cpu_dai);
int ret;
if (substream->stream != SNDRV_PCM_STREAM_CAPTURE)
return -EINVAL;
/* enable clock gate */
ret = clk_prepare_enable(p_pdm->clk_gate);
/* enable clock */
ret = clk_prepare_enable(p_pdm->clk_pll);
if (ret) {
pr_err("Can't enable pcm clk_pll clock: %d\n", ret);
goto err;
}
ret = clk_prepare_enable(p_pdm->clk_pdm_sysclk);
if (ret) {
pr_err("Can't enable pcm clk_pdm_sysclk clock: %d\n", ret);
goto err;
}
ret = clk_prepare_enable(p_pdm->clk_pdm_dclk);
if (ret) {
pr_err("Can't enable pcm clk_pdm_dclk clock: %d\n", ret);
goto err;
}
return 0;
err:
pr_err("failed enable clock\n");
return -EINVAL;
}
void aml_pdm_dai_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct aml_pdm *p_pdm = snd_soc_dai_get_drvdata(cpu_dai);
/* disable clock and gate */
clk_disable_unprepare(p_pdm->clk_pdm_dclk);
clk_disable_unprepare(p_pdm->clk_pdm_sysclk);
clk_disable_unprepare(p_pdm->clk_pll);
clk_disable_unprepare(p_pdm->clk_gate);
}
static struct snd_soc_dai_ops aml_pdm_dai_ops = {
.set_fmt = aml_pdm_dai_set_fmt,
.hw_params = aml_pdm_dai_hw_params,
.prepare = aml_pdm_dai_prepare,
.trigger = aml_pdm_dai_trigger,
.set_sysclk = aml_pdm_dai_set_sysclk,
.set_bclk_ratio = aml_pdm_dai_set_bclk_ratio,
.startup = aml_pdm_dai_startup,
.shutdown = aml_pdm_dai_shutdown,
};
struct snd_soc_dai_driver aml_pdm_dai[] = {
@@ -691,7 +682,6 @@ static int aml_pdm_platform_probe(struct platform_device *pdev)
"Can't get pdm gate\n");
return PTR_ERR(p_pdm->clk_gate);
}
clk_prepare_enable(p_pdm->clk_gate);
/* pinmux */
p_pdm->pdm_pins = devm_pinctrl_get_select(&pdev->dev, "pdm_pins");
@@ -750,27 +740,6 @@ static int aml_pdm_platform_probe(struct platform_device *pdev)
goto err;
}
/* enable clock */
ret = clk_prepare_enable(p_pdm->clk_pll);
if (ret) {
dev_err(&pdev->dev,
"Can't enable pcm clk_pll clock: %d\n", ret);
goto err;
}
ret = clk_prepare_enable(p_pdm->clk_pdm_sysclk);
if (ret) {
dev_err(&pdev->dev,
"Can't enable pcm clk_pdm_sysclk clock: %d\n", ret);
goto err;
}
ret = clk_prepare_enable(p_pdm->clk_pdm_dclk);
if (ret) {
dev_err(&pdev->dev,
"Can't enable pcm clk_pdm_dclk clock: %d\n", ret);
goto err;
}
ret = of_property_read_u32(node, "filter_mode",
&p_pdm->filter_mode);

View File

@@ -84,36 +84,6 @@ void aml_pdm_arb_config(struct aml_audio_controller *actrl)
aml_audiobus_write(actrl, EE_AUDIO_ARB_CTRL, 1<<31|0xff<<0);
}
void aml_pdm_set_bclk_ratio(
struct aml_audio_controller *actrl,
int ratio)
{
unsigned int clk_id;
unsigned int mul;
unsigned int sample_count = ratio / 2;
pr_info("%s, ratio:%d, count:%d\n", __func__, ratio, sample_count);
clk_id = 2; /* according to dts, mpll2 */
/* sysclk */
mul = 1;
aml_audiobus_write(actrl, EE_AUDIO_CLK_PDMIN_CTRL1,
1 << 31 | /* clk enable */
clk_id << 24 | /* clk src */
(mul - 1)/* clk_div */
);
/* dclk */
mul = ratio;
aml_audiobus_write(actrl, EE_AUDIO_CLK_PDMIN_CTRL0,
1 << 31 | /* clk enable */
clk_id << 24 | /* clk src */
(mul - 1)); /* clk_div */
}
/* config for hcic, lpf1,2,3, hpf */
static void aml_pdm_filters_config(int osr,
int lpf1_len, int lpf2_len, int lpf3_len)

View File

@@ -25,10 +25,6 @@ extern void aml_pdm_ctrl(
extern void aml_pdm_arb_config(struct aml_audio_controller *actrl);
extern void aml_pdm_set_bclk_ratio(
struct aml_audio_controller *actrl,
int ratio);
extern int aml_pmd_set_HPF_filter_parameters(void *array);
extern void aml_pdm_filter_ctrl(int osr, int set);

View File

@@ -161,6 +161,16 @@ static int aml_spdif_open(struct snd_pcm_substream *substream)
p_spdif->irq_toddr);
return ret;
}
ret = request_irq(p_spdif->irq_spdifin,
aml_spdifin_status_isr, 0, "irq_spdifin",
p_spdif);
if (ret) {
dev_err(p_spdif->dev, "failed to claim irq_spdifin %u\n",
p_spdif->irq_spdifin);
//return ret;
}
}
runtime->private_data = p_spdif;
@@ -182,6 +192,7 @@ static int aml_spdif_close(struct snd_pcm_substream *substream)
} else {
aml_audio_unregister_toddr(p_spdif->dev, p_spdif->to_ddr_num);
free_irq(p_spdif->irq_toddr, substream);
free_irq(p_spdif->irq_spdifin, p_spdif);
}
runtime->private_data = NULL;
@@ -301,74 +312,15 @@ struct snd_soc_platform_driver aml_spdif_platform = {
static int aml_dai_spdif_probe(struct snd_soc_dai *cpu_dai)
{
struct aml_spdif *p_spdif = snd_soc_dai_get_drvdata(cpu_dai);
struct device *dev = p_spdif->dev;
int ret;
/* gate on */
clk_prepare_enable(p_spdif->gate_spdifin);
clk_prepare_enable(p_spdif->gate_spdifout);
ret = clk_set_parent(p_spdif->clk_spdifin, p_spdif->fixed_clk);
if (ret) {
dev_err(dev,
"Can't set clk_spdifin parent clock\n");
ret = PTR_ERR(p_spdif->clk_spdifin);
return ret;
}
clk_set_rate(p_spdif->clk_spdifin, 250000000);
ret = clk_prepare_enable(p_spdif->clk_spdifin);
if (ret) {
dev_err(dev,
"Can't enable pcm clk_spdifin clock: %d\n", ret);
return ret;
}
ret = clk_set_parent(p_spdif->clk_spdifout, p_spdif->sysclk);
if (ret) {
dev_err(dev,
"Can't set clk_spdifout parent clock\n");
ret = PTR_ERR(p_spdif->clk_spdifout);
return ret;
}
/* enable clock */
ret = clk_prepare_enable(p_spdif->clk_spdifout);
if (ret) {
dev_err(dev,
"Can't enable pcm clk_spdifout clock: %d\n", ret);
return ret;
}
ret = request_irq(p_spdif->irq_spdifin,
aml_spdifin_status_isr, 0, "irq_spdifin", p_spdif);
if (ret) {
dev_err(p_spdif->dev, "failed to claim irq_spdifin %u\n",
p_spdif->irq_spdifin);
return ret;
}
pr_info("asoc debug: %s-%d\n", __func__, __LINE__);
return 0;
}
static int aml_dai_spdif_remove(struct snd_soc_dai *cpu_dai)
{
struct aml_spdif *p_spdif = snd_soc_dai_get_drvdata(cpu_dai);
pr_info("asoc debug: %s-%d\n", __func__, __LINE__);
free_irq(p_spdif->irq_spdifin, p_spdif);
free_irq(p_spdif->irq_frddr, p_spdif);
free_irq(p_spdif->irq_toddr, p_spdif);
clk_disable_unprepare(p_spdif->clk_spdifin);
clk_disable_unprepare(p_spdif->clk_spdifout);
clk_disable_unprepare(p_spdif->sysclk);
clk_disable_unprepare(p_spdif->fixed_clk);
clk_disable_unprepare(p_spdif->gate_spdifin);
clk_disable_unprepare(p_spdif->gate_spdifout);
return 0;
}
@@ -377,20 +329,70 @@ static int aml_dai_spdif_startup(
struct snd_soc_dai *cpu_dai)
{
struct aml_spdif *p_spdif = snd_soc_dai_get_drvdata(cpu_dai);
int ret;
pr_info("asoc debug: %s-%d\n", __func__, __LINE__);
aml_spdif_fifo_reset(p_spdif->actrl, substream->stream);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
/* enable clock gate */
ret = clk_prepare_enable(p_spdif->gate_spdifout);
/* enable clock */
ret = clk_prepare_enable(p_spdif->sysclk);
if (ret) {
pr_err("Can't enable pcm sysclk clock: %d\n", ret);
goto err;
}
ret = clk_prepare_enable(p_spdif->clk_spdifout);
if (ret) {
pr_err("Can't enable pcm clk_spdifout clock: %d\n",
ret);
goto err;
}
} else {
/* enable clock gate */
ret = clk_prepare_enable(p_spdif->gate_spdifin);
/* enable clock */
ret = clk_prepare_enable(p_spdif->fixed_clk);
if (ret) {
pr_err("Can't enable pcm fixed_clk clock: %d\n", ret);
goto err;
}
ret = clk_prepare_enable(p_spdif->clk_spdifin);
if (ret) {
pr_err("Can't enable pcm clk_spdifin clock: %d\n", ret);
goto err;
}
}
return 0;
err:
pr_err("failed enable clock\n");
return -EINVAL;
}
static void aml_dai_spdif_shutdown(
struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
struct snd_soc_dai *cpu_dai)
{
struct aml_spdif *p_spdif = snd_soc_dai_get_drvdata(cpu_dai);
/* disable clock and gate */
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
clk_disable_unprepare(p_spdif->clk_spdifout);
clk_disable_unprepare(p_spdif->sysclk);
clk_disable_unprepare(p_spdif->gate_spdifout);
} else {
clk_disable_unprepare(p_spdif->clk_spdifin);
clk_disable_unprepare(p_spdif->fixed_clk);
clk_disable_unprepare(p_spdif->gate_spdifin);
}
}
static int aml_dai_spdif_prepare(
struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
@@ -491,13 +493,19 @@ static int aml_dai_spdif_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *cpu_dai)
{
struct aml_spdif *p_spdif = snd_soc_dai_get_drvdata(cpu_dai);
unsigned int rate = params_rate(params);
int ret = 0;
pr_info("%s\n", __func__);
rate *= 128;
snd_soc_dai_set_sysclk(cpu_dai,
0, rate, SND_SOC_CLOCK_OUT);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
rate *= 128;
snd_soc_dai_set_sysclk(cpu_dai,
0, rate, SND_SOC_CLOCK_OUT);
} else {
clk_set_rate(p_spdif->clk_spdifin, 250000000);
}
return ret;
}
@@ -515,7 +523,8 @@ static void aml_set_spdifclk(struct aml_spdif *p_spdif)
{
unsigned int mpll_freq = 0;
pr_info("asoc debug: %s-%d\n", __func__, __LINE__);
pr_info("asoc debug: %s-%d, sys freq:%d\n", __func__, __LINE__,
p_spdif->sysclk_freq);
if (p_spdif->sysclk_freq) {
unsigned int mul = 4;
@@ -534,6 +543,7 @@ static int aml_dai_set_spdif_sysclk(struct snd_soc_dai *cpu_dai,
p_spdif->sysclk_freq = freq;
pr_info("aml_dai_set_spdif_sysclk, %d, %d, %d\n",
clk_id, freq, dir);
aml_set_spdifclk(p_spdif);
return 0;
@@ -580,6 +590,7 @@ static const struct snd_soc_component_driver aml_spdif_component = {
static int aml_spdif_clks_parse_of(struct aml_spdif *p_spdif)
{
struct device *dev = p_spdif->dev;
int ret = 0;
/* clock gate */
p_spdif->gate_spdifin = devm_clk_get(dev, "gate_spdifin");
@@ -618,6 +629,22 @@ static int aml_spdif_clks_parse_of(struct aml_spdif *p_spdif)
return PTR_ERR(p_spdif->clk_spdifout);
}
ret = clk_set_parent(p_spdif->clk_spdifin, p_spdif->fixed_clk);
if (ret) {
dev_err(dev,
"Can't set clk_spdifin parent clock\n");
ret = PTR_ERR(p_spdif->clk_spdifin);
return ret;
}
ret = clk_set_parent(p_spdif->clk_spdifout, p_spdif->sysclk);
if (ret) {
dev_err(dev,
"Can't set clk_spdifout parent clock\n");
ret = PTR_ERR(p_spdif->clk_spdifout);
return ret;
}
return 0;
}

View File

@@ -332,12 +332,31 @@ struct snd_soc_platform_driver aml_tdm_platform = {
static int aml_dai_tdm_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
return 0;
struct aml_tdm *p_tdm = snd_soc_dai_get_drvdata(cpu_dai);
int ret;
aml_tdm_fifo_reset(p_tdm->actrl, substream->stream, p_tdm->id);
ret = clk_prepare_enable(p_tdm->clk);
if (ret) {
pr_err("Can't enable mpll clock: %d\n", ret);
goto err;
}
return ret;
err:
pr_err("failed enable clock\n");
return ret;
}
static void aml_dai_tdm_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
struct snd_soc_dai *cpu_dai)
{
struct aml_tdm *p_tdm = snd_soc_dai_get_drvdata(cpu_dai);
/* disable clock and gate */
clk_disable_unprepare(p_tdm->clk);
}
static int aml_dai_tdm_prepare(struct snd_pcm_substream *substream,
@@ -731,26 +750,16 @@ static int aml_dai_set_tdm_slot(struct snd_soc_dai *cpu_dai,
static int aml_dai_tdm_probe(struct snd_soc_dai *cpu_dai)
{
struct aml_tdm *p_tdm = snd_soc_dai_get_drvdata(cpu_dai);
struct device *dev = p_tdm->dev;
int ret;
/* config ddr arb */
aml_tdm_arb_config(p_tdm->actrl);
ret = clk_prepare_enable(p_tdm->clk);
if (ret) {
dev_err(dev, "Can't enable mpll clock: %d\n", ret);
return ret;
}
return 0;
}
static int aml_dai_tdm_remove(struct snd_soc_dai *cpu_dai)
{
struct aml_tdm *p_tdm = snd_soc_dai_get_drvdata(cpu_dai);
clk_disable_unprepare(p_tdm->clk);
return 0;
}