Commit acf6470a authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'asoc/topic/cs35l30', 'asoc/topic/cs42l73',...

Merge remote-tracking branches 'asoc/topic/cs35l30', 'asoc/topic/cs42l73', 'asoc/topic/cs53l30' and 'asoc/topic/da7213' into asoc-next
......@@ -794,7 +794,7 @@ struct cs42l73_mclk_div {
u8 mmcc;
};
static struct cs42l73_mclk_div cs42l73_mclk_coeffs[] = {
static const struct cs42l73_mclk_div cs42l73_mclk_coeffs[] = {
/* MCLK, Sample Rate, xMMCC[5:0] */
{5644800, 11025, 0x30},
{5644800, 22050, 0x20},
......@@ -844,7 +844,7 @@ struct cs42l73_mclkx_div {
u8 mclkdiv;
};
static struct cs42l73_mclkx_div cs42l73_mclkx_coeffs[] = {
static const struct cs42l73_mclkx_div cs42l73_mclkx_coeffs[] = {
{5644800, 1, 0}, /* 5644800 */
{6000000, 1, 0}, /* 6000000 */
{6144000, 1, 0}, /* 6144000 */
......
......@@ -466,7 +466,7 @@ struct cs53l30_mclk_div {
u8 mclk_int_scale;
};
static struct cs53l30_mclk_div cs53l30_mclk_coeffs[] = {
static const struct cs53l30_mclk_div cs53l30_mclk_coeffs[] = {
/* NOTE: Enable MCLK_INT_SCALE to save power. */
/* MCLK, Sample Rate, asp_rate, internal_fs_ratio, mclk_int_scale */
......@@ -511,7 +511,7 @@ struct cs53l30_mclkx_div {
u8 mclkdiv;
};
static struct cs53l30_mclkx_div cs53l30_mclkx_coeffs[] = {
static const struct cs53l30_mclkx_div cs53l30_mclkx_coeffs[] = {
{5644800, 1, CS53L30_MCLK_DIV_BY_1},
{6000000, 1, CS53L30_MCLK_DIV_BY_1},
{6144000, 1, CS53L30_MCLK_DIV_BY_1},
......@@ -1000,8 +1000,8 @@ static int cs53l30_i2c_probe(struct i2c_client *client,
/* Check if MCLK provided */
cs53l30->mclk = devm_clk_get(dev, "mclk");
if (IS_ERR(cs53l30->mclk)) {
if (PTR_ERR(cs53l30->mclk) == -EPROBE_DEFER) {
ret = -EPROBE_DEFER;
if (PTR_ERR(cs53l30->mclk) != -ENOENT) {
ret = PTR_ERR(cs53l30->mclk);
goto error;
}
/* Otherwise mark the mclk pointer to NULL */
......
......@@ -750,11 +750,18 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w,
snd_soc_update_bits(codec, DA7213_PC_COUNT,
DA7213_PC_FREERUN_MASK, 0);
/* Slave mode, if SRM not enabled no need for status checks */
/* If SRM not enabled then nothing more to do */
pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL);
if (!(pll_ctrl & DA7213_PLL_SRM_EN))
return 0;
/* Assist 32KHz mode PLL lock */
if (pll_ctrl & DA7213_PLL_32K_MODE) {
snd_soc_write(codec, 0xF0, 0x8B);
snd_soc_write(codec, 0xF2, 0x03);
snd_soc_write(codec, 0xF0, 0x00);
}
/* Check SRM has locked */
do {
pll_status = snd_soc_read(codec, DA7213_PLL_STATUS);
......@@ -771,6 +778,14 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w,
return 0;
case SND_SOC_DAPM_POST_PMD:
/* Revert 32KHz PLL lock udpates if applied previously */
pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL);
if (pll_ctrl & DA7213_PLL_32K_MODE) {
snd_soc_write(codec, 0xF0, 0x8B);
snd_soc_write(codec, 0xF2, 0x01);
snd_soc_write(codec, 0xF0, 0x00);
}
/* PC free-running */
snd_soc_update_bits(codec, DA7213_PC_COUNT,
DA7213_PC_FREERUN_MASK,
......@@ -1297,10 +1312,13 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
switch (clk_id) {
case DA7213_CLKSRC_MCLK:
da7213->mclk_squarer_en = false;
snd_soc_update_bits(codec, DA7213_PLL_CTRL,
DA7213_PLL_MCLK_SQR_EN, 0);
break;
case DA7213_CLKSRC_MCLK_SQR:
da7213->mclk_squarer_en = true;
snd_soc_update_bits(codec, DA7213_PLL_CTRL,
DA7213_PLL_MCLK_SQR_EN,
DA7213_PLL_MCLK_SQR_EN);
break;
default:
dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id);
......@@ -1324,7 +1342,7 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
return 0;
}
/* Supported PLL input frequencies are 5MHz - 54MHz. */
/* Supported PLL input frequencies are 32KHz, 5MHz - 54MHz. */
static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
int source, unsigned int fref, unsigned int fout)
{
......@@ -1336,22 +1354,26 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
u32 freq_ref;
u64 frac_div;
/* Reset PLL configuration */
snd_soc_write(codec, DA7213_PLL_CTRL, 0);
pll_ctrl = 0;
/* Workout input divider based on MCLK rate */
if (da7213->mclk_rate == 32768) {
if (!da7213->master) {
dev_err(codec->dev,
"32KHz only valid if codec is clock master\n");
return -EINVAL;
}
/* 32KHz PLL Mode */
indiv_bits = DA7213_PLL_INDIV_9_TO_18_MHZ;
indiv = DA7213_PLL_INDIV_9_TO_18_MHZ_VAL;
source = DA7213_SYSCLK_PLL_32KHZ;
freq_ref = 3750000;
pll_ctrl |= DA7213_PLL_32K_MODE;
} else {
/* 5 - 54MHz MCLK */
if (da7213->mclk_rate < 5000000) {
goto pll_err;
dev_err(codec->dev,
"PLL input clock %d below valid range\n",
da7213->mclk_rate);
return -EINVAL;
} else if (da7213->mclk_rate <= 9000000) {
indiv_bits = DA7213_PLL_INDIV_5_TO_9_MHZ;
indiv = DA7213_PLL_INDIV_5_TO_9_MHZ_VAL;
......@@ -1365,32 +1387,44 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
indiv_bits = DA7213_PLL_INDIV_36_TO_54_MHZ;
indiv = DA7213_PLL_INDIV_36_TO_54_MHZ_VAL;
} else {
goto pll_err;
dev_err(codec->dev,
"PLL input clock %d above valid range\n",
da7213->mclk_rate);
return -EINVAL;
}
freq_ref = (da7213->mclk_rate / indiv);
}
pll_ctrl |= indiv_bits;
pll_ctrl = indiv_bits;
/* PLL Bypass mode */
if (source == DA7213_SYSCLK_MCLK) {
snd_soc_write(codec, DA7213_PLL_CTRL, pll_ctrl);
/* Configure PLL */
switch (source) {
case DA7213_SYSCLK_MCLK:
snd_soc_update_bits(codec, DA7213_PLL_CTRL,
DA7213_PLL_INDIV_MASK |
DA7213_PLL_MODE_MASK, pll_ctrl);
return 0;
}
case DA7213_SYSCLK_PLL:
break;
case DA7213_SYSCLK_PLL_SRM:
pll_ctrl |= DA7213_PLL_SRM_EN;
fout = DA7213_PLL_FREQ_OUT_94310400;
break;
case DA7213_SYSCLK_PLL_32KHZ:
if (da7213->mclk_rate != 32768) {
dev_err(codec->dev,
"32KHz mode only valid with 32KHz MCLK\n");
return -EINVAL;
}
/*
* If Codec is slave and SRM enabled,
* freq_out is (98304000 + 90316800)/2 = 94310400
*/
if (!da7213->master && da7213->srm_en) {
pll_ctrl |= DA7213_PLL_32K_MODE | DA7213_PLL_SRM_EN;
fout = DA7213_PLL_FREQ_OUT_94310400;
pll_ctrl |= DA7213_PLL_SRM_EN;
break;
default:
dev_err(codec->dev, "Invalid PLL config\n");
return -EINVAL;
}
/* Enable MCLK squarer if required */
if (da7213->mclk_squarer_en)
pll_ctrl |= DA7213_PLL_MCLK_SQR_EN;
/* Calculate dividers for PLL */
pll_integer = fout / freq_ref;
frac_div = (u64)(fout % freq_ref) * 8192ULL;
......@@ -1405,14 +1439,19 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
/* Enable PLL */
pll_ctrl |= DA7213_PLL_EN;
snd_soc_write(codec, DA7213_PLL_CTRL, pll_ctrl);
snd_soc_update_bits(codec, DA7213_PLL_CTRL,
DA7213_PLL_INDIV_MASK | DA7213_PLL_MODE_MASK,
pll_ctrl);
/* Assist 32KHz mode PLL lock */
if (source == DA7213_SYSCLK_PLL_32KHZ) {
snd_soc_write(codec, 0xF0, 0x8B);
snd_soc_write(codec, 0xF1, 0x03);
snd_soc_write(codec, 0xF1, 0x01);
snd_soc_write(codec, 0xF0, 0x00);
}
return 0;
pll_err:
dev_err(codec_dai->dev, "Unsupported PLL input frequency %d\n",
da7213->mclk_rate);
return -EINVAL;
}
/* DAI operations */
......@@ -1454,11 +1493,10 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec,
switch (level) {
case SND_SOC_BIAS_ON:
case SND_SOC_BIAS_PREPARE:
break;
case SND_SOC_BIAS_STANDBY:
if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
/* MCLK */
case SND_SOC_BIAS_PREPARE:
/* Enable MCLK for transition to ON state */
if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) {
if (da7213->mclk) {
ret = clk_prepare_enable(da7213->mclk);
if (ret) {
......@@ -1467,21 +1505,24 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec,
return ret;
}
}
}
break;
case SND_SOC_BIAS_STANDBY:
if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
/* Enable VMID reference & master bias */
snd_soc_update_bits(codec, DA7213_REFERENCES,
DA7213_VMID_EN | DA7213_BIAS_EN,
DA7213_VMID_EN | DA7213_BIAS_EN);
} else {
/* Remove MCLK */
if (da7213->mclk)
clk_disable_unprepare(da7213->mclk);
}
break;
case SND_SOC_BIAS_OFF:
/* Disable VMID reference & master bias */
snd_soc_update_bits(codec, DA7213_REFERENCES,
DA7213_VMID_EN | DA7213_BIAS_EN, 0);
/* MCLK */
if (da7213->mclk)
clk_disable_unprepare(da7213->mclk);
break;
}
return 0;
......@@ -1605,9 +1646,6 @@ static int da7213_probe(struct snd_soc_codec *codec)
DA7213_ALC_CALIB_MODE_MAN, 0);
da7213->alc_calib_auto = true;
/* Default to using SRM for slave mode */
da7213->srm_en = true;
/* Default PC counter to free-running */
snd_soc_update_bits(codec, DA7213_PC_COUNT, DA7213_PC_FREERUN_MASK,
DA7213_PC_FREERUN_MASK);
......
......@@ -172,6 +172,7 @@
#define DA7213_PLL_32K_MODE (0x1 << 5)
#define DA7213_PLL_SRM_EN (0x1 << 6)
#define DA7213_PLL_EN (0x1 << 7)
#define DA7213_PLL_MODE_MASK (0x7 << 5)
/* DA7213_DAI_CLK_MODE = 0x28 */
#define DA7213_DAI_BCLKS_PER_WCLK_32 (0x0 << 0)
......@@ -499,8 +500,6 @@
#define DA7213_ALC_AVG_ITERATIONS 5
/* PLL related */
#define DA7213_SYSCLK_MCLK 0
#define DA7213_SYSCLK_PLL 1
#define DA7213_PLL_FREQ_OUT_90316800 90316800
#define DA7213_PLL_FREQ_OUT_98304000 98304000
#define DA7213_PLL_FREQ_OUT_94310400 94310400
......@@ -515,6 +514,13 @@ enum da7213_clk_src {
DA7213_CLKSRC_MCLK_SQR,
};
enum da7213_sys_clk {
DA7213_SYSCLK_MCLK = 0,
DA7213_SYSCLK_PLL,
DA7213_SYSCLK_PLL_SRM,
DA7213_SYSCLK_PLL_32KHZ
};
/* Codec private data */
struct da7213_priv {
struct regmap *regmap;
......@@ -522,8 +528,6 @@ struct da7213_priv {
unsigned int mclk_rate;
int clk_src;
bool master;
bool mclk_squarer_en;
bool srm_en;
bool alc_calib_auto;
bool alc_en;
struct da7213_platform_data *pdata;
......
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