14b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava/*
24b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava * Copyright (C) 2014 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"
184b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava/*#define LOG_NDEBUG 0*/
194b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#define LOG_NDDEBUG 0
204b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
217c685a1267affc6f96a26f81164b913cd60a3924Vineeta Srivastava#include <stdlib.h>
224b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#include <errno.h>
234b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#include <math.h>
244b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#include <cutils/log.h>
254b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#include <cutils/str_parms.h>
264b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
274b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#include "audio_hw.h"
284b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#include "voice.h"
294b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#include "voice_extn/voice_extn.h"
304b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#include "platform.h"
314b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava#include "platform_api.h"
324b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
334b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavastruct pcm_config pcm_config_voice_call = {
344b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    .channels = 1,
354b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    .rate = 8000,
364b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    .period_size = 160,
374b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    .period_count = 2,
384b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    .format = PCM_FORMAT_S16_LE,
394b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava};
404b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
414b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavastatic struct voice_session *voice_get_session_from_use_case(struct audio_device *adev,
424b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                              audio_usecase_t usecase_id)
434b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
444b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    struct voice_session *session = NULL;
454b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int ret = 0;
464b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
474b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ret = voice_extn_get_session_from_use_case(adev, usecase_id, &session);
484b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if (ret == -ENOSYS) {
494b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        session = &adev->voice.session[VOICE_SESS_IDX];
504b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
514b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
524b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return session;
534b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
544b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
55765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehtastatic bool voice_is_sidetone_device(snd_device_t out_device,
56765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta            char *mixer_path)
57765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta{
58765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    bool is_sidetone_dev = true;
59765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta
60765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    switch (out_device) {
61765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    case SND_DEVICE_OUT_VOICE_HAC_HANDSET:
62765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta        strlcpy(mixer_path, "sidetone-hac-handset", MIXER_PATH_MAX_LENGTH);
63765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta        break;
64765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    case SND_DEVICE_OUT_VOICE_HANDSET:
65765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta        strlcpy(mixer_path, "sidetone-handset", MIXER_PATH_MAX_LENGTH);
66765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta        break;
67765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    case SND_DEVICE_OUT_VOICE_HEADPHONES:
68765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta        strlcpy(mixer_path, "sidetone-headphones", MIXER_PATH_MAX_LENGTH);
69765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta        break;
70765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    default:
71765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta        is_sidetone_dev = false;
72765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta        break;
73765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    }
74765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta
75765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    return is_sidetone_dev;
76765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta}
77765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta
78765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehtavoid voice_set_sidetone(struct audio_device *adev,
79765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta        snd_device_t out_snd_device, bool enable)
80765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta{
81765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    char mixer_path[MIXER_PATH_MAX_LENGTH];
82765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    bool is_sidetone_dev;
83765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta
84765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    ALOGD("%s: %s, out_snd_device: %d\n",
85765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta          __func__, (enable ? "enable" : "disable"),
86765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta          out_snd_device);
87765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta
88765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    is_sidetone_dev = voice_is_sidetone_device(out_snd_device, mixer_path);
89765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta
90765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    if (!is_sidetone_dev) {
91765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta        ALOGD("%s: device %d does not support sidetone\n",
92765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta              __func__, out_snd_device);
93765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta        return;
94765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    }
95765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta
96765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    ALOGD("%s: sidetone out device = %s\n",
97765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta          __func__, mixer_path);
98765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta
99765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    if (enable)
100765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta        audio_route_apply_and_update_path(adev->audio_route, mixer_path);
101765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    else
102765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta        audio_route_reset_and_update_path(adev->audio_route, mixer_path);
103765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta
104765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    return;
105765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta}
106765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta
10708dbcfc116e62f5b4007cade7311430ea235a09eRavi Kumar Alamandaint voice_stop_usecase(struct audio_device *adev, audio_usecase_t usecase_id)
1084b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
1094b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int i, ret = 0;
1104b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    struct audio_usecase *uc_info;
1114b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    struct voice_session *session = NULL;
1124b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1134b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ALOGD("%s: enter usecase:%s", __func__, use_case_table[usecase_id]);
1144b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1154b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    session = (struct voice_session *)voice_get_session_from_use_case(adev, usecase_id);
116765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta
117765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    uc_info = get_usecase_from_list(adev, usecase_id);
118765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    if (uc_info == NULL) {
119765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta        ALOGE("%s: Could not find the usecase (%d) in the list",
120765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta              __func__, usecase_id);
121765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta        return -EINVAL;
122765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    }
123765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta
1244b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    session->state.current = CALL_INACTIVE;
1254b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
126765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    /* Disable sidetone only when no calls are active */
127765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    if (!voice_is_call_state_active(adev))
128765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta        voice_set_sidetone(adev, uc_info->out_snd_device, false);
129765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta
1304b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ret = platform_stop_voice_call(adev->platform, session->vsid);
1314b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1324b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    /* 1. Close the PCM devices */
1334b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if (session->pcm_rx) {
1344b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        pcm_close(session->pcm_rx);
1354b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        session->pcm_rx = NULL;
1364b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
1374b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if (session->pcm_tx) {
1384b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        pcm_close(session->pcm_tx);
1394b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        session->pcm_tx = NULL;
1404b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
1414b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1424b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    /* 2. Get and set stream specific mixer controls */
1434b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    disable_audio_route(adev, uc_info);
1444b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1454b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    /* 3. Disable the rx and tx devices */
1464b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    disable_snd_device(adev, uc_info->out_snd_device);
1474b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    disable_snd_device(adev, uc_info->in_snd_device);
1484b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1494b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    list_remove(&uc_info->list);
1504b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    free(uc_info);
1514b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1524b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ALOGD("%s: exit: status(%d)", __func__, ret);
1534b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return ret;
1544b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
1554b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
15675a2e1d2119c21c043362d53208f4c46d8c556a6Eric Laurentint voice_start_usecase(struct audio_device *adev, audio_usecase_t usecase_id)
1574b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
1584b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int i, ret = 0;
1594b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    struct audio_usecase *uc_info;
1604b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int pcm_dev_rx_id, pcm_dev_tx_id;
1614b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    struct voice_session *session = NULL;
1624b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    struct pcm_config voice_config = pcm_config_voice_call;
1634b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1644b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ALOGD("%s: enter usecase:%s", __func__, use_case_table[usecase_id]);
1654b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1664b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    session = (struct voice_session *)voice_get_session_from_use_case(adev, usecase_id);
1674b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
1684b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    uc_info->id = usecase_id;
1694b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    uc_info->type = VOICE_CALL;
17075a2e1d2119c21c043362d53208f4c46d8c556a6Eric Laurent    uc_info->stream.out = adev->current_call_output ;
17175a2e1d2119c21c043362d53208f4c46d8c556a6Eric Laurent    uc_info->devices = adev->current_call_output ->devices;
1724b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    uc_info->in_snd_device = SND_DEVICE_NONE;
1734b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    uc_info->out_snd_device = SND_DEVICE_NONE;
1744b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1754b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    list_add_tail(&adev->usecase_list, &uc_info->list);
1764b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1774b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    select_devices(adev, usecase_id);
1784b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1794b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    pcm_dev_rx_id = platform_get_pcm_device_id(uc_info->id, PCM_PLAYBACK);
1804b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    pcm_dev_tx_id = platform_get_pcm_device_id(uc_info->id, PCM_CAPTURE);
1814b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
1824b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if (pcm_dev_rx_id < 0 || pcm_dev_tx_id < 0) {
1834b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        ALOGE("%s: Invalid PCM devices (rx: %d tx: %d) for the usecase(%d)",
1844b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava              __func__, pcm_dev_rx_id, pcm_dev_tx_id, uc_info->id);
1854b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        ret = -EIO;
1864b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        goto error_start_voice;
1874b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
1884b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
189765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    ALOGV("%s: Opening PCM capture device card_id(%d) device_id(%d)",
190765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta          __func__, adev->snd_card, pcm_dev_tx_id);
191765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    session->pcm_tx = pcm_open(adev->snd_card,
192765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta                               pcm_dev_tx_id,
193765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta                               PCM_IN, &voice_config);
194765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    if (session->pcm_tx && !pcm_is_ready(session->pcm_tx)) {
195765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta        ALOGE("%s: %s", __func__, pcm_get_error(session->pcm_tx));
196765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta        ret = -EIO;
197765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta        goto error_start_voice;
198765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    }
199765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta
2004b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ALOGV("%s: Opening PCM playback device card_id(%d) device_id(%d)",
2014b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava          __func__, adev->snd_card, pcm_dev_rx_id);
2024b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    session->pcm_rx = pcm_open(adev->snd_card,
2034b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                               pcm_dev_rx_id,
2044b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                               PCM_OUT, &voice_config);
2054b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if (session->pcm_rx && !pcm_is_ready(session->pcm_rx)) {
2064b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        ALOGE("%s: %s", __func__, pcm_get_error(session->pcm_rx));
2074b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        ret = -EIO;
2084b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        goto error_start_voice;
2094b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
2104b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
2114b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    pcm_start(session->pcm_tx);
212765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    pcm_start(session->pcm_rx);
213765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta
214765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    /* Enable sidetone only when no calls are already active */
215765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta    if (!voice_is_call_state_active(adev))
216765eb645d3a83949a05eecb9f22a84bd47978c19vivek mehta        voice_set_sidetone(adev, uc_info->out_snd_device, true);
2174b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
2184b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    voice_set_volume(adev, adev->voice.volume);
2194b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
2204b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ret = platform_start_voice_call(adev->platform, session->vsid);
2214b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if (ret < 0) {
2224b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        ALOGE("%s: platform_start_voice_call error %d\n", __func__, ret);
2234b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        goto error_start_voice;
2244b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
2254b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
2264b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    session->state.current = CALL_ACTIVE;
227f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamanda    goto done;
2284b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
2294b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavaerror_start_voice:
23008dbcfc116e62f5b4007cade7311430ea235a09eRavi Kumar Alamanda    voice_stop_usecase(adev, usecase_id);
2314b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
232f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamandadone:
2334b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ALOGD("%s: exit: status(%d)", __func__, ret);
2344b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return ret;
2354b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
2364b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
237f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamandabool voice_is_call_state_active(struct audio_device *adev)
2384b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
239f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamanda    bool call_state = false;
2404b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int ret = 0;
2414b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
242f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamanda    ret = voice_extn_is_call_state_active(adev, &call_state);
2434b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if (ret == -ENOSYS) {
244f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamanda        call_state = (adev->voice.session[VOICE_SESS_IDX].state.current == CALL_ACTIVE) ? true : false;
2454b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
2464b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
247f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamanda    return call_state;
248f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamanda}
249f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamanda
250f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamandabool voice_is_in_call(struct audio_device *adev)
251f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamanda{
252f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamanda    return adev->voice.in_call;
2534b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
2544b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
2554b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavabool voice_is_in_call_rec_stream(struct stream_in *in)
2564b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
2574b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    bool in_call_rec = false;
2584b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int ret = 0;
2594b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
2604b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ret = voice_extn_is_in_call_rec_stream(in, &in_call_rec);
2614b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if (ret == -ENOSYS) {
2624b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        in_call_rec = false;
2634b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
2644b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
2654b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return in_call_rec;
2664b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
2674b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
2684b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavauint32_t voice_get_active_session_id(struct audio_device *adev)
2694b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
2704b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int ret = 0;
2714b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    uint32_t session_id;
2724b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
2734b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ret = voice_extn_get_active_session_id(adev, &session_id);
2744b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if (ret == -ENOSYS) {
2754b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        session_id = VOICE_VSID;
2764b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
2774b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return session_id;
2784b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
2794b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
2804b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavaint voice_check_and_set_incall_rec_usecase(struct audio_device *adev,
2814b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                                           struct stream_in *in)
2824b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
2834b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int ret = 0;
2844b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    uint32_t session_id;
2854b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int usecase_id;
2864b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int rec_mode = INCALL_REC_NONE;
2874b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
288f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamanda    if (voice_is_call_state_active(adev)) {
2894b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        switch (in->source) {
2904b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        case AUDIO_SOURCE_VOICE_UPLINK:
2914b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            in->usecase = USECASE_INCALL_REC_UPLINK;
2924b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            rec_mode = INCALL_REC_UPLINK;
2934b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            break;
2944b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        case AUDIO_SOURCE_VOICE_DOWNLINK:
2954b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            in->usecase = USECASE_INCALL_REC_DOWNLINK;
2964b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            rec_mode = INCALL_REC_DOWNLINK;
2974b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            break;
2984b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        case AUDIO_SOURCE_VOICE_CALL:
2994b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            in->usecase = USECASE_INCALL_REC_UPLINK_AND_DOWNLINK;
3004b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            rec_mode = INCALL_REC_UPLINK_AND_DOWNLINK;
3014b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            break;
3024b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        default:
3034b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            ALOGV("%s: Source type %d doesnt match incall recording criteria",
3044b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                  __func__, in->source);
3054b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            return ret;
3064b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        }
3074b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3084b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        session_id = voice_get_active_session_id(adev);
3094b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        ret = platform_set_incall_recording_session_id(adev->platform,
3104b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                                                       session_id, rec_mode);
3114b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        ALOGV("%s: Update usecase to %d",__func__, in->usecase);
3124b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    } else {
3134b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        ALOGV("%s: voice call not active", __func__);
3144b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
3154b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3164b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return ret;
3174b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
3184b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3194b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavaint voice_check_and_stop_incall_rec_usecase(struct audio_device *adev,
3204b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                                            struct stream_in *in)
3214b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
3224b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int ret = 0;
3234b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3244b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if (in->source == AUDIO_SOURCE_VOICE_UPLINK ||
3254b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        in->source == AUDIO_SOURCE_VOICE_DOWNLINK ||
3264b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        in->source == AUDIO_SOURCE_VOICE_CALL) {
3274b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        ret = platform_stop_incall_recording_usecase(adev->platform);
3284b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        ALOGV("%s: Stop In-call recording", __func__);
3294b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
3304b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3314b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return ret;
3324b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
3334b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3344b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavaint voice_check_and_set_incall_music_usecase(struct audio_device *adev,
3354b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                                             struct stream_out *out)
3364b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
3374b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int ret = 0;
3384b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3394b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ret = voice_extn_check_and_set_incall_music_usecase(adev, out);
3404b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if (ret == -ENOSYS) {
3414b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        /* Incall music delivery is used only for LCH call state */
3424b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        ret = -EINVAL;
3434b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
3444b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3454b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return ret;
3464b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
3474b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3484b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavaint voice_set_mic_mute(struct audio_device *adev, bool state)
3494b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
3504b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int err = 0;
3514b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3524b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    adev->voice.mic_mute = state;
353a1f480505a2e11b65e8fe6590239bd87b3a33f11Uday Kishore Pasupuleti    if (adev->mode == AUDIO_MODE_IN_CALL ||
354a1f480505a2e11b65e8fe6590239bd87b3a33f11Uday Kishore Pasupuleti        adev->mode == AUDIO_MODE_IN_COMMUNICATION)
3554b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        err = platform_set_mic_mute(adev->platform, state);
3564b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3574b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return err;
3584b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
3594b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3604b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavabool voice_get_mic_mute(struct audio_device *adev)
3614b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
3624b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return adev->voice.mic_mute;
3634b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
3644b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3654b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavaint voice_set_volume(struct audio_device *adev, float volume)
3664b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
3674b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int vol, err = 0;
3684b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3694b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    adev->voice.volume = volume;
3704b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if (adev->mode == AUDIO_MODE_IN_CALL) {
3714b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        if (volume < 0.0) {
3724b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            volume = 0.0;
3734b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        } else if (volume > 1.0) {
3744b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            volume = 1.0;
3754b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        }
3764b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3774b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        vol = lrint(volume * 100.0);
3784b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3794b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        // Voice volume levels from android are mapped to driver volume levels as follows.
3804b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        // 0 -> 5, 20 -> 4, 40 ->3, 60 -> 2, 80 -> 1, 100 -> 0
3814b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        // So adjust the volume to get the correct volume index in driver
3824b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        vol = 100 - vol;
3834b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3844b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        err = platform_set_voice_volume(adev->platform, vol);
3854b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
3864b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
3874b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return err;
3884b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
3894b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
39075a2e1d2119c21c043362d53208f4c46d8c556a6Eric Laurentint voice_start_call(struct audio_device *adev)
3914b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
3924b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int ret = 0;
3934b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
394b09e4a04c7a8ca770affbf48f154222ccd083f4bRavi Kumar Alamanda    adev->voice.in_call = true;
395eecfa9adcc8490896e13bb56ad8451049af80e2cRavi Kumar Alamanda
396eecfa9adcc8490896e13bb56ad8451049af80e2cRavi Kumar Alamanda    voice_set_mic_mute(adev, adev->voice.mic_mute);
397eecfa9adcc8490896e13bb56ad8451049af80e2cRavi Kumar Alamanda
3984b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ret = voice_extn_start_call(adev);
3994b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if (ret == -ENOSYS) {
40075a2e1d2119c21c043362d53208f4c46d8c556a6Eric Laurent        ret = voice_start_usecase(adev, USECASE_VOICE_CALL);
4014b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
4024b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4034b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return ret;
4044b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
4054b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4064b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavaint voice_stop_call(struct audio_device *adev)
4074b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
4084b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int ret = 0;
4094b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
410f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamanda    adev->voice.in_call = false;
4114b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ret = voice_extn_stop_call(adev);
4124b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if (ret == -ENOSYS) {
41308dbcfc116e62f5b4007cade7311430ea235a09eRavi Kumar Alamanda        ret = voice_stop_usecase(adev, USECASE_VOICE_CALL);
4144b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
4154b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4164b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return ret;
4174b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
4184b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4194b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavavoid voice_get_parameters(struct audio_device *adev,
4204b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                          struct str_parms *query,
4214b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                          struct str_parms *reply)
4224b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
4234b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    voice_extn_get_parameters(adev, query, reply);
4244b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
4254b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4264b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavaint voice_set_parameters(struct audio_device *adev, struct str_parms *parms)
4274b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
4284b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    char *str;
4294b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    char value[32];
4304b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int val;
4314b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int ret = 0, err;
4324b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    char *kv_pairs = str_parms_to_str(parms);
4334b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4344b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ALOGV_IF(kv_pairs != NULL, "%s: enter: %s", __func__, kv_pairs);
4354b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4364b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ret = voice_extn_set_parameters(adev, parms);
437ff5d6518fa0e7e4d405fd11f71670551b7728969Haynes Mathew George    if (ret != 0) {
438ff5d6518fa0e7e4d405fd11f71670551b7728969Haynes Mathew George        if (ret == -ENOSYS) {
439ff5d6518fa0e7e4d405fd11f71670551b7728969Haynes Mathew George            ret = 0; /* ignore error */
440ff5d6518fa0e7e4d405fd11f71670551b7728969Haynes Mathew George        } else {
441ff5d6518fa0e7e4d405fd11f71670551b7728969Haynes Mathew George            goto done;
442ff5d6518fa0e7e4d405fd11f71670551b7728969Haynes Mathew George        }
443ff5d6518fa0e7e4d405fd11f71670551b7728969Haynes Mathew George    }
4444b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4454b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_TTY_MODE, value, sizeof(value));
4464b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if (err >= 0) {
4474b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        int tty_mode;
4484b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        str_parms_del(parms, AUDIO_PARAMETER_KEY_TTY_MODE);
4494b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_OFF) == 0)
4504b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            tty_mode = TTY_MODE_OFF;
4514b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_VCO) == 0)
4524b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            tty_mode = TTY_MODE_VCO;
4534b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_HCO) == 0)
4544b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            tty_mode = TTY_MODE_HCO;
4554b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        else if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_FULL) == 0)
4564b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            tty_mode = TTY_MODE_FULL;
4574b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        else {
4584b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            ret = -EINVAL;
4594b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            goto done;
4604b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        }
4614b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4624b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        if (tty_mode != adev->voice.tty_mode) {
4634b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            adev->voice.tty_mode = tty_mode;
4644b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            adev->acdb_settings = (adev->acdb_settings & TTY_MODE_CLEAR) | tty_mode;
465f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamanda            if (voice_is_call_state_active(adev))
4664b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava               voice_update_devices_for_all_voice_usecases(adev);
4674b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        }
4684b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
4694b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4709d0d3f1537b5d157a2c31e0744303524b846446eEric Laurent    err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_HAC,
4719d0d3f1537b5d157a2c31e0744303524b846446eEric Laurent                            value, sizeof(value));
4729d0d3f1537b5d157a2c31e0744303524b846446eEric Laurent    if (err >= 0) {
4739d0d3f1537b5d157a2c31e0744303524b846446eEric Laurent        bool hac = false;
4749d0d3f1537b5d157a2c31e0744303524b846446eEric Laurent        str_parms_del(parms, AUDIO_PARAMETER_KEY_HAC);
4759d0d3f1537b5d157a2c31e0744303524b846446eEric Laurent        if (strcmp(value, AUDIO_PARAMETER_VALUE_HAC_ON) == 0)
4769d0d3f1537b5d157a2c31e0744303524b846446eEric Laurent            hac = true;
4779d0d3f1537b5d157a2c31e0744303524b846446eEric Laurent
4789d0d3f1537b5d157a2c31e0744303524b846446eEric Laurent        if (hac != adev->voice.hac) {
4799d0d3f1537b5d157a2c31e0744303524b846446eEric Laurent            adev->voice.hac = hac;
4809d0d3f1537b5d157a2c31e0744303524b846446eEric Laurent            if (voice_is_in_call(adev))
4819d0d3f1537b5d157a2c31e0744303524b846446eEric Laurent                voice_update_devices_for_all_voice_usecases(adev);
4829d0d3f1537b5d157a2c31e0744303524b846446eEric Laurent        }
4839d0d3f1537b5d157a2c31e0744303524b846446eEric Laurent     }
4849d0d3f1537b5d157a2c31e0744303524b846446eEric Laurent
4854b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_INCALLMUSIC,
4864b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                            value, sizeof(value));
4874b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    if (err >= 0) {
4884b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        str_parms_del(parms, AUDIO_PARAMETER_KEY_INCALLMUSIC);
4894b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        if (strcmp(value, AUDIO_PARAMETER_VALUE_TRUE) == 0)
4904b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            platform_start_incall_music_usecase(adev->platform);
4914b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        else
4924b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            platform_stop_incall_music_usecase(adev->platform);
4934b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava     }
4944b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
4954b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavadone:
4964b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    ALOGV("%s: exit with code(%d)", __func__, ret);
4974b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    free(kv_pairs);
4984b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    return ret;
4994b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
5004b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
5014b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavavoid voice_init(struct audio_device *adev)
5024b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
5034b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    int i = 0;
5044b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
5054b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    memset(&adev->voice, 0, sizeof(adev->voice));
5064b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    adev->voice.tty_mode = TTY_MODE_OFF;
5079d0d3f1537b5d157a2c31e0744303524b846446eEric Laurent    adev->voice.hac = false;
5084b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    adev->voice.volume = 1.0f;
5094b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    adev->voice.mic_mute = false;
510f1819247a21f755757a28ea313678faff73ef349Ravi Kumar Alamanda    adev->voice.in_call = false;
5114b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
5124b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        adev->voice.session[i].pcm_rx = NULL;
5134b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        adev->voice.session[i].pcm_tx = NULL;
5144b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        adev->voice.session[i].state.current = CALL_INACTIVE;
5154b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        adev->voice.session[i].state.new = CALL_INACTIVE;
5164b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        adev->voice.session[i].vsid = VOICE_VSID;
5174b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
5184b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
5194b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    voice_extn_init(adev);
5204b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
5214b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
5224b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastavavoid voice_update_devices_for_all_voice_usecases(struct audio_device *adev)
5234b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava{
5244b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    struct listnode *node;
5254b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    struct audio_usecase *usecase;
5264b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
5274b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    list_for_each(node, &adev->usecase_list) {
5284b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        usecase = node_to_item(node, struct audio_usecase, list);
5294b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        if (usecase->type == VOICE_CALL) {
5304b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            ALOGV("%s: updating device for usecase:%s", __func__,
5314b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava                  use_case_table[usecase->id]);
532a4fc90203ca4c60175b016c4d48438b985a71462Ravi Kumar Alamanda            usecase->stream.out = adev->current_call_output;
5334b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava            select_devices(adev, usecase->id);
5344b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava        }
5354b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava    }
5364b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava}
5374b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
5384b89e37ad290ef955abf8ac1d151728303311345Vineeta Srivastava
539