summaryrefslogtreecommitdiff
path: root/sound/soc/qcom
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/qcom')
-rw-r--r--sound/soc/qcom/Kconfig14
-rw-r--r--sound/soc/qcom/Makefile38
-rw-r--r--sound/soc/qcom/apq8016_sbc.c7
-rw-r--r--sound/soc/qcom/apq8096.c4
-rw-r--r--sound/soc/qcom/common.c44
-rw-r--r--sound/soc/qcom/common.h3
-rw-r--r--sound/soc/qcom/lpass-apq8016.c10
-rw-r--r--sound/soc/qcom/lpass-cdc-dma.c3
-rw-r--r--sound/soc/qcom/lpass-cpu.c51
-rw-r--r--sound/soc/qcom/lpass-hdmi.c2
-rw-r--r--sound/soc/qcom/lpass-ipq806x.c6
-rw-r--r--sound/soc/qcom/lpass-platform.c39
-rw-r--r--sound/soc/qcom/lpass-sc7180.c8
-rw-r--r--sound/soc/qcom/lpass-sc7280.c6
-rw-r--r--sound/soc/qcom/lpass.h6
-rw-r--r--sound/soc/qcom/qdsp6/Makefile4
-rw-r--r--sound/soc/qcom/qdsp6/audioreach.c55
-rw-r--r--sound/soc/qcom/qdsp6/audioreach.h4
-rw-r--r--sound/soc/qcom/qdsp6/q6afe-clocks.c1
-rw-r--r--sound/soc/qcom/qdsp6/q6afe-dai.c17
-rw-r--r--sound/soc/qcom/qdsp6/q6afe.c9
-rw-r--r--sound/soc/qcom/qdsp6/q6afe.h2
-rw-r--r--sound/soc/qcom/qdsp6/q6apm-dai.c33
-rw-r--r--sound/soc/qcom/qdsp6/q6apm-lpass-dais.c24
-rw-r--r--sound/soc/qcom/qdsp6/q6apm.h1
-rw-r--r--sound/soc/qcom/qdsp6/q6asm-dai.c36
-rw-r--r--sound/soc/qcom/qdsp6/q6asm.c1
-rw-r--r--sound/soc/qcom/qdsp6/q6asm.h21
-rw-r--r--sound/soc/qcom/qdsp6/q6dsp-common.c2
-rw-r--r--sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c1
-rw-r--r--sound/soc/qcom/qdsp6/q6prm-clocks.c2
-rw-r--r--sound/soc/qcom/qdsp6/q6routing.c7
-rw-r--r--sound/soc/qcom/qdsp6/topology.c41
-rw-r--r--sound/soc/qcom/sc7180.c205
-rw-r--r--sound/soc/qcom/sc7280.c26
-rw-r--r--sound/soc/qcom/sc8280xp.c51
-rw-r--r--sound/soc/qcom/sdm845.c11
-rw-r--r--sound/soc/qcom/sdw.c56
-rw-r--r--sound/soc/qcom/sdw.h1
-rw-r--r--sound/soc/qcom/sm8250.c35
-rw-r--r--sound/soc/qcom/storm.c2
-rw-r--r--sound/soc/qcom/x1e80100.c206
42 files changed, 814 insertions, 281 deletions
diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
index e7b00d1d9e99..ca7a30ebd26a 100644
--- a/sound/soc/qcom/Kconfig
+++ b/sound/soc/qcom/Kconfig
@@ -157,6 +157,7 @@ config SND_SOC_SDM845
depends on COMMON_CLK
select SND_SOC_QDSP6
select SND_SOC_QCOM_COMMON
+ select SND_SOC_QCOM_SDW
select SND_SOC_RT5663
select SND_SOC_MAX98927
imply SND_SOC_CROS_EC_CODEC
@@ -208,6 +209,7 @@ config SND_SOC_SC7280
tristate "SoC Machine driver for SC7280 boards"
depends on I2C && SOUNDWIRE
select SND_SOC_QCOM_COMMON
+ select SND_SOC_QCOM_SDW
select SND_SOC_LPASS_SC7280
select SND_SOC_MAX98357A
select SND_SOC_WCD938X_SDW
@@ -221,4 +223,16 @@ config SND_SOC_SC7280
SC7280 SoC-based systems.
Say Y or M if you want to use audio device on this SoCs.
+config SND_SOC_X1E80100
+ tristate "SoC Machine driver for X1E80100 boards"
+ depends on QCOM_APR && SOUNDWIRE
+ depends on COMMON_CLK
+ select SND_SOC_QDSP6
+ select SND_SOC_QCOM_COMMON
+ select SND_SOC_QCOM_SDW
+ help
+ Add support for audio on Qualcomm Technologies Inc.
+ X1E80100 SoC-based systems.
+ Say Y or M if you want to use audio device on this SoCs.
+
endif #SND_SOC_QCOM
diff --git a/sound/soc/qcom/Makefile b/sound/soc/qcom/Makefile
index 254350d9dc06..16db7b53ddac 100644
--- a/sound/soc/qcom/Makefile
+++ b/sound/soc/qcom/Makefile
@@ -1,13 +1,13 @@
# SPDX-License-Identifier: GPL-2.0
# Platform
-snd-soc-lpass-cpu-objs := lpass-cpu.o
-snd-soc-lpass-cdc-dma-objs := lpass-cdc-dma.o
-snd-soc-lpass-hdmi-objs := lpass-hdmi.o
-snd-soc-lpass-platform-objs := lpass-platform.o
-snd-soc-lpass-ipq806x-objs := lpass-ipq806x.o
-snd-soc-lpass-apq8016-objs := lpass-apq8016.o
-snd-soc-lpass-sc7180-objs := lpass-sc7180.o
-snd-soc-lpass-sc7280-objs := lpass-sc7280.o
+snd-soc-lpass-cpu-y := lpass-cpu.o
+snd-soc-lpass-cdc-dma-y := lpass-cdc-dma.o
+snd-soc-lpass-hdmi-y := lpass-hdmi.o
+snd-soc-lpass-platform-y := lpass-platform.o
+snd-soc-lpass-ipq806x-y := lpass-ipq806x.o
+snd-soc-lpass-apq8016-y := lpass-apq8016.o
+snd-soc-lpass-sc7180-y := lpass-sc7180.o
+snd-soc-lpass-sc7280-y := lpass-sc7280.o
obj-$(CONFIG_SND_SOC_LPASS_CPU) += snd-soc-lpass-cpu.o
obj-$(CONFIG_SND_SOC_LPASS_CDC_DMA) += snd-soc-lpass-cdc-dma.o
@@ -19,16 +19,17 @@ obj-$(CONFIG_SND_SOC_LPASS_SC7180) += snd-soc-lpass-sc7180.o
obj-$(CONFIG_SND_SOC_LPASS_SC7280) += snd-soc-lpass-sc7280.o
# Machine
-snd-soc-storm-objs := storm.o
-snd-soc-apq8016-sbc-objs := apq8016_sbc.o
-snd-soc-apq8096-objs := apq8096.o
-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
-snd-soc-qcom-sdw-objs := sdw.o
+snd-soc-storm-y := storm.o
+snd-soc-apq8016-sbc-y := apq8016_sbc.o
+snd-soc-apq8096-y := apq8096.o
+snd-soc-sc7180-y := sc7180.o
+snd-soc-sc7280-y := sc7280.o
+snd-soc-sdm845-y := sdm845.o
+snd-soc-sm8250-y := sm8250.o
+snd-soc-sc8280xp-y := sc8280xp.o
+snd-soc-qcom-common-y := common.o
+snd-soc-qcom-sdw-y := sdw.o
+snd-soc-x1e80100-y := x1e80100.o
obj-$(CONFIG_SND_SOC_STORM) += snd-soc-storm.o
obj-$(CONFIG_SND_SOC_APQ8016_SBC) += snd-soc-apq8016-sbc.o
@@ -40,6 +41,7 @@ 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
obj-$(CONFIG_SND_SOC_QCOM_SDW) += snd-soc-qcom-sdw.o
+obj-$(CONFIG_SND_SOC_X1E80100) += snd-soc-x1e80100.o
#DSP lib
obj-$(CONFIG_SND_SOC_QDSP6) += qdsp6/
diff --git a/sound/soc/qcom/apq8016_sbc.c b/sound/soc/qcom/apq8016_sbc.c
index ff9f6a1c95df..3023cf180a75 100644
--- a/sound/soc/qcom/apq8016_sbc.c
+++ b/sound/soc/qcom/apq8016_sbc.c
@@ -16,6 +16,7 @@
#include <sound/soc.h>
#include <uapi/linux/input-event-codes.h>
#include <dt-bindings/sound/apq8016-lpass.h>
+#include <dt-bindings/sound/qcom,q6afe.h>
#include "common.h"
#include "qdsp6/q6afe.h"
@@ -191,7 +192,7 @@ static int msm8916_qdsp6_dai_init(struct snd_soc_pcm_runtime *rtd)
static int msm8916_qdsp6_startup(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card;
struct apq8016_sbc_data *data = snd_soc_card_get_drvdata(card);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
@@ -212,7 +213,7 @@ static int msm8916_qdsp6_startup(struct snd_pcm_substream *substream)
static void msm8916_qdsp6_shutdown(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card;
struct apq8016_sbc_data *data = snd_soc_card_get_drvdata(card);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
@@ -343,4 +344,4 @@ module_platform_driver(apq8016_sbc_platform_driver);
MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org");
MODULE_DESCRIPTION("APQ8016 ASoC Machine Driver");
-MODULE_LICENSE("GPL v2");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/qcom/apq8096.c b/sound/soc/qcom/apq8096.c
index cddeb47dbcf2..4f6594cc723c 100644
--- a/sound/soc/qcom/apq8096.c
+++ b/sound/soc/qcom/apq8096.c
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2018, Linaro Limited
+#include <linux/mod_devicetable.h>
#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>
@@ -142,4 +142,4 @@ static struct platform_driver msm_snd_apq8096_driver = {
module_platform_driver(msm_snd_apq8096_driver);
MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org");
MODULE_DESCRIPTION("APQ8096 ASoC Machine Driver");
-MODULE_LICENSE("GPL v2");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/qcom/common.c b/sound/soc/qcom/common.c
index f2d1e3009cd2..928cf5cb5999 100644
--- a/sound/soc/qcom/common.c
+++ b/sound/soc/qcom/common.c
@@ -2,15 +2,25 @@
// Copyright (c) 2018, Linaro Limited.
// Copyright (c) 2018, The Linux Foundation. All rights reserved.
+#include <dt-bindings/sound/qcom,q6afe.h>
#include <linux/module.h>
#include <sound/jack.h>
#include <linux/input-event-codes.h>
-#include "qdsp6/q6afe.h"
#include "common.h"
+#define NAME_SIZE 32
+
static const struct snd_soc_dapm_widget qcom_jack_snd_widgets[] = {
SND_SOC_DAPM_HP("Headphone Jack", NULL),
SND_SOC_DAPM_MIC("Mic Jack", NULL),
+ SND_SOC_DAPM_SPK("DP0 Jack", NULL),
+ SND_SOC_DAPM_SPK("DP1 Jack", NULL),
+ SND_SOC_DAPM_SPK("DP2 Jack", NULL),
+ SND_SOC_DAPM_SPK("DP3 Jack", NULL),
+ SND_SOC_DAPM_SPK("DP4 Jack", NULL),
+ SND_SOC_DAPM_SPK("DP5 Jack", NULL),
+ SND_SOC_DAPM_SPK("DP6 Jack", NULL),
+ SND_SOC_DAPM_SPK("DP7 Jack", NULL),
};
int qcom_snd_parse_of(struct snd_soc_card *card)
@@ -73,7 +83,7 @@ int qcom_snd_parse_of(struct snd_soc_card *card)
link = card->dai_link;
for_each_available_child_of_node(dev->of_node, np) {
- dlc = devm_kzalloc(dev, 2 * sizeof(*dlc), GFP_KERNEL);
+ dlc = devm_kcalloc(dev, 2, sizeof(*dlc), GFP_KERNEL);
if (!dlc) {
ret = -ENOMEM;
goto err_put_np;
@@ -145,7 +155,6 @@ int qcom_snd_parse_of(struct snd_soc_card *card)
if (platform || !codec) {
/* DPCM */
- snd_soc_dai_link_set_capabilities(link);
link->ignore_suspend = 1;
link->nonatomic = 1;
}
@@ -239,4 +248,31 @@ int qcom_snd_wcd_jack_setup(struct snd_soc_pcm_runtime *rtd,
return 0;
}
EXPORT_SYMBOL_GPL(qcom_snd_wcd_jack_setup);
-MODULE_LICENSE("GPL v2");
+
+int qcom_snd_dp_jack_setup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_soc_jack *dp_jack, int dp_pcm_id)
+{
+ struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
+ struct snd_soc_card *card = rtd->card;
+ char jack_name[NAME_SIZE];
+ int rval, i;
+
+ snprintf(jack_name, sizeof(jack_name), "DP%d Jack", dp_pcm_id);
+ rval = snd_soc_card_jack_new(card, jack_name, SND_JACK_AVOUT, dp_jack);
+ if (rval)
+ return rval;
+
+ for_each_rtd_codec_dais(rtd, i, codec_dai) {
+ rval = snd_soc_component_set_jack(codec_dai->component, dp_jack, NULL);
+ if (rval != 0 && rval != -ENOTSUPP) {
+ dev_warn(card->dev, "Failed to set jack: %d\n", rval);
+ return rval;
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(qcom_snd_dp_jack_setup);
+
+MODULE_DESCRIPTION("ASoC Qualcomm helper functions");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/qcom/common.h b/sound/soc/qcom/common.h
index d7f80ee5ae26..1b8d3f90bffa 100644
--- a/sound/soc/qcom/common.h
+++ b/sound/soc/qcom/common.h
@@ -9,5 +9,8 @@
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);
+int qcom_snd_dp_jack_setup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_soc_jack *dp_jack, int id);
+
#endif
diff --git a/sound/soc/qcom/lpass-apq8016.c b/sound/soc/qcom/lpass-apq8016.c
index f919d46e18ca..b8f23414eb77 100644
--- a/sound/soc/qcom/lpass-apq8016.c
+++ b/sound/soc/qcom/lpass-apq8016.c
@@ -123,7 +123,7 @@ static struct snd_soc_dai_driver apq8016_lpass_cpu_dai_driver[] = {
static int apq8016_lpass_alloc_dma_channel(struct lpass_data *drvdata,
int direction, unsigned int dai_id)
{
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
int chan = 0;
if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -157,7 +157,7 @@ static int apq8016_lpass_free_dma_channel(struct lpass_data *drvdata, int chan,
static int apq8016_lpass_init(struct platform_device *pdev)
{
struct lpass_data *drvdata = platform_get_drvdata(pdev);
- struct lpass_variant *variant = drvdata->variant;
+ const struct lpass_variant *variant = drvdata->variant;
struct device *dev = &pdev->dev;
int ret, i;
@@ -223,7 +223,7 @@ static int apq8016_lpass_exit(struct platform_device *pdev)
}
-static struct lpass_variant apq8016_data = {
+static const struct lpass_variant apq8016_data = {
.i2sctrl_reg_base = 0x1000,
.i2sctrl_reg_stride = 0x1000,
.i2s_ports = 4,
@@ -300,10 +300,10 @@ static struct platform_driver apq8016_lpass_cpu_platform_driver = {
.of_match_table = of_match_ptr(apq8016_lpass_cpu_device_id),
},
.probe = asoc_qcom_lpass_cpu_platform_probe,
- .remove = asoc_qcom_lpass_cpu_platform_remove,
+ .remove = asoc_qcom_lpass_cpu_platform_remove,
};
module_platform_driver(apq8016_lpass_cpu_platform_driver);
MODULE_DESCRIPTION("APQ8016 LPASS CPU Driver");
-MODULE_LICENSE("GPL v2");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/qcom/lpass-cdc-dma.c b/sound/soc/qcom/lpass-cdc-dma.c
index 4d5d147b47db..8106c586f68a 100644
--- a/sound/soc/qcom/lpass-cdc-dma.c
+++ b/sound/soc/qcom/lpass-cdc-dma.c
@@ -5,6 +5,7 @@
* lpass-cdc-dma.c -- ALSA SoC CDC DMA CPU DAI driver for QTi LPASS
*/
+#include <dt-bindings/sound/qcom,lpass.h>
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/export.h>
@@ -37,7 +38,7 @@ static void __lpass_get_dmactl_handle(struct snd_pcm_substream *substream, struc
struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
struct snd_pcm_runtime *rt = substream->runtime;
struct lpass_pcm_data *pcm_data = rt->private_data;
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
unsigned int dai_id = cpu_dai->driver->id;
switch (dai_id) {
diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
index e587455dc40a..242bc16da36d 100644
--- a/sound/soc/qcom/lpass-cpu.c
+++ b/sound/soc/qcom/lpass-cpu.c
@@ -5,11 +5,11 @@
* lpass-cpu.c -- ALSA SoC CPU DAI driver for QTi LPASS
*/
+#include <dt-bindings/sound/qcom,lpass.h>
#include <linux/clk.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -44,7 +44,7 @@ static int lpass_cpu_init_i2sctl_bitfields(struct device *dev,
struct lpaif_i2sctl *i2sctl, struct regmap *map)
{
struct lpass_data *drvdata = dev_get_drvdata(dev);
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
i2sctl->loopback = devm_regmap_field_alloc(dev, map, v->loopback);
i2sctl->spken = devm_regmap_field_alloc(dev, map, v->spken);
@@ -463,7 +463,7 @@ static int asoc_qcom_of_xlate_dai_name(struct snd_soc_component *component,
const char **dai_name)
{
struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
- struct lpass_variant *variant = drvdata->variant;
+ const struct lpass_variant *variant = drvdata->variant;
int id = args->args[0];
int ret = -EINVAL;
int i;
@@ -488,7 +488,7 @@ static const struct snd_soc_component_driver lpass_cpu_comp_driver = {
static bool lpass_cpu_regmap_writeable(struct device *dev, unsigned int reg)
{
struct lpass_data *drvdata = dev_get_drvdata(dev);
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
int i;
for (i = 0; i < v->i2s_ports; ++i)
@@ -530,7 +530,7 @@ static bool lpass_cpu_regmap_writeable(struct device *dev, unsigned int reg)
static bool lpass_cpu_regmap_readable(struct device *dev, unsigned int reg)
{
struct lpass_data *drvdata = dev_get_drvdata(dev);
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
int i;
for (i = 0; i < v->i2s_ports; ++i)
@@ -578,7 +578,7 @@ static bool lpass_cpu_regmap_readable(struct device *dev, unsigned int reg)
static bool lpass_cpu_regmap_volatile(struct device *dev, unsigned int reg)
{
struct lpass_data *drvdata = dev_get_drvdata(dev);
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
int i;
for (i = 0; i < v->irq_ports; ++i) {
@@ -613,7 +613,7 @@ static struct regmap_config lpass_cpu_regmap_config = {
static int lpass_hdmi_init_bitfields(struct device *dev, struct regmap *map)
{
struct lpass_data *drvdata = dev_get_drvdata(dev);
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
unsigned int i;
struct lpass_hdmi_tx_ctl *tx_ctl;
struct regmap_field *legacy_en;
@@ -691,7 +691,7 @@ static int lpass_hdmi_init_bitfields(struct device *dev, struct regmap *map)
static bool lpass_hdmi_regmap_writeable(struct device *dev, unsigned int reg)
{
struct lpass_data *drvdata = dev_get_drvdata(dev);
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
int i;
if (reg == LPASS_HDMI_TX_CTL_ADDR(v))
@@ -736,7 +736,7 @@ static bool lpass_hdmi_regmap_writeable(struct device *dev, unsigned int reg)
static bool lpass_hdmi_regmap_readable(struct device *dev, unsigned int reg)
{
struct lpass_data *drvdata = dev_get_drvdata(dev);
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
int i;
if (reg == LPASS_HDMI_TX_CTL_ADDR(v))
@@ -785,7 +785,7 @@ static bool lpass_hdmi_regmap_readable(struct device *dev, unsigned int reg)
static bool lpass_hdmi_regmap_volatile(struct device *dev, unsigned int reg)
{
struct lpass_data *drvdata = dev_get_drvdata(dev);
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
int i;
if (reg == LPASS_HDMITX_APP_IRQSTAT_REG(v))
@@ -824,7 +824,7 @@ static struct regmap_config lpass_hdmi_regmap_config = {
static bool __lpass_rxtx_regmap_accessible(struct device *dev, unsigned int reg, bool rw)
{
struct lpass_data *drvdata = dev_get_drvdata(dev);
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
int i;
for (i = 0; i < v->rxtx_irq_ports; ++i) {
@@ -890,7 +890,7 @@ static bool lpass_rxtx_regmap_readable(struct device *dev, unsigned int reg)
static bool lpass_rxtx_regmap_volatile(struct device *dev, unsigned int reg)
{
struct lpass_data *drvdata = dev_get_drvdata(dev);
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
int i;
for (i = 0; i < v->rxtx_irq_ports; ++i) {
@@ -915,7 +915,7 @@ static bool lpass_rxtx_regmap_volatile(struct device *dev, unsigned int reg)
static bool __lpass_va_regmap_accessible(struct device *dev, unsigned int reg, bool rw)
{
struct lpass_data *drvdata = dev_get_drvdata(dev);
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
int i;
for (i = 0; i < v->va_irq_ports; ++i) {
@@ -965,7 +965,7 @@ static bool lpass_va_regmap_readable(struct device *dev, unsigned int reg)
static bool lpass_va_regmap_volatile(struct device *dev, unsigned int reg)
{
struct lpass_data *drvdata = dev_get_drvdata(dev);
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
int i;
for (i = 0; i < v->va_irq_ports; ++i) {
@@ -1104,9 +1104,8 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
struct lpass_data *drvdata;
struct device_node *dsp_of_node;
struct resource *res;
- struct lpass_variant *variant;
+ const struct lpass_variant *variant;
struct device *dev = &pdev->dev;
- const struct of_device_id *match;
int ret, i, dai_id;
dsp_of_node = of_parse_phandle(pdev->dev.of_node, "qcom,adsp", 0);
@@ -1121,17 +1120,14 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
return -ENOMEM;
platform_set_drvdata(pdev, drvdata);
- match = of_match_device(dev->driver->of_match_table, dev);
- if (!match || !match->data)
+ variant = device_get_match_data(dev);
+ if (!variant)
return -EINVAL;
- if (of_device_is_compatible(dev->of_node, "qcom,lpass-cpu-apq8016")) {
- dev_warn(dev, "%s compatible is deprecated\n",
- match->compatible);
- }
+ if (of_device_is_compatible(dev->of_node, "qcom,lpass-cpu-apq8016"))
+ dev_warn(dev, "qcom,lpass-cpu-apq8016 compatible is deprecated\n");
- drvdata->variant = (struct lpass_variant *)match->data;
- variant = drvdata->variant;
+ drvdata->variant = variant;
of_lpass_cpu_parse_dai_data(dev, drvdata);
@@ -1284,15 +1280,12 @@ err:
}
EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_platform_probe);
-int asoc_qcom_lpass_cpu_platform_remove(struct platform_device *pdev)
+void asoc_qcom_lpass_cpu_platform_remove(struct platform_device *pdev)
{
struct lpass_data *drvdata = platform_get_drvdata(pdev);
if (drvdata->variant->exit)
drvdata->variant->exit(pdev);
-
-
- return 0;
}
EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_platform_remove);
@@ -1307,4 +1300,4 @@ void asoc_qcom_lpass_cpu_platform_shutdown(struct platform_device *pdev)
EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_platform_shutdown);
MODULE_DESCRIPTION("QTi LPASS CPU Driver");
-MODULE_LICENSE("GPL v2");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/qcom/lpass-hdmi.c b/sound/soc/qcom/lpass-hdmi.c
index 24b1a7523adb..ce753ebc0894 100644
--- a/sound/soc/qcom/lpass-hdmi.c
+++ b/sound/soc/qcom/lpass-hdmi.c
@@ -251,4 +251,4 @@ const struct snd_soc_dai_ops asoc_qcom_lpass_hdmi_dai_ops = {
EXPORT_SYMBOL_GPL(asoc_qcom_lpass_hdmi_dai_ops);
MODULE_DESCRIPTION("QTi LPASS HDMI Driver");
-MODULE_LICENSE("GPL v2");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/qcom/lpass-ipq806x.c b/sound/soc/qcom/lpass-ipq806x.c
index 2c97f295e394..e57d29ea4ce7 100644
--- a/sound/soc/qcom/lpass-ipq806x.c
+++ b/sound/soc/qcom/lpass-ipq806x.c
@@ -108,7 +108,7 @@ static int ipq806x_lpass_free_dma_channel(struct lpass_data *drvdata, int chan,
return 0;
}
-static struct lpass_variant ipq806x_data = {
+static const struct lpass_variant ipq806x_data = {
.i2sctrl_reg_base = 0x0010,
.i2sctrl_reg_stride = 0x04,
.i2s_ports = 5,
@@ -172,9 +172,9 @@ static struct platform_driver ipq806x_lpass_cpu_platform_driver = {
.of_match_table = of_match_ptr(ipq806x_lpass_cpu_device_id),
},
.probe = asoc_qcom_lpass_cpu_platform_probe,
- .remove = asoc_qcom_lpass_cpu_platform_remove,
+ .remove = asoc_qcom_lpass_cpu_platform_remove,
};
module_platform_driver(ipq806x_lpass_cpu_platform_driver);
MODULE_DESCRIPTION("QTi LPASS CPU Driver");
-MODULE_LICENSE("GPL v2");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platform.c
index 73e3d39bd24c..addd2c4bdd3e 100644
--- a/sound/soc/qcom/lpass-platform.c
+++ b/sound/soc/qcom/lpass-platform.c
@@ -5,6 +5,7 @@
* lpass-platform.c -- ALSA SoC platform driver for QTi LPASS
*/
+#include <dt-bindings/sound/qcom,lpass.h>
#include <linux/dma-mapping.h>
#include <linux/export.h>
#include <linux/kernel.h>
@@ -100,7 +101,7 @@ static int lpass_platform_alloc_rxtx_dmactl_fields(struct device *dev,
struct regmap *map)
{
struct lpass_data *drvdata = dev_get_drvdata(dev);
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
struct lpaif_dmactl *rd_dmactl, *wr_dmactl;
int rval;
@@ -128,7 +129,7 @@ static int lpass_platform_alloc_va_dmactl_fields(struct device *dev,
struct regmap *map)
{
struct lpass_data *drvdata = dev_get_drvdata(dev);
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
struct lpaif_dmactl *wr_dmactl;
wr_dmactl = devm_kzalloc(dev, sizeof(*wr_dmactl), GFP_KERNEL);
@@ -145,7 +146,7 @@ static int lpass_platform_alloc_dmactl_fields(struct device *dev,
struct regmap *map)
{
struct lpass_data *drvdata = dev_get_drvdata(dev);
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
struct lpaif_dmactl *rd_dmactl, *wr_dmactl;
int rval;
@@ -175,7 +176,7 @@ static int lpass_platform_alloc_hdmidmactl_fields(struct device *dev,
struct regmap *map)
{
struct lpass_data *drvdata = dev_get_drvdata(dev);
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
struct lpaif_dmactl *rd_dmactl;
rd_dmactl = devm_kzalloc(dev, sizeof(struct lpaif_dmactl), GFP_KERNEL);
@@ -195,7 +196,7 @@ static int lpass_platform_pcmops_open(struct snd_soc_component *component,
struct snd_soc_pcm_runtime *soc_runtime = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(soc_runtime, 0);
struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
int ret, dma_ch, dir = substream->stream;
struct lpass_pcm_data *data;
struct regmap *map;
@@ -287,7 +288,7 @@ static int lpass_platform_pcmops_close(struct snd_soc_component *component,
struct snd_soc_pcm_runtime *soc_runtime = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(soc_runtime, 0);
struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
struct lpass_pcm_data *data;
unsigned int dai_id = cpu_dai->driver->id;
@@ -358,7 +359,7 @@ static int __lpass_get_id(const struct snd_pcm_substream *substream,
struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
struct snd_pcm_runtime *rt = substream->runtime;
struct lpass_pcm_data *pcm_data = rt->private_data;
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
int id;
switch (cpu_dai->driver->id) {
@@ -421,7 +422,7 @@ static int lpass_platform_pcmops_hw_params(struct snd_soc_component *component,
struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
struct snd_pcm_runtime *rt = substream->runtime;
struct lpass_pcm_data *pcm_data = rt->private_data;
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
snd_pcm_format_t format = params_format(params);
unsigned int channels = params_channels(params);
unsigned int regval;
@@ -574,7 +575,7 @@ static int lpass_platform_pcmops_hw_free(struct snd_soc_component *component,
struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
struct snd_pcm_runtime *rt = substream->runtime;
struct lpass_pcm_data *pcm_data = rt->private_data;
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
unsigned int reg;
int ret;
struct regmap *map;
@@ -602,7 +603,7 @@ static int lpass_platform_pcmops_prepare(struct snd_soc_component *component,
struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
struct snd_pcm_runtime *rt = substream->runtime;
struct lpass_pcm_data *pcm_data = rt->private_data;
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
struct lpaif_dmactl *dmactl;
struct regmap *map;
int ret, id, ch, dir = substream->stream;
@@ -665,7 +666,7 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
struct snd_pcm_runtime *rt = substream->runtime;
struct lpass_pcm_data *pcm_data = rt->private_data;
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
struct lpaif_dmactl *dmactl;
struct regmap *map;
int ret, ch, id;
@@ -864,7 +865,7 @@ static snd_pcm_uframes_t lpass_platform_pcmops_pointer(
struct lpass_data *drvdata = snd_soc_component_get_drvdata(component);
struct snd_pcm_runtime *rt = substream->runtime;
struct lpass_pcm_data *pcm_data = rt->private_data;
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
unsigned int base_addr, curr_addr;
int ret, ch, dir = substream->stream;
struct regmap *map;
@@ -928,7 +929,7 @@ static irqreturn_t lpass_dma_interrupt_handler(
{
struct snd_soc_pcm_runtime *soc_runtime = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(soc_runtime, 0);
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
irqreturn_t ret = IRQ_NONE;
int rv;
unsigned int reg, val, mask;
@@ -1020,7 +1021,7 @@ static irqreturn_t lpass_dma_interrupt_handler(
static irqreturn_t lpass_platform_lpaif_irq(int irq, void *data)
{
struct lpass_data *drvdata = data;
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
unsigned int irqs;
int rv, chan;
@@ -1048,7 +1049,7 @@ static irqreturn_t lpass_platform_lpaif_irq(int irq, void *data)
static irqreturn_t lpass_platform_hdmiif_irq(int irq, void *data)
{
struct lpass_data *drvdata = data;
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
unsigned int irqs;
int rv, chan;
@@ -1078,7 +1079,7 @@ static irqreturn_t lpass_platform_hdmiif_irq(int irq, void *data)
static irqreturn_t lpass_platform_rxtxif_irq(int irq, void *data)
{
struct lpass_data *drvdata = data;
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
unsigned int irqs;
irqreturn_t rv;
int chan;
@@ -1103,7 +1104,7 @@ static irqreturn_t lpass_platform_rxtxif_irq(int irq, void *data)
static irqreturn_t lpass_platform_vaif_irq(int irq, void *data)
{
struct lpass_data *drvdata = data;
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
unsigned int irqs;
irqreturn_t rv;
int chan;
@@ -1268,7 +1269,7 @@ static const struct snd_soc_component_driver lpass_component_driver = {
int asoc_qcom_lpass_platform_register(struct platform_device *pdev)
{
struct lpass_data *drvdata = platform_get_drvdata(pdev);
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
int ret;
drvdata->lpaif_irq = platform_get_irq_byname(pdev, "lpass-irq-lpaif");
@@ -1383,4 +1384,4 @@ int asoc_qcom_lpass_platform_register(struct platform_device *pdev)
EXPORT_SYMBOL_GPL(asoc_qcom_lpass_platform_register);
MODULE_DESCRIPTION("QTi LPASS Platform Driver");
-MODULE_LICENSE("GPL v2");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/qcom/lpass-sc7180.c b/sound/soc/qcom/lpass-sc7180.c
index d16c0d83aaad..fbead6af3d95 100644
--- a/sound/soc/qcom/lpass-sc7180.c
+++ b/sound/soc/qcom/lpass-sc7180.c
@@ -76,7 +76,7 @@ static struct snd_soc_dai_driver sc7180_lpass_cpu_dai_driver[] = {
static int sc7180_lpass_alloc_dma_channel(struct lpass_data *drvdata,
int direction, unsigned int dai_id)
{
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
int chan = 0;
if (dai_id == LPASS_DP_RX) {
@@ -123,7 +123,7 @@ static int sc7180_lpass_free_dma_channel(struct lpass_data *drvdata, int chan, u
static int sc7180_lpass_init(struct platform_device *pdev)
{
struct lpass_data *drvdata = platform_get_drvdata(pdev);
- struct lpass_variant *variant = drvdata->variant;
+ const struct lpass_variant *variant = drvdata->variant;
struct device *dev = &pdev->dev;
int ret, i;
@@ -179,7 +179,7 @@ static const struct dev_pm_ops sc7180_lpass_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(sc7180_lpass_dev_suspend, sc7180_lpass_dev_resume)
};
-static struct lpass_variant sc7180_data = {
+static const struct lpass_variant sc7180_data = {
.i2sctrl_reg_base = 0x1000,
.i2sctrl_reg_stride = 0x1000,
.i2s_ports = 3,
@@ -322,4 +322,4 @@ static struct platform_driver sc7180_lpass_cpu_platform_driver = {
module_platform_driver(sc7180_lpass_cpu_platform_driver);
MODULE_DESCRIPTION("SC7180 LPASS CPU DRIVER");
-MODULE_LICENSE("GPL v2");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/qcom/lpass-sc7280.c b/sound/soc/qcom/lpass-sc7280.c
index 6b2eb25ed939..7cd3e291382a 100644
--- a/sound/soc/qcom/lpass-sc7280.c
+++ b/sound/soc/qcom/lpass-sc7280.c
@@ -110,7 +110,7 @@ static struct snd_soc_dai_driver sc7280_lpass_cpu_dai_driver[] = {
static int sc7280_lpass_alloc_dma_channel(struct lpass_data *drvdata,
int direction, unsigned int dai_id)
{
- struct lpass_variant *v = drvdata->variant;
+ const struct lpass_variant *v = drvdata->variant;
int chan = 0;
switch (dai_id) {
@@ -196,7 +196,7 @@ static int sc7280_lpass_free_dma_channel(struct lpass_data *drvdata, int chan, u
static int sc7280_lpass_init(struct platform_device *pdev)
{
struct lpass_data *drvdata = platform_get_drvdata(pdev);
- struct lpass_variant *variant = drvdata->variant;
+ const struct lpass_variant *variant = drvdata->variant;
struct device *dev = &pdev->dev;
int ret, i;
@@ -252,7 +252,7 @@ static const struct dev_pm_ops sc7280_lpass_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(sc7280_lpass_dev_suspend, sc7280_lpass_dev_resume)
};
-static struct lpass_variant sc7280_data = {
+static const struct lpass_variant sc7280_data = {
.i2sctrl_reg_base = 0x1000,
.i2sctrl_reg_stride = 0x1000,
.i2s_ports = 3,
diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h
index bdfe66ec3314..27a2bf9a6613 100644
--- a/sound/soc/qcom/lpass.h
+++ b/sound/soc/qcom/lpass.h
@@ -139,7 +139,7 @@ struct lpass_data {
int vaif_irq;
/* SOC specific variations in the LPASS IP integration */
- struct lpass_variant *variant;
+ const struct lpass_variant *variant;
/* bit map to keep track of static channel allocations */
unsigned long dma_ch_bit_map;
@@ -398,8 +398,8 @@ struct lpass_pcm_data {
};
/* register the platform driver from the CPU DAI driver */
-int asoc_qcom_lpass_platform_register(struct platform_device *);
-int asoc_qcom_lpass_cpu_platform_remove(struct platform_device *pdev);
+int asoc_qcom_lpass_platform_register(struct platform_device *pdev);
+void asoc_qcom_lpass_cpu_platform_remove(struct platform_device *pdev);
void asoc_qcom_lpass_cpu_platform_shutdown(struct platform_device *pdev);
int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev);
extern const struct snd_soc_dai_ops asoc_qcom_lpass_cpu_dai_ops;
diff --git a/sound/soc/qcom/qdsp6/Makefile b/sound/soc/qcom/qdsp6/Makefile
index 3963bf234664..26b7c55c9c11 100644
--- a/sound/soc/qcom/qdsp6/Makefile
+++ b/sound/soc/qcom/qdsp6/Makefile
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
-snd-q6dsp-common-objs := q6dsp-common.o q6dsp-lpass-ports.o q6dsp-lpass-clocks.o
-snd-q6apm-objs := q6apm.o audioreach.o topology.o
+snd-q6dsp-common-y := q6dsp-common.o q6dsp-lpass-ports.o q6dsp-lpass-clocks.o
+snd-q6apm-y := q6apm.o audioreach.o topology.o
obj-$(CONFIG_SND_SOC_QDSP6_COMMON) += snd-q6dsp-common.o
obj-$(CONFIG_SND_SOC_QDSP6_CORE) += q6core.o
diff --git a/sound/soc/qcom/qdsp6/audioreach.c b/sound/soc/qcom/qdsp6/audioreach.c
index 5974c7929dd3..4ebaaf736fb9 100644
--- a/sound/soc/qcom/qdsp6/audioreach.c
+++ b/sound/soc/qcom/qdsp6/audioreach.c
@@ -267,6 +267,22 @@ void *audioreach_alloc_apm_cmd_pkt(int pkt_size, uint32_t opcode, uint32_t token
}
EXPORT_SYMBOL_GPL(audioreach_alloc_apm_cmd_pkt);
+void audioreach_set_default_channel_mapping(u8 *ch_map, int num_channels)
+{
+ if (num_channels == 1) {
+ ch_map[0] = PCM_CHANNEL_FL;
+ } else if (num_channels == 2) {
+ ch_map[0] = PCM_CHANNEL_FL;
+ ch_map[1] = PCM_CHANNEL_FR;
+ } else if (num_channels == 4) {
+ ch_map[0] = PCM_CHANNEL_FL;
+ ch_map[1] = PCM_CHANNEL_FR;
+ ch_map[2] = PCM_CHANNEL_LS;
+ ch_map[3] = PCM_CHANNEL_RS;
+ }
+}
+EXPORT_SYMBOL_GPL(audioreach_set_default_channel_mapping);
+
static void apm_populate_container_config(struct apm_container_obj *cfg,
struct audioreach_container *cont)
{
@@ -804,7 +820,7 @@ static int audioreach_mfc_set_media_format(struct q6apm_graph *graph,
uint32_t num_channels = cfg->num_channels;
int payload_size;
struct gpr_pkt *pkt;
- int rc;
+ int rc, i;
void *p;
payload_size = APM_MFC_CFG_PSIZE(media_format, num_channels) +
@@ -827,13 +843,8 @@ static int audioreach_mfc_set_media_format(struct q6apm_graph *graph,
media_format->sample_rate = cfg->sample_rate;
media_format->bit_width = cfg->bit_width;
media_format->num_channels = cfg->num_channels;
-
- if (num_channels == 1) {
- media_format->channel_mapping[0] = PCM_CHANNEL_L;
- } else if (num_channels == 2) {
- media_format->channel_mapping[0] = PCM_CHANNEL_L;
- media_format->channel_mapping[1] = PCM_CHANNEL_R;
- }
+ for (i = 0; i < num_channels; i++)
+ media_format->channel_mapping[i] = cfg->channel_map[i];
rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);
@@ -863,13 +874,6 @@ static int audioreach_set_compr_media_format(struct media_format *media_fmt_hdr,
mp3_cfg->q_factor = mcfg->bit_width - 1;
mp3_cfg->endianness = PCM_LITTLE_ENDIAN;
mp3_cfg->num_channels = mcfg->num_channels;
-
- if (mcfg->num_channels == 1) {
- mp3_cfg->channel_mapping[0] = PCM_CHANNEL_L;
- } else if (mcfg->num_channels == 2) {
- mp3_cfg->channel_mapping[0] = PCM_CHANNEL_L;
- mp3_cfg->channel_mapping[1] = PCM_CHANNEL_R;
- }
break;
case SND_AUDIOCODEC_AAC:
media_fmt_hdr->data_format = DATA_FORMAT_RAW_COMPRESSED;
@@ -1057,7 +1061,7 @@ static int audioreach_pcm_set_media_format(struct q6apm_graph *graph,
int rc, payload_size;
struct gpr_pkt *pkt;
- if (num_channels > 2) {
+ if (num_channels > 4) {
dev_err(graph->dev, "Error: Invalid channels (%d)!\n", num_channels);
return -EINVAL;
}
@@ -1088,14 +1092,7 @@ static int audioreach_pcm_set_media_format(struct q6apm_graph *graph,
media_cfg->num_channels = mcfg->num_channels;
media_cfg->q_factor = mcfg->bit_width - 1;
media_cfg->bits_per_sample = mcfg->bit_width;
-
- if (num_channels == 1) {
- media_cfg->channel_mapping[0] = PCM_CHANNEL_L;
- } else if (num_channels == 2) {
- media_cfg->channel_mapping[0] = PCM_CHANNEL_L;
- media_cfg->channel_mapping[1] = PCM_CHANNEL_R;
-
- }
+ memcpy(media_cfg->channel_mapping, mcfg->channel_map, mcfg->num_channels);
rc = q6apm_send_cmd_sync(graph->apm, pkt, 0);
@@ -1116,7 +1113,7 @@ static int audioreach_shmem_set_media_format(struct q6apm_graph *graph,
struct gpr_pkt *pkt;
void *p;
- if (num_channels > 2) {
+ if (num_channels > 4) {
dev_err(graph->dev, "Error: Invalid channels (%d)!\n", num_channels);
return -EINVAL;
}
@@ -1152,13 +1149,7 @@ static int audioreach_shmem_set_media_format(struct q6apm_graph *graph,
cfg->q_factor = mcfg->bit_width - 1;
cfg->endianness = PCM_LITTLE_ENDIAN;
cfg->num_channels = mcfg->num_channels;
-
- if (mcfg->num_channels == 1)
- cfg->channel_mapping[0] = PCM_CHANNEL_L;
- else if (num_channels == 2) {
- cfg->channel_mapping[0] = PCM_CHANNEL_L;
- cfg->channel_mapping[1] = PCM_CHANNEL_R;
- }
+ memcpy(cfg->channel_mapping, mcfg->channel_map, mcfg->num_channels);
} else {
rc = audioreach_set_compr_media_format(header, p, mcfg);
if (rc) {
diff --git a/sound/soc/qcom/qdsp6/audioreach.h b/sound/soc/qcom/qdsp6/audioreach.h
index e38111ffd7b9..61a69df4f50f 100644
--- a/sound/soc/qcom/qdsp6/audioreach.h
+++ b/sound/soc/qcom/qdsp6/audioreach.h
@@ -158,8 +158,6 @@ struct param_id_enc_bitrate_param {
#define MEDIA_FMT_ID_PCM 0x09001000
#define MEDIA_FMT_ID_MP3 0x09001009
-#define PCM_CHANNEL_L 1
-#define PCM_CHANNEL_R 2
#define SAMPLE_RATE_48K 48000
#define BIT_WIDTH_16 16
@@ -757,7 +755,6 @@ struct audioreach_module_config {
u16 data_format;
u16 num_channels;
- u16 active_channels_mask;
u16 dp_idx;
u32 channel_allocation;
u32 sd_line_mask;
@@ -769,6 +766,7 @@ struct audioreach_module_config {
/* Packet Allocation routines */
void *audioreach_alloc_apm_cmd_pkt(int pkt_size, uint32_t opcode, uint32_t
token);
+void audioreach_set_default_channel_mapping(u8 *ch_map, int num_channels);
void *audioreach_alloc_cmd_pkt(int payload_size, uint32_t opcode,
uint32_t token, uint32_t src_port,
uint32_t dest_port);
diff --git a/sound/soc/qcom/qdsp6/q6afe-clocks.c b/sound/soc/qcom/qdsp6/q6afe-clocks.c
index 1ccab64ff00b..84b9018c36ba 100644
--- a/sound/soc/qcom/qdsp6/q6afe-clocks.c
+++ b/sound/soc/qcom/qdsp6/q6afe-clocks.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2020, Linaro Limited
+#include <dt-bindings/sound/qcom,q6afe.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/clk-provider.h>
diff --git a/sound/soc/qcom/qdsp6/q6afe-dai.c b/sound/soc/qcom/qdsp6/q6afe-dai.c
index 3faa7e0eb0dd..7d9628cda875 100644
--- a/sound/soc/qcom/qdsp6/q6afe-dai.c
+++ b/sound/soc/qcom/qdsp6/q6afe-dai.c
@@ -2,6 +2,7 @@
// Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
// Copyright (c) 2018, Linaro Limited
+#include <dt-bindings/sound/qcom,q6afe.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/module.h>
@@ -171,8 +172,8 @@ static int q6tdm_set_tdm_slot(struct snd_soc_dai *dai,
}
static int q6tdm_set_channel_map(struct snd_soc_dai *dai,
- unsigned int tx_num, unsigned int *tx_slot,
- unsigned int rx_num, unsigned int *rx_slot)
+ unsigned int tx_num, const unsigned int *tx_slot,
+ unsigned int rx_num, const unsigned int *rx_slot)
{
struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
@@ -249,8 +250,10 @@ static int q6tdm_hw_params(struct snd_pcm_substream *substream,
}
static int q6dma_set_channel_map(struct snd_soc_dai *dai,
- unsigned int tx_num, unsigned int *tx_ch_mask,
- unsigned int rx_num, unsigned int *rx_ch_mask)
+ unsigned int tx_num,
+ const unsigned int *tx_ch_mask,
+ unsigned int rx_num,
+ const unsigned int *rx_ch_mask)
{
struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
@@ -406,8 +409,10 @@ static int q6afe_dai_prepare(struct snd_pcm_substream *substream,
}
static int q6slim_set_channel_map(struct snd_soc_dai *dai,
- unsigned int tx_num, unsigned int *tx_slot,
- unsigned int rx_num, unsigned int *rx_slot)
+ unsigned int tx_num,
+ const unsigned int *tx_slot,
+ unsigned int rx_num,
+ const unsigned int *rx_slot)
{
struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
struct q6afe_port_config *pcfg = &dai_data->port_config[dai->id];
diff --git a/sound/soc/qcom/qdsp6/q6afe.c b/sound/soc/qcom/qdsp6/q6afe.c
index 919e326b9462..ef7557be5d66 100644
--- a/sound/soc/qcom/qdsp6/q6afe.c
+++ b/sound/soc/qcom/qdsp6/q6afe.c
@@ -2,6 +2,7 @@
// Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
// Copyright (c) 2018, Linaro Limited
+#include <dt-bindings/sound/qcom,q6afe.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/uaccess.h>
@@ -552,13 +553,13 @@ struct q6afe_port {
};
struct afe_cmd_remote_lpass_core_hw_vote_request {
- uint32_t hw_block_id;
- char client_name[8];
+ uint32_t hw_block_id;
+ char client_name[8];
} __packed;
struct afe_cmd_remote_lpass_core_hw_devote_request {
- uint32_t hw_block_id;
- uint32_t client_handle;
+ uint32_t hw_block_id;
+ uint32_t client_handle;
} __packed;
diff --git a/sound/soc/qcom/qdsp6/q6afe.h b/sound/soc/qcom/qdsp6/q6afe.h
index 30fd77e2f458..65d0676075e1 100644
--- a/sound/soc/qcom/qdsp6/q6afe.h
+++ b/sound/soc/qcom/qdsp6/q6afe.h
@@ -3,8 +3,6 @@
#ifndef __Q6AFE_H__
#define __Q6AFE_H__
-#include <dt-bindings/sound/qcom,q6afe.h>
-
#define AFE_PORT_MAX 129
#define MSM_AFE_PORT_TYPE_RX 0
diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c
index 739856a00017..c9404b5934c7 100644
--- a/sound/soc/qcom/qdsp6/q6apm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6apm-dai.c
@@ -4,6 +4,7 @@
#include <linux/init.h>
#include <linux/err.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/soc.h>
@@ -12,7 +13,6 @@
#include <sound/pcm.h>
#include <asm/dma.h>
#include <linux/dma-mapping.h>
-#include <linux/of_device.h>
#include <sound/pcm_params.h>
#include "q6apm.h"
@@ -70,14 +70,10 @@ struct q6apm_dai_rtd {
unsigned int bytes_received;
unsigned int copied_total;
uint16_t bits_per_sample;
- uint16_t source; /* Encoding source bit mask */
- uint16_t session_id;
bool next_track;
enum stream_state state;
struct q6apm_graph *graph;
spinlock_t lock;
- uint32_t initial_samples_drop;
- uint32_t trailing_samples_drop;
bool notify_on_drain;
};
@@ -85,7 +81,7 @@ struct q6apm_dai_data {
long long sid;
};
-static struct snd_pcm_hardware q6apm_dai_hardware_capture = {
+static const struct snd_pcm_hardware q6apm_dai_hardware_capture = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME |
@@ -104,7 +100,7 @@ static struct snd_pcm_hardware q6apm_dai_hardware_capture = {
.fifo_size = 0,
};
-static struct snd_pcm_hardware q6apm_dai_hardware_playback = {
+static const struct snd_pcm_hardware q6apm_dai_hardware_playback = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME |
@@ -123,7 +119,7 @@ static struct snd_pcm_hardware q6apm_dai_hardware_playback = {
.fifo_size = 0,
};
-static void event_handler(uint32_t opcode, uint32_t token, uint32_t *payload, void *priv)
+static void event_handler(uint32_t opcode, uint32_t token, void *payload, void *priv)
{
struct q6apm_dai_rtd *prtd = priv;
struct snd_pcm_substream *substream = prtd->substream;
@@ -134,7 +130,7 @@ static void event_handler(uint32_t opcode, uint32_t token, uint32_t *payload, vo
prtd->state = Q6APM_STREAM_STOPPED;
break;
case APM_CLIENT_EVENT_DATA_WRITE_DONE:
- spin_lock_irqsave(&prtd->lock, flags);
+ spin_lock_irqsave(&prtd->lock, flags);
prtd->pos += prtd->pcm_count;
spin_unlock_irqrestore(&prtd->lock, flags);
snd_pcm_period_elapsed(substream);
@@ -143,7 +139,7 @@ static void event_handler(uint32_t opcode, uint32_t token, uint32_t *payload, vo
break;
case APM_CLIENT_EVENT_DATA_READ_DONE:
- spin_lock_irqsave(&prtd->lock, flags);
+ spin_lock_irqsave(&prtd->lock, flags);
prtd->pos += prtd->pcm_count;
spin_unlock_irqrestore(&prtd->lock, flags);
snd_pcm_period_elapsed(substream);
@@ -157,7 +153,7 @@ static void event_handler(uint32_t opcode, uint32_t token, uint32_t *payload, vo
}
static void event_handler_compr(uint32_t opcode, uint32_t token,
- uint32_t *payload, void *priv)
+ void *payload, void *priv)
{
struct q6apm_dai_rtd *prtd = priv;
struct snd_compr_stream *substream = prtd->cstream;
@@ -243,6 +239,7 @@ static int q6apm_dai_prepare(struct snd_soc_component *component,
cfg.num_channels = runtime->channels;
cfg.bit_width = prtd->bits_per_sample;
cfg.fmt = SND_AUDIOCODEC_PCM;
+ audioreach_set_default_channel_mapping(cfg.channel_map, runtime->channels);
if (prtd->state) {
/* clear the previous setup if any */
@@ -331,7 +328,7 @@ static int q6apm_dai_open(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
+ struct snd_soc_pcm_runtime *soc_prtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(soc_prtd, 0);
struct device *dev = component->dev;
struct q6apm_dai_data *pdata;
@@ -352,7 +349,7 @@ static int q6apm_dai_open(struct snd_soc_component *component,
spin_lock_init(&prtd->lock);
prtd->substream = substream;
- prtd->graph = q6apm_graph_open(dev, (q6apm_cb)event_handler, prtd, graph_id);
+ prtd->graph = q6apm_graph_open(dev, event_handler, prtd, graph_id);
if (IS_ERR(prtd->graph)) {
dev_err(dev, "%s: Could not allocate memory\n", __func__);
ret = PTR_ERR(prtd->graph);
@@ -496,7 +493,7 @@ static int q6apm_dai_compr_open(struct snd_soc_component *component,
return -ENOMEM;
prtd->cstream = stream;
- prtd->graph = q6apm_graph_open(dev, (q6apm_cb)event_handler_compr, prtd, graph_id);
+ prtd->graph = q6apm_graph_open(dev, event_handler_compr, prtd, graph_id);
if (IS_ERR(prtd->graph)) {
ret = PTR_ERR(prtd->graph);
kfree(prtd);
@@ -669,6 +666,8 @@ static int q6apm_dai_compr_set_params(struct snd_soc_component *component,
cfg.num_channels = 2;
cfg.bit_width = prtd->bits_per_sample;
cfg.fmt = codec->id;
+ audioreach_set_default_channel_mapping(cfg.channel_map,
+ cfg.num_channels);
memcpy(&cfg.codec, codec, sizeof(*codec));
ret = q6apm_graph_media_format_shmem(prtd->graph, &cfg);
@@ -720,14 +719,12 @@ static int q6apm_dai_compr_set_metadata(struct snd_soc_component *component,
switch (metadata->key) {
case SNDRV_COMPRESS_ENCODER_PADDING:
- prtd->trailing_samples_drop = metadata->value[0];
q6apm_remove_trailing_silence(component->dev, prtd->graph,
- prtd->trailing_samples_drop);
+ metadata->value[0]);
break;
case SNDRV_COMPRESS_ENCODER_DELAY:
- prtd->initial_samples_drop = metadata->value[0];
q6apm_remove_initial_silence(component->dev, prtd->graph,
- prtd->initial_samples_drop);
+ metadata->value[0]);
break;
default:
ret = -EINVAL;
diff --git a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
index 6511f0a08de1..9c98a35ad099 100644
--- a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
+++ b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2021, Linaro Limited
+#include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/module.h>
@@ -24,13 +25,15 @@ struct q6apm_lpass_dai_data {
};
static int q6dma_set_channel_map(struct snd_soc_dai *dai,
- unsigned int tx_num, unsigned int *tx_ch_mask,
- unsigned int rx_num, unsigned int *rx_ch_mask)
+ unsigned int tx_num,
+ const unsigned int *tx_ch_mask,
+ unsigned int rx_num,
+ const unsigned int *rx_ch_mask)
{
struct q6apm_lpass_dai_data *dai_data = dev_get_drvdata(dai->dev);
struct audioreach_module_config *cfg = &dai_data->module_config[dai->id];
- int ch_mask;
+ int i;
switch (dai->id) {
case WSA_CODEC_DMA_TX_0:
@@ -55,7 +58,8 @@ static int q6dma_set_channel_map(struct snd_soc_dai *dai,
tx_num);
return -EINVAL;
}
- ch_mask = *tx_ch_mask;
+ for (i = 0; i < tx_num; i++)
+ cfg->channel_map[i] = tx_ch_mask[i];
break;
case WSA_CODEC_DMA_RX_0:
@@ -78,7 +82,8 @@ static int q6dma_set_channel_map(struct snd_soc_dai *dai,
rx_num);
return -EINVAL;
}
- ch_mask = *rx_ch_mask;
+ for (i = 0; i < rx_num; i++)
+ cfg->channel_map[i] = rx_ch_mask[i];
break;
default:
@@ -87,8 +92,6 @@ static int q6dma_set_channel_map(struct snd_soc_dai *dai,
return -EINVAL;
}
- cfg->active_channels_mask = ch_mask;
-
return 0;
}
@@ -97,12 +100,13 @@ static int q6hdmi_hw_params(struct snd_pcm_substream *substream,
{
struct q6apm_lpass_dai_data *dai_data = dev_get_drvdata(dai->dev);
struct audioreach_module_config *cfg = &dai_data->module_config[dai->id];
- int channels = params_channels(params);
+ int channels = hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max;
int ret;
cfg->bit_width = params_width(params);
cfg->sample_rate = params_rate(params);
cfg->num_channels = channels;
+ audioreach_set_default_channel_mapping(cfg->channel_map, channels);
switch (dai->id) {
case DISPLAY_PORT_RX_0:
@@ -127,10 +131,12 @@ static int q6dma_hw_params(struct snd_pcm_substream *substream,
{
struct q6apm_lpass_dai_data *dai_data = dev_get_drvdata(dai->dev);
struct audioreach_module_config *cfg = &dai_data->module_config[dai->id];
+ int channels = hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max;
cfg->bit_width = params_width(params);
cfg->sample_rate = params_rate(params);
- cfg->num_channels = params_channels(params);
+ cfg->num_channels = channels;
+ audioreach_set_default_channel_mapping(cfg->channel_map, channels);
return 0;
}
diff --git a/sound/soc/qcom/qdsp6/q6apm.h b/sound/soc/qcom/qdsp6/q6apm.h
index f486bd639b9f..c248c8d2b1ab 100644
--- a/sound/soc/qcom/qdsp6/q6apm.h
+++ b/sound/soc/qcom/qdsp6/q6apm.h
@@ -13,7 +13,6 @@
#include <linux/of_platform.h>
#include <linux/jiffies.h>
#include <linux/soc/qcom/apr.h>
-#include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h>
#include "audioreach.h"
#define APM_PORT_MAX 127
diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c b/sound/soc/qcom/qdsp6/q6asm-dai.c
index 5e14cd0a38de..045100c94352 100644
--- a/sound/soc/qcom/qdsp6/q6asm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6asm-dai.c
@@ -2,9 +2,11 @@
// Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
// Copyright (c) 2018, Linaro Limited
+#include <dt-bindings/sound/qcom,q6asm.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/soc.h>
@@ -14,7 +16,6 @@
#include <sound/compress_driver.h>
#include <asm/dma.h>
#include <linux/dma-mapping.h>
-#include <linux/of_device.h>
#include <sound/pcm_params.h>
#include "q6asm.h"
#include "q6routing.h"
@@ -102,7 +103,7 @@ static const struct snd_pcm_hardware q6asm_dai_hardware_capture = {
.fifo_size = 0,
};
-static struct snd_pcm_hardware q6asm_dai_hardware_playback = {
+static const struct snd_pcm_hardware q6asm_dai_hardware_playback = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_BATCH |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID |
@@ -127,8 +128,13 @@ static struct snd_pcm_hardware q6asm_dai_hardware_playback = {
#define Q6ASM_FEDAI_DRIVER(num) { \
.playback = { \
.stream_name = "MultiMedia"#num" Playback", \
- .rates = (SNDRV_PCM_RATE_8000_192000| \
- SNDRV_PCM_RATE_KNOT), \
+ .rates = (SNDRV_PCM_RATE_8000_48000 | \
+ SNDRV_PCM_RATE_12000 | \
+ SNDRV_PCM_RATE_24000 | \
+ SNDRV_PCM_RATE_88200 | \
+ SNDRV_PCM_RATE_96000 | \
+ SNDRV_PCM_RATE_176400 | \
+ SNDRV_PCM_RATE_192000), \
.formats = (SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_LE), \
.channels_min = 1, \
@@ -138,8 +144,9 @@ static struct snd_pcm_hardware q6asm_dai_hardware_playback = {
}, \
.capture = { \
.stream_name = "MultiMedia"#num" Capture", \
- .rates = (SNDRV_PCM_RATE_8000_48000| \
- SNDRV_PCM_RATE_KNOT), \
+ .rates = (SNDRV_PCM_RATE_8000_48000 | \
+ SNDRV_PCM_RATE_12000 | \
+ SNDRV_PCM_RATE_24000), \
.formats = (SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_LE), \
.channels_min = 1, \
@@ -151,18 +158,6 @@ static struct snd_pcm_hardware q6asm_dai_hardware_playback = {
.id = MSM_FRONTEND_DAI_MULTIMEDIA##num, \
}
-/* Conventional and unconventional sample rate supported */
-static unsigned int supported_sample_rates[] = {
- 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
- 88200, 96000, 176400, 192000
-};
-
-static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
- .count = ARRAY_SIZE(supported_sample_rates),
- .list = supported_sample_rates,
- .mask = 0,
-};
-
static const struct snd_compr_codec_caps q6asm_compr_caps = {
.num_descriptors = 1,
.descriptor[0].max_ch = 2,
@@ -389,11 +384,6 @@ static int q6asm_dai_open(struct snd_soc_component *component,
else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
runtime->hw = q6asm_dai_hardware_capture;
- ret = snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE,
- &constraints_sample_rates);
- if (ret < 0)
- dev_info(dev, "snd_pcm_hw_constraint_list failed\n");
/* Ensure that buffer size is a multiple of period size */
ret = snd_pcm_hw_constraint_integer(runtime,
SNDRV_PCM_HW_PARAM_PERIODS);
diff --git a/sound/soc/qcom/qdsp6/q6asm.c b/sound/soc/qcom/qdsp6/q6asm.c
index 195780f75d05..06a802f9dba5 100644
--- a/sound/soc/qcom/qdsp6/q6asm.c
+++ b/sound/soc/qcom/qdsp6/q6asm.c
@@ -2,6 +2,7 @@
// Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
// Copyright (c) 2018, Linaro Limited
+#include <dt-bindings/sound/qcom,q6asm.h>
#include <linux/mutex.h>
#include <linux/wait.h>
#include <linux/module.h>
diff --git a/sound/soc/qcom/qdsp6/q6asm.h b/sound/soc/qcom/qdsp6/q6asm.h
index 394604c34943..519e1b3a3f7c 100644
--- a/sound/soc/qcom/qdsp6/q6asm.h
+++ b/sound/soc/qcom/qdsp6/q6asm.h
@@ -2,7 +2,6 @@
#ifndef __Q6_ASM_H__
#define __Q6_ASM_H__
#include "q6dsp-common.h"
-#include <dt-bindings/sound/qcom,q6asm.h>
/* ASM client callback events */
#define CMD_PAUSE 0x0001
@@ -36,16 +35,16 @@ enum {
#define ASM_LAST_BUFFER_FLAG BIT(30)
struct q6asm_flac_cfg {
- u32 sample_rate;
- u32 ext_sample_rate;
- u32 min_frame_size;
- u32 max_frame_size;
- u16 stream_info_present;
- u16 min_blk_size;
- u16 max_blk_size;
- u16 ch_cfg;
- u16 sample_size;
- u16 md5_sum;
+ u32 sample_rate;
+ u32 ext_sample_rate;
+ u32 min_frame_size;
+ u32 max_frame_size;
+ u16 stream_info_present;
+ u16 min_blk_size;
+ u16 max_blk_size;
+ u16 ch_cfg;
+ u16 sample_size;
+ u16 md5_sum;
};
struct q6asm_wma_cfg {
diff --git a/sound/soc/qcom/qdsp6/q6dsp-common.c b/sound/soc/qcom/qdsp6/q6dsp-common.c
index 95585dea2b36..f74585d88bd6 100644
--- a/sound/soc/qcom/qdsp6/q6dsp-common.c
+++ b/sound/soc/qcom/qdsp6/q6dsp-common.c
@@ -98,4 +98,6 @@ int q6dsp_get_channel_allocation(int channels)
return channel_allocation;
}
EXPORT_SYMBOL_GPL(q6dsp_get_channel_allocation);
+
+MODULE_DESCRIPTION("ASoC MSM QDSP6 helper functions");
MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c b/sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c
index 4613867d1133..e758411603be 100644
--- a/sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c
+++ b/sound/soc/qcom/qdsp6/q6dsp-lpass-clocks.c
@@ -8,7 +8,6 @@
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/of.h>
-#include <linux/of_device.h>
#include <linux/slab.h>
#include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h>
#include "q6dsp-lpass-clocks.h"
diff --git a/sound/soc/qcom/qdsp6/q6prm-clocks.c b/sound/soc/qcom/qdsp6/q6prm-clocks.c
index 73b0cbac73d4..4c574b48ab00 100644
--- a/sound/soc/qcom/qdsp6/q6prm-clocks.c
+++ b/sound/soc/qcom/qdsp6/q6prm-clocks.c
@@ -1,13 +1,13 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2021, Linaro Limited
+#include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/platform_device.h>
-#include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h>
#include "q6dsp-lpass-clocks.h"
#include "q6prm.h"
diff --git a/sound/soc/qcom/qdsp6/q6routing.c b/sound/soc/qcom/qdsp6/q6routing.c
index c583faae3a3e..90228699ba7d 100644
--- a/sound/soc/qcom/qdsp6/q6routing.c
+++ b/sound/soc/qcom/qdsp6/q6routing.c
@@ -2,14 +2,15 @@
// Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
// Copyright (c) 2018, Linaro Limited
+#include <dt-bindings/sound/qcom,q6asm.h>
+#include <dt-bindings/sound/qcom,q6afe.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/module.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
-#include <linux/of_platform.h>
#include <linux/bitops.h>
#include <linux/mutex.h>
-#include <linux/of_device.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/soc.h>
@@ -1160,7 +1161,7 @@ static struct platform_driver q6pcm_routing_platform_driver = {
.of_match_table = of_match_ptr(q6pcm_routing_device_id),
},
.probe = q6pcm_routing_probe,
- .remove_new = q6pcm_routing_remove,
+ .remove = q6pcm_routing_remove,
};
module_platform_driver(q6pcm_routing_platform_driver);
diff --git a/sound/soc/qcom/qdsp6/topology.c b/sound/soc/qcom/qdsp6/topology.c
index 130b22a34fb3..83319a928f29 100644
--- a/sound/soc/qcom/qdsp6/topology.c
+++ b/sound/soc/qcom/qdsp6/topology.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2020, Linaro Limited
+#include <linux/cleanup.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/pcm.h>
@@ -545,6 +546,7 @@ static struct audioreach_module *audioreach_parse_common_tokens(struct q6apm *ap
if (mod) {
int pn, id = 0;
+
mod->module_id = module_id;
mod->max_ip_port = max_ip_port;
mod->max_op_port = max_op_port;
@@ -729,6 +731,29 @@ static int audioreach_widget_i2s_module_load(struct audioreach_module *mod,
return 0;
}
+static int audioreach_widget_dp_module_load(struct audioreach_module *mod,
+ struct snd_soc_tplg_vendor_array *mod_array)
+{
+ struct snd_soc_tplg_vendor_value_elem *mod_elem;
+ int tkn_count = 0;
+
+ mod_elem = mod_array->value;
+
+ while (tkn_count <= (le32_to_cpu(mod_array->num_elems) - 1)) {
+ switch (le32_to_cpu(mod_elem->token)) {
+ case AR_TKN_U32_MODULE_FMT_DATA:
+ mod->data_format = le32_to_cpu(mod_elem->value);
+ break;
+ default:
+ break;
+ }
+ tkn_count++;
+ mod_elem++;
+ }
+
+ return 0;
+}
+
static int audioreach_widget_load_buffer(struct snd_soc_component *component,
int index, struct snd_soc_dapm_widget *w,
struct snd_soc_tplg_dapm_widget *tplg_w)
@@ -759,6 +784,9 @@ static int audioreach_widget_load_buffer(struct snd_soc_component *component,
case MODULE_ID_I2S_SOURCE:
audioreach_widget_i2s_module_load(mod, mod_array);
break;
+ case MODULE_ID_DISPLAY_PORT_SINK:
+ audioreach_widget_dp_module_load(mod, mod_array);
+ break;
default:
return -EINVAL;
}
@@ -1239,7 +1267,7 @@ static const struct snd_soc_tplg_kcontrol_ops audioreach_io_ops[] = {
audioreach_put_vol_ctrl_audio_mixer, snd_soc_info_volsw},
};
-static struct snd_soc_tplg_ops audioreach_tplg_ops = {
+static const struct snd_soc_tplg_ops audioreach_tplg_ops = {
.io_ops = audioreach_io_ops,
.io_ops_count = ARRAY_SIZE(audioreach_io_ops),
@@ -1261,18 +1289,19 @@ int audioreach_tplg_init(struct snd_soc_component *component)
struct snd_soc_card *card = component->card;
struct device *dev = component->dev;
const struct firmware *fw;
- char *tplg_fw_name;
int ret;
/* Inline with Qualcomm UCM configs and linux-firmware path */
- tplg_fw_name = kasprintf(GFP_KERNEL, "qcom/%s/%s-tplg.bin", card->driver_name, card->name);
+ char *tplg_fw_name __free(kfree) = kasprintf(GFP_KERNEL, "qcom/%s/%s-tplg.bin",
+ card->driver_name,
+ card->name);
if (!tplg_fw_name)
return -ENOMEM;
ret = request_firmware(&fw, tplg_fw_name, dev);
if (ret < 0) {
- dev_err(dev, "tplg firmware loading %s failed %d \n", tplg_fw_name, ret);
- goto err;
+ dev_err(dev, "tplg firmware loading %s failed %d\n", tplg_fw_name, ret);
+ return ret;
}
ret = snd_soc_tplg_component_load(component, &audioreach_tplg_ops, fw);
@@ -1282,8 +1311,6 @@ int audioreach_tplg_init(struct snd_soc_component *component)
}
release_firmware(fw);
-err:
- kfree(tplg_fw_name);
return ret;
}
diff --git a/sound/soc/qcom/sc7180.c b/sound/soc/qcom/sc7180.c
index d1fd40e3f7a9..bc030ce29680 100644
--- a/sound/soc/qcom/sc7180.c
+++ b/sound/soc/qcom/sc7180.c
@@ -5,10 +5,10 @@
// sc7180.c -- ALSA SoC Machine driver for SC7180
#include <dt-bindings/sound/sc7180-lpass.h>
-#include <linux/gpio.h>
+#include <dt-bindings/sound/qcom,q6afe.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <sound/core.h>
#include <sound/jack.h>
@@ -19,9 +19,10 @@
#include "../codecs/rt5682.h"
#include "../codecs/rt5682s.h"
#include "common.h"
-#include "lpass.h"
+#include "qdsp6/q6afe.h"
#define DEFAULT_MCLK_RATE 19200000
+#define MI2S_BCLK_RATE 1536000
#define RT5682_PLL1_FREQ (48000 * 512)
#define DRIVER_NAME "SC7180"
@@ -134,12 +135,28 @@ static int sc7180_init(struct snd_soc_pcm_runtime *rtd)
return 0;
}
-static int sc7180_snd_startup(struct snd_pcm_substream *substream)
+static int sc7180_qdsp_init(struct snd_soc_pcm_runtime *rtd)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_card *card = rtd->card;
- struct sc7180_snd_data *data = snd_soc_card_get_drvdata(card);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
+
+ switch (cpu_dai->id) {
+ case PRIMARY_MI2S_RX:
+ return sc7180_headset_init(rtd);
+ case PRIMARY_MI2S_TX:
+ case TERTIARY_MI2S_RX:
+ return 0;
+ case DISPLAY_PORT_RX:
+ return sc7180_hdmi_init(rtd);
+ default:
+ dev_err(rtd->dev, "%s: invalid dai id 0x%x\n", __func__,
+ cpu_dai->id);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int sc7180_startup_realtek_codec(struct snd_soc_pcm_runtime *rtd)
+{
struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
int pll_id, pll_source, pll_in, pll_out, clk_id, ret;
@@ -155,8 +172,40 @@ static int sc7180_snd_startup(struct snd_pcm_substream *substream)
clk_id = RT5682S_SCLK_S_PLL2;
pll_out = RT5682_PLL1_FREQ;
pll_in = DEFAULT_MCLK_RATE;
+ } else {
+ return 0;
+ }
+ snd_soc_dai_set_fmt(codec_dai,
+ SND_SOC_DAIFMT_BC_FC |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_I2S);
+
+ /* Configure PLL1 for codec */
+ ret = snd_soc_dai_set_pll(codec_dai, pll_id, pll_source,
+ pll_in, pll_out);
+ if (ret) {
+ dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
+ return ret;
}
+ /* Configure sysclk for codec */
+ ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, pll_out,
+ SND_SOC_CLOCK_IN);
+ if (ret)
+ dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n",
+ ret);
+
+ return ret;
+}
+
+static int sc7180_snd_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct snd_soc_card *card = rtd->card;
+ struct sc7180_snd_data *data = snd_soc_card_get_drvdata(card);
+ struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
+ int ret;
+
switch (cpu_dai->id) {
case MI2S_PRIMARY:
if (++data->pri_mi2s_clk_count == 1) {
@@ -166,30 +215,66 @@ static int sc7180_snd_startup(struct snd_pcm_substream *substream)
SNDRV_PCM_STREAM_PLAYBACK);
}
- snd_soc_dai_set_fmt(codec_dai,
- SND_SOC_DAIFMT_BC_FC |
- SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_I2S);
-
- /* Configure PLL1 for codec */
- ret = snd_soc_dai_set_pll(codec_dai, pll_id, pll_source,
- pll_in, pll_out);
- if (ret) {
- dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
+ ret = sc7180_startup_realtek_codec(rtd);
+ if (ret)
return ret;
+
+ break;
+ case MI2S_SECONDARY:
+ break;
+ case LPASS_DP_RX:
+ break;
+ default:
+ dev_err(rtd->dev, "%s: invalid dai id 0x%x\n", __func__,
+ cpu_dai->id);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int sc7180_qdsp_snd_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct snd_soc_card *card = rtd->card;
+ struct sc7180_snd_data *data = snd_soc_card_get_drvdata(card);
+ struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
+ struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
+ int ret;
+
+ switch (cpu_dai->id) {
+ case PRIMARY_MI2S_RX:
+ case PRIMARY_MI2S_TX:
+ if (++data->pri_mi2s_clk_count == 1) {
+ snd_soc_dai_set_sysclk(cpu_dai,
+ Q6AFE_LPASS_CLK_ID_MCLK_1,
+ DEFAULT_MCLK_RATE,
+ SNDRV_PCM_STREAM_PLAYBACK);
+ snd_soc_dai_set_sysclk(cpu_dai,
+ Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT,
+ MI2S_BCLK_RATE,
+ SNDRV_PCM_STREAM_PLAYBACK);
}
- /* Configure sysclk for codec */
- ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, pll_out,
- SND_SOC_CLOCK_IN);
+ snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_BP_FP);
+
+ ret = sc7180_startup_realtek_codec(rtd);
if (ret)
- dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n",
- ret);
+ return ret;
break;
- case MI2S_SECONDARY:
+ case TERTIARY_MI2S_RX:
+ snd_soc_dai_set_sysclk(cpu_dai,
+ Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT,
+ MI2S_BCLK_RATE,
+ SNDRV_PCM_STREAM_PLAYBACK);
+
+ snd_soc_dai_set_fmt(codec_dai,
+ SND_SOC_DAIFMT_BC_FC |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_I2S);
+ snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_BP_FP);
break;
- case LPASS_DP_RX:
+ case DISPLAY_PORT_RX:
break;
default:
dev_err(rtd->dev, "%s: invalid dai id 0x%x\n", __func__,
@@ -222,7 +307,7 @@ static int dmic_set(struct snd_kcontrol *kcontrol,
static void sc7180_snd_shutdown(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card;
struct sc7180_snd_data *data = snd_soc_card_get_drvdata(card);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
@@ -247,6 +332,42 @@ static void sc7180_snd_shutdown(struct snd_pcm_substream *substream)
}
}
+static void sc7180_qdsp_snd_shutdown(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct snd_soc_card *card = rtd->card;
+ struct sc7180_snd_data *data = snd_soc_card_get_drvdata(card);
+ struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
+
+ switch (cpu_dai->id) {
+ case PRIMARY_MI2S_RX:
+ case PRIMARY_MI2S_TX:
+ if (--data->pri_mi2s_clk_count == 0) {
+ snd_soc_dai_set_sysclk(cpu_dai,
+ Q6AFE_LPASS_CLK_ID_MCLK_1,
+ 0,
+ SNDRV_PCM_STREAM_PLAYBACK);
+ snd_soc_dai_set_sysclk(cpu_dai,
+ Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT,
+ 0,
+ SNDRV_PCM_STREAM_PLAYBACK);
+ }
+ break;
+ case TERTIARY_MI2S_RX:
+ snd_soc_dai_set_sysclk(cpu_dai,
+ Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT,
+ 0,
+ SNDRV_PCM_STREAM_PLAYBACK);
+ break;
+ case DISPLAY_PORT_RX:
+ break;
+ default:
+ dev_err(rtd->dev, "%s: invalid dai id 0x%x\n", __func__,
+ cpu_dai->id);
+ break;
+ }
+}
+
static int sc7180_adau7002_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
@@ -268,7 +389,7 @@ static int sc7180_adau7002_init(struct snd_soc_pcm_runtime *rtd)
static int sc7180_adau7002_snd_startup(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
struct snd_pcm_runtime *runtime = substream->runtime;
@@ -295,11 +416,30 @@ static int sc7180_adau7002_snd_startup(struct snd_pcm_substream *substream)
return 0;
}
+static int sc7180_qdsp_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ 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 = channels->max = 2;
+
+ return 0;
+}
+
static const struct snd_soc_ops sc7180_ops = {
.startup = sc7180_snd_startup,
.shutdown = sc7180_snd_shutdown,
};
+static const struct snd_soc_ops sc7180_qdsp_ops = {
+ .startup = sc7180_qdsp_snd_startup,
+ .shutdown = sc7180_qdsp_snd_shutdown,
+};
+
static const struct snd_soc_ops sc7180_adau7002_ops = {
.startup = sc7180_adau7002_snd_startup,
};
@@ -355,7 +495,7 @@ static int sc7180_snd_platform_probe(struct platform_device *pdev)
struct snd_soc_dai_link *link;
int ret;
int i;
- bool no_headphone = false;
+ bool qdsp = false, no_headphone = false;
/* Allocate the private data */
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
@@ -391,6 +531,8 @@ static int sc7180_snd_platform_probe(struct platform_device *pdev)
no_headphone = true;
card->dapm_widgets = sc7180_adau7002_snd_widgets;
card->num_dapm_widgets = ARRAY_SIZE(sc7180_adau7002_snd_widgets);
+ } else if (of_device_is_compatible(dev->of_node, "qcom,sc7180-qdsp6-sndcard")) {
+ qdsp = true;
}
ret = qcom_snd_parse_of(card);
@@ -401,6 +543,12 @@ static int sc7180_snd_platform_probe(struct platform_device *pdev)
if (no_headphone) {
link->ops = &sc7180_adau7002_ops;
link->init = sc7180_adau7002_init;
+ } else if (qdsp) {
+ if (link->no_pcm == 1) {
+ link->ops = &sc7180_qdsp_ops;
+ link->be_hw_params_fixup = sc7180_qdsp_be_hw_params_fixup;
+ link->init = sc7180_qdsp_init;
+ }
} else {
link->ops = &sc7180_ops;
link->init = sc7180_init;
@@ -413,6 +561,7 @@ static int sc7180_snd_platform_probe(struct platform_device *pdev)
static const struct of_device_id sc7180_snd_device_id[] = {
{.compatible = "google,sc7180-trogdor"},
{.compatible = "google,sc7180-coachz"},
+ {.compatible = "qcom,sc7180-qdsp6-sndcard"},
{},
};
MODULE_DEVICE_TABLE(of, sc7180_snd_device_id);
@@ -428,4 +577,4 @@ static struct platform_driver sc7180_snd_driver = {
module_platform_driver(sc7180_snd_driver);
MODULE_DESCRIPTION("sc7180 ASoC Machine Driver");
-MODULE_LICENSE("GPL v2");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/qcom/sc7280.c b/sound/soc/qcom/sc7280.c
index c23df4c8f341..230af8d7b205 100644
--- a/sound/soc/qcom/sc7280.c
+++ b/sound/soc/qcom/sc7280.c
@@ -4,9 +4,11 @@
//
// ALSA SoC Machine driver for sc7280
+#include <dt-bindings/sound/qcom,lpass.h>
+#include <dt-bindings/sound/qcom,q6afe.h>
#include <linux/input.h>
+#include <linux/mod_devicetable.h>
#include <linux/module.h>
-#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <sound/core.h>
#include <sound/jack.h>
@@ -21,6 +23,7 @@
#include "common.h"
#include "lpass.h"
#include "qdsp6/q6afe.h"
+#include "sdw.h"
#define DEFAULT_MCLK_RATE 19200000
#define RT5682_PLL_FREQ (48000 * 512)
@@ -203,7 +206,7 @@ static int sc7280_snd_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai;
const struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct sc7280_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card);
@@ -235,7 +238,7 @@ static int sc7280_snd_hw_params(struct snd_pcm_substream *substream,
static int sc7280_snd_swr_prepare(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
const struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct sc7280_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
@@ -266,7 +269,7 @@ static int sc7280_snd_swr_prepare(struct snd_pcm_substream *substream)
static int sc7280_snd_prepare(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
const struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
switch (cpu_dai->id) {
@@ -285,7 +288,7 @@ static int sc7280_snd_prepare(struct snd_pcm_substream *substream)
static int sc7280_snd_hw_free(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct sc7280_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
const struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
@@ -310,10 +313,11 @@ static int sc7280_snd_hw_free(struct snd_pcm_substream *substream)
static void sc7280_snd_shutdown(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card;
struct sc7280_snd_data *data = snd_soc_card_get_drvdata(card);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
+ struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
switch (cpu_dai->id) {
case MI2S_PRIMARY:
@@ -331,13 +335,16 @@ static void sc7280_snd_shutdown(struct snd_pcm_substream *substream)
default:
break;
}
+
+ data->sruntime[cpu_dai->id] = NULL;
+ sdw_release_stream(sruntime);
}
static int sc7280_snd_startup(struct snd_pcm_substream *substream)
{
unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
unsigned int codec_dai_fmt = SND_SOC_DAIFMT_CBS_CFS;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
int ret = 0;
@@ -345,6 +352,8 @@ static int sc7280_snd_startup(struct snd_pcm_substream *substream)
switch (cpu_dai->id) {
case MI2S_PRIMARY:
ret = sc7280_rt5682_init(rtd);
+ if (ret)
+ return ret;
break;
case SECONDARY_MI2S_RX:
codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S;
@@ -358,7 +367,8 @@ static int sc7280_snd_startup(struct snd_pcm_substream *substream)
default:
break;
}
- return ret;
+
+ return qcom_snd_sdw_startup(substream);
}
static const struct snd_soc_ops sc7280_ops = {
diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c
index 6e5f194bc34b..922ecada1cd8 100644
--- a/sound/soc/qcom/sc8280xp.c
+++ b/sound/soc/qcom/sc8280xp.c
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2022, Linaro Limited
+#include <dt-bindings/sound/qcom,q6afe.h>
#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>
@@ -14,21 +14,22 @@
#include "common.h"
#include "sdw.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;
+ struct snd_soc_jack dp_jack[8];
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);
- struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+ struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct snd_soc_card *card = rtd->card;
+ struct snd_soc_jack *dp_jack = NULL;
+ int dp_pcm_id = 0;
switch (cpu_dai->id) {
case WSA_CODEC_DMA_RX_0:
@@ -43,13 +44,36 @@ static int sc8280xp_snd_init(struct snd_soc_pcm_runtime *rtd)
snd_soc_limit_volume(card, "SpkrLeft PA Volume", 17);
snd_soc_limit_volume(card, "SpkrRight PA Volume", 17);
break;
+ case DISPLAY_PORT_RX_0:
+ /* DISPLAY_PORT dai ids are not contiguous */
+ dp_pcm_id = 0;
+ dp_jack = &data->dp_jack[dp_pcm_id];
+ break;
+ case DISPLAY_PORT_RX_1 ... DISPLAY_PORT_RX_7:
+ dp_pcm_id = cpu_dai->id - DISPLAY_PORT_RX_1 + 1;
+ dp_jack = &data->dp_jack[dp_pcm_id];
+ break;
default:
break;
}
+ if (dp_jack)
+ return qcom_snd_dp_jack_setup(rtd, dp_jack, dp_pcm_id);
+
return qcom_snd_wcd_jack_setup(rtd, &data->jack, &data->jack_setup);
}
+static void sc8280xp_snd_shutdown(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
+ struct sc8280xp_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card);
+ struct sdw_stream_runtime *sruntime = pdata->sruntime[cpu_dai->id];
+
+ pdata->sruntime[cpu_dai->id] = NULL;
+ sdw_release_stream(sruntime);
+}
+
static int sc8280xp_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
@@ -80,7 +104,7 @@ static int sc8280xp_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
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_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct sc8280xp_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card);
@@ -89,7 +113,7 @@ static int sc8280xp_snd_hw_params(struct snd_pcm_substream *substream,
static int sc8280xp_snd_prepare(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_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];
@@ -100,7 +124,7 @@ static int sc8280xp_snd_prepare(struct snd_pcm_substream *substream)
static int sc8280xp_snd_hw_free(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
@@ -110,6 +134,8 @@ static int sc8280xp_snd_hw_free(struct snd_pcm_substream *substream)
}
static const struct snd_soc_ops sc8280xp_be_ops = {
+ .startup = qcom_snd_sdw_startup,
+ .shutdown = sc8280xp_snd_shutdown,
.hw_params = sc8280xp_snd_hw_params,
.hw_free = sc8280xp_snd_hw_free,
.prepare = sc8280xp_snd_prepare,
@@ -152,13 +178,18 @@ static int sc8280xp_platform_probe(struct platform_device *pdev)
if (ret)
return ret;
- card->driver_name = DRIVER_NAME;
+ card->driver_name = of_device_get_match_data(dev);
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",},
+ {.compatible = "qcom,qcm6490-idp-sndcard", "qcm6490"},
+ {.compatible = "qcom,qcs6490-rb3gen2-sndcard", "qcs6490"},
+ {.compatible = "qcom,sc8280xp-sndcard", "sc8280xp"},
+ {.compatible = "qcom,sm8450-sndcard", "sm8450"},
+ {.compatible = "qcom,sm8550-sndcard", "sm8550"},
+ {.compatible = "qcom,sm8650-sndcard", "sm8650"},
{}
};
@@ -174,4 +205,4 @@ static struct platform_driver snd_sc8280xp_driver = {
module_platform_driver(snd_sc8280xp_driver);
MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org");
MODULE_DESCRIPTION("SC8280XP ASoC Machine Driver");
-MODULE_LICENSE("GPL v2");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/qcom/sdm845.c b/sound/soc/qcom/sdm845.c
index 25b964dea6c5..a479d7e5b7fb 100644
--- a/sound/soc/qcom/sdm845.c
+++ b/sound/soc/qcom/sdm845.c
@@ -3,9 +3,9 @@
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
*/
+#include <dt-bindings/sound/qcom,q6afe.h>
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/of_device.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -15,6 +15,7 @@
#include <uapi/linux/input-event-codes.h>
#include "common.h"
#include "qdsp6/q6afe.h"
+#include "sdw.h"
#include "../codecs/rt5663.h"
#define DRIVER_NAME "sdm845"
@@ -416,7 +417,7 @@ static int sdm845_snd_startup(struct snd_pcm_substream *substream)
pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id);
break;
}
- return 0;
+ return qcom_snd_sdw_startup(substream);
}
static void sdm845_snd_shutdown(struct snd_pcm_substream *substream)
@@ -425,6 +426,7 @@ static void sdm845_snd_shutdown(struct snd_pcm_substream *substream)
struct snd_soc_card *card = rtd->card;
struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
+ struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
switch (cpu_dai->id) {
case PRIMARY_MI2S_RX:
@@ -463,6 +465,9 @@ static void sdm845_snd_shutdown(struct snd_pcm_substream *substream)
pr_err("%s: invalid dai id 0x%x\n", __func__, cpu_dai->id);
break;
}
+
+ data->sruntime[cpu_dai->id] = NULL;
+ sdw_release_stream(sruntime);
}
static int sdm845_snd_prepare(struct snd_pcm_substream *substream)
@@ -625,4 +630,4 @@ static struct platform_driver sdm845_snd_driver = {
module_platform_driver(sdm845_snd_driver);
MODULE_DESCRIPTION("sdm845 ASoC Machine Driver");
-MODULE_LICENSE("GPL v2");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/qcom/sdw.c b/sound/soc/qcom/sdw.c
index ce89c0a33ef0..f2eda2ff46c0 100644
--- a/sound/soc/qcom/sdw.c
+++ b/sound/soc/qcom/sdw.c
@@ -1,17 +1,60 @@
// SPDX-License-Identifier: GPL-2.0
-// Copyright (c) 2018, Linaro Limited.
+// Copyright (c) 2018-2023, Linaro Limited.
// Copyright (c) 2018, The Linux Foundation. All rights reserved.
+#include <dt-bindings/sound/qcom,q6afe.h>
#include <linux/module.h>
#include <sound/soc.h>
-#include "qdsp6/q6afe.h"
#include "sdw.h"
+/**
+ * qcom_snd_sdw_startup() - Helper to start Soundwire stream for SoC audio card
+ * @substream: The PCM substream from audio, as passed to snd_soc_ops->startup()
+ *
+ * Helper for the SoC audio card (snd_soc_ops->startup()) to allocate and set
+ * Soundwire stream runtime to each codec DAI.
+ *
+ * The shutdown() callback should call sdw_release_stream() on the same
+ * sdw_stream_runtime.
+ *
+ * Return: 0 or errno
+ */
+int qcom_snd_sdw_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
+ struct sdw_stream_runtime *sruntime;
+ struct snd_soc_dai *codec_dai;
+ int ret, i;
+
+ sruntime = sdw_alloc_stream(cpu_dai->name);
+ if (!sruntime)
+ return -ENOMEM;
+
+ for_each_rtd_codec_dais(rtd, i, codec_dai) {
+ ret = snd_soc_dai_set_stream(codec_dai, sruntime,
+ substream->stream);
+ if (ret < 0 && ret != -ENOTSUPP) {
+ dev_err(rtd->dev, "Failed to set sdw stream on %s\n",
+ codec_dai->name);
+ goto err_set_stream;
+ }
+ }
+
+ return 0;
+
+err_set_stream:
+ sdw_release_stream(sruntime);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(qcom_snd_sdw_startup);
+
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_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
int ret;
@@ -62,7 +105,7 @@ 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_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai;
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct sdw_stream_runtime *sruntime;
@@ -92,7 +135,7 @@ 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_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
switch (cpu_dai->id) {
@@ -117,4 +160,5 @@ int qcom_snd_sdw_hw_free(struct snd_pcm_substream *substream,
return 0;
}
EXPORT_SYMBOL_GPL(qcom_snd_sdw_hw_free);
-MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Qualcomm ASoC SoundWire helper functions");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/qcom/sdw.h b/sound/soc/qcom/sdw.h
index d74cbb84da13..392e3455f1b1 100644
--- a/sound/soc/qcom/sdw.h
+++ b/sound/soc/qcom/sdw.h
@@ -6,6 +6,7 @@
#include <linux/soundwire/sdw.h>
+int qcom_snd_sdw_startup(struct snd_pcm_substream *substream);
int qcom_snd_sdw_prepare(struct snd_pcm_substream *substream,
struct sdw_stream_runtime *runtime,
bool *stream_prepared);
diff --git a/sound/soc/qcom/sm8250.c b/sound/soc/qcom/sm8250.c
index 9eb8ae0196d9..19adadedc88a 100644
--- a/sound/soc/qcom/sm8250.c
+++ b/sound/soc/qcom/sm8250.c
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2020, Linaro Limited
+#include <dt-bindings/sound/qcom,q6afe.h>
#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>
@@ -50,11 +50,19 @@ static int sm8250_snd_startup(struct snd_pcm_substream *substream)
{
unsigned int fmt = SND_SOC_DAIFMT_BP_FP;
unsigned int codec_dai_fmt = SND_SOC_DAIFMT_BC_FC;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
switch (cpu_dai->id) {
+ case PRIMARY_MI2S_RX:
+ codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S;
+ snd_soc_dai_set_sysclk(cpu_dai,
+ Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT,
+ MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
+ snd_soc_dai_set_fmt(cpu_dai, fmt);
+ snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt);
+ break;
case TERTIARY_MI2S_RX:
codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S;
snd_soc_dai_set_sysclk(cpu_dai,
@@ -66,13 +74,25 @@ static int sm8250_snd_startup(struct snd_pcm_substream *substream)
default:
break;
}
- return 0;
+
+ return qcom_snd_sdw_startup(substream);
+}
+
+static void sm2450_snd_shutdown(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct snd_soc_dai *cpu_dai = snd_soc_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];
+
+ data->sruntime[cpu_dai->id] = NULL;
+ sdw_release_stream(sruntime);
}
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_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct sm8250_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card);
@@ -81,7 +101,7 @@ static int sm8250_snd_hw_params(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_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai *cpu_dai = snd_soc_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];
@@ -92,7 +112,7 @@ static int sm8250_snd_prepare(struct snd_pcm_substream *substream)
static int sm8250_snd_hw_free(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
@@ -103,6 +123,7 @@ static int sm8250_snd_hw_free(struct snd_pcm_substream *substream)
static const struct snd_soc_ops sm8250_be_ops = {
.startup = sm8250_snd_startup,
+ .shutdown = sm2450_snd_shutdown,
.hw_params = sm8250_snd_hw_params,
.hw_free = sm8250_snd_hw_free,
.prepare = sm8250_snd_prepare,
@@ -170,4 +191,4 @@ static struct platform_driver snd_sm8250_driver = {
module_platform_driver(snd_sm8250_driver);
MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org");
MODULE_DESCRIPTION("SM8250 ASoC Machine Driver");
-MODULE_LICENSE("GPL v2");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/qcom/storm.c b/sound/soc/qcom/storm.c
index 553165f11d30..c8d5ac43a176 100644
--- a/sound/soc/qcom/storm.c
+++ b/sound/soc/qcom/storm.c
@@ -140,4 +140,4 @@ static struct platform_driver storm_platform_driver = {
module_platform_driver(storm_platform_driver);
MODULE_DESCRIPTION("QTi IPQ806x-based Storm Machine Driver");
-MODULE_LICENSE("GPL v2");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/qcom/x1e80100.c b/sound/soc/qcom/x1e80100.c
new file mode 100644
index 000000000000..898b5c26bf1e
--- /dev/null
+++ b/sound/soc/qcom/x1e80100.c
@@ -0,0 +1,206 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2023, Linaro Limited
+
+#include <dt-bindings/sound/qcom,q6afe.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/soundwire/sdw.h>
+#include <sound/pcm.h>
+#include <sound/jack.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+#include "common.h"
+#include "qdsp6/q6afe.h"
+#include "qdsp6/q6dsp-common.h"
+#include "sdw.h"
+
+struct x1e80100_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;
+ struct snd_soc_jack dp_jack[8];
+ bool jack_setup;
+};
+
+static int x1e80100_snd_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct x1e80100_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
+ struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
+ struct snd_soc_jack *dp_jack = NULL;
+ int dp_pcm_id = 0;
+
+ switch (cpu_dai->id) {
+ case DISPLAY_PORT_RX_0:
+ dp_pcm_id = 0;
+ dp_jack = &data->dp_jack[dp_pcm_id];
+ break;
+ case DISPLAY_PORT_RX_1 ... DISPLAY_PORT_RX_7:
+ dp_pcm_id = cpu_dai->id - DISPLAY_PORT_RX_1 + 1;
+ dp_jack = &data->dp_jack[dp_pcm_id];
+ break;
+ default:
+ break;
+ }
+
+ if (dp_jack)
+ return qcom_snd_dp_jack_setup(rtd, dp_jack, dp_pcm_id);
+
+ return qcom_snd_wcd_jack_setup(rtd, &data->jack, &data->jack_setup);
+}
+
+static void x1e80100_snd_shutdown(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
+ struct x1e80100_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
+ struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
+
+ data->sruntime[cpu_dai->id] = NULL;
+ sdw_release_stream(sruntime);
+}
+
+static int x1e80100_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_dai *cpu_dai = snd_soc_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;
+ 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 x1e80100_snd_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
+ struct x1e80100_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
+
+ return qcom_snd_sdw_hw_params(substream, params, &data->sruntime[cpu_dai->id]);
+}
+
+static int x1e80100_snd_prepare(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
+ struct x1e80100_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
+ struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id];
+ const unsigned int rx_slot[4] = { PCM_CHANNEL_FL,
+ PCM_CHANNEL_LB,
+ PCM_CHANNEL_FR,
+ PCM_CHANNEL_RB };
+ int ret;
+
+ switch (cpu_dai->id) {
+ case WSA_CODEC_DMA_RX_0:
+ case WSA_CODEC_DMA_RX_1:
+ ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL,
+ ARRAY_SIZE(rx_slot), rx_slot);
+ if (ret)
+ return ret;
+ break;
+ default:
+ break;
+ }
+
+ return qcom_snd_sdw_prepare(substream, sruntime,
+ &data->stream_prepared[cpu_dai->id]);
+}
+
+static int x1e80100_snd_hw_free(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct x1e80100_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
+ struct snd_soc_dai *cpu_dai = snd_soc_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 x1e80100_be_ops = {
+ .startup = qcom_snd_sdw_startup,
+ .shutdown = x1e80100_snd_shutdown,
+ .hw_params = x1e80100_snd_hw_params,
+ .hw_free = x1e80100_snd_hw_free,
+ .prepare = x1e80100_snd_prepare,
+};
+
+static void x1e80100_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 = x1e80100_snd_init;
+ link->be_hw_params_fixup = x1e80100_be_hw_params_fixup;
+ link->ops = &x1e80100_be_ops;
+ }
+ }
+}
+
+static int x1e80100_platform_probe(struct platform_device *pdev)
+{
+ struct snd_soc_card *card;
+ struct x1e80100_snd_data *data;
+ struct device *dev = &pdev->dev;
+ int ret;
+
+ card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
+ if (!card)
+ return -ENOMEM;
+ /* Allocate the private data */
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ card->owner = THIS_MODULE;
+ 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 = "x1e80100";
+ x1e80100_add_be_ops(card);
+
+ return devm_snd_soc_register_card(dev, card);
+}
+
+static const struct of_device_id snd_x1e80100_dt_match[] = {
+ { .compatible = "qcom,x1e80100-sndcard", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, snd_x1e80100_dt_match);
+
+static struct platform_driver snd_x1e80100_driver = {
+ .probe = x1e80100_platform_probe,
+ .driver = {
+ .name = "snd-x1e80100",
+ .of_match_table = snd_x1e80100_dt_match,
+ },
+};
+module_platform_driver(snd_x1e80100_driver);
+MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org");
+MODULE_AUTHOR("Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>");
+MODULE_DESCRIPTION("Qualcomm X1E80100 ASoC Machine Driver");
+MODULE_LICENSE("GPL");