[alsa-devel] [PATCH 0/5] ASoC: da7213: clocking related improvements for codec
This is a collection of updates with regards to clocking on da7213 codec, including power efficiency & stability improvements.
Patches are based on v4.6-rc7 kernel.
Adam Thomson (5): ASoC: da7213: Add DAI DAPM event to control DAI clocks ASoC: da7213: Add checking of SRM lock status before enabling DAI ASoC: da7213: Default PC counter to free-running when DAI disabled ASoC: da7213: Update PLL ranges to improve locking at frequency boundary ASoC: da7213: Allow PLL disable/bypass when using 32KHz sysclk
sound/soc/codecs/da7213.c | 99 +++++++++++++++++++++++++++++++++++++++-------- sound/soc/codecs/da7213.h | 35 ++++++++++------- 2 files changed, 102 insertions(+), 32 deletions(-)
-- 1.9.3
Currently, when Codec is I2S master DAI clocks are continuously generated even if all audio streams have stopped. To improve efficiency, control of the DAI clocks for master mode have been moved to a DAPM widget event so they're only enabled as required.
Signed-off-by: Adam Thomson Adam.Thomson.Opensource@diasemi.com --- sound/soc/codecs/da7213.c | 35 ++++++++++++++++++++++++++++++++--- sound/soc/codecs/da7213.h | 2 -- 2 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index 7278f93..701bd62 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c @@ -726,6 +726,36 @@ static const struct snd_kcontrol_new da7213_dapm_mixoutr_controls[] = {
/* + * DAPM Events + */ + +static int da7213_dai_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* Enable DAI clks for master mode */ + if (da7213->master) + snd_soc_update_bits(codec, DA7213_DAI_CLK_MODE, + DA7213_DAI_CLK_EN_MASK, + DA7213_DAI_CLK_EN_MASK); + return 0; + case SND_SOC_DAPM_POST_PMD: + /* Disable DAI clks if in master mode */ + if (da7213->master) + snd_soc_update_bits(codec, DA7213_DAI_CLK_MODE, + DA7213_DAI_CLK_EN_MASK, 0); + return 0; + default: + return -EINVAL; + } +} + + +/* * DAPM widgets */
@@ -736,7 +766,8 @@ static const struct snd_soc_dapm_widget da7213_dapm_widgets[] = {
/* Use a supply here as this controls both input & output DAIs */ SND_SOC_DAPM_SUPPLY("DAI", DA7213_DAI_CTRL, DA7213_DAI_EN_SHIFT, - DA7213_NO_INVERT, NULL, 0), + DA7213_NO_INVERT, da7213_dai_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
/* * Input @@ -1143,11 +1174,9 @@ static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) /* Set master/slave mode */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBM_CFM: - dai_clk_mode |= DA7213_DAI_CLK_EN_MASTER_MODE; da7213->master = true; break; case SND_SOC_DAIFMT_CBS_CFS: - dai_clk_mode |= DA7213_DAI_CLK_EN_SLAVE_MODE; da7213->master = false; break; default: diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h index 030fd69..5de5c29 100644 --- a/sound/soc/codecs/da7213.h +++ b/sound/soc/codecs/da7213.h @@ -178,8 +178,6 @@ #define DA7213_DAI_BCLKS_PER_WCLK_MASK (0x3 << 0) #define DA7213_DAI_CLK_POL_INV (0x1 << 2) #define DA7213_DAI_WCLK_POL_INV (0x1 << 3) -#define DA7213_DAI_CLK_EN_SLAVE_MODE (0x0 << 7) -#define DA7213_DAI_CLK_EN_MASTER_MODE (0x1 << 7) #define DA7213_DAI_CLK_EN_MASK (0x1 << 7)
/* DA7213_DAI_CTRL = 0x29 */
The patch
ASoC: da7213: Add DAI DAPM event to control DAI clocks
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
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
From a0d5caeaebfd00853efa0080afc850e10be7b39a Mon Sep 17 00:00:00 2001
From: Adam Thomson Adam.Thomson.Opensource@diasemi.com Date: Tue, 10 May 2016 16:11:04 +0100 Subject: [PATCH] ASoC: da7213: Add DAI DAPM event to control DAI clocks
Currently, when Codec is I2S master DAI clocks are continuously generated even if all audio streams have stopped. To improve efficiency, control of the DAI clocks for master mode have been moved to a DAPM widget event so they're only enabled as required.
Signed-off-by: Adam Thomson Adam.Thomson.Opensource@diasemi.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/codecs/da7213.c | 35 ++++++++++++++++++++++++++++++++--- sound/soc/codecs/da7213.h | 2 -- 2 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index 7278f93460c1..701bd6204747 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c @@ -726,6 +726,36 @@ static const struct snd_kcontrol_new da7213_dapm_mixoutr_controls[] = {
/* + * DAPM Events + */ + +static int da7213_dai_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* Enable DAI clks for master mode */ + if (da7213->master) + snd_soc_update_bits(codec, DA7213_DAI_CLK_MODE, + DA7213_DAI_CLK_EN_MASK, + DA7213_DAI_CLK_EN_MASK); + return 0; + case SND_SOC_DAPM_POST_PMD: + /* Disable DAI clks if in master mode */ + if (da7213->master) + snd_soc_update_bits(codec, DA7213_DAI_CLK_MODE, + DA7213_DAI_CLK_EN_MASK, 0); + return 0; + default: + return -EINVAL; + } +} + + +/* * DAPM widgets */
@@ -736,7 +766,8 @@ static const struct snd_soc_dapm_widget da7213_dapm_widgets[] = {
/* Use a supply here as this controls both input & output DAIs */ SND_SOC_DAPM_SUPPLY("DAI", DA7213_DAI_CTRL, DA7213_DAI_EN_SHIFT, - DA7213_NO_INVERT, NULL, 0), + DA7213_NO_INVERT, da7213_dai_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
/* * Input @@ -1143,11 +1174,9 @@ static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) /* Set master/slave mode */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBM_CFM: - dai_clk_mode |= DA7213_DAI_CLK_EN_MASTER_MODE; da7213->master = true; break; case SND_SOC_DAIFMT_CBS_CFS: - dai_clk_mode |= DA7213_DAI_CLK_EN_SLAVE_MODE; da7213->master = false; break; default: diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h index 030fd691b076..5de5c2997e0c 100644 --- a/sound/soc/codecs/da7213.h +++ b/sound/soc/codecs/da7213.h @@ -178,8 +178,6 @@ #define DA7213_DAI_BCLKS_PER_WCLK_MASK (0x3 << 0) #define DA7213_DAI_CLK_POL_INV (0x1 << 2) #define DA7213_DAI_WCLK_POL_INV (0x1 << 3) -#define DA7213_DAI_CLK_EN_SLAVE_MODE (0x0 << 7) -#define DA7213_DAI_CLK_EN_MASTER_MODE (0x1 << 7) #define DA7213_DAI_CLK_EN_MASK (0x1 << 7)
/* DA7213_DAI_CTRL = 0x29 */
When the codec is DAI clk slave, and the SRM feature of the PLL is being used, the enabling of the DAI should occur only after the PLL has locked to the incoming WCLK. This update adds checking to the the DAI widget event, so it waits for SRM to lock. There is also a timeout if that lock doesn't occur within a given time.
Signed-off-by: Adam Thomson Adam.Thomson.Opensource@diasemi.com --- sound/soc/codecs/da7213.c | 23 +++++++++++++++++++++++ sound/soc/codecs/da7213.h | 4 ++++ 2 files changed, 27 insertions(+)
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index 701bd62..680d111 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c @@ -734,6 +734,9 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w, { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec); + u8 pll_ctrl, pll_status; + int i = 0; + bool srm_lock = false;
switch (event) { case SND_SOC_DAPM_PRE_PMU: @@ -742,6 +745,26 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, DA7213_DAI_CLK_MODE, DA7213_DAI_CLK_EN_MASK, DA7213_DAI_CLK_EN_MASK); + + /* Slave mode, if SRM not enabled no need for status checks */ + pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL); + if (!(pll_ctrl & DA7213_PLL_SRM_EN)) + return 0; + + /* Check SRM has locked */ + do { + pll_status = snd_soc_read(codec, DA7213_PLL_STATUS); + if (pll_status & DA7219_PLL_SRM_LOCK) { + srm_lock = true; + } else { + ++i; + msleep(50); + } + } while ((i < DA7213_SRM_CHECK_RETRIES) & (!srm_lock)); + + if (!srm_lock) + dev_warn(codec->dev, "SRM failed to lock\n"); + return 0; case SND_SOC_DAPM_POST_PMD: /* Disable DAI clks if in master mode */ diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h index 5de5c29..af75340 100644 --- a/sound/soc/codecs/da7213.h +++ b/sound/soc/codecs/da7213.h @@ -142,6 +142,9 @@ * Bit fields */
+/* DA7213_PLL_STATUS = 0x03 */ +#define DA7219_PLL_SRM_LOCK (0x1 << 1) + /* DA7213_SR = 0x22 */ #define DA7213_SR_8000 (0x1 << 0) #define DA7213_SR_11025 (0x2 << 0) @@ -502,6 +505,7 @@ #define DA7213_PLL_INDIV_10_20_MHZ_VAL 4 #define DA7213_PLL_INDIV_20_40_MHZ_VAL 8 #define DA7213_PLL_INDIV_40_54_MHZ_VAL 16 +#define DA7213_SRM_CHECK_RETRIES 8
enum da7213_clk_src { DA7213_CLKSRC_MCLK = 0,
On Tue, May 10, 2016 at 04:11:05PM +0100, Adam Thomson wrote:
/* Slave mode, if SRM not enabled no need for status checks */
pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL);
if (!(pll_ctrl & DA7213_PLL_SRM_EN))
return 0;
This isn't going to work, the driver has no volatile registers but it does have a cache...
On Tue, May 10, 2016 at 07:21:43PM +0100, Mark Brown wrote:
On Tue, May 10, 2016 at 04:11:05PM +0100, Adam Thomson wrote:
/* Slave mode, if SRM not enabled no need for status checks */
pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL);
if (!(pll_ctrl & DA7213_PLL_SRM_EN))
return 0;
This isn't going to work, the driver has no volatile registers but it does have a cache...
Ugh, yes it does - was looking at the wrong driver there.
The patch
ASoC: da7213: Add checking of SRM lock status before enabling DAI
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
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
From d575b0b0f01a805508c5cf48b540f004e9b5de07 Mon Sep 17 00:00:00 2001
From: Adam Thomson Adam.Thomson.Opensource@diasemi.com Date: Tue, 10 May 2016 16:11:05 +0100 Subject: [PATCH] ASoC: da7213: Add checking of SRM lock status before enabling DAI
When the codec is DAI clk slave, and the SRM feature of the PLL is being used, the enabling of the DAI should occur only after the PLL has locked to the incoming WCLK. This update adds checking to the the DAI widget event, so it waits for SRM to lock. There is also a timeout if that lock doesn't occur within a given time.
Signed-off-by: Adam Thomson Adam.Thomson.Opensource@diasemi.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/codecs/da7213.c | 23 +++++++++++++++++++++++ sound/soc/codecs/da7213.h | 4 ++++ 2 files changed, 27 insertions(+)
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index 701bd6204747..680d11116ccf 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c @@ -734,6 +734,9 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w, { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec); + u8 pll_ctrl, pll_status; + int i = 0; + bool srm_lock = false;
switch (event) { case SND_SOC_DAPM_PRE_PMU: @@ -742,6 +745,26 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, DA7213_DAI_CLK_MODE, DA7213_DAI_CLK_EN_MASK, DA7213_DAI_CLK_EN_MASK); + + /* Slave mode, if SRM not enabled no need for status checks */ + pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL); + if (!(pll_ctrl & DA7213_PLL_SRM_EN)) + return 0; + + /* Check SRM has locked */ + do { + pll_status = snd_soc_read(codec, DA7213_PLL_STATUS); + if (pll_status & DA7219_PLL_SRM_LOCK) { + srm_lock = true; + } else { + ++i; + msleep(50); + } + } while ((i < DA7213_SRM_CHECK_RETRIES) & (!srm_lock)); + + if (!srm_lock) + dev_warn(codec->dev, "SRM failed to lock\n"); + return 0; case SND_SOC_DAPM_POST_PMD: /* Disable DAI clks if in master mode */ diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h index 5de5c2997e0c..af75340dea63 100644 --- a/sound/soc/codecs/da7213.h +++ b/sound/soc/codecs/da7213.h @@ -142,6 +142,9 @@ * Bit fields */
+/* DA7213_PLL_STATUS = 0x03 */ +#define DA7219_PLL_SRM_LOCK (0x1 << 1) + /* DA7213_SR = 0x22 */ #define DA7213_SR_8000 (0x1 << 0) #define DA7213_SR_11025 (0x2 << 0) @@ -502,6 +505,7 @@ #define DA7213_PLL_INDIV_10_20_MHZ_VAL 4 #define DA7213_PLL_INDIV_20_40_MHZ_VAL 8 #define DA7213_PLL_INDIV_40_54_MHZ_VAL 16 +#define DA7213_SRM_CHECK_RETRIES 8
enum da7213_clk_src { DA7213_CLKSRC_MCLK = 0,
Currently PC counter is always synchronised to DAI which means that when the DAI is disabled, features such as ALC calibration cannot be executed successfully. This patch makes sure that when the DAI is disabled, PC counter is set to free-running.
Signed-off-by: Adam Thomson Adam.Thomson.Opensource@diasemi.com --- sound/soc/codecs/da7213.c | 13 +++++++++++++ sound/soc/codecs/da7213.h | 3 +++ 2 files changed, 16 insertions(+)
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index 680d111..657b7eb 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c @@ -746,6 +746,10 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w, DA7213_DAI_CLK_EN_MASK, DA7213_DAI_CLK_EN_MASK);
+ /* PC synchronised to DAI */ + snd_soc_update_bits(codec, DA7213_PC_COUNT, + DA7213_PC_FREERUN_MASK, 0); + /* Slave mode, if SRM not enabled no need for status checks */ pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL); if (!(pll_ctrl & DA7213_PLL_SRM_EN)) @@ -767,6 +771,11 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w,
return 0; case SND_SOC_DAPM_POST_PMD: + /* PC free-running */ + snd_soc_update_bits(codec, DA7213_PC_COUNT, + DA7213_PC_FREERUN_MASK, + DA7213_PC_FREERUN_MASK); + /* Disable DAI clks if in master mode */ if (da7213->master) snd_soc_update_bits(codec, DA7213_DAI_CLK_MODE, @@ -1599,6 +1608,10 @@ static int da7213_probe(struct snd_soc_codec *codec) /* 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); + /* Enable all Gain Ramps */ snd_soc_update_bits(codec, DA7213_AUX_L_CTRL, DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN); diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h index af75340..26b87e3 100644 --- a/sound/soc/codecs/da7213.h +++ b/sound/soc/codecs/da7213.h @@ -413,6 +413,9 @@ #define DA7213_DMIC_CLK_RATE_SHIFT 2 #define DA7213_DMIC_CLK_RATE_MASK (0x1 << 2)
+/* DA7213_PC_COUNT = 0x94 */ +#define DA7213_PC_FREERUN_MASK (0x1 << 0) + /* DA7213_DIG_CTRL = 0x99 */ #define DA7213_DAC_L_INV_SHIFT 3 #define DA7213_DAC_R_INV_SHIFT 7
The patch
ASoC: da7213: Default PC counter to free-running when DAI disabled
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
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
From 7e28fd469624fc41ec326a31abbc63a7afdd10f5 Mon Sep 17 00:00:00 2001
From: Adam Thomson Adam.Thomson.Opensource@diasemi.com Date: Tue, 10 May 2016 16:11:06 +0100 Subject: [PATCH] ASoC: da7213: Default PC counter to free-running when DAI disabled
Currently PC counter is always synchronised to DAI which means that when the DAI is disabled, features such as ALC calibration cannot be executed successfully. This patch makes sure that when the DAI is disabled, PC counter is set to free-running.
Signed-off-by: Adam Thomson Adam.Thomson.Opensource@diasemi.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/codecs/da7213.c | 13 +++++++++++++ sound/soc/codecs/da7213.h | 3 +++ 2 files changed, 16 insertions(+)
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index 680d11116ccf..657b7eba9954 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c @@ -746,6 +746,10 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w, DA7213_DAI_CLK_EN_MASK, DA7213_DAI_CLK_EN_MASK);
+ /* PC synchronised to DAI */ + snd_soc_update_bits(codec, DA7213_PC_COUNT, + DA7213_PC_FREERUN_MASK, 0); + /* Slave mode, if SRM not enabled no need for status checks */ pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL); if (!(pll_ctrl & DA7213_PLL_SRM_EN)) @@ -767,6 +771,11 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w,
return 0; case SND_SOC_DAPM_POST_PMD: + /* PC free-running */ + snd_soc_update_bits(codec, DA7213_PC_COUNT, + DA7213_PC_FREERUN_MASK, + DA7213_PC_FREERUN_MASK); + /* Disable DAI clks if in master mode */ if (da7213->master) snd_soc_update_bits(codec, DA7213_DAI_CLK_MODE, @@ -1599,6 +1608,10 @@ static int da7213_probe(struct snd_soc_codec *codec) /* 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); + /* Enable all Gain Ramps */ snd_soc_update_bits(codec, DA7213_AUX_L_CTRL, DA7213_GAIN_RAMP_EN, DA7213_GAIN_RAMP_EN); diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h index af75340dea63..26b87e3c3088 100644 --- a/sound/soc/codecs/da7213.h +++ b/sound/soc/codecs/da7213.h @@ -413,6 +413,9 @@ #define DA7213_DMIC_CLK_RATE_SHIFT 2 #define DA7213_DMIC_CLK_RATE_MASK (0x1 << 2)
+/* DA7213_PC_COUNT = 0x94 */ +#define DA7213_PC_FREERUN_MASK (0x1 << 0) + /* DA7213_DIG_CTRL = 0x99 */ #define DA7213_DAC_L_INV_SHIFT 3 #define DA7213_DAC_R_INV_SHIFT 7
This update changes the dividers used for ranges of input MCLK frequencies, to improve PLL locking for a corner case when at edge of MCLK frequency input divider range.
Signed-off-by: Adam Thomson Adam.Thomson.Opensource@diasemi.com --- sound/soc/codecs/da7213.c | 26 +++++++++++++------------- sound/soc/codecs/da7213.h | 28 ++++++++++++++-------------- 2 files changed, 27 insertions(+), 27 deletions(-)
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index 657b7eb..a233fe7 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c @@ -1344,26 +1344,26 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, /* Workout input divider based on MCLK rate */ if ((da7213->mclk_rate == 32768) && (source == DA7213_SYSCLK_PLL)) { /* 32KHz PLL Mode */ - indiv_bits = DA7213_PLL_INDIV_10_20_MHZ; - indiv = DA7213_PLL_INDIV_10_20_MHZ_VAL; + indiv_bits = DA7213_PLL_INDIV_9_TO_18_MHZ; + indiv = DA7213_PLL_INDIV_9_TO_18_MHZ_VAL; freq_ref = 3750000; pll_ctrl |= DA7213_PLL_32K_MODE; } else { /* 5 - 54MHz MCLK */ if (da7213->mclk_rate < 5000000) { goto pll_err; - } else if (da7213->mclk_rate <= 10000000) { - indiv_bits = DA7213_PLL_INDIV_5_10_MHZ; - indiv = DA7213_PLL_INDIV_5_10_MHZ_VAL; - } else if (da7213->mclk_rate <= 20000000) { - indiv_bits = DA7213_PLL_INDIV_10_20_MHZ; - indiv = DA7213_PLL_INDIV_10_20_MHZ_VAL; - } else if (da7213->mclk_rate <= 40000000) { - indiv_bits = DA7213_PLL_INDIV_20_40_MHZ; - indiv = DA7213_PLL_INDIV_20_40_MHZ_VAL; + } else if (da7213->mclk_rate <= 9000000) { + indiv_bits = DA7213_PLL_INDIV_5_TO_9_MHZ; + indiv = DA7213_PLL_INDIV_5_TO_9_MHZ_VAL; + } else if (da7213->mclk_rate <= 18000000) { + indiv_bits = DA7213_PLL_INDIV_9_TO_18_MHZ; + indiv = DA7213_PLL_INDIV_9_TO_18_MHZ_VAL; + } else if (da7213->mclk_rate <= 36000000) { + indiv_bits = DA7213_PLL_INDIV_18_TO_36_MHZ; + indiv = DA7213_PLL_INDIV_18_TO_36_MHZ_VAL; } else if (da7213->mclk_rate <= 54000000) { - indiv_bits = DA7213_PLL_INDIV_40_54_MHZ; - indiv = DA7213_PLL_INDIV_40_54_MHZ_VAL; + indiv_bits = DA7213_PLL_INDIV_36_TO_54_MHZ; + indiv = DA7213_PLL_INDIV_36_TO_54_MHZ_VAL; } else { goto pll_err; } diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h index 26b87e3..fbb7a35 100644 --- a/sound/soc/codecs/da7213.h +++ b/sound/soc/codecs/da7213.h @@ -163,10 +163,10 @@ #define DA7213_VMID_EN (0x1 << 7)
/* DA7213_PLL_CTRL = 0x27 */ -#define DA7213_PLL_INDIV_5_10_MHZ (0x0 << 2) -#define DA7213_PLL_INDIV_10_20_MHZ (0x1 << 2) -#define DA7213_PLL_INDIV_20_40_MHZ (0x2 << 2) -#define DA7213_PLL_INDIV_40_54_MHZ (0x3 << 2) +#define DA7213_PLL_INDIV_5_TO_9_MHZ (0x0 << 2) +#define DA7213_PLL_INDIV_9_TO_18_MHZ (0x1 << 2) +#define DA7213_PLL_INDIV_18_TO_36_MHZ (0x2 << 2) +#define DA7213_PLL_INDIV_36_TO_54_MHZ (0x3 << 2) #define DA7213_PLL_INDIV_MASK (0x3 << 2) #define DA7213_PLL_MCLK_SQR_EN (0x1 << 4) #define DA7213_PLL_32K_MODE (0x1 << 5) @@ -499,16 +499,16 @@ #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 -#define DA7213_PLL_INDIV_5_10_MHZ_VAL 2 -#define DA7213_PLL_INDIV_10_20_MHZ_VAL 4 -#define DA7213_PLL_INDIV_20_40_MHZ_VAL 8 -#define DA7213_PLL_INDIV_40_54_MHZ_VAL 16 -#define DA7213_SRM_CHECK_RETRIES 8 +#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 +#define DA7213_PLL_INDIV_5_TO_9_MHZ_VAL 2 +#define DA7213_PLL_INDIV_9_TO_18_MHZ_VAL 4 +#define DA7213_PLL_INDIV_18_TO_36_MHZ_VAL 8 +#define DA7213_PLL_INDIV_36_TO_54_MHZ_VAL 16 +#define DA7213_SRM_CHECK_RETRIES 8
enum da7213_clk_src { DA7213_CLKSRC_MCLK = 0,
The patch
ASoC: da7213: Update PLL ranges to improve locking at frequency boundary
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
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
From 1e62c52ddc2d23a02ac2308cc1bb6ff18f0cf3cd Mon Sep 17 00:00:00 2001
From: Adam Thomson Adam.Thomson.Opensource@diasemi.com Date: Tue, 10 May 2016 16:11:07 +0100 Subject: [PATCH] ASoC: da7213: Update PLL ranges to improve locking at frequency boundary
This update changes the dividers used for ranges of input MCLK frequencies, to improve PLL locking for a corner case when at edge of MCLK frequency input divider range.
Signed-off-by: Adam Thomson Adam.Thomson.Opensource@diasemi.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/codecs/da7213.c | 26 +++++++++++++------------- sound/soc/codecs/da7213.h | 28 ++++++++++++++-------------- 2 files changed, 27 insertions(+), 27 deletions(-)
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index 657b7eba9954..a233fe7f12eb 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c @@ -1344,26 +1344,26 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, /* Workout input divider based on MCLK rate */ if ((da7213->mclk_rate == 32768) && (source == DA7213_SYSCLK_PLL)) { /* 32KHz PLL Mode */ - indiv_bits = DA7213_PLL_INDIV_10_20_MHZ; - indiv = DA7213_PLL_INDIV_10_20_MHZ_VAL; + indiv_bits = DA7213_PLL_INDIV_9_TO_18_MHZ; + indiv = DA7213_PLL_INDIV_9_TO_18_MHZ_VAL; freq_ref = 3750000; pll_ctrl |= DA7213_PLL_32K_MODE; } else { /* 5 - 54MHz MCLK */ if (da7213->mclk_rate < 5000000) { goto pll_err; - } else if (da7213->mclk_rate <= 10000000) { - indiv_bits = DA7213_PLL_INDIV_5_10_MHZ; - indiv = DA7213_PLL_INDIV_5_10_MHZ_VAL; - } else if (da7213->mclk_rate <= 20000000) { - indiv_bits = DA7213_PLL_INDIV_10_20_MHZ; - indiv = DA7213_PLL_INDIV_10_20_MHZ_VAL; - } else if (da7213->mclk_rate <= 40000000) { - indiv_bits = DA7213_PLL_INDIV_20_40_MHZ; - indiv = DA7213_PLL_INDIV_20_40_MHZ_VAL; + } else if (da7213->mclk_rate <= 9000000) { + indiv_bits = DA7213_PLL_INDIV_5_TO_9_MHZ; + indiv = DA7213_PLL_INDIV_5_TO_9_MHZ_VAL; + } else if (da7213->mclk_rate <= 18000000) { + indiv_bits = DA7213_PLL_INDIV_9_TO_18_MHZ; + indiv = DA7213_PLL_INDIV_9_TO_18_MHZ_VAL; + } else if (da7213->mclk_rate <= 36000000) { + indiv_bits = DA7213_PLL_INDIV_18_TO_36_MHZ; + indiv = DA7213_PLL_INDIV_18_TO_36_MHZ_VAL; } else if (da7213->mclk_rate <= 54000000) { - indiv_bits = DA7213_PLL_INDIV_40_54_MHZ; - indiv = DA7213_PLL_INDIV_40_54_MHZ_VAL; + indiv_bits = DA7213_PLL_INDIV_36_TO_54_MHZ; + indiv = DA7213_PLL_INDIV_36_TO_54_MHZ_VAL; } else { goto pll_err; } diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h index 26b87e3c3088..fbb7a356a501 100644 --- a/sound/soc/codecs/da7213.h +++ b/sound/soc/codecs/da7213.h @@ -163,10 +163,10 @@ #define DA7213_VMID_EN (0x1 << 7)
/* DA7213_PLL_CTRL = 0x27 */ -#define DA7213_PLL_INDIV_5_10_MHZ (0x0 << 2) -#define DA7213_PLL_INDIV_10_20_MHZ (0x1 << 2) -#define DA7213_PLL_INDIV_20_40_MHZ (0x2 << 2) -#define DA7213_PLL_INDIV_40_54_MHZ (0x3 << 2) +#define DA7213_PLL_INDIV_5_TO_9_MHZ (0x0 << 2) +#define DA7213_PLL_INDIV_9_TO_18_MHZ (0x1 << 2) +#define DA7213_PLL_INDIV_18_TO_36_MHZ (0x2 << 2) +#define DA7213_PLL_INDIV_36_TO_54_MHZ (0x3 << 2) #define DA7213_PLL_INDIV_MASK (0x3 << 2) #define DA7213_PLL_MCLK_SQR_EN (0x1 << 4) #define DA7213_PLL_32K_MODE (0x1 << 5) @@ -499,16 +499,16 @@ #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 -#define DA7213_PLL_INDIV_5_10_MHZ_VAL 2 -#define DA7213_PLL_INDIV_10_20_MHZ_VAL 4 -#define DA7213_PLL_INDIV_20_40_MHZ_VAL 8 -#define DA7213_PLL_INDIV_40_54_MHZ_VAL 16 -#define DA7213_SRM_CHECK_RETRIES 8 +#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 +#define DA7213_PLL_INDIV_5_TO_9_MHZ_VAL 2 +#define DA7213_PLL_INDIV_9_TO_18_MHZ_VAL 4 +#define DA7213_PLL_INDIV_18_TO_36_MHZ_VAL 8 +#define DA7213_PLL_INDIV_36_TO_54_MHZ_VAL 16 +#define DA7213_SRM_CHECK_RETRIES 8
enum da7213_clk_src { DA7213_CLKSRC_MCLK = 0,
Current checking for PLL 32KHz mode fails in driver code when bypassing the PLL. This is due to an incorrect check of PLL source type when 32KHz clock is provided. Removal of this check resolves the issue.
Signed-off-by: Adam Thomson Adam.Thomson.Opensource@diasemi.com --- sound/soc/codecs/da7213.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index a233fe7..e5527bc 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c @@ -1342,7 +1342,7 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, pll_ctrl = 0;
/* Workout input divider based on MCLK rate */ - if ((da7213->mclk_rate == 32768) && (source == DA7213_SYSCLK_PLL)) { + if (da7213->mclk_rate == 32768) { /* 32KHz PLL Mode */ indiv_bits = DA7213_PLL_INDIV_9_TO_18_MHZ; indiv = DA7213_PLL_INDIV_9_TO_18_MHZ_VAL;
The patch
ASoC: da7213: Allow PLL disable/bypass when using 32KHz sysclk
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
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
From abc189eadf6c12e60f95030e9c84083175526eaf Mon Sep 17 00:00:00 2001
From: Adam Thomson Adam.Thomson.Opensource@diasemi.com Date: Tue, 10 May 2016 16:11:08 +0100 Subject: [PATCH] ASoC: da7213: Allow PLL disable/bypass when using 32KHz sysclk
Current checking for PLL 32KHz mode fails in driver code when bypassing the PLL. This is due to an incorrect check of PLL source type when 32KHz clock is provided. Removal of this check resolves the issue.
Signed-off-by: Adam Thomson Adam.Thomson.Opensource@diasemi.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/codecs/da7213.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index a233fe7f12eb..e5527bc570ae 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c @@ -1342,7 +1342,7 @@ static int da7213_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, pll_ctrl = 0;
/* Workout input divider based on MCLK rate */ - if ((da7213->mclk_rate == 32768) && (source == DA7213_SYSCLK_PLL)) { + if (da7213->mclk_rate == 32768) { /* 32KHz PLL Mode */ indiv_bits = DA7213_PLL_INDIV_9_TO_18_MHZ; indiv = DA7213_PLL_INDIV_9_TO_18_MHZ_VAL;
participants (2)
-
Adam Thomson
-
Mark Brown