aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sound/sdw.h49
-rw-r--r--sound/soc/codecs/max98373-sdw.c31
-rw-r--r--sound/soc/codecs/max9867.c33
-rw-r--r--sound/soc/codecs/rt1308-sdw.c33
-rw-r--r--sound/soc/codecs/rt1316-sdw.c32
-rw-r--r--sound/soc/codecs/rt5640.c8
-rw-r--r--sound/soc/codecs/rt5682-sdw.c28
-rw-r--r--sound/soc/codecs/rt700.c32
-rw-r--r--sound/soc/codecs/rt711-sdca.c27
-rw-r--r--sound/soc/codecs/rt711.c27
-rw-r--r--sound/soc/codecs/rt715-sdca.c25
-rw-r--r--sound/soc/codecs/rt715.c25
-rw-r--r--sound/soc/codecs/sdw-mockup.c28
-rw-r--r--sound/soc/qcom/lpass-sc7180.c26
-rw-r--r--sound/soc/sh/Kconfig2
-rw-r--r--sound/soc/sh/rcar/adg.c4
-rw-r--r--sound/soc/sof/Kconfig2
-rw-r--r--sound/soc/sof/amd/acp-common.c1
-rw-r--r--sound/soc/sof/amd/acp-ipc.c30
-rw-r--r--sound/soc/sof/amd/acp.c4
-rw-r--r--sound/soc/sof/amd/acp.h12
-rw-r--r--sound/soc/sof/amd/rembrandt.c16
-rw-r--r--sound/soc/sof/amd/renoir.c16
23 files changed, 288 insertions, 203 deletions
diff --git a/include/sound/sdw.h b/include/sound/sdw.h
new file mode 100644
index 000000000000..6dcdb3228dba
--- /dev/null
+++ b/include/sound/sdw.h
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * linux/sound/sdw.h -- SoundWire helpers for ALSA/ASoC
+ *
+ * Copyright (c) 2022 Cirrus Logic Inc.
+ *
+ * Author: Charles Keepax <[email protected]>
+ */
+
+#include <linux/soundwire/sdw.h>
+#include <sound/asound.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+
+#ifndef __INCLUDE_SOUND_SDW_H
+#define __INCLUDE_SOUND_SDW_H
+
+/**
+ * snd_sdw_params_to_config() - Conversion from hw_params to SoundWire config
+ *
+ * @substream: Pointer to the PCM substream structure
+ * @params: Pointer to the hardware params structure
+ * @stream_config: Stream configuration for the SoundWire audio stream
+ * @port_config: Port configuration for the SoundWire audio stream
+ *
+ * This function provides a basic conversion from the hw_params structure to
+ * SoundWire configuration structures. The user will at a minimum need to also
+ * set the port number in the port config, but may also override more of the
+ * setup, or in the case of a complex user, not use this helper at all and
+ * open-code everything.
+ */
+static inline void snd_sdw_params_to_config(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct sdw_stream_config *stream_config,
+ struct sdw_port_config *port_config)
+{
+ stream_config->frame_rate = params_rate(params);
+ stream_config->ch_count = params_channels(params);
+ stream_config->bps = snd_pcm_format_width(params_format(params));
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ stream_config->direction = SDW_DATA_DIR_RX;
+ else
+ stream_config->direction = SDW_DATA_DIR_TX;
+
+ port_config->ch_mask = GENMASK(stream_config->ch_count - 1, 0);
+}
+
+#endif
diff --git a/sound/soc/codecs/max98373-sdw.c b/sound/soc/codecs/max98373-sdw.c
index 899965b19d12..3cd1be743d9e 100644
--- a/sound/soc/codecs/max98373-sdw.c
+++ b/sound/soc/codecs/max98373-sdw.c
@@ -10,6 +10,7 @@
#include <linux/slab.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
+#include <sound/sdw.h>
#include <sound/soc.h>
#include <sound/tlv.h>
#include <linux/of.h>
@@ -533,10 +534,8 @@ static int max98373_sdw_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_component *component = dai->component;
struct max98373_priv *max98373 =
snd_soc_component_get_drvdata(component);
-
- struct sdw_stream_config stream_config;
- struct sdw_port_config port_config;
- enum sdw_data_direction direction;
+ struct sdw_stream_config stream_config = {0};
+ struct sdw_port_config port_config = {0};
struct sdw_stream_data *stream;
int ret, chan_sz, sampling_rate;
@@ -548,28 +547,20 @@ static int max98373_sdw_dai_hw_params(struct snd_pcm_substream *substream,
if (!max98373->slave)
return -EINVAL;
+ snd_sdw_params_to_config(substream, params, &stream_config, &port_config);
+
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- direction = SDW_DATA_DIR_RX;
port_config.num = 1;
+
+ if (max98373->slot) {
+ stream_config.ch_count = max98373->slot;
+ port_config.ch_mask = max98373->rx_mask;
+ }
} else {
- direction = SDW_DATA_DIR_TX;
port_config.num = 3;
- }
- stream_config.frame_rate = params_rate(params);
- stream_config.bps = snd_pcm_format_width(params_format(params));
- stream_config.direction = direction;
-
- if (max98373->slot && direction == SDW_DATA_DIR_RX) {
- stream_config.ch_count = max98373->slot;
- port_config.ch_mask = max98373->rx_mask;
- } else {
/* only IV are supported by capture */
- if (direction == SDW_DATA_DIR_TX)
- stream_config.ch_count = 2;
- else
- stream_config.ch_count = params_channels(params);
-
+ stream_config.ch_count = 2;
port_config.ch_mask = GENMASK((int)stream_config.ch_count - 1, 0);
}
diff --git a/sound/soc/codecs/max9867.c b/sound/soc/codecs/max9867.c
index 6d2941a9dbd6..e161ab037bf7 100644
--- a/sound/soc/codecs/max9867.c
+++ b/sound/soc/codecs/max9867.c
@@ -323,7 +323,7 @@ static int max9867_startup(struct snd_pcm_substream *substream,
static int max9867_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
- int value;
+ int value, freq = 0;
unsigned long int rate, ratio;
struct snd_soc_component *component = dai->component;
struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
@@ -373,6 +373,35 @@ static int max9867_dai_hw_params(struct snd_pcm_substream *substream,
}
regmap_update_bits(max9867->regmap, MAX9867_IFC1B,
MAX9867_IFC1B_BCLK_MASK, value);
+
+ /* Exact integer mode available for 8kHz and 16kHz sample rates
+ * and certain PCLK (prescaled MCLK) values.
+ */
+ if (params_rate(params) == 8000 ||
+ params_rate(params) == 16000) {
+ switch (max9867->pclk) {
+ case 12000000:
+ freq = 0x08;
+ break;
+ case 13000000:
+ freq = 0x0A;
+ break;
+ case 16000000:
+ freq = 0x0C;
+ break;
+ case 19200000:
+ freq = 0x0E;
+ break;
+ }
+ }
+ if (freq && params_rate(params) == 16000)
+ freq++;
+
+ /* If exact integer mode not available, the freq value
+ * remains zero, i.e. normal mode is used.
+ */
+ regmap_update_bits(max9867->regmap, MAX9867_SYSCLK,
+ MAX9867_FREQ_MASK, freq);
} else {
/*
* digital pll locks on to any externally supplied LRCLK signal
@@ -428,8 +457,6 @@ static int max9867_set_dai_sysclk(struct snd_soc_dai *codec_dai,
freq);
max9867->sysclk = freq;
value = value << MAX9867_PSCLK_SHIFT;
- /* exact integer mode is not supported */
- value &= ~MAX9867_FREQ_MASK;
regmap_update_bits(max9867->regmap, MAX9867_SYSCLK,
MAX9867_PSCLK_MASK, value);
return 0;
diff --git a/sound/soc/codecs/rt1308-sdw.c b/sound/soc/codecs/rt1308-sdw.c
index 7f4248284f35..ca2790d63b71 100644
--- a/sound/soc/codecs/rt1308-sdw.c
+++ b/sound/soc/codecs/rt1308-sdw.c
@@ -17,6 +17,7 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
+#include <sound/sdw.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>
@@ -553,11 +554,10 @@ static int rt1308_sdw_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_component *component = dai->component;
struct rt1308_sdw_priv *rt1308 =
snd_soc_component_get_drvdata(component);
- struct sdw_stream_config stream_config;
- struct sdw_port_config port_config;
- enum sdw_data_direction direction;
+ struct sdw_stream_config stream_config = {0};
+ struct sdw_port_config port_config = {0};
struct sdw_stream_data *stream;
- int retval, port, num_channels, ch_mask;
+ int retval;
dev_dbg(dai->dev, "%s %s", __func__, dai->name);
stream = snd_soc_dai_get_dma_data(dai, substream);
@@ -569,30 +569,19 @@ static int rt1308_sdw_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
/* SoundWire specific configuration */
+ snd_sdw_params_to_config(substream, params, &stream_config, &port_config);
+
/* port 1 for playback */
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- direction = SDW_DATA_DIR_RX;
- port = 1;
- } else {
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ port_config.num = 1;
+ else
return -EINVAL;
- }
if (rt1308->slots) {
- num_channels = rt1308->slots;
- ch_mask = rt1308->rx_mask;
- } else {
- num_channels = params_channels(params);
- ch_mask = (1 << num_channels) - 1;
+ stream_config.ch_count = rt1308->slots;
+ port_config.ch_mask = rt1308->rx_mask;
}
- stream_config.frame_rate = params_rate(params);
- stream_config.ch_count = num_channels;
- stream_config.bps = snd_pcm_format_width(params_format(params));
- stream_config.direction = direction;
-
- port_config.ch_mask = ch_mask;
- port_config.num = port;
-
retval = sdw_stream_add_slave(rt1308->sdw_slave, &stream_config,
&port_config, 1, stream->sdw_stream);
if (retval) {
diff --git a/sound/soc/codecs/rt1316-sdw.c b/sound/soc/codecs/rt1316-sdw.c
index 2db7ee6c6d33..e6294cc7a995 100644
--- a/sound/soc/codecs/rt1316-sdw.c
+++ b/sound/soc/codecs/rt1316-sdw.c
@@ -14,6 +14,7 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
+#include <sound/sdw.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include "rt1316-sdw.h"
@@ -530,11 +531,10 @@ static int rt1316_sdw_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_component *component = dai->component;
struct rt1316_sdw_priv *rt1316 =
snd_soc_component_get_drvdata(component);
- struct sdw_stream_config stream_config;
- struct sdw_port_config port_config;
- enum sdw_data_direction direction;
+ struct sdw_stream_config stream_config = {0};
+ struct sdw_port_config port_config = {0};
struct sdw_stream_data *stream;
- int retval, port, num_channels, ch_mask;
+ int retval;
dev_dbg(dai->dev, "%s %s", __func__, dai->name);
stream = snd_soc_dai_get_dma_data(dai, substream);
@@ -546,25 +546,13 @@ static int rt1316_sdw_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
/* SoundWire specific configuration */
- /* port 1 for playback */
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- direction = SDW_DATA_DIR_RX;
- port = 1;
- } else {
- direction = SDW_DATA_DIR_TX;
- port = 2;
- }
-
- num_channels = params_channels(params);
- ch_mask = (1 << num_channels) - 1;
+ snd_sdw_params_to_config(substream, params, &stream_config, &port_config);
- stream_config.frame_rate = params_rate(params);
- stream_config.ch_count = num_channels;
- stream_config.bps = snd_pcm_format_width(params_format(params));
- stream_config.direction = direction;
-
- port_config.ch_mask = ch_mask;
- port_config.num = port;
+ /* port 1 for playback */
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ port_config.num = 1;
+ else
+ port_config.num = 2;
retval = sdw_stream_add_slave(rt1316->sdw_slave, &stream_config,
&port_config, 1, stream->sdw_stream);
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index 0f8e6dd214b0..708e55b7431a 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -2792,6 +2792,11 @@ static int rt5640_suspend(struct snd_soc_component *component)
{
struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
+ if (rt5640->irq) {
+ /* disable jack interrupts during system suspend */
+ disable_irq(rt5640->irq);
+ }
+
rt5640_cancel_work(rt5640);
snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
rt5640_reset(component);
@@ -2815,6 +2820,9 @@ static int rt5640_resume(struct snd_soc_component *component)
regcache_cache_only(rt5640->regmap, false);
regcache_sync(rt5640->regmap);
+ if (rt5640->irq)
+ enable_irq(rt5640->irq);
+
if (rt5640->jack) {
if (rt5640->jd_src == RT5640_JD_SRC_HDA_HEADER) {
snd_soc_component_update_bits(component,
diff --git a/sound/soc/codecs/rt5682-sdw.c b/sound/soc/codecs/rt5682-sdw.c
index c1a94229dc7e..d8a573dcb771 100644
--- a/sound/soc/codecs/rt5682-sdw.c
+++ b/sound/soc/codecs/rt5682-sdw.c
@@ -24,6 +24,7 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/jack.h>
+#include <sound/sdw.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>
@@ -130,11 +131,10 @@ static int rt5682_sdw_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_component *component = dai->component;
struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component);
- struct sdw_stream_config stream_config;
- struct sdw_port_config port_config;
- enum sdw_data_direction direction;
+ struct sdw_stream_config stream_config = {0};
+ struct sdw_port_config port_config = {0};
struct sdw_stream_data *stream;
- int retval, port, num_channels;
+ int retval;
unsigned int val_p = 0, val_c = 0, osr_p = 0, osr_c = 0;
dev_dbg(dai->dev, "%s %s", __func__, dai->name);
@@ -147,22 +147,12 @@ static int rt5682_sdw_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
/* SoundWire specific configuration */
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- direction = SDW_DATA_DIR_RX;
- port = 1;
- } else {
- direction = SDW_DATA_DIR_TX;
- port = 2;
- }
+ snd_sdw_params_to_config(substream, params, &stream_config, &port_config);
- stream_config.frame_rate = params_rate(params);
- stream_config.ch_count = params_channels(params);
- stream_config.bps = snd_pcm_format_width(params_format(params));
- stream_config.direction = direction;
-
- num_channels = params_channels(params);
- port_config.ch_mask = (1 << (num_channels)) - 1;
- port_config.num = port;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ port_config.num = 1;
+ else
+ port_config.num = 2;
retval = sdw_stream_add_slave(rt5682->slave, &stream_config,
&port_config, 1, stream->sdw_stream);
diff --git a/sound/soc/codecs/rt700.c b/sound/soc/codecs/rt700.c
index 055c3ae974d8..6534c9b51442 100644
--- a/sound/soc/codecs/rt700.c
+++ b/sound/soc/codecs/rt700.c
@@ -19,6 +19,7 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
+#include <sound/sdw.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>
@@ -910,11 +911,10 @@ static int rt700_pcm_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_component *component = dai->component;
struct rt700_priv *rt700 = snd_soc_component_get_drvdata(component);
- struct sdw_stream_config stream_config;
- struct sdw_port_config port_config;
- enum sdw_data_direction direction;
+ struct sdw_stream_config stream_config = {0};
+ struct sdw_port_config port_config = {0};
struct sdw_stream_data *stream;
- int retval, port, num_channels;
+ int retval;
unsigned int val = 0;
dev_dbg(dai->dev, "%s %s", __func__, dai->name);
@@ -927,35 +927,25 @@ static int rt700_pcm_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
/* SoundWire specific configuration */
+ snd_sdw_params_to_config(substream, params, &stream_config, &port_config);
+
/* This code assumes port 1 for playback and port 2 for capture */
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- direction = SDW_DATA_DIR_RX;
- port = 1;
- } else {
- direction = SDW_DATA_DIR_TX;
- port = 2;
- }
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ port_config.num = 1;
+ else
+ port_config.num = 2;
switch (dai->id) {
case RT700_AIF1:
break;
case RT700_AIF2:
- port += 2;
+ port_config.num += 2;
break;
default:
dev_err(component->dev, "Invalid DAI id %d\n", dai->id);
return -EINVAL;
}
- stream_config.frame_rate = params_rate(params);
- stream_config.ch_count = params_channels(params);
- stream_config.bps = snd_pcm_format_width(params_format(params));
- stream_config.direction = direction;
-
- num_channels = params_channels(params);
- port_config.ch_mask = (1 << (num_channels)) - 1;
- port_config.num = port;
-
retval = sdw_stream_add_slave(rt700->slave, &stream_config,
&port_config, 1, stream->sdw_stream);
if (retval) {
diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c
index 925268121901..b78dd5994edb 100644
--- a/sound/soc/codecs/rt711-sdca.c
+++ b/sound/soc/codecs/rt711-sdca.c
@@ -18,6 +18,7 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
+#include <sound/sdw.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
@@ -1257,11 +1258,10 @@ static int rt711_sdca_pcm_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_component *component = dai->component;
struct rt711_sdca_priv *rt711 = snd_soc_component_get_drvdata(component);
- struct sdw_stream_config stream_config;
- struct sdw_port_config port_config;
- enum sdw_data_direction direction;
+ struct sdw_stream_config stream_config = {0};
+ struct sdw_port_config port_config = {0};
struct sdw_stream_data *stream;
- int retval, port, num_channels;
+ int retval;
unsigned int sampling_rate;
dev_dbg(dai->dev, "%s %s", __func__, dai->name);
@@ -1274,28 +1274,19 @@ static int rt711_sdca_pcm_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
/* SoundWire specific configuration */
+ snd_sdw_params_to_config(substream, params, &stream_config, &port_config);
+
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- direction = SDW_DATA_DIR_RX;
- port = 3;
+ port_config.num = 3;
} else {
- direction = SDW_DATA_DIR_TX;
if (dai->id == RT711_AIF1)
- port = 2;
+ port_config.num = 2;
else if (dai->id == RT711_AIF2)
- port = 4;
+ port_config.num = 4;
else
return -EINVAL;
}
- stream_config.frame_rate = params_rate(params);
- stream_config.ch_count = params_channels(params);
- stream_config.bps = snd_pcm_format_width(params_format(params));
- stream_config.direction = direction;
-
- num_channels = params_channels(params);
- port_config.ch_mask = GENMASK(num_channels - 1, 0);
- port_config.num = port;
-
retval = sdw_stream_add_slave(rt711->slave, &stream_config,
&port_config, 1, stream->sdw_stream);
if (retval) {
diff --git a/sound/soc/codecs/rt711.c b/sound/soc/codecs/rt711.c
index 1bf618089194..78e1da9b0738 100644
--- a/sound/soc/codecs/rt711.c
+++ b/sound/soc/codecs/rt711.c
@@ -19,6 +19,7 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
+#include <sound/sdw.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>
@@ -999,11 +1000,10 @@ static int rt711_pcm_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_component *component = dai->component;
struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
- struct sdw_stream_config stream_config;
- struct sdw_port_config port_config;
- enum sdw_data_direction direction;
+ struct sdw_stream_config stream_config = {0};
+ struct sdw_port_config port_config = {0};
struct sdw_stream_data *stream;
- int retval, port, num_channels;
+ int retval;
unsigned int val = 0;
dev_dbg(dai->dev, "%s %s", __func__, dai->name);
@@ -1016,28 +1016,19 @@ static int rt711_pcm_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
/* SoundWire specific configuration */
+ snd_sdw_params_to_config(substream, params, &stream_config, &port_config);
+
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- direction = SDW_DATA_DIR_RX;
- port = 3;
+ port_config.num = 3;
} else {
- direction = SDW_DATA_DIR_TX;
if (dai->id == RT711_AIF1)
- port = 4;
+ port_config.num = 4;
else if (dai->id == RT711_AIF2)
- port = 2;
+ port_config.num = 2;
else
return -EINVAL;
}
- stream_config.frame_rate = params_rate(params);
- stream_config.ch_count = params_channels(params);
- stream_config.bps = snd_pcm_format_width(params_format(params));
- stream_config.direction = direction;
-
- num_channels = params_channels(params);
- port_config.ch_mask = (1 << (num_channels)) - 1;
- port_config.num = port;
-
retval = sdw_stream_add_slave(rt711->slave, &stream_config,
&port_config, 1, stream->sdw_stream);
if (retval) {
diff --git a/sound/soc/codecs/rt715-sdca.c b/sound/soc/codecs/rt715-sdca.c
index ce8bbc76199a..1fca7a3f46ea 100644
--- a/sound/soc/codecs/rt715-sdca.c
+++ b/sound/soc/codecs/rt715-sdca.c
@@ -20,6 +20,7 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
+#include <sound/sdw.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>
@@ -820,11 +821,10 @@ static int rt715_sdca_pcm_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_component *component = dai->component;
struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);
- struct sdw_stream_config stream_config;
- struct sdw_port_config port_config;
- enum sdw_data_direction direction;
+ struct sdw_stream_config stream_config = {0};
+ struct sdw_port_config port_config = {0};
struct rt715_sdw_stream_data *stream;
- int retval, port, num_channels;
+ int retval;
unsigned int val;
stream = snd_soc_dai_get_dma_data(dai, substream);
@@ -835,16 +835,16 @@ static int rt715_sdca_pcm_hw_params(struct snd_pcm_substream *substream,
if (!rt715->slave)
return -EINVAL;
+ snd_sdw_params_to_config(substream, params, &stream_config, &port_config);
+
switch (dai->id) {
case RT715_AIF1:
- direction = SDW_DATA_DIR_TX;
- port = 6;
+ port_config.num = 6;
rt715_sdca_index_write(rt715, RT715_VENDOR_REG, RT715_SDW_INPUT_SEL,
0xa500);
break;
case RT715_AIF2:
- direction = SDW_DATA_DIR_TX;
- port = 4;
+ port_config.num = 4;
rt715_sdca_index_write(rt715, RT715_VENDOR_REG, RT715_SDW_INPUT_SEL,
0xaf00);
break;
@@ -853,15 +853,6 @@ static int rt715_sdca_pcm_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
- stream_config.frame_rate = params_rate(params);
- stream_config.ch_count = params_channels(params);
- stream_config.bps = snd_pcm_format_width(params_format(params));
- stream_config.direction = direction;
-
- num_channels = params_channels(params);
- port_config.ch_mask = GENMASK(num_channels - 1, 0);
- port_config.num = port;
-
retval = sdw_stream_add_slave(rt715->slave, &stream_config,
&port_config, 1, stream->sdw_stream);
if (retval) {
diff --git a/sound/soc/codecs/rt715.c b/sound/soc/codecs/rt715.c
index e93240521c74..917a04092da2 100644
--- a/sound/soc/codecs/rt715.c
+++ b/sound/soc/codecs/rt715.c
@@ -28,6 +28,7 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
+#include <sound/sdw.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>
@@ -801,11 +802,10 @@ static int rt715_pcm_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_component *component = dai->component;
struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);
- struct sdw_stream_config stream_config;
- struct sdw_port_config port_config;
- enum sdw_data_direction direction;
+ struct sdw_stream_config stream_config = {0};
+ struct sdw_port_config port_config = {0};
struct sdw_stream_data *stream;
- int retval, port, num_channels;
+ int retval;
unsigned int val = 0;
stream = snd_soc_dai_get_dma_data(dai, substream);
@@ -816,15 +816,15 @@ static int rt715_pcm_hw_params(struct snd_pcm_substream *substream,
if (!rt715->slave)
return -EINVAL;
+ snd_sdw_params_to_config(substream, params, &stream_config, &port_config);
+
switch (dai->id) {
case RT715_AIF1:
- direction = SDW_DATA_DIR_TX;
- port = 6;
+ port_config.num = 6;
rt715_index_write(rt715->regmap, RT715_SDW_INPUT_SEL, 0xa500);
break;
case RT715_AIF2:
- direction = SDW_DATA_DIR_TX;
- port = 4;
+ port_config.num = 4;
rt715_index_write(rt715->regmap, RT715_SDW_INPUT_SEL, 0xa000);
break;
default:
@@ -832,15 +832,6 @@ static int rt715_pcm_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
- stream_config.frame_rate = params_rate(params);
- stream_config.ch_count = params_channels(params);
- stream_config.bps = snd_pcm_format_width(params_format(params));
- stream_config.direction = direction;
-
- num_channels = params_channels(params);
- port_config.ch_mask = (1 << (num_channels)) - 1;
- port_config.num = port;
-
retval = sdw_stream_add_slave(rt715->slave, &stream_config,
&port_config, 1, stream->sdw_stream);
if (retval) {
diff --git a/sound/soc/codecs/sdw-mockup.c b/sound/soc/codecs/sdw-mockup.c
index 288b55368d2a..af52f2728854 100644
--- a/sound/soc/codecs/sdw-mockup.c
+++ b/sound/soc/codecs/sdw-mockup.c
@@ -16,6 +16,7 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
+#include <sound/sdw.h>
#include <sound/soc.h>
struct sdw_mockup_priv {
@@ -80,12 +81,9 @@ static int sdw_mockup_pcm_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_component *component = dai->component;
struct sdw_mockup_priv *sdw_mockup = snd_soc_component_get_drvdata(component);
- struct sdw_stream_config stream_config;
- struct sdw_port_config port_config;
- enum sdw_data_direction direction;
+ struct sdw_stream_config stream_config = {0};
+ struct sdw_port_config port_config = {0};
struct sdw_stream_data *stream;
- int num_channels;
- int port;
int ret;
stream = snd_soc_dai_get_dma_data(dai, substream);
@@ -96,22 +94,12 @@ static int sdw_mockup_pcm_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
/* SoundWire specific configuration */
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- direction = SDW_DATA_DIR_RX;
- port = 1;
- } else {
- direction = SDW_DATA_DIR_TX;
- port = 8;
- }
-
- stream_config.frame_rate = params_rate(params);
- stream_config.ch_count = params_channels(params);
- stream_config.bps = snd_pcm_format_width(params_format(params));
- stream_config.direction = direction;
+ snd_sdw_params_to_config(substream, params, &stream_config, &port_config);
- num_channels = params_channels(params);
- port_config.ch_mask = (1 << num_channels) - 1;
- port_config.num = port;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ port_config.num = 1;
+ else
+ port_config.num = 8;
ret = sdw_stream_add_slave(sdw_mockup->slave, &stream_config,
&port_config, 1, stream->sdw_stream);
diff --git a/sound/soc/qcom/lpass-sc7180.c b/sound/soc/qcom/lpass-sc7180.c
index 24a1c121cb2e..9c3365ddc274 100644
--- a/sound/soc/qcom/lpass-sc7180.c
+++ b/sound/soc/qcom/lpass-sc7180.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include <dt-bindings/sound/sc7180-lpass.h>
#include <sound/pcm.h>
#include <sound/soc.h>
@@ -159,10 +160,34 @@ static int sc7180_lpass_exit(struct platform_device *pdev)
struct lpass_data *drvdata = platform_get_drvdata(pdev);
clk_bulk_disable_unprepare(drvdata->num_clks, drvdata->clks);
+ return 0;
+}
+
+static int sc7180_lpass_dev_resume(struct device *dev)
+{
+ int ret = 0;
+ struct lpass_data *drvdata = dev_get_drvdata(dev);
+ ret = clk_bulk_prepare_enable(drvdata->num_clks, drvdata->clks);
+ if (ret) {
+ dev_err(dev, "sc7180 clk prepare and enable failed\n");
+ return ret;
+ }
+ return ret;
+}
+
+static int sc7180_lpass_dev_suspend(struct device *dev)
+{
+ struct lpass_data *drvdata = dev_get_drvdata(dev);
+
+ clk_bulk_disable_unprepare(drvdata->num_clks, drvdata->clks);
return 0;
}
+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 = {
.i2sctrl_reg_base = 0x1000,
.i2sctrl_reg_stride = 0x1000,
@@ -296,6 +321,7 @@ static struct platform_driver sc7180_lpass_cpu_platform_driver = {
.driver = {
.name = "sc7180-lpass-cpu",
.of_match_table = of_match_ptr(sc7180_lpass_cpu_device_id),
+ .pm = &sc7180_lpass_pm_ops,
},
.probe = asoc_qcom_lpass_cpu_platform_probe,
.remove = asoc_qcom_lpass_cpu_platform_remove,
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 97916e3ca9dd..7bddfd5e38d6 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -39,7 +39,7 @@ config SND_SOC_SH4_SIU
config SND_SOC_RCAR
tristate "R-Car series SRU/SCU/SSIU/SSI support"
depends on COMMON_CLK
- depends on OF || COMPILE_TEST
+ depends on OF
select SND_SIMPLE_CARD_UTILS
select REGMAP_MMIO
help
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index 5f1e72edfee0..ca1e1281cefa 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -648,8 +648,8 @@ void rsnd_adg_clk_dbg_info(struct rsnd_priv *priv, struct seq_file *m)
int i;
for_each_rsnd_clk(clk, adg, i)
- dbg_msg(dev, m, "%s : %pa : %ld\n",
- clk_name[i], clk, clk_get_rate(clk));
+ dbg_msg(dev, m, "%-18s : %pa : %ld\n",
+ __clk_get_name(clk), clk, clk_get_rate(clk));
dbg_msg(dev, m, "BRGCKR = 0x%08x, BRRA/BRRB = 0x%x/0x%x\n",
adg->ckr, adg->rbga, adg->rbgb);
diff --git a/sound/soc/sof/Kconfig b/sound/soc/sof/Kconfig
index 0b9beb74b0f6..a2725188f4ce 100644
--- a/sound/soc/sof/Kconfig
+++ b/sound/soc/sof/Kconfig
@@ -39,7 +39,7 @@ config SND_SOC_SOF_ACPI_DEV
config SND_SOC_SOF_OF
tristate "SOF OF enumeration support"
- depends on OF || COMPILE_TEST
+ depends on OF
help
This adds support for Device Tree enumeration. This option is
required to enable i.MX8 or Mediatek devices.
diff --git a/sound/soc/sof/amd/acp-common.c b/sound/soc/sof/amd/acp-common.c
index 27b95187356e..150e042e4039 100644
--- a/sound/soc/sof/amd/acp-common.c
+++ b/sound/soc/sof/amd/acp-common.c
@@ -76,6 +76,7 @@ struct snd_sof_dsp_ops sof_acp_common_ops = {
/*IPC */
.send_msg = acp_sof_ipc_send_msg,
.ipc_msg_data = acp_sof_ipc_msg_data,
+ .set_stream_data_offset = acp_set_stream_data_offset,
.get_mailbox_offset = acp_sof_ipc_get_mailbox_offset,
.get_window_offset = acp_sof_ipc_get_window_offset,
.irq_thread = acp_sof_ipc_irq_thread,
diff --git a/sound/soc/sof/amd/acp-ipc.c b/sound/soc/sof/amd/acp-ipc.c
index dd030566e372..dd6e53c63407 100644
--- a/sound/soc/sof/amd/acp-ipc.c
+++ b/sound/soc/sof/amd/acp-ipc.c
@@ -192,13 +192,41 @@ int acp_sof_ipc_msg_data(struct snd_sof_dev *sdev, struct snd_pcm_substream *sub
{
unsigned int offset = sdev->dsp_box.offset;
- if (!substream || !sdev->stream_box.size)
+ if (!substream || !sdev->stream_box.size) {
acp_mailbox_read(sdev, offset, p, sz);
+ } else {
+ struct acp_dsp_stream *stream = substream->runtime->private_data;
+
+ if (!stream)
+ return -ESTRPIPE;
+
+ acp_mailbox_read(sdev, stream->posn_offset, p, sz);
+ }
return 0;
}
EXPORT_SYMBOL_NS(acp_sof_ipc_msg_data, SND_SOC_SOF_AMD_COMMON);
+int acp_set_stream_data_offset(struct snd_sof_dev *sdev,
+ struct snd_pcm_substream *substream,
+ size_t posn_offset)
+{
+ struct acp_dsp_stream *stream = substream->runtime->private_data;
+
+ /* check for unaligned offset or overflow */
+ if (posn_offset > sdev->stream_box.size ||
+ posn_offset % sizeof(struct sof_ipc_stream_posn) != 0)
+ return -EINVAL;
+
+ stream->posn_offset = sdev->stream_box.offset + posn_offset;
+
+ dev_dbg(sdev->dev, "pcm: stream dir %d, posn mailbox offset is %zu",
+ substream->stream, stream->posn_offset);
+
+ return 0;
+}
+EXPORT_SYMBOL_NS(acp_set_stream_data_offset, SND_SOC_SOF_AMD_COMMON);
+
int acp_sof_ipc_get_mailbox_offset(struct snd_sof_dev *sdev)
{
const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
diff --git a/sound/soc/sof/amd/acp.c b/sound/soc/sof/amd/acp.c
index 36966643e36a..47115a77c92c 100644
--- a/sound/soc/sof/amd/acp.c
+++ b/sound/soc/sof/amd/acp.c
@@ -390,6 +390,7 @@ static int acp_power_on(struct snd_sof_dev *sdev)
static int acp_reset(struct snd_sof_dev *sdev)
{
+ const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
unsigned int val;
int ret;
@@ -410,6 +411,7 @@ static int acp_reset(struct snd_sof_dev *sdev)
if (ret < 0)
dev_err(sdev->dev, "timeout in releasing reset\n");
+ snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->acp_clkmux_sel, ACP_CLOCK_ACLK);
return ret;
}
@@ -456,7 +458,7 @@ int amd_sof_acp_resume(struct snd_sof_dev *sdev)
return ret;
}
- snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->acp_clkmux_sel, 0x03);
+ snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->acp_clkmux_sel, ACP_CLOCK_ACLK);
ret = acp_memory_init(sdev);
diff --git a/sound/soc/sof/amd/acp.h b/sound/soc/sof/amd/acp.h
index dd3c072d0172..76ad963faec1 100644
--- a/sound/soc/sof/amd/acp.h
+++ b/sound/soc/sof/amd/acp.h
@@ -69,6 +69,14 @@
#define BOX_SIZE_512 0x200
#define BOX_SIZE_1024 0x400
+enum clock_source {
+ ACP_CLOCK_96M = 0,
+ ACP_CLOCK_48M,
+ ACP_CLOCK_24M,
+ ACP_CLOCK_ACLK,
+ ACP_CLOCK_MCLK,
+};
+
struct acp_atu_grp_pte {
u32 low;
u32 high;
@@ -138,6 +146,7 @@ struct acp_dsp_stream {
int stream_tag;
int active;
unsigned int reg_offset;
+ size_t posn_offset;
};
struct sof_amd_acp_desc {
@@ -199,6 +208,9 @@ int acp_dsp_block_read(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_ty
irqreturn_t acp_sof_ipc_irq_thread(int irq, void *context);
int acp_sof_ipc_msg_data(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream,
void *p, size_t sz);
+int acp_set_stream_data_offset(struct snd_sof_dev *sdev,
+ struct snd_pcm_substream *substream,
+ size_t posn_offset);
int acp_sof_ipc_send_msg(struct snd_sof_dev *sdev,
struct snd_sof_ipc_msg *msg);
int acp_sof_ipc_get_mailbox_offset(struct snd_sof_dev *sdev);
diff --git a/sound/soc/sof/amd/rembrandt.c b/sound/soc/sof/amd/rembrandt.c
index dcb64a23e121..5288ab882fc9 100644
--- a/sound/soc/sof/amd/rembrandt.c
+++ b/sound/soc/sof/amd/rembrandt.c
@@ -23,6 +23,7 @@
#define I2S_BT_INSTANCE 1
#define I2S_SP_INSTANCE 2
#define PDM_DMIC_INSTANCE 3
+#define I2S_HS_VIRTUAL_INSTANCE 4
static struct snd_soc_dai_driver rembrandt_sof_dai[] = {
[I2S_HS_INSTANCE] = {
@@ -112,6 +113,21 @@ static struct snd_soc_dai_driver rembrandt_sof_dai[] = {
.rate_max = 48000,
},
},
+
+ [I2S_HS_VIRTUAL_INSTANCE] = {
+ .id = I2S_HS_VIRTUAL_INSTANCE,
+ .name = "acp-sof-hs-virtual",
+ .playback = {
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ },
+ .probe = &acp_dai_probe,
+ },
};
/* Rembrandt ops */
diff --git a/sound/soc/sof/amd/renoir.c b/sound/soc/sof/amd/renoir.c
index 6ea8727f977e..adade2e3d3be 100644
--- a/sound/soc/sof/amd/renoir.c
+++ b/sound/soc/sof/amd/renoir.c
@@ -22,6 +22,7 @@
#define I2S_BT_INSTANCE 0
#define I2S_SP_INSTANCE 1
#define PDM_DMIC_INSTANCE 2
+#define I2S_SP_VIRTUAL_INSTANCE 3
static struct snd_soc_dai_driver renoir_sof_dai[] = {
[I2S_BT_INSTANCE] = {
@@ -86,6 +87,21 @@ static struct snd_soc_dai_driver renoir_sof_dai[] = {
.rate_max = 48000,
},
},
+
+ [I2S_SP_VIRTUAL_INSTANCE] = {
+ .id = I2S_SP_VIRTUAL_INSTANCE,
+ .name = "acp-sof-sp-virtual",
+ .playback = {
+ .rates = SNDRV_PCM_RATE_8000_96000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
+ SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 96000,
+ },
+ .probe = &acp_dai_probe,
+ },
};
/* Renoir ops */