[PATCH v5 3/6] ASoC: tegra: Add audio graph based card driver

Jon Hunter jonathanh at nvidia.com
Mon Nov 23 11:35:33 CET 2020


On 11/11/2020 18:34, Sameer Pujar wrote:
> Add Tegra audio machine driver which is based on generic audio graph card
> driver. It re-uses most of the common stuff from audio graph driver and
> uses the same DT binding. Required Tegra specific customizations are done
> in the driver and additional DT bindings are required for clock handling.
> 
> Details on the customizations done:
> 
>  - Update PLL rates at runtime: Tegra HW supports multiple sample rates
>    (multiples of 8x and 11.025x) and both of these groups require different
>    PLL rates. Hence there is a requirement to update this at runtime.
>    This is achieved by providing a custom 'snd_soc_ops' and in hw_param()
>    callback PLL rate is updated as per the sample rate.
> 
>  - Internal structure 'tegra_audio_graph_data' is used to maintain clock
>    handles of PLL.
> 
>  - The 'force_dpcm' flag is set to use DPCM for all DAI links.
> 
>  - The 'component_chaining' flag is set to use DPCM with component model.
> 
> Signed-off-by: Sameer Pujar <spujar at nvidia.com>
> ---
>  sound/soc/tegra/Kconfig                  |   9 ++
>  sound/soc/tegra/Makefile                 |   2 +
>  sound/soc/tegra/tegra_audio_graph_card.c | 255 +++++++++++++++++++++++++++++++
>  3 files changed, 266 insertions(+)
>  create mode 100644 sound/soc/tegra/tegra_audio_graph_card.c
> 
> diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
> index a62cc87..6dc83ad 100644
> --- a/sound/soc/tegra/Kconfig
> +++ b/sound/soc/tegra/Kconfig
> @@ -117,6 +117,15 @@ config SND_SOC_TEGRA210_ADMAIF
>  	  channel. Buffer size is configurable for each ADMAIIF channel.
>  	  Say Y or M if you want to add support for Tegra210 ADMAIF module.
>  
> +config SND_SOC_TEGRA_AUDIO_GRAPH_CARD
> +	tristate "Audio Graph Card based Tegra driver"
> +	depends on SND_AUDIO_GRAPH_CARD
> +	help
> +	  Config to enable Tegra audio machine driver based on generic
> +	  audio graph driver. It is a thin driver written to customize
> +	  few things for Tegra audio. Most of the code is re-used from
> +	  audio graph driver and the same DT bindings are used.
> +
>  config SND_SOC_TEGRA_RT5640
>  	tristate "SoC Audio support for Tegra boards using an RT5640 codec"
>  	depends on SND_SOC_TEGRA && I2C && GPIOLIB
> diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
> index 60040a0..b17dd6e 100644
> --- a/sound/soc/tegra/Makefile
> +++ b/sound/soc/tegra/Makefile
> @@ -38,6 +38,7 @@ snd-soc-tegra-trimslice-objs := trimslice.o
>  snd-soc-tegra-alc5632-objs := tegra_alc5632.o
>  snd-soc-tegra-max98090-objs := tegra_max98090.o
>  snd-soc-tegra-sgtl5000-objs := tegra_sgtl5000.o
> +snd-soc-tegra-audio-graph-card-objs := tegra_audio_graph_card.o
>  
>  obj-$(CONFIG_SND_SOC_TEGRA_RT5640) += snd-soc-tegra-rt5640.o
>  obj-$(CONFIG_SND_SOC_TEGRA_RT5677) += snd-soc-tegra-rt5677.o
> @@ -48,3 +49,4 @@ obj-$(CONFIG_SND_SOC_TEGRA_TRIMSLICE) += snd-soc-tegra-trimslice.o
>  obj-$(CONFIG_SND_SOC_TEGRA_ALC5632) += snd-soc-tegra-alc5632.o
>  obj-$(CONFIG_SND_SOC_TEGRA_MAX98090) += snd-soc-tegra-max98090.o
>  obj-$(CONFIG_SND_SOC_TEGRA_SGTL5000) += snd-soc-tegra-sgtl5000.o
> +obj-$(CONFIG_SND_SOC_TEGRA_AUDIO_GRAPH_CARD) += snd-soc-tegra-audio-graph-card.o
> diff --git a/sound/soc/tegra/tegra_audio_graph_card.c b/sound/soc/tegra/tegra_audio_graph_card.c
> new file mode 100644
> index 0000000..f4d826d
> --- /dev/null
> +++ b/sound/soc/tegra/tegra_audio_graph_card.c
> @@ -0,0 +1,255 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +//
> +// tegra_audio_graph_card.c - Audio Graph based Tegra Machine Driver
> +//
> +// Copyright (c) 2020 NVIDIA CORPORATION.  All rights reserved.
> +
> +#include <linux/math64.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <sound/graph_card.h>
> +#include <sound/pcm_params.h>
> +
> +#define MAX_PLLA_OUT0_DIV 128
> +
> +#define simple_to_tegra_priv(simple) \
> +		container_of(simple, struct tegra_audio_priv, simple)
> +
> +enum srate_type {
> +	/*
> +	 * Sample rates multiple of 8000 Hz and below are supported:
> +	 * ( 8000, 16000, 32000, 48000, 96000, 192000 Hz )
> +	 */
> +	x8_RATE,
> +
> +	/*
> +	 * Sample rates multiple of 11025 Hz and below are supported:
> +	 * ( 11025, 22050, 44100, 88200, 176400 Hz )
> +	 */
> +	x11_RATE,
> +
> +	NUM_RATE_TYPE,
> +};
> +
> +struct tegra_audio_priv {
> +	struct asoc_simple_priv simple;
> +	struct clk *clk_plla_out0;
> +	struct clk *clk_plla;
> +};
> +
> +/* Tegra audio chip data */
> +struct tegra_audio_cdata {
> +	unsigned int plla_rates[NUM_RATE_TYPE];
> +	unsigned int plla_out0_rates[NUM_RATE_TYPE];
> +};
> +
> +/* Setup PLL clock as per the given sample rate */
> +static int tegra_audio_graph_update_pll(struct snd_pcm_substream *substream,
> +					struct snd_pcm_hw_params *params)
> +{
> +	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
> +	struct asoc_simple_priv *simple = snd_soc_card_get_drvdata(rtd->card);
> +	struct tegra_audio_priv *priv = simple_to_tegra_priv(simple);
> +	struct device *dev = rtd->card->dev;
> +	const struct tegra_audio_cdata *data = of_device_get_match_data(dev);
> +	unsigned int plla_rate, plla_out0_rate, bclk;
> +	unsigned int srate = params_rate(params);
> +	int err;
> +
> +	/* There is nothing to configure */
> +	if (!data)
> +		return 0;


Seems like this should never happen and so if it did this is an error.
Any reason why we don't return an error here?

Cheers
Jon

-- 
nvpublic


More information about the Alsa-devel mailing list