All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] Add support for DSP volume controls
@ 2022-12-14 18:54 Amadeusz Sławiński
  2022-12-14 18:54 ` [PATCH 1/4] ASoC: Intel: avs: Add peakvol runtime-parameter requests Amadeusz Sławiński
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Amadeusz Sławiński @ 2022-12-14 18:54 UTC (permalink / raw)
  To: Mark Brown
  Cc: Cezary Rojewski, alsa-devel, Takashi Iwai, Pierre-Louis Bossart,
	Amadeusz Sławiński

Some devices like DMIC don't expose native controls or need volume limit
due to possible HW damage. Add support for volume controls allowing to
change volume level in DSP. Maximum volume level is imposed by the
topology file which defines given path.

Amadeusz Sławiński (4):
  ASoC: Intel: avs: Add peakvol runtime-parameter requests
  ASoC: Intel: avs: Add control volume operations
  ASoC: Intel: avs: Parse control tuples
  ASoC: Intel: avs: Peakvol module configuration

 include/uapi/sound/intel/avs/tokens.h |   4 +
 sound/soc/intel/avs/Makefile          |   2 +-
 sound/soc/intel/avs/control.c         | 105 ++++++++++++++++++++++++++
 sound/soc/intel/avs/control.h         |  23 ++++++
 sound/soc/intel/avs/messages.c        |  29 +++++++
 sound/soc/intel/avs/messages.h        |  33 ++++++++
 sound/soc/intel/avs/path.c            |  62 +++++++++++++++
 sound/soc/intel/avs/topology.c        |  76 +++++++++++++++++++
 sound/soc/intel/avs/topology.h        |   3 +
 9 files changed, 336 insertions(+), 1 deletion(-)
 create mode 100644 sound/soc/intel/avs/control.c
 create mode 100644 sound/soc/intel/avs/control.h

-- 
2.25.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] ASoC: Intel: avs: Add peakvol runtime-parameter requests
  2022-12-14 18:54 [PATCH 0/4] Add support for DSP volume controls Amadeusz Sławiński
@ 2022-12-14 18:54 ` Amadeusz Sławiński
  2022-12-14 18:54 ` [PATCH 2/4] ASoC: Intel: avs: Add control volume operations Amadeusz Sławiński
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Amadeusz Sławiński @ 2022-12-14 18:54 UTC (permalink / raw)
  To: Mark Brown
  Cc: Cezary Rojewski, alsa-devel, Takashi Iwai, Pierre-Louis Bossart,
	Amadeusz Sławiński

Peakvol module allows for setting and obtaining DSP volume as well as
modifying shape and duration at which volume actually changes. Add IPC
messages to expose those capabilities.

Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
---
 sound/soc/intel/avs/messages.c | 29 +++++++++++++++++++++++++++++
 sound/soc/intel/avs/messages.h | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+)

diff --git a/sound/soc/intel/avs/messages.c b/sound/soc/intel/avs/messages.c
index e11ae4246416..f887ab5b0311 100644
--- a/sound/soc/intel/avs/messages.c
+++ b/sound/soc/intel/avs/messages.c
@@ -702,6 +702,35 @@ int avs_ipc_copier_set_sink_format(struct avs_dev *adev, u16 module_id,
 					(u8 *)&cpr_fmt, sizeof(cpr_fmt));
 }
 
+int avs_ipc_peakvol_set_volume(struct avs_dev *adev, u16 module_id, u8 instance_id,
+			       struct avs_volume_cfg *vol)
+{
+	return avs_ipc_set_large_config(adev, module_id, instance_id, AVS_PEAKVOL_VOLUME, (u8 *)vol,
+					sizeof(*vol));
+}
+
+int avs_ipc_peakvol_get_volume(struct avs_dev *adev, u16 module_id, u8 instance_id,
+			       struct avs_volume_cfg **vols, size_t *num_vols)
+{
+	size_t payload_size;
+	u8 *payload;
+	int ret;
+
+	ret = avs_ipc_get_large_config(adev, module_id, instance_id, AVS_PEAKVOL_VOLUME, NULL, 0,
+				       &payload, &payload_size);
+	if (ret)
+		return ret;
+
+	/* Non-zero payload expected for PEAKVOL_VOLUME. */
+	if (!payload_size)
+		return -EREMOTEIO;
+
+	*vols = (struct avs_volume_cfg *)payload;
+	*num_vols = payload_size / sizeof(**vols);
+
+	return 0;
+}
+
 #ifdef CONFIG_DEBUG_FS
 int avs_ipc_set_enable_logs(struct avs_dev *adev, u8 *log_info, size_t size)
 {
diff --git a/sound/soc/intel/avs/messages.h b/sound/soc/intel/avs/messages.h
index 9dd835527e02..d3b60ae7d743 100644
--- a/sound/soc/intel/avs/messages.h
+++ b/sound/soc/intel/avs/messages.h
@@ -561,6 +561,12 @@ int avs_ipc_set_system_time(struct avs_dev *adev);
 #define AVS_COPIER_MOD_UUID \
 	GUID_INIT(0x9BA00C83, 0xCA12, 0x4A83, 0x94, 0x3C, 0x1F, 0xA2, 0xE8, 0x2F, 0x9D, 0xDA)
 
+#define AVS_PEAKVOL_MOD_UUID \
+	GUID_INIT(0x8A171323, 0x94A3, 0x4E1D, 0xAF, 0xE9, 0xFE, 0x5D, 0xBA, 0xa4, 0xC3, 0x93)
+
+#define AVS_GAIN_MOD_UUID \
+	GUID_INIT(0x61BCA9A8, 0x18D0, 0x4A18, 0x8E, 0x7B, 0x26, 0x39, 0x21, 0x98, 0x04, 0xB7)
+
 #define AVS_KPBUFF_MOD_UUID \
 	GUID_INIT(0xA8A0CB32, 0x4A77, 0x4DB1, 0x85, 0xC7, 0x53, 0xD7, 0xEE, 0x07, 0xBC, 0xE6)
 
@@ -729,6 +735,19 @@ struct avs_copier_cfg {
 	struct avs_copier_gtw_cfg gtw_cfg;
 } __packed;
 
+struct avs_volume_cfg {
+	u32 channel_id;
+	u32 target_volume;
+	u32 curve_type;
+	u32 reserved; /* alignment */
+	u64 curve_duration;
+} __packed;
+
+struct avs_peakvol_cfg {
+	struct avs_modcfg_base base;
+	struct avs_volume_cfg vols[];
+} __packed;
+
 struct avs_micsel_cfg {
 	struct avs_modcfg_base base;
 	struct avs_audio_format out_fmt;
@@ -802,6 +821,20 @@ int avs_ipc_copier_set_sink_format(struct avs_dev *adev, u16 module_id,
 				   const struct avs_audio_format *src_fmt,
 				   const struct avs_audio_format *sink_fmt);
 
+enum avs_peakvol_runtime_param {
+	AVS_PEAKVOL_VOLUME = 0,
+};
+
+enum avs_audio_curve_type {
+	AVS_AUDIO_CURVE_NONE = 0,
+	AVS_AUDIO_CURVE_WINDOWS_FADE = 1,
+};
+
+int avs_ipc_peakvol_set_volume(struct avs_dev *adev, u16 module_id, u8 instance_id,
+			       struct avs_volume_cfg *vol);
+int avs_ipc_peakvol_get_volume(struct avs_dev *adev, u16 module_id, u8 instance_id,
+			       struct avs_volume_cfg **vols, size_t *num_vols);
+
 #define AVS_PROBE_INST_ID	0
 
 enum avs_probe_runtime_param {
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] ASoC: Intel: avs: Add control volume operations
  2022-12-14 18:54 [PATCH 0/4] Add support for DSP volume controls Amadeusz Sławiński
  2022-12-14 18:54 ` [PATCH 1/4] ASoC: Intel: avs: Add peakvol runtime-parameter requests Amadeusz Sławiński
@ 2022-12-14 18:54 ` Amadeusz Sławiński
  2022-12-14 18:54 ` [PATCH 3/4] ASoC: Intel: avs: Parse control tuples Amadeusz Sławiński
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Amadeusz Sławiński @ 2022-12-14 18:54 UTC (permalink / raw)
  To: Mark Brown
  Cc: Cezary Rojewski, alsa-devel, Takashi Iwai, Pierre-Louis Bossart,
	Amadeusz Sławiński

To make introduced peakvol module useful from userspace perspective,
expose ALSA controls allowing DSP volume modification. These provide
even more granular control over volume but are also the only way to
modify volume for devices devoid of codec kcontrols e.g.: DMIC.

Co-authored-by: Cezary Rojewski <cezary.rojewski@intel.com>
Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
---
 sound/soc/intel/avs/Makefile  |  2 +-
 sound/soc/intel/avs/control.c | 95 +++++++++++++++++++++++++++++++++++
 sound/soc/intel/avs/control.h | 23 +++++++++
 3 files changed, 119 insertions(+), 1 deletion(-)
 create mode 100644 sound/soc/intel/avs/control.c
 create mode 100644 sound/soc/intel/avs/control.h

diff --git a/sound/soc/intel/avs/Makefile b/sound/soc/intel/avs/Makefile
index 1c6924a1ebca..460ee6599daf 100644
--- a/sound/soc/intel/avs/Makefile
+++ b/sound/soc/intel/avs/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
 snd-soc-avs-objs := dsp.o ipc.o messages.o utils.o core.o loader.o \
-		    topology.o path.o pcm.o board_selection.o
+		    topology.o path.o pcm.o board_selection.o control.o
 snd-soc-avs-objs += cldma.o
 snd-soc-avs-objs += skl.o apl.o
 
diff --git a/sound/soc/intel/avs/control.c b/sound/soc/intel/avs/control.c
new file mode 100644
index 000000000000..92b3aad0baca
--- /dev/null
+++ b/sound/soc/intel/avs/control.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+//
+// Authors: Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
+//          Cezary Rojewski <cezary.rojewski@intel.com>
+//
+
+#include <sound/soc.h>
+#include "avs.h"
+#include "control.h"
+#include "messages.h"
+#include "path.h"
+
+static struct avs_dev *avs_get_kcontrol_adev(struct snd_kcontrol *kcontrol)
+{
+	struct snd_soc_dapm_widget *w;
+
+	w = snd_soc_dapm_kcontrol_widget(kcontrol);
+
+	return to_avs_dev(w->dapm->component->dev);
+}
+
+static struct avs_path_module *avs_get_kcontrol_module(struct avs_dev *adev, u32 id)
+{
+	return NULL;
+}
+
+int avs_control_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+	struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value;
+	struct avs_control_data *ctl_data = (struct avs_control_data *)mc->dobj.private;
+	struct avs_dev *adev = avs_get_kcontrol_adev(kcontrol);
+	struct avs_volume_cfg *dspvols = NULL;
+	struct avs_path_module *active_module;
+	size_t num_dspvols;
+	int ret = 0;
+
+	/* prevent access to modules while path is being constructed */
+	mutex_lock(&adev->path_mutex);
+
+	active_module = avs_get_kcontrol_module(adev, ctl_data->id);
+	if (active_module) {
+		ret = avs_ipc_peakvol_get_volume(adev, active_module->module_id,
+						 active_module->instance_id, &dspvols,
+						 &num_dspvols);
+		if (!ret)
+			ucontrol->value.integer.value[0] = dspvols[0].target_volume;
+
+		ret = AVS_IPC_RET(ret);
+		kfree(dspvols);
+	} else {
+		ucontrol->value.integer.value[0] = ctl_data->volume;
+	}
+
+	mutex_unlock(&adev->path_mutex);
+	return ret;
+}
+
+int avs_control_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+	struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value;
+	struct avs_control_data *ctl_data = (struct avs_control_data *)mc->dobj.private;
+	struct avs_dev *adev = avs_get_kcontrol_adev(kcontrol);
+	long *volume = &ctl_data->volume;
+	struct avs_path_module *active_module;
+	struct avs_volume_cfg dspvol = {0};
+	long ctlvol = ucontrol->value.integer.value[0];
+	int ret = 0, changed = 0;
+
+	if (ctlvol < 0 || ctlvol > mc->max)
+		return -EINVAL;
+
+	/* prevent access to modules while path is being constructed */
+	mutex_lock(&adev->path_mutex);
+
+	if (*volume != ctlvol) {
+		*volume = ctlvol;
+		changed = 1;
+	}
+
+	active_module = avs_get_kcontrol_module(adev, ctl_data->id);
+	if (active_module) {
+		dspvol.channel_id = AVS_ALL_CHANNELS_MASK;
+		dspvol.target_volume = *volume;
+
+		ret = avs_ipc_peakvol_set_volume(adev, active_module->module_id,
+						 active_module->instance_id, &dspvol);
+		ret = AVS_IPC_RET(ret);
+	}
+
+	mutex_unlock(&adev->path_mutex);
+
+	return ret ? ret : changed;
+}
diff --git a/sound/soc/intel/avs/control.h b/sound/soc/intel/avs/control.h
new file mode 100644
index 000000000000..08631bde13c3
--- /dev/null
+++ b/sound/soc/intel/avs/control.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
+ *
+ * Authors: Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
+ *          Cezary Rojewski <cezary.rojewski@intel.com>
+ */
+
+#ifndef __SOUND_SOC_INTEL_AVS_CTRL_H
+#define __SOUND_SOC_INTEL_AVS_CTRL_H
+
+#include <sound/control.h>
+
+struct avs_control_data {
+	u32 id;
+
+	long volume;
+};
+
+int avs_control_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+int avs_control_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+
+#endif
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/4] ASoC: Intel: avs: Parse control tuples
  2022-12-14 18:54 [PATCH 0/4] Add support for DSP volume controls Amadeusz Sławiński
  2022-12-14 18:54 ` [PATCH 1/4] ASoC: Intel: avs: Add peakvol runtime-parameter requests Amadeusz Sławiński
  2022-12-14 18:54 ` [PATCH 2/4] ASoC: Intel: avs: Add control volume operations Amadeusz Sławiński
@ 2022-12-14 18:54 ` Amadeusz Sławiński
  2022-12-14 18:55 ` [PATCH 4/4] ASoC: Intel: avs: Peakvol module configuration Amadeusz Sławiński
  2022-12-27 11:57 ` [PATCH 0/4] Add support for DSP volume controls Mark Brown
  4 siblings, 0 replies; 6+ messages in thread
From: Amadeusz Sławiński @ 2022-12-14 18:54 UTC (permalink / raw)
  To: Mark Brown
  Cc: Cezary Rojewski, alsa-devel, Takashi Iwai, Pierre-Louis Bossart,
	Amadeusz Sławiński

Add callback to handle loading of kcontrol and linking it to active
widget. In order to link kcontrol to specific modules add additional
field to module data, as well as specify control id in kcontrol data.

Co-authored-by: Cezary Rojewski <cezary.rojewski@intel.com>
Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
---
 include/uapi/sound/intel/avs/tokens.h |  4 ++
 sound/soc/intel/avs/control.c         | 10 ++++
 sound/soc/intel/avs/topology.c        | 76 +++++++++++++++++++++++++++
 sound/soc/intel/avs/topology.h        |  3 ++
 4 files changed, 93 insertions(+)

diff --git a/include/uapi/sound/intel/avs/tokens.h b/include/uapi/sound/intel/avs/tokens.h
index 754f02b2f444..4ffe546aa409 100644
--- a/include/uapi/sound/intel/avs/tokens.h
+++ b/include/uapi/sound/intel/avs/tokens.h
@@ -108,6 +108,7 @@ enum avs_tplg_token {
 	AVS_TKN_MOD_CORE_ID_U8				= 1704,
 	AVS_TKN_MOD_PROC_DOMAIN_U8			= 1705,
 	AVS_TKN_MOD_MODCFG_EXT_ID_U32			= 1706,
+	AVS_TKN_MOD_KCONTROL_ID_U32			= 1707,
 
 	/* struct avs_tplg_path_template */
 	AVS_TKN_PATH_TMPL_ID_U32			= 1801,
@@ -121,6 +122,9 @@ enum avs_tplg_token {
 	AVS_TKN_PIN_FMT_INDEX_U32			= 2201,
 	AVS_TKN_PIN_FMT_IOBS_U32			= 2202,
 	AVS_TKN_PIN_FMT_AFMT_ID_U32			= 2203,
+
+	/* struct avs_tplg_kcontrol */
+	AVS_TKN_KCONTROL_ID_U32				= 2301,
 };
 
 #endif
diff --git a/sound/soc/intel/avs/control.c b/sound/soc/intel/avs/control.c
index 92b3aad0baca..a8b14b784f8a 100644
--- a/sound/soc/intel/avs/control.c
+++ b/sound/soc/intel/avs/control.c
@@ -23,6 +23,16 @@ static struct avs_dev *avs_get_kcontrol_adev(struct snd_kcontrol *kcontrol)
 
 static struct avs_path_module *avs_get_kcontrol_module(struct avs_dev *adev, u32 id)
 {
+	struct avs_path *path;
+	struct avs_path_pipeline *ppl;
+	struct avs_path_module *mod;
+
+	list_for_each_entry(path, &adev->path_list, node)
+		list_for_each_entry(ppl, &path->ppl_list, node)
+			list_for_each_entry(mod, &ppl->mod_list, node)
+				if (mod->template->ctl_id && mod->template->ctl_id == id)
+					return mod;
+
 	return NULL;
 }
 
diff --git a/sound/soc/intel/avs/topology.c b/sound/soc/intel/avs/topology.c
index e845eaf0a1e7..5fee7a8ec06a 100644
--- a/sound/soc/intel/avs/topology.c
+++ b/sound/soc/intel/avs/topology.c
@@ -13,6 +13,7 @@
 #include <sound/soc-topology.h>
 #include <uapi/sound/intel/avs/tokens.h>
 #include "avs.h"
+#include "control.h"
 #include "topology.h"
 
 /* Get pointer to vendor array at the specified offset. */
@@ -1070,6 +1071,12 @@ static const struct avs_tplg_token_parser module_parsers[] = {
 		.offset = offsetof(struct avs_tplg_module, cfg_ext),
 		.parse = avs_parse_modcfg_ext_ptr,
 	},
+	{
+		.token = AVS_TKN_MOD_KCONTROL_ID_U32,
+		.type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
+		.offset = offsetof(struct avs_tplg_module, ctl_id),
+		.parse = avs_parse_byte_token,
+	},
 };
 
 static struct avs_tplg_module *
@@ -1435,6 +1442,16 @@ static int avs_widget_load(struct snd_soc_component *comp, int index,
 	return 0;
 }
 
+static int avs_widget_ready(struct snd_soc_component *comp, int index,
+			    struct snd_soc_dapm_widget *w,
+			    struct snd_soc_tplg_dapm_widget *dw)
+{
+	struct avs_tplg_path_template *template = w->priv;
+
+	template->w = w;
+	return 0;
+}
+
 static int avs_dai_load(struct snd_soc_component *comp, int index,
 			struct snd_soc_dai_driver *dai_drv, struct snd_soc_tplg_pcm *pcm,
 			struct snd_soc_dai *dai)
@@ -1586,9 +1603,68 @@ static int avs_manifest(struct snd_soc_component *comp, int index,
 	return avs_tplg_parse_bindings(comp, tuples, remaining);
 }
 
+#define AVS_CONTROL_OPS_VOLUME	257
+
+static const struct snd_soc_tplg_kcontrol_ops avs_control_ops[] = {
+	{
+		.id = AVS_CONTROL_OPS_VOLUME,
+		.get = avs_control_volume_get,
+		.put = avs_control_volume_put,
+	},
+};
+
+static const struct avs_tplg_token_parser control_parsers[] = {
+	{
+		.token = AVS_TKN_KCONTROL_ID_U32,
+		.type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
+		.offset = offsetof(struct avs_control_data, id),
+		.parse = avs_parse_word_token,
+	},
+};
+
+static int
+avs_control_load(struct snd_soc_component *comp, int index, struct snd_kcontrol_new *ctmpl,
+		 struct snd_soc_tplg_ctl_hdr *hdr)
+{
+	struct snd_soc_tplg_vendor_array *tuples;
+	struct snd_soc_tplg_mixer_control *tmc;
+	struct avs_control_data *ctl_data;
+	struct soc_mixer_control *mc;
+	size_t block_size;
+	int ret;
+
+	switch (hdr->type) {
+	case SND_SOC_TPLG_TYPE_MIXER:
+		tmc = container_of(hdr, typeof(*tmc), hdr);
+		tuples = tmc->priv.array;
+		block_size = le32_to_cpu(tmc->priv.size);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	ctl_data = devm_kzalloc(comp->card->dev, sizeof(*ctl_data), GFP_KERNEL);
+	if (!ctl_data)
+		return -ENOMEM;
+
+	ret = parse_dictionary_entries(comp, tuples, block_size, ctl_data, 1, sizeof(*ctl_data),
+				       AVS_TKN_KCONTROL_ID_U32, control_parsers,
+				       ARRAY_SIZE(control_parsers));
+	if (ret)
+		return ret;
+
+	mc = (struct soc_mixer_control *)ctmpl->private_value;
+	mc->dobj.private = ctl_data;
+	return 0;
+}
+
 static struct snd_soc_tplg_ops avs_tplg_ops = {
+	.io_ops			= avs_control_ops,
+	.io_ops_count		= ARRAY_SIZE(avs_control_ops),
+	.control_load		= avs_control_load,
 	.dapm_route_load	= avs_route_load,
 	.widget_load		= avs_widget_load,
+	.widget_ready		= avs_widget_ready,
 	.dai_load		= avs_dai_load,
 	.link_load		= avs_link_load,
 	.manifest		= avs_manifest,
diff --git a/sound/soc/intel/avs/topology.h b/sound/soc/intel/avs/topology.h
index 68e5f6312353..6e1c8e9b2496 100644
--- a/sound/soc/intel/avs/topology.h
+++ b/sound/soc/intel/avs/topology.h
@@ -138,6 +138,8 @@ struct avs_tplg_path_template_id {
 struct avs_tplg_path_template {
 	u32 id;
 
+	struct snd_soc_dapm_widget *w;
+
 	struct list_head path_list;
 
 	struct avs_tplg *owner;
@@ -180,6 +182,7 @@ struct avs_tplg_module {
 	u8 core_id;
 	u8 domain;
 	struct avs_tplg_modcfg_ext *cfg_ext;
+	u32 ctl_id;
 
 	struct avs_tplg_pipeline *owner;
 	/* Pipeline modules management. */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/4] ASoC: Intel: avs: Peakvol module configuration
  2022-12-14 18:54 [PATCH 0/4] Add support for DSP volume controls Amadeusz Sławiński
                   ` (2 preceding siblings ...)
  2022-12-14 18:54 ` [PATCH 3/4] ASoC: Intel: avs: Parse control tuples Amadeusz Sławiński
@ 2022-12-14 18:55 ` Amadeusz Sławiński
  2022-12-27 11:57 ` [PATCH 0/4] Add support for DSP volume controls Mark Brown
  4 siblings, 0 replies; 6+ messages in thread
From: Amadeusz Sławiński @ 2022-12-14 18:55 UTC (permalink / raw)
  To: Mark Brown
  Cc: Cezary Rojewski, alsa-devel, Takashi Iwai, Pierre-Louis Bossart,
	Amadeusz Sławiński

Handle creation of peakvol module in FW. When peakvol module is created
it retrieves actual value from kcontrol and sends it to FW as part of
configuration data.

Co-authored-by: Cezary Rojewski <cezary.rojewski@intel.com>
Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
---
 sound/soc/intel/avs/path.c | 62 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c
index ce157a8d6552..05302ab705ae 100644
--- a/sound/soc/intel/avs/path.c
+++ b/sound/soc/intel/avs/path.c
@@ -10,6 +10,7 @@
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include "avs.h"
+#include "control.h"
 #include "path.h"
 #include "topology.h"
 
@@ -264,6 +265,65 @@ static int avs_copier_create(struct avs_dev *adev, struct avs_path_module *mod)
 	return ret;
 }
 
+static struct avs_control_data *avs_get_module_control(struct avs_path_module *mod)
+{
+	struct avs_tplg_module *t = mod->template;
+	struct avs_tplg_path_template *path_tmpl;
+	struct snd_soc_dapm_widget *w;
+	int i;
+
+	path_tmpl = t->owner->owner->owner;
+	w = path_tmpl->w;
+
+	for (i = 0; i < w->num_kcontrols; i++) {
+		struct avs_control_data *ctl_data;
+		struct soc_mixer_control *mc;
+
+		mc = (struct soc_mixer_control *)w->kcontrols[i]->private_value;
+		ctl_data = (struct avs_control_data *)mc->dobj.private;
+		if (ctl_data->id == t->ctl_id)
+			return ctl_data;
+	}
+
+	return NULL;
+}
+
+static int avs_peakvol_create(struct avs_dev *adev, struct avs_path_module *mod)
+{
+	struct avs_tplg_module *t = mod->template;
+	struct avs_control_data *ctl_data;
+	struct avs_peakvol_cfg *cfg;
+	int volume = S32_MAX;
+	size_t size;
+	int ret;
+
+	ctl_data = avs_get_module_control(mod);
+	if (ctl_data)
+		volume = ctl_data->volume;
+
+	/* As 2+ channels controls are unsupported, have a single block for all channels. */
+	size = struct_size(cfg, vols, 1);
+	cfg = kzalloc(size, GFP_KERNEL);
+	if (!cfg)
+		return -ENOMEM;
+
+	cfg->base.cpc = t->cfg_base->cpc;
+	cfg->base.ibs = t->cfg_base->ibs;
+	cfg->base.obs = t->cfg_base->obs;
+	cfg->base.is_pages = t->cfg_base->is_pages;
+	cfg->base.audio_fmt = *t->in_fmt;
+	cfg->vols[0].target_volume = volume;
+	cfg->vols[0].channel_id = AVS_ALL_CHANNELS_MASK;
+	cfg->vols[0].curve_type = AVS_AUDIO_CURVE_NONE;
+	cfg->vols[0].curve_duration = 0;
+
+	ret = avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id, t->core_id,
+				  t->domain, cfg, size, &mod->instance_id);
+
+	kfree(cfg);
+	return ret;
+}
+
 static int avs_updown_mix_create(struct avs_dev *adev, struct avs_path_module *mod)
 {
 	struct avs_tplg_module *t = mod->template;
@@ -465,6 +525,8 @@ static struct avs_module_create avs_module_create[] = {
 	{ &AVS_MIXOUT_MOD_UUID, avs_modbase_create },
 	{ &AVS_KPBUFF_MOD_UUID, avs_modbase_create },
 	{ &AVS_COPIER_MOD_UUID, avs_copier_create },
+	{ &AVS_PEAKVOL_MOD_UUID, avs_peakvol_create },
+	{ &AVS_GAIN_MOD_UUID, avs_peakvol_create },
 	{ &AVS_MICSEL_MOD_UUID, avs_micsel_create },
 	{ &AVS_MUX_MOD_UUID, avs_mux_create },
 	{ &AVS_UPDWMIX_MOD_UUID, avs_updown_mix_create },
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/4] Add support for DSP volume controls
  2022-12-14 18:54 [PATCH 0/4] Add support for DSP volume controls Amadeusz Sławiński
                   ` (3 preceding siblings ...)
  2022-12-14 18:55 ` [PATCH 4/4] ASoC: Intel: avs: Peakvol module configuration Amadeusz Sławiński
@ 2022-12-27 11:57 ` Mark Brown
  4 siblings, 0 replies; 6+ messages in thread
From: Mark Brown @ 2022-12-27 11:57 UTC (permalink / raw)
  To: Amadeusz Sławiński
  Cc: Pierre-Louis Bossart, Cezary Rojewski, alsa-devel, Takashi Iwai

On Wed, 14 Dec 2022 19:54:56 +0100, Amadeusz Sławiński wrote:
> Some devices like DMIC don't expose native controls or need volume limit
> due to possible HW damage. Add support for volume controls allowing to
> change volume level in DSP. Maximum volume level is imposed by the
> topology file which defines given path.
> 
> Amadeusz Sławiński (4):
>   ASoC: Intel: avs: Add peakvol runtime-parameter requests
>   ASoC: Intel: avs: Add control volume operations
>   ASoC: Intel: avs: Parse control tuples
>   ASoC: Intel: avs: Peakvol module configuration
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/4] ASoC: Intel: avs: Add peakvol runtime-parameter requests
      commit: 905ea24f0f17d826e6b90ece706bfefde3d7b2e5
[2/4] ASoC: Intel: avs: Add control volume operations
      commit: 585b9427edd65ad124e23affb80fca3d15a6375d
[3/4] ASoC: Intel: avs: Parse control tuples
      commit: be2b81b519d7121290cfecc5fdfb4907ecc41c39
[4/4] ASoC: Intel: avs: Peakvol module configuration
      commit: 29d6523698f68011eda67619faa6358a46952e96

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-12-27 11:59 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-14 18:54 [PATCH 0/4] Add support for DSP volume controls Amadeusz Sławiński
2022-12-14 18:54 ` [PATCH 1/4] ASoC: Intel: avs: Add peakvol runtime-parameter requests Amadeusz Sławiński
2022-12-14 18:54 ` [PATCH 2/4] ASoC: Intel: avs: Add control volume operations Amadeusz Sławiński
2022-12-14 18:54 ` [PATCH 3/4] ASoC: Intel: avs: Parse control tuples Amadeusz Sławiński
2022-12-14 18:55 ` [PATCH 4/4] ASoC: Intel: avs: Peakvol module configuration Amadeusz Sławiński
2022-12-27 11:57 ` [PATCH 0/4] Add support for DSP volume controls Mark Brown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.