qahw: Add support for new stream APIs

Add support for new APIs to support voice call and
voice call features.

CRs-fixed: 2381271
Change-Id: Id3ba4417f1365018e5a26d243caea83571857f63
diff --git a/configure.ac b/configure.ac
index 572e07d..89326c0 100755
--- a/configure.ac
+++ b/configure.ac
@@ -141,6 +141,7 @@
 AM_CONDITIONAL([RUN_KEEP_ALIVE_IN_ARM_FFV], [test x$AUDIO_FEATURE_ENABLED_KEEP_ALIVE_ARM_FFV = xtrue])
 AM_CONDITIONAL([INSTANCE_ID], [test x$AUDIO_FEATURE_ENABLED_INSTANCE_ID = xtrue])
 AM_CONDITIONAL([LL_AS_PRIMARY_OUTPUT], [test x$AUDIO_USE_LL_AS_PRIMARY_OUTPUT = xtrue])
+AM_CONDITIONAL([QAHW_V1], [test x$AUDIO_FEATURE_ENABLED_QAHW_1_0 = xtrue])
 
 AC_CONFIG_FILES([ \
         Makefile \
diff --git a/qahw/Makefile.am b/qahw/Makefile.am
index b78c9b7..fccf003 100644
--- a/qahw/Makefile.am
+++ b/qahw/Makefile.am
@@ -17,6 +17,10 @@
 AM_CFLAGS += -DSVA_AUDIO_CONC
 endif
 
+if QAHW_V1
+AM_CFLAGS += -DQAHW_V1
+endif
+
 libqahwwrapper_la_CFLAGS  = $(AM_CFLAGS)
 libqahwwrapper_la_CFLAGS += -include stddef.h
 libqahwwrapper_la_CFLAGS += -Dstrlcpy=g_strlcpy $(GLIB_CFLAGS) -include glib.h
diff --git a/qahw/configure.ac b/qahw/configure.ac
index 5bd3a22..94ca645 100644
--- a/qahw/configure.ac
+++ b/qahw/configure.ac
@@ -30,6 +30,7 @@
 PKG_PROG_PKG_CONFIG
 
 AM_CONDITIONAL([SVA_AUDIO_CONCURRENCY],[test x$BOARD_SUPPORTS_SVA_AUDIO_CONCURRENCY = xtrue])
+AM_CONDITIONAL([QAHW_V1], [test x$AUDIO_FEATURE_ENABLED_QAHW_1_0 = xtrue])
 AC_ARG_WITH([glib],
       AC_HELP_STRING([--with-glib],
          [enable glib, Build against glib. Use this when building for HLOS systems which use glib]))
diff --git a/qahw/inc/qahw.h b/qahw/inc/qahw.h
index 5020c8f..dd920e2 100644
--- a/qahw/inc/qahw.h
+++ b/qahw/inc/qahw.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2011 The Android Open Source Project *
@@ -45,6 +45,9 @@
 /* First generation of audio devices had version hardcoded to 0. all devices with
  * versions < 1.0 will be considered of first generation API.
  */
+#if QAHW_V1
+#define QAHW_MODULE_API_VERSION_1_0 QAHW_MAKE_API_VERSION(1, 0)
+#endif
 #define QAHW_MODULE_API_VERSION_0_0 QAHW_MAKE_API_VERSION(0, 0)
 
 /* Minimal QTI audio HAL version supported by the audio framework */
diff --git a/qahw/inc/qahw_defs.h b/qahw/inc/qahw_defs.h
index 7d136d2..b0eb332 100644
--- a/qahw/inc/qahw_defs.h
+++ b/qahw/inc/qahw_defs.h
@@ -18,6 +18,7 @@
 
 #include <sys/cdefs.h>
 #include <stdint.h>
+#include <system/audio.h>
 
 #ifndef QTI_AUDIO_HAL_DEFS_H
 #define QTI_AUDIO_HAL_DEFS_H
@@ -171,6 +172,9 @@
 #define QAHW_INPUT_FLAG_TIMESTAMP 0x80000000
 #define QAHW_INPUT_FLAG_COMPRESS  0x40000000
 #define QAHW_INPUT_FLAG_PASSTHROUGH 0x20000000
+#define QAHW_OUTPUT_FLAG_INCALL_MUSIC 0x80000000
+#define QAHW_AUDIO_FLAG_HPCM_TX 0x00020000
+#define QAHW_AUDIO_FLAG_HPCM_RX 0x00040000
 
 /* Query fm volume */
 #define QAHW_PARAMETER_KEY_FM_VOLUME "fm_volume"
@@ -267,6 +271,14 @@
     uint32_t reserved[64]; /*reserved for future */
 } qahw_in_buffer_t;
 
+typedef struct {
+    void *buffer;    /* write buffer pointer */
+    size_t size;          /* size of buffer */
+    size_t offset;         /* offset in buffer from where valid byte starts */
+    int64_t *timestamp;    /* timestmap */
+    qahw_meta_data_flags_t flags; /* meta data flags */
+} qahw_buffer_t;
+
 #define MAX_SECTORS 8
 
 struct qahw_source_tracking_param {
@@ -391,6 +403,42 @@
     char license[QAHW_LICENCE_STR_MAX_LENGTH + 1];
 } qahw_license_params_t;
 
+typedef struct qahw_dtmf_gen_params {
+   bool enable;
+   uint16_t low_freq;
+   uint16_t high_freq;
+   uint16_t gain;
+} qahw_dtmf_gen_params_t;
+
+enum {
+    QAHW_TTY_MODE_OFF,
+    QAHW_TTY_MODE_FULL,
+    QAHW_TTY_MODE_VCO,
+    QAHW_TTY_MODE_HCO,
+    QAHW_TTY_MODE_MAX,
+};
+
+typedef struct qahw_tty_params {
+   uint32_t mode;
+} qahw_tty_params_t;
+
+typedef enum {
+    QAHW_HPCM_TAP_POINT_RX = 1,
+    QAHW_HPCM_TAP_POINT_TX = 2,
+    QAHW_HPCM_TAP_POINT_RX_TX = 3,
+} qahw_hpcm_tap_point;
+
+typedef enum {
+    QAHW_HPCM_DIRECTION_OUT,
+    QAHW_HPCM_DIRECTION_IN,
+    QAHW_HPCM_DIRECTION_OUT_IN,
+} qahw_hpcm_direction;
+
+typedef struct qahw_hpcm_params {
+   qahw_hpcm_tap_point tap_point;
+   qahw_hpcm_direction direction;
+} qahw_hpcm_params_t;
+
 typedef union {
     struct qahw_source_tracking_param st_params;
     struct qahw_sound_focus_param sf_params;
@@ -406,6 +454,9 @@
     struct qahw_mix_matrix_params mix_matrix_params;
     struct qahw_license_params license_params;
     struct qahw_out_presentation_position_param pos_param;
+    struct qahw_dtmf_gen_params dtmf_gen_params;
+    struct qahw_tty_params tty_mode_params;
+    struct qahw_hpcm_params hpcm_params;
 } qahw_param_payload;
 
 typedef enum {
@@ -426,6 +477,9 @@
     QAHW_PARAM_CH_MIX_MATRIX_PARAMS,
     QAHW_PARAM_LICENSE_PARAMS,
     QAHW_PARAM_OUT_PRESENTATION_POSITION,
+    QAHW_PARAM_DTMF_GEN,
+    QAHW_PARAM_TTY_MODE,
+    QAHW_PARAM_HPCM,
 } qahw_param_id;
 
 typedef union {
@@ -436,6 +490,94 @@
     QAHW_PARAM_LOOPBACK_RENDER_WINDOW /* PARAM to set render window */
 } qahw_loopback_param_id;
 
+/** stream direction enumeration */
+typedef enum {
+    QAHW_STREAM_INPUT,
+    QAHW_STREAM_OUTPUT,
+    QAHW_STREAM_INPUT_OUTPUT,
+} qahw_stream_direction;
+
+/** stream types */
+typedef enum {
+    QAHW_STREAM_TYPE_INVALID,
+    QAHW_AUDIO_PLAYBACK_LOW_LATENCY,      /**< low latency, higher power*/
+    QAHW_AUDIO_PLAYBACK_DEEP_BUFFER,          /**< low power, higher latency*/
+    QAHW_AUDIO_PLAYBACK_COMPRESSED,           /**< compresssed audio*/
+    QAHW_AUDIO_PLAYBACK_VOIP,                 /**< pcm voip audio*/
+    QAHW_AUDIO_PLAYBACK_VOICE_CALL_MUSIC,     /**< pcm voip audio*/
+
+    QAHW_AUDIO_CAPTURE_LOW_LATENCY,           /**< low latency, higher power*/
+    QAHW_AUDIO_CAPTURE_DEEP_BUFFER,           /**< low power, higher latency*/
+    QAHW_AUDIO_CAPTURE_COMPRESSED,            /**< compresssed audio*/
+    QAHW_AUDIO_CAPTURE_RAW,                   /**< pcm no post processing*/
+    QAHW_AUDIO_CAPTURE_VOIP,                  /**< pcm voip audio*/
+    QAHW_AUDIO_CAPTURE_VOICE_ACTIVATION,      /**< voice activation*/
+    QAHW_AUDIO_CAPTURE_VOICE_CALL_RX,         /**< incall record, downlink */
+    QAHW_AUDIO_CAPTURE_VOICE_CALL_TX,         /**< incall record, uplink */
+    QAHW_AUDIO_CAPTURE_VOICE_CALL_RX_TX,      /**< incall record, uplink & Downlink */
+
+    QAHW_VOICE_CALL,                          /**< voice call */
+
+    QAHW_AUDIO_TRANSCODE,                     /**< audio transcode */
+    QAHW_AUDIO_HOST_PCM_TX,
+    QAHW_AUDIO_HOST_PCM_RX,
+    QAHW_AUDIO_HOST_PCM_TX_RX,
+    QAHW_AUDIO_STREAM_TYPE_MAX,
+} qahw_audio_stream_type;
+
+typedef uint32_t qahw_device_t;
+
+/**< Key value pair to identify the topology of a usecase from default  */
+struct qahw_modifier_kv  {
+    uint32_t key;
+    uint32_t value;
+};
+
+struct qahw_shared_attributes{
+     audio_config_t config;
+};
+struct qahw_voice_attributes{
+     audio_config_t config;
+     const char *vsid;
+};
+
+struct qahw_audio_attributes{
+    audio_config_t config;
+};
+
+typedef union {
+    struct qahw_shared_attributes shared;
+    struct qahw_voice_attributes voice;
+    struct qahw_audio_attributes audio;
+} qahw_stream_attributes_config;
+
+struct qahw_stream_attributes {
+     qahw_audio_stream_type type;
+     qahw_stream_direction direction;
+     qahw_stream_attributes_config attr;
+};
+
+typedef enum {
+    QAHW_CHANNEL_L = 0, /*left channel*/
+    QAHW_CHANNEL_R = 1, /*right channel*/
+    QAHW_CHANNELS_MAX = 2, /*max number of supported streams*/
+} qahw_channel_map;
+
+struct qahw_channel_vol {
+    qahw_channel_map channel;
+    float vol;
+};
+
+struct qahw_volume_data {
+    uint32_t num_of_channels;
+    struct qahw_channel_vol *vol_pair;
+};
+
+struct qahw_mute_data {
+    bool enable;
+    qahw_stream_direction direction;
+};
+
 __END_DECLS
 
 #endif  // QTI_AUDIO_HAL_DEFS_H
diff --git a/qahw/src/qahw.c b/qahw/src/qahw.c
index ceec657..2ae6906 100644
--- a/qahw/src/qahw.c
+++ b/qahw/src/qahw.c
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
@@ -45,8 +45,13 @@
 
 /*
  * The current HAL API version.
+ * version 1.0 has support for voice only in new stream based APIS
  */
+#ifdef QAHW_MODULE_API_VERSION_1_0
+#define QAHW_MODULE_API_VERSION_CURRENT QAHW_MODULE_API_VERSION_1_0
+#else
 #define QAHW_MODULE_API_VERSION_CURRENT QAHW_MODULE_API_VERSION_0_0
+#endif
 
 
 typedef uint64_t (*qahwi_out_write_v2_t)(audio_stream_out_t *out, const void* buffer,
diff --git a/qahw_api/Makefile.am b/qahw_api/Makefile.am
index 38506b8..e4cbdb5 100644
--- a/qahw_api/Makefile.am
+++ b/qahw_api/Makefile.am
@@ -22,8 +22,13 @@
 libqahw_la_CPPFLAGS += -std=c++11 -DHAVE_PTHREADS -DHAVE_ANDROID_OS
 libqahw_la_CPPFLAGS += -DDEBUG_REFS_CALLSTACK_ENABLED=0
 libqahw_la_CPPFLAGS += -DNDEBUG
-libqahw_la_LDFLAGS   = -ltinyalsa -lhardware -lexpat -lcutils -llog -ldl -shared -avoid-version -lpthread -lutils
+libqahw_la_CPPFLAGS += $(GLIB_CFLAGS) -include glib.h
+libqahw_la_LDFLAGS   = -ltinyalsa -lhardware -lexpat -lcutils -llog -ldl -shared -avoid-version -lpthread -lutils $(GLIB_LIBS)
 if QTI_AUDIO_SERVER_ENABLED
 AM_CPPFLAGS += -DQTI_AUDIO_SERVER_ENABLED
 libqahw_la_LDFLAGS +=  -lqtiaudioserver -lbinder
 endif
+if QAHW_V1
+AM_CPPFLAGS += -DQAHW_V1
+endif
+
diff --git a/qahw_api/inc/qahw_api.h b/qahw_api/inc/qahw_api.h
index b37757d..80d9c64 100644
--- a/qahw_api/inc/qahw_api.h
+++ b/qahw_api/inc/qahw_api.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2011 The Android Open Source Project *
@@ -485,6 +485,75 @@
 
 void qahw_register_qas_death_notify_cb(audio_error_callback cb, void* context);
 
+/* updated new stream APIs to support voice and Audio use cases */
+
+int qahw_stream_open(qahw_module_handle_t *hw_module,
+                     struct qahw_stream_attributes attr,
+                     uint32_t num_of_devices,
+                     qahw_device_t *devices,
+                     uint32_t no_of_modifiers,
+                     struct qahw_modifier_kv *modifiers,
+                     qahw_stream_callback_t cb,
+                     void *cookie,
+                     qahw_stream_handle_t **stream_handle);
+
+int qahw_stream_close(qahw_stream_handle_t *stream_handle);
+
+int qahw_stream_start(qahw_stream_handle_t *stream_handle);
+
+int qahw_stream_stop(qahw_stream_handle_t *stream_handle);
+
+int qahw_stream_set_device(qahw_stream_handle_t *stream_handle,
+                           uint32_t num_of_dev,
+                           qahw_device_t *devices);
+
+int qahw_stream_get_device(qahw_stream_handle_t *stream_handle,
+                           uint32_t *num_of_dev,
+                           qahw_device_t **devices);
+
+int qahw_stream_set_volume(qahw_stream_handle_t *stream_handle,
+                           struct qahw_volume_data vol_data);
+
+int qahw_stream_get_volume(qahw_stream_handle_t *stream_handle,
+                           struct qahw_volume_data **vol_data);
+
+int qahw_stream_set_mute(qahw_stream_handle_t *stream_handle,
+                         struct qahw_mute_data mute_data);
+
+int qahw_stream_get_mute(qahw_stream_handle_t *stream_handle,
+                         struct qahw_mute_data *mute_data);
+
+ssize_t qahw_stream_read(qahw_stream_handle_t *stream_handle,
+                         qahw_buffer_t *in_buf);
+
+ssize_t qahw_stream_write(qahw_stream_handle_t *stream_handle,
+                          qahw_buffer_t *out_buf);
+
+int32_t qahw_stream_pause(qahw_stream_handle_t *stream_handle);
+
+int32_t qahw_stream_standby(qahw_stream_handle_t *stream_handle);
+
+int32_t qahw_stream_resume(qahw_stream_handle_t *stream_handle);
+
+int32_t qahw_stream_flush(qahw_stream_handle_t *stream_handle);
+
+int32_t qahw_stream_drain(qahw_stream_handle_t *stream_handle,
+                          qahw_drain_type_t type);
+
+int32_t qahw_stream_get_buffer_size(const qahw_stream_handle_t *stream_handle,
+                                    size_t *in_buffer, size_t *out_buffer);
+
+int32_t qahw_stream_set_buffer_size(const qahw_stream_handle_t *stream_handle,
+                                    size_t in_buffer, size_t out_buffer);
+
+int32_t qahw_stream_set_parameters(qahw_stream_handle_t *stream_handle,
+                                   uint32_t param_id,
+                                   qahw_param_payload *param_payload);
+
+int32_t qahw_stream_get_parameters(qahw_stream_handle_t *stream_handle,
+                                   uint32_t param_id,
+                                   qahw_param_payload *param_payload);
+
 __END_DECLS
 
 #endif  // QTI_AUDIO_QAHW_API_H
diff --git a/qahw_api/inc/qahw_defs.h b/qahw_api/inc/qahw_defs.h
index 7bd5118..f979013 100644
--- a/qahw_api/inc/qahw_defs.h
+++ b/qahw_api/inc/qahw_defs.h
@@ -18,6 +18,7 @@
 
 #include <sys/cdefs.h>
 #include <stdint.h>
+#include <system/audio.h>
 
 #ifndef QTI_AUDIO_HAL_DEFS_H
 #define QTI_AUDIO_HAL_DEFS_H
@@ -171,6 +172,9 @@
 #define QAHW_INPUT_FLAG_TIMESTAMP 0x80000000
 #define QAHW_INPUT_FLAG_COMPRESS  0x40000000
 #define QAHW_INPUT_FLAG_PASSTHROUGH 0x20000000
+#define QAHW_OUTPUT_FLAG_INCALL_MUSIC 0x80000000
+#define QAHW_AUDIO_FLAG_HPCM_TX 0x00020000
+#define QAHW_AUDIO_FLAG_HPCM_RX 0x00040000
 
 /* Query fm volume */
 #define QAHW_PARAMETER_KEY_FM_VOLUME "fm_volume"
@@ -245,6 +249,14 @@
     uint32_t reserved[64]; /*reserved for future */
 } qahw_in_buffer_t;
 
+typedef struct {
+    void *buffer;    /* write buffer pointer */
+    size_t size;          /* size of buffer */
+    size_t offset;         /* offset in buffer from where valid byte starts */
+    int64_t *timestamp;    /* timestmap */
+    qahw_meta_data_flags_t flags; /* meta data flags */
+} qahw_buffer_t;
+
 #define MAX_SECTORS 8
 
 struct qahw_source_tracking_param {
@@ -370,6 +382,42 @@
     char license[QAHW_LICENCE_STR_MAX_LENGTH + 1];
 } qahw_license_params_t;
 
+typedef struct qahw_dtmf_gen_params {
+   bool enable;
+   uint16_t low_freq;
+   uint16_t high_freq;
+   uint16_t gain;
+} qahw_dtmf_gen_params_t;
+
+enum {
+    QAHW_TTY_MODE_OFF,
+    QAHW_TTY_MODE_FULL,
+    QAHW_TTY_MODE_VCO,
+    QAHW_TTY_MODE_HCO,
+    QAHW_TTY_MODE_MAX,
+};
+
+typedef struct qahw_tty_params {
+   uint32_t mode;
+} qahw_tty_params_t;
+
+typedef enum {
+    QAHW_HPCM_TAP_POINT_RX = 1,
+    QAHW_HPCM_TAP_POINT_TX = 2,
+    QAHW_HPCM_TAP_POINT_RX_TX = 3,
+} qahw_hpcm_tap_point;
+
+typedef enum {
+    QAHW_HPCM_DIRECTION_OUT,
+    QAHW_HPCM_DIRECTION_IN,
+    QAHW_HPCM_DIRECTION_OUT_IN,
+} qahw_hpcm_direction;
+
+typedef struct qahw_hpcm_params {
+   qahw_hpcm_tap_point tap_point;
+   qahw_hpcm_direction direction;
+} qahw_hpcm_params_t;
+
 typedef union {
     struct qahw_source_tracking_param st_params;
     struct qahw_sound_focus_param sf_params;
@@ -385,6 +433,9 @@
     struct qahw_mix_matrix_params mix_matrix_params;
     struct qahw_license_params license_params;
     struct qahw_out_presentation_position_param pos_param;
+    struct qahw_dtmf_gen_params dtmf_gen_params;
+    struct qahw_tty_params tty_mode_params;
+    struct qahw_hpcm_params hpcm_params;
 } qahw_param_payload;
 
 typedef enum {
@@ -405,6 +456,9 @@
     QAHW_PARAM_CH_MIX_MATRIX_PARAMS,
     QAHW_PARAM_LICENSE_PARAMS,
     QAHW_PARAM_OUT_PRESENTATION_POSITION,
+    QAHW_PARAM_DTMF_GEN,
+    QAHW_PARAM_TTY_MODE,
+    QAHW_PARAM_HPCM,
 } qahw_param_id;
 
 
@@ -416,6 +470,94 @@
     QAHW_PARAM_LOOPBACK_RENDER_WINDOW /* PARAM to set render window */
 } qahw_loopback_param_id;
 
+/** stream direction enumeration */
+typedef enum {
+    QAHW_STREAM_INPUT,
+    QAHW_STREAM_OUTPUT,
+    QAHW_STREAM_INPUT_OUTPUT,
+} qahw_stream_direction;
+
+/** stream types */
+typedef enum {
+    QAHW_STREAM_TYPE_INVALID,
+    QAHW_AUDIO_PLAYBACK_LOW_LATENCY,      /**< low latency, higher power*/
+    QAHW_AUDIO_PLAYBACK_DEEP_BUFFER,          /**< low power, higher latency*/
+    QAHW_AUDIO_PLAYBACK_COMPRESSED,           /**< compresssed audio*/
+    QAHW_AUDIO_PLAYBACK_VOIP,                 /**< pcm voip audio*/
+    QAHW_AUDIO_PLAYBACK_VOICE_CALL_MUSIC,     /**< pcm voip audio*/
+
+    QAHW_AUDIO_CAPTURE_LOW_LATENCY,           /**< low latency, higher power*/
+    QAHW_AUDIO_CAPTURE_DEEP_BUFFER,           /**< low power, higher latency*/
+    QAHW_AUDIO_CAPTURE_COMPRESSED,            /**< compresssed audio*/
+    QAHW_AUDIO_CAPTURE_RAW,                   /**< pcm no post processing*/
+    QAHW_AUDIO_CAPTURE_VOIP,                  /**< pcm voip audio*/
+    QAHW_AUDIO_CAPTURE_VOICE_ACTIVATION,      /**< voice activation*/
+    QAHW_AUDIO_CAPTURE_VOICE_CALL_RX,         /**< incall record, downlink */
+    QAHW_AUDIO_CAPTURE_VOICE_CALL_TX,         /**< incall record, uplink */
+    QAHW_AUDIO_CAPTURE_VOICE_CALL_RX_TX,      /**< incall record, uplink & Downlink */
+
+    QAHW_VOICE_CALL,                          /**< voice call */
+
+    QAHW_AUDIO_TRANSCODE,                     /**< audio transcode */
+    QAHW_AUDIO_HOST_PCM_TX,
+    QAHW_AUDIO_HOST_PCM_RX,
+    QAHW_AUDIO_HOST_PCM_TX_RX,
+    QAHW_AUDIO_STREAM_TYPE_MAX,
+} qahw_audio_stream_type;
+
+typedef uint32_t qahw_device_t;
+
+/**< Key value pair to identify the topology of a usecase from default  */
+struct qahw_modifier_kv  {
+    uint32_t key;
+    uint32_t value;
+};
+
+struct qahw_shared_attributes{
+     audio_config_t config;
+};
+struct qahw_voice_attributes{
+     audio_config_t config;
+     const char *vsid;
+};
+
+struct qahw_audio_attributes{
+    audio_config_t config;
+};
+
+typedef union {
+    struct qahw_shared_attributes shared;
+    struct qahw_voice_attributes voice;
+    struct qahw_audio_attributes audio;
+} qahw_stream_attributes_config;
+
+struct qahw_stream_attributes {
+     qahw_audio_stream_type type;
+     qahw_stream_direction direction;
+     qahw_stream_attributes_config attr;
+};
+
+typedef enum {
+    QAHW_CHANNEL_L = 0, /*left channel*/
+    QAHW_CHANNEL_R = 1, /*right channel*/
+    QAHW_CHANNELS_MAX = 2, /*max number of supported streams*/
+} qahw_channel_map;
+
+struct qahw_channel_vol {
+    qahw_channel_map channel;
+    float vol;
+};
+
+struct qahw_volume_data {
+    uint32_t num_of_channels;
+    struct qahw_channel_vol *vol_pair;
+};
+
+struct qahw_mute_data {
+    bool enable;
+    qahw_stream_direction direction;
+};
+
 __END_DECLS
 
 #endif  // QTI_AUDIO_HAL_DEFS_H
diff --git a/qahw_api/src/qahw_api.cpp b/qahw_api/src/qahw_api.cpp
index 0810ede..cbde5e3 100644
--- a/qahw_api/src/qahw_api.cpp
+++ b/qahw_api/src/qahw_api.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
@@ -37,11 +37,99 @@
 #include <stdlib.h>
 #include <cutils/list.h>
 #include <assert.h>
+#include <string.h>
 
 #include <hardware/audio.h>
 #include <cutils/properties.h>
 #include "qahw_api.h"
 #include "qahw.h"
+#include <errno.h>
+
+#ifndef ANDROID
+#define strlcpy g_strlcpy
+#define strlcat g_strlcat
+#endif
+
+#if QAHW_V1
+#define QAHW_DEV_ROUTE_LENGTH 15
+#define QAHW_KV_PAIR_LENGTH 255
+#define QAHW_NUM_OF_ROUTINGS 4
+#define QAHW_NUM_OF_SESSIONS 4
+#define QAHW_NAMES_PER_SESSION 2
+#define QAHW_SESSION_NAME_MAX_LEN 255
+#define QAHW_MAX_INT_STRING 12
+#define QAHW_NUM_OF_MUTE_TYPES 4
+
+#define MAX_NUM_DEVICES 10
+
+typedef struct {
+    qahw_stream_handle_t *out_stream;
+    qahw_stream_handle_t *in_stream;
+    qahw_module_handle_t *hw_module;
+    uint32_t num_of_devices;
+    audio_devices_t devices[MAX_NUM_DEVICES];
+    qahw_stream_direction dir;
+    qahw_audio_stream_type type;
+    struct qahw_volume_data vol;
+    struct qahw_mute_data out_mute;
+    struct qahw_mute_data in_mute;
+} qahw_api_stream_t;
+
+/* Array to store sound devices */
+static const char * const stream_name_map[QAHW_AUDIO_STREAM_TYPE_MAX] = {
+    [QAHW_STREAM_TYPE_INVALID] = "",
+    [QAHW_AUDIO_PLAYBACK_LOW_LATENCY]= "playback-low-latency",
+    [QAHW_AUDIO_PLAYBACK_DEEP_BUFFER]= "playback-deep-buffer",
+    [QAHW_AUDIO_PLAYBACK_COMPRESSED]= "playback-compressed",
+    [QAHW_AUDIO_PLAYBACK_VOIP]= "playback-voip",
+    [QAHW_AUDIO_PLAYBACK_VOICE_CALL_MUSIC]= "playback-in-call-music",
+    [QAHW_AUDIO_CAPTURE_LOW_LATENCY]= "capture-low-latency",
+    [QAHW_AUDIO_CAPTURE_DEEP_BUFFER]= "capture-deep-buffer",
+    [QAHW_AUDIO_CAPTURE_COMPRESSED]= "capture-compressed",
+    [QAHW_AUDIO_CAPTURE_RAW]= "capture-raw",
+    [QAHW_AUDIO_CAPTURE_VOIP]= "capture-voip",
+    [QAHW_AUDIO_CAPTURE_VOICE_ACTIVATION]= "capture-voice-activation",
+    [QAHW_AUDIO_CAPTURE_VOICE_CALL_RX]= "capture-voice-rx",
+    [QAHW_AUDIO_CAPTURE_VOICE_CALL_TX]= "capture-voice-tx",
+    [QAHW_AUDIO_CAPTURE_VOICE_CALL_RX_TX]= "capture-voice-rx-tx",
+    [QAHW_VOICE_CALL]= "voice-call",
+    [QAHW_AUDIO_TRANSCODE]= "audio-transcode",
+    [QAHW_AUDIO_HOST_PCM_TX]= "host-pcm-tx",
+    [QAHW_AUDIO_HOST_PCM_RX]= "host-pcm-rx",
+    [QAHW_AUDIO_HOST_PCM_TX_RX]= "host-pcm-tx-rx",
+};
+
+static const char * const tty_mode_map[QAHW_TTY_MODE_MAX] = {
+    [QAHW_TTY_MODE_OFF] = "tty_mode=tty_off",
+    [QAHW_TTY_MODE_FULL] = "tty_mode=tty_full",
+    [QAHW_TTY_MODE_VCO] = "tty_mode=tty_vco",
+    [QAHW_TTY_MODE_HCO] = "tty_mode=tty_hco",
+};
+
+typedef struct {
+    char sess_id[QAHW_NAMES_PER_SESSION][QAHW_SESSION_NAME_MAX_LEN + 1];
+    char sess_id_call_state[QAHW_KV_PAIR_LENGTH];
+} session_info_t;
+
+static session_info_t session_info[QAHW_NUM_OF_SESSIONS] = {
+    {{"default mmodevoice1", "11C05000"}, "vsid=297816064;call_state=2"},
+    {{"default mmodevoice2", "11DC5000"}, "vsid=299651072;call_state=2"},
+    {{"default modem voice", "10C01000"}, "vsid=281022464;call_state=2"},
+    {{"default volte voice", "10C02000"}, "vsid=281026560;call_state=2"}
+};
+
+typedef struct {
+    struct qahw_mute_data mute;
+    char mute_state[QAHW_KV_PAIR_LENGTH];
+} qahw_mute_info_t;
+
+static qahw_mute_info_t mute_info[QAHW_NUM_OF_MUTE_TYPES] = {
+    {{1, QAHW_STREAM_INPUT}, "device_mute=true;direction=tx" },
+    {{0, QAHW_STREAM_INPUT}, "device_mute=false;direction=tx" },
+    {{1, QAHW_STREAM_OUTPUT}, "device_mute=true;direction=rx" },
+    {{0, QAHW_STREAM_OUTPUT}, "device_mute=false;direction=rx" },
+};
+#endif
 
 #if QTI_AUDIO_SERVER_ENABLED
 #include <mm-audio/qti-audio-server/qti_audio_server.h>
@@ -1817,4 +1905,1062 @@
     ALOGV("%d:%s",__LINE__, __func__);
     return qahw_load_module_l(hw_module_id);
 }
+
+#if QAHW_V1
+char * qahw_get_session_id(const char* vsid)
+{
+    int i = 0;
+    int j = 0;
+    char *ret = "vsid=281022464;call_state=2";
+
+    for(i = 0; i < QAHW_NUM_OF_SESSIONS; i++) {
+        for(j = 0; j < QAHW_NAMES_PER_SESSION; j++) {
+            if(!strcmp(vsid,session_info[i].sess_id[j])) {
+                ret = session_info[i].sess_id_call_state;
+                ALOGV("%s: vsid %s\n", __func__, vsid);
+                break;
+            }
+        }
+    }
+    ALOGV("%s: sess_id_call_state %s\n", __func__, ret);
+    return ret;
+}
+
+int qahw_add_flags_source(struct qahw_stream_attributes attr,
+                          int *flags, audio_source_t *source) {
+    int rc = 0;
+    /*default source */
+    if (source && flags) {
+        *source = AUDIO_SOURCE_MIC;
+        /*default flag*/
+        *flags = 0;
+    } else
+        return -EINVAL;
+
+    switch (attr.type) {
+    case QAHW_AUDIO_PLAYBACK_LOW_LATENCY:
+        /*TODO*/
+        break;
+    case QAHW_AUDIO_PLAYBACK_DEEP_BUFFER:
+        *flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
+        break;
+    case QAHW_AUDIO_PLAYBACK_COMPRESSED:
+        *flags = AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
+        break;
+    case QAHW_AUDIO_PLAYBACK_VOIP:
+        /*TODO*/
+        break;
+    case QAHW_AUDIO_PLAYBACK_VOICE_CALL_MUSIC:
+        *flags = QAHW_OUTPUT_FLAG_INCALL_MUSIC;
+        break;
+    case QAHW_AUDIO_CAPTURE_LOW_LATENCY:
+        /*TODO*/
+        break;
+    case QAHW_AUDIO_CAPTURE_DEEP_BUFFER:
+        /*TODO*/
+        break;
+    case QAHW_AUDIO_CAPTURE_COMPRESSED:
+        /*TODO*/
+        break;
+    case QAHW_AUDIO_CAPTURE_RAW:
+        /*TODO*/
+        break;
+    case QAHW_AUDIO_CAPTURE_VOIP:
+        break;
+    case QAHW_AUDIO_CAPTURE_VOICE_ACTIVATION:
+        /*TODO*/
+        break;
+    case QAHW_AUDIO_CAPTURE_VOICE_CALL_RX:
+        *source = AUDIO_SOURCE_VOICE_DOWNLINK;
+        break;
+    case QAHW_AUDIO_CAPTURE_VOICE_CALL_TX:
+        *source = AUDIO_SOURCE_VOICE_UPLINK;
+        break;
+    case QAHW_AUDIO_CAPTURE_VOICE_CALL_RX_TX:
+        /*unsupported */
+        break;
+    case QAHW_VOICE_CALL:
+        *flags = AUDIO_OUTPUT_FLAG_PRIMARY;
+        break;
+    case QAHW_AUDIO_TRANSCODE:
+        /*TODO*/
+        break;
+    case QAHW_AUDIO_HOST_PCM_TX:
+        *flags = QAHW_AUDIO_FLAG_HPCM_TX;
+        break;
+    case QAHW_AUDIO_HOST_PCM_RX:
+        *flags = QAHW_AUDIO_FLAG_HPCM_RX;
+        break;
+    case QAHW_AUDIO_HOST_PCM_TX_RX:
+        /*TODO*/
+        break;
+    default:
+        rc = -EINVAL;
+        break;
+    }
+
+    return rc;
+}
+
+int qahw_stream_open(qahw_module_handle_t *hw_module,
+                     struct qahw_stream_attributes attr,
+                     uint32_t num_of_devices,
+                     qahw_device_t *devices,
+                     uint32_t no_of_modifiers,
+                     struct qahw_modifier_kv *modifiers,
+                     qahw_stream_callback_t cb,
+                     void *cookie,
+                     qahw_stream_handle_t **stream_handle) {
+
+    audio_io_handle_t handle = 0x999;
+    int rc = -EINVAL;
+    const char *address = stream_name_map[attr.type];
+    const char *session_id;
+    int flags = 0;
+    audio_source_t source = AUDIO_SOURCE_MIC;
+    qahw_api_stream_t *stream;
+    struct qahw_channel_vol *vols;
+
+    /* validate number of devices */
+    if (num_of_devices > MAX_NUM_DEVICES)
+    {
+        ALOGE("%s: invalid number of devices for stream", __func__);
+        return rc;
+    }
+    /* validate direction for voice stream */
+    if (attr.type == QAHW_VOICE_CALL &&
+        attr.direction != QAHW_STREAM_INPUT_OUTPUT) {
+        ALOGE("%s: invalid direction for a voice stream", __func__);
+        return rc;
+    }
+    /* add flag*/
+    rc = qahw_add_flags_source(attr, &flags, &source);
+
+    if (rc) {
+        ALOGE("%s: invalid type %d", __func__, attr.type);
+        return rc;
+    }
+
+    stream = (qahw_api_stream_t *)calloc(1, sizeof(qahw_api_stream_t));
+    if (!stream) {
+        ALOGE("%s: stream allocation failed ", __func__);
+        return -ENOMEM;
+    }
+    vols = (struct qahw_channel_vol *)
+            calloc(1, sizeof(struct qahw_channel_vol)*QAHW_CHANNELS_MAX);
+    if (!vols) {
+        ALOGE("%s: vol allocation failed ", __func__);
+        return -ENOMEM;
+    }
+
+    memset(stream, 0, sizeof(qahw_api_stream_t));
+    memset(vols, 0, sizeof(struct qahw_channel_vol)*QAHW_CHANNELS_MAX);
+    stream->dir = attr.direction;
+    stream->hw_module = hw_module;
+    stream->num_of_devices = num_of_devices;
+    memset(&stream->devices[0], 0, sizeof(stream->devices));
+    memcpy(&stream->devices[0], devices, num_of_devices);
+    stream->type = attr.type;
+    stream->vol.vol_pair = vols;
+    /* if voice call stream, num_of_channels set to 1 */
+    if (attr.type == QAHW_VOICE_CALL)
+        stream->vol.num_of_channels = 1;
+    else
+        stream->vol.num_of_channels = QAHW_CHANNELS_MAX;
+
+    switch (attr.direction) {
+    case QAHW_STREAM_INPUT_OUTPUT:
+        /*for now only support one stream to one device*/
+        if (num_of_devices != 2 && attr.type != QAHW_VOICE_CALL) {
+            ALOGE("%s: invalid num of streams %d for dir %d",
+                  __func__, num_of_devices, attr.direction);
+            return rc;
+        }
+        rc = qahw_open_output_stream(hw_module, handle, devices[0],
+                                     (audio_output_flags_t)flags,
+                                     &(attr.attr.shared.config),
+                                     &stream->out_stream,
+                                     address);
+        /*set cb function */
+        if (rc)
+            rc = qahw_out_set_callback(stream->out_stream, cb, cookie);
+        if (rc)
+            ALOGE("%s: setting callback failed %d \n", __func__, rc);
+
+        if (attr.type != QAHW_VOICE_CALL) {
+            rc = qahw_open_input_stream(hw_module, handle, devices[1],
+                                        &(attr.attr.shared.config),
+                                        &stream->in_stream,
+                                        (audio_input_flags_t)flags,
+                                        address,
+                                        source);
+        }
+        break;
+    case QAHW_STREAM_OUTPUT:
+        if (num_of_devices != 1) {
+            ALOGE("%s: invalid num of streams %d for dir %d",
+                  __func__, num_of_devices, attr.direction);
+            return rc;
+        }
+        rc = qahw_open_output_stream(hw_module, handle, devices[0],
+                                     (audio_output_flags_t)flags,
+                                     &(attr.attr.shared.config),
+                                     &stream->out_stream,
+                                     address);
+        /*set cb function */
+        if (rc)
+            rc = qahw_out_set_callback(stream->out_stream, cb, cookie);
+        if (rc)
+            ALOGE("%s: setting callback failed %d \n", __func__, rc);
+        break;
+    case QAHW_STREAM_INPUT:
+        if (num_of_devices != 1) {
+            ALOGE("%s: invalid num of streams %d for dir %d",
+                  __func__, num_of_devices, attr.direction);
+            return rc;
+        }
+        rc = qahw_open_input_stream(hw_module, handle, devices[0],
+                                    &(attr.attr.shared.config),
+                                    &stream->in_stream,
+                                    (audio_input_flags_t)flags,
+                                    address,
+                                    source);
+        break;
+    default:
+        ALOGE("%s: invalid stream direction %d ", __func__, attr.direction);
+        return rc;
+    }
+    /*set the stream type as the handle add to list*/
+    *stream_handle = (qahw_stream_handle_t *)stream;
+
+    /*if voice call set vsid and call state/mode*/
+    if (attr.type == QAHW_VOICE_CALL) {
+        session_id = qahw_get_session_id(attr.attr.voice.vsid);
+
+        rc = qahw_set_parameters(hw_module, session_id);
+        if (rc) {
+            ALOGE("%s: setting vsid failed %d \n", __func__, rc);
+        }
+    }
+
+    if(no_of_modifiers){
+        ALOGE("%s: modifiers not currently supported\n", __func__);
+    }
+    return rc;
+}
+
+int qahw_stream_close(qahw_stream_handle_t *stream_handle) {
+    int rc = -EINVAL;
+    qahw_stream_direction dir;
+    qahw_api_stream_t *stream = (qahw_api_stream_t *)stream_handle;
+
+    if (stream) {
+        switch (stream->dir) {
+        case QAHW_STREAM_OUTPUT:
+            ALOGV("%s: closing output stream\n", __func__);
+            rc = qahw_close_output_stream(stream->out_stream);
+            break;
+        case QAHW_STREAM_INPUT:
+            ALOGV("%s: closing input stream\n", __func__);
+            rc = qahw_close_input_stream(stream->in_stream);
+            break;
+        case QAHW_STREAM_INPUT_OUTPUT:
+            rc = qahw_close_output_stream(stream->out_stream);
+            if (rc)
+                ALOGE("%s: closing output stream failed\n", __func__);
+            /*if not voice call close input stream*/
+            if (stream->type != QAHW_VOICE_CALL) {
+                rc = qahw_close_input_stream(stream->in_stream);
+                if (rc)
+                    ALOGE("%s: closing output stream failed\n", __func__);
+            }
+            break;
+        default:
+            ALOGE("%s: invalid dir close failed\n", __func__);
+        }
+    } else
+        ALOGE("%s: null stream handle\n", __func__);
+
+    free(stream->vol.vol_pair);
+    free(stream);
+    return rc;
+}
+
+int qahw_stream_start(qahw_stream_handle_t *stream_handle) {
+    int rc = -EINVAL;
+    qahw_audio_stream_type type;
+    qahw_api_stream_t *stream = (qahw_api_stream_t *)stream_handle;
+
+    if (!stream) {
+        ALOGE("%d:%s invalid stream handle", __LINE__, __func__);
+        return rc;
+    }
+    /*set call state and call mode for voice */
+    if (stream->type == QAHW_VOICE_CALL) {
+        rc = qahw_set_mode(stream->hw_module, AUDIO_MODE_IN_CALL);
+    }
+
+    qahw_stream_set_device(stream, stream->num_of_devices, stream->devices);
+    return rc;
+}
+
+int qahw_stream_stop(qahw_stream_handle_t *stream_handle) {
+    int rc = -EINVAL;
+    qahw_audio_stream_type type;
+    qahw_api_stream_t *stream = (qahw_api_stream_t *)stream_handle;
+
+    /*reset call state and call mode for voice */
+    if (stream->type == QAHW_VOICE_CALL) {
+        rc = qahw_set_parameters(stream->hw_module, "call_state=1");
+        rc = qahw_set_mode(stream->hw_module, AUDIO_MODE_NORMAL);
+    }
+    return rc;
+}
+
+int qahw_stream_set_device(qahw_stream_handle_t *stream_handle,
+                    uint32_t num_of_devices,
+                    qahw_device_t *devices) {
+    int rc = -EINVAL;
+    char dev_s[QAHW_MAX_INT_STRING];
+    char device_route[QAHW_MAX_INT_STRING];
+    qahw_api_stream_t *stream = (qahw_api_stream_t *)stream_handle;
+    bool is_voice = false;
+
+    strlcpy(device_route, "routing=", QAHW_MAX_INT_STRING);
+
+    if (stream && num_of_devices && devices) {
+        if (stream->type == QAHW_VOICE_CALL)
+            is_voice = true;
+
+        switch (stream->dir) {
+        case QAHW_STREAM_OUTPUT:
+            if (num_of_devices != 1 || !devices) {
+                ALOGE("%s: invalid device params\n", __func__);
+                return rc;
+            }
+
+            snprintf(dev_s, QAHW_MAX_INT_STRING, "%d", devices[0]);
+            strlcat(device_route, dev_s, QAHW_MAX_INT_STRING);
+            rc = qahw_out_set_parameters(stream->out_stream,
+                                         device_route);
+            break;
+        case QAHW_STREAM_INPUT:
+            if (num_of_devices != 1 || !devices) {
+                ALOGE("%s: invalid device params\n", __func__);
+                return rc;
+            }
+
+            snprintf(dev_s, QAHW_MAX_INT_STRING, "%d", devices[0]);
+            strlcat(device_route, dev_s, QAHW_MAX_INT_STRING);
+            rc = qahw_in_set_parameters(stream->in_stream,
+                                        device_route);
+            break;
+        case QAHW_STREAM_INPUT_OUTPUT:
+            if (!devices) {
+                ALOGE("%s: invalid device params\n", __func__);
+                return rc;
+            }
+            snprintf(dev_s, QAHW_MAX_INT_STRING, "%d", devices[0]);
+            strlcat(device_route, dev_s, QAHW_MAX_INT_STRING);
+            rc = qahw_out_set_parameters(stream->out_stream,
+                                         device_route);
+            if (rc)
+                ALOGE("%s: failed to set out device\n", __func__);
+            /*if not voice set input stream*/
+            if (!is_voice) {
+                strlcpy(device_route, "routing=", QAHW_MAX_INT_STRING);
+                snprintf(dev_s, QAHW_MAX_INT_STRING, "%d", devices[1]);
+                strlcat(device_route, dev_s, QAHW_MAX_INT_STRING);
+                rc = qahw_in_set_parameters(stream->in_stream,
+                                            device_route);
+                if (rc)
+                    ALOGE("%s: failed to set in device\n", __func__);
+            }
+            break;
+        default:
+            ALOGE("%s: invalid dir close failed\n", __func__);
+        }
+    }
+
+    if (!rc)
+    {
+        stream->num_of_devices = num_of_devices;
+        memset(&stream->devices[0], 0, sizeof(stream->devices));
+        memcpy(&stream->devices[0], devices, num_of_devices);
+    }
+
+    return rc;
+}
+
+int qahw_stream_get_device(qahw_stream_handle_t *stream_handle, uint32_t *num_of_dev,
+                    qahw_device_t **devices) {
+    int rc = 0;
+    qahw_api_stream_t *stream = (qahw_api_stream_t *)stream_handle;
+
+    if (stream && num_of_dev && devices) {
+        *num_of_dev = stream->num_of_devices;
+        *devices = stream->devices;
+    } else {
+        ALOGE("%s: invalid params\n", __func__);
+        rc = -EINVAL;
+    }
+
+    return rc;
+}
+
+int qahw_stream_set_volume(qahw_stream_handle_t *stream_handle,
+                           struct qahw_volume_data vol_data) {
+    int rc = -EINVAL;
+    qahw_audio_stream_type type;
+    qahw_api_stream_t *stream = (qahw_api_stream_t *)stream_handle;
+    float left;
+    float right;
+    bool l_found = false;
+    bool r_found = false;
+    int i;
+
+    if(stream) {
+        /*currently max 2 channels is supported */
+        if ( vol_data.num_of_channels > QAHW_CHANNELS_MAX) {
+           return -ENOTSUP;
+        }
+
+        /*set voice call vol*/
+        if (stream->type == QAHW_VOICE_CALL &&
+            (vol_data.vol_pair && (vol_data.num_of_channels == 1))) {
+            ALOGV("%s: calling voice set volume with vol value %f\n",
+                  __func__, vol_data.vol_pair[0].vol);
+            rc = qahw_set_voice_volume(stream->hw_module,
+                                       vol_data.vol_pair[0].vol);
+            /* Voice Stream picks up only single channel */
+            stream->vol.num_of_channels = vol_data.num_of_channels;
+            stream->vol.vol_pair[0] = vol_data.vol_pair[0];
+        } /*currently HAL requires 2 channels only */
+        else if (vol_data.num_of_channels == QAHW_CHANNELS_MAX &&
+                   vol_data.vol_pair) {
+            for(i=0; i < vol_data.num_of_channels; i++) {
+                if(vol_data.vol_pair[i].channel == QAHW_CHANNEL_L) {
+                    left = vol_data.vol_pair[i].vol;
+                    l_found = true;
+                }
+                if(vol_data.vol_pair[i].channel == QAHW_CHANNEL_R) {
+                    right = vol_data.vol_pair[i].vol;
+                    r_found = true;
+                }
+            }
+            if(l_found && r_found) {
+                rc = qahw_out_set_volume(stream->out_stream,
+                                         left, right);
+                /* Cache volume if applied successfully */
+                if (!rc) {
+                    for(i=0; i < vol_data.num_of_channels; i++) {
+                        stream->vol.vol_pair[i] = vol_data.vol_pair[i];
+                    }
+                }
+            } else
+                ALOGE("%s: setting vol requires left and right channel vol\n",
+                      __func__);
+        } else {
+            ALOGE("%s: invalid input \n", __func__);
+        }
+    } else
+        ALOGE("%s: null stream handle\n", __func__);
+
+    return rc;
+}
+
+int qahw_stream_get_volume(qahw_stream_handle_t *stream_handle,
+                           struct qahw_volume_data **vol_data) {
+    int rc = 0;
+    qahw_api_stream_t *stream = (qahw_api_stream_t *)stream_handle;
+    if (stream)
+        *vol_data = &stream->vol;
+    else
+        rc = -EINVAL;
+
+    return rc;
+}
+
+char *qahw_get_device_mute_info(struct qahw_mute_data mute) {
+    int i = 0;
+    char *ret = NULL;
+
+    for (i=0; i < QAHW_NUM_OF_MUTE_TYPES; i++) {
+        if ((mute.enable == mute_info[i].mute.enable) &&
+            (mute.direction == mute_info[i].mute.direction)) {
+            ret = mute_info[i].mute_state;
+            break;
+        }
+    }
+    ALOGV("%s mute_state %s \n", __func__, ret == NULL ? "null" : ret);
+
+    return ret;
+}
+
+int qahw_stream_set_mute(qahw_stream_handle_t *stream_handle,
+                         struct qahw_mute_data mute_data) {
+    int rc = -EINVAL;
+    qahw_module_handle_t *hw_module;
+    qahw_api_stream_t *stream = (qahw_api_stream_t *)stream_handle;
+    char *mute_param;
+
+    if(stream) {
+        mute_param = qahw_get_device_mute_info(mute_data);
+
+        if (mute_param == NULL)
+            return rc;
+
+        rc = qahw_set_parameters(stream->hw_module, mute_param);
+
+        if(!rc){
+            switch(mute_data.direction) {
+                case QAHW_STREAM_INPUT_OUTPUT:
+                    stream->out_mute.enable = mute_data.enable;
+                    stream->in_mute.enable = mute_data.enable;
+                    break;
+                case QAHW_STREAM_OUTPUT:
+                    stream->out_mute.enable = mute_data.enable;
+                    break;
+                case QAHW_STREAM_INPUT:
+                    stream->in_mute.enable = mute_data.enable;
+                    break;
+                default:
+                    ALOGE("%s: invalid dir mute failed\n", __func__);
+                    break;
+            }
+        }
+    }
+    return rc;
+}
+
+int qahw_stream_get_mute(qahw_stream_handle_t *stream_handle,
+                         struct qahw_mute_data *mute_data) {
+    int rc = 0;
+    qahw_api_stream_t *stream = (qahw_api_stream_t *)stream_handle;
+
+    if(stream && mute_data){
+            switch(mute_data->direction) {
+                case QAHW_STREAM_OUTPUT:
+                    mute_data->enable = stream->out_mute.enable;
+                    break;
+                case QAHW_STREAM_INPUT:
+                    mute_data->enable = stream->in_mute.enable;
+                    break;
+                default:
+                    ALOGE("%s: invalid mute dir get failed\n", __func__);
+                    rc = -EINVAL;
+                    break;
+            }
+    }
+
+    return rc;
+}
+
+ssize_t qahw_stream_read(qahw_stream_handle_t *stream_handle,
+                         qahw_buffer_t *in_buf) {
+    ssize_t rc = 0;
+    qahw_api_stream_t *stream = (qahw_api_stream_t *)stream_handle;
+    qahw_in_buffer_t buff;
+
+    if(in_buf) {
+        buff.buffer = in_buf->buffer;
+        buff.bytes = in_buf->size;
+        buff.offset = in_buf->offset;
+        buff.timestamp = in_buf->timestamp;
+    }
+
+    if (stream && stream->in_stream) {
+        rc = qahw_in_read(stream->in_stream, &buff);
+    } else {
+        ALOGE("%d:%s input stream invalid, read failed", __LINE__, __func__);
+        rc = -ENODEV;
+    }
+    return rc;
+}
+
+ssize_t qahw_stream_write(qahw_stream_handle_t *stream_handle,
+                   qahw_buffer_t *out_buf) {
+    ssize_t rc = 0;
+    qahw_api_stream_t *stream = (qahw_api_stream_t *)stream_handle;
+    qahw_out_buffer_t buff;
+
+    if(out_buf) {
+        buff.buffer = out_buf->buffer;
+        buff.bytes = out_buf->size;
+        buff.offset = out_buf->offset;
+        buff.timestamp = out_buf->timestamp;
+        buff.flags = out_buf->flags;
+    }
+
+    if (stream && stream->out_stream) {
+        rc = qahw_out_write(stream->out_stream, &buff);
+    } else {
+        ALOGE("%d:%s out stream invalid, write failed", __LINE__, __func__);
+        rc = -ENODEV;
+    }
+    return rc;
+}
+
+int qahw_stream_standby(qahw_stream_handle_t *stream_handle) {
+    int rc = -EINVAL;
+    qahw_api_stream_t *stream = (qahw_api_stream_t *)stream_handle;
+    if (stream) {
+        switch (stream->dir) {
+        case QAHW_STREAM_OUTPUT:
+            if (stream->out_stream)
+                rc = qahw_out_standby(stream->out_stream);
+            else
+                ALOGE("%d:%s out stream invalid, cannot put in standby"
+                      , __LINE__, __func__);
+            break;
+        case QAHW_STREAM_INPUT:
+            if (stream->in_stream)
+                rc = qahw_in_standby(stream->in_stream);
+            else
+                ALOGE("%d:%s in stream invalid, cannot put in standby"
+                      , __LINE__, __func__);
+            break;
+        case QAHW_STREAM_INPUT_OUTPUT:
+            if (stream->in_stream)
+                rc = qahw_in_standby(stream->in_stream);
+            else
+                ALOGE("%d:%s in stream invalid, cannot put in standby"
+                      , __LINE__, __func__);
+            if (stream->out_stream)
+                rc = qahw_out_standby(stream->out_stream);
+            else
+                ALOGE("%d:%s out stream invalid, cannot put in standby"
+                      , __LINE__, __func__);
+            break;
+        }
+    } else
+        ALOGE("%d:%s invalid stream handle, standby failed"
+              , __LINE__, __func__);
+    return rc;
+}
+
+int qahw_stream_pause(qahw_stream_handle_t *stream_handle) {
+    int rc = -EINVAL;
+    qahw_api_stream_t *stream = (qahw_api_stream_t *)stream_handle;
+    if (stream) {
+        switch (stream->dir) {
+        case QAHW_STREAM_OUTPUT:
+            if (stream->out_stream)
+                rc = qahw_out_pause(stream->out_stream);
+            else
+                ALOGE("%d:%s out stream invalid, cannot put in pause"
+                      , __LINE__, __func__);
+            break;
+        case QAHW_STREAM_INPUT:
+                ALOGE("%d:%s cannot pause input stream"
+                      , __LINE__, __func__);
+            break;
+        case QAHW_STREAM_INPUT_OUTPUT:
+            if (stream->out_stream)
+                rc = qahw_out_pause(stream->out_stream);
+            else
+                ALOGE("%d:%s out stream invalid, cannot put in pause"
+                      , __LINE__, __func__);
+            break;
+        }
+    } else
+        ALOGE("%d:%s invalid stream handle, pause failed"
+              , __LINE__, __func__);
+    return rc;
+}
+
+int qahw_stream_resume(qahw_stream_handle_t *stream_handle) {
+    int rc = -EINVAL;
+    qahw_api_stream_t *stream = (qahw_api_stream_t *)stream_handle;
+    if (stream) {
+        switch (stream->dir) {
+        case QAHW_STREAM_OUTPUT:
+            if (stream->out_stream)
+                rc = qahw_out_resume(stream->out_stream);
+            else
+                ALOGE("%d:%s out stream invalid, cannot put in resume"
+                      , __LINE__, __func__);
+            break;
+        case QAHW_STREAM_INPUT:
+                ALOGE("%d:%s cannot resume input stream"
+                      , __LINE__, __func__);
+            break;
+        case QAHW_STREAM_INPUT_OUTPUT:
+            if (stream->out_stream)
+                rc = qahw_out_resume(stream->out_stream);
+            else
+                ALOGE("%d:%s out stream invalid, cannot put in resume"
+                      , __LINE__, __func__);
+            break;
+        }
+    } else
+        ALOGE("%d:%s invalid stream handle, resume failed"
+              , __LINE__, __func__);
+    return rc;
+}
+
+int qahw_stream_flush(qahw_stream_handle_t *stream_handle) {
+    int rc = -EINVAL;
+    qahw_api_stream_t *stream = (qahw_api_stream_t *)stream_handle;
+    if (stream) {
+        switch (stream->dir) {
+        case QAHW_STREAM_OUTPUT:
+            if (stream->out_stream)
+                rc = qahw_out_flush(stream->out_stream);
+            else
+                ALOGE("%d:%s out stream invalid, cannot flush"
+                      , __LINE__, __func__);
+        case QAHW_STREAM_INPUT:
+                ALOGE("%d:%s cannot flush input stream"
+                      , __LINE__, __func__);
+        case QAHW_STREAM_INPUT_OUTPUT:
+            if (stream->out_stream)
+                rc = qahw_out_flush(stream->out_stream);
+            else
+                ALOGE("%d:%s out stream invalid, cannot flush"
+                      , __LINE__, __func__);
+        }
+    } else
+        ALOGE("%d:%s invalid stream handle, flush failed"
+              , __LINE__, __func__);
+    return rc;
+}
+
+int32_t qahw_stream_drain(qahw_stream_handle_t *stream_handle,
+                          qahw_drain_type_t type) {
+    int rc = -EINVAL;
+    qahw_api_stream_t *stream = (qahw_api_stream_t *)stream_handle;
+    if (stream) {
+        switch (stream->dir) {
+        case QAHW_STREAM_OUTPUT:
+            if (stream->out_stream)
+                rc = qahw_out_drain(stream->out_stream, type);
+            else
+                ALOGE("%d:%s out stream invalid, cannot drain"
+                      , __LINE__, __func__);
+        case QAHW_STREAM_INPUT:
+                ALOGE("%d:%s cannot drain input stream"
+                      , __LINE__, __func__);
+        case QAHW_STREAM_INPUT_OUTPUT:
+            if (stream->out_stream)
+                rc = qahw_out_drain(stream->out_stream, type);
+            else
+                ALOGE("%d:%s out stream invalid, cannot drain"
+                      , __LINE__, __func__);
+        }
+    } else
+        ALOGE("%d:%s invalid stream handle, drain failed"
+              , __LINE__, __func__);
+    return rc;
+}
+
+int32_t qahw_stream_get_buffer_size(const qahw_stream_handle_t *stream_handle,
+                                   size_t *in_buffer, size_t *out_buffer) {
+    int32_t rc = 0;
+    qahw_api_stream_t *stream = (qahw_api_stream_t *)stream_handle;
+    if (stream) {
+        switch (stream->dir) {
+        case QAHW_STREAM_OUTPUT:
+            if (stream->out_stream)
+                *out_buffer = qahw_out_get_buffer_size(stream->out_stream);
+            else {
+                ALOGE("%d:%s out stream invalid, cannot get size"
+                      , __LINE__, __func__);
+                rc = -EINVAL;
+            }
+        case QAHW_STREAM_INPUT:
+            if (stream->in_stream)
+                *in_buffer = qahw_in_get_buffer_size(stream->in_stream);
+            else {
+                ALOGE("%d:%s in stream invalid, cannot get size"
+                      , __LINE__, __func__);
+                rc = -EINVAL;
+            }
+        case QAHW_STREAM_INPUT_OUTPUT:
+            if (stream->out_stream)
+                *out_buffer = qahw_out_get_buffer_size(stream->out_stream);
+            else {
+                ALOGE("%d:%s out stream invalid, cannot get size"
+                      , __LINE__, __func__);
+                rc = -EINVAL;
+            }
+            if (stream->in_stream)
+                *in_buffer = qahw_in_get_buffer_size(stream->in_stream);
+            else {
+                ALOGE("%d:%s in stream invalid, cannot get size"
+                      , __LINE__, __func__);
+                rc = -EINVAL;
+            }
+        }
+    } else {
+        ALOGE("%d:%s invalid stream handle, get size failed failed"
+              , __LINE__, __func__);
+        rc = -EINVAL;
+    }
+    return rc;
+}
+
+int32_t qahw_stream_set_buffer_size(const qahw_stream_handle_t *stream_handle,
+                                   size_t in_buffer, size_t out_buffer){
+    return -ENOTSUP;
+}
+
+int32_t qahw_stream_set_dtmf_gen_params(qahw_api_stream_t *stream,
+                                      struct qahw_dtmf_gen_params *dtmf_params){
+    int32_t rc = -EINVAL;
+    char kv[QAHW_KV_PAIR_LENGTH];
+
+    if(stream->type == QAHW_VOICE_CALL) {
+        if(dtmf_params->enable) {
+            snprintf(kv, QAHW_KV_PAIR_LENGTH,
+                     "dtmf_low_freq=%d;dtmf_high_freq=%d;dtmf_tone_gain=%d",
+                     dtmf_params->low_freq,
+                     dtmf_params->high_freq,
+                     dtmf_params->gain);
+           ALOGV("%d:%s kv set is %s", __LINE__, __func__, kv);
+        } else
+            snprintf(kv, QAHW_KV_PAIR_LENGTH, "dtmf_tone_off");
+        rc = qahw_out_set_parameters(stream->out_stream,kv);
+    } else
+        ALOGE("%d:%s cannot set dtmf on non voice stream", __LINE__, __func__);
+    return rc;
+}
+
+int32_t qahw_stream_set_tty_mode_params(qahw_api_stream_t *stream,
+                                       struct qahw_tty_params *tty_params){
+    int32_t rc = -EINVAL;
+
+    if(stream->type == QAHW_VOICE_CALL) {
+        if(tty_params->mode >= QAHW_TTY_MODE_MAX) {
+            ALOGE("%d:%s invalid tty mode", __LINE__, __func__);
+            return rc;
+        }
+
+        ALOGV("%d:%s kv set is %s", __LINE__, __func__,
+              tty_mode_map[tty_params->mode]);
+        /*currently tty is set on the dev */
+        rc = qahw_set_parameters(stream->hw_module,
+                                 tty_mode_map[tty_params->mode]);
+    } else
+        ALOGE("%d:%s cannot set tty mode on non voice stream", __LINE__,
+              __func__);
+    return rc;
+}
+
+int32_t qahw_stream_set_hpcm_params(qahw_api_stream_t *stream,
+                                    struct qahw_hpcm_params *hpcm_params){
+    int32_t rc = -EINVAL;
+    char kv[QAHW_KV_PAIR_LENGTH];
+    int32_t tp;
+
+    if(stream->type == QAHW_VOICE_CALL) {
+        /*if rx and tx call both mixer commands */
+        if(hpcm_params->tap_point == QAHW_HPCM_TAP_POINT_RX_TX) {
+            snprintf(kv, QAHW_KV_PAIR_LENGTH,
+                     "hpcm_tp=%d;hpcm_dir=%d",
+                     QAHW_HPCM_TAP_POINT_RX,
+                     hpcm_params->direction);
+            ALOGV("%d:%s kv set is %s", __LINE__, __func__, kv);
+            rc = qahw_out_set_parameters(stream->out_stream, kv);
+            if(rc) {
+                ALOGE("%d:%s failed to set hpcm on RX Path", __LINE__,
+                __func__);
+            }
+            snprintf(kv, QAHW_KV_PAIR_LENGTH,
+                     "hpcm_tp=%d;hpcm_dir=%d",
+                     QAHW_HPCM_TAP_POINT_TX,
+                     hpcm_params->direction);
+            ALOGV("%d:%s kv set is %s", __LINE__, __func__, kv);
+            rc = qahw_out_set_parameters(stream->out_stream, kv);
+            if(rc) {
+                ALOGE("%d:%s failed to set hpcm on TX Path", __LINE__,
+                __func__);
+            }
+        } else {
+            snprintf(kv, QAHW_KV_PAIR_LENGTH,
+                     "hpcm_tp=%d;hpcm_dir=%d",
+                     hpcm_params->tap_point,
+                     hpcm_params->direction);
+            ALOGV("%d:%s kv set is %s", __LINE__, __func__, kv);
+            rc = qahw_out_set_parameters(stream->out_stream, kv);
+            if(rc) {
+                ALOGE("%d:%s failed to set hpcm params", __LINE__,
+                __func__);
+            }
+        }
+    } else
+        ALOGE("%d:%s cannot set hpcm params on non voice stream",
+              __LINE__, __func__);
+    return rc;
+}
+
+int32_t qahw_stream_set_parameters(qahw_stream_handle_t *stream_handle,
+                                   uint32_t param_id,
+                                   qahw_param_payload *param_payload) {
+    int32_t rc = -EINVAL;
+    qahw_api_stream_t *stream = (qahw_api_stream_t *)stream_handle;
+
+    if(stream && param_payload) {
+        switch(param_id){
+            case QAHW_PARAM_DTMF_GEN:
+                rc = qahw_stream_set_dtmf_gen_params(stream,
+                                               &param_payload->dtmf_gen_params);
+                break;
+            case QAHW_PARAM_TTY_MODE:
+                rc = qahw_stream_set_tty_mode_params(stream,
+                                               &param_payload->tty_mode_params);
+                break;
+            case QAHW_PARAM_HPCM:
+                rc = qahw_stream_set_hpcm_params(stream,
+                                                 &param_payload->hpcm_params);
+                break;
+            default:
+            ALOGE("%d:%s unsupported param id %d"
+                  ,__LINE__, __func__, param_id);
+            break;
+        }
+    } else
+        ALOGE("%d:%s invalid stream handle, cannot set param"
+              , __LINE__, __func__);
+    return rc;
+}
+
+int32_t qahw_stream_get_parameters(qahw_stream_handle_t *stream_handle,
+                                   uint32_t param_id,
+                                   qahw_param_payload *param_payload) {
+    ALOGE("%s is an unsupported api", __func__);
+    return -ENOTSUP;
+}
+#else
+int qahw_stream_open(qahw_module_handle_t *hw_module,
+                     struct qahw_stream_attributes attr,
+                     uint32_t num_of_devices,
+                     qahw_device_t *devices,
+                     uint32_t no_of_modifiers,
+                     struct qahw_modifier_kv *modifiers,
+                     qahw_stream_callback_t cb,
+                     void *cookie,
+                     qahw_stream_handle_t **stream_handle){
+    ALOGE("%s is an unsupported api", __func__);
+    return -ENOTSUP;
+}
+
+int qahw_stream_close(qahw_stream_handle_t *stream_handle){
+    ALOGE("%s is an unsupported api", __func__);
+    return -ENOTSUP;
+}
+
+int qahw_stream_start(qahw_stream_handle_t *stream_handle){
+    ALOGE("%s is an unsupported api", __func__);
+    return -ENOTSUP;
+}
+
+int qahw_stream_stop(qahw_stream_handle_t *stream_handle){
+    ALOGE("%s is an unsupported api", __func__);
+    return -ENOTSUP;
+}
+
+int qahw_stream_set_device(qahw_stream_handle_t *stream_handle,
+                           uint32_t num_of_dev,
+                    qahw_device_t *devices){
+    ALOGE("%s is an unsupported api", __func__);
+    return -ENOTSUP;
+}
+
+int qahw_stream_get_device(qahw_stream_handle_t *stream_handle,
+                           uint32_t *num_of_dev,
+                           qahw_device_t **devices){
+    ALOGE("%s is an unsupported api", __func__);
+    return -ENOTSUP;
+}
+
+int qahw_stream_set_volume(qahw_stream_handle_t *stream_handle,
+                           struct qahw_volume_data vol_data){
+    ALOGE("%s is an unsupported api", __func__);
+    return -ENOTSUP;
+}
+
+int qahw_stream_get_volume(qahw_stream_handle_t *stream_handle,
+                           struct qahw_volume_data **vol_data){
+    ALOGE("%s is an unsupported api", __func__);
+    return -ENOTSUP;
+}
+
+int qahw_stream_set_mute(qahw_stream_handle_t *stream_handle,
+                         struct qahw_mute_data mute_data){
+    ALOGE("%s is an unsupported api", __func__);
+    return -ENOTSUP;
+}
+
+int qahw_stream_get_mute(qahw_stream_handle_t *stream_handle,
+                         struct qahw_mute_data *mute_data){
+    ALOGE("%s is an unsupported api", __func__);
+    return -ENOTSUP;
+}
+
+ssize_t qahw_stream_read(qahw_stream_handle_t *stream_handle,
+                         qahw_buffer_t *in_buf){
+    ALOGE("%s is an unsupported api", __func__);
+    return -ENOTSUP;
+}
+
+ssize_t qahw_stream_write(qahw_stream_handle_t *stream_handle,
+                          qahw_buffer_t *out_buf){
+    ALOGE("%s is an unsupported api", __func__);
+    return -ENOTSUP;
+}
+
+int32_t qahw_stream_pause(qahw_stream_handle_t *stream_handle){
+    ALOGE("%s is an unsupported api", __func__);
+    return -ENOTSUP;
+}
+
+int32_t qahw_stream_standby(qahw_stream_handle_t *stream_handle){
+    ALOGE("%s is an unsupported api", __func__);
+    return -ENOTSUP;
+}
+
+int32_t qahw_stream_resume(qahw_stream_handle_t *stream_handle){
+    ALOGE("%s is an unsupported api", __func__);
+    return -ENOTSUP;
+}
+
+int32_t qahw_stream_flush(qahw_stream_handle_t *stream_handle){
+    ALOGE("%s is an unsupported api", __func__);
+    return -ENOTSUP;
+}
+
+int32_t qahw_stream_drain(qahw_stream_handle_t *stream_handle,
+                          qahw_drain_type_t type){
+    ALOGE("%s is an unsupported api", __func__);
+    return -ENOTSUP;
+}
+
+int32_t qahw_stream_get_buffer_size(const qahw_stream_handle_t *stream_handle,
+                                    size_t *in_buffer, size_t *out_buffer){
+    ALOGE("%s is an unsupported api", __func__);
+    return -ENOTSUP;
+}
+
+int32_t qahw_stream_set_buffer_size(const qahw_stream_handle_t *stream_handle,
+                                    size_t in_buffer, size_t out_buffer){
+    ALOGE("%s is an unsupported api", __func__);
+    return -ENOTSUP;
+}
+
+int32_t qahw_stream_set_parameters(qahw_stream_handle_t *stream_handle,
+                              uint32_t param_id,
+                              qahw_param_payload *param_payload){
+    ALOGE("%s is an unsupported api", __func__);
+    return -ENOTSUP;
+}
+
+int32_t qahw_stream_get_parameters(qahw_stream_handle_t *stream_handle,
+                              uint32_t param_id,
+                              qahw_param_payload *param_payload){
+    ALOGE("%s is an unsupported api", __func__);
+    return -ENOTSUP;
+}
+#endif
+
 #endif