audio: hal: Initialize AFE configs by querying the kernel

- AFE configuration is not reset to default after a 24 bit playback.
- To fix this initialize the configurations by querying  the
  kernel for mixer bitwidth, samplerate, and channel configurations
  everytime.

Change-Id: Id68a41e36f40ce0d6720d92ee0ce048a266e48fa
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 7f32f4d..3ea6646 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -629,6 +629,9 @@
 int audio_extn_utils_get_snd_card_num();
 bool audio_extn_is_dsp_bit_width_enforce_mode_supported(audio_output_flags_t flags);
 bool audio_extn_utils_is_dolby_format(audio_format_t format);
+int audio_extn_utils_get_bit_width_from_string(const char *);
+int audio_extn_utils_get_sample_rate_from_string(const char *);
+int audio_extn_utils_get_channels_from_string(const char *);
 
 #ifdef DS2_DOLBY_DAP_ENABLED
 #define LIB_DS2_DAP_HAL "vendor/lib/libhwdaphal.so"
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index c01e6f7..de233ea 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -106,6 +106,11 @@
 #define MAX_CHANNELS_SUPPORTED 8
 #endif
 
+typedef struct {
+    const char *id_string;
+    const int value;
+} mixer_config_lookup;
+
 struct string_to_enum {
     const char *name;
     uint32_t value;
@@ -2363,4 +2368,63 @@
         return false;
 }
 
+int audio_extn_utils_get_bit_width_from_string(const char *id_string)
+{
+    int i;
+    const mixer_config_lookup mixer_bitwidth_config[] = {{"S24_3LE", 24},
+                                                         {"S32_LE", 32},
+                                                         {"S24_LE", 24},
+                                                         {"S16_LE", 16}};
+    int num_configs = sizeof(mixer_bitwidth_config) / sizeof(mixer_bitwidth_config[0]);
 
+    for (i = 0; i < num_configs; i++) {
+        if (!strcmp(id_string, mixer_bitwidth_config[i].id_string))
+            return mixer_bitwidth_config[i].value;
+    }
+
+    return -EINVAL;
+}
+
+int audio_extn_utils_get_sample_rate_from_string(const char *id_string)
+{
+    int i;
+    const mixer_config_lookup mixer_samplerate_config[] = {{"KHZ_32", 32000},
+                                                           {"KHZ_48", 48000},
+                                                           {"KHZ_96", 96000},
+                                                           {"KHZ_144", 144000},
+                                                           {"KHZ_192", 192000},
+                                                           {"KHZ_384", 384000},
+                                                           {"KHZ_44P1", 44100},
+                                                           {"KHZ_88P2", 88200},
+                                                           {"KHZ_176P4", 176400},
+                                                           {"KHZ_352P8", 352800}};
+    int num_configs = sizeof(mixer_samplerate_config) / sizeof(mixer_samplerate_config[0]);
+
+    for (i = 0; i < num_configs; i++) {
+        if (!strcmp(id_string, mixer_samplerate_config[i].id_string))
+            return mixer_samplerate_config[i].value;
+    }
+
+    return -EINVAL;
+}
+
+int audio_extn_utils_get_channels_from_string(const char *id_string)
+{
+    int i;
+    const mixer_config_lookup mixer_channels_config[] = {{"One", 1},
+                                                         {"Two", 2},
+                                                         {"Three",3},
+                                                         {"Four", 4},
+                                                         {"Five", 5},
+                                                         {"Six", 6},
+                                                         {"Seven", 7},
+                                                         {"Eight", 8}};
+    int num_configs = sizeof(mixer_channels_config) / sizeof(mixer_channels_config[0]);
+
+    for (i = 0; i < num_configs; i++) {
+        if (!strcmp(id_string, mixer_channels_config[i].id_string))
+            return mixer_channels_config[i].value;
+    }
+
+    return -EINVAL;
+}
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 45b02e3..4987f8b 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -972,6 +972,8 @@
 #define ULL_PLATFORM_DELAY (6*1000LL)
 #define MMAP_PLATFORM_DELAY (3*1000LL)
 
+static const char *platform_get_mixer_control(struct mixer_ctl *);
+
 static void update_interface(const char *snd_card_name) {
      if (!strncmp(snd_card_name, "apq8009-tashalite-snd-card",
                   sizeof("apq8009-tashalite-snd-card"))) {
@@ -2149,6 +2151,8 @@
     int idx;
     int wsaCount =0;
     bool is_wsa_combo_supported = false;
+    const char *id_string = NULL;
+    int cfg_value = -1;
 
     snd_card_num = audio_extn_utils_get_snd_card_num();
     if(snd_card_num < 0) {
@@ -2599,6 +2603,41 @@
     my_data->current_backend_cfg[HDMI_TX_BACKEND].channels_mixer_ctl =
         strdup("QUAT_MI2S_TX Channels");
 
+    for (idx = 0; idx < MAX_CODEC_BACKENDS; idx++) {
+        if (my_data->current_backend_cfg[idx].bitwidth_mixer_ctl) {
+            ctl = mixer_get_ctl_by_name(adev->mixer,
+                         my_data->current_backend_cfg[idx].bitwidth_mixer_ctl);
+            id_string = platform_get_mixer_control(ctl);
+            if (id_string) {
+                cfg_value = audio_extn_utils_get_bit_width_from_string(id_string);
+                if (cfg_value > 0)
+                    my_data->current_backend_cfg[idx].bit_width = cfg_value;
+            }
+        }
+
+        if (my_data->current_backend_cfg[idx].samplerate_mixer_ctl) {
+            ctl = mixer_get_ctl_by_name(adev->mixer,
+                         my_data->current_backend_cfg[idx].samplerate_mixer_ctl);
+            id_string = platform_get_mixer_control(ctl);
+            if (id_string) {
+                cfg_value = audio_extn_utils_get_sample_rate_from_string(id_string);
+                if (cfg_value > 0)
+                    my_data->current_backend_cfg[idx].sample_rate = cfg_value;
+            }
+        }
+
+        if (my_data->current_backend_cfg[idx].channels_mixer_ctl) {
+            ctl = mixer_get_ctl_by_name(adev->mixer,
+                         my_data->current_backend_cfg[idx].channels_mixer_ctl);
+            id_string = platform_get_mixer_control(ctl);
+            if (id_string) {
+                cfg_value = audio_extn_utils_get_channels_from_string(id_string);
+                if (cfg_value > 0)
+                    my_data->current_backend_cfg[idx].channels = cfg_value;
+            }
+        }
+    }
+
     ret = audio_extn_utils_get_codec_version(snd_card_name,
                                              my_data->adev->snd_card,
                                              my_data->codec_version);
@@ -7847,3 +7886,20 @@
     return -1;
 }
 #endif
+
+static const char *platform_get_mixer_control(struct mixer_ctl *ctl)
+{
+    int id = -1;
+    const char *id_string = NULL;
+
+    if (!ctl) {
+        ALOGD("%s: mixer ctl not obtained", __func__);
+    } else {
+        id = mixer_ctl_get_value(ctl, 0);
+        if (id >= 0) {
+            id_string = mixer_ctl_get_enum_string(ctl, id);
+        }
+    }
+
+    return id_string;
+}
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 64dde86..371f3fc 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -1018,6 +1018,8 @@
     return ret;
 }
 
+static const char *platform_get_mixer_control(struct mixer_ctl *);
+
 bool platform_send_gain_dep_cal(void *platform, int level) {
     bool ret_val = false;
     struct platform_data *my_data = (struct platform_data *)platform;
@@ -1880,6 +1882,9 @@
     char *tmp = NULL;
     char mixer_xml_file[MIXER_PATH_MAX_LENGTH]= {0};
     int idx;
+    struct mixer_ctl *ctl = NULL;
+    const char *id_string = NULL;
+    int cfg_value = -1;
 
     adev->snd_card = audio_extn_utils_get_snd_card_num();
     if (adev->snd_card < 0) {
@@ -2342,6 +2347,41 @@
     my_data->current_backend_cfg[HDMI_TX_BACKEND].channels_mixer_ctl =
         strdup("QUAT_MI2S_TX Channels");
 
+    for (idx = 0; idx < MAX_CODEC_BACKENDS; idx++) {
+        if (my_data->current_backend_cfg[idx].bitwidth_mixer_ctl) {
+            ctl = mixer_get_ctl_by_name(adev->mixer,
+                         my_data->current_backend_cfg[idx].bitwidth_mixer_ctl);
+            id_string = platform_get_mixer_control(ctl);
+            if (id_string) {
+                cfg_value = audio_extn_utils_get_bit_width_from_string(id_string);
+                if (cfg_value > 0)
+                    my_data->current_backend_cfg[idx].bit_width = cfg_value;
+            }
+        }
+
+        if (my_data->current_backend_cfg[idx].samplerate_mixer_ctl) {
+            ctl = mixer_get_ctl_by_name(adev->mixer,
+                         my_data->current_backend_cfg[idx].samplerate_mixer_ctl);
+            id_string = platform_get_mixer_control(ctl);
+            if (id_string) {
+                cfg_value = audio_extn_utils_get_sample_rate_from_string(id_string);
+                if (cfg_value > 0)
+                    my_data->current_backend_cfg[idx].sample_rate = cfg_value;
+            }
+        }
+
+        if (my_data->current_backend_cfg[idx].channels_mixer_ctl) {
+            ctl = mixer_get_ctl_by_name(adev->mixer,
+                         my_data->current_backend_cfg[idx].channels_mixer_ctl);
+            id_string = platform_get_mixer_control(ctl);
+            if (id_string) {
+                cfg_value = audio_extn_utils_get_channels_from_string(id_string);
+                if (cfg_value > 0)
+                    my_data->current_backend_cfg[idx].channels = cfg_value;
+            }
+        }
+    }
+
     ret = audio_extn_utils_get_codec_version(snd_card_name,
                                              my_data->adev->snd_card,
                                              my_data->codec_version);
@@ -7585,3 +7625,20 @@
     return -1;
 }
 #endif
+
+static const char *platform_get_mixer_control(struct mixer_ctl *ctl)
+{
+    int id = -1;
+    const char *id_string = NULL;
+
+    if (!ctl) {
+        ALOGD("%s: mixer ctl not obtained", __func__);
+    } else {
+        id = mixer_ctl_get_value(ctl, 0);
+        if (id >= 0) {
+            id_string = mixer_ctl_get_enum_string(ctl, id);
+        }
+    }
+
+    return id_string;
+}