2020-05-11 13:27:42

by Sebastian Reichel

[permalink] [raw]
Subject: [PATCHv3 5/5] ASoC: da7213: add default clock handling

This adds default clock/PLL configuration to the driver
for usage with generic drivers like simple-card for usage
with a fixed rate clock.

Signed-off-by: Sebastian Reichel <[email protected]>
---
sound/soc/codecs/da7213.c | 76 ++++++++++++++++++++++++++++++++++++---
sound/soc/codecs/da7213.h | 2 ++
2 files changed, 73 insertions(+), 5 deletions(-)

diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c
index 3e6ad996741b..4a0edd3b7f83 100644
--- a/sound/soc/codecs/da7213.c
+++ b/sound/soc/codecs/da7213.c
@@ -1156,6 +1156,7 @@ static int da7213_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_component *component = dai->component;
+ struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
u8 dai_ctrl = 0;
u8 fs;

@@ -1181,33 +1182,43 @@ static int da7213_hw_params(struct snd_pcm_substream *substream,
switch (params_rate(params)) {
case 8000:
fs = DA7213_SR_8000;
+ da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
break;
case 11025:
fs = DA7213_SR_11025;
+ da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800;
break;
case 12000:
fs = DA7213_SR_12000;
+ da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
break;
case 16000:
fs = DA7213_SR_16000;
+ da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
break;
case 22050:
fs = DA7213_SR_22050;
+ da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800;
break;
case 32000:
fs = DA7213_SR_32000;
+ da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
break;
case 44100:
fs = DA7213_SR_44100;
+ da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800;
break;
case 48000:
fs = DA7213_SR_48000;
+ da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
break;
case 88200:
fs = DA7213_SR_88200;
+ da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800;
break;
case 96000:
fs = DA7213_SR_96000;
+ da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
break;
default:
return -EINVAL;
@@ -1392,9 +1403,9 @@ static int da7213_set_component_sysclk(struct snd_soc_component *component,
}

/* Supported PLL input frequencies are 32KHz, 5MHz - 54MHz. */
-static int da7213_set_component_pll(struct snd_soc_component *component,
- int pll_id, int source,
- unsigned int fref, unsigned int fout)
+static int _da7213_set_component_pll(struct snd_soc_component *component,
+ int pll_id, int source,
+ unsigned int fref, unsigned int fout)
{
struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);

@@ -1503,6 +1514,16 @@ static int da7213_set_component_pll(struct snd_soc_component *component,
return 0;
}

+static int da7213_set_component_pll(struct snd_soc_component *component,
+ int pll_id, int source,
+ unsigned int fref, unsigned int fout)
+{
+ struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
+ da7213->fixed_clk_auto_pll = false;
+
+ return _da7213_set_component_pll(component, pll_id, source, fref, fout);
+}
+
/* DAI operations */
static const struct snd_soc_dai_ops da7213_dai_ops = {
.hw_params = da7213_hw_params,
@@ -1532,6 +1553,43 @@ static struct snd_soc_dai_driver da7213_dai = {
.symmetric_rates = 1,
};

+static int da7213_set_auto_pll(struct snd_soc_component *component, bool enable)
+{
+ struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
+ int mode;
+
+ if (!da7213->fixed_clk_auto_pll)
+ return 0;
+
+ da7213->mclk_rate = clk_get_rate(da7213->mclk);
+
+ if (enable)
+ mode = DA7213_SYSCLK_PLL;
+ else
+ mode = DA7213_SYSCLK_MCLK;
+
+ switch (da7213->out_rate) {
+ case DA7213_PLL_FREQ_OUT_90316800:
+ if (da7213->mclk_rate == 11289600 ||
+ da7213->mclk_rate == 22579200 ||
+ da7213->mclk_rate == 45158400)
+ mode = DA7213_SYSCLK_MCLK;
+ break;
+ case DA7213_PLL_FREQ_OUT_98304000:
+ if (da7213->mclk_rate == 12288000 ||
+ da7213->mclk_rate == 24576000 ||
+ da7213->mclk_rate == 49152000)
+ mode = DA7213_SYSCLK_MCLK;
+
+ break;
+ default:
+ return -1;
+ }
+
+ return _da7213_set_component_pll(component, 0, mode,
+ da7213->mclk_rate, da7213->out_rate);
+}
+
static int da7213_set_bias_level(struct snd_soc_component *component,
enum snd_soc_bias_level level)
{
@@ -1551,6 +1609,8 @@ static int da7213_set_bias_level(struct snd_soc_component *component,
"Failed to enable mclk\n");
return ret;
}
+
+ da7213_set_auto_pll(component, true);
}
}
break;
@@ -1562,8 +1622,10 @@ static int da7213_set_bias_level(struct snd_soc_component *component,
DA7213_VMID_EN | DA7213_BIAS_EN);
} else {
/* Remove MCLK */
- if (da7213->mclk)
+ if (da7213->mclk) {
+ da7213_set_auto_pll(component, false);
clk_disable_unprepare(da7213->mclk);
+ }
}
break;
case SND_SOC_BIAS_OFF:
@@ -1693,7 +1755,6 @@ static struct da7213_platform_data
return pdata;
}

-
static int da7213_probe(struct snd_soc_component *component)
{
struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
@@ -1829,6 +1890,11 @@ static int da7213_probe(struct snd_soc_component *component)
return PTR_ERR(da7213->mclk);
else
da7213->mclk = NULL;
+ } else {
+ /* Do automatic PLL handling assuming fixed clock until
+ * set_pll() has been called. This makes the codec usable
+ * with the simple-audio-card driver. */
+ da7213->fixed_clk_auto_pll = true;
}

return 0;
diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h
index 3890829dfb6e..97ccf0ddd2be 100644
--- a/sound/soc/codecs/da7213.h
+++ b/sound/soc/codecs/da7213.h
@@ -535,10 +535,12 @@ struct da7213_priv {
struct regulator_bulk_data supplies[DA7213_NUM_SUPPLIES];
struct clk *mclk;
unsigned int mclk_rate;
+ unsigned int out_rate;
int clk_src;
bool master;
bool alc_calib_auto;
bool alc_en;
+ bool fixed_clk_auto_pll;
struct da7213_platform_data *pdata;
};

--
2.26.2


2020-05-18 11:22:39

by Adam Thomson

[permalink] [raw]
Subject: RE: [PATCHv3 5/5] ASoC: da7213: add default clock handling

On 11 May 2020 14:26, Sebastian Reichel wrote:

> This adds default clock/PLL configuration to the driver
> for usage with generic drivers like simple-card for usage
> with a fixed rate clock.
>
> Signed-off-by: Sebastian Reichel <[email protected]>
> ---
> sound/soc/codecs/da7213.c | 76
> ++++++++++++++++++++++++++++++++++++---
> sound/soc/codecs/da7213.h | 2 ++
> 2 files changed, 73 insertions(+), 5 deletions(-)
>
> diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c
> index 3e6ad996741b..4a0edd3b7f83 100644
> --- a/sound/soc/codecs/da7213.c
> +++ b/sound/soc/codecs/da7213.c
> @@ -1156,6 +1156,7 @@ static int da7213_hw_params(struct
> snd_pcm_substream *substream,
> struct snd_soc_dai *dai)
> {
> struct snd_soc_component *component = dai->component;
> + struct da7213_priv *da7213 =
> snd_soc_component_get_drvdata(component);
> u8 dai_ctrl = 0;
> u8 fs;
>
> @@ -1181,33 +1182,43 @@ static int da7213_hw_params(struct
> snd_pcm_substream *substream,
> switch (params_rate(params)) {
> case 8000:
> fs = DA7213_SR_8000;
> + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
> break;
> case 11025:
> fs = DA7213_SR_11025;
> + da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800;
> break;
> case 12000:
> fs = DA7213_SR_12000;
> + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
> break;
> case 16000:
> fs = DA7213_SR_16000;
> + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
> break;
> case 22050:
> fs = DA7213_SR_22050;
> + da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800;
> break;
> case 32000:
> fs = DA7213_SR_32000;
> + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
> break;
> case 44100:
> fs = DA7213_SR_44100;
> + da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800;
> break;
> case 48000:
> fs = DA7213_SR_48000;
> + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
> break;
> case 88200:
> fs = DA7213_SR_88200;
> + da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800;
> break;
> case 96000:
> fs = DA7213_SR_96000;
> + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
> break;
> default:
> return -EINVAL;
> @@ -1392,9 +1403,9 @@ static int da7213_set_component_sysclk(struct
> snd_soc_component *component,
> }
>
> /* Supported PLL input frequencies are 32KHz, 5MHz - 54MHz. */
> -static int da7213_set_component_pll(struct snd_soc_component *component,
> - int pll_id, int source,
> - unsigned int fref, unsigned int fout)
> +static int _da7213_set_component_pll(struct snd_soc_component
> *component,
> + int pll_id, int source,
> + unsigned int fref, unsigned int fout)
> {
> struct da7213_priv *da7213 =
> snd_soc_component_get_drvdata(component);
>
> @@ -1503,6 +1514,16 @@ static int da7213_set_component_pll(struct
> snd_soc_component *component,
> return 0;
> }
>
> +static int da7213_set_component_pll(struct snd_soc_component *component,
> + int pll_id, int source,
> + unsigned int fref, unsigned int fout)
> +{
> + struct da7213_priv *da7213 =
> snd_soc_component_get_drvdata(component);
> + da7213->fixed_clk_auto_pll = false;
> +
> + return _da7213_set_component_pll(component, pll_id, source, fref,
> fout);
> +}
> +
> /* DAI operations */
> static const struct snd_soc_dai_ops da7213_dai_ops = {
> .hw_params = da7213_hw_params,
> @@ -1532,6 +1553,43 @@ static struct snd_soc_dai_driver da7213_dai = {
> .symmetric_rates = 1,
> };
>
> +static int da7213_set_auto_pll(struct snd_soc_component *component, bool
> enable)
> +{
> + struct da7213_priv *da7213 =
> snd_soc_component_get_drvdata(component);
> + int mode;
> +
> + if (!da7213->fixed_clk_auto_pll)
> + return 0;
> +
> + da7213->mclk_rate = clk_get_rate(da7213->mclk);
> +
> + if (enable)
> + mode = DA7213_SYSCLK_PLL;
> + else
> + mode = DA7213_SYSCLK_MCLK;
> +

We still need to address the handling of the PLL when the codec is slave, and
the MCLK rate is not harmonic. In that scenario we need to use the SRM feature
of the PLL to synchronise the PLL with the incoming WCLK signal on the DAI.
Right now your code will allow for slave mode where the PLL is enabled without
SRM, regardless of whether we're acting as slave or not. Either we just don't
allow for slave mode with non-harmonic frequencies or we add a bit more in this
function to determine if SRM is required which shouldn't be much more code.

> + switch (da7213->out_rate) {
> + case DA7213_PLL_FREQ_OUT_90316800:
> + if (da7213->mclk_rate == 11289600 ||
> + da7213->mclk_rate == 22579200 ||
> + da7213->mclk_rate == 45158400)
> + mode = DA7213_SYSCLK_MCLK;
> + break;
> + case DA7213_PLL_FREQ_OUT_98304000:
> + if (da7213->mclk_rate == 12288000 ||
> + da7213->mclk_rate == 24576000 ||
> + da7213->mclk_rate == 49152000)
> + mode = DA7213_SYSCLK_MCLK;
> +
> + break;
> + default:
> + return -1;
> + }
> +
> + return _da7213_set_component_pll(component, 0, mode,
> + da7213->mclk_rate, da7213->out_rate);
> +}
> +
> static int da7213_set_bias_level(struct snd_soc_component *component,
> enum snd_soc_bias_level level)
> {
> @@ -1551,6 +1609,8 @@ static int da7213_set_bias_level(struct
> snd_soc_component *component,
> "Failed to enable mclk\n");
> return ret;
> }
> +
> + da7213_set_auto_pll(component, true);
> }
> }
> break;
> @@ -1562,8 +1622,10 @@ static int da7213_set_bias_level(struct
> snd_soc_component *component,
> DA7213_VMID_EN | DA7213_BIAS_EN);
> } else {
> /* Remove MCLK */
> - if (da7213->mclk)
> + if (da7213->mclk) {
> + da7213_set_auto_pll(component, false);
> clk_disable_unprepare(da7213->mclk);
> + }
> }
> break;
> case SND_SOC_BIAS_OFF:
> @@ -1693,7 +1755,6 @@ static struct da7213_platform_data
> return pdata;
> }
>
> -
> static int da7213_probe(struct snd_soc_component *component)
> {
> struct da7213_priv *da7213 =
> snd_soc_component_get_drvdata(component);
> @@ -1829,6 +1890,11 @@ static int da7213_probe(struct snd_soc_component
> *component)
> return PTR_ERR(da7213->mclk);
> else
> da7213->mclk = NULL;
> + } else {
> + /* Do automatic PLL handling assuming fixed clock until
> + * set_pll() has been called. This makes the codec usable
> + * with the simple-audio-card driver. */
> + da7213->fixed_clk_auto_pll = true;
> }
>
> return 0;
> diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h
> index 3890829dfb6e..97ccf0ddd2be 100644
> --- a/sound/soc/codecs/da7213.h
> +++ b/sound/soc/codecs/da7213.h
> @@ -535,10 +535,12 @@ struct da7213_priv {
> struct regulator_bulk_data supplies[DA7213_NUM_SUPPLIES];
> struct clk *mclk;
> unsigned int mclk_rate;
> + unsigned int out_rate;
> int clk_src;
> bool master;
> bool alc_calib_auto;
> bool alc_en;
> + bool fixed_clk_auto_pll;
> struct da7213_platform_data *pdata;
> };
>
> --
> 2.26.2

2020-06-26 17:21:51

by Sebastian Reichel

[permalink] [raw]
Subject: [PATCHv4] ASoC: da7213: add default clock handling

This adds default clock/PLL configuration to the driver
for usage with generic drivers like simple-card for usage
with a fixed rate clock.

Signed-off-by: Sebastian Reichel <[email protected]>
---
Changes since PATCHv3:
* rebase to v5.8-rc1
* add SRM support for usage in slave mode with simple-card.
I only tested with master mode, though.
---
sound/soc/codecs/da7213.c | 83 ++++++++++++++++++++++++++++++++++++---
sound/soc/codecs/da7213.h | 2 +
2 files changed, 80 insertions(+), 5 deletions(-)

diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c
index 3e6ad996741b..1a4fece20bcd 100644
--- a/sound/soc/codecs/da7213.c
+++ b/sound/soc/codecs/da7213.c
@@ -1156,6 +1156,7 @@ static int da7213_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_component *component = dai->component;
+ struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
u8 dai_ctrl = 0;
u8 fs;

@@ -1181,33 +1182,43 @@ static int da7213_hw_params(struct snd_pcm_substream *substream,
switch (params_rate(params)) {
case 8000:
fs = DA7213_SR_8000;
+ da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
break;
case 11025:
fs = DA7213_SR_11025;
+ da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800;
break;
case 12000:
fs = DA7213_SR_12000;
+ da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
break;
case 16000:
fs = DA7213_SR_16000;
+ da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
break;
case 22050:
fs = DA7213_SR_22050;
+ da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800;
break;
case 32000:
fs = DA7213_SR_32000;
+ da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
break;
case 44100:
fs = DA7213_SR_44100;
+ da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800;
break;
case 48000:
fs = DA7213_SR_48000;
+ da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
break;
case 88200:
fs = DA7213_SR_88200;
+ da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800;
break;
case 96000:
fs = DA7213_SR_96000;
+ da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
break;
default:
return -EINVAL;
@@ -1392,9 +1403,9 @@ static int da7213_set_component_sysclk(struct snd_soc_component *component,
}

/* Supported PLL input frequencies are 32KHz, 5MHz - 54MHz. */
-static int da7213_set_component_pll(struct snd_soc_component *component,
- int pll_id, int source,
- unsigned int fref, unsigned int fout)
+static int _da7213_set_component_pll(struct snd_soc_component *component,
+ int pll_id, int source,
+ unsigned int fref, unsigned int fout)
{
struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);

@@ -1503,6 +1514,16 @@ static int da7213_set_component_pll(struct snd_soc_component *component,
return 0;
}

+static int da7213_set_component_pll(struct snd_soc_component *component,
+ int pll_id, int source,
+ unsigned int fref, unsigned int fout)
+{
+ struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
+ da7213->fixed_clk_auto_pll = false;
+
+ return _da7213_set_component_pll(component, pll_id, source, fref, fout);
+}
+
/* DAI operations */
static const struct snd_soc_dai_ops da7213_dai_ops = {
.hw_params = da7213_hw_params,
@@ -1532,6 +1553,50 @@ static struct snd_soc_dai_driver da7213_dai = {
.symmetric_rates = 1,
};

+static int da7213_set_auto_pll(struct snd_soc_component *component, bool enable)
+{
+ struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
+ int mode;
+
+ if (!da7213->fixed_clk_auto_pll)
+ return 0;
+
+ da7213->mclk_rate = clk_get_rate(da7213->mclk);
+
+ if (enable) {
+ /* Slave mode needs SRM for non-harmonic frequencies */
+ if (da7213->master)
+ mode = DA7213_SYSCLK_PLL;
+ else
+ mode = DA7213_SYSCLK_PLL_SRM;
+
+ /* PLL is not required for harmonic frequencies */
+ switch (da7213->out_rate) {
+ case DA7213_PLL_FREQ_OUT_90316800:
+ if (da7213->mclk_rate == 11289600 ||
+ da7213->mclk_rate == 22579200 ||
+ da7213->mclk_rate == 45158400)
+ mode = DA7213_SYSCLK_MCLK;
+ break;
+ case DA7213_PLL_FREQ_OUT_98304000:
+ if (da7213->mclk_rate == 12288000 ||
+ da7213->mclk_rate == 24576000 ||
+ da7213->mclk_rate == 49152000)
+ mode = DA7213_SYSCLK_MCLK;
+
+ break;
+ default:
+ return -1;
+ }
+ } else {
+ /* Disable PLL in standby */
+ mode = DA7213_SYSCLK_MCLK;
+ }
+
+ return _da7213_set_component_pll(component, 0, mode,
+ da7213->mclk_rate, da7213->out_rate);
+}
+
static int da7213_set_bias_level(struct snd_soc_component *component,
enum snd_soc_bias_level level)
{
@@ -1551,6 +1616,8 @@ static int da7213_set_bias_level(struct snd_soc_component *component,
"Failed to enable mclk\n");
return ret;
}
+
+ da7213_set_auto_pll(component, true);
}
}
break;
@@ -1562,8 +1629,10 @@ static int da7213_set_bias_level(struct snd_soc_component *component,
DA7213_VMID_EN | DA7213_BIAS_EN);
} else {
/* Remove MCLK */
- if (da7213->mclk)
+ if (da7213->mclk) {
+ da7213_set_auto_pll(component, false);
clk_disable_unprepare(da7213->mclk);
+ }
}
break;
case SND_SOC_BIAS_OFF:
@@ -1693,7 +1762,6 @@ static struct da7213_platform_data
return pdata;
}

-
static int da7213_probe(struct snd_soc_component *component)
{
struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
@@ -1829,6 +1897,11 @@ static int da7213_probe(struct snd_soc_component *component)
return PTR_ERR(da7213->mclk);
else
da7213->mclk = NULL;
+ } else {
+ /* Do automatic PLL handling assuming fixed clock until
+ * set_pll() has been called. This makes the codec usable
+ * with the simple-audio-card driver. */
+ da7213->fixed_clk_auto_pll = true;
}

return 0;
diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h
index 3890829dfb6e..97ccf0ddd2be 100644
--- a/sound/soc/codecs/da7213.h
+++ b/sound/soc/codecs/da7213.h
@@ -535,10 +535,12 @@ struct da7213_priv {
struct regulator_bulk_data supplies[DA7213_NUM_SUPPLIES];
struct clk *mclk;
unsigned int mclk_rate;
+ unsigned int out_rate;
int clk_src;
bool master;
bool alc_calib_auto;
bool alc_en;
+ bool fixed_clk_auto_pll;
struct da7213_platform_data *pdata;
};

--
2.27.0

2020-07-03 09:45:10

by Adam Thomson

[permalink] [raw]
Subject: RE: [PATCHv4] ASoC: da7213: add default clock handling

On 26 June 2020 17:46, Sebastian Reichel wrote:

> This adds default clock/PLL configuration to the driver
> for usage with generic drivers like simple-card for usage
> with a fixed rate clock.
>
> Signed-off-by: Sebastian Reichel <[email protected]>

Looks good. Thanks for the work here.

Reviewed-by: Adam Thomson <[email protected]>

> ---
> Changes since PATCHv3:
> * rebase to v5.8-rc1
> * add SRM support for usage in slave mode with simple-card.
> I only tested with master mode, though.
> ---
> sound/soc/codecs/da7213.c | 83
> ++++++++++++++++++++++++++++++++++++---
> sound/soc/codecs/da7213.h | 2 +
> 2 files changed, 80 insertions(+), 5 deletions(-)
>
> diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c
> index 3e6ad996741b..1a4fece20bcd 100644
> --- a/sound/soc/codecs/da7213.c
> +++ b/sound/soc/codecs/da7213.c
> @@ -1156,6 +1156,7 @@ static int da7213_hw_params(struct
> snd_pcm_substream *substream,
> struct snd_soc_dai *dai)
> {
> struct snd_soc_component *component = dai->component;
> + struct da7213_priv *da7213 =
> snd_soc_component_get_drvdata(component);
> u8 dai_ctrl = 0;
> u8 fs;
>
> @@ -1181,33 +1182,43 @@ static int da7213_hw_params(struct
> snd_pcm_substream *substream,
> switch (params_rate(params)) {
> case 8000:
> fs = DA7213_SR_8000;
> + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
> break;
> case 11025:
> fs = DA7213_SR_11025;
> + da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800;
> break;
> case 12000:
> fs = DA7213_SR_12000;
> + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
> break;
> case 16000:
> fs = DA7213_SR_16000;
> + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
> break;
> case 22050:
> fs = DA7213_SR_22050;
> + da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800;
> break;
> case 32000:
> fs = DA7213_SR_32000;
> + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
> break;
> case 44100:
> fs = DA7213_SR_44100;
> + da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800;
> break;
> case 48000:
> fs = DA7213_SR_48000;
> + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
> break;
> case 88200:
> fs = DA7213_SR_88200;
> + da7213->out_rate = DA7213_PLL_FREQ_OUT_90316800;
> break;
> case 96000:
> fs = DA7213_SR_96000;
> + da7213->out_rate = DA7213_PLL_FREQ_OUT_98304000;
> break;
> default:
> return -EINVAL;
> @@ -1392,9 +1403,9 @@ static int da7213_set_component_sysclk(struct
> snd_soc_component *component,
> }
>
> /* Supported PLL input frequencies are 32KHz, 5MHz - 54MHz. */
> -static int da7213_set_component_pll(struct snd_soc_component *component,
> - int pll_id, int source,
> - unsigned int fref, unsigned int fout)
> +static int _da7213_set_component_pll(struct snd_soc_component
> *component,
> + int pll_id, int source,
> + unsigned int fref, unsigned int fout)
> {
> struct da7213_priv *da7213 =
> snd_soc_component_get_drvdata(component);
>
> @@ -1503,6 +1514,16 @@ static int da7213_set_component_pll(struct
> snd_soc_component *component,
> return 0;
> }
>
> +static int da7213_set_component_pll(struct snd_soc_component *component,
> + int pll_id, int source,
> + unsigned int fref, unsigned int fout)
> +{
> + struct da7213_priv *da7213 =
> snd_soc_component_get_drvdata(component);
> + da7213->fixed_clk_auto_pll = false;
> +
> + return _da7213_set_component_pll(component, pll_id, source, fref,
> fout);
> +}
> +
> /* DAI operations */
> static const struct snd_soc_dai_ops da7213_dai_ops = {
> .hw_params = da7213_hw_params,
> @@ -1532,6 +1553,50 @@ static struct snd_soc_dai_driver da7213_dai = {
> .symmetric_rates = 1,
> };
>
> +static int da7213_set_auto_pll(struct snd_soc_component *component, bool
> enable)
> +{
> + struct da7213_priv *da7213 =
> snd_soc_component_get_drvdata(component);
> + int mode;
> +
> + if (!da7213->fixed_clk_auto_pll)
> + return 0;
> +
> + da7213->mclk_rate = clk_get_rate(da7213->mclk);
> +
> + if (enable) {
> + /* Slave mode needs SRM for non-harmonic frequencies */
> + if (da7213->master)
> + mode = DA7213_SYSCLK_PLL;
> + else
> + mode = DA7213_SYSCLK_PLL_SRM;
> +
> + /* PLL is not required for harmonic frequencies */
> + switch (da7213->out_rate) {
> + case DA7213_PLL_FREQ_OUT_90316800:
> + if (da7213->mclk_rate == 11289600 ||
> + da7213->mclk_rate == 22579200 ||
> + da7213->mclk_rate == 45158400)
> + mode = DA7213_SYSCLK_MCLK;
> + break;
> + case DA7213_PLL_FREQ_OUT_98304000:
> + if (da7213->mclk_rate == 12288000 ||
> + da7213->mclk_rate == 24576000 ||
> + da7213->mclk_rate == 49152000)
> + mode = DA7213_SYSCLK_MCLK;
> +
> + break;
> + default:
> + return -1;
> + }
> + } else {
> + /* Disable PLL in standby */
> + mode = DA7213_SYSCLK_MCLK;
> + }
> +
> + return _da7213_set_component_pll(component, 0, mode,
> + da7213->mclk_rate, da7213->out_rate);
> +}
> +
> static int da7213_set_bias_level(struct snd_soc_component *component,
> enum snd_soc_bias_level level)
> {
> @@ -1551,6 +1616,8 @@ static int da7213_set_bias_level(struct
> snd_soc_component *component,
> "Failed to enable mclk\n");
> return ret;
> }
> +
> + da7213_set_auto_pll(component, true);
> }
> }
> break;
> @@ -1562,8 +1629,10 @@ static int da7213_set_bias_level(struct
> snd_soc_component *component,
> DA7213_VMID_EN | DA7213_BIAS_EN);
> } else {
> /* Remove MCLK */
> - if (da7213->mclk)
> + if (da7213->mclk) {
> + da7213_set_auto_pll(component, false);
> clk_disable_unprepare(da7213->mclk);
> + }
> }
> break;
> case SND_SOC_BIAS_OFF:
> @@ -1693,7 +1762,6 @@ static struct da7213_platform_data
> return pdata;
> }
>
> -
> static int da7213_probe(struct snd_soc_component *component)
> {
> struct da7213_priv *da7213 =
> snd_soc_component_get_drvdata(component);
> @@ -1829,6 +1897,11 @@ static int da7213_probe(struct snd_soc_component
> *component)
> return PTR_ERR(da7213->mclk);
> else
> da7213->mclk = NULL;
> + } else {
> + /* Do automatic PLL handling assuming fixed clock until
> + * set_pll() has been called. This makes the codec usable
> + * with the simple-audio-card driver. */
> + da7213->fixed_clk_auto_pll = true;
> }
>
> return 0;
> diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h
> index 3890829dfb6e..97ccf0ddd2be 100644
> --- a/sound/soc/codecs/da7213.h
> +++ b/sound/soc/codecs/da7213.h
> @@ -535,10 +535,12 @@ struct da7213_priv {
> struct regulator_bulk_data supplies[DA7213_NUM_SUPPLIES];
> struct clk *mclk;
> unsigned int mclk_rate;
> + unsigned int out_rate;
> int clk_src;
> bool master;
> bool alc_calib_auto;
> bool alc_en;
> + bool fixed_clk_auto_pll;
> struct da7213_platform_data *pdata;
> };
>
> --
> 2.27.0

2020-07-07 14:17:47

by Mark Brown

[permalink] [raw]
Subject: Re: [PATCHv4] ASoC: da7213: add default clock handling

On Fri, 26 Jun 2020 18:46:23 +0200, Sebastian Reichel wrote:
> This adds default clock/PLL configuration to the driver
> for usage with generic drivers like simple-card for usage
> with a fixed rate clock.

Applied to

https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/1] ASoC: da7213: add default clock handling
commit: 5146b6a92c1194674f21def93d7025c97ed6977f

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark