Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 70fe99d8 authored by Mark Brown's avatar Mark Brown
Browse files

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

parents 87fd83fd cf1f7c6e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -311,6 +311,8 @@ struct device;
#define SND_SOC_DAPM_POST_PMD	0x8		/* after widget power down */
#define SND_SOC_DAPM_PRE_REG	0x10	/* before audio path setup */
#define SND_SOC_DAPM_POST_REG	0x20	/* after audio path setup */
#define SND_SOC_DAPM_WILL_PMU   0x40    /* called at start of sequence */
#define SND_SOC_DAPM_WILL_PMD   0x80    /* called at start of sequence */
#define SND_SOC_DAPM_PRE_POST_PMD \
				(SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD)

+44 −62
Original line number Diff line number Diff line
@@ -272,8 +272,8 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
	codec->debugfs_codec_root = debugfs_create_dir(codec->name,
						       debugfs_card_root);
	if (!codec->debugfs_codec_root) {
		dev_warn(codec->dev, "ASoC: Failed to create codec debugfs"
			" directory\n");
		dev_warn(codec->dev,
			"ASoC: Failed to create codec debugfs directory\n");
		return;
	}

@@ -286,8 +286,8 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
						 codec->debugfs_codec_root,
						 codec, &codec_reg_fops);
	if (!codec->debugfs_reg)
		dev_warn(codec->dev, "ASoC: Failed to create codec register"
			" debugfs file\n");
		dev_warn(codec->dev,
			"ASoC: Failed to create codec register debugfs file\n");

	snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root);
}
@@ -631,8 +631,7 @@ int snd_soc_suspend(struct device *dev)
				 */
				if (codec->dapm.idle_bias_off) {
					dev_dbg(codec->dev,
						"ASoC: idle_bias_off CODEC on"
						" over suspend\n");
						"ASoC: idle_bias_off CODEC on over suspend\n");
					break;
				}
			case SND_SOC_BIAS_OFF:
@@ -643,8 +642,8 @@ int snd_soc_suspend(struct device *dev)
					regcache_mark_dirty(codec->control_data);
				break;
			default:
				dev_dbg(codec->dev, "ASoC: CODEC is on"
					" over suspend\n");
				dev_dbg(codec->dev,
					"ASoC: CODEC is on over suspend\n");
				break;
			}
		}
@@ -713,8 +712,8 @@ static void soc_resume_deferred(struct work_struct *work)
				codec->suspended = 0;
				break;
			default:
				dev_dbg(codec->dev, "ASoC: CODEC was on over"
					" suspend\n");
				dev_dbg(codec->dev,
					"ASoC: CODEC was on over suspend\n");
				break;
			}
		}
@@ -1110,8 +1109,8 @@ static int soc_probe_codec(struct snd_soc_card *card,
		}
		WARN(codec->dapm.idle_bias_off &&
			codec->dapm.bias_level != SND_SOC_BIAS_OFF,
			"codec %s can not start from non-off bias"
			" with idle_bias_off==1\n", codec->name);
			"codec %s can not start from non-off bias with idle_bias_off==1\n",
			codec->name);
	}

	/* If the driver didn't set I/O up try regmap */
@@ -1582,8 +1581,9 @@ static int snd_soc_init_codec_cache(struct snd_soc_codec *codec,
		codec->compress_type = compress_type;
	ret = snd_soc_cache_init(codec);
	if (ret < 0) {
		dev_err(codec->dev, "ASoC: Failed to set cache compression"
			" type: %d\n", ret);
		dev_err(codec->dev,
			"ASoC: Failed to set cache compression type: %d\n",
			ret);
		return ret;
	}
	codec->cache_init = 1;
@@ -1639,8 +1639,9 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
	ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
			card->owner, 0, &card->snd_card);
	if (ret < 0) {
		dev_err(card->dev, "ASoC: can't create sound card for"
			" card %s: %d\n", card->name, ret);
		dev_err(card->dev,
			"ASoC: can't create sound card for card %s: %d\n",
			card->name, ret);
		goto base_error;
	}
	card->snd_card->dev = card->dev;
@@ -1815,8 +1816,8 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
	for (i = 0; i < card->num_rtd; i++) {
		ret = soc_register_ac97_dai_link(&card->rtd[i]);
		if (ret < 0) {
			dev_err(card->dev, "ASoC: failed to register AC97:"
				" %d\n", ret);
			dev_err(card->dev,
				"ASoC: failed to register AC97: %d\n", ret);
			while (--i >= 0)
				soc_unregister_ac97_dai_link(card->rtd[i].codec);
			goto probe_aux_dev_err;
@@ -2218,29 +2219,6 @@ int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg,
}
EXPORT_SYMBOL_GPL(snd_soc_test_bits);

/**
 * snd_soc_set_runtime_hwparams - set the runtime hardware parameters
 * @substream: the pcm substream
 * @hw: the hardware parameters
 *
 * Sets the substream runtime hardware parameters.
 */
int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
	const struct snd_pcm_hardware *hw)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	runtime->hw.info = hw->info;
	runtime->hw.formats = hw->formats;
	runtime->hw.period_bytes_min = hw->period_bytes_min;
	runtime->hw.period_bytes_max = hw->period_bytes_max;
	runtime->hw.periods_min = hw->periods_min;
	runtime->hw.periods_max = hw->periods_max;
	runtime->hw.buffer_bytes_max = hw->buffer_bytes_max;
	runtime->hw.fifo_size = hw->fifo_size;
	return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_set_runtime_hwparams);

/**
 * snd_soc_cnew - create new control
 * @_template: control template
@@ -2259,7 +2237,6 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
	struct snd_kcontrol_new template;
	struct snd_kcontrol *kcontrol;
	char *name = NULL;
	int name_len;

	memcpy(&template, _template, sizeof(template));
	template.index = 0;
@@ -2268,13 +2245,10 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
		long_name = template.name;

	if (prefix) {
		name_len = strlen(long_name) + strlen(prefix) + 2;
		name = kmalloc(name_len, GFP_KERNEL);
		name = kasprintf(GFP_KERNEL, "%s %s", prefix, long_name);
		if (!name)
			return NULL;

		snprintf(name, name_len, "%s %s", prefix, long_name);

		template.name = name;
	} else {
		template.name = long_name;
@@ -3586,14 +3560,16 @@ int snd_soc_register_card(struct snd_soc_card *card)
		 * not both or neither.
		 */
		if (!!link->codec_name == !!link->codec_of_node) {
			dev_err(card->dev, "ASoC: Neither/both codec"
				" name/of_node are set for %s\n", link->name);
			dev_err(card->dev,
				"ASoC: Neither/both codec name/of_node are set for %s\n",
				link->name);
			return -EINVAL;
		}
		/* Codec DAI name must be specified */
		if (!link->codec_dai_name) {
			dev_err(card->dev, "ASoC: codec_dai_name not"
				" set for %s\n", link->name);
			dev_err(card->dev,
				"ASoC: codec_dai_name not set for %s\n",
				link->name);
			return -EINVAL;
		}

@@ -3602,8 +3578,9 @@ int snd_soc_register_card(struct snd_soc_card *card)
		 * can be left unspecified, and a dummy platform will be used.
		 */
		if (link->platform_name && link->platform_of_node) {
			dev_err(card->dev, "ASoC: Both platform name/of_node"
				" are set for %s\n", link->name);
			dev_err(card->dev,
				"ASoC: Both platform name/of_node are set for %s\n",
				link->name);
			return -EINVAL;
		}

@@ -3613,8 +3590,9 @@ int snd_soc_register_card(struct snd_soc_card *card)
		 * name alone..
		 */
		if (link->cpu_name && link->cpu_of_node) {
			dev_err(card->dev, "ASoC: Neither/both "
				"cpu name/of_node are set for %s\n",link->name);
			dev_err(card->dev,
				"ASoC: Neither/both cpu name/of_node are set for %s\n",
				link->name);
			return -EINVAL;
		}
		/*
@@ -3623,8 +3601,9 @@ int snd_soc_register_card(struct snd_soc_card *card)
		 */
		if (!link->cpu_dai_name &&
		    !(link->cpu_name || link->cpu_of_node)) {
			dev_err(card->dev, "ASoC: Neither cpu_dai_name nor "
				"cpu_name/of_node are set for %s\n", link->name);
			dev_err(card->dev,
				"ASoC: Neither cpu_dai_name nor cpu_name/of_node are set for %s\n",
				link->name);
			return -EINVAL;
		}
	}
@@ -3728,8 +3707,9 @@ static inline char *fmt_multiple_name(struct device *dev,
		struct snd_soc_dai_driver *dai_drv)
{
	if (dai_drv->name == NULL) {
		dev_err(dev, "ASoC: error - multiple DAI %s registered with"
				" no name\n", dev_name(dev));
		dev_err(dev,
			"ASoC: error - multiple DAI %s registered with no name\n",
			dev_name(dev));
		return NULL;
	}

@@ -3859,8 +3839,9 @@ static int snd_soc_register_dais(struct device *dev,

		list_for_each_entry(codec, &codec_list, list) {
			if (codec->dev == dev) {
				dev_dbg(dev, "ASoC: Mapped DAI %s to "
					"CODEC %s\n", dai->name, codec->name);
				dev_dbg(dev,
					"ASoC: Mapped DAI %s to CODEC %s\n",
					dai->name, codec->name);
				dai->codec = codec;
				break;
			}
@@ -4296,8 +4277,9 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,

	num_routes = of_property_count_strings(np, propname);
	if (num_routes < 0 || num_routes & 1) {
		dev_err(card->dev, "ASoC: Property '%s' does not exist or its"
			" length is not even\n", propname);
		dev_err(card->dev,
			"ASoC: Property '%s' does not exist or its length is not even\n",
			propname);
		return -EINVAL;
	}
	num_routes /= 2;
+26 −21
Original line number Diff line number Diff line
@@ -526,7 +526,6 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
	int wlistentries;
	size_t wlistsize;
	bool wname_in_long_name, kcname_in_long_name;
	size_t name_len;
	char *long_name;
	const char *name;
	int ret;
@@ -591,25 +590,19 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
		}

		if (wname_in_long_name && kcname_in_long_name) {
			name_len = strlen(w->name) - prefix_len + 1 +
				   strlen(w->kcontrol_news[kci].name) + 1;

			long_name = kmalloc(name_len, GFP_KERNEL);
			if (long_name == NULL) {
				kfree(wlist);
				return -ENOMEM;
			}

			/*
			 * The control will get a prefix from the control
			 * creation process but we're also using the same
			 * prefix for widgets so cut the prefix off the
			 * front of the widget name.
			 */
			snprintf(long_name, name_len, "%s %s",
			long_name = kasprintf(GFP_KERNEL, "%s %s",
				 w->name + prefix_len,
				 w->kcontrol_news[kci].name);
			long_name[name_len - 1] = '\0';
			if (long_name == NULL) {
				kfree(wlist);
				return -ENOMEM;
			}

			name = long_name;
		} else if (wname_in_long_name) {
@@ -1272,6 +1265,14 @@ static void dapm_seq_check_event(struct snd_soc_dapm_context *dapm,
		ev_name = "POST_PMD";
		power = 0;
		break;
	case SND_SOC_DAPM_WILL_PMU:
		ev_name = "WILL_PMU";
		power = 1;
		break;
	case SND_SOC_DAPM_WILL_PMD:
		ev_name = "WILL_PMD";
		power = 0;
		break;
	default:
		BUG();
		return;
@@ -1732,6 +1733,14 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
					&async_domain);
	async_synchronize_full_domain(&async_domain);

	list_for_each_entry(w, &down_list, power_list) {
		dapm_seq_check_event(dapm, w, SND_SOC_DAPM_WILL_PMD);
	}

	list_for_each_entry(w, &up_list, power_list) {
		dapm_seq_check_event(dapm, w, SND_SOC_DAPM_WILL_PMU);
	}

	/* Power down widgets first; try to avoid amplifying pops. */
	dapm_seq_run(dapm, &down_list, event, false);

@@ -3057,7 +3066,6 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
			 const struct snd_soc_dapm_widget *widget)
{
	struct snd_soc_dapm_widget *w;
	size_t name_len;
	int ret;

	if ((w = dapm_cnew_widget(widget)) == NULL)
@@ -3098,19 +3106,16 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
		break;
	}

	name_len = strlen(widget->name) + 1;
	if (dapm->codec && dapm->codec->name_prefix)
		name_len += 1 + strlen(dapm->codec->name_prefix);
	w->name = kmalloc(name_len, GFP_KERNEL);
		w->name = kasprintf(GFP_KERNEL, "%s %s",
			dapm->codec->name_prefix, widget->name);
	else
		w->name = kasprintf(GFP_KERNEL, "%s", widget->name);

	if (w->name == NULL) {
		kfree(w);
		return NULL;
	}
	if (dapm->codec && dapm->codec->name_prefix)
		snprintf((char *)w->name, name_len, "%s %s",
			dapm->codec->name_prefix, widget->name);
	else
		snprintf((char *)w->name, name_len, "%s", widget->name);

	switch (w->id) {
	case snd_soc_dapm_switch:
+47 −44
Original line number Diff line number Diff line
@@ -33,6 +33,29 @@

#define DPCM_MAX_BE_USERS	8

/**
 * snd_soc_set_runtime_hwparams - set the runtime hardware parameters
 * @substream: the pcm substream
 * @hw: the hardware parameters
 *
 * Sets the substream runtime hardware parameters.
 */
int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
	const struct snd_pcm_hardware *hw)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	runtime->hw.info = hw->info;
	runtime->hw.formats = hw->formats;
	runtime->hw.period_bytes_min = hw->period_bytes_min;
	runtime->hw.period_bytes_max = hw->period_bytes_max;
	runtime->hw.periods_min = hw->periods_min;
	runtime->hw.periods_max = hw->periods_max;
	runtime->hw.buffer_bytes_max = hw->buffer_bytes_max;
	runtime->hw.fifo_size = hw->fifo_size;
	return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_set_runtime_hwparams);

/* DPCM stream event, send event to FE and all active BEs. */
static int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,
	int event)
@@ -124,6 +147,26 @@ static void soc_pcm_apply_msb(struct snd_pcm_substream *substream,
	}
}

static void soc_pcm_init_runtime_hw(struct snd_pcm_hardware *hw,
	struct snd_soc_pcm_stream *codec_stream,
	struct snd_soc_pcm_stream *cpu_stream)
{
	hw->rate_min = max(codec_stream->rate_min, cpu_stream->rate_min);
	hw->rate_max = max(codec_stream->rate_max, cpu_stream->rate_max);
	hw->channels_min = max(codec_stream->channels_min,
		cpu_stream->channels_min);
	hw->channels_max = min(codec_stream->channels_max,
		cpu_stream->channels_max);
	hw->formats = codec_stream->formats & cpu_stream->formats;
	hw->rates = codec_stream->rates & cpu_stream->rates;
	if (codec_stream->rates
		& (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
		hw->rates |= cpu_stream->rates;
	if (cpu_stream->rates
		& (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
		hw->rates |= codec_stream->rates;
}

/*
 * Called by ALSA when a PCM substream is opened, the runtime->hw record is
 * then initialized and any private data can be allocated. This also calls
@@ -189,51 +232,11 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)

	/* Check that the codec and cpu DAIs are compatible */
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		runtime->hw.rate_min =
			max(codec_dai_drv->playback.rate_min,
			    cpu_dai_drv->playback.rate_min);
		runtime->hw.rate_max =
			min(codec_dai_drv->playback.rate_max,
			    cpu_dai_drv->playback.rate_max);
		runtime->hw.channels_min =
			max(codec_dai_drv->playback.channels_min,
				cpu_dai_drv->playback.channels_min);
		runtime->hw.channels_max =
			min(codec_dai_drv->playback.channels_max,
				cpu_dai_drv->playback.channels_max);
		runtime->hw.formats =
			codec_dai_drv->playback.formats & cpu_dai_drv->playback.formats;
		runtime->hw.rates =
			codec_dai_drv->playback.rates & cpu_dai_drv->playback.rates;
		if (codec_dai_drv->playback.rates
			   & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
			runtime->hw.rates |= cpu_dai_drv->playback.rates;
		if (cpu_dai_drv->playback.rates
			   & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
			runtime->hw.rates |= codec_dai_drv->playback.rates;
		soc_pcm_init_runtime_hw(&runtime->hw, &codec_dai_drv->playback,
			&cpu_dai_drv->playback);
	} else {
		runtime->hw.rate_min =
			max(codec_dai_drv->capture.rate_min,
			    cpu_dai_drv->capture.rate_min);
		runtime->hw.rate_max =
			min(codec_dai_drv->capture.rate_max,
			    cpu_dai_drv->capture.rate_max);
		runtime->hw.channels_min =
			max(codec_dai_drv->capture.channels_min,
				cpu_dai_drv->capture.channels_min);
		runtime->hw.channels_max =
			min(codec_dai_drv->capture.channels_max,
				cpu_dai_drv->capture.channels_max);
		runtime->hw.formats =
			codec_dai_drv->capture.formats & cpu_dai_drv->capture.formats;
		runtime->hw.rates =
			codec_dai_drv->capture.rates & cpu_dai_drv->capture.rates;
		if (codec_dai_drv->capture.rates
			   & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
			runtime->hw.rates |= cpu_dai_drv->capture.rates;
		if (cpu_dai_drv->capture.rates
			   & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
			runtime->hw.rates |= codec_dai_drv->capture.rates;
		soc_pcm_init_runtime_hw(&runtime->hw, &codec_dai_drv->capture,
			&cpu_dai_drv->capture);
	}

	ret = -EINVAL;
+4 −9
Original line number Diff line number Diff line
@@ -159,15 +159,10 @@ int __init snd_soc_util_init(void)
{
	int ret;

	soc_dummy_dev = platform_device_alloc("snd-soc-dummy", -1);
	if (!soc_dummy_dev)
		return -ENOMEM;

	ret = platform_device_add(soc_dummy_dev);
	if (ret != 0) {
		platform_device_put(soc_dummy_dev);
		return ret;
	}
	soc_dummy_dev =
		platform_device_register_simple("snd-soc-dummy", -1, NULL, 0);
	if (IS_ERR(soc_dummy_dev))
		return PTR_ERR(soc_dummy_dev);

	ret = platform_driver_register(&soc_dummy_driver);
	if (ret != 0)