summaryrefslogtreecommitdiff
path: root/sound/soc/qcom
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/qcom')
-rw-r--r--sound/soc/qcom/Kconfig11
-rw-r--r--sound/soc/qcom/Makefile2
-rw-r--r--sound/soc/qcom/common.c173
-rw-r--r--sound/soc/qcom/common.h35
-rw-r--r--sound/soc/qcom/qdsp6/q6prm-clocks.c9
-rw-r--r--sound/soc/qcom/qdsp6/q6prm.h19
-rw-r--r--sound/soc/qcom/sc8280xp.c157
-rw-r--r--sound/soc/qcom/sm8250.c152
8 files changed, 412 insertions, 146 deletions
diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
index 750653404ba3..d0e59e07b1fc 100644
--- a/sound/soc/qcom/Kconfig
+++ b/sound/soc/qcom/Kconfig
@@ -173,6 +173,17 @@ config SND_SOC_SM8250
SM8250 SoC-based systems.
Say Y if you want to use audio device on this SoCs.
+config SND_SOC_SC8280XP
+ tristate "SoC Machine driver for SC8280XP boards"
+ depends on QCOM_APR && SOUNDWIRE
+ depends on COMMON_CLK
+ select SND_SOC_QDSP6
+ select SND_SOC_QCOM_COMMON
+ help
+ To add support for audio on Qualcomm Technologies Inc.
+ SC8280XP SoC-based systems.
+ Say Y if you want to use audio device on this SoCs.
+
config SND_SOC_SC7180
tristate "SoC Machine driver for SC7180 boards"
depends on I2C && GPIOLIB
diff --git a/sound/soc/qcom/Makefile b/sound/soc/qcom/Makefile
index 8b7b876899a8..8b97172cf990 100644
--- a/sound/soc/qcom/Makefile
+++ b/sound/soc/qcom/Makefile
@@ -26,6 +26,7 @@ snd-soc-sc7180-objs := sc7180.o
snd-soc-sc7280-objs := sc7280.o
snd-soc-sdm845-objs := sdm845.o
snd-soc-sm8250-objs := sm8250.o
+snd-soc-sc8280xp-objs := sc8280xp.o
snd-soc-qcom-common-objs := common.o
obj-$(CONFIG_SND_SOC_STORM) += snd-soc-storm.o
@@ -33,6 +34,7 @@ obj-$(CONFIG_SND_SOC_APQ8016_SBC) += snd-soc-apq8016-sbc.o
obj-$(CONFIG_SND_SOC_MSM8996) += snd-soc-apq8096.o
obj-$(CONFIG_SND_SOC_SC7180) += snd-soc-sc7180.o
obj-$(CONFIG_SND_SOC_SC7280) += snd-soc-sc7280.o
+obj-$(CONFIG_SND_SOC_SC8280XP) += snd-soc-sc8280xp.o
obj-$(CONFIG_SND_SOC_SDM845) += snd-soc-sdm845.o
obj-$(CONFIG_SND_SOC_SM8250) += snd-soc-sm8250.o
obj-$(CONFIG_SND_SOC_QCOM_COMMON) += snd-soc-qcom-common.o
diff --git a/sound/soc/qcom/common.c b/sound/soc/qcom/common.c
index c407684ce1a2..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)
@@ -175,6 +178,174 @@ err_put_np:
of_node_put(np);
return ret;
}
-EXPORT_SYMBOL(qcom_snd_parse_of);
+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/qdsp6/q6prm-clocks.c b/sound/soc/qcom/qdsp6/q6prm-clocks.c
index a26cda5140c1..73b0cbac73d4 100644
--- a/sound/soc/qcom/qdsp6/q6prm-clocks.c
+++ b/sound/soc/qcom/qdsp6/q6prm-clocks.c
@@ -50,6 +50,15 @@ static const struct q6dsp_clk_init q6prm_clks[] = {
Q6PRM_CLK(LPASS_CLK_ID_RX_CORE_MCLK),
Q6PRM_CLK(LPASS_CLK_ID_RX_CORE_NPL_MCLK),
Q6PRM_CLK(LPASS_CLK_ID_VA_CORE_2X_MCLK),
+ Q6PRM_CLK(LPASS_CLK_ID_WSA2_CORE_MCLK),
+ Q6PRM_CLK(LPASS_CLK_ID_WSA2_CORE_2X_MCLK),
+ Q6PRM_CLK(LPASS_CLK_ID_RX_CORE_TX_MCLK),
+ Q6PRM_CLK(LPASS_CLK_ID_RX_CORE_TX_2X_MCLK),
+ Q6PRM_CLK(LPASS_CLK_ID_WSA_CORE_TX_MCLK),
+ Q6PRM_CLK(LPASS_CLK_ID_WSA_CORE_TX_2X_MCLK),
+ Q6PRM_CLK(LPASS_CLK_ID_WSA2_CORE_TX_MCLK),
+ Q6PRM_CLK(LPASS_CLK_ID_WSA2_CORE_TX_2X_MCLK),
+ Q6PRM_CLK(LPASS_CLK_ID_RX_CORE_MCLK2_2X_MCLK),
Q6DSP_VOTE_CLK(LPASS_HW_MACRO_VOTE, Q6PRM_HW_CORE_ID_LPASS,
"LPASS_HW_MACRO"),
Q6DSP_VOTE_CLK(LPASS_HW_DCODEC_VOTE, Q6PRM_HW_CORE_ID_DCODEC,
diff --git a/sound/soc/qcom/qdsp6/q6prm.h b/sound/soc/qcom/qdsp6/q6prm.h
index fea4d1954bc1..a988a32086fe 100644
--- a/sound/soc/qcom/qdsp6/q6prm.h
+++ b/sound/soc/qcom/qdsp6/q6prm.h
@@ -64,6 +64,25 @@
#define Q6PRM_LPASS_CLK_ID_RX_CORE_MCLK 0x30e
#define Q6PRM_LPASS_CLK_ID_RX_CORE_NPL_MCLK 0x30f
+/* Clock ID for MCLK for WSA2 core */
+#define Q6PRM_LPASS_CLK_ID_WSA2_CORE_MCLK 0x310
+/* Clock ID for NPL MCLK for WSA2 core */
+#define Q6PRM_LPASS_CLK_ID_WSA2_CORE_2X_MCLK 0x311
+/* Clock ID for RX Core TX MCLK */
+#define Q6PRM_LPASS_CLK_ID_RX_CORE_TX_MCLK 0x312
+/* Clock ID for RX CORE TX 2X MCLK */
+#define Q6PRM_LPASS_CLK_ID_RX_CORE_TX_2X_MCLK 0x313
+/* Clock ID for WSA core TX MCLK */
+#define Q6PRM_LPASS_CLK_ID_WSA_CORE_TX_MCLK 0x314
+/* Clock ID for WSA core TX 2X MCLK */
+#define Q6PRM_LPASS_CLK_ID_WSA_CORE_TX_2X_MCLK 0x315
+/* Clock ID for WSA2 core TX MCLK */
+#define Q6PRM_LPASS_CLK_ID_WSA2_CORE_TX_MCLK 0x316
+/* Clock ID for WSA2 core TX 2X MCLK */
+#define Q6PRM_LPASS_CLK_ID_WSA2_CORE_TX_2X_MCLK 0x317
+/* Clock ID for RX CORE MCLK2 2X MCLK */
+#define Q6PRM_LPASS_CLK_ID_RX_CORE_MCLK2_2X_MCLK 0x318
+
#define Q6PRM_LPASS_CLK_SRC_INTERNAL 1
#define Q6PRM_LPASS_CLK_ROOT_DEFAULT 0
#define Q6PRM_HW_CORE_ID_LPASS 1
diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c
new file mode 100644
index 000000000000..ade44ad7c585
--- /dev/null
+++ b/sound/soc/qcom/sc8280xp.c
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2022, Linaro Limited
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of_device.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/pcm.h>
+#include <linux/soundwire/sdw.h>
+#include <sound/jack.h>
+#include <linux/input-event-codes.h>
+#include "qdsp6/q6afe.h"
+#include "common.h"
+
+#define DRIVER_NAME "sc8280xp"
+
+struct sc8280xp_snd_data {
+ bool stream_prepared[AFE_PORT_MAX];
+ struct snd_soc_card *card;
+ struct sdw_stream_runtime *sruntime[AFE_PORT_MAX];
+ struct snd_soc_jack jack;
+ bool jack_setup;
+};
+
+static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
+
+ return qcom_snd_wcd_jack_setup(rtd, &data->jack, &data->jack_setup);
+}
+
+static int sc8280xp_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+ struct snd_interval *rate = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+ struct snd_interval *channels = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+
+ rate->min = rate->max = 48000;
+ channels->min = 2;
+ channels->max = 2;
+ 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:
+ channels->min = 1;
+ break;
+ default:
+ break;
+ }
+
+
+ return 0;
+}
+
+static int sc8280xp_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 *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+ struct sc8280xp_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card);
+
+ return qcom_snd_sdw_hw_params(substream, params, &pdata->sruntime[cpu_dai->id]);
+}
+
+static int sc8280xp_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 sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
+ struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
+
+ return qcom_snd_sdw_prepare(substream, sruntime,
+ &data->stream_prepared[cpu_dai->id]);
+}
+
+static int sc8280xp_snd_hw_free(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
+ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+ struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
+
+ return qcom_snd_sdw_hw_free(substream, sruntime,
+ &data->stream_prepared[cpu_dai->id]);
+}
+
+static const struct snd_soc_ops sc8280xp_be_ops = {
+ .hw_params = sc8280xp_snd_hw_params,
+ .hw_free = sc8280xp_snd_hw_free,
+ .prepare = sc8280xp_snd_prepare,
+};
+
+static void sc8280xp_add_be_ops(struct snd_soc_card *card)
+{
+ struct snd_soc_dai_link *link;
+ int i;
+
+ for_each_card_prelinks(card, i, link) {
+ if (link->no_pcm == 1) {
+ link->init = sc8280xp_snd_init;
+ link->be_hw_params_fixup = sc8280xp_be_hw_params_fixup;
+ link->ops = &sc8280xp_be_ops;
+ }
+ }
+}
+
+static int sc8280xp_platform_probe(struct platform_device *pdev)
+{
+ struct snd_soc_card *card;
+ struct sc8280xp_snd_data *data;
+ struct device *dev = &pdev->dev;
+ int ret;
+
+ card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
+ if (!card)
+ return -ENOMEM;
+ card->owner = THIS_MODULE;
+ /* Allocate the private data */
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ card->dev = dev;
+ dev_set_drvdata(dev, card);
+ snd_soc_card_set_drvdata(card, data);
+ ret = qcom_snd_parse_of(card);
+ if (ret)
+ return ret;
+
+ card->driver_name = DRIVER_NAME;
+ sc8280xp_add_be_ops(card);
+ return devm_snd_soc_register_card(dev, card);
+}
+
+static const struct of_device_id snd_sc8280xp_dt_match[] = {
+ {.compatible = "qcom,sc8280xp-sndcard",},
+ {}
+};
+
+MODULE_DEVICE_TABLE(of, snd_sc8280xp_dt_match);
+
+static struct platform_driver snd_sc8280xp_driver = {
+ .probe = sc8280xp_platform_probe,
+ .driver = {
+ .name = "snd-sc8280xp",
+ .of_match_table = snd_sc8280xp_dt_match,
+ },
+};
+module_platform_driver(snd_sc8280xp_driver);
+MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org");
+MODULE_DESCRIPTION("SC8280XP ASoC Machine Driver");
+MODULE_LICENSE("GPL v2");
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 = {