diff options
author | David Lin <dtwlin@google.com> | 2016-07-14 15:13:00 -0500 |
---|---|---|
committer | Alex Elder <elder@linaro.org> | 2016-07-14 16:53:55 -0500 |
commit | 6ba7fad430d6300b966800bc5d2c782e2baf6f1d (patch) | |
tree | 69966b93b1c1381c4b807e0d92eab27e4fc654af /drivers/staging/greybus/audio_topology.c | |
parent | 61e13db9cc8945d53f72d4021594ee3be214e667 (diff) | |
download | op-kernel-dev-6ba7fad430d6300b966800bc5d2c782e2baf6f1d.zip op-kernel-dev-6ba7fad430d6300b966800bc5d2c782e2baf6f1d.tar.gz |
greybus: audio: add runtime pm support
Add runtime pm support to audio protocol device class driver.
Testing Done:
- Use white speaker module and check the interface is autosuspended when
it's idle and resumed when playback audio
Signed-off-by: David Lin <dtwlin@google.com>
Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
Reviewed-by: Vaibhav Agarwal <vaibhav.agarwal@linaro.org>
Signed-off-by: Alex Elder <elder@linaro.org>
Diffstat (limited to 'drivers/staging/greybus/audio_topology.c')
-rw-r--r-- | drivers/staging/greybus/audio_topology.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/staging/greybus/audio_topology.c b/drivers/staging/greybus/audio_topology.c index e0779ca..487f744 100644 --- a/drivers/staging/greybus/audio_topology.c +++ b/drivers/staging/greybus/audio_topology.c @@ -213,6 +213,7 @@ static int gbcodec_mixer_ctl_get(struct snd_kcontrol *kcontrol, struct gbaudio_module_info *module; struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec); + struct gb_bundle *bundle; dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name); module = find_gb_module(gb, kcontrol->id.name); @@ -221,9 +222,17 @@ static int gbcodec_mixer_ctl_get(struct snd_kcontrol *kcontrol, data = (struct gbaudio_ctl_pvt *)kcontrol->private_value; info = (struct gb_audio_ctl_elem_info *)data->info; + 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, data->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); @@ -266,6 +275,7 @@ static int gbcodec_mixer_ctl_put(struct snd_kcontrol *kcontrol, struct gbaudio_module_info *module; struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec); + struct gb_bundle *bundle; dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name); module = find_gb_module(gb, kcontrol->id.name); @@ -274,6 +284,7 @@ static int gbcodec_mixer_ctl_put(struct snd_kcontrol *kcontrol, data = (struct gbaudio_ctl_pvt *)kcontrol->private_value; info = (struct gb_audio_ctl_elem_info *)data->info; + bundle = to_gb_bundle(module->dev); /* update ucontrol */ switch (info->type) { @@ -302,8 +313,15 @@ static int gbcodec_mixer_ctl_put(struct snd_kcontrol *kcontrol, if (ret) return ret; + ret = gb_pm_runtime_get_sync(bundle); + if (ret) + return ret; + ret = gb_audio_gb_set_control(module->mgmt_connection, data->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); @@ -370,6 +388,7 @@ static int gbcodec_mixer_dapm_ctl_get(struct snd_kcontrol *kcontrol, struct snd_soc_dapm_widget *widget = wlist->widgets[0]; struct snd_soc_codec *codec = widget->codec; struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec); + struct gb_bundle *bundle; dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name); module = find_gb_module(gb, kcontrol->id.name); @@ -378,14 +397,22 @@ static int gbcodec_mixer_dapm_ctl_get(struct snd_kcontrol *kcontrol, data = (struct gbaudio_ctl_pvt *)kcontrol->private_value; info = (struct gb_audio_ctl_elem_info *)data->info; + bundle = to_gb_bundle(module->dev); if (data->vcount == 2) dev_warn(widget->dapm->dev, "GB: Control '%s' is stereo, which is not supported\n", kcontrol->id.name); + ret = gb_pm_runtime_get_sync(bundle); + if (ret) + return ret; + ret = gb_audio_gb_get_control(module->mgmt_connection, data->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); @@ -410,6 +437,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol, struct snd_soc_dapm_widget *widget = wlist->widgets[0]; struct snd_soc_codec *codec = widget->codec; struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec); + struct gb_bundle *bundle; dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name); module = find_gb_module(gb, kcontrol->id.name); @@ -418,6 +446,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol, data = (struct gbaudio_ctl_pvt *)kcontrol->private_value; info = (struct gb_audio_ctl_elem_info *)data->info; + bundle = to_gb_bundle(module->dev); if (data->vcount == 2) dev_warn(widget->dapm->dev, @@ -441,9 +470,17 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol, } gbvalue.value.integer_value[0] = ucontrol->value.integer.value[0]; + + ret = gb_pm_runtime_get_sync(bundle); + if (ret) + return ret; + ret = gb_audio_gb_set_control(module->mgmt_connection, data->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, @@ -850,6 +887,7 @@ static int gbaudio_widget_event(struct snd_soc_dapm_widget *w, struct snd_soc_codec *codec = w->codec; struct gbaudio_codec_info *gbcodec = snd_soc_codec_get_drvdata(codec); struct gbaudio_module_info *module; + struct gb_bundle *bundle; dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event); @@ -865,6 +903,12 @@ static int gbaudio_widget_event(struct snd_soc_dapm_widget *w, return -EINVAL; } + bundle = to_gb_bundle(module->dev); + + ret = gb_pm_runtime_get_sync(bundle); + if (ret) + return ret; + switch (event) { case SND_SOC_DAPM_PRE_PMU: ret = gb_audio_gb_enable_widget(module->mgmt_connection, wid); @@ -883,6 +927,9 @@ static int gbaudio_widget_event(struct snd_soc_dapm_widget *w, dev_err_ratelimited(codec->dev, "%d: widget, event:%d failed:%d\n", wid, event, ret); + + gb_pm_runtime_put_autosuspend(bundle); + return ret; } |