14b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava/*
2a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta * Copyright (C) 2014-2016 The Android Open Source Project
34b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava *
44b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava * Licensed under the Apache License, Version 2.0 (the "License");
54b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava * you may not use this file except in compliance with the License.
64b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava * You may obtain a copy of the License at
74b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava *
84b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava *      http://www.apache.org/licenses/LICENSE-2.0
94b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava *
104b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava * Unless required by applicable law or agreed to in writing, software
114b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava * distributed under the License is distributed on an "AS IS" BASIS,
124b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava * See the License for the specific language governing permissions and
144b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava * limitations under the License.
154b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava */
164b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
174b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#define LOG_TAG "voice_extn"
184b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava/*#define LOG_NDEBUG 0*/
194b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#define LOG_NDDEBUG 0
204b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
214b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#include <errno.h>
224b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#include <math.h>
2337a7699e96b3a4433e80b3899230809976d5e14bGlenn Kasten#include <stdlib.h>
24adecf116d67af03d71d63a602978fca45e5a5b6aJiyong Park#include <log/log.h>
254b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#include <cutils/str_parms.h>
264b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#include <sys/ioctl.h>
274b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#include <sound/voice_params.h>
284b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
294b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#include "audio_hw.h"
304b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#include "voice.h"
314b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#include "platform.h"
324b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#include "platform_api.h"
334b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#include "voice_extn.h"
344b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
354b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#define AUDIO_PARAMETER_KEY_VSID                "vsid"
364b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#define AUDIO_PARAMETER_KEY_CALL_STATE          "call_state"
374b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#define AUDIO_PARAMETER_KEY_AUDIO_MODE          "audio_mode"
384b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#define AUDIO_PARAMETER_KEY_ALL_CALL_STATES     "all_call_states"
394b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#define AUDIO_PARAMETER_KEY_DEVICE_MUTE         "device_mute"
404b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#define AUDIO_PARAMETER_KEY_DIRECTION           "direction"
414b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
424b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#define VOICE_EXTN_PARAMETER_VALUE_MAX_LEN 256
434b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
44a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta#define VOICE2_VSID              0x10DC1000
45a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta#define VOLTE_VSID               0x10C02000
46a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta#define QCHAT_VSID               0x10803000
47a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta#define VOWLAN_VSID              0x10002000
48a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta#define VOICEMMODE1_VSID         0x11C05000
49a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta#define VOICEMMODE2_VSID         0x11DC5000
50a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta#define ALL_VSID                 0xFFFFFFFF
514b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
524b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava/* Voice Session Indices */
534b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#define VOICE2_SESS_IDX    (VOICE_SESS_IDX + 1)
544b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#define VOLTE_SESS_IDX     (VOICE_SESS_IDX + 2)
554b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#define QCHAT_SESS_IDX     (VOICE_SESS_IDX + 3)
564b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#define VOWLAN_SESS_IDX    (VOICE_SESS_IDX + 4)
57a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta#define MMODE1_SESS_IDX    (VOICE_SESS_IDX + 5)
58a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta#define MMODE2_SESS_IDX    (VOICE_SESS_IDX + 6)
594b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
604b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava/* Call States */
614b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#define CALL_HOLD           (BASE_CALL_STATE + 2)
624b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#define CALL_LOCAL_HOLD     (BASE_CALL_STATE + 3)
634b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
644b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavastruct pcm_config pcm_config_incall_music = {
654b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    .channels = 1,
664b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    .rate = DEFAULT_OUTPUT_SAMPLING_RATE,
674b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    .period_size = LOW_LATENCY_OUTPUT_PERIOD_SIZE,
684b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    .period_count = LOW_LATENCY_OUTPUT_PERIOD_COUNT,
694b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    .format = PCM_FORMAT_S16_LE,
704b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    .start_threshold = LOW_LATENCY_OUTPUT_PERIOD_SIZE / 4,
714b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    .stop_threshold = INT_MAX,
724b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    .avail_min = LOW_LATENCY_OUTPUT_PERIOD_SIZE / 4,
734b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava};
744b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
75f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamandaint voice_extn_is_call_state_active(struct audio_device *adev, bool *is_call_active);
764b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
774b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavastatic bool is_valid_call_state(int call_state)
784b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
794b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if (call_state < CALL_INACTIVE || call_state > CALL_LOCAL_HOLD)
804b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        return false;
814b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    else
824b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        return true;
834b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
844b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
854b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavastatic bool is_valid_vsid(uint32_t vsid)
864b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
874b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if (vsid == VOICE_VSID ||
884b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        vsid == VOICE2_VSID ||
894b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        vsid == VOLTE_VSID ||
904b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        vsid == QCHAT_VSID ||
91a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta        vsid == VOICEMMODE1_VSID ||
92a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta        vsid == VOICEMMODE2_VSID ||
934b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        vsid == VOWLAN_VSID)
944b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        return true;
954b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    else
964b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        return false;
974b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
984b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
994b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavastatic audio_usecase_t voice_extn_get_usecase_for_session_idx(const int index)
1004b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
1014b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    audio_usecase_t usecase_id = -1;
1024b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1034b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    switch(index) {
1044b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    case VOICE_SESS_IDX:
1054b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        usecase_id = USECASE_VOICE_CALL;
1064b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        break;
1074b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1084b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    case VOICE2_SESS_IDX:
1094b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        usecase_id = USECASE_VOICE2_CALL;
1104b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        break;
1114b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1124b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    case VOLTE_SESS_IDX:
1134b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        usecase_id = USECASE_VOLTE_CALL;
1144b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        break;
1154b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1164b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    case QCHAT_SESS_IDX:
1174b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        usecase_id = USECASE_QCHAT_CALL;
1184b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        break;
1194b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1204b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    case VOWLAN_SESS_IDX:
1214b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        usecase_id = USECASE_VOWLAN_CALL;
1224b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        break;
1234b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
124a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta    case MMODE1_SESS_IDX:
125a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta        usecase_id = USECASE_VOICEMMODE1_CALL;
126a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta        break;
127a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta
128a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta    case MMODE2_SESS_IDX:
129a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta        usecase_id = USECASE_VOICEMMODE2_CALL;
130a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta        break;
131a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta
1324b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    default:
1334b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        ALOGE("%s: Invalid voice session index\n", __func__);
1344b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
1354b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1364b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return usecase_id;
1374b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
1384b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1394b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavastatic uint32_t get_session_id_with_state(struct audio_device *adev,
1404b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                                          int call_state)
1414b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
1424b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    struct voice_session *session = NULL;
1434b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int i = 0;
1444b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    uint32_t session_id = 0;
1454b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1464b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
1474b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        session = &adev->voice.session[i];
1484b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        if(session->state.current == call_state){
1494b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            session_id = session->vsid;
1504b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            break;
1514b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        }
1524b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
1534b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1544b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return session_id;
1554b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
1564b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1574b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavastatic int update_calls(struct audio_device *adev)
1584b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
1594b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int i = 0;
1604b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    audio_usecase_t usecase_id = 0;
1614b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    enum voice_lch_mode lch_mode;
1624b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    struct voice_session *session = NULL;
1634b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int fd = 0;
1644b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int ret = 0;
1654b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1664b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ALOGD("%s: enter:", __func__);
1674b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1684b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
1694b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        usecase_id = voice_extn_get_usecase_for_session_idx(i);
1704b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        session = &adev->voice.session[i];
1714b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        ALOGD("%s: cur_state=%d new_state=%d vsid=%x",
1724b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava              __func__, session->state.current, session->state.new, session->vsid);
1734b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1744b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        switch(session->state.new)
1754b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        {
1764b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        case CALL_ACTIVE:
1774b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            switch(session->state.current)
1784b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            {
1794b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            case CALL_INACTIVE:
1804b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                ALOGD("%s: INACTIVE -> ACTIVE vsid:%x", __func__, session->vsid);
18108dbcfc116e62f5b4007cade7311430ea235a09eRavi Kumar Alamanda                ret = voice_start_usecase(adev, usecase_id);
1824b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                if(ret < 0) {
18308dbcfc116e62f5b4007cade7311430ea235a09eRavi Kumar Alamanda                    ALOGE("%s: voice_start_usecase() failed for usecase: %d\n",
1844b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                          __func__, usecase_id);
1854b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                } else {
1864b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                    session->state.current = session->state.new;
1874b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                }
1884b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                break;
1894b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1904b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            case CALL_HOLD:
1914b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                ALOGD("%s: HOLD -> ACTIVE vsid:%x", __func__, session->vsid);
1924b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                session->state.current = session->state.new;
1934b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                break;
1944b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1954b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            case CALL_LOCAL_HOLD:
1964b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                ALOGD("%s: LOCAL_HOLD -> ACTIVE vsid:%x", __func__, session->vsid);
1974b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                lch_mode = VOICE_LCH_STOP;
1984b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                if (pcm_ioctl(session->pcm_tx, SNDRV_VOICE_IOCTL_LCH, &lch_mode) < 0) {
1994b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                    ALOGE("LOCAL_HOLD -> ACTIVE failed");
2004b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                } else {
2014b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                    session->state.current = session->state.new;
2024b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                }
2034b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                break;
2044b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
2054b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            default:
2064b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                ALOGV("%s: CALL_ACTIVE cannot be handled in state=%d vsid:%x",
2074b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                      __func__, session->state.current, session->vsid);
2084b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                break;
2094b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            }
2104b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            break;
2114b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
2124b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        case CALL_INACTIVE:
2134b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            switch(session->state.current)
2144b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            {
2154b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            case CALL_ACTIVE:
2164b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            case CALL_HOLD:
2174b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            case CALL_LOCAL_HOLD:
2184b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                ALOGD("%s: ACTIVE/HOLD/LOCAL_HOLD -> INACTIVE vsid:%x", __func__, session->vsid);
21908dbcfc116e62f5b4007cade7311430ea235a09eRavi Kumar Alamanda                ret = voice_stop_usecase(adev, usecase_id);
2204b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                if(ret < 0) {
22108dbcfc116e62f5b4007cade7311430ea235a09eRavi Kumar Alamanda                    ALOGE("%s: voice_stop_usecase() failed for usecase: %d\n",
2224b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                          __func__, usecase_id);
2234b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                } else {
2244b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                    session->state.current = session->state.new;
2254b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                }
2264b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                break;
2274b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
2284b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            default:
2294b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                ALOGV("%s: CALL_INACTIVE cannot be handled in state=%d vsid:%x",
2304b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                      __func__, session->state.current, session->vsid);
2314b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                break;
2324b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            }
2334b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            break;
2344b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
2354b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        case CALL_HOLD:
2364b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            switch(session->state.current)
2374b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            {
2384b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            case CALL_ACTIVE:
2394b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                ALOGD("%s: CALL_ACTIVE -> HOLD vsid:%x", __func__, session->vsid);
2404b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                session->state.current = session->state.new;
2414b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                break;
2424b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
2434b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            case CALL_LOCAL_HOLD:
2444b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                ALOGD("%s: CALL_LOCAL_HOLD -> HOLD vsid:%x", __func__, session->vsid);
2454b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                lch_mode = VOICE_LCH_STOP;
2464b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                if (pcm_ioctl(session->pcm_tx, SNDRV_VOICE_IOCTL_LCH, &lch_mode) < 0) {
2474b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                    ALOGE("LOCAL_HOLD -> HOLD failed");
2484b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                } else {
2494b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                    session->state.current = session->state.new;
2504b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                }
2514b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                break;
2524b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
2534b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            default:
2544b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                ALOGV("%s: CALL_HOLD cannot be handled in state=%d vsid:%x",
2554b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                      __func__, session->state.current, session->vsid);
2564b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                break;
2574b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            }
2584b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            break;
2594b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
2604b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        case CALL_LOCAL_HOLD:
2614b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            switch(session->state.current)
2624b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            {
2634b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            case CALL_ACTIVE:
2644b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            case CALL_HOLD:
2654b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                ALOGD("%s: ACTIVE/CALL_HOLD -> LOCAL_HOLD vsid:%x", __func__,
2664b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                      session->vsid);
2674b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                lch_mode = VOICE_LCH_START;
2684b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                if (pcm_ioctl(session->pcm_tx, SNDRV_VOICE_IOCTL_LCH, &lch_mode) < 0) {
2694b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                    ALOGE("LOCAL_HOLD -> HOLD failed");
2704b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                } else {
2714b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                    session->state.current = session->state.new;
2724b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                }
2734b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                break;
2744b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
2754b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            default:
2764b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                ALOGV("%s: CALL_LOCAL_HOLD cannot be handled in state=%d vsid:%x",
2774b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                      __func__, session->state.current, session->vsid);
2784b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                break;
2794b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            }
2804b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            break;
2814b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
2824b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        default:
2834b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            break;
2844b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        } //end out switch loop
2854b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    } //end for loop
2864b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
2874b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return ret;
2884b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
2894b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
2904b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavastatic int update_call_states(struct audio_device *adev,
2914b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                                    const uint32_t vsid, const int call_state)
2924b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
2934b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    struct voice_session *session = NULL;
2944b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int i = 0;
295f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamanda    bool is_call_active;
2964b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
2974b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
2984b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        if (vsid == adev->voice.session[i].vsid) {
2994b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            session = &adev->voice.session[i];
3004b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            break;
3014b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        }
3024b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
3034b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3044b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if (session) {
3054b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        session->state.new = call_state;
306f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamanda        voice_extn_is_call_state_active(adev, &is_call_active);
307f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamanda        ALOGD("%s is_call_active:%d in_call:%d, mode:%d\n",
308f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamanda              __func__, is_call_active, adev->voice.in_call, adev->mode);
3094b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        /* Dont start voice call before device routing for voice usescases has
3104b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava         * occured, otherwise voice calls will be started unintendedly on
3114b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava         * speaker.
3124b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava         */
31336886fcdc57683b8a3d08edc59fa5a8e8f5f461aRavi Kumar Alamanda        if (is_call_active ||
31436886fcdc57683b8a3d08edc59fa5a8e8f5f461aRavi Kumar Alamanda                (adev->voice.in_call && adev->mode == AUDIO_MODE_IN_CALL)) {
3154b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            /* Device routing is not triggered for voice calls on the subsequent
3164b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava             * subs, Hence update the call states if voice call is already
3174b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava             * active on other sub.
3184b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava             */
3194b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            update_calls(adev);
3204b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        }
3214b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    } else {
3224b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        return -EINVAL;
3234b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
3244b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3254b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return 0;
3264b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3274b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
3284b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3294b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavaint voice_extn_get_active_session_id(struct audio_device *adev,
3304b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                                     uint32_t *session_id)
3314b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
3324b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    *session_id = get_session_id_with_state(adev, CALL_ACTIVE);
3334b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return 0;
3344b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
3354b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
336f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamandaint voice_extn_is_call_state_active(struct audio_device *adev, bool *is_call_active)
3374b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
3384b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    struct voice_session *session = NULL;
3394b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int i = 0;
340f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamanda    *is_call_active = false;
3414b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3424b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
3434b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        session = &adev->voice.session[i];
3444b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        if(session->state.current != CALL_INACTIVE){
345f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamanda            *is_call_active = true;
3464b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            break;
3474b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        }
3484b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
3494b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3504b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return 0;
3514b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
3524b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3534b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavaint voice_extn_is_in_call_rec_stream(struct stream_in *in, bool *in_call_rec)
3544b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
3554b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    *in_call_rec = false;
3564b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3574b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if(in->source == AUDIO_SOURCE_VOICE_DOWNLINK ||
3584b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava       in->source == AUDIO_SOURCE_VOICE_UPLINK ||
3594b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava       in->source == AUDIO_SOURCE_VOICE_CALL) {
3604b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava       *in_call_rec = true;
3614b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
3624b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3634b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return 0;
3644b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
3654b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3664b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavavoid voice_extn_init(struct audio_device *adev)
3674b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
3684b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    adev->voice.session[VOICE_SESS_IDX].vsid =  VOICE_VSID;
3694b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    adev->voice.session[VOICE2_SESS_IDX].vsid = VOICE2_VSID;
3704b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    adev->voice.session[VOLTE_SESS_IDX].vsid =  VOLTE_VSID;
3714b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    adev->voice.session[QCHAT_SESS_IDX].vsid =  QCHAT_VSID;
3724b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    adev->voice.session[VOWLAN_SESS_IDX].vsid = VOWLAN_VSID;
373a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta    adev->voice.session[MMODE1_SESS_IDX].vsid = VOICEMMODE1_VSID;
374a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta    adev->voice.session[MMODE2_SESS_IDX].vsid = VOICEMMODE2_VSID;
3754b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
3764b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3774b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavaint voice_extn_get_session_from_use_case(struct audio_device *adev,
3784b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                                         const audio_usecase_t usecase_id,
3794b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                                         struct voice_session **session)
3804b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
3814b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3824b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    switch(usecase_id)
3834b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    {
3844b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    case USECASE_VOICE_CALL:
3854b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        *session = &adev->voice.session[VOICE_SESS_IDX];
3864b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        break;
3874b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3884b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    case USECASE_VOICE2_CALL:
3894b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        *session = &adev->voice.session[VOICE2_SESS_IDX];
3904b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        break;
3914b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3924b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    case USECASE_VOLTE_CALL:
3934b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        *session = &adev->voice.session[VOLTE_SESS_IDX];
3944b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        break;
3954b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3964b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    case USECASE_QCHAT_CALL:
3974b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        *session = &adev->voice.session[QCHAT_SESS_IDX];
3984b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        break;
3994b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4004b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    case USECASE_VOWLAN_CALL:
4014b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        *session = &adev->voice.session[VOWLAN_SESS_IDX];
4024b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        break;
4034b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
404a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta    case USECASE_VOICEMMODE1_CALL:
405a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta        *session = &adev->voice.session[MMODE1_SESS_IDX];
406a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta        break;
407a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta
408a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta    case USECASE_VOICEMMODE2_CALL:
409a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta        *session = &adev->voice.session[MMODE2_SESS_IDX];
410a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta        break;
411a51fd4083112343fddcc294f850f2d5456f24fd4vivek mehta
4124b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    default:
4134b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        ALOGE("%s: Invalid usecase_id:%d\n", __func__, usecase_id);
4144b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        *session = NULL;
4154b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        return -EINVAL;
4164b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
4174b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4184b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return 0;
4194b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
4204b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4214b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavaint voice_extn_start_call(struct audio_device *adev)
4224b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
4234b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    /* Start voice calls on sessions whose call state has been
4244b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava     * udpated.
4254b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava     */
4264b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ALOGV("%s: enter:", __func__);
4274b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return update_calls(adev);
4284b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
4294b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4304b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavaint voice_extn_stop_call(struct audio_device *adev)
4314b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
4324b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int i;
4334b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int ret = 0;
4344b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4354b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ALOGV("%s: enter:", __func__);
4364b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4374b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    /* If BT device is enabled and voice calls are ended, telephony will call
4384b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava     * set_mode(AUDIO_MODE_NORMAL) which will trigger audio policy manager to
4394b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava     * set routing with device BT A2DP profile. Hence end all voice calls when
4404b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava     * set_mode(AUDIO_MODE_NORMAL) before BT A2DP profile is selected.
4414b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava     */
4424b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if (adev->mode == AUDIO_MODE_NORMAL) {
4434b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        ALOGD("%s: end all calls", __func__);
4444b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
4454b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            adev->voice.session[i].state.new = CALL_INACTIVE;
4464b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        }
4474b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4484b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        ret = update_calls(adev);
4494b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
4504b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4514b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return ret;
4524b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
4534b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4544b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavaint voice_extn_set_parameters(struct audio_device *adev,
4554b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                              struct str_parms *parms)
4564b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
4574b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    char *str;
4584b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int value;
4594b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int ret = 0, err;
4604b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    char *kv_pairs = str_parms_to_str(parms);
4614b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    char str_value[256] = {0};
4624b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4634b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ALOGV_IF(kv_pairs != NULL, "%s: enter: %s", __func__, kv_pairs);
4644b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4654b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    err = str_parms_get_int(parms, AUDIO_PARAMETER_KEY_VSID, &value);
4664b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if (err >= 0) {
4674b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        str_parms_del(parms, AUDIO_PARAMETER_KEY_VSID);
4684b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        uint32_t vsid = value;
4694b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        int call_state = -1;
4704b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        err = str_parms_get_int(parms, AUDIO_PARAMETER_KEY_CALL_STATE, &value);
4714b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        if (err >= 0) {
4724b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            call_state = value;
473f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamanda            str_parms_del(parms, AUDIO_PARAMETER_KEY_CALL_STATE);
4744b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        } else {
4754b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            ALOGE("%s: call_state key not found", __func__);
4764b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            ret = -EINVAL;
4774b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            goto done;
4784b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        }
4794b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4804b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        if (is_valid_vsid(vsid) && is_valid_call_state(call_state)) {
4814b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            ret = update_call_states(adev, vsid, call_state);
4824b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        } else {
4834b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            ALOGE("%s: invalid vsid:%x or call_state:%d",
4844b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                  __func__, vsid, call_state);
4854b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            ret = -EINVAL;
4864b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            goto done;
4874b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        }
4884b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
4894b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4904b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_DEVICE_MUTE, str_value,
4914b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                            sizeof(str_value));
4924b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if (err >= 0) {
4934b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        str_parms_del(parms, AUDIO_PARAMETER_KEY_DEVICE_MUTE);
4944b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        bool mute = false;
4954b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4964b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        if (!strncmp("true", str_value, sizeof("true"))) {
4974b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            mute = true;
4984b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        }
4994b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
5004b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_DIRECTION, str_value,
5014b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                                sizeof(str_value));
5024b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        if (err >= 0) {
5034b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            str_parms_del(parms, AUDIO_PARAMETER_KEY_DIRECTION);
5044b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        } else {
5054b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            ALOGE("%s: direction key not found", __func__);
5064b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            ret = -EINVAL;
5074b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            goto done;
5084b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        }
5094b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
5104b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        ret = platform_set_device_mute(adev->platform, mute, str_value);
5114b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        if (ret != 0) {
5124b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            ALOGE("%s: Failed to set mute err:%d", __func__, ret);
5134b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            ret = -EINVAL;
5144b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            goto done;
5154b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        }
5164b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
5174b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
5184b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavadone:
5194b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ALOGV("%s: exit with code(%d)", __func__, ret);
5204b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    free(kv_pairs);
5214b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return ret;
5224b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
5234b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
5244b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavastatic int get_all_call_states_str(const struct audio_device *adev,
5254b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                            char *value)
5264b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
5274b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int ret = 0;
5284b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    char *cur_ptr = value;
5294b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int i, len=0;
5304b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
5314b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
5324b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        snprintf(cur_ptr, VOICE_EXTN_PARAMETER_VALUE_MAX_LEN - len,
5334b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                 "%d:%d,",adev->voice.session[i].vsid,
5344b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                 adev->voice.session[i].state.current);
5354b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        len = strlen(cur_ptr);
5364b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        cur_ptr = cur_ptr + len;
5374b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
5384b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ALOGV("%s:value=%s", __func__, value);
5394b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return ret;
5404b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
5414b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
5424b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavavoid voice_extn_get_parameters(const struct audio_device *adev,
5434b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                               struct str_parms *query,
5444b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                               struct str_parms *reply)
5454b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
5464b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int ret;
5474b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    char value[VOICE_EXTN_PARAMETER_VALUE_MAX_LEN] = {0};
5484b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    char *str = str_parms_to_str(query);
5494b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
5504b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ALOGV_IF(str != NULL, "%s: enter %s", __func__, str);
5514b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    free(str);
5524b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
5534b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_AUDIO_MODE, value,
5544b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                            sizeof(value));
5554b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if (ret >= 0) {
5564b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        str_parms_add_int(reply, AUDIO_PARAMETER_KEY_AUDIO_MODE, adev->mode);
5574b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
5584b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
5594b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_ALL_CALL_STATES,
5604b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                            value, sizeof(value));
5614b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if (ret >= 0) {
5624b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        ret = get_all_call_states_str(adev, value);
5634b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        if (ret) {
5644b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            ALOGE("%s: Error fetching call states, err:%d", __func__, ret);
5654b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            return;
5664b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        }
5674b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        str_parms_add_str(reply, AUDIO_PARAMETER_KEY_ALL_CALL_STATES, value);
5684b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
5694b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
5704b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    str = str_parms_to_str(reply);
5714b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ALOGV_IF(str != NULL, "%s: exit: returns \"%s\"", __func__, str);
5724b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    free(str);
5734b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
5744b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
5754b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#ifdef INCALL_MUSIC_ENABLED
5764b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavaint voice_extn_check_and_set_incall_music_usecase(struct audio_device *adev,
5774b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                                                  struct stream_out *out)
5784b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
5793d72cfc09b6fd8f20a12e2557097080ad48a365dNadav Bar    out->usecase = USECASE_INCALL_MUSIC_UPLINK;
5804b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    out->config = pcm_config_incall_music;
5813d72cfc09b6fd8f20a12e2557097080ad48a365dNadav Bar    //FIXME: add support for MONO stream configuration when audioflinger mixer supports it
5823d72cfc09b6fd8f20a12e2557097080ad48a365dNadav Bar    out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
5833d72cfc09b6fd8f20a12e2557097080ad48a365dNadav Bar    out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
5843d72cfc09b6fd8f20a12e2557097080ad48a365dNadav Bar    out->config.rate = out->sample_rate;
5854b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
5863d72cfc09b6fd8f20a12e2557097080ad48a365dNadav Bar    ALOGV("%s: mode=%d, usecase id=%d", __func__, adev->mode, out->usecase);
5874b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return 0;
5884b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
5894b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#endif
5904b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
591