summaryrefslogtreecommitdiff
path: root/drivers/staging/greybus/audio_topology.c
diff options
context:
space:
mode:
authorDavid Lin <dtwlin@google.com>2016-07-25 16:29:20 -0700
committerGreg Kroah-Hartman <gregkh@google.com>2016-07-26 20:58:37 -0700
commit9d3717f71c22c4f39723f18ed094c552f4b73146 (patch)
tree29c04b17083806b79cf14a48f1738ce23c1f10a3 /drivers/staging/greybus/audio_topology.c
parent7c4a0edb38ba734bd89efbda4262698a58839c26 (diff)
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: Vaibhav Agarwal <vaibhav.agarwal@linaro.org> Signed-off-by: David Lin <dtwlin@google.com> Reviewed-by: Vaibhav Agarwal <vaibhav.agarwal@linaro.org> Reviewed-by: Mark Greer <mgreer@animalcreek.com> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Diffstat (limited to 'drivers/staging/greybus/audio_topology.c')
-rw-r--r--drivers/staging/greybus/audio_topology.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/staging/greybus/audio_topology.c b/drivers/staging/greybus/audio_topology.c
index 17ba0a028426..3c7c786d3b03 100644
--- a/drivers/staging/greybus/audio_topology.c
+++ b/drivers/staging/greybus/audio_topology.c
@@ -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,