summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorDeepa Madiregama <dmadiregama@nvidia.com>2014-04-22 17:06:13 +0530
committerRiham Haidar <rhaidar@nvidia.com>2014-05-06 10:49:42 -0700
commitff271dcc374f2dfc41228feaef2f369c5151a30a (patch)
tree8e67761712a2099109de1433fbdb049e6f23e57a /sound
parent7bac96f903147e9dfdd4811e3cfa27e0c032010a (diff)
ASoC: Tegra: Add compress offload volume control
Add alsa control for volume changes during compress offload playback. Bug 1498475 Change-Id: I5572338648a2fefdcf3095702bcbade35f1b0565 Signed-off-by: Deepa Madiregama <dmadiregama@nvidia.com> Reviewed-on: http://git-master/r/399682 Reviewed-by: Ravindra Lokhande <rlokhande@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Sumit Bhattacharya <sumitb@nvidia.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/tegra/tegra_offload.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/sound/soc/tegra/tegra_offload.c b/sound/soc/tegra/tegra_offload.c
index 465d28f8a961..3940f42c44ea 100644
--- a/sound/soc/tegra/tegra_offload.c
+++ b/sound/soc/tegra/tegra_offload.c
@@ -51,6 +51,8 @@ struct tegra_offload_compr_data {
struct tegra_offload_compr_ops *ops;
struct snd_codec codec;
int stream_id;
+ int stream_vol[2];
+ struct snd_kcontrol *kcontrol;
};
static struct tegra_offload_ops offload_ops;
@@ -107,6 +109,80 @@ static void tegra_offload_compr_fragment_elapsed(void *arg, unsigned int is_eos)
}
}
+static int tegra_set_compress_volume(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ret = 1;
+ struct snd_compr_stream *stream = snd_kcontrol_chip(kcontrol);
+ struct tegra_offload_compr_data *data = stream->runtime->private_data;
+ struct snd_soc_pcm_runtime *rtd = stream->device->private_data;
+ struct device *dev = rtd->platform->dev;
+
+ pr_debug("%s: value[0]: %d value[1]: %d\n", __func__,
+ (int)ucontrol->value.integer.value[0],
+ (int)ucontrol->value.integer.value[1]);
+ ret = data->ops->set_stream_volume(data->stream_id,
+ (int)ucontrol->value.integer.value[0],
+ (int)ucontrol->value.integer.value[1]);
+ if (ret < 0) {
+ dev_err(dev, "Failed to get compr caps. ret %d", ret);
+ return ret;
+ } else {
+ data->stream_vol[0] = (int)ucontrol->value.integer.value[0];
+ data->stream_vol[1] = (int)ucontrol->value.integer.value[1];
+ }
+ return 1;
+}
+
+
+static int tegra_get_compress_volume(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_compr_stream *stream = snd_kcontrol_chip(kcontrol);
+ struct tegra_offload_compr_data *data = stream->runtime->private_data;
+
+ ucontrol->value.integer.value[0] = data->stream_vol[0];
+ ucontrol->value.integer.value[1] = data->stream_vol[1];
+
+ return 0;
+}
+
+struct snd_kcontrol_new tegra_offload_volume =
+ SOC_DOUBLE_EXT("Compress Playback Volume", 0, 1, 0, 0xFFFFFFFF,
+ 1, tegra_get_compress_volume, tegra_set_compress_volume);
+
+static int tegra_offload_compr_add_controls(struct snd_compr_stream *stream)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = stream->device->private_data;
+ struct device *dev = rtd->platform->dev;
+ struct tegra_offload_compr_data *data = stream->runtime->private_data;
+
+ data->kcontrol = snd_ctl_new1(&tegra_offload_volume, stream);
+ ret = snd_ctl_add(rtd->card->snd_card, data->kcontrol);
+ if (ret < 0) {
+ dev_err(dev, "Can't add offload volume");
+ return ret;
+ }
+ return ret;
+}
+
+
+static int tegra_offload_compr_remove_controls(struct snd_compr_stream *stream)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = stream->device->private_data;
+ struct device *dev = rtd->platform->dev;
+ struct tegra_offload_compr_data *data = stream->runtime->private_data;
+
+ ret = snd_ctl_remove(rtd->card->snd_card, data->kcontrol);
+ if (ret < 0) {
+ dev_err(dev, "Can't remove offload volume");
+ return ret;
+ }
+ return ret;
+}
+
static int tegra_offload_compr_open(struct snd_compr_stream *stream)
{
struct snd_soc_pcm_runtime *rtd = stream->device->private_data;
@@ -138,6 +214,11 @@ static int tegra_offload_compr_open(struct snd_compr_stream *stream)
}
stream->runtime->private_data = data;
+
+ ret = tegra_offload_compr_add_controls(stream);
+ if (ret)
+ dev_err(dev, "Failed to add controls\n");
+
return 0;
}
@@ -145,9 +226,14 @@ static int tegra_offload_compr_free(struct snd_compr_stream *stream)
{
struct device *dev = stream->device->dev;
struct tegra_offload_compr_data *data = stream->runtime->private_data;
+ int ret = 0;
dev_vdbg(dev, "%s", __func__);
+ ret = tegra_offload_compr_remove_controls(stream);
+ if (ret)
+ dev_err(dev, "Failed to remove controls\n");
+
data->ops->stream_close(data->stream_id);
devm_kfree(dev, data);
return 0;