[alsa-devel] [PATCH 0/5] ASoC: codecs: ad193x: Several fixes and imprevements
From: Codrin Ciubotariu codrin.ciubotariu@microchip.com
This patch set contains some changes I needed to make I2S and TDM (DSP_A) formats work. I tested only with ad1936, but the patches should work fine for all the codecs that use this driver. Although I checked the DS for all of them (I hope) to assure that the patches apply, I would really appreciate if someone else can test them on another codec.
Codrin Ciubotariu (5): ASoC: codecs: ad193x: Remove capture support for codecs without ADC ASoC: codecs: ad193x: Set constraint to always have 32 sample bits ASoC: codecs: ad193x: Fix frame polarity for DSP_A format ASoC: codecs: ad193x: Add runtime support for DSP_A and I2S modes ASoC: codecs: ad193x: Add support to disable on-chip PLL
sound/soc/codecs/ad193x.c | 76 ++++++++++++++++++++++++++++++++++++--- sound/soc/codecs/ad193x.h | 8 +++++ 2 files changed, 80 insertions(+), 4 deletions(-)
From: Codrin Ciubotariu codrin.ciubotariu@microchip.com
Some ad193x codecs don't have ADCs, so they have no capture capabilities. This way, we can use this driver in multicodec cards.
Signed-off-by: Codrin Ciubotariu codrin.ciubotariu@microchip.com --- sound/soc/codecs/ad193x.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index 4b60ebee491d..21a38cc9e3da 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -351,6 +351,20 @@ static struct snd_soc_dai_driver ad193x_dai = { .ops = &ad193x_dai_ops, };
+/* codec DAI instance for DAC only */ +static struct snd_soc_dai_driver ad193x_no_adc_dai = { + .name = "ad193x-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 8, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE, + }, + .ops = &ad193x_dai_ops, +}; + static int ad193x_component_probe(struct snd_soc_component *component) { struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component); @@ -444,8 +458,11 @@ int ad193x_probe(struct device *dev, struct regmap *regmap,
dev_set_drvdata(dev, ad193x);
+ if (ad193x_has_adc(ad193x)) + return devm_snd_soc_register_component(dev, &soc_component_dev_ad193x, + &ad193x_dai, 1); return devm_snd_soc_register_component(dev, &soc_component_dev_ad193x, - &ad193x_dai, 1); + &ad193x_no_adc_dai, 1); } EXPORT_SYMBOL_GPL(ad193x_probe);
The patch
ASoC: codecs: ad193x: Remove capture support for codecs without ADC
has been applied to the asoc tree at
https://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 7aac8d13fc60db3ec2422f26c4dc2425a7fef20c Mon Sep 17 00:00:00 2001
From: Codrin Ciubotariu codrin.ciubotariu@microchip.com Date: Mon, 18 Feb 2019 16:10:28 +0000 Subject: [PATCH] ASoC: codecs: ad193x: Remove capture support for codecs without ADC
Some ad193x codecs don't have ADCs, so they have no capture capabilities. This way, we can use this driver in multicodec cards.
Signed-off-by: Codrin Ciubotariu codrin.ciubotariu@microchip.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/codecs/ad193x.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index 4b60ebee491d..21a38cc9e3da 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -351,6 +351,20 @@ static struct snd_soc_dai_driver ad193x_dai = { .ops = &ad193x_dai_ops, };
+/* codec DAI instance for DAC only */ +static struct snd_soc_dai_driver ad193x_no_adc_dai = { + .name = "ad193x-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 8, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE, + }, + .ops = &ad193x_dai_ops, +}; + static int ad193x_component_probe(struct snd_soc_component *component) { struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component); @@ -444,8 +458,11 @@ int ad193x_probe(struct device *dev, struct regmap *regmap,
dev_set_drvdata(dev, ad193x);
+ if (ad193x_has_adc(ad193x)) + return devm_snd_soc_register_component(dev, &soc_component_dev_ad193x, + &ad193x_dai, 1); return devm_snd_soc_register_component(dev, &soc_component_dev_ad193x, - &ad193x_dai, 1); + &ad193x_no_adc_dai, 1); } EXPORT_SYMBOL_GPL(ad193x_probe);
From: Codrin Ciubotariu codrin.ciubotariu@microchip.com
DACs and ADCs on ad193x codecs require a 32 bit slot size. We should assure that no other size is used.
Signed-off-by: Codrin Ciubotariu codrin.ciubotariu@microchip.com --- sound/soc/codecs/ad193x.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index 21a38cc9e3da..c16c9969d1a0 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -37,6 +37,13 @@ static SOC_ENUM_SINGLE_DECL(ad193x_deemp_enum, AD193X_DAC_CTRL2, 1,
static const DECLARE_TLV_DB_MINMAX(adau193x_tlv, -9563, 0);
+static const unsigned int ad193x_sb[] = {32}; + +static struct snd_pcm_hw_constraint_list constr = { + .list = ad193x_sb, + .count = ARRAY_SIZE(ad193x_sb), +}; + static const struct snd_kcontrol_new ad193x_snd_controls[] = { /* DAC volume control */ SOC_DOUBLE_R_TLV("DAC1 Volume", AD193X_DAC_L1_VOL, @@ -321,7 +328,16 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream, return 0; }
+static int ad193x_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + return snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_SAMPLE_BITS, + &constr); +} + static const struct snd_soc_dai_ops ad193x_dai_ops = { + .startup = ad193x_startup, .hw_params = ad193x_hw_params, .digital_mute = ad193x_mute, .set_tdm_slot = ad193x_set_tdm_slot,
The patch
ASoC: codecs: ad193x: Set constraint to always have 32 sample bits
has been applied to the asoc tree at
https://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 75c2ecb4bda296f89d4ea6a42750f48bfcd8a1d9 Mon Sep 17 00:00:00 2001
From: Codrin Ciubotariu codrin.ciubotariu@microchip.com Date: Mon, 18 Feb 2019 16:10:30 +0000 Subject: [PATCH] ASoC: codecs: ad193x: Set constraint to always have 32 sample bits
DACs and ADCs on ad193x codecs require a 32 bit slot size. We should assure that no other size is used.
Signed-off-by: Codrin Ciubotariu codrin.ciubotariu@microchip.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/codecs/ad193x.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index 21a38cc9e3da..c16c9969d1a0 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -37,6 +37,13 @@ static SOC_ENUM_SINGLE_DECL(ad193x_deemp_enum, AD193X_DAC_CTRL2, 1,
static const DECLARE_TLV_DB_MINMAX(adau193x_tlv, -9563, 0);
+static const unsigned int ad193x_sb[] = {32}; + +static struct snd_pcm_hw_constraint_list constr = { + .list = ad193x_sb, + .count = ARRAY_SIZE(ad193x_sb), +}; + static const struct snd_kcontrol_new ad193x_snd_controls[] = { /* DAC volume control */ SOC_DOUBLE_R_TLV("DAC1 Volume", AD193X_DAC_L1_VOL, @@ -321,7 +328,16 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream, return 0; }
+static int ad193x_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + return snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_SAMPLE_BITS, + &constr); +} + static const struct snd_soc_dai_ops ad193x_dai_ops = { + .startup = ad193x_startup, .hw_params = ad193x_hw_params, .digital_mute = ad193x_mute, .set_tdm_slot = ad193x_set_tdm_slot,
From: Codrin Ciubotariu codrin.ciubotariu@microchip.com
By default, the codec starts to interpret the left (first) channel on the falling edge (low polarity) of LRCLK. However, for DSP_A, the left channel needs to start on the rising edge of LRCLK. This patch fixes this channel swap by toggling the bit which selects the LRCLK polarity.
Signed-off-by: Codrin Ciubotariu codrin.ciubotariu@microchip.com --- sound/soc/codecs/ad193x.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index c16c9969d1a0..315ec9775118 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -228,6 +228,12 @@ static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai, return -EINVAL; }
+ /* For DSP_*, LRCLK's polarity must be inverted */ + if (fmt & SND_SOC_DAIFMT_DSP_A) { + change_bit(ffs(AD193X_DAC_LEFT_HIGH) - 1, + (unsigned long *)&dac_fmt); + } + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & frm master */ adc_fmt |= AD193X_ADC_LCR_MASTER;
The patch
ASoC: codecs: ad193x: Fix frame polarity for DSP_A format
has been applied to the asoc tree at
https://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 90f6e68031397fb6212bef5619193cd15707fa0f Mon Sep 17 00:00:00 2001
From: Codrin Ciubotariu codrin.ciubotariu@microchip.com Date: Mon, 18 Feb 2019 16:10:32 +0000 Subject: [PATCH] ASoC: codecs: ad193x: Fix frame polarity for DSP_A format
By default, the codec starts to interpret the left (first) channel on the falling edge (low polarity) of LRCLK. However, for DSP_A, the left channel needs to start on the rising edge of LRCLK. This patch fixes this channel swap by toggling the bit which selects the LRCLK polarity.
Signed-off-by: Codrin Ciubotariu codrin.ciubotariu@microchip.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/codecs/ad193x.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index c16c9969d1a0..315ec9775118 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -228,6 +228,12 @@ static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai, return -EINVAL; }
+ /* For DSP_*, LRCLK's polarity must be inverted */ + if (fmt & SND_SOC_DAIFMT_DSP_A) { + change_bit(ffs(AD193X_DAC_LEFT_HIGH) - 1, + (unsigned long *)&dac_fmt); + } + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & frm master */ adc_fmt |= AD193X_ADC_LCR_MASTER;
From: Codrin Ciubotariu codrin.ciubotariu@microchip.com
The driver only supports DPS_A for DAC, which is configured at probe. This patch adds support for DSP_A and I2S modes by using the set_fmt() callback.
A trivial break is also removed from a case's default branch.
Signed-off-by: Codrin Ciubotariu codrin.ciubotariu@microchip.com --- sound/soc/codecs/ad193x.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index 315ec9775118..f8cf182518a3 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -188,23 +188,26 @@ static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai, { struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(codec_dai->component); unsigned int adc_serfmt = 0; + unsigned int dac_serfmt = 0; unsigned int adc_fmt = 0; unsigned int dac_fmt = 0;
/* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S - * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A) + * with TDM), ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A) and DAC I2S mode + * (SND_SOC_DAIFMT_I2S) */ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: adc_serfmt |= AD193X_ADC_SERFMT_TDM; + dac_serfmt |= AD193X_DAC_SERFMT_STEREO; break; case SND_SOC_DAIFMT_DSP_A: adc_serfmt |= AD193X_ADC_SERFMT_AUX; + dac_serfmt |= AD193X_DAC_SERFMT_TDM; break; default: if (ad193x_has_adc(ad193x)) return -EINVAL; - break; }
switch (fmt & SND_SOC_DAIFMT_INV_MASK) { @@ -261,6 +264,8 @@ static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai, regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2, AD193X_ADC_FMT_MASK, adc_fmt); } + regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL0, + AD193X_DAC_SERFMT_MASK, dac_serfmt); regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1, AD193X_DAC_FMT_MASK, dac_fmt);
The patch
ASoC: codecs: ad193x: Add runtime support for DSP_A and I2S modes
has been applied to the asoc tree at
https://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 bccf9c7e14830af0004399d42d861b33c92eacff Mon Sep 17 00:00:00 2001
From: Codrin Ciubotariu codrin.ciubotariu@microchip.com Date: Mon, 18 Feb 2019 16:10:34 +0000 Subject: [PATCH] ASoC: codecs: ad193x: Add runtime support for DSP_A and I2S modes
The driver only supports DPS_A for DAC, which is configured at probe. This patch adds support for DSP_A and I2S modes by using the set_fmt() callback.
A trivial break is also removed from a case's default branch.
Signed-off-by: Codrin Ciubotariu codrin.ciubotariu@microchip.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/codecs/ad193x.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index 315ec9775118..f8cf182518a3 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -188,23 +188,26 @@ static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai, { struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(codec_dai->component); unsigned int adc_serfmt = 0; + unsigned int dac_serfmt = 0; unsigned int adc_fmt = 0; unsigned int dac_fmt = 0;
/* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S - * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A) + * with TDM), ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A) and DAC I2S mode + * (SND_SOC_DAIFMT_I2S) */ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: adc_serfmt |= AD193X_ADC_SERFMT_TDM; + dac_serfmt |= AD193X_DAC_SERFMT_STEREO; break; case SND_SOC_DAIFMT_DSP_A: adc_serfmt |= AD193X_ADC_SERFMT_AUX; + dac_serfmt |= AD193X_DAC_SERFMT_TDM; break; default: if (ad193x_has_adc(ad193x)) return -EINVAL; - break; }
switch (fmt & SND_SOC_DAIFMT_INV_MASK) { @@ -261,6 +264,8 @@ static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai, regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2, AD193X_ADC_FMT_MASK, adc_fmt); } + regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL0, + AD193X_DAC_SERFMT_MASK, dac_serfmt); regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1, AD193X_DAC_FMT_MASK, dac_fmt);
From: Codrin Ciubotariu codrin.ciubotariu@microchip.com
The on-chip PLL can be disabled if on the MCLKI pin we have an external clock at 512 x fs. This clock can be used as direct internal clock for ADCs or DACs. To support this, we add an extra clock id that can be configured using the set_sysclk() callback.
Signed-off-by: Codrin Ciubotariu codrin.ciubotariu@microchip.com --- sound/soc/codecs/ad193x.c | 26 +++++++++++++++++++++++++- sound/soc/codecs/ad193x.h | 8 ++++++++ 2 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index f8cf182518a3..96d7cb2e4a56 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -100,6 +100,15 @@ static const struct snd_soc_dapm_widget ad193x_adc_widgets[] = { SND_SOC_DAPM_INPUT("ADC2IN"), };
+static int ad193x_check_pll(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm); + struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component); + + return !!ad193x->sysclk; +} + static const struct snd_soc_dapm_route audio_paths[] = { { "DAC", NULL, "SYSCLK" }, { "DAC Output", NULL, "DAC" }, @@ -108,7 +117,7 @@ static const struct snd_soc_dapm_route audio_paths[] = { { "DAC2OUT", NULL, "DAC Output" }, { "DAC3OUT", NULL, "DAC Output" }, { "DAC4OUT", NULL, "DAC Output" }, - { "SYSCLK", NULL, "PLL_PWR" }, + { "SYSCLK", NULL, "PLL_PWR", &ad193x_check_pll }, };
static const struct snd_soc_dapm_route ad193x_adc_audio_paths[] = { @@ -276,7 +285,22 @@ static int ad193x_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, unsigned int freq, int dir) { struct snd_soc_component *component = codec_dai->component; + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component); + + if (clk_id == AD193X_SYSCLK_MCLK) { + /* MCLK must be 512 x fs */ + if (dir == SND_SOC_CLOCK_OUT || freq != 24576000) + return -EINVAL; + + regmap_update_bits(ad193x->regmap, AD193X_PLL_CLK_CTRL1, + AD193X_PLL_SRC_MASK, + AD193X_PLL_DAC_SRC_MCLK | + AD193X_PLL_CLK_SRC_MCLK); + + snd_soc_dapm_sync(dapm); + return 0; + } switch (freq) { case 12288000: case 18432000: diff --git a/sound/soc/codecs/ad193x.h b/sound/soc/codecs/ad193x.h index 8b1e65f928d2..27d6afbd7dfb 100644 --- a/sound/soc/codecs/ad193x.h +++ b/sound/soc/codecs/ad193x.h @@ -31,6 +31,11 @@ int ad193x_probe(struct device *dev, struct regmap *regmap, #define AD193X_PLL_INPUT_512 (2 << 1) #define AD193X_PLL_INPUT_768 (3 << 1) #define AD193X_PLL_CLK_CTRL1 0x01 +#define AD193X_PLL_SRC_MASK 0x03 +#define AD193X_PLL_DAC_SRC_PLL 0 +#define AD193X_PLL_DAC_SRC_MCLK 1 +#define AD193X_PLL_CLK_SRC_PLL (0 << 1) +#define AD193X_PLL_CLK_SRC_MCLK (1 << 1) #define AD193X_DAC_CTRL0 0x02 #define AD193X_DAC_POWERDOWN 0x01 #define AD193X_DAC_SERFMT_MASK 0xC0 @@ -96,4 +101,7 @@ int ad193x_probe(struct device *dev, struct regmap *regmap,
#define AD193X_NUM_REGS 17
+#define AD193X_SYSCLK_PLL 0 +#define AD193X_SYSCLK_MCLK 1 + #endif
The patch
ASoC: codecs: ad193x: Add support to disable on-chip PLL
has been applied to the asoc tree at
https://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 59529473751e987e28c926838f70aaef588b83b0 Mon Sep 17 00:00:00 2001
From: Codrin Ciubotariu codrin.ciubotariu@microchip.com Date: Mon, 18 Feb 2019 16:10:36 +0000 Subject: [PATCH] ASoC: codecs: ad193x: Add support to disable on-chip PLL
The on-chip PLL can be disabled if on the MCLKI pin we have an external clock at 512 x fs. This clock can be used as direct internal clock for ADCs or DACs. To support this, we add an extra clock id that can be configured using the set_sysclk() callback.
Signed-off-by: Codrin Ciubotariu codrin.ciubotariu@microchip.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/codecs/ad193x.c | 26 +++++++++++++++++++++++++- sound/soc/codecs/ad193x.h | 8 ++++++++ 2 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index f8cf182518a3..96d7cb2e4a56 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -100,6 +100,15 @@ static const struct snd_soc_dapm_widget ad193x_adc_widgets[] = { SND_SOC_DAPM_INPUT("ADC2IN"), };
+static int ad193x_check_pll(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm); + struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component); + + return !!ad193x->sysclk; +} + static const struct snd_soc_dapm_route audio_paths[] = { { "DAC", NULL, "SYSCLK" }, { "DAC Output", NULL, "DAC" }, @@ -108,7 +117,7 @@ static const struct snd_soc_dapm_route audio_paths[] = { { "DAC2OUT", NULL, "DAC Output" }, { "DAC3OUT", NULL, "DAC Output" }, { "DAC4OUT", NULL, "DAC Output" }, - { "SYSCLK", NULL, "PLL_PWR" }, + { "SYSCLK", NULL, "PLL_PWR", &ad193x_check_pll }, };
static const struct snd_soc_dapm_route ad193x_adc_audio_paths[] = { @@ -276,7 +285,22 @@ static int ad193x_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, unsigned int freq, int dir) { struct snd_soc_component *component = codec_dai->component; + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component); + + if (clk_id == AD193X_SYSCLK_MCLK) { + /* MCLK must be 512 x fs */ + if (dir == SND_SOC_CLOCK_OUT || freq != 24576000) + return -EINVAL; + + regmap_update_bits(ad193x->regmap, AD193X_PLL_CLK_CTRL1, + AD193X_PLL_SRC_MASK, + AD193X_PLL_DAC_SRC_MCLK | + AD193X_PLL_CLK_SRC_MCLK); + + snd_soc_dapm_sync(dapm); + return 0; + } switch (freq) { case 12288000: case 18432000: diff --git a/sound/soc/codecs/ad193x.h b/sound/soc/codecs/ad193x.h index 8b1e65f928d2..27d6afbd7dfb 100644 --- a/sound/soc/codecs/ad193x.h +++ b/sound/soc/codecs/ad193x.h @@ -31,6 +31,11 @@ int ad193x_probe(struct device *dev, struct regmap *regmap, #define AD193X_PLL_INPUT_512 (2 << 1) #define AD193X_PLL_INPUT_768 (3 << 1) #define AD193X_PLL_CLK_CTRL1 0x01 +#define AD193X_PLL_SRC_MASK 0x03 +#define AD193X_PLL_DAC_SRC_PLL 0 +#define AD193X_PLL_DAC_SRC_MCLK 1 +#define AD193X_PLL_CLK_SRC_PLL (0 << 1) +#define AD193X_PLL_CLK_SRC_MCLK (1 << 1) #define AD193X_DAC_CTRL0 0x02 #define AD193X_DAC_POWERDOWN 0x01 #define AD193X_DAC_SERFMT_MASK 0xC0 @@ -96,4 +101,7 @@ int ad193x_probe(struct device *dev, struct regmap *regmap,
#define AD193X_NUM_REGS 17
+#define AD193X_SYSCLK_PLL 0 +#define AD193X_SYSCLK_MCLK 1 + #endif
On 18.02.2019 18:10, Codrin Ciubotariu - M19940 wrote:
From: Codrin Ciubotariu codrin.ciubotariu@microchip.com
This patch set contains some changes I needed to make I2S and TDM (DSP_A) formats work. I tested only with ad1936, but the patches
actually, it's ad1934. Sorry about that.
Best regards, Codrin
should work fine for all the codecs that use this driver. Although I checked the DS for all of them (I hope) to assure that the patches apply, I would really appreciate if someone else can test them on another codec.
Codrin Ciubotariu (5): ASoC: codecs: ad193x: Remove capture support for codecs without ADC ASoC: codecs: ad193x: Set constraint to always have 32 sample bits ASoC: codecs: ad193x: Fix frame polarity for DSP_A format ASoC: codecs: ad193x: Add runtime support for DSP_A and I2S modes ASoC: codecs: ad193x: Add support to disable on-chip PLL
sound/soc/codecs/ad193x.c | 76 ++++++++++++++++++++++++++++++++++++--- sound/soc/codecs/ad193x.h | 8 +++++ 2 files changed, 80 insertions(+), 4 deletions(-)
participants (2)
-
Codrin.Ciubotariu@microchip.com
-
Mark Brown