diff options
-rw-r--r-- | include/sound/sdw.h | 49 | ||||
-rw-r--r-- | sound/soc/codecs/max98373-sdw.c | 31 | ||||
-rw-r--r-- | sound/soc/codecs/max9867.c | 33 | ||||
-rw-r--r-- | sound/soc/codecs/rt1308-sdw.c | 33 | ||||
-rw-r--r-- | sound/soc/codecs/rt1316-sdw.c | 32 | ||||
-rw-r--r-- | sound/soc/codecs/rt5640.c | 8 | ||||
-rw-r--r-- | sound/soc/codecs/rt5682-sdw.c | 28 | ||||
-rw-r--r-- | sound/soc/codecs/rt700.c | 32 | ||||
-rw-r--r-- | sound/soc/codecs/rt711-sdca.c | 27 | ||||
-rw-r--r-- | sound/soc/codecs/rt711.c | 27 | ||||
-rw-r--r-- | sound/soc/codecs/rt715-sdca.c | 25 | ||||
-rw-r--r-- | sound/soc/codecs/rt715.c | 25 | ||||
-rw-r--r-- | sound/soc/codecs/sdw-mockup.c | 28 | ||||
-rw-r--r-- | sound/soc/qcom/lpass-sc7180.c | 26 | ||||
-rw-r--r-- | sound/soc/sh/Kconfig | 2 | ||||
-rw-r--r-- | sound/soc/sh/rcar/adg.c | 4 | ||||
-rw-r--r-- | sound/soc/sof/Kconfig | 2 | ||||
-rw-r--r-- | sound/soc/sof/amd/acp-common.c | 1 | ||||
-rw-r--r-- | sound/soc/sof/amd/acp-ipc.c | 30 | ||||
-rw-r--r-- | sound/soc/sof/amd/acp.c | 4 | ||||
-rw-r--r-- | sound/soc/sof/amd/acp.h | 12 | ||||
-rw-r--r-- | sound/soc/sof/amd/rembrandt.c | 16 | ||||
-rw-r--r-- | sound/soc/sof/amd/renoir.c | 16 |
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 */ |