blob: 629bd8c9a3cd5796a2eee8fa576f730ff96c8bfc [file] [log] [blame]
Eric Laurentb23d5282013-05-14 15:27:20 -07001/*
Shiv Maliyappanahalli3e064fd2013-12-16 15:54:40 -08002 * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07003 * Not a Contribution.
4 *
Shiv Maliyappanahalli8911f282014-01-10 15:56:19 -08005 * Copyright (C) 2013 The Android Open Source Project
Eric Laurentb23d5282013-05-14 15:27:20 -07006 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20#define LOG_TAG "msm8974_platform"
21/*#define LOG_NDEBUG 0*/
22#define LOG_NDDEBUG 0
23
24#include <stdlib.h>
25#include <dlfcn.h>
26#include <cutils/log.h>
27#include <cutils/properties.h>
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -070028#include <cutils/str_parms.h>
Eric Laurentb23d5282013-05-14 15:27:20 -070029#include <audio_hw.h>
30#include <platform_api.h>
31#include "platform.h"
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -070032#include "audio_extn.h"
Narsinga Rao Chella05573b72013-11-15 15:21:40 -080033#include "voice_extn.h"
ApurupaPattapu0c566872014-01-10 14:46:02 -080034#include "sound/compress_params.h"
Ben Rombergera1673712014-01-10 13:49:02 -080035#include "platform_parser.h"
Eric Laurentb23d5282013-05-14 15:27:20 -070036
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -070037#define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
Damir Didjustof1d46c72013-11-06 17:59:04 -080038#define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml"
Eric Laurentb23d5282013-05-14 15:27:20 -070039#define LIB_ACDB_LOADER "libacdbloader.so"
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -070040#define AUDIO_DATA_BLOCK_MIXER_CTL "HDMI EDID"
Eric Laurentb23d5282013-05-14 15:27:20 -070041
ApurupaPattapu0c566872014-01-10 14:46:02 -080042#define MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE (256 * 1024)
43#define MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE (2 * 1024)
44#define COMPRESS_OFFLOAD_FRAGMENT_SIZE_FOR_AV_STREAMING (2 * 1024)
45#define COMPRESS_OFFLOAD_FRAGMENT_SIZE (32 * 1024)
46
47/* Used in calculating fragment size for pcm offload */
ApurupaPattapu0c097d52014-04-08 10:41:07 -070048#define PCM_OFFLOAD_BUFFER_DURATION_FOR_AV 1000 /* 1 sec */
49#define PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING 80 /* 80 millisecs */
ApurupaPattapu0c566872014-01-10 14:46:02 -080050
51/* MAX PCM fragment size cannot be increased further due
52 * to flinger's cblk size of 1mb,and it has to be a multiple of
53 * 24 - lcm of channels supported by DSP
54 */
55#define MAX_PCM_OFFLOAD_FRAGMENT_SIZE (240 * 1024)
ApurupaPattapu0c097d52014-04-08 10:41:07 -070056#define MIN_PCM_OFFLOAD_FRAGMENT_SIZE (4 * 1024)
ApurupaPattapu0c566872014-01-10 14:46:02 -080057
58#define ALIGN( num, to ) (((num) + (to-1)) & (~(to-1)))
Eric Laurentb23d5282013-05-14 15:27:20 -070059/*
Eric Laurentb23d5282013-05-14 15:27:20 -070060 * This file will have a maximum of 38 bytes:
61 *
62 * 4 bytes: number of audio blocks
63 * 4 bytes: total length of Short Audio Descriptor (SAD) blocks
64 * Maximum 10 * 3 bytes: SAD blocks
65 */
66#define MAX_SAD_BLOCKS 10
67#define SAD_BLOCK_SIZE 3
68
69/* EDID format ID for LPCM audio */
70#define EDID_FORMAT_LPCM 1
71
sangwoo1b9f4b32013-06-21 18:22:55 -070072/* Retry for delay in FW loading*/
73#define RETRY_NUMBER 10
74#define RETRY_US 500000
Apoorv Raghuvanshi84fa2fe2013-12-04 11:57:47 -080075#define MAX_SND_CARD 8
sangwoo1b9f4b32013-06-21 18:22:55 -070076
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -070077#define SAMPLE_RATE_8KHZ 8000
78#define SAMPLE_RATE_16KHZ 16000
79
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -070080#define AUDIO_PARAMETER_KEY_FLUENCE_TYPE "fluence"
81#define AUDIO_PARAMETER_KEY_BTSCO "bt_samplerate"
82#define AUDIO_PARAMETER_KEY_SLOWTALK "st_enable"
Ben Rombergerc1dc70d2013-12-19 15:11:17 -080083#define AUDIO_PARAMETER_KEY_VOLUME_BOOST "volume_boost"
84
85enum {
86 VOICE_FEATURE_SET_DEFAULT,
87 VOICE_FEATURE_SET_VOLUME_BOOST
88};
sangwoo53b2cf02013-07-25 19:18:44 -070089
Eric Laurentb23d5282013-05-14 15:27:20 -070090struct audio_block_header
91{
92 int reserved;
93 int length;
94};
95
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -080096/* Audio calibration related functions */
Eric Laurentb23d5282013-05-14 15:27:20 -070097typedef void (*acdb_deallocate_t)();
98typedef int (*acdb_init_t)();
99typedef void (*acdb_send_audio_cal_t)(int, int);
100typedef void (*acdb_send_voice_cal_t)(int, int);
Ben Rombergerc1dc70d2013-12-19 15:11:17 -0800101typedef int (*acdb_reload_vocvoltable_t)(int);
Eric Laurentb23d5282013-05-14 15:27:20 -0700102
Eric Laurentb23d5282013-05-14 15:27:20 -0700103struct platform_data {
104 struct audio_device *adev;
105 bool fluence_in_spkr_mode;
106 bool fluence_in_voice_call;
107 bool fluence_in_voice_rec;
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800108 bool fluence_in_audio_rec;
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700109 int fluence_type;
Venkata Narendra Kumar Gutta9c38b182014-03-27 17:39:57 +0530110 char fluence_cap[PROPERTY_VALUE_MAX];
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700111 int btsco_sample_rate;
112 bool slowtalk;
Ravi Kumar Alamanda48c921d2013-10-29 06:07:44 -0700113 /* Audio calibration related functions */
Ben Rombergerc1dc70d2013-12-19 15:11:17 -0800114 void *acdb_handle;
115 int voice_feature_set;
116 acdb_init_t acdb_init;
117 acdb_deallocate_t acdb_deallocate;
118 acdb_send_audio_cal_t acdb_send_audio_cal;
119 acdb_send_voice_cal_t acdb_send_voice_cal;
120 acdb_reload_vocvoltable_t acdb_reload_vocvoltable;
Ravi Kumar Alamanda48c921d2013-10-29 06:07:44 -0700121
122 void *hw_info;
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800123 struct csd_data *csd;
Eric Laurentb23d5282013-05-14 15:27:20 -0700124};
125
126static const int pcm_device_table[AUDIO_USECASE_MAX][2] = {
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700127 [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {DEEP_BUFFER_PCM_DEVICE,
128 DEEP_BUFFER_PCM_DEVICE},
129 [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
Preetam Singh Ranawatde84f1a2013-11-01 14:58:16 -0700130 LOWLATENCY_PCM_DEVICE},
131 [USECASE_AUDIO_PLAYBACK_MULTI_CH] = {MULTIMEDIA2_PCM_DEVICE,
132 MULTIMEDIA2_PCM_DEVICE},
Krishnankutty Kolathappillya43f96e2013-11-01 12:17:53 -0700133 [USECASE_AUDIO_PLAYBACK_OFFLOAD] =
134 {PLAYBACK_OFFLOAD_DEVICE, PLAYBACK_OFFLOAD_DEVICE},
Shiv Maliyappanahallida107642013-10-17 11:16:13 -0700135 [USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE, AUDIO_RECORD_PCM_DEVICE},
Mingming Yine62d7842013-10-25 16:26:03 -0700136 [USECASE_AUDIO_RECORD_COMPRESS] = {COMPRESS_CAPTURE_DEVICE, COMPRESS_CAPTURE_DEVICE},
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700137 [USECASE_AUDIO_RECORD_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
138 LOWLATENCY_PCM_DEVICE},
Preetam Singh Ranawatde84f1a2013-11-01 14:58:16 -0700139 [USECASE_AUDIO_RECORD_FM_VIRTUAL] = {MULTIMEDIA2_PCM_DEVICE,
140 MULTIMEDIA2_PCM_DEVICE},
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -0700141 [USECASE_AUDIO_PLAYBACK_FM] = {FM_PLAYBACK_PCM_DEVICE, FM_CAPTURE_PCM_DEVICE},
Vimal Puthanveed5b4d3f12013-11-05 15:57:39 -0800142 [USECASE_AUDIO_HFP_SCO] = {HFP_PCM_RX, HFP_SCO_RX},
Vimal Puthanveed47e64852013-12-20 13:23:39 -0800143 [USECASE_AUDIO_HFP_SCO_WB] = {HFP_PCM_RX, HFP_SCO_RX},
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700144 [USECASE_VOICE_CALL] = {VOICE_CALL_PCM_DEVICE, VOICE_CALL_PCM_DEVICE},
145 [USECASE_VOICE2_CALL] = {VOICE2_CALL_PCM_DEVICE, VOICE2_CALL_PCM_DEVICE},
146 [USECASE_VOLTE_CALL] = {VOLTE_CALL_PCM_DEVICE, VOLTE_CALL_PCM_DEVICE},
147 [USECASE_QCHAT_CALL] = {QCHAT_CALL_PCM_DEVICE, QCHAT_CALL_PCM_DEVICE},
Vicky Sehrawat111aeb32014-02-12 17:58:59 -0800148 [USECASE_VOWLAN_CALL] = {VOWLAN_CALL_PCM_DEVICE, VOWLAN_CALL_PCM_DEVICE},
Narsinga Rao Chella05573b72013-11-15 15:21:40 -0800149 [USECASE_COMPRESS_VOIP_CALL] = {COMPRESS_VOIP_CALL_PCM_DEVICE, COMPRESS_VOIP_CALL_PCM_DEVICE},
Shiv Maliyappanahallida107642013-10-17 11:16:13 -0700150 [USECASE_INCALL_REC_UPLINK] = {AUDIO_RECORD_PCM_DEVICE,
151 AUDIO_RECORD_PCM_DEVICE},
152 [USECASE_INCALL_REC_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
153 AUDIO_RECORD_PCM_DEVICE},
154 [USECASE_INCALL_REC_UPLINK_AND_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
155 AUDIO_RECORD_PCM_DEVICE},
Helen Zenge56b4852013-12-03 16:54:40 -0800156 [USECASE_INCALL_REC_UPLINK_COMPRESS] = {COMPRESS_CAPTURE_DEVICE,
157 COMPRESS_CAPTURE_DEVICE},
158 [USECASE_INCALL_REC_DOWNLINK_COMPRESS] = {COMPRESS_CAPTURE_DEVICE,
159 COMPRESS_CAPTURE_DEVICE},
160 [USECASE_INCALL_REC_UPLINK_AND_DOWNLINK_COMPRESS] = {COMPRESS_CAPTURE_DEVICE,
161 COMPRESS_CAPTURE_DEVICE},
Shiv Maliyappanahallif3b9a422013-10-22 16:38:08 -0700162 [USECASE_INCALL_MUSIC_UPLINK] = {INCALL_MUSIC_UPLINK_PCM_DEVICE,
163 INCALL_MUSIC_UPLINK_PCM_DEVICE},
164 [USECASE_INCALL_MUSIC_UPLINK2] = {INCALL_MUSIC_UPLINK2_PCM_DEVICE,
165 INCALL_MUSIC_UPLINK2_PCM_DEVICE},
Gopikrishnaiah Anandanf538cef2013-10-28 14:06:03 -0700166 [USECASE_AUDIO_SPKR_CALIB_RX] = {SPKR_PROT_CALIB_RX_PCM_DEVICE, -1},
167 [USECASE_AUDIO_SPKR_CALIB_TX] = {-1, SPKR_PROT_CALIB_TX_PCM_DEVICE},
Eric Laurentb23d5282013-05-14 15:27:20 -0700168};
169
170/* Array to store sound devices */
171static const char * const device_table[SND_DEVICE_MAX] = {
172 [SND_DEVICE_NONE] = "none",
173 /* Playback sound devices */
174 [SND_DEVICE_OUT_HANDSET] = "handset",
175 [SND_DEVICE_OUT_SPEAKER] = "speaker",
176 [SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
177 [SND_DEVICE_OUT_HEADPHONES] = "headphones",
178 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
179 [SND_DEVICE_OUT_VOICE_HANDSET] = "voice-handset",
180 [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
181 [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
182 [SND_DEVICE_OUT_HDMI] = "hdmi",
183 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
184 [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700185 [SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
Eric Laurentb23d5282013-05-14 15:27:20 -0700186 [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
187 [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
188 [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -0700189 [SND_DEVICE_OUT_AFE_PROXY] = "afe-proxy",
190 [SND_DEVICE_OUT_USB_HEADSET] = "usb-headphones",
191 [SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = "speaker-and-usb-headphones",
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -0700192 [SND_DEVICE_OUT_TRANSMISSION_FM] = "transmission-fm",
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -0700193 [SND_DEVICE_OUT_ANC_HEADSET] = "anc-headphones",
194 [SND_DEVICE_OUT_ANC_FB_HEADSET] = "anc-fb-headphones",
195 [SND_DEVICE_OUT_VOICE_ANC_HEADSET] = "voice-anc-headphones",
196 [SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET] = "voice-anc-fb-headphones",
197 [SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET] = "speaker-and-anc-headphones",
198 [SND_DEVICE_OUT_ANC_HANDSET] = "anc-handset",
Gopikrishnaiah Anandanf538cef2013-10-28 14:06:03 -0700199 [SND_DEVICE_OUT_SPEAKER_PROTECTED] = "speaker-protected",
Eric Laurentb23d5282013-05-14 15:27:20 -0700200
201 /* Capture sound devices */
202 [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
Eric Laurentb23d5282013-05-14 15:27:20 -0700203 [SND_DEVICE_IN_HANDSET_MIC_AEC] = "handset-mic",
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800204 [SND_DEVICE_IN_HANDSET_MIC_NS] = "handset-mic",
205 [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = "handset-mic",
206 [SND_DEVICE_IN_HANDSET_DMIC] = "dmic-endfire",
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800207 [SND_DEVICE_IN_HANDSET_DMIC_AEC] = "dmic-endfire",
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800208 [SND_DEVICE_IN_HANDSET_DMIC_NS] = "dmic-endfire",
209 [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = "dmic-endfire",
210 [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800211 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "speaker-mic",
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800212 [SND_DEVICE_IN_SPEAKER_MIC_NS] = "speaker-mic",
213 [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = "speaker-mic",
214 [SND_DEVICE_IN_SPEAKER_DMIC] = "speaker-dmic-endfire",
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800215 [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = "speaker-dmic-endfire",
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800216 [SND_DEVICE_IN_SPEAKER_DMIC_NS] = "speaker-dmic-endfire",
217 [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = "speaker-dmic-endfire",
218 [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
219 [SND_DEVICE_IN_HEADSET_MIC_FLUENCE] = "headset-mic",
Eric Laurentb23d5282013-05-14 15:27:20 -0700220 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
221 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
222 [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
223 [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700224 [SND_DEVICE_IN_BT_SCO_MIC_WB] = "bt-sco-mic-wb",
Eric Laurentb23d5282013-05-14 15:27:20 -0700225 [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700226 [SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700227 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = "voice-speaker-dmic-ef",
Vidyakumar Athotaadfe4e32013-12-13 14:51:26 -0800228 [SND_DEVICE_IN_VOICE_SPEAKER_QMIC] = "voice-speaker-qmic",
Eric Laurentb23d5282013-05-14 15:27:20 -0700229 [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = "voice-tty-full-headset-mic",
230 [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = "voice-tty-vco-handset-mic",
231 [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = "voice-tty-hco-headset-mic",
232 [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800233 [SND_DEVICE_IN_VOICE_REC_MIC_NS] = "voice-rec-mic",
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800234 [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = "voice-rec-dmic-ef",
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700235 [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = "voice-rec-dmic-ef-fluence",
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -0700236 [SND_DEVICE_IN_USB_HEADSET_MIC] = "usb-headset-mic",
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -0700237 [SND_DEVICE_IN_CAPTURE_FM] = "capture-fm",
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -0700238 [SND_DEVICE_IN_AANC_HANDSET_MIC] = "aanc-handset-mic",
Apoorv Raghuvanshi6178a3f2013-10-19 12:38:54 -0700239 [SND_DEVICE_IN_QUAD_MIC] = "quad-mic",
Apoorv Raghuvanshi6bd8dbf2013-10-19 18:37:52 -0700240 [SND_DEVICE_IN_HANDSET_STEREO_DMIC] = "handset-stereo-dmic-ef",
241 [SND_DEVICE_IN_SPEAKER_STEREO_DMIC] = "speaker-stereo-dmic-ef",
Gopikrishnaiah Anandanf538cef2013-10-28 14:06:03 -0700242 [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = "vi-feedback",
Eric Laurentb23d5282013-05-14 15:27:20 -0700243};
244
245/* ACDB IDs (audio DSP path configuration IDs) for each sound device */
Ben Rombergera1673712014-01-10 13:49:02 -0800246static int acdb_device_table[SND_DEVICE_MAX] = {
Eric Laurentb23d5282013-05-14 15:27:20 -0700247 [SND_DEVICE_NONE] = -1,
248 [SND_DEVICE_OUT_HANDSET] = 7,
Vidyakumar Athotac29d4ab2013-11-14 16:58:02 -0800249 [SND_DEVICE_OUT_SPEAKER] = 14,
250 [SND_DEVICE_OUT_SPEAKER_REVERSE] = 14,
Eric Laurentb23d5282013-05-14 15:27:20 -0700251 [SND_DEVICE_OUT_HEADPHONES] = 10,
252 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
253 [SND_DEVICE_OUT_VOICE_HANDSET] = 7,
Vidyakumar Athotac29d4ab2013-11-14 16:58:02 -0800254 [SND_DEVICE_OUT_VOICE_SPEAKER] = 14,
Eric Laurentb23d5282013-05-14 15:27:20 -0700255 [SND_DEVICE_OUT_VOICE_HEADPHONES] = 10,
256 [SND_DEVICE_OUT_HDMI] = 18,
Vidyakumar Athotac29d4ab2013-11-14 16:58:02 -0800257 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 14,
Eric Laurentb23d5282013-05-14 15:27:20 -0700258 [SND_DEVICE_OUT_BT_SCO] = 22,
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700259 [SND_DEVICE_OUT_BT_SCO_WB] = 39,
Eric Laurentb23d5282013-05-14 15:27:20 -0700260 [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
261 [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
262 [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -0700263 [SND_DEVICE_OUT_AFE_PROXY] = 0,
264 [SND_DEVICE_OUT_USB_HEADSET] = 0,
265 [SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = 14,
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -0700266 [SND_DEVICE_OUT_TRANSMISSION_FM] = 0,
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -0700267 [SND_DEVICE_OUT_ANC_HEADSET] = 26,
Ravi Kumar Alamanda48c921d2013-10-29 06:07:44 -0700268 [SND_DEVICE_OUT_ANC_FB_HEADSET] = 27,
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -0700269 [SND_DEVICE_OUT_VOICE_ANC_HEADSET] = 26,
Ravi Kumar Alamanda48c921d2013-10-29 06:07:44 -0700270 [SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET] = 27,
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -0700271 [SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET] = 26,
272 [SND_DEVICE_OUT_ANC_HANDSET] = 103,
Gopikrishnaiah Anandanf538cef2013-10-28 14:06:03 -0700273 [SND_DEVICE_OUT_SPEAKER_PROTECTED] = 101,
Eric Laurentb23d5282013-05-14 15:27:20 -0700274
275 [SND_DEVICE_IN_HANDSET_MIC] = 4,
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800276 [SND_DEVICE_IN_HANDSET_MIC_AEC] = 106,
277 [SND_DEVICE_IN_HANDSET_MIC_NS] = 107,
278 [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = 108,
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800279 [SND_DEVICE_IN_HANDSET_DMIC] = 41,
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800280 [SND_DEVICE_IN_HANDSET_DMIC_AEC] = 109,
281 [SND_DEVICE_IN_HANDSET_DMIC_NS] = 110,
282 [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = 111,
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800283 [SND_DEVICE_IN_SPEAKER_MIC] = 11,
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800284 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = 112,
285 [SND_DEVICE_IN_SPEAKER_MIC_NS] = 113,
286 [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = 114,
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800287 [SND_DEVICE_IN_SPEAKER_DMIC] = 43,
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800288 [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = 115,
289 [SND_DEVICE_IN_SPEAKER_DMIC_NS] = 116,
290 [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = 117,
Eric Laurentb23d5282013-05-14 15:27:20 -0700291 [SND_DEVICE_IN_HEADSET_MIC] = 8,
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800292 [SND_DEVICE_IN_HEADSET_MIC_FLUENCE] = 47,
Eric Laurentb23d5282013-05-14 15:27:20 -0700293 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = 11,
294 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = 8,
295 [SND_DEVICE_IN_HDMI_MIC] = 4,
296 [SND_DEVICE_IN_BT_SCO_MIC] = 21,
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700297 [SND_DEVICE_IN_BT_SCO_MIC_WB] = 38,
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800298 [SND_DEVICE_IN_CAMCORDER_MIC] = 4,
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700299 [SND_DEVICE_IN_VOICE_DMIC] = 41,
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700300 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = 43,
Vidyakumar Athotaadfe4e32013-12-13 14:51:26 -0800301 [SND_DEVICE_IN_VOICE_SPEAKER_QMIC] = 19,
Eric Laurentb23d5282013-05-14 15:27:20 -0700302 [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = 16,
303 [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = 36,
304 [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = 16,
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800305 [SND_DEVICE_IN_VOICE_REC_MIC] = 4,
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800306 [SND_DEVICE_IN_VOICE_REC_MIC_NS] = 107,
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800307 [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = 34,
308 [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = 41,
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -0700309 [SND_DEVICE_IN_USB_HEADSET_MIC] = 44,
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -0700310 [SND_DEVICE_IN_CAPTURE_FM] = 0,
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -0700311 [SND_DEVICE_IN_AANC_HANDSET_MIC] = 104,
Apoorv Raghuvanshi6178a3f2013-10-19 12:38:54 -0700312 [SND_DEVICE_IN_QUAD_MIC] = 46,
Apoorv Raghuvanshi6bd8dbf2013-10-19 18:37:52 -0700313 [SND_DEVICE_IN_HANDSET_STEREO_DMIC] = 34,
314 [SND_DEVICE_IN_SPEAKER_STEREO_DMIC] = 35,
Gopikrishnaiah Anandanf538cef2013-10-28 14:06:03 -0700315 [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = 102,
Eric Laurentb23d5282013-05-14 15:27:20 -0700316};
317
Haynes Mathew George7ff216f2013-09-11 19:51:41 -0700318#define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
319#define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
320
Anish Kumar674837a2014-04-17 12:42:20 -0700321static void set_echo_reference(struct audio_device *adev, bool enable)
Eric Laurentb23d5282013-05-14 15:27:20 -0700322{
Anish Kumar674837a2014-04-17 12:42:20 -0700323 if (enable)
324 audio_route_apply_and_update_path(adev->audio_route, "echo-reference");
325 else
326 audio_route_reset_and_update_path(adev->audio_route, "echo-reference");
Eric Laurentb23d5282013-05-14 15:27:20 -0700327
Anish Kumar674837a2014-04-17 12:42:20 -0700328 ALOGV("Setting EC Reference: %d", enable);
Eric Laurentb23d5282013-05-14 15:27:20 -0700329}
330
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800331static struct csd_data *open_csd_client()
332{
333 struct csd_data *csd = calloc(1, sizeof(struct csd_data));
334
335 csd->csd_client = dlopen(LIB_CSD_CLIENT, RTLD_NOW);
336 if (csd->csd_client == NULL) {
337 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_CSD_CLIENT);
338 goto error;
339 } else {
340 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_CSD_CLIENT);
341
342 csd->deinit = (deinit_t)dlsym(csd->csd_client,
343 "csd_client_deinit");
344 if (csd->deinit == NULL) {
345 ALOGE("%s: dlsym error %s for csd_client_deinit", __func__,
346 dlerror());
347 goto error;
348 }
349 csd->disable_device = (disable_device_t)dlsym(csd->csd_client,
350 "csd_client_disable_device");
351 if (csd->disable_device == NULL) {
352 ALOGE("%s: dlsym error %s for csd_client_disable_device",
353 __func__, dlerror());
354 goto error;
355 }
356 csd->enable_device = (enable_device_t)dlsym(csd->csd_client,
357 "csd_client_enable_device");
358 if (csd->enable_device == NULL) {
359 ALOGE("%s: dlsym error %s for csd_client_enable_device",
360 __func__, dlerror());
361 goto error;
362 }
363 csd->start_voice = (start_voice_t)dlsym(csd->csd_client,
364 "csd_client_start_voice");
365 if (csd->start_voice == NULL) {
366 ALOGE("%s: dlsym error %s for csd_client_start_voice",
367 __func__, dlerror());
368 goto error;
369 }
370 csd->stop_voice = (stop_voice_t)dlsym(csd->csd_client,
371 "csd_client_stop_voice");
372 if (csd->stop_voice == NULL) {
373 ALOGE("%s: dlsym error %s for csd_client_stop_voice",
374 __func__, dlerror());
375 goto error;
376 }
377 csd->volume = (volume_t)dlsym(csd->csd_client,
378 "csd_client_volume");
379 if (csd->volume == NULL) {
380 ALOGE("%s: dlsym error %s for csd_client_volume",
381 __func__, dlerror());
382 goto error;
383 }
384 csd->mic_mute = (mic_mute_t)dlsym(csd->csd_client,
385 "csd_client_mic_mute");
386 if (csd->mic_mute == NULL) {
387 ALOGE("%s: dlsym error %s for csd_client_mic_mute",
388 __func__, dlerror());
389 goto error;
390 }
391 csd->slow_talk = (slow_talk_t)dlsym(csd->csd_client,
392 "csd_client_slow_talk");
393 if (csd->slow_talk == NULL) {
394 ALOGE("%s: dlsym error %s for csd_client_slow_talk",
395 __func__, dlerror());
396 goto error;
397 }
398 csd->start_playback = (start_playback_t)dlsym(csd->csd_client,
399 "csd_client_start_playback");
400 if (csd->start_playback == NULL) {
401 ALOGE("%s: dlsym error %s for csd_client_start_playback",
402 __func__, dlerror());
403 goto error;
404 }
405 csd->stop_playback = (stop_playback_t)dlsym(csd->csd_client,
406 "csd_client_stop_playback");
407 if (csd->stop_playback == NULL) {
408 ALOGE("%s: dlsym error %s for csd_client_stop_playback",
409 __func__, dlerror());
410 goto error;
411 }
412 csd->start_record = (start_record_t)dlsym(csd->csd_client,
413 "csd_client_start_record");
414 if (csd->start_record == NULL) {
415 ALOGE("%s: dlsym error %s for csd_client_start_record",
416 __func__, dlerror());
417 goto error;
418 }
419 csd->stop_record = (stop_record_t)dlsym(csd->csd_client,
420 "csd_client_stop_record");
421 if (csd->stop_record == NULL) {
422 ALOGE("%s: dlsym error %s for csd_client_stop_record",
423 __func__, dlerror());
424 goto error;
425 }
426 csd->init = (init_t)dlsym(csd->csd_client, "csd_client_init");
427
428 if (csd->init == NULL) {
429 ALOGE("%s: dlsym error %s for csd_client_init",
430 __func__, dlerror());
431 goto error;
432 } else {
433 csd->init();
434 }
435 }
436 return csd;
437
438error:
439 free(csd);
440 csd = NULL;
441 return csd;
442}
443
444void close_csd_client(struct csd_data *csd)
445{
446 if (csd != NULL) {
447 csd->deinit();
448 dlclose(csd->csd_client);
449 free(csd);
450 csd = NULL;
451 }
452}
453
Eric Laurentb23d5282013-05-14 15:27:20 -0700454void *platform_init(struct audio_device *adev)
455{
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800456 char platform[PROPERTY_VALUE_MAX];
457 char baseband[PROPERTY_VALUE_MAX];
Eric Laurentb23d5282013-05-14 15:27:20 -0700458 char value[PROPERTY_VALUE_MAX];
Apoorv Raghuvanshi84fa2fe2013-12-04 11:57:47 -0800459 struct platform_data *my_data = NULL;
460 int retry_num = 0, snd_card_num = 0;
Ravi Kumar Alamanda48c921d2013-10-29 06:07:44 -0700461 const char *snd_card_name;
sangwoo1b9f4b32013-06-21 18:22:55 -0700462
Eric Laurentb23d5282013-05-14 15:27:20 -0700463 my_data = calloc(1, sizeof(struct platform_data));
464
Apoorv Raghuvanshi84fa2fe2013-12-04 11:57:47 -0800465 while (snd_card_num < MAX_SND_CARD) {
466 adev->mixer = mixer_open(snd_card_num);
467
468 while (!adev->mixer && retry_num < RETRY_NUMBER) {
469 usleep(RETRY_US);
470 adev->mixer = mixer_open(snd_card_num);
471 retry_num++;
472 }
473
474 if (!adev->mixer) {
475 ALOGE("%s: Unable to open the mixer card: %d", __func__,
476 snd_card_num);
477 retry_num = 0;
478 snd_card_num++;
479 continue;
480 }
481
482 snd_card_name = mixer_get_name(adev->mixer);
483 ALOGV("%s: snd_card_name: %s", __func__, snd_card_name);
484
485 my_data->hw_info = hw_info_init(snd_card_name);
486 if (!my_data->hw_info) {
487 ALOGE("%s: Failed to init hardware info", __func__);
488 } else {
489 if (audio_extn_read_xml(adev, snd_card_num, MIXER_XML_PATH,
490 MIXER_XML_PATH_AUXPCM) == -ENOSYS)
491 adev->audio_route = audio_route_init(snd_card_num,
492 MIXER_XML_PATH);
493 if (!adev->audio_route) {
494 ALOGE("%s: Failed to init audio route controls, aborting.",
495 __func__);
496 free(my_data);
497 return NULL;
498 }
499 adev->snd_card = snd_card_num;
500 ALOGD("%s: Opened sound card:%d", __func__, snd_card_num);
501 break;
502 }
503 retry_num = 0;
504 snd_card_num++;
505 }
506
507 if (snd_card_num >= MAX_SND_CARD) {
508 ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
509 free(my_data);
510 return NULL;
Ravi Kumar Alamanda48c921d2013-10-29 06:07:44 -0700511 }
512
Eric Laurentb23d5282013-05-14 15:27:20 -0700513 my_data->adev = adev;
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700514 my_data->btsco_sample_rate = SAMPLE_RATE_8KHZ;
Eric Laurentb23d5282013-05-14 15:27:20 -0700515 my_data->fluence_in_spkr_mode = false;
516 my_data->fluence_in_voice_call = false;
517 my_data->fluence_in_voice_rec = false;
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800518 my_data->fluence_in_audio_rec = false;
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700519 my_data->fluence_type = FLUENCE_NONE;
Eric Laurentb23d5282013-05-14 15:27:20 -0700520
Venkata Narendra Kumar Gutta9c38b182014-03-27 17:39:57 +0530521 property_get("ro.qc.sdk.audio.fluencetype", my_data->fluence_cap, "");
522 if (!strncmp("fluencepro", my_data->fluence_cap, sizeof("fluencepro"))) {
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800523 my_data->fluence_type = FLUENCE_QUAD_MIC | FLUENCE_DUAL_MIC;
Venkata Narendra Kumar Gutta9c38b182014-03-27 17:39:57 +0530524 } else if (!strncmp("fluence", my_data->fluence_cap, sizeof("fluence"))) {
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700525 my_data->fluence_type = FLUENCE_DUAL_MIC;
526 } else {
527 my_data->fluence_type = FLUENCE_NONE;
Eric Laurentb23d5282013-05-14 15:27:20 -0700528 }
529
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700530 if (my_data->fluence_type != FLUENCE_NONE) {
Eric Laurentb23d5282013-05-14 15:27:20 -0700531 property_get("persist.audio.fluence.voicecall",value,"");
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700532 if (!strncmp("true", value, sizeof("true"))) {
Eric Laurentb23d5282013-05-14 15:27:20 -0700533 my_data->fluence_in_voice_call = true;
534 }
535
536 property_get("persist.audio.fluence.voicerec",value,"");
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700537 if (!strncmp("true", value, sizeof("true"))) {
Eric Laurentb23d5282013-05-14 15:27:20 -0700538 my_data->fluence_in_voice_rec = true;
539 }
540
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800541 property_get("persist.audio.fluence.audiorec",value,"");
542 if (!strncmp("true", value, sizeof("true"))) {
543 my_data->fluence_in_audio_rec = true;
544 }
545
Eric Laurentb23d5282013-05-14 15:27:20 -0700546 property_get("persist.audio.fluence.speaker",value,"");
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700547 if (!strncmp("true", value, sizeof("true"))) {
Eric Laurentb23d5282013-05-14 15:27:20 -0700548 my_data->fluence_in_spkr_mode = true;
549 }
550 }
551
Ben Rombergerc1dc70d2013-12-19 15:11:17 -0800552 my_data->voice_feature_set = VOICE_FEATURE_SET_DEFAULT;
Eric Laurentb23d5282013-05-14 15:27:20 -0700553 my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
554 if (my_data->acdb_handle == NULL) {
555 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
556 } else {
557 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
558 my_data->acdb_deallocate = (acdb_deallocate_t)dlsym(my_data->acdb_handle,
559 "acdb_loader_deallocate_ACDB");
Ben Rombergerc1dc70d2013-12-19 15:11:17 -0800560 if (!my_data->acdb_deallocate)
561 ALOGE("%s: Could not find the symbol acdb_loader_deallocate_ACDB from %s",
562 __func__, LIB_ACDB_LOADER);
563
Eric Laurentb23d5282013-05-14 15:27:20 -0700564 my_data->acdb_send_audio_cal = (acdb_send_audio_cal_t)dlsym(my_data->acdb_handle,
565 "acdb_loader_send_audio_cal");
566 if (!my_data->acdb_send_audio_cal)
Ben Rombergerc1dc70d2013-12-19 15:11:17 -0800567 ALOGE("%s: Could not find the symbol acdb_send_audio_cal from %s",
Eric Laurentb23d5282013-05-14 15:27:20 -0700568 __func__, LIB_ACDB_LOADER);
Ben Rombergerc1dc70d2013-12-19 15:11:17 -0800569
Eric Laurentb23d5282013-05-14 15:27:20 -0700570 my_data->acdb_send_voice_cal = (acdb_send_voice_cal_t)dlsym(my_data->acdb_handle,
571 "acdb_loader_send_voice_cal");
Ben Rombergerc1dc70d2013-12-19 15:11:17 -0800572 if (!my_data->acdb_send_voice_cal)
573 ALOGE("%s: Could not find the symbol acdb_loader_send_voice_cal from %s",
574 __func__, LIB_ACDB_LOADER);
575
576 my_data->acdb_reload_vocvoltable = (acdb_reload_vocvoltable_t)dlsym(my_data->acdb_handle,
577 "acdb_loader_reload_vocvoltable");
578 if (!my_data->acdb_reload_vocvoltable)
579 ALOGE("%s: Could not find the symbol acdb_loader_reload_vocvoltable from %s",
580 __func__, LIB_ACDB_LOADER);
581
Eric Laurentb23d5282013-05-14 15:27:20 -0700582 my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
583 "acdb_loader_init_ACDB");
584 if (my_data->acdb_init == NULL)
585 ALOGE("%s: dlsym error %s for acdb_loader_init_ACDB", __func__, dlerror());
586 else
587 my_data->acdb_init();
588 }
589
Ben Rombergera1673712014-01-10 13:49:02 -0800590 /* Initialize ACDB ID's */
591 platform_info_init();
592
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800593 /* If platform is apq8084 and baseband is MDM, load CSD Client specific
594 * symbols. Voice call is handled by MDM and apps processor talks to
595 * MDM through CSD Client
596 */
597 property_get("ro.board.platform", platform, "");
598 property_get("ro.baseband", baseband, "");
599 if (!strncmp("apq8084", platform, sizeof("apq8084")) &&
600 !strncmp("mdm", baseband, sizeof("mdm"))) {
601 my_data->csd = open_csd_client();
602 }
603
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -0700604 /* init usb */
605 audio_extn_usb_init(adev);
Apoorv Raghuvanshi84fa2fe2013-12-04 11:57:47 -0800606 /* update sound cards appropriately */
607 audio_extn_usb_set_proxy_sound_card(adev->snd_card);
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -0700608
Apoorv Raghuvanshi6178a3f2013-10-19 12:38:54 -0700609 /* Read one time ssr property */
Mingming Yin49be8032013-12-19 12:51:25 -0800610 audio_extn_ssr_update_enabled();
Gopikrishnaiah Anandanf538cef2013-10-28 14:06:03 -0700611 audio_extn_spkr_prot_init(adev);
Eric Laurentb23d5282013-05-14 15:27:20 -0700612 return my_data;
613}
614
615void platform_deinit(void *platform)
616{
Ravi Kumar Alamanda48c921d2013-10-29 06:07:44 -0700617 struct platform_data *my_data = (struct platform_data *)platform;
618
619 hw_info_deinit(my_data->hw_info);
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800620 close_csd_client(my_data->csd);
621
Eric Laurentb23d5282013-05-14 15:27:20 -0700622 free(platform);
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -0700623 /* deinit usb */
624 audio_extn_usb_deinit();
Eric Laurentb23d5282013-05-14 15:27:20 -0700625}
626
627const char *platform_get_snd_device_name(snd_device_t snd_device)
628{
629 if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX)
630 return device_table[snd_device];
631 else
632 return "";
633}
634
Ravi Kumar Alamanda48c921d2013-10-29 06:07:44 -0700635int platform_get_snd_device_name_extn(void *platform, snd_device_t snd_device,
636 char *device_name)
637{
638 struct platform_data *my_data = (struct platform_data *)platform;
639
640 if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) {
641 strlcpy(device_name, device_table[snd_device], DEVICE_NAME_MAX_SIZE);
642 hw_info_append_hw_type(my_data->hw_info, snd_device, device_name);
643 } else {
644 strlcpy(device_name, "", DEVICE_NAME_MAX_SIZE);
645 return -EINVAL;
646 }
647
648 return 0;
649}
650
Eric Laurentb23d5282013-05-14 15:27:20 -0700651void platform_add_backend_name(char *mixer_path, snd_device_t snd_device)
652{
653 if (snd_device == SND_DEVICE_IN_BT_SCO_MIC)
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700654 strlcat(mixer_path, " bt-sco", MIXER_PATH_MAX_LENGTH);
655 else if (snd_device == SND_DEVICE_IN_BT_SCO_MIC_WB)
656 strlcat(mixer_path, " bt-sco-wb", MIXER_PATH_MAX_LENGTH);
Eric Laurentb23d5282013-05-14 15:27:20 -0700657 else if(snd_device == SND_DEVICE_OUT_BT_SCO)
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700658 strlcat(mixer_path, " bt-sco", MIXER_PATH_MAX_LENGTH);
659 else if(snd_device == SND_DEVICE_OUT_BT_SCO_WB)
660 strlcat(mixer_path, " bt-sco-wb", MIXER_PATH_MAX_LENGTH);
Eric Laurentb23d5282013-05-14 15:27:20 -0700661 else if (snd_device == SND_DEVICE_OUT_HDMI)
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700662 strlcat(mixer_path, " hdmi", MIXER_PATH_MAX_LENGTH);
Eric Laurentb23d5282013-05-14 15:27:20 -0700663 else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HDMI)
664 strcat(mixer_path, " speaker-and-hdmi");
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -0700665 else if (snd_device == SND_DEVICE_OUT_AFE_PROXY)
666 strlcat(mixer_path, " afe-proxy", MIXER_PATH_MAX_LENGTH);
667 else if (snd_device == SND_DEVICE_OUT_USB_HEADSET)
668 strlcat(mixer_path, " usb-headphones", MIXER_PATH_MAX_LENGTH);
669 else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET)
670 strlcat(mixer_path, " speaker-and-usb-headphones",
671 MIXER_PATH_MAX_LENGTH);
672 else if (snd_device == SND_DEVICE_IN_USB_HEADSET_MIC)
673 strlcat(mixer_path, " usb-headset-mic", MIXER_PATH_MAX_LENGTH);
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -0700674 else if (snd_device == SND_DEVICE_IN_CAPTURE_FM)
675 strlcat(mixer_path, " capture-fm", MIXER_PATH_MAX_LENGTH);
676 else if (snd_device == SND_DEVICE_OUT_TRANSMISSION_FM)
677 strlcat(mixer_path, " transmission-fm", MIXER_PATH_MAX_LENGTH);
Eric Laurentb23d5282013-05-14 15:27:20 -0700678}
679
680int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
681{
682 int device_id;
683 if (device_type == PCM_PLAYBACK)
684 device_id = pcm_device_table[usecase][0];
685 else
686 device_id = pcm_device_table[usecase][1];
687 return device_id;
688}
689
Venkata Narendra Kumar Gutta9c38b182014-03-27 17:39:57 +0530690int platform_set_fluence_type(void *platform, char *value)
691{
692 int ret = 0;
693 int fluence_type = FLUENCE_NONE;
694 int fluence_flag = NONE_FLAG;
695 struct platform_data *my_data = (struct platform_data *)platform;
696 struct audio_device *adev = my_data->adev;
697
698 ALOGV("%s: fluence type:%d", __func__, my_data->fluence_type);
699
700 /* only dual mic turn on and off is supported as of now through setparameters */
701 if (!strncmp(AUDIO_PARAMETER_VALUE_DUALMIC,value, sizeof(AUDIO_PARAMETER_VALUE_DUALMIC))) {
702 if (!strncmp("fluencepro", my_data->fluence_cap, sizeof("fluencepro")) ||
703 !strncmp("fluence", my_data->fluence_cap, sizeof("fluence"))) {
704 ALOGV("fluence dualmic feature enabled \n");
705 fluence_type = FLUENCE_DUAL_MIC;
706 fluence_flag = DMIC_FLAG;
707 } else {
708 ALOGE("%s: Failed to set DUALMIC", __func__);
709 ret = -1;
710 goto done;
711 }
712 } else if (!strncmp(AUDIO_PARAMETER_KEY_NO_FLUENCE, value, sizeof(AUDIO_PARAMETER_KEY_NO_FLUENCE))) {
713 ALOGV("fluence disabled");
714 fluence_type = FLUENCE_NONE;
715 } else {
716 ALOGE("Invalid fluence value : %s",value);
717 ret = -1;
718 goto done;
719 }
720
721 if (fluence_type != my_data->fluence_type) {
722 ALOGV("%s: Updating fluence_type to :%d", __func__, fluence_type);
723 my_data->fluence_type = fluence_type;
724 adev->acdb_settings = (adev->acdb_settings & FLUENCE_MODE_CLEAR) | fluence_flag;
725 }
726done:
727 return ret;
728}
729
Ben Rombergera1673712014-01-10 13:49:02 -0800730int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
731{
732 int ret = 0;
733
734 if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
735 ALOGE("%s: Invalid snd_device = %d",
736 __func__, snd_device);
737 ret = -EINVAL;
738 goto done;
739 }
740
741 acdb_device_table[snd_device] = acdb_id;
742done:
743 return ret;
744}
745
Venkata Narendra Kumar Gutta9c38b182014-03-27 17:39:57 +0530746int platform_get_fluence_type(void *platform, char *value, uint32_t len)
747{
748 int ret = 0;
749 struct platform_data *my_data = (struct platform_data *)platform;
750
751 if (my_data->fluence_type == FLUENCE_QUAD_MIC) {
752 strlcpy(value, "quadmic", len);
753 } else if (my_data->fluence_type == FLUENCE_DUAL_MIC) {
754 strlcpy(value, "dualmic", len);
755 } else if (my_data->fluence_type == FLUENCE_NONE) {
756 strlcpy(value, "none", len);
757 } else
758 ret = -1;
759
760 return ret;
761}
762
Eric Laurentb23d5282013-05-14 15:27:20 -0700763int platform_send_audio_calibration(void *platform, snd_device_t snd_device)
764{
765 struct platform_data *my_data = (struct platform_data *)platform;
766 int acdb_dev_id, acdb_dev_type;
767
768 acdb_dev_id = acdb_device_table[snd_device];
769 if (acdb_dev_id < 0) {
770 ALOGE("%s: Could not find acdb id for device(%d)",
771 __func__, snd_device);
772 return -EINVAL;
773 }
774 if (my_data->acdb_send_audio_cal) {
Eric Laurent994a6932013-07-17 11:51:42 -0700775 ("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
Eric Laurentb23d5282013-05-14 15:27:20 -0700776 __func__, snd_device, acdb_dev_id);
777 if (snd_device >= SND_DEVICE_OUT_BEGIN &&
778 snd_device < SND_DEVICE_OUT_END)
779 acdb_dev_type = ACDB_DEV_TYPE_OUT;
780 else
781 acdb_dev_type = ACDB_DEV_TYPE_IN;
782 my_data->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type);
783 }
784 return 0;
785}
786
787int platform_switch_voice_call_device_pre(void *platform)
788{
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800789 struct platform_data *my_data = (struct platform_data *)platform;
790 int ret = 0;
791
Vidyakumar Athota1fd21792013-11-15 14:50:57 -0800792 if (my_data->csd != NULL &&
793 my_data->adev->mode == AUDIO_MODE_IN_CALL) {
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800794 /* This must be called before disabling mixer controls on APQ side */
795 ret = my_data->csd->disable_device();
796 if (ret < 0) {
797 ALOGE("%s: csd_client_disable_device, failed, error %d",
798 __func__, ret);
799 }
800 }
801 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -0700802}
803
804int platform_switch_voice_call_device_post(void *platform,
805 snd_device_t out_snd_device,
806 snd_device_t in_snd_device)
807{
808 struct platform_data *my_data = (struct platform_data *)platform;
809 int acdb_rx_id, acdb_tx_id;
810
811 if (my_data->acdb_send_voice_cal == NULL) {
812 ALOGE("%s: dlsym error for acdb_send_voice_call", __func__);
813 } else {
Vidyakumar Athota1fd21792013-11-15 14:50:57 -0800814 acdb_rx_id = acdb_device_table[out_snd_device];
815 acdb_tx_id = acdb_device_table[in_snd_device];
816
Eric Laurentb23d5282013-05-14 15:27:20 -0700817 if (acdb_rx_id > 0 && acdb_tx_id > 0)
818 my_data->acdb_send_voice_cal(acdb_rx_id, acdb_tx_id);
819 else
820 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
821 acdb_rx_id, acdb_tx_id);
822 }
823
Vidyakumar Athota1fd21792013-11-15 14:50:57 -0800824 return 0;
825}
826
827int platform_switch_voice_call_usecase_route_post(void *platform,
828 snd_device_t out_snd_device,
829 snd_device_t in_snd_device)
830{
831 struct platform_data *my_data = (struct platform_data *)platform;
832 int acdb_rx_id, acdb_tx_id;
833 int ret = 0;
834
835 acdb_rx_id = acdb_device_table[out_snd_device];
836 acdb_tx_id = acdb_device_table[in_snd_device];
837
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800838 if (my_data->csd != NULL) {
Vidyakumar Athota1fd21792013-11-15 14:50:57 -0800839 if (acdb_rx_id > 0 && acdb_tx_id > 0) {
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800840 ret = my_data->csd->enable_device(acdb_rx_id, acdb_tx_id,
841 my_data->adev->acdb_settings);
842 if (ret < 0) {
843 ALOGE("%s: csd_enable_device, failed, error %d",
844 __func__, ret);
845 }
846 } else {
847 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
848 acdb_rx_id, acdb_tx_id);
849 }
850 }
851 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -0700852}
853
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800854int platform_start_voice_call(void *platform, uint32_t vsid)
Eric Laurentb23d5282013-05-14 15:27:20 -0700855{
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800856 struct platform_data *my_data = (struct platform_data *)platform;
857 int ret = 0;
858
859 if (my_data->csd != NULL) {
860 ret = my_data->csd->start_voice(vsid);
861 if (ret < 0) {
862 ALOGE("%s: csd_start_voice error %d\n", __func__, ret);
863 }
864 }
865 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -0700866}
867
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800868int platform_stop_voice_call(void *platform, uint32_t vsid)
Eric Laurentb23d5282013-05-14 15:27:20 -0700869{
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800870 struct platform_data *my_data = (struct platform_data *)platform;
871 int ret = 0;
872
873 if (my_data->csd != NULL) {
874 ret = my_data->csd->stop_voice(vsid);
875 if (ret < 0) {
876 ALOGE("%s: csd_stop_voice error %d\n", __func__, ret);
877 }
878 }
879 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -0700880}
881
882int platform_set_voice_volume(void *platform, int volume)
883{
884 struct platform_data *my_data = (struct platform_data *)platform;
885 struct audio_device *adev = my_data->adev;
886 struct mixer_ctl *ctl;
sangwoo53b2cf02013-07-25 19:18:44 -0700887 const char *mixer_ctl_name = "Voice Rx Gain";
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800888 int vol_index = 0, ret = 0;
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700889 uint32_t set_values[ ] = {0,
890 ALL_SESSION_VSID,
891 DEFAULT_VOLUME_RAMP_DURATION_MS};
Eric Laurentb23d5282013-05-14 15:27:20 -0700892
893 // Voice volume levels are mapped to adsp volume levels as follows.
894 // 100 -> 5, 80 -> 4, 60 -> 3, 40 -> 2, 20 -> 1 0 -> 0
895 // But this values don't changed in kernel. So, below change is need.
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700896 vol_index = (int)percent_to_index(volume, MIN_VOL_INDEX, MAX_VOL_INDEX);
897 set_values[0] = vol_index;
Eric Laurentb23d5282013-05-14 15:27:20 -0700898
899 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
900 if (!ctl) {
901 ALOGE("%s: Could not get ctl for mixer cmd - %s",
902 __func__, mixer_ctl_name);
903 return -EINVAL;
904 }
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700905 ALOGV("Setting voice volume index: %d", set_values[0]);
906 mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
Eric Laurentb23d5282013-05-14 15:27:20 -0700907
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800908 if (my_data->csd != NULL) {
909 ret = my_data->csd->volume(ALL_SESSION_VSID, volume);
910 if (ret < 0) {
911 ALOGE("%s: csd_volume error %d", __func__, ret);
912 }
913 }
914 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -0700915}
916
917int platform_set_mic_mute(void *platform, bool state)
918{
919 struct platform_data *my_data = (struct platform_data *)platform;
920 struct audio_device *adev = my_data->adev;
921 struct mixer_ctl *ctl;
922 const char *mixer_ctl_name = "Voice Tx Mute";
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800923 int ret = 0;
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700924 uint32_t set_values[ ] = {0,
925 ALL_SESSION_VSID,
926 DEFAULT_VOLUME_RAMP_DURATION_MS};
Eric Laurentb23d5282013-05-14 15:27:20 -0700927
Narsinga Rao Chella05573b72013-11-15 15:21:40 -0800928 set_values[0] = state;
929 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
930 if (!ctl) {
931 ALOGE("%s: Could not get ctl for mixer cmd - %s",
932 __func__, mixer_ctl_name);
933 return -EINVAL;
934 }
935 ALOGV("Setting voice mute state: %d", state);
936 mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
Eric Laurentb23d5282013-05-14 15:27:20 -0700937
Narsinga Rao Chella05573b72013-11-15 15:21:40 -0800938 if (my_data->csd != NULL) {
939 ret = my_data->csd->mic_mute(ALL_SESSION_VSID, state);
940 if (ret < 0) {
941 ALOGE("%s: csd_mic_mute error %d", __func__, ret);
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800942 }
943 }
944 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -0700945}
946
Shiv Maliyappanahalli575c1552014-03-07 15:31:55 -0800947int platform_set_device_mute(void *platform, bool state, char *dir)
948{
949 struct platform_data *my_data = (struct platform_data *)platform;
950 struct audio_device *adev = my_data->adev;
951 struct mixer_ctl *ctl;
952 char *mixer_ctl_name = NULL;
953 int ret = 0;
954 uint32_t set_values[ ] = {0,
955 ALL_SESSION_VSID,
956 0};
957 if(dir == NULL) {
958 ALOGE("%s: Invalid direction:%s", __func__, dir);
959 return -EINVAL;
960 }
961
962 if (!strncmp("rx", dir, sizeof("rx"))) {
963 mixer_ctl_name = "Voice Rx Device Mute";
964 } else if (!strncmp("tx", dir, sizeof("tx"))) {
965 mixer_ctl_name = "Voice Tx Device Mute";
966 } else {
967 return -EINVAL;
968 }
969
970 set_values[0] = state;
971 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
972 if (!ctl) {
973 ALOGE("%s: Could not get ctl for mixer cmd - %s",
974 __func__, mixer_ctl_name);
975 return -EINVAL;
976 }
977
978 ALOGV("%s: Setting device mute state: %d, mixer ctrl:%s",
979 __func__,state, mixer_ctl_name);
980 mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
981
982 return ret;
983}
984
Eric Laurentb23d5282013-05-14 15:27:20 -0700985snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices)
986{
987 struct platform_data *my_data = (struct platform_data *)platform;
988 struct audio_device *adev = my_data->adev;
989 audio_mode_t mode = adev->mode;
990 snd_device_t snd_device = SND_DEVICE_NONE;
991
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -0700992 audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
993 AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
994 int channel_count = popcount(channel_mask);
995
Eric Laurentb23d5282013-05-14 15:27:20 -0700996 ALOGV("%s: enter: output devices(%#x)", __func__, devices);
997 if (devices == AUDIO_DEVICE_NONE ||
998 devices & AUDIO_DEVICE_BIT_IN) {
999 ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
1000 goto exit;
1001 }
1002
Mingming Yin4a72d652014-01-03 18:54:18 -08001003 if (popcount(devices) == 2) {
1004 if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
1005 AUDIO_DEVICE_OUT_SPEAKER)) {
1006 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
1007 } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
1008 AUDIO_DEVICE_OUT_SPEAKER)) {
1009 if (audio_extn_get_anc_enabled())
1010 snd_device = SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET;
1011 else
1012 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
1013 } else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
1014 AUDIO_DEVICE_OUT_SPEAKER)) {
1015 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI;
1016 } else if (devices == (AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET |
1017 AUDIO_DEVICE_OUT_SPEAKER)) {
1018 snd_device = SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET;
1019 } else {
1020 ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
1021 goto exit;
1022 }
1023 if (snd_device != SND_DEVICE_NONE) {
1024 goto exit;
1025 }
1026 }
1027
1028 if (popcount(devices) != 1) {
1029 ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
1030 goto exit;
1031 }
1032
Narsinga Rao Chella05573b72013-11-15 15:21:40 -08001033 if ((mode == AUDIO_MODE_IN_CALL) ||
1034 voice_extn_compress_voip_is_active(adev)) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001035 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1036 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Narsinga Rao Chella05573b72013-11-15 15:21:40 -08001037 if ((adev->voice.tty_mode != TTY_MODE_OFF) &&
1038 !voice_extn_compress_voip_is_active(adev)) {
1039 switch (adev->voice.tty_mode) {
1040 case TTY_MODE_FULL:
1041 snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES;
1042 break;
1043 case TTY_MODE_VCO:
1044 snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES;
1045 break;
1046 case TTY_MODE_HCO:
1047 snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET;
1048 break;
1049 default:
1050 ALOGE("%s: Invalid TTY mode (%#x)",
1051 __func__, adev->voice.tty_mode);
1052 }
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001053 } else if (audio_extn_get_anc_enabled()) {
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001054 if (audio_extn_should_use_fb_anc())
1055 snd_device = SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET;
1056 else
1057 snd_device = SND_DEVICE_OUT_VOICE_ANC_HEADSET;
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001058 } else {
Eric Laurentb23d5282013-05-14 15:27:20 -07001059 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001060 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001061 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001062 if (my_data->btsco_sample_rate == SAMPLE_RATE_16KHZ)
1063 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
1064 else
1065 snd_device = SND_DEVICE_OUT_BT_SCO;
Eric Laurentb23d5282013-05-14 15:27:20 -07001066 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
1067 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001068 } else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
1069 devices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
1070 snd_device = SND_DEVICE_OUT_USB_HEADSET;
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -07001071 } else if (devices & AUDIO_DEVICE_OUT_FM_TX) {
1072 snd_device = SND_DEVICE_OUT_TRANSMISSION_FM;
Eric Laurentb23d5282013-05-14 15:27:20 -07001073 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Ravi Kumar Alamandaceb40822013-11-06 11:01:47 -08001074 if (audio_extn_should_use_handset_anc(channel_count))
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001075 snd_device = SND_DEVICE_OUT_ANC_HANDSET;
Eric Laurentb23d5282013-05-14 15:27:20 -07001076 else
Mingming Yin8e5a4f62013-10-07 15:23:41 -07001077 snd_device = SND_DEVICE_OUT_VOICE_HANDSET;
Eric Laurentb23d5282013-05-14 15:27:20 -07001078 }
1079 if (snd_device != SND_DEVICE_NONE) {
1080 goto exit;
1081 }
1082 }
1083
Eric Laurentb23d5282013-05-14 15:27:20 -07001084 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1085 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001086 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADSET
1087 && audio_extn_get_anc_enabled()) {
1088 if (audio_extn_should_use_fb_anc())
1089 snd_device = SND_DEVICE_OUT_ANC_FB_HEADSET;
1090 else
1091 snd_device = SND_DEVICE_OUT_ANC_HEADSET;
1092 }
1093 else
1094 snd_device = SND_DEVICE_OUT_HEADPHONES;
Eric Laurentb23d5282013-05-14 15:27:20 -07001095 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
1096 if (adev->speaker_lr_swap)
1097 snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE;
1098 else
1099 snd_device = SND_DEVICE_OUT_SPEAKER;
1100 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001101 if (my_data->btsco_sample_rate == SAMPLE_RATE_16KHZ)
1102 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
1103 else
1104 snd_device = SND_DEVICE_OUT_BT_SCO;
Eric Laurentb23d5282013-05-14 15:27:20 -07001105 } else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
1106 snd_device = SND_DEVICE_OUT_HDMI ;
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001107 } else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
1108 devices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
Mingming Yin5bdb7052014-03-05 17:45:03 -08001109 ALOGD("%s: setting USB hadset channel capability(2) for Proxy", __func__);
1110 audio_extn_set_afe_proxy_channel_mixer(adev, 2);
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001111 snd_device = SND_DEVICE_OUT_USB_HEADSET;
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -07001112 } else if (devices & AUDIO_DEVICE_OUT_FM_TX) {
1113 snd_device = SND_DEVICE_OUT_TRANSMISSION_FM;
Eric Laurentb23d5282013-05-14 15:27:20 -07001114 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
1115 snd_device = SND_DEVICE_OUT_HANDSET;
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001116 } else if (devices & AUDIO_DEVICE_OUT_PROXY) {
Mingming Yin5bdb7052014-03-05 17:45:03 -08001117 channel_count = audio_extn_get_afe_proxy_channel_count();
1118 ALOGD("%s: setting sink capability(%d) for Proxy", __func__, channel_count);
1119 audio_extn_set_afe_proxy_channel_mixer(adev, channel_count);
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001120 snd_device = SND_DEVICE_OUT_AFE_PROXY;
Eric Laurentb23d5282013-05-14 15:27:20 -07001121 } else {
1122 ALOGE("%s: Unknown device(s) %#x", __func__, devices);
1123 }
1124exit:
1125 ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
1126 return snd_device;
1127}
1128
1129snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device)
1130{
1131 struct platform_data *my_data = (struct platform_data *)platform;
1132 struct audio_device *adev = my_data->adev;
1133 audio_source_t source = (adev->active_input == NULL) ?
1134 AUDIO_SOURCE_DEFAULT : adev->active_input->source;
1135
1136 audio_mode_t mode = adev->mode;
1137 audio_devices_t in_device = ((adev->active_input == NULL) ?
1138 AUDIO_DEVICE_NONE : adev->active_input->device)
1139 & ~AUDIO_DEVICE_BIT_IN;
1140 audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
1141 AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
1142 snd_device_t snd_device = SND_DEVICE_NONE;
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001143 int channel_count = popcount(channel_mask);
Eric Laurentb23d5282013-05-14 15:27:20 -07001144
1145 ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
1146 __func__, out_device, in_device);
Helen Zeng067b96b2013-11-26 12:10:29 -08001147 if ((out_device != AUDIO_DEVICE_NONE) && ((mode == AUDIO_MODE_IN_CALL) ||
Satya Krishna Pindiprolifa518782014-05-21 14:45:28 +05301148 voice_extn_compress_voip_is_active(adev) || audio_extn_hfp_is_active(adev))) {
Narsinga Rao Chella05573b72013-11-15 15:21:40 -08001149 if ((adev->voice.tty_mode != TTY_MODE_OFF) &&
1150 !voice_extn_compress_voip_is_active(adev)) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001151 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1152 out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001153 switch (adev->voice.tty_mode) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001154 case TTY_MODE_FULL:
1155 snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC;
1156 break;
1157 case TTY_MODE_VCO:
1158 snd_device = SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC;
1159 break;
1160 case TTY_MODE_HCO:
1161 snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC;
1162 break;
1163 default:
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001164 ALOGE("%s: Invalid TTY mode (%#x)",
1165 __func__, adev->voice.tty_mode);
Eric Laurentb23d5282013-05-14 15:27:20 -07001166 }
1167 goto exit;
1168 }
1169 }
1170 if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
1171 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001172 if (out_device & AUDIO_DEVICE_OUT_EARPIECE &&
1173 audio_extn_should_use_handset_anc(channel_count)) {
1174 snd_device = SND_DEVICE_IN_AANC_HANDSET_MIC;
1175 } else if (my_data->fluence_type == FLUENCE_NONE ||
Mingming Yin8e5a4f62013-10-07 15:23:41 -07001176 my_data->fluence_in_voice_call == false) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001177 snd_device = SND_DEVICE_IN_HANDSET_MIC;
Anish Kumar674837a2014-04-17 12:42:20 -07001178 set_echo_reference(adev, true);
Eric Laurentb23d5282013-05-14 15:27:20 -07001179 } else {
Ravi Kumar Alamandaceb40822013-11-06 11:01:47 -08001180 snd_device = SND_DEVICE_IN_VOICE_DMIC;
Mingming Yin8e5a4f62013-10-07 15:23:41 -07001181 adev->acdb_settings |= DMIC_FLAG;
Eric Laurentb23d5282013-05-14 15:27:20 -07001182 }
1183 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1184 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
Anish Kumarb6928412014-06-12 23:16:32 -07001185 set_echo_reference(adev, true);
Eric Laurentb23d5282013-05-14 15:27:20 -07001186 } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001187 if (my_data->btsco_sample_rate == SAMPLE_RATE_16KHZ)
1188 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
1189 else
1190 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001191 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
Mingming Yin8e5a4f62013-10-07 15:23:41 -07001192 if (my_data->fluence_type != FLUENCE_NONE &&
1193 my_data->fluence_in_voice_call &&
1194 my_data->fluence_in_spkr_mode) {
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -08001195 if(my_data->fluence_type & FLUENCE_QUAD_MIC) {
Mingming Yin8e5a4f62013-10-07 15:23:41 -07001196 adev->acdb_settings |= QMIC_FLAG;
1197 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_QMIC;
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -08001198 } else {
1199 adev->acdb_settings |= DMIC_FLAG;
1200 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC;
Mingming Yin8e5a4f62013-10-07 15:23:41 -07001201 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001202 } else {
1203 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
Anish Kumarb6928412014-06-12 23:16:32 -07001204 set_echo_reference(adev, true);
Eric Laurentb23d5282013-05-14 15:27:20 -07001205 }
1206 }
1207 } else if (source == AUDIO_SOURCE_CAMCORDER) {
1208 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
1209 in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1210 snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
1211 }
1212 } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
1213 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001214 if (channel_count == 2) {
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -08001215 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO;
Mingming Yin8e5a4f62013-10-07 15:23:41 -07001216 adev->acdb_settings |= DMIC_FLAG;
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001217 } else if (adev->active_input->enable_ns)
1218 snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
1219 else if (my_data->fluence_type != FLUENCE_NONE &&
1220 my_data->fluence_in_voice_rec) {
1221 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
1222 adev->acdb_settings |= DMIC_FLAG;
1223 } else {
1224 snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
1225 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001226 }
1227 } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
1228 if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
1229 in_device = AUDIO_DEVICE_IN_BACK_MIC;
1230 if (adev->active_input) {
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001231 if (adev->active_input->enable_aec &&
1232 adev->active_input->enable_ns) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001233 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001234 if (my_data->fluence_type & FLUENCE_DUAL_MIC &&
1235 my_data->fluence_in_spkr_mode) {
1236 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
1237 adev->acdb_settings |= DMIC_FLAG;
1238 } else
1239 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
Eric Laurentb23d5282013-05-14 15:27:20 -07001240 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001241 if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
1242 snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
1243 adev->acdb_settings |= DMIC_FLAG;
1244 } else
1245 snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
Eric Laurentb23d5282013-05-14 15:27:20 -07001246 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001247 snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
Eric Laurentb23d5282013-05-14 15:27:20 -07001248 }
Anish Kumar674837a2014-04-17 12:42:20 -07001249 set_echo_reference(adev, true);
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001250 } else if (adev->active_input->enable_aec) {
1251 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1252 if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
1253 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
1254 adev->acdb_settings |= DMIC_FLAG;
1255 } else
1256 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
1257 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
1258 if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
1259 snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
1260 adev->acdb_settings |= DMIC_FLAG;
1261 } else
1262 snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
1263 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
1264 snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
1265 }
Anish Kumar674837a2014-04-17 12:42:20 -07001266 set_echo_reference(adev, true);
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001267 } else if (adev->active_input->enable_ns) {
1268 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1269 if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
1270 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
1271 adev->acdb_settings |= DMIC_FLAG;
1272 } else
1273 snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
1274 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
1275 if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
1276 snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
1277 adev->acdb_settings |= DMIC_FLAG;
1278 } else
1279 snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
1280 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
1281 snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
1282 }
Anish Kumar674837a2014-04-17 12:42:20 -07001283 set_echo_reference(adev, false);
Eric Laurentb23d5282013-05-14 15:27:20 -07001284 } else
Anish Kumar674837a2014-04-17 12:42:20 -07001285 set_echo_reference(adev, false);
Eric Laurentb23d5282013-05-14 15:27:20 -07001286 }
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -08001287 } else if (source == AUDIO_SOURCE_MIC) {
Apoorv Raghuvanshic0536542013-11-14 16:25:59 -08001288 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC &&
1289 channel_count == 1 ) {
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -08001290 if(my_data->fluence_type & FLUENCE_DUAL_MIC &&
Ravi Kumar Alamanda31cf24c2014-03-07 11:40:24 -08001291 my_data->fluence_in_audio_rec) {
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -08001292 snd_device = SND_DEVICE_IN_HANDSET_DMIC;
Anish Kumar674837a2014-04-17 12:42:20 -07001293 set_echo_reference(adev, true);
Ravi Kumar Alamanda31cf24c2014-03-07 11:40:24 -08001294 }
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -08001295 }
Mingming Yinab429782013-11-07 11:16:55 -08001296 } else if (source == AUDIO_SOURCE_FM_RX ||
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001297 source == AUDIO_SOURCE_FM_RX_A2DP) {
Preetam Singh Ranawatde84f1a2013-11-01 14:58:16 -07001298 snd_device = SND_DEVICE_IN_CAPTURE_FM;
Eric Laurentb23d5282013-05-14 15:27:20 -07001299 } else if (source == AUDIO_SOURCE_DEFAULT) {
1300 goto exit;
1301 }
1302
1303
1304 if (snd_device != SND_DEVICE_NONE) {
1305 goto exit;
1306 }
1307
1308 if (in_device != AUDIO_DEVICE_NONE &&
1309 !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
1310 !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
1311 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Apoorv Raghuvanshi6178a3f2013-10-19 12:38:54 -07001312 if (audio_extn_ssr_get_enabled() && channel_count == 6)
1313 snd_device = SND_DEVICE_IN_QUAD_MIC;
Walter Yangf8a5d0a2014-01-17 11:24:23 +08001314 else if (my_data->fluence_type & (FLUENCE_DUAL_MIC | FLUENCE_QUAD_MIC) &&
1315 channel_count == 2)
Apoorv Raghuvanshi6bd8dbf2013-10-19 18:37:52 -07001316 snd_device = SND_DEVICE_IN_HANDSET_STEREO_DMIC;
Apoorv Raghuvanshi6178a3f2013-10-19 12:38:54 -07001317 else
1318 snd_device = SND_DEVICE_IN_HANDSET_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001319 } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1320 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
1321 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
1322 snd_device = SND_DEVICE_IN_HEADSET_MIC;
1323 } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001324 if (my_data->btsco_sample_rate == SAMPLE_RATE_16KHZ)
1325 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
1326 else
1327 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001328 } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
1329 snd_device = SND_DEVICE_IN_HDMI_MIC;
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001330 } else if (in_device & AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET ||
1331 in_device & AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET) {
1332 snd_device = SND_DEVICE_IN_USB_HEADSET_MIC;
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -07001333 } else if (in_device & AUDIO_DEVICE_IN_FM_RX) {
1334 snd_device = SND_DEVICE_IN_CAPTURE_FM;
Eric Laurentb23d5282013-05-14 15:27:20 -07001335 } else {
1336 ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
1337 ALOGW("%s: Using default handset-mic", __func__);
1338 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1339 }
1340 } else {
1341 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
1342 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1343 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1344 snd_device = SND_DEVICE_IN_HEADSET_MIC;
1345 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
Apoorv Raghuvanshi6bd8dbf2013-10-19 18:37:52 -07001346 if (channel_count > 1)
1347 snd_device = SND_DEVICE_IN_SPEAKER_STEREO_DMIC;
1348 else
1349 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001350 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
1351 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1352 } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001353 if (my_data->btsco_sample_rate == SAMPLE_RATE_16KHZ)
1354 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
1355 else
1356 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001357 } else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
1358 snd_device = SND_DEVICE_IN_HDMI_MIC;
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001359 } else if (out_device & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
1360 out_device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
1361 snd_device = SND_DEVICE_IN_USB_HEADSET_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001362 } else {
1363 ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
1364 ALOGW("%s: Using default handset-mic", __func__);
1365 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1366 }
1367 }
1368exit:
1369 ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
1370 return snd_device;
1371}
1372
1373int platform_set_hdmi_channels(void *platform, int channel_count)
1374{
1375 struct platform_data *my_data = (struct platform_data *)platform;
1376 struct audio_device *adev = my_data->adev;
1377 struct mixer_ctl *ctl;
1378 const char *channel_cnt_str = NULL;
1379 const char *mixer_ctl_name = "HDMI_RX Channels";
1380 switch (channel_count) {
1381 case 8:
1382 channel_cnt_str = "Eight"; break;
1383 case 7:
1384 channel_cnt_str = "Seven"; break;
1385 case 6:
1386 channel_cnt_str = "Six"; break;
1387 case 5:
1388 channel_cnt_str = "Five"; break;
1389 case 4:
1390 channel_cnt_str = "Four"; break;
1391 case 3:
1392 channel_cnt_str = "Three"; break;
1393 default:
1394 channel_cnt_str = "Two"; break;
1395 }
1396 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1397 if (!ctl) {
1398 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1399 __func__, mixer_ctl_name);
1400 return -EINVAL;
1401 }
1402 ALOGV("HDMI channel count: %s", channel_cnt_str);
1403 mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
1404 return 0;
1405}
1406
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001407int platform_edid_get_max_channels(void *platform)
Eric Laurentb23d5282013-05-14 15:27:20 -07001408{
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001409 struct platform_data *my_data = (struct platform_data *)platform;
1410 struct audio_device *adev = my_data->adev;
Eric Laurentb23d5282013-05-14 15:27:20 -07001411 char block[MAX_SAD_BLOCKS * SAD_BLOCK_SIZE];
1412 char *sad = block;
1413 int num_audio_blocks;
1414 int channel_count;
1415 int max_channels = 0;
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001416 int i, ret, count;
Eric Laurentb23d5282013-05-14 15:27:20 -07001417
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001418 struct mixer_ctl *ctl;
1419
1420 ctl = mixer_get_ctl_by_name(adev->mixer, AUDIO_DATA_BLOCK_MIXER_CTL);
1421 if (!ctl) {
1422 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1423 __func__, AUDIO_DATA_BLOCK_MIXER_CTL);
Eric Laurentb23d5282013-05-14 15:27:20 -07001424 return 0;
1425 }
1426
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001427 mixer_ctl_update(ctl);
1428
1429 count = mixer_ctl_get_num_values(ctl);
Eric Laurentb23d5282013-05-14 15:27:20 -07001430
1431 /* Read SAD blocks, clamping the maximum size for safety */
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001432 if (count > (int)sizeof(block))
1433 count = (int)sizeof(block);
Eric Laurentb23d5282013-05-14 15:27:20 -07001434
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001435 ret = mixer_ctl_get_array(ctl, block, count);
1436 if (ret != 0) {
1437 ALOGE("%s: mixer_ctl_get_array() failed to get EDID info", __func__);
1438 return 0;
1439 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001440
1441 /* Calculate the number of SAD blocks */
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001442 num_audio_blocks = count / SAD_BLOCK_SIZE;
Eric Laurentb23d5282013-05-14 15:27:20 -07001443
1444 for (i = 0; i < num_audio_blocks; i++) {
1445 /* Only consider LPCM blocks */
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001446 if ((sad[0] >> 3) != EDID_FORMAT_LPCM) {
1447 sad += 3;
Eric Laurentb23d5282013-05-14 15:27:20 -07001448 continue;
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07001449 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001450
1451 channel_count = (sad[0] & 0x7) + 1;
1452 if (channel_count > max_channels)
1453 max_channels = channel_count;
1454
1455 /* Advance to next block */
1456 sad += 3;
1457 }
1458
1459 return max_channels;
1460}
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001461
1462static int platform_set_slowtalk(struct platform_data *my_data, bool state)
1463{
1464 int ret = 0;
1465 struct audio_device *adev = my_data->adev;
1466 struct mixer_ctl *ctl;
1467 const char *mixer_ctl_name = "Slowtalk Enable";
1468 uint32_t set_values[ ] = {0,
1469 ALL_SESSION_VSID};
1470
1471 set_values[0] = state;
1472 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1473 if (!ctl) {
1474 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1475 __func__, mixer_ctl_name);
1476 ret = -EINVAL;
1477 } else {
1478 ALOGV("Setting slowtalk state: %d", state);
1479 ret = mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1480 my_data->slowtalk = state;
1481 }
1482
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001483 if (my_data->csd != NULL) {
1484 ret = my_data->csd->slow_talk(ALL_SESSION_VSID, state);
1485 if (ret < 0) {
1486 ALOGE("%s: csd_client_disable_device, failed, error %d",
1487 __func__, ret);
1488 }
1489 }
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001490 return ret;
1491}
1492
1493int platform_set_parameters(void *platform, struct str_parms *parms)
1494{
1495 struct platform_data *my_data = (struct platform_data *)platform;
1496 char *str;
Vidyakumar Athota3ade2792013-12-02 11:02:20 -08001497 char value[256] = {0};
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001498 int val;
Shiv Maliyappanahalli3e064fd2013-12-16 15:54:40 -08001499 int ret = 0, err;
Krishnankutty Kolathappilly301cc362014-01-31 18:12:13 -08001500 char *kv_pairs = str_parms_to_str(parms);
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001501
Krishnankutty Kolathappilly301cc362014-01-31 18:12:13 -08001502 ALOGV_IF(kv_pairs != NULL, "%s: enter: %s", __func__, kv_pairs);
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001503
Shiv Maliyappanahalli3e064fd2013-12-16 15:54:40 -08001504 err = str_parms_get_int(parms, AUDIO_PARAMETER_KEY_BTSCO, &val);
1505 if (err >= 0) {
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001506 str_parms_del(parms, AUDIO_PARAMETER_KEY_BTSCO);
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001507 my_data->btsco_sample_rate = val;
Vidyakumar Athota67c42712013-12-04 14:03:06 -08001508 if (val == SAMPLE_RATE_16KHZ) {
1509 audio_route_apply_path(my_data->adev->audio_route,
1510 "bt-sco-wb-samplerate");
1511 audio_route_update_mixer(my_data->adev->audio_route);
1512 }
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001513 }
1514
Shiv Maliyappanahalli3e064fd2013-12-16 15:54:40 -08001515 err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SLOWTALK, value, sizeof(value));
1516 if (err >= 0) {
Vidyakumar Athota3ade2792013-12-02 11:02:20 -08001517 bool state = false;
1518 if (!strncmp("true", value, sizeof("true"))) {
1519 state = true;
1520 }
1521
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001522 str_parms_del(parms, AUDIO_PARAMETER_KEY_SLOWTALK);
Vidyakumar Athota3ade2792013-12-02 11:02:20 -08001523 ret = platform_set_slowtalk(my_data, state);
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001524 if (ret)
1525 ALOGE("%s: Failed to set slow talk err: %d", __func__, ret);
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001526 }
1527
Shiv Maliyappanahalli3e064fd2013-12-16 15:54:40 -08001528 err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_VOLUME_BOOST,
Ben Rombergerc1dc70d2013-12-19 15:11:17 -08001529 value, sizeof(value));
Shiv Maliyappanahalli3e064fd2013-12-16 15:54:40 -08001530 if (err >= 0) {
Ben Rombergerc1dc70d2013-12-19 15:11:17 -08001531 str_parms_del(parms, AUDIO_PARAMETER_KEY_VOLUME_BOOST);
1532
1533 if (my_data->acdb_reload_vocvoltable == NULL) {
1534 ALOGE("%s: acdb_reload_vocvoltable is NULL", __func__);
1535 } else if (!strcmp(value, "on")) {
1536 if (!my_data->acdb_reload_vocvoltable(VOICE_FEATURE_SET_VOLUME_BOOST)) {
1537 my_data->voice_feature_set = 1;
1538 }
1539 } else {
1540 if (!my_data->acdb_reload_vocvoltable(VOICE_FEATURE_SET_DEFAULT)) {
1541 my_data->voice_feature_set = 0;
1542 }
1543 }
1544 }
1545
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001546 ALOGV("%s: exit with code(%d)", __func__, ret);
Krishnankutty Kolathappilly301cc362014-01-31 18:12:13 -08001547 free(kv_pairs);
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001548 return ret;
1549}
1550
Vidyakumar Athota2850d532013-11-19 16:02:12 -08001551int platform_set_incall_recording_session_id(void *platform,
1552 uint32_t session_id, int rec_mode)
Shiv Maliyappanahallida107642013-10-17 11:16:13 -07001553{
1554 int ret = 0;
1555 struct platform_data *my_data = (struct platform_data *)platform;
1556 struct audio_device *adev = my_data->adev;
1557 struct mixer_ctl *ctl;
1558 const char *mixer_ctl_name = "Voc VSID";
1559 int num_ctl_values;
1560 int i;
1561
1562 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1563 if (!ctl) {
1564 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1565 __func__, mixer_ctl_name);
1566 ret = -EINVAL;
1567 } else {
1568 num_ctl_values = mixer_ctl_get_num_values(ctl);
1569 for (i = 0; i < num_ctl_values; i++) {
1570 if (mixer_ctl_set_value(ctl, i, session_id)) {
1571 ALOGV("Error: invalid session_id: %x", session_id);
1572 ret = -EINVAL;
1573 break;
1574 }
1575 }
1576 }
1577
Vidyakumar Athota2850d532013-11-19 16:02:12 -08001578 if (my_data->csd != NULL) {
1579 ret = my_data->csd->start_record(ALL_SESSION_VSID, rec_mode);
1580 if (ret < 0) {
1581 ALOGE("%s: csd_client_start_record failed, error %d",
1582 __func__, ret);
1583 }
1584 }
1585
1586 return ret;
1587}
1588
1589int platform_stop_incall_recording_usecase(void *platform)
1590{
1591 int ret = 0;
1592 struct platform_data *my_data = (struct platform_data *)platform;
1593
1594 if (my_data->csd != NULL) {
1595 ret = my_data->csd->stop_record(ALL_SESSION_VSID);
1596 if (ret < 0) {
1597 ALOGE("%s: csd_client_stop_record failed, error %d",
1598 __func__, ret);
1599 }
1600 }
1601
1602 return ret;
1603}
1604
1605int platform_start_incall_music_usecase(void *platform)
1606{
1607 int ret = 0;
1608 struct platform_data *my_data = (struct platform_data *)platform;
1609
1610 if (my_data->csd != NULL) {
1611 ret = my_data->csd->start_playback(ALL_SESSION_VSID);
1612 if (ret < 0) {
1613 ALOGE("%s: csd_client_start_playback failed, error %d",
1614 __func__, ret);
1615 }
1616 }
1617
1618 return ret;
1619}
1620
1621int platform_stop_incall_music_usecase(void *platform)
1622{
1623 int ret = 0;
1624 struct platform_data *my_data = (struct platform_data *)platform;
1625
1626 if (my_data->csd != NULL) {
1627 ret = my_data->csd->stop_playback(ALL_SESSION_VSID);
1628 if (ret < 0) {
1629 ALOGE("%s: csd_client_stop_playback failed, error %d",
1630 __func__, ret);
1631 }
1632 }
1633
Shiv Maliyappanahallida107642013-10-17 11:16:13 -07001634 return ret;
1635}
1636
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001637void platform_get_parameters(void *platform,
1638 struct str_parms *query,
1639 struct str_parms *reply)
1640{
1641 struct platform_data *my_data = (struct platform_data *)platform;
1642 char *str = NULL;
1643 char value[256] = {0};
1644 int ret;
Krishnankutty Kolathappilly301cc362014-01-31 18:12:13 -08001645 char *kv_pairs = NULL;
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001646
Shiv Maliyappanahalli9d899292013-11-20 14:43:01 -08001647 ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_SLOWTALK,
1648 value, sizeof(value));
1649 if (ret >= 0) {
Vidyakumar Athota3ade2792013-12-02 11:02:20 -08001650 str_parms_add_str(reply, AUDIO_PARAMETER_KEY_SLOWTALK,
1651 my_data->slowtalk?"true":"false");
Shiv Maliyappanahalli9d899292013-11-20 14:43:01 -08001652 }
1653
Ben Rombergerc1dc70d2013-12-19 15:11:17 -08001654 ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_VOLUME_BOOST,
1655 value, sizeof(value));
1656 if (ret >= 0) {
1657 if (my_data->voice_feature_set == VOICE_FEATURE_SET_VOLUME_BOOST) {
1658 strlcpy(value, "on", sizeof(value));
1659 } else {
1660 strlcpy(value, "off", sizeof(value));
1661 }
1662
1663 str_parms_add_str(reply, AUDIO_PARAMETER_KEY_VOLUME_BOOST, value);
1664 }
1665
Krishnankutty Kolathappilly301cc362014-01-31 18:12:13 -08001666 kv_pairs = str_parms_to_str(reply);
1667 ALOGV_IF(kv_pairs != NULL, "%s: exit: returns - %s", __func__, kv_pairs);
Narsinga Rao Chelladb712ed2014-02-13 11:44:31 -08001668 free(kv_pairs);
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001669}
1670
Haynes Mathew George7ff216f2013-09-11 19:51:41 -07001671/* Delay in Us */
1672int64_t platform_render_latency(audio_usecase_t usecase)
1673{
1674 switch (usecase) {
1675 case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
1676 return DEEP_BUFFER_PLATFORM_DELAY;
1677 case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
1678 return LOW_LATENCY_PLATFORM_DELAY;
1679 default:
1680 return 0;
1681 }
1682}
Preetam Singh Ranawatde84f1a2013-11-01 14:58:16 -07001683
Mingming Yine62d7842013-10-25 16:26:03 -07001684int platform_update_usecase_from_source(int source, int usecase)
Preetam Singh Ranawatde84f1a2013-11-01 14:58:16 -07001685{
Mingming Yinab429782013-11-07 11:16:55 -08001686 ALOGV("%s: input source :%d", __func__, source);
1687 if(source == AUDIO_SOURCE_FM_RX_A2DP)
Mingming Yine62d7842013-10-25 16:26:03 -07001688 usecase = USECASE_AUDIO_RECORD_FM_VIRTUAL;
1689 return usecase;
Preetam Singh Ranawatde84f1a2013-11-01 14:58:16 -07001690}
Kiran Kandide144c82013-11-20 15:58:32 -08001691
1692bool platform_listen_update_status(snd_device_t snd_device)
1693{
1694 if ((snd_device >= SND_DEVICE_IN_BEGIN) &&
1695 (snd_device < SND_DEVICE_IN_END) &&
1696 (snd_device != SND_DEVICE_IN_CAPTURE_FM) &&
1697 (snd_device != SND_DEVICE_IN_CAPTURE_VI_FEEDBACK))
1698 return true;
1699 else
1700 return false;
1701}
ApurupaPattapu0c566872014-01-10 14:46:02 -08001702
1703/* Read offload buffer size from a property.
1704 * If value is not power of 2 round it to
1705 * power of 2.
1706 */
1707uint32_t platform_get_compress_offload_buffer_size(audio_offload_info_t* info)
1708{
1709 char value[PROPERTY_VALUE_MAX] = {0};
1710 uint32_t fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
1711 if((property_get("audio.offload.buffer.size.kb", value, "")) &&
1712 atoi(value)) {
1713 fragment_size = atoi(value) * 1024;
1714 }
1715
1716 if (info != NULL && info->has_video && info->is_streaming) {
1717 fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE_FOR_AV_STREAMING;
1718 ALOGV("%s: offload fragment size reduced for AV streaming to %d",
ApurupaPattapu28261e92014-03-05 11:13:32 -08001719 __func__, fragment_size);
ApurupaPattapu0c566872014-01-10 14:46:02 -08001720 }
1721
1722 fragment_size = ALIGN( fragment_size, 1024);
1723
1724 if(fragment_size < MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE)
1725 fragment_size = MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE;
1726 else if(fragment_size > MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE)
1727 fragment_size = MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE;
1728 ALOGV("%s: fragment_size %d", __func__, fragment_size);
1729 return fragment_size;
1730}
1731
1732uint32_t platform_get_pcm_offload_buffer_size(audio_offload_info_t* info)
1733{
1734 uint32_t fragment_size = MIN_PCM_OFFLOAD_FRAGMENT_SIZE;
1735 uint32_t bits_per_sample = 16;
1736
1737 if (info->format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD) {
1738 bits_per_sample = 32;
1739 }
1740
1741 if (!info->has_video) {
1742 fragment_size = MAX_PCM_OFFLOAD_FRAGMENT_SIZE;
1743
1744 } else if (info->has_video && info->is_streaming) {
1745 fragment_size = (PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING
1746 * info->sample_rate
ApurupaPattapu0c097d52014-04-08 10:41:07 -07001747 * (bits_per_sample >> 3)
ApurupaPattapu0c566872014-01-10 14:46:02 -08001748 * popcount(info->channel_mask))/1000;
1749
1750 } else if (info->has_video) {
1751 fragment_size = (PCM_OFFLOAD_BUFFER_DURATION_FOR_AV
1752 * info->sample_rate
ApurupaPattapu0c097d52014-04-08 10:41:07 -07001753 * (bits_per_sample >> 3)
ApurupaPattapu0c566872014-01-10 14:46:02 -08001754 * popcount(info->channel_mask))/1000;
1755 }
1756
ApurupaPattapu0c097d52014-04-08 10:41:07 -07001757 char value[PROPERTY_VALUE_MAX] = {0};
1758 if((property_get("audio.offload.pcm.buffer.size", value, "")) &&
1759 atoi(value)) {
1760 fragment_size = atoi(value) * 1024;
1761 ALOGV("Using buffer size from sys prop %d", fragment_size);
1762 }
1763
ApurupaPattapu0c566872014-01-10 14:46:02 -08001764 fragment_size = ALIGN( fragment_size, 1024);
1765
1766 if(fragment_size < MIN_PCM_OFFLOAD_FRAGMENT_SIZE)
1767 fragment_size = MIN_PCM_OFFLOAD_FRAGMENT_SIZE;
1768 else if(fragment_size > MAX_PCM_OFFLOAD_FRAGMENT_SIZE)
1769 fragment_size = MAX_PCM_OFFLOAD_FRAGMENT_SIZE;
1770
1771 ALOGV("%s: fragment_size %d", __func__, fragment_size);
1772 return fragment_size;
1773}
1774