hal: support for for mi2s speaker adsp algo.

Change-Id: I77945be6eb8f853e29e394a51eb28fc8fb759b4a
diff --git a/hal/Android.mk b/hal/Android.mk
index 564deb3..73a298d 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -77,6 +77,11 @@
     LOCAL_SRC_FILES += audio_extn/spkr_protection.c
 endif
 
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_DSM_FEEDBACK)),true)
+    LOCAL_CFLAGS += -DDSM_FEEDBACK_ENABLED
+    LOCAL_SRC_FILES += audio_extn/dsm_feedback.c
+endif
+
 LOCAL_MODULE := audio.primary.$(TARGET_BOARD_PLATFORM)
 
 LOCAL_MODULE_RELATIVE_PATH := hw
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index ae91833..51abf46 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -87,4 +87,12 @@
                                   size_t bytes);
 #endif
 
+#ifndef DSM_FEEDBACK_ENABLED
+#define audio_extn_dsm_feedback_enable(adev, snd_device, benable)                (0)
+#else
+void audio_extn_dsm_feedback_enable(struct audio_device *adev,
+                         snd_device_t snd_device,
+                         bool benable);
+#endif
+
 #endif /* AUDIO_EXTN_H */
diff --git a/hal/audio_extn/dsm_feedback.c b/hal/audio_extn/dsm_feedback.c
new file mode 100755
index 0000000..e5c3c45
--- /dev/null
+++ b/hal/audio_extn/dsm_feedback.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * 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.
+ */
+
+#define LOG_TAG "audio_hw_dsm_feedback"
+/*#define LOG_NDEBUG 0*/
+#define LOG_NDDEBUG 0
+
+#include <errno.h>
+#include <math.h>
+#include <cutils/log.h>
+
+#include "audio_hw.h"
+#include "platform.h"
+#include "platform_api.h"
+#include <stdlib.h>
+
+
+static struct pcm_config pcm_config_dsm = {
+    .channels = 2,
+    .rate = 48000,
+    .period_size = 256,
+    .period_count = 4,
+    .format = PCM_FORMAT_S16_LE,
+    .start_threshold = 0,
+    .stop_threshold = INT_MAX,
+    .avail_min = 0,
+};
+
+int start_dsm_feedback_processing(struct audio_device *adev, int enable)
+{
+    int ret = 0;
+    int32_t pcm_dev_tx_id = -1;
+    static struct pcm *dsm_pcm_handle = NULL;
+
+    if (enable) {
+        /*do nothing if already enabled*/
+        if (dsm_pcm_handle)
+            return ret;
+
+        pcm_dev_tx_id = platform_get_pcm_device_id(USECASE_AUDIO_DSM_FEEDBACK, PCM_CAPTURE);
+        if (pcm_dev_tx_id < 0) {
+            ALOGE("%s: Invalid pcm device for usecase (%d)",
+                  __func__, USECASE_AUDIO_DSM_FEEDBACK);
+            ret = -ENODEV;

+            goto close;
+        }
+
+        dsm_pcm_handle = pcm_open(adev->snd_card,
+                                 pcm_dev_tx_id,
+                                 PCM_IN, &pcm_config_dsm);
+        if (dsm_pcm_handle && !pcm_is_ready(dsm_pcm_handle)) {
+            ALOGE("%s: %s", __func__, pcm_get_error(dsm_pcm_handle));
+            ret = -EIO;
+            goto close;
+        }
+
+        if (pcm_start(dsm_pcm_handle) < 0) {
+            ALOGE("%s: pcm start for RX failed", __func__);
+            ret = -EINVAL;
+            goto close;
+        }
+
+        return ret;
+    }
+
+close:
+    /*close pcm if disable or error happend in opening*/
+    if (dsm_pcm_handle) {
+        pcm_close(dsm_pcm_handle);
+        dsm_pcm_handle = NULL;
+    }
+
+    return ret;
+}
+
+void audio_extn_dsm_feedback_enable(struct audio_device *adev,
+                         snd_device_t snd_device,
+                         int benable)
+{
+    if ( NULL == adev )
+        return;
+
+    if( snd_device == SND_DEVICE_OUT_SPEAKER ||
+        snd_device == SND_DEVICE_OUT_SPEAKER_REVERSE ||
+        snd_device == SND_DEVICE_OUT_SPEAKER_SAFE ||
+        snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES ||
+        snd_device == SND_DEVICE_OUT_VOICE_SPEAKER ||
+        snd_device == SND_DEVICE_OUT_SPEAKER_AND_LINE )
+        start_dsm_feedback_processing(adev, benable);
+}
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index aa9a7ae..52d2a45 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -293,6 +293,8 @@
         return -EINVAL;
     }
 
+    audio_extn_dsm_feedback_enable(adev, snd_device, true);
+
     if ((snd_device == SND_DEVICE_OUT_SPEAKER ||
         snd_device == SND_DEVICE_OUT_VOICE_SPEAKER) &&
         audio_extn_spkr_prot_is_enabled()) {
@@ -329,6 +331,8 @@
     if (adev->snd_dev_ref_cnt[snd_device] == 0) {
         const char * dev_path = platform_get_snd_device_name(snd_device);
         ALOGD("%s: snd_device(%d: %s)", __func__, snd_device, dev_path);
+
+        audio_extn_dsm_feedback_enable(adev, snd_device, false);
         if ((snd_device == SND_DEVICE_OUT_SPEAKER ||
             snd_device == SND_DEVICE_OUT_VOICE_SPEAKER) &&
             audio_extn_spkr_prot_is_enabled()) {
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 92cd5de..b4b2583 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -83,6 +83,7 @@
 
     USECASE_AUDIO_PLAYBACK_AFE_PROXY,
     USECASE_AUDIO_RECORD_AFE_PROXY,
+    USECASE_AUDIO_DSM_FEEDBACK,
 
     AUDIO_USECASE_MAX
 };
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 00f3c2d..305e1c1 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -129,6 +129,7 @@
                                           AFE_PROXY_RECORD_PCM_DEVICE},
     [USECASE_AUDIO_RECORD_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
                                         AFE_PROXY_RECORD_PCM_DEVICE},
+    [USECASE_AUDIO_DSM_FEEDBACK] = {QUAT_MI2S_PCM_DEVICE, QUAT_MI2S_PCM_DEVICE},
 
 };
 
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index a5c4bd1..c242b16 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -185,6 +185,7 @@
 
 #define MULTIMEDIA3_PCM_DEVICE 4
 
+#define QUAT_MI2S_PCM_DEVICE    44
 #define PLAYBACK_OFFLOAD_DEVICE 9
 #define LOWLATENCY_PCM_DEVICE 15
 #define VOICE_VSID  0x10C01000