aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sound/cs35l56.h2
-rw-r--r--include/sound/simple_card_utils.h5
-rw-r--r--include/sound/soc-dai.h3
-rw-r--r--include/sound/soc.h6
-rw-r--r--sound/soc/amd/acp/acp-rembrandt.c22
-rw-r--r--sound/soc/codecs/cs35l56-shared.c38
-rw-r--r--sound/soc/codecs/cs35l56.c5
-rw-r--r--sound/soc/generic/audio-graph-card.c2
-rw-r--r--sound/soc/generic/audio-graph-card2.c2
-rw-r--r--sound/soc/generic/simple-card-utils.c23
-rw-r--r--sound/soc/generic/simple-card.c20
-rw-r--r--sound/soc/soc-core.c133
12 files changed, 196 insertions, 65 deletions
diff --git a/include/sound/cs35l56.h b/include/sound/cs35l56.h
index 1f9713d7ca76..ec672daa36cf 100644
--- a/include/sound/cs35l56.h
+++ b/include/sound/cs35l56.h
@@ -260,7 +260,7 @@ extern const struct cs_dsp_region cs35l56_dsp1_regions[CS35L56_NUM_DSP_REGIONS];
extern const char * const cs35l56_tx_input_texts[CS35L56_NUM_INPUT_SRC];
extern const unsigned int cs35l56_tx_input_values[CS35L56_NUM_INPUT_SRC];
-void cs35l56_reread_firmware_registers(struct device *dev, struct regmap *regmap);
+int cs35l56_set_patch(struct regmap *regmap);
int cs35l56_get_bclk_freq_id(unsigned int freq);
void cs35l56_fill_supply_names(struct regulator_bulk_data *data);
diff --git a/include/sound/simple_card_utils.h b/include/sound/simple_card_utils.h
index b450d5873227..d1a95bc33c56 100644
--- a/include/sound/simple_card_utils.h
+++ b/include/sound/simple_card_utils.h
@@ -192,9 +192,8 @@ int asoc_simple_remove(struct platform_device *pdev);
int asoc_graph_card_probe(struct snd_soc_card *card);
int asoc_graph_is_ports0(struct device_node *port);
-int asoc_graph_parse_dai(struct device_node *ep,
- struct snd_soc_dai_link_component *dlc,
- int *is_single_link);
+int asoc_graph_parse_dai(struct device *dev, struct device_node *ep,
+ struct snd_soc_dai_link_component *dlc, int *is_single_link);
#ifdef DEBUG
static inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv,
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index e3906ecda740..a33d803fe548 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -271,6 +271,8 @@ int snd_soc_dai_compr_get_metadata(struct snd_soc_dai *dai,
struct snd_compr_stream *cstream,
struct snd_compr_metadata *metadata);
+const char *snd_soc_dai_name_get(struct snd_soc_dai *dai);
+
struct snd_soc_dai_ops {
/*
* DAI clocking configuration, all optional.
@@ -397,6 +399,7 @@ struct snd_soc_dai_driver {
unsigned int id;
unsigned int base;
struct snd_soc_dobj dobj;
+ struct of_phandle_args *dai_args;
/* DAI driver callbacks */
int (*probe)(struct snd_soc_dai *dai);
diff --git a/include/sound/soc.h b/include/sound/soc.h
index b27f84580c5b..fa2337a3cf4c 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -651,6 +651,7 @@ struct snd_soc_dai_link_component {
const char *name;
struct device_node *of_node;
const char *dai_name;
+ struct of_phandle_args *dai_args;
};
struct snd_soc_dai_link_codec_ch_map {
@@ -1335,6 +1336,11 @@ int snd_soc_add_pcm_runtimes(struct snd_soc_card *card,
void snd_soc_remove_pcm_runtime(struct snd_soc_card *card,
struct snd_soc_pcm_runtime *rtd);
+void snd_soc_dlc_use_cpu_as_platform(struct snd_soc_dai_link_component *platforms,
+ struct snd_soc_dai_link_component *cpus);
+struct of_phandle_args *snd_soc_copy_dai_args(struct device *dev,
+ struct of_phandle_args *args);
+struct snd_soc_dai *snd_soc_get_dai_via_args(struct of_phandle_args *dai_args);
struct snd_soc_dai *snd_soc_register_dai(struct snd_soc_component *component,
struct snd_soc_dai_driver *dai_drv,
bool legacy_dai_naming);
diff --git a/sound/soc/amd/acp/acp-rembrandt.c b/sound/soc/amd/acp/acp-rembrandt.c
index 21e67ed956d1..cc8284f417c0 100644
--- a/sound/soc/amd/acp/acp-rembrandt.c
+++ b/sound/soc/amd/acp/acp-rembrandt.c
@@ -266,18 +266,16 @@ static int __maybe_unused rmb_pcm_resume(struct device *dev)
acp6x_master_clock_generate(dev);
spin_lock(&adata->acp_lock);
list_for_each_entry(stream, &adata->stream_list, list) {
- if (stream) {
- substream = stream->substream;
- if (substream && substream->runtime) {
- buf_in_frames = (substream->runtime->buffer_size);
- buf_size = frames_to_bytes(substream->runtime, buf_in_frames);
- config_pte_for_stream(adata, stream);
- config_acp_dma(adata, stream, buf_size);
- if (stream->dai_id)
- restore_acp_i2s_params(substream, adata, stream);
- else
- restore_acp_pdm_params(substream, adata);
- }
+ substream = stream->substream;
+ if (substream && substream->runtime) {
+ buf_in_frames = (substream->runtime->buffer_size);
+ buf_size = frames_to_bytes(substream->runtime, buf_in_frames);
+ config_pte_for_stream(adata, stream);
+ config_acp_dma(adata, stream, buf_size);
+ if (stream->dai_id)
+ restore_acp_i2s_params(substream, adata, stream);
+ else
+ restore_acp_pdm_params(substream, adata);
}
}
spin_unlock(&adata->acp_lock);
diff --git a/sound/soc/codecs/cs35l56-shared.c b/sound/soc/codecs/cs35l56-shared.c
index d561fbdc12de..cb0130d1e7e9 100644
--- a/sound/soc/codecs/cs35l56-shared.c
+++ b/sound/soc/codecs/cs35l56-shared.c
@@ -11,6 +11,19 @@
#include "cs35l56.h"
+static const struct reg_sequence cs35l56_patch[] = {
+ /* These are not reset by a soft-reset, so patch to defaults. */
+ { CS35L56_MAIN_RENDER_USER_MUTE, 0x00000000 },
+ { CS35L56_MAIN_RENDER_USER_VOLUME, 0x00000000 },
+ { CS35L56_MAIN_POSTURE_NUMBER, 0x00000000 },
+};
+
+int cs35l56_set_patch(struct regmap *regmap)
+{
+ return regmap_register_patch(regmap, cs35l56_patch, ARRAY_SIZE(cs35l56_patch));
+}
+EXPORT_SYMBOL_NS_GPL(cs35l56_set_patch, SND_SOC_CS35L56_SHARED);
+
static const struct reg_default cs35l56_reg_defaults[] = {
{ CS35L56_ASP1_ENABLES1, 0x00000000 },
{ CS35L56_ASP1_CONTROL1, 0x00000028 },
@@ -35,9 +48,9 @@ static const struct reg_default cs35l56_reg_defaults[] = {
{ CS35L56_IRQ1_MASK_8, 0xfc000fff },
{ CS35L56_IRQ1_MASK_18, 0x1f7df0ff },
{ CS35L56_IRQ1_MASK_20, 0x15c00000 },
- /* CS35L56_MAIN_RENDER_USER_MUTE - soft register, no default */
- /* CS35L56_MAIN_RENDER_USER_VOLUME - soft register, no default */
- /* CS35L56_MAIN_POSTURE_NUMBER - soft register, no default */
+ { CS35L56_MAIN_RENDER_USER_MUTE, 0x00000000 },
+ { CS35L56_MAIN_RENDER_USER_VOLUME, 0x00000000 },
+ { CS35L56_MAIN_POSTURE_NUMBER, 0x00000000 },
};
static bool cs35l56_is_dsp_memory(unsigned int reg)
@@ -181,25 +194,6 @@ static bool cs35l56_volatile_reg(struct device *dev, unsigned int reg)
}
}
-static const u32 cs35l56_firmware_registers[] = {
- CS35L56_MAIN_RENDER_USER_MUTE,
- CS35L56_MAIN_RENDER_USER_VOLUME,
- CS35L56_MAIN_POSTURE_NUMBER,
-};
-
-void cs35l56_reread_firmware_registers(struct device *dev, struct regmap *regmap)
-{
- int i;
- unsigned int val;
-
- for (i = 0; i < ARRAY_SIZE(cs35l56_firmware_registers); i++) {
- regmap_read(regmap, cs35l56_firmware_registers[i], &val);
- dev_dbg(dev, "%s: %d: %#x: %#x\n", __func__,
- i, cs35l56_firmware_registers[i], val);
- }
-}
-EXPORT_SYMBOL_NS_GPL(cs35l56_reread_firmware_registers, SND_SOC_CS35L56_SHARED);
-
const struct cs_dsp_region cs35l56_dsp1_regions[] = {
{ .type = WMFW_HALO_PM_PACKED, .base = CS35L56_DSP1_PMEM_0 },
{ .type = WMFW_HALO_XM_PACKED, .base = CS35L56_DSP1_XMEM_PACKED_0 },
diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c
index c03f9d3c9a13..e046fdd26b74 100644
--- a/sound/soc/codecs/cs35l56.c
+++ b/sound/soc/codecs/cs35l56.c
@@ -1572,8 +1572,9 @@ post_soft_reset:
if (ret)
return ret;
- /* Populate soft registers in the regmap cache */
- cs35l56_reread_firmware_registers(cs35l56->dev, cs35l56->regmap);
+ ret = cs35l56_set_patch(cs35l56->regmap);
+ if (ret)
+ return ret;
/* Registers could be dirty after soft reset or SoundWire enumeration */
regcache_sync(cs35l56->regmap);
diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c
index c6e0f9132193..0b8258b6bd8e 100644
--- a/sound/soc/generic/audio-graph-card.c
+++ b/sound/soc/generic/audio-graph-card.c
@@ -126,7 +126,7 @@ static int graph_parse_node(struct asoc_simple_priv *priv,
graph_parse_mclk_fs(top, ep, dai_props);
- ret = asoc_graph_parse_dai(ep, dlc, cpu);
+ ret = asoc_graph_parse_dai(dev, ep, dlc, cpu);
if (ret < 0)
return ret;
diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c
index 542c4a114940..98732468a992 100644
--- a/sound/soc/generic/audio-graph-card2.c
+++ b/sound/soc/generic/audio-graph-card2.c
@@ -407,7 +407,7 @@ static int __graph_parse_node(struct asoc_simple_priv *priv,
graph_parse_mclk_fs(ep, dai_props);
- ret = asoc_graph_parse_dai(ep, dlc, &is_single_links);
+ ret = asoc_graph_parse_dai(dev, ep, dlc, &is_single_links);
if (ret < 0)
return ret;
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index 3019626b0592..5b18a4af022f 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -649,7 +649,7 @@ void asoc_simple_canonicalize_platform(struct snd_soc_dai_link_component *platfo
* simple-card.c :: simple_count_noml()
*/
if (!platforms->of_node)
- platforms->of_node = cpus->of_node;
+ snd_soc_dlc_use_cpu_as_platform(platforms, cpus);
}
EXPORT_SYMBOL_GPL(asoc_simple_canonicalize_platform);
@@ -1066,12 +1066,12 @@ static int graph_get_dai_id(struct device_node *ep)
return id;
}
-int asoc_graph_parse_dai(struct device_node *ep,
- struct snd_soc_dai_link_component *dlc,
- int *is_single_link)
+int asoc_graph_parse_dai(struct device *dev, struct device_node *ep,
+ struct snd_soc_dai_link_component *dlc, int *is_single_link)
{
struct device_node *node;
struct of_phandle_args args = {};
+ struct snd_soc_dai *dai;
int ret;
if (!ep)
@@ -1079,6 +1079,20 @@ int asoc_graph_parse_dai(struct device_node *ep,
node = of_graph_get_port_parent(ep);
+ /*
+ * Try to find from DAI node
+ */
+ args.np = ep;
+ dai = snd_soc_get_dai_via_args(&args);
+ if (dai) {
+ dlc->dai_name = snd_soc_dai_name_get(dai);
+ dlc->dai_args = snd_soc_copy_dai_args(dev, &args);
+ if (!dlc->dai_args)
+ return -ENOMEM;
+
+ goto parse_dai_end;
+ }
+
/* Get dai->name */
args.np = node;
args.args[0] = graph_get_dai_id(ep);
@@ -1109,6 +1123,7 @@ int asoc_graph_parse_dai(struct device_node *ep,
return ret;
}
+parse_dai_end:
if (is_single_link)
*is_single_link = of_graph_get_endpoint_count(node) == 1;
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index a78babf44f38..190f11366e84 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -52,11 +52,13 @@ static int asoc_simple_parse_platform(struct device_node *node,
return 0;
}
-static int asoc_simple_parse_dai(struct device_node *node,
+static int asoc_simple_parse_dai(struct device *dev,
+ struct device_node *node,
struct snd_soc_dai_link_component *dlc,
int *is_single_link)
{
struct of_phandle_args args;
+ struct snd_soc_dai *dai;
int ret;
if (!node)
@@ -71,6 +73,19 @@ static int asoc_simple_parse_dai(struct device_node *node,
return ret;
/*
+ * Try to find from DAI args
+ */
+ dai = snd_soc_get_dai_via_args(&args);
+ if (dai) {
+ dlc->dai_name = snd_soc_dai_name_get(dai);
+ dlc->dai_args = snd_soc_copy_dai_args(dev, &args);
+ if (!dlc->dai_args)
+ return -ENOMEM;
+
+ goto parse_dai_end;
+ }
+
+ /*
* FIXME
*
* Here, dlc->dai_name is pointer to CPU/Codec DAI name.
@@ -93,6 +108,7 @@ static int asoc_simple_parse_dai(struct device_node *node,
if (ret < 0)
return ret;
+parse_dai_end:
if (is_single_link)
*is_single_link = !args.args_count;
@@ -156,7 +172,7 @@ static int simple_parse_node(struct asoc_simple_priv *priv,
simple_parse_mclk_fs(top, np, dai_props, prefix);
- ret = asoc_simple_parse_dai(np, dlc, cpu);
+ ret = asoc_simple_parse_dai(dev, np, dlc, cpu);
if (ret)
return ret;
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 94e856d67a46..a5b96c17633a 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -238,9 +238,25 @@ static inline void snd_soc_debugfs_exit(void) { }
#endif
+static int snd_soc_is_match_dai_args(struct of_phandle_args *args1,
+ struct of_phandle_args *args2)
+{
+ if (!args1 || !args2)
+ return 0;
+
+ if (args1->np != args2->np)
+ return 0;
+
+ for (int i = 0; i < args1->args_count; i++)
+ if (args1->args[i] != args2->args[i])
+ return 0;
+
+ return 1;
+}
+
static inline int snd_soc_dlc_component_is_empty(struct snd_soc_dai_link_component *dlc)
{
- return !(dlc->name || dlc->of_node);
+ return !(dlc->dai_args || dlc->name || dlc->of_node);
}
static inline int snd_soc_dlc_component_is_invalid(struct snd_soc_dai_link_component *dlc)
@@ -250,8 +266,52 @@ static inline int snd_soc_dlc_component_is_invalid(struct snd_soc_dai_link_compo
static inline int snd_soc_dlc_dai_is_empty(struct snd_soc_dai_link_component *dlc)
{
- return !dlc->dai_name;
+ return !(dlc->dai_args || dlc->dai_name);
+}
+
+static int snd_soc_is_matching_dai(const struct snd_soc_dai_link_component *dlc,
+ struct snd_soc_dai *dai)
+{
+ if (!dlc)
+ return 0;
+
+ if (dlc->dai_args)
+ return snd_soc_is_match_dai_args(dai->driver->dai_args, dlc->dai_args);
+
+ if (!dlc->dai_name)
+ return 1;
+
+ /* see snd_soc_dai_name_get() */
+
+ if (strcmp(dlc->dai_name, dai->name) == 0)
+ return 1;
+
+ if (dai->driver->name &&
+ strcmp(dai->driver->name, dlc->dai_name) == 0)
+ return 1;
+
+ if (dai->component->name &&
+ strcmp(dlc->dai_name, dai->component->name) == 0)
+ return 1;
+
+ return 0;
+}
+
+const char *snd_soc_dai_name_get(struct snd_soc_dai *dai)
+{
+ /* see snd_soc_is_matching_dai() */
+ if (dai->name)
+ return dai->name;
+
+ if (dai->driver->name)
+ return dai->driver->name;
+
+ if (dai->component->name)
+ return dai->component->name;
+
+ return NULL;
}
+EXPORT_SYMBOL_GPL(snd_soc_dai_name_get);
static int snd_soc_rtd_add_component(struct snd_soc_pcm_runtime *rtd,
struct snd_soc_component *component)
@@ -749,6 +809,19 @@ static struct device_node
return of_node;
}
+struct of_phandle_args *snd_soc_copy_dai_args(struct device *dev, struct of_phandle_args *args)
+{
+ struct of_phandle_args *ret = devm_kzalloc(dev, sizeof(*ret), GFP_KERNEL);
+
+ if (!ret)
+ return NULL;
+
+ *ret = *args;
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(snd_soc_copy_dai_args);
+
static int snd_soc_is_matching_component(
const struct snd_soc_dai_link_component *dlc,
struct snd_soc_component *component)
@@ -758,6 +831,15 @@ static int snd_soc_is_matching_component(
if (!dlc)
return 0;
+ if (dlc->dai_args) {
+ struct snd_soc_dai *dai;
+
+ for_each_component_dais(component, dai)
+ if (snd_soc_is_matching_dai(dlc, dai))
+ return 1;
+ return 0;
+ }
+
component_of_node = soc_component_to_node(component);
if (dlc->of_node && component_of_node != dlc->of_node)
@@ -810,18 +892,11 @@ struct snd_soc_dai *snd_soc_find_dai(
lockdep_assert_held(&client_mutex);
/* Find CPU DAI from registered DAIs */
- for_each_component(component) {
- if (!snd_soc_is_matching_component(dlc, component))
- continue;
- for_each_component_dais(component, dai) {
- if (dlc->dai_name && strcmp(dai->name, dlc->dai_name)
- && (!dai->driver->name
- || strcmp(dai->driver->name, dlc->dai_name)))
- continue;
-
- return dai;
- }
- }
+ for_each_component(component)
+ if (snd_soc_is_matching_component(dlc, component))
+ for_each_component_dais(component, dai)
+ if (snd_soc_is_matching_dai(dlc, dai))
+ return dai;
return NULL;
}
@@ -2943,6 +3018,14 @@ int snd_soc_of_parse_tdm_slot(struct device_node *np,
}
EXPORT_SYMBOL_GPL(snd_soc_of_parse_tdm_slot);
+void snd_soc_dlc_use_cpu_as_platform(struct snd_soc_dai_link_component *platforms,
+ struct snd_soc_dai_link_component *cpus)
+{
+ platforms->of_node = cpus->of_node;
+ platforms->dai_args = cpus->dai_args;
+}
+EXPORT_SYMBOL_GPL(snd_soc_dlc_use_cpu_as_platform);
+
void snd_soc_of_parse_node_prefix(struct device_node *np,
struct snd_soc_codec_conf *codec_conf,
struct device_node *of_node,
@@ -3316,9 +3399,7 @@ int snd_soc_get_dlc(const struct of_phandle_args *args, struct snd_soc_dai_link_
id--;
}
- dlc->dai_name = dai->driver->name;
- if (!dlc->dai_name)
- dlc->dai_name = pos->name;
+ dlc->dai_name = snd_soc_dai_name_get(dai);
} else if (ret) {
/*
* if another error than ENOTSUPP is returned go on and
@@ -3386,6 +3467,24 @@ int snd_soc_of_get_dai_name(struct device_node *of_node,
}
EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_name);
+struct snd_soc_dai *snd_soc_get_dai_via_args(struct of_phandle_args *dai_args)
+{
+ struct snd_soc_dai *dai;
+ struct snd_soc_component *component;
+
+ mutex_lock(&client_mutex);
+ for_each_component(component) {
+ for_each_component_dais(component, dai)
+ if (snd_soc_is_match_dai_args(dai->driver->dai_args, dai_args))
+ goto found;
+ }
+ dai = NULL;
+found:
+ mutex_unlock(&client_mutex);
+ return dai;
+}
+EXPORT_SYMBOL_GPL(snd_soc_get_dai_via_args);
+
static void __snd_soc_of_put_component(struct snd_soc_dai_link_component *component)
{
if (component->of_node) {