@@ -414,9 +414,10 @@ int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card);
void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card);
int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
- const struct snd_soc_pcm_stream *params,
+ struct snd_soc_pcm_stream *params,
struct snd_soc_dapm_widget *source,
- struct snd_soc_dapm_widget *sink);
+ struct snd_soc_dapm_widget *sink,
+ struct snd_soc_dai_link *dai_link);
/* dapm path setup */
int snd_soc_dapm_new_widgets(struct snd_soc_card *card);
@@ -561,7 +562,7 @@ struct snd_soc_dapm_widget {
void *priv; /* widget specific data */
struct regulator *regulator; /* attached regulator */
- const struct snd_soc_pcm_stream *params; /* params for dai links */
+ struct snd_soc_pcm_stream *params; /* params for dai links */
/* dapm control */
int reg; /* negative reg = no direct dapm */
@@ -875,7 +875,9 @@ struct snd_soc_dai_link {
const struct device_node *platform_of_node;
int be_id; /* optional ID for machine driver BE identification */
- const struct snd_soc_pcm_stream *params;
+ struct snd_soc_pcm_stream *params;
+ /* optional params re-writing for dai links */
+ int (*params_fixup)(struct snd_soc_dapm_widget *w, int event);
unsigned int dai_fmt; /* format to set on init */
@@ -1469,7 +1469,7 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
capture_w = cpu_dai->capture_widget;
if (play_w && capture_w) {
ret = snd_soc_dapm_new_pcm(card, dai_link->params,
- capture_w, play_w);
+ capture_w, play_w, dai_link);
if (ret != 0) {
dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n",
play_w->name, capture_w->name, ret);
@@ -1481,7 +1481,7 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
capture_w = codec_dai->capture_widget;
if (play_w && capture_w) {
ret = snd_soc_dapm_new_pcm(card, dai_link->params,
- capture_w, play_w);
+ capture_w, play_w, dai_link);
if (ret != 0) {
dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n",
play_w->name, capture_w->name, ret);
@@ -3378,11 +3378,12 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
{
struct snd_soc_dapm_path *source_p, *sink_p;
struct snd_soc_dai *source, *sink;
- const struct snd_soc_pcm_stream *config = w->params;
+ struct snd_soc_pcm_stream *config = w->params;
+ struct snd_soc_dai_link *dai_link = w->priv;
struct snd_pcm_substream substream;
struct snd_pcm_hw_params *params = NULL;
u64 fmt;
- int ret;
+ int ret = 0;
if (WARN_ON(!config) ||
WARN_ON(list_empty(&w->sources) || list_empty(&w->sinks)))
@@ -3402,6 +3403,16 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
source = source_p->source->priv;
sink = sink_p->sink->priv;
+ if (dai_link && dai_link->params_fixup) {
+ ret = dai_link->params_fixup(w, event);
+ if (ret < 0) {
+ dev_err(w->dapm->dev,
+ "ASoC: params_fixup for dai link widget failed %d\n",
+ ret);
+ goto out;
+ }
+ }
+
/* Be a little careful as we don't want to overflow the mask array */
if (config->formats) {
fmt = ffs(config->formats) - 1;
@@ -3483,9 +3494,10 @@ out:
}
int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
- const struct snd_soc_pcm_stream *params,
+ struct snd_soc_pcm_stream *params,
struct snd_soc_dapm_widget *source,
- struct snd_soc_dapm_widget *sink)
+ struct snd_soc_dapm_widget *sink,
+ struct snd_soc_dai_link *dai_link)
{
struct snd_soc_dapm_route routes[2];
struct snd_soc_dapm_widget template;
@@ -3517,6 +3529,7 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
}
w->params = params;
+ w->priv = (void *)dai_link;
memset(&routes, 0, sizeof(routes));