diff --git a/arch/arm64/boot/dts/amlogic/axg_s400.dts b/arch/arm64/boot/dts/amlogic/axg_s400.dts index 298bbc4615e7..4da307309380 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s400.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s400.dts @@ -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>; diff --git a/arch/arm64/boot/dts/amlogic/axg_s420.dts b/arch/arm64/boot/dts/amlogic/axg_s420.dts index 710c2c4b757c..1202dd24fb28 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s420.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s420.dts @@ -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>; diff --git a/sound/soc/amlogic/auge/card.c b/sound/soc/amlogic/auge/card.c index 5ec2464a4df2..81655746747b 100644 --- a/sound/soc/amlogic/auge/card.c +++ b/sound/soc/amlogic/auge/card.c @@ -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) diff --git a/sound/soc/amlogic/auge/iomap.c b/sound/soc/amlogic/auge/iomap.c index a457ba428f02..28762007f15e 100644 --- a/sound/soc/amlogic/auge/iomap.c +++ b/sound/soc/amlogic/auge/iomap.c @@ -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; diff --git a/sound/soc/amlogic/auge/iomap.h b/sound/soc/amlogic/auge/iomap.h index 4d5bdd7b3832..4137a4715eff 100644 --- a/sound/soc/amlogic/auge/iomap.h +++ b/sound/soc/amlogic/auge/iomap.h @@ -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 diff --git a/sound/soc/amlogic/auge/pdm.c b/sound/soc/amlogic/auge/pdm.c index 5ecbcc111647..20b244e8beee 100644 --- a/sound/soc/amlogic/auge/pdm.c +++ b/sound/soc/amlogic/auge/pdm.c @@ -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); diff --git a/sound/soc/amlogic/auge/pdm_hw.c b/sound/soc/amlogic/auge/pdm_hw.c index 9c903c5544e4..52463ef24298 100644 --- a/sound/soc/amlogic/auge/pdm_hw.c +++ b/sound/soc/amlogic/auge/pdm_hw.c @@ -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) diff --git a/sound/soc/amlogic/auge/pdm_hw.h b/sound/soc/amlogic/auge/pdm_hw.h index 5f4a9d69d45c..7fc7333c8537 100644 --- a/sound/soc/amlogic/auge/pdm_hw.h +++ b/sound/soc/amlogic/auge/pdm_hw.h @@ -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); diff --git a/sound/soc/amlogic/auge/spdif.c b/sound/soc/amlogic/auge/spdif.c index 4d6f4b3b37a8..ad6d68c60088 100644 --- a/sound/soc/amlogic/auge/spdif.c +++ b/sound/soc/amlogic/auge/spdif.c @@ -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; } diff --git a/sound/soc/amlogic/auge/tdm.c b/sound/soc/amlogic/auge/tdm.c index 6ba4b42216f1..0e0886d6010a 100644 --- a/sound/soc/amlogic/auge/tdm.c +++ b/sound/soc/amlogic/auge/tdm.c @@ -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; }