Commit 6e7c4443 authored by Adam Thomson's avatar Adam Thomson Committed by Mark Brown

ASoC: da7213: Add support to handle mclk data provided to driver

Driver now can make use of mclk data, if provided, to set, enable
and disable the clock source. As part of this, the choice to
enable clock squaring is dealt with as part of dai_sysclk() call
rather than as platform data.
Signed-off-by: default avatarAdam Thomson <Adam.Thomson.Opensource@diasemi.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent e90996a3
...@@ -44,9 +44,6 @@ struct da7213_platform_data { ...@@ -44,9 +44,6 @@ struct da7213_platform_data {
enum da7213_dmic_data_sel dmic_data_sel; enum da7213_dmic_data_sel dmic_data_sel;
enum da7213_dmic_samplephase dmic_samplephase; enum da7213_dmic_samplephase dmic_samplephase;
enum da7213_dmic_clk_rate dmic_clk_rate; enum da7213_dmic_clk_rate dmic_clk_rate;
/* MCLK squaring config */
bool mclk_squaring;
}; };
#endif /* _DA7213_PDATA_H */ #endif /* _DA7213_PDATA_H */
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
* option) any later version. * option) any later version.
*/ */
#include <linux/clk.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/regmap.h> #include <linux/regmap.h>
...@@ -1222,23 +1223,44 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai, ...@@ -1222,23 +1223,44 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
{ {
struct snd_soc_codec *codec = codec_dai->codec; struct snd_soc_codec *codec = codec_dai->codec;
struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec); struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
int ret = 0;
switch (clk_id) { if ((da7213->clk_src == clk_id) && (da7213->mclk_rate == freq))
case DA7213_CLKSRC_MCLK:
if ((freq == 32768) ||
((freq >= 5000000) && (freq <= 54000000))) {
da7213->mclk_rate = freq;
return 0; return 0;
} else {
if (((freq < 5000000) && (freq != 32768)) || (freq > 54000000)) {
dev_err(codec_dai->dev, "Unsupported MCLK value %d\n", dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",
freq); freq);
return -EINVAL; return -EINVAL;
} }
switch (clk_id) {
case DA7213_CLKSRC_MCLK:
da7213->mclk_squarer_en = false;
break;
case DA7213_CLKSRC_MCLK_SQR:
da7213->mclk_squarer_en = true;
break; break;
default: default:
dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id); dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id);
return -EINVAL; return -EINVAL;
} }
da7213->clk_src = clk_id;
if (da7213->mclk) {
freq = clk_round_rate(da7213->mclk, freq);
ret = clk_set_rate(da7213->mclk, freq);
if (ret) {
dev_err(codec_dai->dev, "Failed to set clock rate %d\n",
freq);
return ret;
}
}
da7213->mclk_rate = freq;
return 0;
} }
/* Supported PLL input frequencies are 5MHz - 54MHz. */ /* Supported PLL input frequencies are 5MHz - 54MHz. */
...@@ -1366,12 +1388,25 @@ static struct snd_soc_dai_driver da7213_dai = { ...@@ -1366,12 +1388,25 @@ static struct snd_soc_dai_driver da7213_dai = {
static int da7213_set_bias_level(struct snd_soc_codec *codec, static int da7213_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level) enum snd_soc_bias_level level)
{ {
struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
int ret;
switch (level) { switch (level) {
case SND_SOC_BIAS_ON: case SND_SOC_BIAS_ON:
case SND_SOC_BIAS_PREPARE: case SND_SOC_BIAS_PREPARE:
break; break;
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
/* MCLK */
if (da7213->mclk) {
ret = clk_prepare_enable(da7213->mclk);
if (ret) {
dev_err(codec->dev,
"Failed to enable mclk\n");
return ret;
}
}
/* Enable VMID reference & master bias */ /* Enable VMID reference & master bias */
snd_soc_update_bits(codec, DA7213_REFERENCES, snd_soc_update_bits(codec, DA7213_REFERENCES,
DA7213_VMID_EN | DA7213_BIAS_EN, DA7213_VMID_EN | DA7213_BIAS_EN,
...@@ -1382,6 +1417,10 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec, ...@@ -1382,6 +1417,10 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec,
/* Disable VMID reference & master bias */ /* Disable VMID reference & master bias */
snd_soc_update_bits(codec, DA7213_REFERENCES, snd_soc_update_bits(codec, DA7213_REFERENCES,
DA7213_VMID_EN | DA7213_BIAS_EN, 0); DA7213_VMID_EN | DA7213_BIAS_EN, 0);
/* MCLK */
if (da7213->mclk)
clk_disable_unprepare(da7213->mclk);
break; break;
} }
return 0; return 0;
...@@ -1618,9 +1657,15 @@ static int da7213_probe(struct snd_soc_codec *codec) ...@@ -1618,9 +1657,15 @@ static int da7213_probe(struct snd_soc_codec *codec)
DA7213_DMIC_DATA_SEL_MASK | DA7213_DMIC_DATA_SEL_MASK |
DA7213_DMIC_SAMPLEPHASE_MASK | DA7213_DMIC_SAMPLEPHASE_MASK |
DA7213_DMIC_CLK_RATE_MASK, dmic_cfg); DA7213_DMIC_CLK_RATE_MASK, dmic_cfg);
}
/* Set MCLK squaring */ /* Check if MCLK provided */
da7213->mclk_squarer_en = pdata->mclk_squaring; da7213->mclk = devm_clk_get(codec->dev, "mclk");
if (IS_ERR(da7213->mclk)) {
if (PTR_ERR(da7213->mclk) != -ENOENT)
return PTR_ERR(da7213->mclk);
else
da7213->mclk = NULL;
} }
return 0; return 0;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#ifndef _DA7213_H #ifndef _DA7213_H
#define _DA7213_H #define _DA7213_H
#include <linux/clk.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <sound/da7213.h> #include <sound/da7213.h>
...@@ -504,14 +505,17 @@ ...@@ -504,14 +505,17 @@
#define DA7213_PLL_INDIV_20_40_MHZ_VAL 8 #define DA7213_PLL_INDIV_20_40_MHZ_VAL 8
#define DA7213_PLL_INDIV_40_54_MHZ_VAL 16 #define DA7213_PLL_INDIV_40_54_MHZ_VAL 16
enum clk_src { enum da7213_clk_src {
DA7213_CLKSRC_MCLK DA7213_CLKSRC_MCLK = 0,
DA7213_CLKSRC_MCLK_SQR,
}; };
/* Codec private data */ /* Codec private data */
struct da7213_priv { struct da7213_priv {
struct regmap *regmap; struct regmap *regmap;
struct clk *mclk;
unsigned int mclk_rate; unsigned int mclk_rate;
int clk_src;
bool master; bool master;
bool mclk_squarer_en; bool mclk_squarer_en;
bool srm_en; bool srm_en;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment