[alsa-devel] [PATCH 1/2] ASoC: pcm512x: Implement the set_bclk_ratio interface
Peter Rosin
peda at axentia.se
Sat Jan 26 19:48:26 CET 2019
On 2019-01-26 14:17, Dimitris Papavasiliou wrote:
> Some boards, such as the HiFiBerry DAC+ Pro, use a pair of external
> oscillators, to generate 44.1 or 48kHz multiples and are forced to
> resort to hacks [1] in order to support 24-bit data without ending up
> with fractional dividers. This patch allows the machine driver to use
> 32-bit frames for 24-bit data to avoid such issues.
>
> Although the datasheet (p. 15) seems to suggest that only a handful
> of ratios are supported, it's not very explicit about it, so we allow
> the full range of values supported by the underlying register in the
> callback, to avoid needlessly rejecting potentially usable
> configurations.
>
> [1] http://mailman.alsa-project.org/pipermail/alsa-devel/2018-December/143442.html
>
> Signed-off-by: Dimitris Papavasiliou <dpapavas at gmail.com>
> ---
>
> Notes:
> This is essentially the same patch submitted previously as an RFC[1].
> It has been split in two, in order to separate the set_bclk_ratio
> implementation from the clocking calculation fix and some conservative
> checking has been added to the argument of the callback.
>
> [1] http://mailman.alsa-project.org/pipermail/alsa-devel/2019-January/144213.html
>
> sound/soc/codecs/pcm512x.c | 28 ++++++++++++++++++++++++----
> 1 file changed, 24 insertions(+), 4 deletions(-)
>
> diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c
> index 6cb1653be804..b63d9392bae3 100644
> --- a/sound/soc/codecs/pcm512x.c
> +++ b/sound/soc/codecs/pcm512x.c
> @@ -55,6 +55,7 @@ struct pcm512x_priv {
> unsigned long overclock_dsp;
> int mute;
> struct mutex mutex;
> + unsigned int bclk_ratio;
> };
>
> /*
> @@ -915,10 +916,15 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai,
> int fssp;
> int gpio;
>
> - lrclk_div = snd_soc_params_to_frame_size(params);
> - if (lrclk_div == 0) {
> - dev_err(dev, "No LRCLK?\n");
> - return -EINVAL;
> + if (pcm512x->bclk_ratio > 0) {
> + lrclk_div = pcm512x->bclk_ratio;
> + } else {
> + lrclk_div = snd_soc_params_to_frame_size(params);
> +
> + if (lrclk_div == 0) {
> + dev_err(dev, "No LRCLK?\n");
> + return -EINVAL;
> + }
> }
>
> if (!pcm512x->pll_out) {
> @@ -1383,6 +1389,19 @@ static int pcm512x_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
> return 0;
> }
>
> +static int pcm512x_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
> +{
> + struct snd_soc_component *component = dai->component;
> + struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
> +
> + if (ratio > 256)
> + return -EINVAL;
ratio == 0 should also generate -EINVAL.
Cheers,
Peter
> +
> + pcm512x->bclk_ratio = ratio;
> +
> + return 0;
> +}
> +
> static int pcm512x_digital_mute(struct snd_soc_dai *dai, int mute)
> {
> struct snd_soc_component *component = dai->component;
> @@ -1438,6 +1457,7 @@ static const struct snd_soc_dai_ops pcm512x_dai_ops = {
> .hw_params = pcm512x_hw_params,
> .set_fmt = pcm512x_set_fmt,
> .digital_mute = pcm512x_digital_mute,
> + .set_bclk_ratio = pcm512x_set_bclk_ratio,
> };
>
> static struct snd_soc_dai_driver pcm512x_dai = {
>
More information about the Alsa-devel
mailing list