resolve merge conflicts of 8d89f40 to nyc-mr1-dev

Change-Id: I7d832f735432356a078a15cd678e2e11d48fd0b2
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 5b449bb..39384a2 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -636,6 +636,8 @@
     bool switch_device[AUDIO_USECASE_MAX];
     int i, num_uc_to_switch = 0;
 
+    platform_check_and_set_capture_backend_cfg(adev, uc_info, snd_device);
+
     /*
      * This function is to make sure that all the active capture usecases
      * are always routed to the same input sound device.
@@ -1456,7 +1458,7 @@
                                   audio_format_t format,
                                   int channel_count)
 {
-    if (format != AUDIO_FORMAT_PCM_16_BIT) {
+    if ((format != AUDIO_FORMAT_PCM_16_BIT) && (format != AUDIO_FORMAT_PCM_8_24_BIT)) {
         ALOGE("%s: unsupported AUDIO FORMAT (%d) ", __func__, format);
         return -EINVAL;
     }
@@ -1499,9 +1501,8 @@
     size = (sample_rate * AUDIO_CAPTURE_PERIOD_DURATION_MSEC) / 1000;
     if (is_low_latency)
         size = configured_low_latency_capture_period_size;
-    /* ToDo: should use frame_size computed based on the format and
-       channel_count here. */
-    size *= sizeof(short) * channel_count;
+
+    size *= channel_count * audio_bytes_per_sample(format);
 
     /* make sure the size is multiple of 32 bytes
      * At 48 kHz mono 16-bit PCM:
@@ -2121,9 +2122,10 @@
     return in->channel_mask;
 }
 
-static audio_format_t in_get_format(const struct audio_stream *stream __unused)
+static audio_format_t in_get_format(const struct audio_stream *stream)
 {
-    return AUDIO_FORMAT_PCM_16_BIT;
+    struct stream_in *in = (struct stream_in *)stream;
+    return in->format;
 }
 
 static int in_set_format(struct audio_stream *stream __unused, audio_format_t format __unused)
@@ -2237,6 +2239,7 @@
     struct stream_in *in = (struct stream_in *)stream;
     struct audio_device *adev = in->dev;
     int i, ret = -1;
+    int *int_buf_stream = NULL;
 
     lock_input_stream(in);
 
@@ -2267,13 +2270,26 @@
     if (in->pcm) {
         if (use_mmap) {
             ret = pcm_mmap_read(in->pcm, buffer, bytes);
-        } else
+        } else {
             ret = pcm_read(in->pcm, buffer, bytes);
-
+        }
         if (ret < 0) {
             ALOGE("Failed to read w/err %s", strerror(errno));
             ret = -errno;
         }
+        if (!ret && bytes > 0 && (in->format == AUDIO_FORMAT_PCM_8_24_BIT)) {
+            if (bytes % 4 == 0) {
+                /* data from DSP comes in 24_8 format, convert it to 8_24 */
+                int_buf_stream = buffer;
+                for (size_t itt=0; itt < bytes/4 ; itt++) {
+                    int_buf_stream[itt] >>= 8;
+                }
+            } else {
+                ALOGE("%s: !!! something wrong !!! ... data not 32 bit aligned ", __func__);
+                ret = -EINVAL;
+                goto exit;
+            }
+        }
     }
 
     release_in_focus(in, ns);
@@ -2879,8 +2895,19 @@
     in->channel_mask = config->channel_mask;
     in->capture_handle = handle;
     in->flags = flags;
+    in->format = config->format;
     // in->frames_read = 0;
 
+    if (in->format == AUDIO_FORMAT_DEFAULT)
+        config->format = AUDIO_FORMAT_PCM_16_BIT;
+
+    if (config->format == AUDIO_FORMAT_PCM_FLOAT ||
+        config->format == AUDIO_FORMAT_PCM_24_BIT_PACKED) {
+        config->format = AUDIO_FORMAT_PCM_8_24_BIT;
+        ret = -EINVAL;
+        goto err_open;
+    }
+
     /* Update config params with the requested sample rate and channels */
     if (in->device == AUDIO_DEVICE_IN_TELEPHONY_RX) {
         if (config->sample_rate == 0)
@@ -2891,8 +2918,7 @@
             ret = -EINVAL;
             goto err_open;
         }
-        if (config->format == AUDIO_FORMAT_DEFAULT)
-            config->format = AUDIO_FORMAT_PCM_16_BIT;
+
         if (config->format != AUDIO_FORMAT_PCM_16_BIT) {
             config->format = AUDIO_FORMAT_PCM_16_BIT;
             ret = -EINVAL;
@@ -2915,12 +2941,15 @@
         in->config = in->realtime ? pcm_config_audio_capture_rt :
                                   pcm_config_audio_capture;
 
+        if (config->format == AUDIO_FORMAT_PCM_8_24_BIT)
+            in->config.format = PCM_FORMAT_S24_LE;
+
         if (!in->realtime) {
             frame_size = audio_stream_in_frame_size(&in->stream);
             buffer_size = get_input_buffer_size(config->sample_rate,
                                                 config->format,
                                                 channel_count,
-                                            is_low_latency);
+                                                is_low_latency);
             in->config.period_size = buffer_size / frame_size;
         } // period size is left untouched for rt mode playback
     }
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 64ac794..b586c57 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -207,6 +207,7 @@
     int af_period_multiplier;
     bool routing_change;
     struct audio_device *dev;
+    audio_format_t format;
 };
 
 typedef enum {
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index b2d4e04..6a934c4 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -1096,3 +1096,9 @@
     return 0;
 }
 
+bool platform_check_and_set_capture_backend_cfg(struct audio_device* adev __unused,
+                                              struct audio_usecase *usecase __unused)
+{
+    return false;
+}
+
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 789824b..5acf86f 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -264,6 +264,9 @@
     [SND_DEVICE_IN_VOICE_REC_HEADSET_MIC] = "headset-mic",
 
     [SND_DEVICE_IN_UNPROCESSED_MIC] = "unprocessed-mic",
+    [SND_DEVICE_IN_UNPROCESSED_STEREO_MIC] = "voice-rec-dmic-ef",
+    [SND_DEVICE_IN_UNPROCESSED_THREE_MIC] = "three-mic",
+    [SND_DEVICE_IN_UNPROCESSED_QUAD_MIC] = "quad-mic",
     [SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC] = "headset-mic",
 
     [SND_DEVICE_IN_VOICE_RX] = "voice-rx",
@@ -357,6 +360,9 @@
 
     [SND_DEVICE_IN_UNPROCESSED_MIC] = ACDB_ID_VOICE_REC_MIC,
     [SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC] = ACDB_ID_HEADSET_MIC_AEC,
+    [SND_DEVICE_IN_UNPROCESSED_STEREO_MIC] = 35,
+    [SND_DEVICE_IN_UNPROCESSED_THREE_MIC] = 125,
+    [SND_DEVICE_IN_UNPROCESSED_QUAD_MIC] = 125,
 
     [SND_DEVICE_IN_VOICE_RX] = 44,
 
@@ -456,6 +462,9 @@
 
     {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_STEREO_MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_THREE_MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_QUAD_MIC)},
 
     {TO_NAME_INDEX(SND_DEVICE_IN_THREE_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_QUAD_MIC)},
@@ -2105,7 +2114,19 @@
         }
     } else if (source == AUDIO_SOURCE_UNPROCESSED) {
         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
-            snd_device = SND_DEVICE_IN_UNPROCESSED_MIC;
+            if (((channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK) ||
+                 (channel_mask == AUDIO_CHANNEL_IN_STEREO)) &&
+                       (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+                snd_device = SND_DEVICE_IN_UNPROCESSED_STEREO_MIC;
+            } else if (((int)channel_mask == AUDIO_CHANNEL_INDEX_MASK_3) &&
+                       (my_data->source_mic_type & SOURCE_THREE_MIC)) {
+                snd_device = SND_DEVICE_IN_UNPROCESSED_THREE_MIC;
+            } else if (((int)channel_mask == AUDIO_CHANNEL_INDEX_MASK_4) &&
+                       (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
+                snd_device = SND_DEVICE_IN_UNPROCESSED_QUAD_MIC;
+            } else {
+                snd_device = SND_DEVICE_IN_UNPROCESSED_MIC;
+            }
         } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
             snd_device = SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC;
         }
@@ -2532,6 +2553,26 @@
     }
 }
 
+bool platform_check_and_set_capture_backend_cfg(struct audio_device* adev,
+         struct audio_usecase *usecase, snd_device_t snd_device)
+{
+    enum pcm_format  in_pcm_format = PCM_FORMAT_S16_LE;
+
+    if (adev && adev->active_input)
+        in_pcm_format = adev->active_input->config.format;
+
+    // allow 24 bit recording only if voice call is not active
+    if (!voice_is_in_call(adev) &&
+        adev->mode != AUDIO_MODE_IN_COMMUNICATION &&
+        in_pcm_format == PCM_FORMAT_S24_LE) {
+        audio_route_apply_and_update_path(adev->audio_route, "set-capture-format-24le");
+    } else {
+        audio_route_apply_and_update_path(adev->audio_route, "set-capture-format-default");
+    }
+
+    return true;
+}
+
 int platform_set_snd_device_backend(snd_device_t device, const char *backend_tag,
                                     const char * hw_interface)
 {
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 7a27359..0f81915 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -135,6 +135,9 @@
 
     SND_DEVICE_IN_UNPROCESSED_MIC,
     SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC,
+    SND_DEVICE_IN_UNPROCESSED_STEREO_MIC,
+    SND_DEVICE_IN_UNPROCESSED_THREE_MIC,
+    SND_DEVICE_IN_UNPROCESSED_QUAD_MIC,
 
     SND_DEVICE_IN_VOICE_RX,
 
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 9bd55b1..5e54e03 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -86,4 +86,7 @@
 
 int platform_set_parameters(void *platform, struct str_parms *parms);
 
+bool platform_check_and_set_capture_backend_cfg(struct audio_device* adev,
+                   struct audio_usecase *usecase, snd_device_t snd_device);
+
 #endif // AUDIO_PLATFORM_API_H