Commit 9d3717f7 authored by David Lin's avatar David Lin Committed by Greg Kroah-Hartman
Browse files

greybus: audio: add runtime pm to enumerated control and DAPM widget



There's an issue that the userspace is not able to control both the
enumerated control and DAPM widget when audio bundle is in the SUSPEND
state. This patch fixes the issue by adding pm_runtime_get/put() calls
for the both controls.

Testing Done:
 - Use tinymix to get and put both enumerated control and DAPM widget as
   the followings, and observe audio bundle is able to wake up from
   suspend.

$ tinymix "GB 3 PB source" 1
$ tinymix "GB 3 PB source"
GB 3 PB source:	AIF1	>AIF2

$ tinymix "GB 3 AIF1_RX MUX" 2
$ tinymix "GB 3 AIF1_RX MUX"
GB 3 AIF1_RX MUX:	Stereo	Left	>Right

Reported-by: default avatarVaibhav Agarwal <vaibhav.agarwal@linaro.org>
Signed-off-by: default avatarDavid Lin <dtwlin@google.com>
Reviewed-by: default avatarVaibhav Agarwal <vaibhav.agarwal@linaro.org>
Reviewed-by: default avatarMark Greer <mgreer@animalcreek.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent 7c4a0edb
Loading
Loading
Loading
Loading
+47 −0
Original line number Diff line number Diff line
@@ -555,6 +555,7 @@ static int gbcodec_enum_ctl_get(struct snd_kcontrol *kcontrol,
	struct gb_audio_ctl_elem_value gbvalue;
	struct gbaudio_module_info *module;
	struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
	struct gb_bundle *bundle;

	module = find_gb_module(gb, kcontrol->id.name);
	if (!module)
@@ -564,8 +565,17 @@ static int gbcodec_enum_ctl_get(struct snd_kcontrol *kcontrol,
	if (ctl_id < 0)
		return -EINVAL;

	bundle = to_gb_bundle(module->dev);

	ret = gb_pm_runtime_get_sync(bundle);
	if (ret)
		return ret;

	ret = gb_audio_gb_get_control(module->mgmt_connection, ctl_id,
				      GB_AUDIO_INVALID_INDEX, &gbvalue);

	gb_pm_runtime_put_autosuspend(bundle);

	if (ret) {
		dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
				    __func__, kcontrol->id.name);
@@ -589,6 +599,7 @@ static int gbcodec_enum_ctl_put(struct snd_kcontrol *kcontrol,
	struct gb_audio_ctl_elem_value gbvalue;
	struct gbaudio_module_info *module;
	struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
	struct gb_bundle *bundle;

	module = find_gb_module(gb, kcontrol->id.name);
	if (!module)
@@ -609,8 +620,17 @@ static int gbcodec_enum_ctl_put(struct snd_kcontrol *kcontrol,
			ucontrol->value.enumerated.item[1];
	}

	bundle = to_gb_bundle(module->dev);

	ret = gb_pm_runtime_get_sync(bundle);
	if (ret)
		return ret;

	ret = gb_audio_gb_set_control(module->mgmt_connection, ctl_id,
				      GB_AUDIO_INVALID_INDEX, &gbvalue);

	gb_pm_runtime_put_autosuspend(bundle);

	if (ret) {
		dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
				    __func__, kcontrol->id.name);
@@ -698,6 +718,7 @@ static int gbcodec_enum_dapm_ctl_get(struct snd_kcontrol *kcontrol,
	struct snd_soc_codec *codec = widget->codec;
	struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
	struct gb_bundle *bundle;

	module = find_gb_module(gb, kcontrol->id.name);
	if (!module)
@@ -707,8 +728,17 @@ static int gbcodec_enum_dapm_ctl_get(struct snd_kcontrol *kcontrol,
	if (ctl_id < 0)
		return -EINVAL;

	bundle = to_gb_bundle(module->dev);

	ret = gb_pm_runtime_get_sync(bundle);
	if (ret)
		return ret;

	ret = gb_audio_gb_get_control(module->mgmt_connection, ctl_id,
				      GB_AUDIO_INVALID_INDEX, &gbvalue);

	gb_pm_runtime_put_autosuspend(bundle);

	if (ret) {
		dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
				    __func__, kcontrol->id.name);
@@ -736,6 +766,7 @@ static int gbcodec_enum_dapm_ctl_put(struct snd_kcontrol *kcontrol,
	struct snd_soc_codec *codec = widget->codec;
	struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
	struct gb_bundle *bundle;

	if (ucontrol->value.enumerated.item[0] > e->max - 1)
		return -EINVAL;
@@ -749,8 +780,17 @@ static int gbcodec_enum_dapm_ctl_put(struct snd_kcontrol *kcontrol,
		return -EINVAL;

	change = 0;
	bundle = to_gb_bundle(module->dev);

	ret = gb_pm_runtime_get_sync(bundle);
	if (ret)
		return ret;

	ret = gb_audio_gb_get_control(module->mgmt_connection, ctl_id,
				      GB_AUDIO_INVALID_INDEX, &gbvalue);

	gb_pm_runtime_put_autosuspend(bundle);

	if (ret) {
		dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
				    __func__, kcontrol->id.name);
@@ -782,8 +822,15 @@ static int gbcodec_enum_dapm_ctl_put(struct snd_kcontrol *kcontrol,
	}

	if (change) {
		ret = gb_pm_runtime_get_sync(bundle);
		if (ret)
			return ret;

		ret = gb_audio_gb_set_control(module->mgmt_connection, ctl_id,
					      GB_AUDIO_INVALID_INDEX, &gbvalue);

		gb_pm_runtime_put_autosuspend(bundle);

		if (ret) {
			dev_err_ratelimited(codec->dev,
					    "%d:Error in %s for %s\n", ret,