mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 20:32:04 +09:00
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:
@@ -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>;
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user