Commit 6bf88ab2 authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branch 'asoc/topic/dapm' into asoc-next

parents 1450da3c 94986198
Loading
Loading
Loading
Loading
+2 −5
Original line number Original line Diff line number Diff line
@@ -256,9 +256,8 @@ struct device;
/* generic widgets */
/* generic widgets */
#define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \
#define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \
{	.id = wid, .name = wname, .kcontrol_news = NULL, .num_kcontrols = 0, \
{	.id = wid, .name = wname, .kcontrol_news = NULL, .num_kcontrols = 0, \
	.reg = -((wreg) + 1), .shift = wshift, .mask = wmask, \
	.reg = wreg, .shift = wshift, .mask = wmask, \
	.on_val = won_val, .off_val = woff_val, .event = dapm_reg_event, \
	.on_val = won_val, .off_val = woff_val, }
	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD}
#define SND_SOC_DAPM_SUPPLY(wname, wreg, wshift, winvert, wevent, wflags) \
#define SND_SOC_DAPM_SUPPLY(wname, wreg, wshift, winvert, wevent, wflags) \
{	.id = snd_soc_dapm_supply, .name = wname, \
{	.id = snd_soc_dapm_supply, .name = wname, \
	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
	SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
@@ -362,8 +361,6 @@ struct regulator;
struct snd_soc_dapm_widget_list;
struct snd_soc_dapm_widget_list;
struct snd_soc_dapm_update;
struct snd_soc_dapm_update;


int dapm_reg_event(struct snd_soc_dapm_widget *w,
		   struct snd_kcontrol *kcontrol, int event);
int dapm_regulator_event(struct snd_soc_dapm_widget *w,
int dapm_regulator_event(struct snd_soc_dapm_widget *w,
			 struct snd_kcontrol *kcontrol, int event);
			 struct snd_kcontrol *kcontrol, int event);
int dapm_clock_event(struct snd_soc_dapm_widget *w,
int dapm_clock_event(struct snd_soc_dapm_widget *w,
+56 −114
Original line number Original line Diff line number Diff line
@@ -1057,26 +1057,6 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
	return paths;
	return paths;
}
}


/*
 * Handler for generic register modifier widget.
 */
int dapm_reg_event(struct snd_soc_dapm_widget *w,
		   struct snd_kcontrol *kcontrol, int event)
{
	unsigned int val;

	if (SND_SOC_DAPM_EVENT_ON(event))
		val = w->on_val;
	else
		val = w->off_val;

	soc_widget_update_bits(w, -(w->reg + 1),
			    w->mask << w->shift, val << w->shift);

	return 0;
}
EXPORT_SYMBOL_GPL(dapm_reg_event);

/*
/*
 * Handler for regulator supply widget.
 * Handler for regulator supply widget.
 */
 */
@@ -2383,8 +2363,7 @@ err:
}
}


static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
				  const struct snd_soc_dapm_route *route,
				  const struct snd_soc_dapm_route *route)
				  unsigned int is_prefixed)
{
{
	struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w;
	struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w;
	struct snd_soc_dapm_widget *wtsource = NULL, *wtsink = NULL;
	struct snd_soc_dapm_widget *wtsource = NULL, *wtsink = NULL;
@@ -2394,7 +2373,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
	char prefixed_source[80];
	char prefixed_source[80];
	int ret;
	int ret;


	if (dapm->codec && dapm->codec->name_prefix && !is_prefixed) {
	if (dapm->codec && dapm->codec->name_prefix) {
		snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s",
		snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s",
			 dapm->codec->name_prefix, route->sink);
			 dapm->codec->name_prefix, route->sink);
		sink = prefixed_sink;
		sink = prefixed_sink;
@@ -2522,7 +2501,7 @@ int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,


	mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
	mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
	for (i = 0; i < num; i++) {
	for (i = 0; i < num; i++) {
		r = snd_soc_dapm_add_route(dapm, route, false);
		r = snd_soc_dapm_add_route(dapm, route);
		if (r < 0) {
		if (r < 0) {
			dev_err(dapm->dev, "ASoC: Failed to add route %s -> %s -> %s\n",
			dev_err(dapm->dev, "ASoC: Failed to add route %s -> %s -> %s\n",
				route->source,
				route->source,
@@ -2794,24 +2773,21 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
	mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
	mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);


	change = dapm_kcontrol_set_value(kcontrol, val);
	change = dapm_kcontrol_set_value(kcontrol, val);

	if (change) {
		if (reg != SND_SOC_NOPM) {
		if (reg != SND_SOC_NOPM) {
			mask = mask << shift;
			mask = mask << shift;
			val = val << shift;
			val = val << shift;


		change = snd_soc_test_bits(codec, reg, mask, val);
			if (snd_soc_test_bits(codec, reg, mask, val)) {
	}

	if (change) {
		if (reg != SND_SOC_NOPM) {
				update.kcontrol = kcontrol;
				update.kcontrol = kcontrol;
				update.reg = reg;
				update.reg = reg;
				update.mask = mask;
				update.mask = mask;
				update.val = val;
				update.val = val;

				card->update = &update;
				card->update = &update;
			}
			}


		}

		ret = soc_dapm_mixer_update_power(card, kcontrol, connect);
		ret = soc_dapm_mixer_update_power(card, kcontrol, connect);


		card->update = NULL;
		card->update = NULL;
@@ -3248,11 +3224,11 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
			 struct snd_soc_dapm_widget *source,
			 struct snd_soc_dapm_widget *source,
			 struct snd_soc_dapm_widget *sink)
			 struct snd_soc_dapm_widget *sink)
{
{
	struct snd_soc_dapm_route routes[2];
	struct snd_soc_dapm_widget template;
	struct snd_soc_dapm_widget template;
	struct snd_soc_dapm_widget *w;
	struct snd_soc_dapm_widget *w;
	size_t len;
	size_t len;
	char *link_name;
	char *link_name;
	int ret;


	len = strlen(source->name) + strlen(sink->name) + 2;
	len = strlen(source->name) + strlen(sink->name) + 2;
	link_name = devm_kzalloc(card->dev, len, GFP_KERNEL);
	link_name = devm_kzalloc(card->dev, len, GFP_KERNEL);
@@ -3279,15 +3255,10 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card,


	w->params = params;
	w->params = params;


	memset(&routes, 0, sizeof(routes));
	ret = snd_soc_dapm_add_path(&card->dapm, source, w, NULL, NULL);

	if (ret)
	routes[0].source = source->name;
		return ret;
	routes[0].sink = link_name;
	return snd_soc_dapm_add_path(&card->dapm, w, sink, NULL, NULL);
	routes[1].source = link_name;
	routes[1].sink = sink->name;

	return snd_soc_dapm_add_routes(&card->dapm, routes,
				       ARRAY_SIZE(routes));
}
}


int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
@@ -3345,6 +3316,7 @@ 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)
int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card)
{
{
	struct snd_soc_dapm_widget *dai_w, *w;
	struct snd_soc_dapm_widget *dai_w, *w;
	struct snd_soc_dapm_widget *src, *sink;
	struct snd_soc_dai *dai;
	struct snd_soc_dai *dai;


	/* For each DAI widget... */
	/* For each DAI widget... */
@@ -3375,25 +3347,15 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card)
			if (!w->sname || !strstr(w->sname, dai_w->name))
			if (!w->sname || !strstr(w->sname, dai_w->name))
				continue;
				continue;


			if (dai->driver->playback.stream_name &&
			if (dai_w->id == snd_soc_dapm_dai_in) {
			    strstr(w->sname,
				src = dai_w;
				   dai->driver->playback.stream_name)) {
				sink = w;
				dev_dbg(dai->dev, "%s -> %s\n",
			} else {
					 dai->playback_widget->name, w->name);
				src = w;

				sink = dai_w;
				snd_soc_dapm_add_path(w->dapm,
					dai->playback_widget, w, NULL, NULL);
			}

			if (dai->driver->capture.stream_name &&
			    strstr(w->sname,
				   dai->driver->capture.stream_name)) {
				dev_dbg(dai->dev, "%s -> %s\n",
					w->name, dai->capture_widget->name);

				snd_soc_dapm_add_path(w->dapm, w,
					dai->capture_widget, NULL, NULL);
			}
			}
			dev_dbg(dai->dev, "%s -> %s\n", src->name, sink->name);
			snd_soc_dapm_add_path(w->dapm, src, sink, NULL, NULL);
		}
		}
	}
	}


@@ -3403,12 +3365,10 @@ 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)
void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card)
{
{
	struct snd_soc_pcm_runtime *rtd = card->rtd;
	struct snd_soc_pcm_runtime *rtd = card->rtd;
	struct snd_soc_dapm_widget *sink, *source;
	struct snd_soc_dai *cpu_dai, *codec_dai;
	struct snd_soc_dai *cpu_dai, *codec_dai;
	struct snd_soc_dapm_route r;
	int i;
	int i;


	memset(&r, 0, sizeof(r));

	/* for each BE DAI link... */
	/* for each BE DAI link... */
	for (i = 0; i < card->num_rtd; i++) {
	for (i = 0; i < card->num_rtd; i++) {
		rtd = &card->rtd[i];
		rtd = &card->rtd[i];
@@ -3429,55 +3389,49 @@ void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card)


		/* connect BE DAI playback if widgets are valid */
		/* connect BE DAI playback if widgets are valid */
		if (codec_dai->playback_widget && cpu_dai->playback_widget) {
		if (codec_dai->playback_widget && cpu_dai->playback_widget) {
			r.source = cpu_dai->playback_widget->name;
			source = cpu_dai->playback_widget;
			r.sink = codec_dai->playback_widget->name;
			sink = codec_dai->playback_widget;
			dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n",
			dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n",
				cpu_dai->codec->name, r.source,
				cpu_dai->codec->name, source->name,
				codec_dai->platform->name, r.sink);
				codec_dai->platform->name, sink->name);


			snd_soc_dapm_add_route(&card->dapm, &r, true);
			snd_soc_dapm_add_path(&card->dapm, source, sink,
				NULL, NULL);
		}
		}


		/* connect BE DAI capture if widgets are valid */
		/* connect BE DAI capture if widgets are valid */
		if (codec_dai->capture_widget && cpu_dai->capture_widget) {
		if (codec_dai->capture_widget && cpu_dai->capture_widget) {
			r.source = codec_dai->capture_widget->name;
			source = codec_dai->capture_widget;
			r.sink = cpu_dai->capture_widget->name;
			sink = cpu_dai->capture_widget;
			dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n",
			dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n",
				codec_dai->codec->name, r.source,
				codec_dai->codec->name, source->name,
				cpu_dai->platform->name, r.sink);
				cpu_dai->platform->name, sink->name);


			snd_soc_dapm_add_route(&card->dapm, &r, true);
			snd_soc_dapm_add_path(&card->dapm, source, sink,
				NULL, NULL);
		}
		}

	}
	}
}
}


static void soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
static void soc_dapm_dai_stream_event(struct snd_soc_dai *dai, int stream,
	int event)
	int event)
{
{
	struct snd_soc_dapm_widget *w;


	struct snd_soc_dapm_widget *w_cpu, *w_codec;
	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
		w = dai->playback_widget;
	struct snd_soc_dai *codec_dai = rtd->codec_dai;
	else

		w = dai->capture_widget;
	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
		w_cpu = cpu_dai->playback_widget;
		w_codec = codec_dai->playback_widget;
	} else {
		w_cpu = cpu_dai->capture_widget;
		w_codec = codec_dai->capture_widget;
	}

	if (w_cpu) {


		dapm_mark_dirty(w_cpu, "stream event");
	if (w) {
		dapm_mark_dirty(w, "stream event");


		switch (event) {
		switch (event) {
		case SND_SOC_DAPM_STREAM_START:
		case SND_SOC_DAPM_STREAM_START:
			w_cpu->active = 1;
			w->active = 1;
			break;
			break;
		case SND_SOC_DAPM_STREAM_STOP:
		case SND_SOC_DAPM_STREAM_STOP:
			w_cpu->active = 0;
			w->active = 0;
			break;
			break;
		case SND_SOC_DAPM_STREAM_SUSPEND:
		case SND_SOC_DAPM_STREAM_SUSPEND:
		case SND_SOC_DAPM_STREAM_RESUME:
		case SND_SOC_DAPM_STREAM_RESUME:
@@ -3486,26 +3440,14 @@ static void soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
			break;
			break;
		}
		}
	}
	}

	if (w_codec) {

		dapm_mark_dirty(w_codec, "stream event");

		switch (event) {
		case SND_SOC_DAPM_STREAM_START:
			w_codec->active = 1;
			break;
		case SND_SOC_DAPM_STREAM_STOP:
			w_codec->active = 0;
			break;
		case SND_SOC_DAPM_STREAM_SUSPEND:
		case SND_SOC_DAPM_STREAM_RESUME:
		case SND_SOC_DAPM_STREAM_PAUSE_PUSH:
		case SND_SOC_DAPM_STREAM_PAUSE_RELEASE:
			break;
		}
}
}


static void soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
	int event)
{
	soc_dapm_dai_stream_event(rtd->cpu_dai, stream, event);
	soc_dapm_dai_stream_event(rtd->codec_dai, stream, event);

	dapm_power_widgets(rtd->card, event);
	dapm_power_widgets(rtd->card, event);
}
}