hal: Add support to dynamically configure MI2S rx sample rate

Add support to dynamically configure MI2S rx sample rate to
support sampling rates upto 192KHZ on head phones for internal
codec. Add and set explicit mixer control to notify the sample
rate value to machine driver.

CRs-Fixed: 970158
Change-Id: Ib7968eaf9aeb5f9911f3c985af61a16a7e06744d
diff --git a/hal/Android.mk b/hal/Android.mk
index 76b4157..ea54bd5 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -69,6 +69,10 @@
     LOCAL_CFLAGS += -DANC_HEADSET_ENABLED
 endif
 
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_HIFI_AUDIO)),true)
+    LOCAL_CFLAGS += -DHIFI_AUDIO_ENABLED
+endif
+
 ifeq ($(strip $(AUDIO_FEATURE_ENABLED_VBAT_MONITOR)),true)
     LOCAL_CFLAGS += -DVBAT_MONITOR_ENABLED
 endif
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index eebe0c4..b8b8b85 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -64,6 +64,7 @@
     uint32_t proxy_channel_num;
     bool hpx_enabled;
     bool vbat_enabled;
+    bool hifi_audio_enabled;
 };
 
 static struct audio_extn_module aextnmod = {
@@ -73,6 +74,7 @@
     .proxy_channel_num = 2,
     .hpx_enabled = 0,
     .vbat_enabled = 0,
+    .hifi_audio_enabled = 0,
 };
 
 #define AUDIO_PARAMETER_KEY_ANC        "anc_enabled"
@@ -335,6 +337,28 @@
 }
 #endif
 
+#ifdef HIFI_AUDIO_ENABLED
+bool audio_extn_is_hifi_audio_enabled(void)
+{
+    ALOGV("%s: status: %d", __func__, aextnmod.hifi_audio_enabled);
+    return (aextnmod.hifi_audio_enabled ? true: false);
+}
+
+bool audio_extn_is_hifi_audio_supported(void)
+{
+    /*
+     * for internal codec, check for hifiaudio property to enable hifi audio
+     */
+    if (property_get_bool("persist.audio.hifi.int_codec", false))
+    {
+        ALOGD("%s: hifi audio supported on internal codec", __func__);
+        aextnmod.hifi_audio_enabled = 1;
+    }
+
+    return (aextnmod.hifi_audio_enabled ? true: false);
+}
+#endif
+
 #ifdef VBAT_MONITOR_ENABLED
 bool audio_extn_is_vbat_enabled(void)
 {
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index c442aa7..10693ea 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2013 The Android Open Source Project
@@ -131,6 +131,14 @@
 bool audio_extn_can_use_vbat(void);
 #endif
 
+#ifndef HIFI_AUDIO_ENABLED
+#define audio_extn_is_hifi_audio_enabled()               (0)
+#define audio_extn_is_hifi_audio_supported()             (0)
+#else
+bool audio_extn_is_hifi_audio_enabled(void);
+bool audio_extn_is_hifi_audio_supported(void);
+#endif
+
 #ifndef FLUENCE_ENABLED
 #define audio_extn_set_fluence_parameters(adev, parms) (0)
 #define audio_extn_get_fluence_parameters(adev, query, reply) (0)
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 45fa223..6771bf9 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -625,10 +625,15 @@
          if ((24 == usecase->stream.out->bit_width) &&
              (usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER)) {
              usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
-         } else if (!audio_is_this_native_usecase(usecase) ||
-             (usecase->stream.out->sample_rate < OUTPUT_SAMPLING_RATE_44100)) {
-             usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+         } else if ((usecase->stream.out->app_type_cfg.sample_rate == OUTPUT_SAMPLING_RATE_44100 &&
+                      !(audio_is_this_native_usecase(usecase))) ||
+                      (usecase->stream.out->sample_rate < OUTPUT_SAMPLING_RATE_44100)) {
+                    usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
          }
+
+         if (!audio_extn_is_hifi_audio_enabled())
+             usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+
          sample_rate = usecase->stream.out->app_type_cfg.sample_rate;
 
          property_get("audio.playback.mch.downsample",value,"");
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 155f0c8..9cd7928 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -222,6 +222,7 @@
     bool ec_ref_enabled;
     bool is_wsa_speaker;
     bool is_acdb_initialized;
+    bool hifi_audio;
     /* Vbat monitor related flags */
     bool is_vbat_speaker;
     bool gsm_mode_enabled;
@@ -1773,6 +1774,14 @@
     if (ret)
         my_data->is_vbat_speaker = true;
 
+    /*
+     * Check if hifi audio( i.e. 96, 192 KHZ) is enabled for this platform,
+     * enable hifi audio by default for external codec targets
+     */
+    ret = audio_extn_is_hifi_audio_supported();
+    if (ret || is_external_codec)
+        my_data->hifi_audio = true;
+
     my_data->voice_feature_set = VOICE_FEATURE_SET_DEFAULT;
     my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
     if (my_data->acdb_handle == NULL) {
@@ -1891,16 +1900,22 @@
         my_data->current_backend_cfg[idx].bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
     }
 
-    my_data->current_backend_cfg[DEFAULT_CODEC_BACKEND].bitwidth_mixer_ctl =
-        strdup("SLIM_0_RX Format");
-    my_data->current_backend_cfg[DEFAULT_CODEC_BACKEND].samplerate_mixer_ctl =
-        strdup("SLIM_0_RX SampleRate");
+    if (is_external_codec) {
+        my_data->current_backend_cfg[DEFAULT_CODEC_BACKEND].bitwidth_mixer_ctl =
+            strdup("SLIM_0_RX Format");
+        my_data->current_backend_cfg[DEFAULT_CODEC_BACKEND].samplerate_mixer_ctl =
+            strdup("SLIM_0_RX SampleRate");
 
-    my_data->current_backend_cfg[HEADPHONE_44_1_BACKEND].bitwidth_mixer_ctl =
-        strdup("SLIM_5_RX Format");
-    my_data->current_backend_cfg[HEADPHONE_44_1_BACKEND].samplerate_mixer_ctl =
-        strdup("SLIM_5_RX SampleRate");
-
+        my_data->current_backend_cfg[HEADPHONE_44_1_BACKEND].bitwidth_mixer_ctl =
+            strdup("SLIM_5_RX Format");
+        my_data->current_backend_cfg[HEADPHONE_44_1_BACKEND].samplerate_mixer_ctl =
+            strdup("SLIM_5_RX SampleRate");
+    } else {
+        my_data->current_backend_cfg[DEFAULT_CODEC_BACKEND].bitwidth_mixer_ctl =
+            strdup("MI2S_RX Format");
+        my_data->current_backend_cfg[DEFAULT_CODEC_BACKEND].samplerate_mixer_ctl =
+            strdup("MI2S_RX SampleRate");
+    }
 
     ret = audio_extn_utils_get_codec_version(snd_card_name,
                                              my_data->adev->snd_card,
@@ -4071,44 +4086,6 @@
     return OFFLOAD_USE_SMALL_BUFFER;
 }
 
-int platform_is_external_codec (char *snd_card_name)
-{
-
-    if (!strncmp(snd_card_name, "msm8952-tomtom-snd-card",
-                  sizeof("msm8952-tomtom-snd-card")) ||
-        !strncmp(snd_card_name, "msm8952-tasha-snd-card",
-                  sizeof("msm8952-tasha-snd-card")) ||
-        !strncmp(snd_card_name, "msm8952-tashalite-snd-card",
-                  sizeof("msm8952-tashalite-snd-card")) ||
-        !strncmp(snd_card_name, "msm8952-tasha-skun-snd-card",
-                  sizeof("msm8952-tasha-skun-snd-card")) ||
-        !strncmp(snd_card_name, "msm8976-tasha-snd-card",
-                  sizeof("msm8976-tasha-snd-card")) ||
-        !strncmp(snd_card_name, "msm8976-tashalite-snd-card",
-                  sizeof("msm8976-tashalite-snd-card")) ||
-        !strncmp(snd_card_name, "msm8976-tasha-skun-snd-card",
-                  sizeof("msm8976-tasha-skun-snd-card")) ||
-        !strncmp(snd_card_name, "msm8937-tasha-snd-card",
-                  sizeof("msm8937-tasha-snd-card")) ||
-         !strncmp(snd_card_name, "msm8937-tashalite-snd-card",
-                  sizeof("msm8937-tashalite-snd-card"))  ||
-         !strncmp(snd_card_name, "msm8953-tasha-snd-card",
-                  sizeof("msm8953-tasha-snd-card")) ||
-         !strncmp(snd_card_name, "msm8953-tashalite-snd-card",
-                  sizeof("msm8953-tashalite-snd-card")))
-    {
-        /* external codec, for rest/old of the external codecs
-           we dont support this funtionality(chaning AFE params)
-           at the monment
-         */
-        return 1;
-    }
-    else {
-        /* internal codec */
-        return 0;
-    }
-}
-
 /*
  * configures afe with bit width and Sample Rate
  */
@@ -4120,7 +4097,6 @@
     int backend_idx = DEFAULT_CODEC_BACKEND;
     struct platform_data *my_data = (struct platform_data *)adev->platform;
     const char *snd_card_name = mixer_get_name(adev->mixer);
-    int is_external_codec = platform_is_external_codec(snd_card_name);
     int na_mode = platform_get_native_support();
 
 
@@ -4133,14 +4109,8 @@
         my_data->current_backend_cfg[backend_idx].bit_width) {
 
         struct  mixer_ctl *ctl;
-        if (!is_external_codec) {
-            ctl = mixer_get_ctl_by_name(adev->mixer,
-                        "MI2S_RX Format");
-
-        } else {
-            ctl = mixer_get_ctl_by_name(adev->mixer,
+        ctl = mixer_get_ctl_by_name(adev->mixer,
                         my_data->current_backend_cfg[backend_idx].bitwidth_mixer_ctl);
-        }
         if (!ctl) {
             ALOGE("%s:becf: afe: Could not get ctl for mixer command - %s",
                   __func__,
@@ -4169,9 +4139,10 @@
     // TODO: This has to be more dynamic based on policy file
 
     if ((sample_rate != my_data->current_backend_cfg[(int)backend_idx].sample_rate) &&
-            (is_external_codec)) {
-            /* sample rate update is needed only for external codecs which
-               support 24 bit playback*/
+            (my_data->hifi_audio)) {
+            /*
+             * sample rate update is needed only for hifi audio enabled platforms
+             */
             char *rate_str = NULL;
             struct  mixer_ctl *ctl;
 
@@ -4343,14 +4314,12 @@
     }
 
     /*
-     * Sample rate greater than 48K is only supported by external codecs on
-     * specific devices e.g. Headphones, reset the sample rate to
-     * default value if not external codec.
+     * reset the sample rate to default value(48K), if hifi audio is not supported
      */
-    if (!is_external_codec) {
-        ALOGD("%s:becf: afe: For internal codec only 48 is supported \
-              Configure afe to default Sample Rate(48k)", __func__);
-        sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+    if (!my_data->hifi_audio) {
+               ALOGD("%s:becf: afe: only 48KHZ sample rate is supported \
+                      Configure afe to default Sample Rate(48k)", __func__);
+               sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
     }
 
     //check if mulitchannel clip needs to be down sampled to 48k