audio-hal: soft step volume params controls

set/get soft step volume control params values dynamically
for each usecase. each usecase can set different params values.
these values are set to module through mixer command.

Change-Id: I8ae200046ca5ab1ce253fc43e241d794fbb52183
Signed-off-by: Krishna Kishor Jha <quic_kkishorj@quicinc.com>
diff --git a/configs/msmnile_au/audio_platform_info.xml b/configs/msmnile_au/audio_platform_info.xml
old mode 100644
new mode 100755
index 7972f29..c9a5b34
--- a/configs/msmnile_au/audio_platform_info.xml
+++ b/configs/msmnile_au/audio_platform_info.xml
@@ -142,6 +142,12 @@
         <usecase name="USECASE_AUDIO_RECORD_COMPRESS2" type="in" id="31" />
     </pcm_ids>
 
+    <soft_volume_params>
+        <vol_params name="USECASE_AUDIO_PLAYBACK_MEDIA" period="70" step="10000" curve="0"/>
+        <vol_params name="USECASE_AUDIO_PLAYBACK_SYS_NOTIFICATION" period="25" step="1000" curve="0"/>
+        <vol_params name="USECASE_AUDIO_PLAYBACK_REAR_SEAT" period="40" step="1000" curve="0"/>
+    </soft_volume_params>
+
     <config_params>
         <param key="spkr_1_tz_name" value="wsatz.13"/>
         <param key="spkr_2_tz_name" value="wsatz.14"/>
diff --git a/configs/msmnile_au/msmnile_au.mk b/configs/msmnile_au/msmnile_au.mk
old mode 100644
new mode 100755
index 609195c..d1a4fd7
--- a/configs/msmnile_au/msmnile_au.mk
+++ b/configs/msmnile_au/msmnile_au.mk
@@ -49,6 +49,7 @@
 AUDIO_FEATURE_ENABLED_AHAL_EXT := false
 DOLBY_ENABLE := false
 AUDIO_FEATURE_ENABLED_EXTENDED_COMPRESS_FORMAT := true
+AUDIO_FEATURE_ENABLED_SOFT_VOLUME:= true
 endif
 
 USE_XML_AUDIO_POLICY_CONF := 1
@@ -89,6 +90,7 @@
 AUDIO_FEATURE_ENABLED_USB_BURST_MODE := false
 AUDIO_FEATURE_ENABLED_SVA_MULTI_STAGE := true
 AUDIO_FEATURE_ENABLED_BATTERY_LISTENER := false
+AUDIO_FEATURE_ENABLED_SOFT_VOLUME:= true
 ##AUDIO_FEATURE_FLAGS
 
 AUDIO_HARDWARE += audio.a2dp.default
diff --git a/hal/Android.mk b/hal/Android.mk
old mode 100644
new mode 100755
index 3ba981d..8615268
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -258,6 +258,11 @@
     LOCAL_CFLAGS += -DCONCURRENT_CAPTURE_ENABLED
 endif
 
+# soft step volume params control
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_SOFT_VOLUME)),true)
+    LOCAL_CFLAGS += -DSOFT_VOLUME
+endif
+
 # Hardware specific feature
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_QAP)),true)
 LOCAL_CFLAGS += -DQAP_EXTN_ENABLED -Wno-tautological-pointer-compare
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
old mode 100644
new mode 100755
index 9664b7e..d22c26f
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -535,7 +535,9 @@
 static int out_set_mmap_volume(struct audio_stream_out *stream, float left, float right);
 static int out_set_voip_volume(struct audio_stream_out *stream, float left, float right);
 static int out_set_pcm_volume(struct audio_stream_out *stream, float left, float right);
-
+#ifdef SOFT_VOLUME
+static int out_set_soft_volume_params(struct audio_stream_out *stream);
+#endif
 static void adev_snd_mon_cb(void *cookie, struct str_parms *parms);
 static void in_snd_mon_cb(void * stream, struct str_parms * parms);
 static void out_snd_mon_cb(void * stream, struct str_parms * parms);
@@ -4229,6 +4231,9 @@
                  out->apply_volume = false;
         } else if (audio_extn_auto_hal_is_bus_device_usecase(out->usecase)) {
             out_set_pcm_volume(&out->stream, out->volume_l, out->volume_r);
+#ifdef SOFT_VOLUME
+            out_set_soft_volume_params(&out->stream);
+#endif
         }
     } else {
         /*
@@ -5592,6 +5597,45 @@
     return db;
 }
 
+#ifdef SOFT_VOLUME
+static int out_set_soft_volume_params(struct audio_stream_out *stream)
+{
+    struct stream_out *out = (struct stream_out *)stream;
+    int ret = 0;
+    char mixer_ctl_name[128];
+    struct audio_device *adev = out->dev;
+    struct mixer_ctl *ctl = NULL;
+    struct soft_step_volume_params *volume_params = NULL;
+
+    int pcm_device_id = platform_get_pcm_device_id(out->usecase, PCM_PLAYBACK);
+    snprintf(mixer_ctl_name, sizeof(mixer_ctl_name), "Playback  %d Soft Vol Params", pcm_device_id);
+    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+    if (!ctl) {
+        ALOGE("%s : Could not get ctl for mixer cmd - %s", __func__, mixer_ctl_name);
+        return -EINVAL;
+    }
+
+    volume_params =(struct soft_step_volume_params * ) malloc(sizeof(struct soft_step_volume_params));
+    if (volume_params == NULL){
+        ALOGE("%s : malloc is failed for volume params", __func__);
+        return -EINVAL;
+    } else {
+        ret = platform_get_soft_step_volume_params(volume_params,out->usecase);
+        if (ret < 0) {
+            ALOGE("%s : platform_get_soft_step_volume_params is fialed", __func__);
+            return -EINVAL;
+        }
+
+    }
+    ret = mixer_ctl_set_array(ctl, volume_params, sizeof(struct soft_step_volume_params)/sizeof(int));
+    if (ret < 0) {
+        ALOGE("%s: Could not set ctl, error:%d ", __func__, ret);
+        return -EINVAL;
+    }
+    return 0;
+}
+#endif
+
 static int out_set_mmap_volume(struct audio_stream_out *stream, float left,
                           float right)
 {
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index c424ec1..a8b5fb0 100755
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -33,6 +33,40 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
+
+ *  Changes from Qualcomm Innovation Center are provided under the following license:
+
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+
+ *   * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef QCOM_AUDIO_HW_H
@@ -801,6 +835,15 @@
     struct audio_patch patch;
 };
 
+#ifdef SOFT_VOLUME
+/* this struct is used for set/get values from AHAL*/
+struct soft_step_volume_params {
+    int period;
+    int step;
+    int curve;
+};
+#endif
+
 int select_devices(struct audio_device *adev,
                           audio_usecase_t uc_id);
 int disable_audio_route(struct audio_device *adev,
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index f5c956b..79028fc 100755
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -402,6 +402,17 @@
     char chmap[AUDIO_CHANNEL_COUNT_MAX];
 };
 
+#ifdef SOFT_VOLUME
+static int usecase_volume_params[AUDIO_USECASE_MAX][3] = {
+    [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {-1,-1,-1},
+    [USECASE_AUDIO_PLAYBACK_MEDIA] = {-1,-1,-1},
+    [USECASE_AUDIO_PLAYBACK_SYS_NOTIFICATION] = {-1,-1,-1},
+    [USECASE_AUDIO_PLAYBACK_NAV_GUIDANCE] = {-1,-1,-1},
+    [USECASE_AUDIO_PLAYBACK_FRONT_PASSENGER] = {-1,-1,-1},
+    [USECASE_AUDIO_PLAYBACK_REAR_SEAT] = {-1,-1,-1},
+};
+#endif
+
 static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
     [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {DEEP_BUFFER_PCM_DEVICE,
                                             DEEP_BUFFER_PCM_DEVICE},
@@ -12557,6 +12568,48 @@
     return true;
 }
 
+#ifdef SOFT_VOLUME
+int platform_get_soft_step_volume_params(struct soft_step_volume_params *volume_params, int uc_id)
+{
+    int ret = 0;
+
+    if (volume_params == NULL) {
+        ALOGE("%s: Invalid volume_params", __func__);
+        ret = -EINVAL;
+        goto done;
+    }
+
+    if ((usecase_volume_params[uc_id][0] < 0) || (usecase_volume_params[uc_id][1] < 0) || (usecase_volume_params[uc_id][2] < 0) ) {
+        ALOGE("%s: soft step volume params values are not set dynamically,will use default static values set through cal data",__func__);
+        ret = -EINVAL;
+    } else {
+        memcpy(volume_params,usecase_volume_params[uc_id],sizeof(struct soft_step_volume_params));
+        ALOGV("%s: usecase-id = %d, ramp period = %d, ramp step = %d, ramp curve = %d",
+           __func__, uc_id, volume_params->period, volume_params->step, volume_params->curve);
+    }
+done:
+    return ret;
+}
+
+int platform_set_soft_step_volume_params(int uc_id, int period, int step, int curve)
+{
+    int ret = 0;
+
+    ALOGV("%s: usecase-id = %d, ramp period = %d, ramp step = %d, ramp curve = %d",
+           __func__, uc_id, period, step, curve);
+    if ((uc_id < 0) || (uc_id >= AUDIO_USECASE_MAX)) {
+        ALOGE("%s : invalid usecase id", __func__);
+	    ret = -EINVAL;
+    }
+
+    usecase_volume_params[uc_id][0] = period;
+    usecase_volume_params[uc_id][1] = step;
+    usecase_volume_params[uc_id][2] = curve;
+
+    return ret;
+}
+#endif
+
 int platform_get_active_microphones(void *platform, unsigned int channels,
                                     audio_usecase_t uc_id,
                                     struct audio_microphone_characteristic_t *mic_array,
diff --git a/hal/platform_api.h b/hal/platform_api.h
old mode 100644
new mode 100755
index bea9675..805db2f
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -15,6 +15,41 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
+
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+
+ *   * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
  */
 
 #ifndef AUDIO_PLATFORM_API_H
@@ -440,4 +475,8 @@
 void platform_reset_island_power_status(void *platform, snd_device_t snd_device);
 void platform_is_volume_boost_supported_device(void *platform, struct listnode *devices);
 const char *platform_get_mixer_FM_RX_control(struct audio_device *adev);
+#ifdef SOFT_VOLUME
+int platform_set_soft_step_volume_params(int uc_id, int period, int step, int curve);
+int platform_get_soft_step_volume_params(struct soft_step_volume_params *volume_params, int uc_id);
+#endif
 #endif // AUDIO_PLATFORM_API_H
diff --git a/hal/platform_info.c b/hal/platform_info.c
index e55b91d..da11cae 100755
--- a/hal/platform_info.c
+++ b/hal/platform_info.c
@@ -25,6 +25,40 @@
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted (subject to the limitations in the
+ * disclaimer below) provided that the following conditions are met:
+
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+
+ *   * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
+ * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #define LOG_TAG "platform_info"
@@ -84,6 +118,9 @@
     CUSTOM_MTMX_PARAM_IN_CH_INFO,
     MMSECNS,
     AUDIO_SOURCE_DELAY,
+#ifdef SOFT_VOLUME
+    SOFT_VOLUME_PARAMS,
+#endif
 } section_t;
 
 typedef void (* section_process_fn)(const XML_Char **attr);
@@ -121,6 +158,9 @@
 static void process_custom_mtmx_param_in_ch_info(const XML_Char **attr);
 static void process_fluence_mmsecns(const XML_Char **attr);
 static void process_audio_source_delay(const XML_Char **attr);
+#ifdef SOFT_VOLUME
+static void process_soft_volume_params(const XML_Char **attr);
+#endif
 
 static section_process_fn section_table[] = {
     [ROOT] = process_root,
@@ -146,6 +186,9 @@
     [CUSTOM_MTMX_PARAM_IN_CH_INFO] = process_custom_mtmx_param_in_ch_info,
     [MMSECNS] = process_fluence_mmsecns,
     [AUDIO_SOURCE_DELAY] = process_audio_source_delay,
+#ifdef SOFT_VOLUME
+    [SOFT_VOLUME_PARAMS] = process_soft_volume_params,
+#endif
 };
 
 static section_t section;
@@ -255,54 +298,59 @@
 static struct audio_custom_mtmx_params_info mtmx_params_info;
 static struct audio_custom_mtmx_in_params_info mtmx_in_params_info;
 
-/*
- * <audio_platform_info>
- * <acdb_ids>
- * <device name="???" acdb_id="???"/>
- * ...
- * ...
- * </acdb_ids>
- * <module_ids>
- * <device name="???" module_id="???"/>
- * ...
- * ...
- * </module_ids>
- * <backend_names>
- * <device name="???" backend="???"/>
- * ...
- * ...
- * </backend_names>
- * <pcm_ids>
- * <usecase name="???" type="in/out" id="???"/>
- * ...
- * ...
- * </pcm_ids>
- * <interface_names>
- * <device name="Use audio device name here, not sound device name" interface="PRIMARY_I2S" codec_type="external/internal"/>
- * ...
- * ...
- * </interface_names>
- * <config_params>
- *      <param key="snd_card_name" value="msm8994-tomtom-mtp-snd-card"/>
- *      <param key="operator_info" value="tmus;aa;bb;cc"/>
- *      <param key="operator_info" value="sprint;xx;yy;zz"/>
- *      ...
- *      ...
- * </config_params>
- *
- * <operator_specific>
- *      <device name="???" operator="???" mixer_path="???" acdb_id="???"/>
- *      ...
- *      ...
- * </operator_specific>
- *
- * </audio_platform_info>
- */
-
 static void process_root(const XML_Char **attr __unused)
 {
 }
 
+#ifdef SOFT_VOLUME
+/**mapping usecase and soft volume params **/
+static void process_soft_volume_params(const XML_Char **attr)
+{
+    int index;
+
+    if (strcmp(attr[0], "name") != 0) {
+        ALOGE("%s: 'name' not found, no pcm_id set!", __func__);
+        goto done;
+    }
+
+    index = platform_get_usecase_index((char *)attr[1]);
+    if (index < 0) {
+        ALOGE("%s: usecase %s not found!",
+                                __func__, attr[1]);
+        goto done;
+    }
+
+    if (strcmp(attr[2], "period") != 0) {
+        ALOGE("%s: ramp period not mentioned", __func__);
+        goto done;
+    }
+
+    int period = atoi((char *)attr[3]);
+
+    if (strcmp(attr[4], "step") != 0) {
+        ALOGE("%s: ramp period not mentioned", __func__);
+        goto done;
+    }
+    int step = atoi((char *)attr[5]);
+
+    if (strcmp(attr[6], "curve") != 0) {
+        ALOGE("%s: usecase id not mentioned", __func__);
+        goto done;
+    }
+
+    int curve = atoi((char *)attr[7]);
+
+    if (platform_set_soft_step_volume_params(index, period, step, curve) < 0) {
+        ALOGE("%s: usecase %s period %d  step %d  curve %d ",
+                            __func__, attr[1], period, step, curve);
+    goto done;
+    }
+
+done:
+    return;
+}
+#endif
+
 /* mapping from usecase to pcm dev id */
 static void process_pcm_id(const XML_Char **attr)
 {
@@ -1348,7 +1396,11 @@
             section = MICROPHONE_CHARACTERISTIC;
         } else if (strcmp(tag_name, "snd_devices") == 0) {
             section = SND_DEVICES;
-        } else if (strcmp(tag_name, "device") == 0) {
+#ifdef SOFT_VOLUME
+        } else if (strcmp(tag_name, "soft_vol_params") == 0) {
+            section = SOFT_VOLUME_PARAMS;
+#endif
+		} else if (strcmp(tag_name, "device") == 0) {
             if ((section != ACDB) && (section != AEC) && (section != NS) && (section != MMSECNS) &&
                 (section != BACKEND_NAME) && (section != BITWIDTH) &&
                 (section != INTERFACE_NAME) && (section != OPERATOR_SPECIFIC)) {
@@ -1494,6 +1546,12 @@
         } else if (strcmp(tag_name, "audio_source_delay") == 0) {
             section_process_fn fn = section_table[section];
             fn(attr);
+#ifdef SOFT_VOLUME
+        } else if (strcmp(tag_name, "vol_params") == 0) {
+            section = SOFT_VOLUME_PARAMS;
+            section_process_fn fn = section_table[section];
+            fn(attr);
+#endif
         }
     } else {
         if(strcmp(tag_name, "config_params") == 0) {
@@ -1527,6 +1585,10 @@
         section = MODULE;
     } else if (strcmp(tag_name, "pcm_ids") == 0) {
         section = ROOT;
+#ifdef SOFT_VOLUME
+    } else if (strcmp(tag_name, "soft_volume_params") == 0) {
+        section = ROOT;
+#endif
     } else if (strcmp(tag_name, "backend_names") == 0) {
         section = ROOT;
     } else if (strcmp(tag_name, "config_params") == 0) {