Re: [PATCH v4 3/4] ASoC: qcom: sm8250: move some code to common

From: Bjorn Andersson
Date: Thu Sep 15 2022 - 13:24:54 EST


On Thu, Sep 15, 2022 at 01:56:10PM +0100, Srinivas Kandagatla wrote:
> SM8450 machine driver code can be reused across multiple Qualcomm SoCs,
> At least another 2 of them for now (SM8450 and SM8250XP).

s/SM8250XP/SC8280XP/

Regards,
Bjorn

>
> Move some of the common SoundWire stream specific code to common file
> so that other drivers can use it instead of duplication.
>
> This patch is to prepare the common driver to be able to add new SoCs support
> with less dupication.
>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@xxxxxxxxxx>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@xxxxxxxxxx>
> ---
> sound/soc/qcom/common.c | 171 ++++++++++++++++++++++++++++++++++++++++
> sound/soc/qcom/common.h | 35 ++++++++
> sound/soc/qcom/sm8250.c | 152 ++---------------------------------
> 3 files changed, 213 insertions(+), 145 deletions(-)
>
> diff --git a/sound/soc/qcom/common.c b/sound/soc/qcom/common.c
> index e53ad84f8ff5..69dd3b504e20 100644
> --- a/sound/soc/qcom/common.c
> +++ b/sound/soc/qcom/common.c
> @@ -3,6 +3,9 @@
> // Copyright (c) 2018, The Linux Foundation. All rights reserved.
>
> #include <linux/module.h>
> +#include <sound/jack.h>
> +#include <linux/input-event-codes.h>
> +#include "qdsp6/q6afe.h"
> #include "common.h"
>
> int qcom_snd_parse_of(struct snd_soc_card *card)
> @@ -177,4 +180,172 @@ int qcom_snd_parse_of(struct snd_soc_card *card)
> }
> EXPORT_SYMBOL_GPL(qcom_snd_parse_of);
>
> +#if IS_ENABLED(CONFIG_SOUNDWIRE)
> +int qcom_snd_sdw_prepare(struct snd_pcm_substream *substream,
> + struct sdw_stream_runtime *sruntime,
> + bool *stream_prepared)
> +{
> + struct snd_soc_pcm_runtime *rtd = substream->private_data;
> + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
> + int ret;
> +
> + if (!sruntime)
> + return 0;
> +
> + switch (cpu_dai->id) {
> + case WSA_CODEC_DMA_RX_0:
> + case WSA_CODEC_DMA_RX_1:
> + case RX_CODEC_DMA_RX_0:
> + case RX_CODEC_DMA_RX_1:
> + case TX_CODEC_DMA_TX_0:
> + case TX_CODEC_DMA_TX_1:
> + case TX_CODEC_DMA_TX_2:
> + case TX_CODEC_DMA_TX_3:
> + break;
> + default:
> + return 0;
> + }
> +
> + if (*stream_prepared) {
> + sdw_disable_stream(sruntime);
> + sdw_deprepare_stream(sruntime);
> + *stream_prepared = false;
> + }
> +
> + ret = sdw_prepare_stream(sruntime);
> + if (ret)
> + return ret;
> +
> + /**
> + * NOTE: there is a strict hw requirement about the ordering of port
> + * enables and actual WSA881x PA enable. PA enable should only happen
> + * after soundwire ports are enabled if not DC on the line is
> + * accumulated resulting in Click/Pop Noise
> + * PA enable/mute are handled as part of codec DAPM and digital mute.
> + */
> +
> + ret = sdw_enable_stream(sruntime);
> + if (ret) {
> + sdw_deprepare_stream(sruntime);
> + return ret;
> + }
> + *stream_prepared = true;
> +
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(qcom_snd_sdw_prepare);
> +
> +int qcom_snd_sdw_hw_params(struct snd_pcm_substream *substream,
> + struct snd_pcm_hw_params *params,
> + struct sdw_stream_runtime **psruntime)
> +{
> + struct snd_soc_pcm_runtime *rtd = substream->private_data;
> + struct snd_soc_dai *codec_dai;
> + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
> + struct sdw_stream_runtime *sruntime;
> + int i;
> +
> + switch (cpu_dai->id) {
> + case WSA_CODEC_DMA_RX_0:
> + case RX_CODEC_DMA_RX_0:
> + case RX_CODEC_DMA_RX_1:
> + case TX_CODEC_DMA_TX_0:
> + case TX_CODEC_DMA_TX_1:
> + case TX_CODEC_DMA_TX_2:
> + case TX_CODEC_DMA_TX_3:
> + for_each_rtd_codec_dais(rtd, i, codec_dai) {
> + sruntime = snd_soc_dai_get_stream(codec_dai, substream->stream);
> + if (sruntime != ERR_PTR(-ENOTSUPP))
> + *psruntime = sruntime;
> + }
> + break;
> + }
> +
> + return 0;
> +
> +}
> +EXPORT_SYMBOL_GPL(qcom_snd_sdw_hw_params);
> +
> +int qcom_snd_sdw_hw_free(struct snd_pcm_substream *substream,
> + struct sdw_stream_runtime *sruntime, bool *stream_prepared)
> +{
> + struct snd_soc_pcm_runtime *rtd = substream->private_data;
> + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
> +
> + switch (cpu_dai->id) {
> + case WSA_CODEC_DMA_RX_0:
> + case WSA_CODEC_DMA_RX_1:
> + case RX_CODEC_DMA_RX_0:
> + case RX_CODEC_DMA_RX_1:
> + case TX_CODEC_DMA_TX_0:
> + case TX_CODEC_DMA_TX_1:
> + case TX_CODEC_DMA_TX_2:
> + case TX_CODEC_DMA_TX_3:
> + if (sruntime && *stream_prepared) {
> + sdw_disable_stream(sruntime);
> + sdw_deprepare_stream(sruntime);
> + *stream_prepared = false;
> + }
> + break;
> + default:
> + break;
> + }
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(qcom_snd_sdw_hw_free);
> +#endif
> +
> +int qcom_snd_wcd_jack_setup(struct snd_soc_pcm_runtime *rtd,
> + struct snd_soc_jack *jack, bool *jack_setup)
> +{
> + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
> + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
> + struct snd_soc_card *card = rtd->card;
> + int rval, i;
> +
> + if (!*jack_setup) {
> + rval = snd_soc_card_jack_new(card, "Headset Jack",
> + SND_JACK_HEADSET | SND_JACK_LINEOUT |
> + SND_JACK_MECHANICAL |
> + SND_JACK_BTN_0 | SND_JACK_BTN_1 |
> + SND_JACK_BTN_2 | SND_JACK_BTN_3 |
> + SND_JACK_BTN_4 | SND_JACK_BTN_5,
> + jack);
> +
> + if (rval < 0) {
> + dev_err(card->dev, "Unable to add Headphone Jack\n");
> + return rval;
> + }
> +
> + snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA);
> + snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
> + snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
> + snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
> + *jack_setup = true;
> + }
> +
> + switch (cpu_dai->id) {
> + case TX_CODEC_DMA_TX_0:
> + case TX_CODEC_DMA_TX_1:
> + case TX_CODEC_DMA_TX_2:
> + case TX_CODEC_DMA_TX_3:
> + for_each_rtd_codec_dais(rtd, i, codec_dai) {
> + rval = snd_soc_component_set_jack(codec_dai->component,
> + jack, NULL);
> + if (rval != 0 && rval != -ENOTSUPP) {
> + dev_warn(card->dev, "Failed to set jack: %d\n", rval);
> + return rval;
> + }
> + }
> +
> + break;
> + default:
> + break;
> + }
> +
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(qcom_snd_wcd_jack_setup);
> MODULE_LICENSE("GPL v2");
> diff --git a/sound/soc/qcom/common.h b/sound/soc/qcom/common.h
> index f05c05b12bd7..c5472a642de0 100644
> --- a/sound/soc/qcom/common.h
> +++ b/sound/soc/qcom/common.h
> @@ -5,7 +5,42 @@
> #define __QCOM_SND_COMMON_H__
>
> #include <sound/soc.h>
> +#include <linux/soundwire/sdw.h>
>
> int qcom_snd_parse_of(struct snd_soc_card *card);
> +int qcom_snd_wcd_jack_setup(struct snd_soc_pcm_runtime *rtd,
> + struct snd_soc_jack *jack, bool *jack_setup);
>
> +#if IS_ENABLED(CONFIG_SOUNDWIRE)
> +int qcom_snd_sdw_prepare(struct snd_pcm_substream *substream,
> + struct sdw_stream_runtime *runtime,
> + bool *stream_prepared);
> +int qcom_snd_sdw_hw_params(struct snd_pcm_substream *substream,
> + struct snd_pcm_hw_params *params,
> + struct sdw_stream_runtime **psruntime);
> +int qcom_snd_sdw_hw_free(struct snd_pcm_substream *substream,
> + struct sdw_stream_runtime *sruntime,
> + bool *stream_prepared);
> +#else
> +static inline int qcom_snd_sdw_prepare(struct snd_pcm_substream *substream,
> + struct sdw_stream_runtime *runtime,
> + bool *stream_prepared)
> +{
> + return -ENOTSUPP;
> +}
> +
> +static inline int qcom_snd_sdw_hw_params(struct snd_pcm_substream *substream,
> + struct snd_pcm_hw_params *params,
> + struct sdw_stream_runtime **psruntime)
> +{
> + return -ENOTSUPP;
> +}
> +
> +static inline int qcom_snd_sdw_hw_free(struct snd_pcm_substream *substream,
> + struct sdw_stream_runtime *sruntime,
> + bool *stream_prepared)
> +{
> + return -ENOTSUPP;
> +}
> +#endif
> #endif
> diff --git a/sound/soc/qcom/sm8250.c b/sound/soc/qcom/sm8250.c
> index 98a2fde9e004..8dbe9ef41b1c 100644
> --- a/sound/soc/qcom/sm8250.c
> +++ b/sound/soc/qcom/sm8250.c
> @@ -27,57 +27,8 @@ struct sm8250_snd_data {
> static int sm8250_snd_init(struct snd_soc_pcm_runtime *rtd)
> {
> struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
> - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
> - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
> - struct snd_soc_card *card = rtd->card;
> - int rval, i;
> -
> - if (!data->jack_setup) {
> - struct snd_jack *jack;
> -
> - rval = snd_soc_card_jack_new(card, "Headset Jack",
> - SND_JACK_HEADSET | SND_JACK_LINEOUT |
> - SND_JACK_MECHANICAL |
> - SND_JACK_BTN_0 | SND_JACK_BTN_1 |
> - SND_JACK_BTN_2 | SND_JACK_BTN_3 |
> - SND_JACK_BTN_4 | SND_JACK_BTN_5,
> - &data->jack);
> -
> - if (rval < 0) {
> - dev_err(card->dev, "Unable to add Headphone Jack\n");
> - return rval;
> - }
> -
> - jack = data->jack.jack;
> -
> - snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_MEDIA);
> - snd_jack_set_key(jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
> - snd_jack_set_key(jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
> - snd_jack_set_key(jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
> - data->jack_setup = true;
> - }
> -
> - switch (cpu_dai->id) {
> - case TX_CODEC_DMA_TX_0:
> - case TX_CODEC_DMA_TX_1:
> - case TX_CODEC_DMA_TX_2:
> - case TX_CODEC_DMA_TX_3:
> - for_each_rtd_codec_dais(rtd, i, codec_dai) {
> - rval = snd_soc_component_set_jack(codec_dai->component,
> - &data->jack, NULL);
> - if (rval != 0 && rval != -ENOTSUPP) {
> - dev_warn(card->dev, "Failed to set jack: %d\n", rval);
> - return rval;
> - }
> - }
> -
> - break;
> - default:
> - break;
> - }
>
> -
> - return 0;
> + return qcom_snd_wcd_jack_setup(rtd, &data->jack, &data->jack_setup);
> }
>
> static int sm8250_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
> @@ -121,92 +72,21 @@ static int sm8250_snd_hw_params(struct snd_pcm_substream *substream,
> struct snd_pcm_hw_params *params)
> {
> struct snd_soc_pcm_runtime *rtd = substream->private_data;
> - struct snd_soc_dai *codec_dai;
> struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
> struct sm8250_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card);
> - struct sdw_stream_runtime *sruntime;
> - int i;
> -
> - switch (cpu_dai->id) {
> - case WSA_CODEC_DMA_RX_0:
> - case RX_CODEC_DMA_RX_0:
> - case RX_CODEC_DMA_RX_1:
> - case TX_CODEC_DMA_TX_0:
> - case TX_CODEC_DMA_TX_1:
> - case TX_CODEC_DMA_TX_2:
> - case TX_CODEC_DMA_TX_3:
> - for_each_rtd_codec_dais(rtd, i, codec_dai) {
> - sruntime = snd_soc_dai_get_stream(codec_dai,
> - substream->stream);
> - if (sruntime != ERR_PTR(-ENOTSUPP))
> - pdata->sruntime[cpu_dai->id] = sruntime;
> - }
> - break;
> - }
> -
> - return 0;
>
> + return qcom_snd_sdw_hw_params(substream, params, &pdata->sruntime[cpu_dai->id]);
> }
>
> -static int sm8250_snd_wsa_dma_prepare(struct snd_pcm_substream *substream)
> +static int sm8250_snd_prepare(struct snd_pcm_substream *substream)
> {
> struct snd_soc_pcm_runtime *rtd = substream->private_data;
> struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
> struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
> struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
> - int ret;
> -
> - if (!sruntime)
> - return 0;
>
> - if (data->stream_prepared[cpu_dai->id]) {
> - sdw_disable_stream(sruntime);
> - sdw_deprepare_stream(sruntime);
> - data->stream_prepared[cpu_dai->id] = false;
> - }
> -
> - ret = sdw_prepare_stream(sruntime);
> - if (ret)
> - return ret;
> -
> - /**
> - * NOTE: there is a strict hw requirement about the ordering of port
> - * enables and actual WSA881x PA enable. PA enable should only happen
> - * after soundwire ports are enabled if not DC on the line is
> - * accumulated resulting in Click/Pop Noise
> - * PA enable/mute are handled as part of codec DAPM and digital mute.
> - */
> -
> - ret = sdw_enable_stream(sruntime);
> - if (ret) {
> - sdw_deprepare_stream(sruntime);
> - return ret;
> - }
> - data->stream_prepared[cpu_dai->id] = true;
> -
> - return ret;
> -}
> -
> -static int sm8250_snd_prepare(struct snd_pcm_substream *substream)
> -{
> - struct snd_soc_pcm_runtime *rtd = substream->private_data;
> - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
> -
> - switch (cpu_dai->id) {
> - case WSA_CODEC_DMA_RX_0:
> - case WSA_CODEC_DMA_RX_1:
> - case RX_CODEC_DMA_RX_0:
> - case RX_CODEC_DMA_RX_1:
> - case TX_CODEC_DMA_TX_0:
> - case TX_CODEC_DMA_TX_1:
> - case TX_CODEC_DMA_TX_2:
> - case TX_CODEC_DMA_TX_3:
> - return sm8250_snd_wsa_dma_prepare(substream);
> - default:
> - break;
> - }
> -
> - return 0;
> + return qcom_snd_sdw_prepare(substream, sruntime,
> + &data->stream_prepared[cpu_dai->id]);
> }
>
> static int sm8250_snd_hw_free(struct snd_pcm_substream *substream)
> @@ -216,26 +96,8 @@ static int sm8250_snd_hw_free(struct snd_pcm_substream *substream)
> struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
> struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
>
> - switch (cpu_dai->id) {
> - case WSA_CODEC_DMA_RX_0:
> - case WSA_CODEC_DMA_RX_1:
> - case RX_CODEC_DMA_RX_0:
> - case RX_CODEC_DMA_RX_1:
> - case TX_CODEC_DMA_TX_0:
> - case TX_CODEC_DMA_TX_1:
> - case TX_CODEC_DMA_TX_2:
> - case TX_CODEC_DMA_TX_3:
> - if (sruntime && data->stream_prepared[cpu_dai->id]) {
> - sdw_disable_stream(sruntime);
> - sdw_deprepare_stream(sruntime);
> - data->stream_prepared[cpu_dai->id] = false;
> - }
> - break;
> - default:
> - break;
> - }
> -
> - return 0;
> + return qcom_snd_sdw_hw_free(substream, sruntime,
> + &data->stream_prepared[cpu_dai->id]);
> }
>
> static const struct snd_soc_ops sm8250_be_ops = {
> --
> 2.21.0
>