blob: 1a535ac1ce49f9b3b28f1512913a517c42dd37c3 [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>
Anish Kumar55e6df22014-08-26 17:38:05 -070026#include <fcntl.h>
Vidyakumar Athota21b3bb92014-04-25 11:08:08 -070027#include <sys/ioctl.h>
Eric Laurentb23d5282013-05-14 15:27:20 -070028#include <cutils/log.h>
29#include <cutils/properties.h>
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -070030#include <cutils/str_parms.h>
Eric Laurentb23d5282013-05-14 15:27:20 -070031#include <audio_hw.h>
32#include <platform_api.h>
33#include "platform.h"
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -070034#include "audio_extn.h"
Narsinga Rao Chella05573b72013-11-15 15:21:40 -080035#include "voice_extn.h"
ApurupaPattapuc6a3a9e2014-01-10 14:46:02 -080036#include "sound/compress_params.h"
Anish Kumar55e6df22014-08-26 17:38:05 -070037#include "sound/msmcal-hwdep.h"
Eric Laurentb23d5282013-05-14 15:27:20 -070038
Anish Kumar55e6df22014-08-26 17:38:05 -070039#define SOUND_TRIGGER_DEVICE_HANDSET_MONO_LOW_POWER_ACDB_ID (100)
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -070040#define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
Damir Didjustof1d46c72013-11-06 17:59:04 -080041#define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml"
Helen Zeng6a16ad72014-02-23 22:04:44 -080042#define MIXER_XML_PATH_I2S "/system/etc/mixer_paths_i2s.xml"
43
44#define PLATFORM_INFO_XML_PATH "/system/etc/audio_platform_info.xml"
45#define PLATFORM_INFO_XML_PATH_I2S "/system/etc/audio_platform_info_i2s.xml"
46
Eric Laurentb23d5282013-05-14 15:27:20 -070047#define LIB_ACDB_LOADER "libacdbloader.so"
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -070048#define AUDIO_DATA_BLOCK_MIXER_CTL "HDMI EDID"
Walter Yang6f800052014-07-14 16:15:38 -070049#define CVD_VERSION_MIXER_CTL "CVD Version"
Eric Laurentb23d5282013-05-14 15:27:20 -070050
ApurupaPattapuc6a3a9e2014-01-10 14:46:02 -080051#define MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE (256 * 1024)
52#define MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE (2 * 1024)
53#define COMPRESS_OFFLOAD_FRAGMENT_SIZE_FOR_AV_STREAMING (2 * 1024)
54#define COMPRESS_OFFLOAD_FRAGMENT_SIZE (32 * 1024)
55
56/* Used in calculating fragment size for pcm offload */
ApurupaPattapub57da782014-04-08 10:41:07 -070057#define PCM_OFFLOAD_BUFFER_DURATION_FOR_AV 1000 /* 1 sec */
58#define PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING 80 /* 80 millisecs */
ApurupaPattapuc6a3a9e2014-01-10 14:46:02 -080059
60/* MAX PCM fragment size cannot be increased further due
61 * to flinger's cblk size of 1mb,and it has to be a multiple of
62 * 24 - lcm of channels supported by DSP
63 */
64#define MAX_PCM_OFFLOAD_FRAGMENT_SIZE (240 * 1024)
ApurupaPattapub57da782014-04-08 10:41:07 -070065#define MIN_PCM_OFFLOAD_FRAGMENT_SIZE (4 * 1024)
ApurupaPattapuc6a3a9e2014-01-10 14:46:02 -080066
67#define ALIGN( num, to ) (((num) + (to-1)) & (~(to-1)))
Eric Laurentb23d5282013-05-14 15:27:20 -070068/*
Eric Laurentb23d5282013-05-14 15:27:20 -070069 * This file will have a maximum of 38 bytes:
70 *
71 * 4 bytes: number of audio blocks
72 * 4 bytes: total length of Short Audio Descriptor (SAD) blocks
73 * Maximum 10 * 3 bytes: SAD blocks
74 */
75#define MAX_SAD_BLOCKS 10
76#define SAD_BLOCK_SIZE 3
77
Walter Yang6f800052014-07-14 16:15:38 -070078#define MAX_CVD_VERSION_STRING_SIZE 100
79
Eric Laurentb23d5282013-05-14 15:27:20 -070080/* EDID format ID for LPCM audio */
81#define EDID_FORMAT_LPCM 1
82
Subhash Chandra Bose Naripeddy54274672014-03-10 14:51:02 -070083/* fallback app type if the default app type from acdb loader fails */
84#define DEFAULT_APP_TYPE 0x11130
85
sangwoo1b9f4b32013-06-21 18:22:55 -070086/* Retry for delay in FW loading*/
87#define RETRY_NUMBER 10
88#define RETRY_US 500000
Apoorv Raghuvanshi84fa2fe2013-12-04 11:57:47 -080089#define MAX_SND_CARD 8
sangwoo1b9f4b32013-06-21 18:22:55 -070090
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -070091#define SAMPLE_RATE_8KHZ 8000
92#define SAMPLE_RATE_16KHZ 16000
93
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -070094#define AUDIO_PARAMETER_KEY_FLUENCE_TYPE "fluence"
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -070095#define AUDIO_PARAMETER_KEY_SLOWTALK "st_enable"
Avinash Vaishd5fa4572014-09-15 14:41:14 +053096#define AUDIO_PARAMETER_KEY_HD_VOICE "hd_voice"
Ben Rombergerc1dc70d2013-12-19 15:11:17 -080097#define AUDIO_PARAMETER_KEY_VOLUME_BOOST "volume_boost"
Tanya Finkel00130052014-07-14 04:26:56 -070098/* Query external audio device connection status */
99#define AUDIO_PARAMETER_KEY_EXT_AUDIO_DEVICE "ext_audio_device"
100
101#define EVENT_EXTERNAL_SPK_1 "qc_ext_spk_1"
102#define EVENT_EXTERNAL_SPK_2 "qc_ext_spk_2"
103#define EVENT_EXTERNAL_MIC "qc_ext_mic"
Anish Kumar55e6df22014-08-26 17:38:05 -0700104#define MAX_CAL_NAME 20
105
106char cal_name_info[WCD9XXX_MAX_CAL][MAX_CAL_NAME] = {
107 [WCD9XXX_ANC_CAL] = "anc_cal",
108 [WCD9XXX_MBHC_CAL] = "mbhc_cal",
109 [WCD9XXX_MAD_CAL] = "mad_cal",
110};
Ben Rombergerc1dc70d2013-12-19 15:11:17 -0800111
112enum {
113 VOICE_FEATURE_SET_DEFAULT,
114 VOICE_FEATURE_SET_VOLUME_BOOST
115};
sangwoo53b2cf02013-07-25 19:18:44 -0700116
Eric Laurentb23d5282013-05-14 15:27:20 -0700117struct audio_block_header
118{
119 int reserved;
120 int length;
121};
122
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800123/* Audio calibration related functions */
Eric Laurentb23d5282013-05-14 15:27:20 -0700124typedef void (*acdb_deallocate_t)();
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -0700125typedef int (*acdb_init_t)(const char *, char *);
Subhash Chandra Bose Naripeddy54274672014-03-10 14:51:02 -0700126typedef void (*acdb_send_audio_cal_t)(int, int, int , int);
Eric Laurentb23d5282013-05-14 15:27:20 -0700127typedef void (*acdb_send_voice_cal_t)(int, int);
Ben Rombergerc1dc70d2013-12-19 15:11:17 -0800128typedef int (*acdb_reload_vocvoltable_t)(int);
Subhash Chandra Bose Naripeddy54274672014-03-10 14:51:02 -0700129typedef int (*acdb_get_default_app_type_t)(void);
Anish Kumar55e6df22014-08-26 17:38:05 -0700130typedef int (*acdb_loader_get_calibration_t)(char *attr, int size, void *data);
131acdb_loader_get_calibration_t acdb_loader_get_calibration;
Eric Laurentb23d5282013-05-14 15:27:20 -0700132
Eric Laurentb23d5282013-05-14 15:27:20 -0700133struct platform_data {
134 struct audio_device *adev;
135 bool fluence_in_spkr_mode;
136 bool fluence_in_voice_call;
137 bool fluence_in_voice_rec;
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800138 bool fluence_in_audio_rec;
Tanya Finkel00130052014-07-14 04:26:56 -0700139 bool external_spk_1;
140 bool external_spk_2;
141 bool external_mic;
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700142 int fluence_type;
Narsinga Rao Chella61e0f9b2014-03-06 21:25:22 -0800143 int fluence_mode;
Venkata Narendra Kumar Gutta88fd0bc2014-03-27 19:47:56 +0530144 char fluence_cap[PROPERTY_VALUE_MAX];
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700145 bool slowtalk;
Avinash Vaishd5fa4572014-09-15 14:41:14 +0530146 bool hd_voice;
Venkata Narendra Kumar Gutta1bbbf542014-09-04 19:11:25 +0530147 bool ec_ref_enabled;
Helen Zeng6a16ad72014-02-23 22:04:44 -0800148 bool is_i2s_ext_modem;
Ravi Kumar Alamanda48c921d2013-10-29 06:07:44 -0700149 /* Audio calibration related functions */
Ben Rombergerc1dc70d2013-12-19 15:11:17 -0800150 void *acdb_handle;
151 int voice_feature_set;
152 acdb_init_t acdb_init;
153 acdb_deallocate_t acdb_deallocate;
154 acdb_send_audio_cal_t acdb_send_audio_cal;
155 acdb_send_voice_cal_t acdb_send_voice_cal;
156 acdb_reload_vocvoltable_t acdb_reload_vocvoltable;
Subhash Chandra Bose Naripeddy54274672014-03-10 14:51:02 -0700157 acdb_get_default_app_type_t acdb_get_default_app_type;
Ravi Kumar Alamanda48c921d2013-10-29 06:07:44 -0700158
159 void *hw_info;
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800160 struct csd_data *csd;
Eric Laurentb23d5282013-05-14 15:27:20 -0700161};
162
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700163static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700164 [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {DEEP_BUFFER_PCM_DEVICE,
165 DEEP_BUFFER_PCM_DEVICE},
166 [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
Preetam Singh Ranawatde84f1a2013-11-01 14:58:16 -0700167 LOWLATENCY_PCM_DEVICE},
168 [USECASE_AUDIO_PLAYBACK_MULTI_CH] = {MULTIMEDIA2_PCM_DEVICE,
169 MULTIMEDIA2_PCM_DEVICE},
Krishnankutty Kolathappillya43f96e2013-11-01 12:17:53 -0700170 [USECASE_AUDIO_PLAYBACK_OFFLOAD] =
171 {PLAYBACK_OFFLOAD_DEVICE, PLAYBACK_OFFLOAD_DEVICE},
Subhash Chandra Bose Naripeddy16ff4f82014-04-01 21:03:10 -0700172#ifdef MULTIPLE_OFFLOAD_ENABLED
173 [USECASE_AUDIO_PLAYBACK_OFFLOAD2] =
174 {PLAYBACK_OFFLOAD_DEVICE2, PLAYBACK_OFFLOAD_DEVICE2},
175 [USECASE_AUDIO_PLAYBACK_OFFLOAD3] =
176 {PLAYBACK_OFFLOAD_DEVICE3, PLAYBACK_OFFLOAD_DEVICE3},
177 [USECASE_AUDIO_PLAYBACK_OFFLOAD4] =
178 {PLAYBACK_OFFLOAD_DEVICE4, PLAYBACK_OFFLOAD_DEVICE4},
179 [USECASE_AUDIO_PLAYBACK_OFFLOAD5] =
180 {PLAYBACK_OFFLOAD_DEVICE5, PLAYBACK_OFFLOAD_DEVICE5},
181 [USECASE_AUDIO_PLAYBACK_OFFLOAD6] =
182 {PLAYBACK_OFFLOAD_DEVICE6, PLAYBACK_OFFLOAD_DEVICE6},
183 [USECASE_AUDIO_PLAYBACK_OFFLOAD7] =
184 {PLAYBACK_OFFLOAD_DEVICE7, PLAYBACK_OFFLOAD_DEVICE7},
185 [USECASE_AUDIO_PLAYBACK_OFFLOAD8] =
186 {PLAYBACK_OFFLOAD_DEVICE8, PLAYBACK_OFFLOAD_DEVICE8},
187 [USECASE_AUDIO_PLAYBACK_OFFLOAD9] =
188 {PLAYBACK_OFFLOAD_DEVICE9, PLAYBACK_OFFLOAD_DEVICE9},
189#endif
Shiv Maliyappanahallida107642013-10-17 11:16:13 -0700190 [USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE, AUDIO_RECORD_PCM_DEVICE},
Mingming Yine62d7842013-10-25 16:26:03 -0700191 [USECASE_AUDIO_RECORD_COMPRESS] = {COMPRESS_CAPTURE_DEVICE, COMPRESS_CAPTURE_DEVICE},
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700192 [USECASE_AUDIO_RECORD_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
193 LOWLATENCY_PCM_DEVICE},
Preetam Singh Ranawatde84f1a2013-11-01 14:58:16 -0700194 [USECASE_AUDIO_RECORD_FM_VIRTUAL] = {MULTIMEDIA2_PCM_DEVICE,
195 MULTIMEDIA2_PCM_DEVICE},
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -0700196 [USECASE_AUDIO_PLAYBACK_FM] = {FM_PLAYBACK_PCM_DEVICE, FM_CAPTURE_PCM_DEVICE},
Vimal Puthanveed5b4d3f12013-11-05 15:57:39 -0800197 [USECASE_AUDIO_HFP_SCO] = {HFP_PCM_RX, HFP_SCO_RX},
Vimal Puthanveed47e64852013-12-20 13:23:39 -0800198 [USECASE_AUDIO_HFP_SCO_WB] = {HFP_PCM_RX, HFP_SCO_RX},
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700199 [USECASE_VOICE_CALL] = {VOICE_CALL_PCM_DEVICE, VOICE_CALL_PCM_DEVICE},
200 [USECASE_VOICE2_CALL] = {VOICE2_CALL_PCM_DEVICE, VOICE2_CALL_PCM_DEVICE},
201 [USECASE_VOLTE_CALL] = {VOLTE_CALL_PCM_DEVICE, VOLTE_CALL_PCM_DEVICE},
202 [USECASE_QCHAT_CALL] = {QCHAT_CALL_PCM_DEVICE, QCHAT_CALL_PCM_DEVICE},
Vicky Sehrawat7e4fc152014-02-12 17:58:59 -0800203 [USECASE_VOWLAN_CALL] = {VOWLAN_CALL_PCM_DEVICE, VOWLAN_CALL_PCM_DEVICE},
Narsinga Rao Chella05573b72013-11-15 15:21:40 -0800204 [USECASE_COMPRESS_VOIP_CALL] = {COMPRESS_VOIP_CALL_PCM_DEVICE, COMPRESS_VOIP_CALL_PCM_DEVICE},
Shiv Maliyappanahallida107642013-10-17 11:16:13 -0700205 [USECASE_INCALL_REC_UPLINK] = {AUDIO_RECORD_PCM_DEVICE,
206 AUDIO_RECORD_PCM_DEVICE},
207 [USECASE_INCALL_REC_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
208 AUDIO_RECORD_PCM_DEVICE},
209 [USECASE_INCALL_REC_UPLINK_AND_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
210 AUDIO_RECORD_PCM_DEVICE},
Helen Zenge56b4852013-12-03 16:54:40 -0800211 [USECASE_INCALL_REC_UPLINK_COMPRESS] = {COMPRESS_CAPTURE_DEVICE,
212 COMPRESS_CAPTURE_DEVICE},
213 [USECASE_INCALL_REC_DOWNLINK_COMPRESS] = {COMPRESS_CAPTURE_DEVICE,
214 COMPRESS_CAPTURE_DEVICE},
215 [USECASE_INCALL_REC_UPLINK_AND_DOWNLINK_COMPRESS] = {COMPRESS_CAPTURE_DEVICE,
216 COMPRESS_CAPTURE_DEVICE},
Shiv Maliyappanahallif3b9a422013-10-22 16:38:08 -0700217 [USECASE_INCALL_MUSIC_UPLINK] = {INCALL_MUSIC_UPLINK_PCM_DEVICE,
218 INCALL_MUSIC_UPLINK_PCM_DEVICE},
219 [USECASE_INCALL_MUSIC_UPLINK2] = {INCALL_MUSIC_UPLINK2_PCM_DEVICE,
220 INCALL_MUSIC_UPLINK2_PCM_DEVICE},
Gopikrishnaiah Anandanf538cef2013-10-28 14:06:03 -0700221 [USECASE_AUDIO_SPKR_CALIB_RX] = {SPKR_PROT_CALIB_RX_PCM_DEVICE, -1},
222 [USECASE_AUDIO_SPKR_CALIB_TX] = {-1, SPKR_PROT_CALIB_TX_PCM_DEVICE},
Eric Laurentb23d5282013-05-14 15:27:20 -0700223};
224
225/* Array to store sound devices */
226static const char * const device_table[SND_DEVICE_MAX] = {
227 [SND_DEVICE_NONE] = "none",
228 /* Playback sound devices */
229 [SND_DEVICE_OUT_HANDSET] = "handset",
230 [SND_DEVICE_OUT_SPEAKER] = "speaker",
Tanya Finkel00130052014-07-14 04:26:56 -0700231 [SND_DEVICE_OUT_SPEAKER_EXTERNAL_1] = "speaker-ext-1",
232 [SND_DEVICE_OUT_SPEAKER_EXTERNAL_2] = "speaker-ext-2",
Eric Laurentb23d5282013-05-14 15:27:20 -0700233 [SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
234 [SND_DEVICE_OUT_HEADPHONES] = "headphones",
235 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
Tanya Finkel00130052014-07-14 04:26:56 -0700236 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1] = "speaker-and-headphones-ext-1",
237 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2] = "speaker-and-headphones-ext-2",
Eric Laurentb23d5282013-05-14 15:27:20 -0700238 [SND_DEVICE_OUT_VOICE_HANDSET] = "voice-handset",
239 [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
240 [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
241 [SND_DEVICE_OUT_HDMI] = "hdmi",
242 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
243 [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700244 [SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
Eric Laurentb23d5282013-05-14 15:27:20 -0700245 [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
246 [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
247 [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -0700248 [SND_DEVICE_OUT_AFE_PROXY] = "afe-proxy",
249 [SND_DEVICE_OUT_USB_HEADSET] = "usb-headphones",
250 [SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = "speaker-and-usb-headphones",
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -0700251 [SND_DEVICE_OUT_TRANSMISSION_FM] = "transmission-fm",
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -0700252 [SND_DEVICE_OUT_ANC_HEADSET] = "anc-headphones",
253 [SND_DEVICE_OUT_ANC_FB_HEADSET] = "anc-fb-headphones",
254 [SND_DEVICE_OUT_VOICE_ANC_HEADSET] = "voice-anc-headphones",
255 [SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET] = "voice-anc-fb-headphones",
256 [SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET] = "speaker-and-anc-headphones",
257 [SND_DEVICE_OUT_ANC_HANDSET] = "anc-handset",
Gopikrishnaiah Anandanf538cef2013-10-28 14:06:03 -0700258 [SND_DEVICE_OUT_SPEAKER_PROTECTED] = "speaker-protected",
Anish Kumar46c7b872014-09-09 01:49:44 -0700259 [SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = "voice-speaker-protected",
Eric Laurentb23d5282013-05-14 15:27:20 -0700260
261 /* Capture sound devices */
262 [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
Tanya Finkel00130052014-07-14 04:26:56 -0700263 [SND_DEVICE_IN_HANDSET_MIC_EXTERNAL] = "handset-mic-ext",
Eric Laurentb23d5282013-05-14 15:27:20 -0700264 [SND_DEVICE_IN_HANDSET_MIC_AEC] = "handset-mic",
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800265 [SND_DEVICE_IN_HANDSET_MIC_NS] = "handset-mic",
266 [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = "handset-mic",
267 [SND_DEVICE_IN_HANDSET_DMIC] = "dmic-endfire",
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800268 [SND_DEVICE_IN_HANDSET_DMIC_AEC] = "dmic-endfire",
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800269 [SND_DEVICE_IN_HANDSET_DMIC_NS] = "dmic-endfire",
270 [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = "dmic-endfire",
271 [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800272 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "speaker-mic",
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800273 [SND_DEVICE_IN_SPEAKER_MIC_NS] = "speaker-mic",
274 [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = "speaker-mic",
275 [SND_DEVICE_IN_SPEAKER_DMIC] = "speaker-dmic-endfire",
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800276 [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = "speaker-dmic-endfire",
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800277 [SND_DEVICE_IN_SPEAKER_DMIC_NS] = "speaker-dmic-endfire",
278 [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = "speaker-dmic-endfire",
279 [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
280 [SND_DEVICE_IN_HEADSET_MIC_FLUENCE] = "headset-mic",
Eric Laurentb23d5282013-05-14 15:27:20 -0700281 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
282 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
283 [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
284 [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
Vicky Sehrawate240e5d2014-08-12 17:17:04 -0700285 [SND_DEVICE_IN_BT_SCO_MIC_NREC] = "bt-sco-mic",
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700286 [SND_DEVICE_IN_BT_SCO_MIC_WB] = "bt-sco-mic-wb",
Vicky Sehrawate240e5d2014-08-12 17:17:04 -0700287 [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = "bt-sco-mic-wb",
Eric Laurentb23d5282013-05-14 15:27:20 -0700288 [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700289 [SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700290 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = "voice-speaker-dmic-ef",
Vidyakumar Athotaadfe4e32013-12-13 14:51:26 -0800291 [SND_DEVICE_IN_VOICE_SPEAKER_QMIC] = "voice-speaker-qmic",
Eric Laurentb23d5282013-05-14 15:27:20 -0700292 [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = "voice-tty-full-headset-mic",
293 [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = "voice-tty-vco-handset-mic",
294 [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = "voice-tty-hco-headset-mic",
295 [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800296 [SND_DEVICE_IN_VOICE_REC_MIC_NS] = "voice-rec-mic",
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800297 [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = "voice-rec-dmic-ef",
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700298 [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = "voice-rec-dmic-ef-fluence",
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -0700299 [SND_DEVICE_IN_USB_HEADSET_MIC] = "usb-headset-mic",
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -0700300 [SND_DEVICE_IN_CAPTURE_FM] = "capture-fm",
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -0700301 [SND_DEVICE_IN_AANC_HANDSET_MIC] = "aanc-handset-mic",
Apoorv Raghuvanshi6178a3f2013-10-19 12:38:54 -0700302 [SND_DEVICE_IN_QUAD_MIC] = "quad-mic",
Apoorv Raghuvanshi6bd8dbf2013-10-19 18:37:52 -0700303 [SND_DEVICE_IN_HANDSET_STEREO_DMIC] = "handset-stereo-dmic-ef",
304 [SND_DEVICE_IN_SPEAKER_STEREO_DMIC] = "speaker-stereo-dmic-ef",
Gopikrishnaiah Anandanf538cef2013-10-28 14:06:03 -0700305 [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = "vi-feedback",
Narsinga Rao Chella61e0f9b2014-03-06 21:25:22 -0800306 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BROADSIDE] = "voice-speaker-dmic-broadside",
307 [SND_DEVICE_IN_SPEAKER_DMIC_BROADSIDE] = "speaker-dmic-broadside",
308 [SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE] = "speaker-dmic-broadside",
309 [SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE] = "speaker-dmic-broadside",
310 [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE] = "speaker-dmic-broadside",
Eric Laurentb23d5282013-05-14 15:27:20 -0700311};
312
313/* ACDB IDs (audio DSP path configuration IDs) for each sound device */
Ben Romberger55886882014-01-10 13:49:02 -0800314static int acdb_device_table[SND_DEVICE_MAX] = {
Eric Laurentb23d5282013-05-14 15:27:20 -0700315 [SND_DEVICE_NONE] = -1,
316 [SND_DEVICE_OUT_HANDSET] = 7,
Vidyakumar Athotac29d4ab2013-11-14 16:58:02 -0800317 [SND_DEVICE_OUT_SPEAKER] = 14,
Tanya Finkel00130052014-07-14 04:26:56 -0700318 [SND_DEVICE_OUT_SPEAKER_EXTERNAL_1] = 14,
319 [SND_DEVICE_OUT_SPEAKER_EXTERNAL_2] = 14,
Vidyakumar Athotac29d4ab2013-11-14 16:58:02 -0800320 [SND_DEVICE_OUT_SPEAKER_REVERSE] = 14,
Eric Laurentb23d5282013-05-14 15:27:20 -0700321 [SND_DEVICE_OUT_HEADPHONES] = 10,
322 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
Tanya Finkel00130052014-07-14 04:26:56 -0700323 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1] = 10,
324 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2] = 10,
Eric Laurentb23d5282013-05-14 15:27:20 -0700325 [SND_DEVICE_OUT_VOICE_HANDSET] = 7,
Vidyakumar Athotac29d4ab2013-11-14 16:58:02 -0800326 [SND_DEVICE_OUT_VOICE_SPEAKER] = 14,
Eric Laurentb23d5282013-05-14 15:27:20 -0700327 [SND_DEVICE_OUT_VOICE_HEADPHONES] = 10,
328 [SND_DEVICE_OUT_HDMI] = 18,
Vidyakumar Athotac29d4ab2013-11-14 16:58:02 -0800329 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 14,
Eric Laurentb23d5282013-05-14 15:27:20 -0700330 [SND_DEVICE_OUT_BT_SCO] = 22,
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700331 [SND_DEVICE_OUT_BT_SCO_WB] = 39,
Eric Laurentb23d5282013-05-14 15:27:20 -0700332 [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
333 [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
334 [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -0700335 [SND_DEVICE_OUT_AFE_PROXY] = 0,
Vidyakumar Athotab9522202014-01-14 20:08:27 -0800336 [SND_DEVICE_OUT_USB_HEADSET] = 45,
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -0700337 [SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = 14,
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -0700338 [SND_DEVICE_OUT_TRANSMISSION_FM] = 0,
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -0700339 [SND_DEVICE_OUT_ANC_HEADSET] = 26,
Ravi Kumar Alamanda48c921d2013-10-29 06:07:44 -0700340 [SND_DEVICE_OUT_ANC_FB_HEADSET] = 27,
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -0700341 [SND_DEVICE_OUT_VOICE_ANC_HEADSET] = 26,
Ravi Kumar Alamanda48c921d2013-10-29 06:07:44 -0700342 [SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET] = 27,
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -0700343 [SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET] = 26,
344 [SND_DEVICE_OUT_ANC_HANDSET] = 103,
Anish Kumar46c7b872014-09-09 01:49:44 -0700345 [SND_DEVICE_OUT_SPEAKER_PROTECTED] = 124,
346 [SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = 101,
Eric Laurentb23d5282013-05-14 15:27:20 -0700347
348 [SND_DEVICE_IN_HANDSET_MIC] = 4,
Tanya Finkel00130052014-07-14 04:26:56 -0700349 [SND_DEVICE_IN_HANDSET_MIC_EXTERNAL] = 4,
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800350 [SND_DEVICE_IN_HANDSET_MIC_AEC] = 106,
351 [SND_DEVICE_IN_HANDSET_MIC_NS] = 107,
352 [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = 108,
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800353 [SND_DEVICE_IN_HANDSET_DMIC] = 41,
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800354 [SND_DEVICE_IN_HANDSET_DMIC_AEC] = 109,
355 [SND_DEVICE_IN_HANDSET_DMIC_NS] = 110,
356 [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = 111,
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800357 [SND_DEVICE_IN_SPEAKER_MIC] = 11,
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800358 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = 112,
359 [SND_DEVICE_IN_SPEAKER_MIC_NS] = 113,
360 [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = 114,
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800361 [SND_DEVICE_IN_SPEAKER_DMIC] = 43,
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800362 [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = 115,
363 [SND_DEVICE_IN_SPEAKER_DMIC_NS] = 116,
364 [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = 117,
Eric Laurentb23d5282013-05-14 15:27:20 -0700365 [SND_DEVICE_IN_HEADSET_MIC] = 8,
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800366 [SND_DEVICE_IN_HEADSET_MIC_FLUENCE] = 47,
Eric Laurentb23d5282013-05-14 15:27:20 -0700367 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = 11,
368 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = 8,
369 [SND_DEVICE_IN_HDMI_MIC] = 4,
370 [SND_DEVICE_IN_BT_SCO_MIC] = 21,
Vicky Sehrawate240e5d2014-08-12 17:17:04 -0700371 [SND_DEVICE_IN_BT_SCO_MIC_NREC] = 122,
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700372 [SND_DEVICE_IN_BT_SCO_MIC_WB] = 38,
Vicky Sehrawate240e5d2014-08-12 17:17:04 -0700373 [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = 123,
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800374 [SND_DEVICE_IN_CAMCORDER_MIC] = 4,
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700375 [SND_DEVICE_IN_VOICE_DMIC] = 41,
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700376 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = 43,
Vidyakumar Athotaadfe4e32013-12-13 14:51:26 -0800377 [SND_DEVICE_IN_VOICE_SPEAKER_QMIC] = 19,
Eric Laurentb23d5282013-05-14 15:27:20 -0700378 [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = 16,
379 [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = 36,
380 [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = 16,
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800381 [SND_DEVICE_IN_VOICE_REC_MIC] = 4,
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800382 [SND_DEVICE_IN_VOICE_REC_MIC_NS] = 107,
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800383 [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = 34,
384 [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = 41,
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -0700385 [SND_DEVICE_IN_USB_HEADSET_MIC] = 44,
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -0700386 [SND_DEVICE_IN_CAPTURE_FM] = 0,
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -0700387 [SND_DEVICE_IN_AANC_HANDSET_MIC] = 104,
Apoorv Raghuvanshi6178a3f2013-10-19 12:38:54 -0700388 [SND_DEVICE_IN_QUAD_MIC] = 46,
Apoorv Raghuvanshi6bd8dbf2013-10-19 18:37:52 -0700389 [SND_DEVICE_IN_HANDSET_STEREO_DMIC] = 34,
390 [SND_DEVICE_IN_SPEAKER_STEREO_DMIC] = 35,
Gopikrishnaiah Anandanf538cef2013-10-28 14:06:03 -0700391 [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = 102,
Narsinga Rao Chella61e0f9b2014-03-06 21:25:22 -0800392 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BROADSIDE] = 12,
393 [SND_DEVICE_IN_SPEAKER_DMIC_BROADSIDE] = 12,
394 [SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE] = 119,
395 [SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE] = 121,
396 [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE] = 120,
Eric Laurentb23d5282013-05-14 15:27:20 -0700397};
398
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700399struct name_to_index {
Ben Romberger61764e32014-01-10 13:49:02 -0800400 char name[100];
401 unsigned int index;
402};
403
404#define TO_NAME_INDEX(X) #X, X
405
406/* Used to get index from parsed sting */
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700407static struct name_to_index snd_device_name_index[SND_DEVICE_MAX] = {
Ben Romberger61764e32014-01-10 13:49:02 -0800408 {TO_NAME_INDEX(SND_DEVICE_OUT_HANDSET)},
409 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER)},
Tanya Finkel00130052014-07-14 04:26:56 -0700410 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_EXTERNAL_1)},
411 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_EXTERNAL_2)},
Ben Romberger61764e32014-01-10 13:49:02 -0800412 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_REVERSE)},
413 {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)},
414 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)},
Tanya Finkel00130052014-07-14 04:26:56 -0700415 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1)},
416 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2)},
Ben Romberger61764e32014-01-10 13:49:02 -0800417 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET)},
418 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER)},
419 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HEADPHONES)},
420 {TO_NAME_INDEX(SND_DEVICE_OUT_HDMI)},
421 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)},
422 {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
423 {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO_WB)},
424 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES)},
425 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES)},
426 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET)},
427 {TO_NAME_INDEX(SND_DEVICE_OUT_AFE_PROXY)},
428 {TO_NAME_INDEX(SND_DEVICE_OUT_USB_HEADSET)},
429 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET)},
430 {TO_NAME_INDEX(SND_DEVICE_OUT_TRANSMISSION_FM)},
431 {TO_NAME_INDEX(SND_DEVICE_OUT_ANC_HEADSET)},
432 {TO_NAME_INDEX(SND_DEVICE_OUT_ANC_FB_HEADSET)},
433 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_ANC_HEADSET)},
434 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET)},
435 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET)},
436 {TO_NAME_INDEX(SND_DEVICE_OUT_ANC_HANDSET)},
437 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_PROTECTED)},
Anish Kumar46c7b872014-09-09 01:49:44 -0700438 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED)},
Ben Romberger61764e32014-01-10 13:49:02 -0800439 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC)},
Tanya Finkel00130052014-07-14 04:26:56 -0700440 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_EXTERNAL)},
Ben Romberger61764e32014-01-10 13:49:02 -0800441 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC)},
442 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_NS)},
443 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)},
444 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC)},
445 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC)},
446 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_NS)},
447 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)},
448 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC)},
449 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC)},
450 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_NS)},
451 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)},
452 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC)},
453 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC)},
454 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_NS)},
455 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)},
456 {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC)},
457 {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC_FLUENCE)},
458 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC)},
459 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_HEADSET_MIC)},
460 {TO_NAME_INDEX(SND_DEVICE_IN_HDMI_MIC)},
461 {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC)},
Vicky Sehrawate240e5d2014-08-12 17:17:04 -0700462 {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_NREC)},
Ben Romberger61764e32014-01-10 13:49:02 -0800463 {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB)},
Vicky Sehrawate240e5d2014-08-12 17:17:04 -0700464 {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB_NREC)},
Ben Romberger61764e32014-01-10 13:49:02 -0800465 {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
466 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC)},
467 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_DMIC)},
468 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_QMIC)},
469 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC)},
470 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC)},
471 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC)},
472 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC)},
473 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC_NS)},
474 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_STEREO)},
475 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE)},
476 {TO_NAME_INDEX(SND_DEVICE_IN_USB_HEADSET_MIC)},
477 {TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_FM)},
478 {TO_NAME_INDEX(SND_DEVICE_IN_AANC_HANDSET_MIC)},
479 {TO_NAME_INDEX(SND_DEVICE_IN_QUAD_MIC)},
480 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_STEREO_DMIC)},
481 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_STEREO_DMIC)},
482 {TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_VI_FEEDBACK)},
Narsinga Rao Chella61e0f9b2014-03-06 21:25:22 -0800483 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BROADSIDE)},
484 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_BROADSIDE)},
485 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE)},
486 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE)},
487 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE)},
Ben Romberger61764e32014-01-10 13:49:02 -0800488};
489
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700490static char * backend_table[SND_DEVICE_MAX] = {0};
491
492static struct name_to_index usecase_name_index[AUDIO_USECASE_MAX] = {
493 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_DEEP_BUFFER)},
494 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_LOW_LATENCY)},
495 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_MULTI_CH)},
496 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD)},
497 {TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
498 {TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
499 {TO_NAME_INDEX(USECASE_VOICE_CALL)},
500 {TO_NAME_INDEX(USECASE_VOICE2_CALL)},
501 {TO_NAME_INDEX(USECASE_VOLTE_CALL)},
502 {TO_NAME_INDEX(USECASE_QCHAT_CALL)},
503 {TO_NAME_INDEX(USECASE_VOWLAN_CALL)},
504 {TO_NAME_INDEX(USECASE_INCALL_REC_UPLINK)},
505 {TO_NAME_INDEX(USECASE_INCALL_REC_DOWNLINK)},
506 {TO_NAME_INDEX(USECASE_INCALL_REC_UPLINK_AND_DOWNLINK)},
507 {TO_NAME_INDEX(USECASE_AUDIO_HFP_SCO)},
508};
509
Haynes Mathew George7ff216f2013-09-11 19:51:41 -0700510#define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
511#define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
512
Venkata Narendra Kumar Gutta1bbbf542014-09-04 19:11:25 +0530513void platform_set_echo_reference(void *platform, bool enable)
Eric Laurentb23d5282013-05-14 15:27:20 -0700514{
Venkata Narendra Kumar Gutta1bbbf542014-09-04 19:11:25 +0530515 struct platform_data *my_data = (struct platform_data *)platform;
516 struct audio_device *adev = my_data->adev;
517
518 if (enable) {
519 my_data->ec_ref_enabled = enable;
520 audio_route_apply_and_update_path(adev->audio_route, "echo-reference");
521 } else {
522 if (my_data->ec_ref_enabled) {
523 audio_route_reset_and_update_path(adev->audio_route, "echo-reference");
524 my_data->ec_ref_enabled = enable;
525 } else {
526 ALOGV("EC Reference is already disabled: %d", my_data->ec_ref_enabled);
527 }
528 }
Eric Laurentb23d5282013-05-14 15:27:20 -0700529
Anish Kumar4980fa12014-04-17 12:42:20 -0700530 ALOGV("Setting EC Reference: %d", enable);
Eric Laurentb23d5282013-05-14 15:27:20 -0700531}
532
Helen Zeng6a16ad72014-02-23 22:04:44 -0800533static struct csd_data *open_csd_client(bool i2s_ext_modem)
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800534{
535 struct csd_data *csd = calloc(1, sizeof(struct csd_data));
536
Haynes Mathew Georgeb51ceb12014-06-30 13:56:18 -0700537 if (!csd) {
538 ALOGE("failed to allocate csd_data mem");
539 return NULL;
540 }
541
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800542 csd->csd_client = dlopen(LIB_CSD_CLIENT, RTLD_NOW);
543 if (csd->csd_client == NULL) {
544 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_CSD_CLIENT);
545 goto error;
546 } else {
547 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_CSD_CLIENT);
548
549 csd->deinit = (deinit_t)dlsym(csd->csd_client,
550 "csd_client_deinit");
551 if (csd->deinit == NULL) {
552 ALOGE("%s: dlsym error %s for csd_client_deinit", __func__,
553 dlerror());
554 goto error;
555 }
556 csd->disable_device = (disable_device_t)dlsym(csd->csd_client,
557 "csd_client_disable_device");
558 if (csd->disable_device == NULL) {
559 ALOGE("%s: dlsym error %s for csd_client_disable_device",
560 __func__, dlerror());
561 goto error;
562 }
Vidyakumar Athota545dbd32013-11-13 17:30:53 -0800563 csd->enable_device_config = (enable_device_config_t)dlsym(csd->csd_client,
564 "csd_client_enable_device_config");
565 if (csd->enable_device_config == NULL) {
566 ALOGE("%s: dlsym error %s for csd_client_enable_device_config",
567 __func__, dlerror());
568 goto error;
569 }
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800570 csd->enable_device = (enable_device_t)dlsym(csd->csd_client,
571 "csd_client_enable_device");
572 if (csd->enable_device == NULL) {
573 ALOGE("%s: dlsym error %s for csd_client_enable_device",
574 __func__, dlerror());
575 goto error;
576 }
577 csd->start_voice = (start_voice_t)dlsym(csd->csd_client,
578 "csd_client_start_voice");
579 if (csd->start_voice == NULL) {
580 ALOGE("%s: dlsym error %s for csd_client_start_voice",
581 __func__, dlerror());
582 goto error;
583 }
584 csd->stop_voice = (stop_voice_t)dlsym(csd->csd_client,
585 "csd_client_stop_voice");
586 if (csd->stop_voice == NULL) {
587 ALOGE("%s: dlsym error %s for csd_client_stop_voice",
588 __func__, dlerror());
589 goto error;
590 }
591 csd->volume = (volume_t)dlsym(csd->csd_client,
592 "csd_client_volume");
593 if (csd->volume == NULL) {
594 ALOGE("%s: dlsym error %s for csd_client_volume",
595 __func__, dlerror());
596 goto error;
597 }
598 csd->mic_mute = (mic_mute_t)dlsym(csd->csd_client,
599 "csd_client_mic_mute");
600 if (csd->mic_mute == NULL) {
601 ALOGE("%s: dlsym error %s for csd_client_mic_mute",
602 __func__, dlerror());
603 goto error;
604 }
605 csd->slow_talk = (slow_talk_t)dlsym(csd->csd_client,
606 "csd_client_slow_talk");
607 if (csd->slow_talk == NULL) {
608 ALOGE("%s: dlsym error %s for csd_client_slow_talk",
609 __func__, dlerror());
610 goto error;
611 }
612 csd->start_playback = (start_playback_t)dlsym(csd->csd_client,
613 "csd_client_start_playback");
614 if (csd->start_playback == NULL) {
615 ALOGE("%s: dlsym error %s for csd_client_start_playback",
616 __func__, dlerror());
617 goto error;
618 }
619 csd->stop_playback = (stop_playback_t)dlsym(csd->csd_client,
620 "csd_client_stop_playback");
621 if (csd->stop_playback == NULL) {
622 ALOGE("%s: dlsym error %s for csd_client_stop_playback",
623 __func__, dlerror());
624 goto error;
625 }
Vidyakumar Athota21b3bb92014-04-25 11:08:08 -0700626 csd->set_lch = (set_lch_t)dlsym(csd->csd_client, "csd_client_set_lch");
627 if (csd->set_lch == NULL) {
628 ALOGE("%s: dlsym error %s for csd_client_set_lch",
629 __func__, dlerror());
630 /* Ignore the error as this is not mandatory function for
631 * basic voice call to work.
632 */
633 }
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800634 csd->start_record = (start_record_t)dlsym(csd->csd_client,
635 "csd_client_start_record");
636 if (csd->start_record == NULL) {
637 ALOGE("%s: dlsym error %s for csd_client_start_record",
638 __func__, dlerror());
639 goto error;
640 }
641 csd->stop_record = (stop_record_t)dlsym(csd->csd_client,
642 "csd_client_stop_record");
643 if (csd->stop_record == NULL) {
644 ALOGE("%s: dlsym error %s for csd_client_stop_record",
645 __func__, dlerror());
646 goto error;
647 }
Helen Zeng6a16ad72014-02-23 22:04:44 -0800648
649 csd->get_sample_rate = (get_sample_rate_t)dlsym(csd->csd_client,
650 "csd_client_get_sample_rate");
651 if (csd->get_sample_rate == NULL) {
652 ALOGE("%s: dlsym error %s for csd_client_get_sample_rate",
653 __func__, dlerror());
654
655 goto error;
656 }
657
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800658 csd->init = (init_t)dlsym(csd->csd_client, "csd_client_init");
659
660 if (csd->init == NULL) {
661 ALOGE("%s: dlsym error %s for csd_client_init",
662 __func__, dlerror());
663 goto error;
664 } else {
Helen Zeng6a16ad72014-02-23 22:04:44 -0800665 csd->init(i2s_ext_modem);
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800666 }
667 }
668 return csd;
669
670error:
671 free(csd);
672 csd = NULL;
673 return csd;
674}
675
676void close_csd_client(struct csd_data *csd)
677{
678 if (csd != NULL) {
679 csd->deinit();
680 dlclose(csd->csd_client);
681 free(csd);
682 csd = NULL;
683 }
684}
685
Helen Zeng6a16ad72014-02-23 22:04:44 -0800686static bool platform_is_i2s_ext_modem(const char *snd_card_name,
687 struct platform_data *plat_data)
688{
689 plat_data->is_i2s_ext_modem = false;
690
691 if (!strncmp(snd_card_name, "apq8084-taiko-i2s-mtp-snd-card",
692 sizeof("apq8084-taiko-i2s-mtp-snd-card")) ||
693 !strncmp(snd_card_name, "apq8084-taiko-i2s-cdp-snd-card",
694 sizeof("apq8084-taiko-i2s-cdp-snd-card"))) {
695 plat_data->is_i2s_ext_modem = true;
696 }
697 ALOGV("%s, is_i2s_ext_modem:%d",__func__, plat_data->is_i2s_ext_modem);
698
699 return plat_data->is_i2s_ext_modem;
Helen Zeng008aebd2014-02-23 19:13:12 -0800700}
701
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -0700702static void set_platform_defaults()
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700703{
704 int32_t dev;
705 for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
706 backend_table[dev] = NULL;
707 }
708
709 // TBD - do these go to the platform-info.xml file.
710 // will help in avoiding strdups here
711 backend_table[SND_DEVICE_IN_BT_SCO_MIC] = strdup("bt-sco");
712 backend_table[SND_DEVICE_IN_BT_SCO_MIC_WB] = strdup("bt-sco-wb");
Vicky Sehrawate240e5d2014-08-12 17:17:04 -0700713 backend_table[SND_DEVICE_IN_BT_SCO_MIC_NREC] = strdup("bt-sco");
714 backend_table[SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = strdup("bt-sco-wb");
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700715 backend_table[SND_DEVICE_OUT_BT_SCO] = strdup("bt-sco");
716 backend_table[SND_DEVICE_OUT_BT_SCO_WB] = strdup("bt-sco-wb");
717 backend_table[SND_DEVICE_OUT_HDMI] = strdup("hdmi");
718 backend_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("speaker-and-hdmi");
719 backend_table[SND_DEVICE_OUT_AFE_PROXY] = strdup("afe-proxy");
720 backend_table[SND_DEVICE_OUT_USB_HEADSET] = strdup("usb-headphones");
721 backend_table[SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] =
722 strdup("speaker-and-usb-headphones");
723 backend_table[SND_DEVICE_IN_USB_HEADSET_MIC] = strdup("usb-headset-mic");
724 backend_table[SND_DEVICE_IN_CAPTURE_FM] = strdup("capture-fm");
725 backend_table[SND_DEVICE_OUT_TRANSMISSION_FM] = strdup("transmission-fm");
726}
727
Walter Yang6f800052014-07-14 16:15:38 -0700728void get_cvd_version(char *cvd_version, struct audio_device *adev)
729{
730 struct mixer_ctl *ctl;
731 int count;
732 int ret = 0;
733
734 ctl = mixer_get_ctl_by_name(adev->mixer, CVD_VERSION_MIXER_CTL);
735 if (!ctl) {
736 ALOGE("%s: Could not get ctl for mixer cmd - %s", __func__, CVD_VERSION_MIXER_CTL);
737 goto done;
738 }
739 mixer_ctl_update(ctl);
740
741 count = mixer_ctl_get_num_values(ctl);
742 if (count > MAX_CVD_VERSION_STRING_SIZE)
743 count = MAX_CVD_VERSION_STRING_SIZE;
744
745 ret = mixer_ctl_get_array(ctl, cvd_version, count);
746 if (ret != 0) {
747 ALOGE("%s: ERROR! mixer_ctl_get_array() failed to get CVD Version", __func__);
748 goto done;
749 }
750
751done:
752 return;
753}
754
Anish Kumar55e6df22014-08-26 17:38:05 -0700755static int hw_util_open(int card_no)
756{
757 int fd = -1;
758 char dev_name[256];
759
760 snprintf(dev_name, sizeof(dev_name), "/dev/snd/hwC%uD%u",
761 card_no, WCD9XXX_CODEC_HWDEP_NODE);
762 ALOGD("%s Opening device %s\n", __func__, dev_name);
763 fd = open(dev_name, O_WRONLY);
764 if (fd < 0) {
765 ALOGE("%s: cannot open device '%s'\n", __func__, dev_name);
766 return fd;
767 }
768 ALOGD("%s success", __func__);
769 return fd;
770}
771
772struct param_data {
773 int use_case;
774 int acdb_id;
775 int get_size;
776 int buff_size;
777 int data_size;
778 void *buff;
779};
780
781static int send_codec_cal(acdb_loader_get_calibration_t acdb_loader_get_calibration, int fd)
782{
783 int ret = 0, type;
784
785 for (type = WCD9XXX_ANC_CAL; type < WCD9XXX_MAX_CAL; type++) {
786 struct wcdcal_ioctl_buffer codec_buffer;
787 struct param_data calib;
788
789 if (!strcmp(cal_name_info[type], "mad_cal"))
790 calib.acdb_id = SOUND_TRIGGER_DEVICE_HANDSET_MONO_LOW_POWER_ACDB_ID;
791 calib.get_size = 1;
792 ret = acdb_loader_get_calibration(cal_name_info[type], sizeof(struct param_data),
793 &calib);
794 if (ret < 0) {
795 ALOGE("%s get_calibration failed\n", __func__);
796 return ret;
797 }
798 calib.get_size = 0;
799 calib.buff = malloc(calib.buff_size);
800 ret = acdb_loader_get_calibration(cal_name_info[type],
801 sizeof(struct param_data), &calib);
802 if (ret < 0) {
803 ALOGE("%s get_calibration failed\n", __func__);
804 free(calib.buff);
805 return ret;
806 }
807 codec_buffer.buffer = calib.buff;
808 codec_buffer.size = calib.data_size;
809 codec_buffer.cal_type = type;
810 if (ioctl(fd, SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE, &codec_buffer) < 0)
811 ALOGE("Failed to call ioctl for %s err=%d",
812 cal_name_info[type], errno);
813 ALOGD("%s cal sent for %s", __func__, cal_name_info[type]);
814 free(calib.buff);
815 }
816 return ret;
817}
818
819static void audio_hwdep_send_cal(struct platform_data *plat_data)
820{
821 int fd;
822
823 fd = hw_util_open(plat_data->adev->snd_card);
824 if (fd == -1) {
825 ALOGE("%s error open\n", __func__);
826 return;
827 }
828
829 acdb_loader_get_calibration = (acdb_loader_get_calibration_t)
830 dlsym(plat_data->acdb_handle, "acdb_loader_get_calibration");
831
832 if (acdb_loader_get_calibration == NULL) {
833 ALOGE("%s: ERROR. dlsym Error:%s acdb_loader_get_calibration", __func__,
834 dlerror());
835 return;
836 }
837 if (send_codec_cal(acdb_loader_get_calibration, fd) < 0)
838 ALOGE("%s: Could not send anc cal", __FUNCTION__);
839}
840
Eric Laurentb23d5282013-05-14 15:27:20 -0700841void *platform_init(struct audio_device *adev)
842{
Vidyakumar Athota77327dd2014-08-07 16:44:25 -0700843 char platform[PROPERTY_VALUE_MAX];
844 char baseband[PROPERTY_VALUE_MAX];
Eric Laurentb23d5282013-05-14 15:27:20 -0700845 char value[PROPERTY_VALUE_MAX];
Apoorv Raghuvanshi84fa2fe2013-12-04 11:57:47 -0800846 struct platform_data *my_data = NULL;
847 int retry_num = 0, snd_card_num = 0;
Ravi Kumar Alamanda48c921d2013-10-29 06:07:44 -0700848 const char *snd_card_name;
Walter Yang6f800052014-07-14 16:15:38 -0700849 char *cvd_version = NULL;
sangwoo1b9f4b32013-06-21 18:22:55 -0700850
Eric Laurentb23d5282013-05-14 15:27:20 -0700851 my_data = calloc(1, sizeof(struct platform_data));
852
Haynes Mathew Georgeb51ceb12014-06-30 13:56:18 -0700853 if (!my_data) {
854 ALOGE("failed to allocate platform data");
855 return NULL;
856 }
857
Apoorv Raghuvanshi84fa2fe2013-12-04 11:57:47 -0800858 while (snd_card_num < MAX_SND_CARD) {
859 adev->mixer = mixer_open(snd_card_num);
860
861 while (!adev->mixer && retry_num < RETRY_NUMBER) {
862 usleep(RETRY_US);
863 adev->mixer = mixer_open(snd_card_num);
864 retry_num++;
865 }
866
867 if (!adev->mixer) {
868 ALOGE("%s: Unable to open the mixer card: %d", __func__,
869 snd_card_num);
870 retry_num = 0;
871 snd_card_num++;
872 continue;
873 }
874
875 snd_card_name = mixer_get_name(adev->mixer);
876 ALOGV("%s: snd_card_name: %s", __func__, snd_card_name);
877
878 my_data->hw_info = hw_info_init(snd_card_name);
879 if (!my_data->hw_info) {
880 ALOGE("%s: Failed to init hardware info", __func__);
881 } else {
Helen Zeng6a16ad72014-02-23 22:04:44 -0800882 if (platform_is_i2s_ext_modem(snd_card_name, my_data)) {
883 ALOGD("%s: Call MIXER_XML_PATH_I2S", __func__);
884
885 adev->audio_route = audio_route_init(snd_card_num,
886 MIXER_XML_PATH_I2S);
887 } else if (audio_extn_read_xml(adev, snd_card_num, MIXER_XML_PATH,
888 MIXER_XML_PATH_AUXPCM) == -ENOSYS) {
Apoorv Raghuvanshi84fa2fe2013-12-04 11:57:47 -0800889 adev->audio_route = audio_route_init(snd_card_num,
890 MIXER_XML_PATH);
Helen Zeng6a16ad72014-02-23 22:04:44 -0800891 }
Apoorv Raghuvanshi84fa2fe2013-12-04 11:57:47 -0800892 if (!adev->audio_route) {
893 ALOGE("%s: Failed to init audio route controls, aborting.",
894 __func__);
895 free(my_data);
896 return NULL;
897 }
898 adev->snd_card = snd_card_num;
899 ALOGD("%s: Opened sound card:%d", __func__, snd_card_num);
900 break;
901 }
902 retry_num = 0;
903 snd_card_num++;
904 }
905
906 if (snd_card_num >= MAX_SND_CARD) {
907 ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
908 free(my_data);
909 return NULL;
Ravi Kumar Alamanda48c921d2013-10-29 06:07:44 -0700910 }
911
Eric Laurentb23d5282013-05-14 15:27:20 -0700912 my_data->adev = adev;
Eric Laurentb23d5282013-05-14 15:27:20 -0700913 my_data->fluence_in_spkr_mode = false;
914 my_data->fluence_in_voice_call = false;
915 my_data->fluence_in_voice_rec = false;
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800916 my_data->fluence_in_audio_rec = false;
Tanya Finkel00130052014-07-14 04:26:56 -0700917 my_data->external_spk_1 = false;
918 my_data->external_spk_2 = false;
919 my_data->external_mic = false;
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700920 my_data->fluence_type = FLUENCE_NONE;
Narsinga Rao Chella61e0f9b2014-03-06 21:25:22 -0800921 my_data->fluence_mode = FLUENCE_ENDFIRE;
Avinash Vaishd5fa4572014-09-15 14:41:14 +0530922 my_data->slowtalk = false;
923 my_data->hd_voice = false;
Eric Laurentb23d5282013-05-14 15:27:20 -0700924
Venkata Narendra Kumar Gutta88fd0bc2014-03-27 19:47:56 +0530925 property_get("ro.qc.sdk.audio.fluencetype", my_data->fluence_cap, "");
926 if (!strncmp("fluencepro", my_data->fluence_cap, sizeof("fluencepro"))) {
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800927 my_data->fluence_type = FLUENCE_QUAD_MIC | FLUENCE_DUAL_MIC;
Venkata Narendra Kumar Gutta88fd0bc2014-03-27 19:47:56 +0530928 } else if (!strncmp("fluence", my_data->fluence_cap, sizeof("fluence"))) {
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700929 my_data->fluence_type = FLUENCE_DUAL_MIC;
930 } else {
931 my_data->fluence_type = FLUENCE_NONE;
Eric Laurentb23d5282013-05-14 15:27:20 -0700932 }
933
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700934 if (my_data->fluence_type != FLUENCE_NONE) {
Eric Laurentb23d5282013-05-14 15:27:20 -0700935 property_get("persist.audio.fluence.voicecall",value,"");
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700936 if (!strncmp("true", value, sizeof("true"))) {
Eric Laurentb23d5282013-05-14 15:27:20 -0700937 my_data->fluence_in_voice_call = true;
938 }
939
940 property_get("persist.audio.fluence.voicerec",value,"");
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700941 if (!strncmp("true", value, sizeof("true"))) {
Eric Laurentb23d5282013-05-14 15:27:20 -0700942 my_data->fluence_in_voice_rec = true;
943 }
944
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800945 property_get("persist.audio.fluence.audiorec",value,"");
946 if (!strncmp("true", value, sizeof("true"))) {
947 my_data->fluence_in_audio_rec = true;
948 }
949
Eric Laurentb23d5282013-05-14 15:27:20 -0700950 property_get("persist.audio.fluence.speaker",value,"");
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700951 if (!strncmp("true", value, sizeof("true"))) {
Eric Laurentb23d5282013-05-14 15:27:20 -0700952 my_data->fluence_in_spkr_mode = true;
953 }
Narsinga Rao Chella61e0f9b2014-03-06 21:25:22 -0800954
955 property_get("persist.audio.fluence.mode",value,"");
956 if (!strncmp("broadside", value, sizeof("broadside"))) {
957 my_data->fluence_mode = FLUENCE_BROADSIDE;
958 }
Eric Laurentb23d5282013-05-14 15:27:20 -0700959 }
960
Ben Rombergerc1dc70d2013-12-19 15:11:17 -0800961 my_data->voice_feature_set = VOICE_FEATURE_SET_DEFAULT;
Eric Laurentb23d5282013-05-14 15:27:20 -0700962 my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
963 if (my_data->acdb_handle == NULL) {
964 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
965 } else {
966 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
967 my_data->acdb_deallocate = (acdb_deallocate_t)dlsym(my_data->acdb_handle,
968 "acdb_loader_deallocate_ACDB");
Ben Rombergerc1dc70d2013-12-19 15:11:17 -0800969 if (!my_data->acdb_deallocate)
970 ALOGE("%s: Could not find the symbol acdb_loader_deallocate_ACDB from %s",
971 __func__, LIB_ACDB_LOADER);
972
Eric Laurentb23d5282013-05-14 15:27:20 -0700973 my_data->acdb_send_audio_cal = (acdb_send_audio_cal_t)dlsym(my_data->acdb_handle,
Subhash Chandra Bose Naripeddy54274672014-03-10 14:51:02 -0700974 "acdb_loader_send_audio_cal_v2");
Eric Laurentb23d5282013-05-14 15:27:20 -0700975 if (!my_data->acdb_send_audio_cal)
Ben Rombergerc1dc70d2013-12-19 15:11:17 -0800976 ALOGE("%s: Could not find the symbol acdb_send_audio_cal from %s",
Eric Laurentb23d5282013-05-14 15:27:20 -0700977 __func__, LIB_ACDB_LOADER);
Ben Rombergerc1dc70d2013-12-19 15:11:17 -0800978
Eric Laurentb23d5282013-05-14 15:27:20 -0700979 my_data->acdb_send_voice_cal = (acdb_send_voice_cal_t)dlsym(my_data->acdb_handle,
980 "acdb_loader_send_voice_cal");
Ben Rombergerc1dc70d2013-12-19 15:11:17 -0800981 if (!my_data->acdb_send_voice_cal)
982 ALOGE("%s: Could not find the symbol acdb_loader_send_voice_cal from %s",
983 __func__, LIB_ACDB_LOADER);
984
985 my_data->acdb_reload_vocvoltable = (acdb_reload_vocvoltable_t)dlsym(my_data->acdb_handle,
986 "acdb_loader_reload_vocvoltable");
987 if (!my_data->acdb_reload_vocvoltable)
988 ALOGE("%s: Could not find the symbol acdb_loader_reload_vocvoltable from %s",
989 __func__, LIB_ACDB_LOADER);
990
Subhash Chandra Bose Naripeddy54274672014-03-10 14:51:02 -0700991 my_data->acdb_get_default_app_type = (acdb_get_default_app_type_t)dlsym(
992 my_data->acdb_handle,
993 "acdb_loader_get_default_app_type");
994 if (!my_data->acdb_get_default_app_type)
995 ALOGE("%s: Could not find the symbol acdb_get_default_app_type from %s",
996 __func__, LIB_ACDB_LOADER);
997
Eric Laurentb23d5282013-05-14 15:27:20 -0700998 my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
Ben Romberger490d3472014-01-15 17:11:59 -0800999 "acdb_loader_init_v2");
Walter Yang6f800052014-07-14 16:15:38 -07001000 if (my_data->acdb_init == NULL) {
Ben Romberger490d3472014-01-15 17:11:59 -08001001 ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__, dlerror());
Walter Yang6f800052014-07-14 16:15:38 -07001002 goto acdb_init_fail;
1003 }
1004
1005 cvd_version = calloc(1, MAX_CVD_VERSION_STRING_SIZE);
1006 if (!cvd_version)
1007 ALOGE("failed to allocate cvd_version");
Eric Laurentb23d5282013-05-14 15:27:20 -07001008 else
Walter Yang6f800052014-07-14 16:15:38 -07001009 get_cvd_version(cvd_version, adev);
1010
1011 my_data->acdb_init(snd_card_name, cvd_version);
1012 if (cvd_version)
1013 free(cvd_version);
Eric Laurentb23d5282013-05-14 15:27:20 -07001014 }
1015
Walter Yang6f800052014-07-14 16:15:38 -07001016acdb_init_fail:
1017
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -07001018 set_platform_defaults();
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001019
Ben Romberger55886882014-01-10 13:49:02 -08001020 /* Initialize ACDB ID's */
Helen Zeng6a16ad72014-02-23 22:04:44 -08001021 if (my_data->is_i2s_ext_modem)
1022 platform_info_init(PLATFORM_INFO_XML_PATH_I2S);
1023 else
1024 platform_info_init(PLATFORM_INFO_XML_PATH);
Ben Romberger55886882014-01-10 13:49:02 -08001025
Vidyakumar Athota77327dd2014-08-07 16:44:25 -07001026 /* If platform is apq8084 and baseband is MDM, load CSD Client specific
1027 * symbols. Voice call is handled by MDM and apps processor talks to
1028 * MDM through CSD Client
1029 */
1030 property_get("ro.board.platform", platform, "");
1031 property_get("ro.baseband", baseband, "");
1032 if (!strncmp("apq8084", platform, sizeof("apq8084")) &&
1033 !strncmp("mdm", baseband, (sizeof("mdm")-1))) {
1034 my_data->csd = open_csd_client(my_data->is_i2s_ext_modem);
1035 } else {
1036 my_data->csd = NULL;
1037 }
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001038
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001039 /* init usb */
1040 audio_extn_usb_init(adev);
Apoorv Raghuvanshi84fa2fe2013-12-04 11:57:47 -08001041 /* update sound cards appropriately */
1042 audio_extn_usb_set_proxy_sound_card(adev->snd_card);
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001043
Apoorv Raghuvanshi6178a3f2013-10-19 12:38:54 -07001044 /* Read one time ssr property */
Mingming Yin49be8032013-12-19 12:51:25 -08001045 audio_extn_ssr_update_enabled();
Gopikrishnaiah Anandanf538cef2013-10-28 14:06:03 -07001046 audio_extn_spkr_prot_init(adev);
Dhananjay Kumar89ea3bd2014-04-29 15:45:57 +05301047
1048 audio_extn_dolby_set_license(adev);
Anish Kumar55e6df22014-08-26 17:38:05 -07001049 audio_hwdep_send_cal(my_data);
Dhananjay Kumar89ea3bd2014-04-29 15:45:57 +05301050
Lior Barenboim0b61bc72014-05-13 13:01:37 +03001051 /* init audio device arbitration */
1052 audio_extn_dev_arbi_init();
1053
Eric Laurentb23d5282013-05-14 15:27:20 -07001054 return my_data;
1055}
1056
1057void platform_deinit(void *platform)
1058{
Ravi Kumar Alamanda48c921d2013-10-29 06:07:44 -07001059 struct platform_data *my_data = (struct platform_data *)platform;
1060
1061 hw_info_deinit(my_data->hw_info);
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001062 close_csd_client(my_data->csd);
1063
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001064 int32_t dev;
1065 for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
1066 if (backend_table[dev]) {
1067 free(backend_table[dev]);
1068 backend_table[dev]= NULL;
1069 }
1070 }
1071
Lior Barenboim0b61bc72014-05-13 13:01:37 +03001072 /* deinit audio device arbitration */
1073 audio_extn_dev_arbi_deinit();
1074
Eric Laurentb23d5282013-05-14 15:27:20 -07001075 free(platform);
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001076 /* deinit usb */
1077 audio_extn_usb_deinit();
Eric Laurentb23d5282013-05-14 15:27:20 -07001078}
1079
1080const char *platform_get_snd_device_name(snd_device_t snd_device)
1081{
1082 if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX)
1083 return device_table[snd_device];
1084 else
1085 return "";
1086}
1087
Ravi Kumar Alamanda48c921d2013-10-29 06:07:44 -07001088int platform_get_snd_device_name_extn(void *platform, snd_device_t snd_device,
1089 char *device_name)
1090{
1091 struct platform_data *my_data = (struct platform_data *)platform;
1092
1093 if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) {
1094 strlcpy(device_name, device_table[snd_device], DEVICE_NAME_MAX_SIZE);
1095 hw_info_append_hw_type(my_data->hw_info, snd_device, device_name);
1096 } else {
1097 strlcpy(device_name, "", DEVICE_NAME_MAX_SIZE);
1098 return -EINVAL;
1099 }
1100
1101 return 0;
1102}
1103
Eric Laurentb23d5282013-05-14 15:27:20 -07001104void platform_add_backend_name(char *mixer_path, snd_device_t snd_device)
1105{
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001106 if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
1107 ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
1108 return;
1109 }
1110
1111 const char * suffix = backend_table[snd_device];
1112
1113 if (suffix != NULL) {
1114 strlcat(mixer_path, " ", MIXER_PATH_MAX_LENGTH);
1115 strlcat(mixer_path, suffix, MIXER_PATH_MAX_LENGTH);
Vidyakumar Athota1c6419a2014-01-10 14:47:34 -08001116 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001117}
1118
1119int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
1120{
1121 int device_id;
1122 if (device_type == PCM_PLAYBACK)
1123 device_id = pcm_device_table[usecase][0];
1124 else
1125 device_id = pcm_device_table[usecase][1];
1126 return device_id;
1127}
1128
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001129static int find_index(struct name_to_index * table, int32_t len, const char * name)
Ben Romberger61764e32014-01-10 13:49:02 -08001130{
1131 int ret = 0;
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001132 int32_t i;
Ben Romberger61764e32014-01-10 13:49:02 -08001133
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001134 if (table == NULL) {
1135 ALOGE("%s: table is NULL", __func__);
Ben Romberger61764e32014-01-10 13:49:02 -08001136 ret = -ENODEV;
1137 goto done;
1138 }
1139
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001140 if (name == NULL) {
1141 ALOGE("null key");
1142 ret = -ENODEV;
1143 goto done;
1144 }
1145
1146 for (i=0; i < len; i++) {
1147 const char* tn = table[i].name;
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -07001148 size_t len = strlen(tn);
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001149 if (strncmp(tn, name, len) == 0) {
1150 if (strlen(name) != len) {
1151 continue; // substring
1152 }
1153 ret = table[i].index;
Ben Romberger61764e32014-01-10 13:49:02 -08001154 goto done;
1155 }
1156 }
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001157 ALOGE("%s: Could not find index for name = %s",
1158 __func__, name);
Ben Romberger61764e32014-01-10 13:49:02 -08001159 ret = -ENODEV;
1160done:
1161 return ret;
1162}
1163
Venkata Narendra Kumar Gutta88fd0bc2014-03-27 19:47:56 +05301164int platform_set_fluence_type(void *platform, char *value)
1165{
1166 int ret = 0;
1167 int fluence_type = FLUENCE_NONE;
1168 int fluence_flag = NONE_FLAG;
1169 struct platform_data *my_data = (struct platform_data *)platform;
1170 struct audio_device *adev = my_data->adev;
1171
1172 ALOGV("%s: fluence type:%d", __func__, my_data->fluence_type);
1173
1174 /* only dual mic turn on and off is supported as of now through setparameters */
1175 if (!strncmp(AUDIO_PARAMETER_VALUE_DUALMIC,value, sizeof(AUDIO_PARAMETER_VALUE_DUALMIC))) {
1176 if (!strncmp("fluencepro", my_data->fluence_cap, sizeof("fluencepro")) ||
1177 !strncmp("fluence", my_data->fluence_cap, sizeof("fluence"))) {
1178 ALOGV("fluence dualmic feature enabled \n");
1179 fluence_type = FLUENCE_DUAL_MIC;
1180 fluence_flag = DMIC_FLAG;
1181 } else {
1182 ALOGE("%s: Failed to set DUALMIC", __func__);
1183 ret = -1;
1184 goto done;
1185 }
1186 } else if (!strncmp(AUDIO_PARAMETER_KEY_NO_FLUENCE, value, sizeof(AUDIO_PARAMETER_KEY_NO_FLUENCE))) {
1187 ALOGV("fluence disabled");
1188 fluence_type = FLUENCE_NONE;
1189 } else {
1190 ALOGE("Invalid fluence value : %s",value);
1191 ret = -1;
1192 goto done;
1193 }
1194
1195 if (fluence_type != my_data->fluence_type) {
1196 ALOGV("%s: Updating fluence_type to :%d", __func__, fluence_type);
1197 my_data->fluence_type = fluence_type;
1198 adev->acdb_settings = (adev->acdb_settings & FLUENCE_MODE_CLEAR) | fluence_flag;
1199 }
1200done:
1201 return ret;
1202}
1203
1204int platform_get_fluence_type(void *platform, char *value, uint32_t len)
1205{
1206 int ret = 0;
1207 struct platform_data *my_data = (struct platform_data *)platform;
1208
1209 if (my_data->fluence_type == FLUENCE_QUAD_MIC) {
1210 strlcpy(value, "quadmic", len);
1211 } else if (my_data->fluence_type == FLUENCE_DUAL_MIC) {
1212 strlcpy(value, "dualmic", len);
1213 } else if (my_data->fluence_type == FLUENCE_NONE) {
1214 strlcpy(value, "none", len);
1215 } else
1216 ret = -1;
1217
1218 return ret;
1219}
1220
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001221int platform_get_snd_device_index(char *device_name)
1222{
1223 return find_index(snd_device_name_index, SND_DEVICE_MAX, device_name);
1224}
1225
1226int platform_get_usecase_index(const char *usecase_name)
1227{
1228 return find_index(usecase_name_index, AUDIO_USECASE_MAX, usecase_name);
1229}
1230
Ben Romberger55886882014-01-10 13:49:02 -08001231int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
1232{
1233 int ret = 0;
1234
1235 if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
1236 ALOGE("%s: Invalid snd_device = %d",
1237 __func__, snd_device);
1238 ret = -EINVAL;
1239 goto done;
1240 }
1241
1242 acdb_device_table[snd_device] = acdb_id;
1243done:
1244 return ret;
1245}
1246
Subhash Chandra Bose Naripeddy54274672014-03-10 14:51:02 -07001247int platform_get_default_app_type(void *platform)
1248{
1249 struct platform_data *my_data = (struct platform_data *)platform;
1250
1251 if (my_data->acdb_get_default_app_type)
1252 return my_data->acdb_get_default_app_type();
1253 else
1254 return DEFAULT_APP_TYPE;
1255}
1256
Subhash Chandra Bose Naripeddy19dc03b2014-03-10 14:43:05 -07001257int platform_get_snd_device_acdb_id(snd_device_t snd_device)
1258{
1259 if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
1260 ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
1261 return -EINVAL;
1262 }
1263 return acdb_device_table[snd_device];
1264}
1265
Subhash Chandra Bose Naripeddy54274672014-03-10 14:51:02 -07001266int platform_send_audio_calibration(void *platform, snd_device_t snd_device,
1267 int app_type, int sample_rate)
Eric Laurentb23d5282013-05-14 15:27:20 -07001268{
1269 struct platform_data *my_data = (struct platform_data *)platform;
1270 int acdb_dev_id, acdb_dev_type;
1271
Anish Kumarf16721c2014-08-01 15:09:25 -07001272 acdb_dev_id = acdb_device_table[audio_extn_get_spkr_prot_snd_device(snd_device)];
Eric Laurentb23d5282013-05-14 15:27:20 -07001273 if (acdb_dev_id < 0) {
1274 ALOGE("%s: Could not find acdb id for device(%d)",
1275 __func__, snd_device);
1276 return -EINVAL;
1277 }
1278 if (my_data->acdb_send_audio_cal) {
Subhash Chandra Bose Naripeddy54274672014-03-10 14:51:02 -07001279 ALOGV("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
Eric Laurentb23d5282013-05-14 15:27:20 -07001280 __func__, snd_device, acdb_dev_id);
1281 if (snd_device >= SND_DEVICE_OUT_BEGIN &&
1282 snd_device < SND_DEVICE_OUT_END)
1283 acdb_dev_type = ACDB_DEV_TYPE_OUT;
1284 else
1285 acdb_dev_type = ACDB_DEV_TYPE_IN;
Subhash Chandra Bose Naripeddy54274672014-03-10 14:51:02 -07001286 my_data->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type, app_type,
1287 sample_rate);
Eric Laurentb23d5282013-05-14 15:27:20 -07001288 }
1289 return 0;
1290}
1291
1292int platform_switch_voice_call_device_pre(void *platform)
1293{
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001294 struct platform_data *my_data = (struct platform_data *)platform;
1295 int ret = 0;
1296
Vidyakumar Athota1fd21792013-11-15 14:50:57 -08001297 if (my_data->csd != NULL &&
1298 my_data->adev->mode == AUDIO_MODE_IN_CALL) {
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001299 /* This must be called before disabling mixer controls on APQ side */
1300 ret = my_data->csd->disable_device();
1301 if (ret < 0) {
1302 ALOGE("%s: csd_client_disable_device, failed, error %d",
1303 __func__, ret);
1304 }
1305 }
1306 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001307}
1308
Vidyakumar Athota545dbd32013-11-13 17:30:53 -08001309int platform_switch_voice_call_enable_device_config(void *platform,
1310 snd_device_t out_snd_device,
1311 snd_device_t in_snd_device)
1312{
1313 struct platform_data *my_data = (struct platform_data *)platform;
1314 int acdb_rx_id, acdb_tx_id;
1315 int ret = 0;
1316
Vidyakumar Athota1c6419a2014-01-10 14:47:34 -08001317 if (my_data->csd == NULL)
1318 return ret;
1319
1320 if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
1321 audio_extn_spkr_prot_is_enabled())
1322 acdb_rx_id = acdb_device_table[SND_DEVICE_OUT_SPEAKER_PROTECTED];
1323 else
1324 acdb_rx_id = acdb_device_table[out_snd_device];
1325
Vidyakumar Athota545dbd32013-11-13 17:30:53 -08001326 acdb_tx_id = acdb_device_table[in_snd_device];
1327
Vidyakumar Athota1c6419a2014-01-10 14:47:34 -08001328 if (acdb_rx_id > 0 && acdb_tx_id > 0) {
1329 ret = my_data->csd->enable_device_config(acdb_rx_id, acdb_tx_id);
1330 if (ret < 0) {
1331 ALOGE("%s: csd_enable_device_config, failed, error %d",
1332 __func__, ret);
Vidyakumar Athota545dbd32013-11-13 17:30:53 -08001333 }
Vidyakumar Athota1c6419a2014-01-10 14:47:34 -08001334 } else {
1335 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1336 acdb_rx_id, acdb_tx_id);
Vidyakumar Athota545dbd32013-11-13 17:30:53 -08001337 }
Vidyakumar Athota1c6419a2014-01-10 14:47:34 -08001338
Vidyakumar Athota545dbd32013-11-13 17:30:53 -08001339 return ret;
1340}
1341
Eric Laurentb23d5282013-05-14 15:27:20 -07001342int platform_switch_voice_call_device_post(void *platform,
1343 snd_device_t out_snd_device,
1344 snd_device_t in_snd_device)
1345{
1346 struct platform_data *my_data = (struct platform_data *)platform;
1347 int acdb_rx_id, acdb_tx_id;
1348
1349 if (my_data->acdb_send_voice_cal == NULL) {
1350 ALOGE("%s: dlsym error for acdb_send_voice_call", __func__);
1351 } else {
Anish Kumar46c7b872014-09-09 01:49:44 -07001352 if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
1353 audio_extn_spkr_prot_is_enabled())
1354 out_snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED;
1355
Vidyakumar Athota1fd21792013-11-15 14:50:57 -08001356 acdb_rx_id = acdb_device_table[out_snd_device];
1357 acdb_tx_id = acdb_device_table[in_snd_device];
1358
Eric Laurentb23d5282013-05-14 15:27:20 -07001359 if (acdb_rx_id > 0 && acdb_tx_id > 0)
1360 my_data->acdb_send_voice_cal(acdb_rx_id, acdb_tx_id);
1361 else
1362 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1363 acdb_rx_id, acdb_tx_id);
1364 }
1365
Vidyakumar Athota1fd21792013-11-15 14:50:57 -08001366 return 0;
1367}
1368
1369int platform_switch_voice_call_usecase_route_post(void *platform,
1370 snd_device_t out_snd_device,
1371 snd_device_t in_snd_device)
1372{
1373 struct platform_data *my_data = (struct platform_data *)platform;
1374 int acdb_rx_id, acdb_tx_id;
1375 int ret = 0;
1376
Vidyakumar Athota1c6419a2014-01-10 14:47:34 -08001377 if (my_data->csd == NULL)
1378 return ret;
1379
1380 if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
1381 audio_extn_spkr_prot_is_enabled())
1382 acdb_rx_id = acdb_device_table[SND_DEVICE_OUT_SPEAKER_PROTECTED];
1383 else
1384 acdb_rx_id = acdb_device_table[out_snd_device];
1385
Vidyakumar Athota1fd21792013-11-15 14:50:57 -08001386 acdb_tx_id = acdb_device_table[in_snd_device];
1387
Vidyakumar Athota1c6419a2014-01-10 14:47:34 -08001388 if (acdb_rx_id > 0 && acdb_tx_id > 0) {
1389 ret = my_data->csd->enable_device(acdb_rx_id, acdb_tx_id,
1390 my_data->adev->acdb_settings);
1391 if (ret < 0) {
1392 ALOGE("%s: csd_enable_device, failed, error %d", __func__, ret);
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001393 }
Vidyakumar Athota1c6419a2014-01-10 14:47:34 -08001394 } else {
1395 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1396 acdb_rx_id, acdb_tx_id);
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001397 }
Vidyakumar Athota1c6419a2014-01-10 14:47:34 -08001398
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001399 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001400}
1401
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001402int platform_start_voice_call(void *platform, uint32_t vsid)
Eric Laurentb23d5282013-05-14 15:27:20 -07001403{
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001404 struct platform_data *my_data = (struct platform_data *)platform;
1405 int ret = 0;
1406
1407 if (my_data->csd != NULL) {
1408 ret = my_data->csd->start_voice(vsid);
1409 if (ret < 0) {
1410 ALOGE("%s: csd_start_voice error %d\n", __func__, ret);
1411 }
1412 }
1413 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001414}
1415
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001416int platform_stop_voice_call(void *platform, uint32_t vsid)
Eric Laurentb23d5282013-05-14 15:27:20 -07001417{
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001418 struct platform_data *my_data = (struct platform_data *)platform;
1419 int ret = 0;
1420
1421 if (my_data->csd != NULL) {
1422 ret = my_data->csd->stop_voice(vsid);
1423 if (ret < 0) {
1424 ALOGE("%s: csd_stop_voice error %d\n", __func__, ret);
1425 }
1426 }
1427 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001428}
1429
Helen Zeng6a16ad72014-02-23 22:04:44 -08001430int platform_get_sample_rate(void *platform, uint32_t *rate)
1431{
1432 struct platform_data *my_data = (struct platform_data *)platform;
1433 int ret = 0;
1434
1435 if ((my_data->csd != NULL) && my_data->is_i2s_ext_modem) {
1436 ret = my_data->csd->get_sample_rate(rate);
1437 if (ret < 0) {
1438 ALOGE("%s: csd_get_sample_rate error %d\n", __func__, ret);
1439 }
1440 }
1441 return ret;
1442}
1443
Eric Laurentb23d5282013-05-14 15:27:20 -07001444int platform_set_voice_volume(void *platform, int volume)
1445{
1446 struct platform_data *my_data = (struct platform_data *)platform;
1447 struct audio_device *adev = my_data->adev;
1448 struct mixer_ctl *ctl;
sangwoo53b2cf02013-07-25 19:18:44 -07001449 const char *mixer_ctl_name = "Voice Rx Gain";
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001450 int vol_index = 0, ret = 0;
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001451 uint32_t set_values[ ] = {0,
1452 ALL_SESSION_VSID,
1453 DEFAULT_VOLUME_RAMP_DURATION_MS};
Eric Laurentb23d5282013-05-14 15:27:20 -07001454
1455 // Voice volume levels are mapped to adsp volume levels as follows.
1456 // 100 -> 5, 80 -> 4, 60 -> 3, 40 -> 2, 20 -> 1 0 -> 0
1457 // But this values don't changed in kernel. So, below change is need.
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001458 vol_index = (int)percent_to_index(volume, MIN_VOL_INDEX, MAX_VOL_INDEX);
1459 set_values[0] = vol_index;
Eric Laurentb23d5282013-05-14 15:27:20 -07001460
1461 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1462 if (!ctl) {
1463 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1464 __func__, mixer_ctl_name);
1465 return -EINVAL;
1466 }
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001467 ALOGV("Setting voice volume index: %d", set_values[0]);
1468 mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
Eric Laurentb23d5282013-05-14 15:27:20 -07001469
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001470 if (my_data->csd != NULL) {
Vidyakumar Athotac37f42a2014-03-11 11:57:48 -07001471 ret = my_data->csd->volume(ALL_SESSION_VSID, volume,
1472 DEFAULT_VOLUME_RAMP_DURATION_MS);
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001473 if (ret < 0) {
1474 ALOGE("%s: csd_volume error %d", __func__, ret);
1475 }
1476 }
1477 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001478}
1479
1480int platform_set_mic_mute(void *platform, bool state)
1481{
1482 struct platform_data *my_data = (struct platform_data *)platform;
1483 struct audio_device *adev = my_data->adev;
1484 struct mixer_ctl *ctl;
1485 const char *mixer_ctl_name = "Voice Tx Mute";
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001486 int ret = 0;
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001487 uint32_t set_values[ ] = {0,
1488 ALL_SESSION_VSID,
Vidyakumar Athotac37f42a2014-03-11 11:57:48 -07001489 DEFAULT_MUTE_RAMP_DURATION_MS};
Eric Laurentb23d5282013-05-14 15:27:20 -07001490
Narsinga Rao Chella05573b72013-11-15 15:21:40 -08001491 set_values[0] = state;
1492 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1493 if (!ctl) {
1494 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1495 __func__, mixer_ctl_name);
1496 return -EINVAL;
1497 }
1498 ALOGV("Setting voice mute state: %d", state);
1499 mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
Eric Laurentb23d5282013-05-14 15:27:20 -07001500
Narsinga Rao Chella05573b72013-11-15 15:21:40 -08001501 if (my_data->csd != NULL) {
Vidyakumar Athotac37f42a2014-03-11 11:57:48 -07001502 ret = my_data->csd->mic_mute(ALL_SESSION_VSID, state,
1503 DEFAULT_MUTE_RAMP_DURATION_MS);
Narsinga Rao Chella05573b72013-11-15 15:21:40 -08001504 if (ret < 0) {
1505 ALOGE("%s: csd_mic_mute error %d", __func__, ret);
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001506 }
1507 }
1508 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001509}
1510
Shiv Maliyappanahallic6fd8ee2014-03-07 15:31:55 -08001511int platform_set_device_mute(void *platform, bool state, char *dir)
1512{
1513 struct platform_data *my_data = (struct platform_data *)platform;
1514 struct audio_device *adev = my_data->adev;
1515 struct mixer_ctl *ctl;
1516 char *mixer_ctl_name = NULL;
1517 int ret = 0;
1518 uint32_t set_values[ ] = {0,
1519 ALL_SESSION_VSID,
1520 0};
1521 if(dir == NULL) {
1522 ALOGE("%s: Invalid direction:%s", __func__, dir);
1523 return -EINVAL;
1524 }
1525
1526 if (!strncmp("rx", dir, sizeof("rx"))) {
1527 mixer_ctl_name = "Voice Rx Device Mute";
1528 } else if (!strncmp("tx", dir, sizeof("tx"))) {
1529 mixer_ctl_name = "Voice Tx Device Mute";
1530 } else {
1531 return -EINVAL;
1532 }
1533
1534 set_values[0] = state;
1535 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1536 if (!ctl) {
1537 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1538 __func__, mixer_ctl_name);
1539 return -EINVAL;
1540 }
1541
1542 ALOGV("%s: Setting device mute state: %d, mixer ctrl:%s",
1543 __func__,state, mixer_ctl_name);
1544 mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1545
1546 return ret;
1547}
1548
Eric Laurentb23d5282013-05-14 15:27:20 -07001549snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices)
1550{
1551 struct platform_data *my_data = (struct platform_data *)platform;
1552 struct audio_device *adev = my_data->adev;
1553 audio_mode_t mode = adev->mode;
1554 snd_device_t snd_device = SND_DEVICE_NONE;
1555
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001556 audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
1557 AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
1558 int channel_count = popcount(channel_mask);
1559
Eric Laurentb23d5282013-05-14 15:27:20 -07001560 ALOGV("%s: enter: output devices(%#x)", __func__, devices);
1561 if (devices == AUDIO_DEVICE_NONE ||
1562 devices & AUDIO_DEVICE_BIT_IN) {
1563 ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
1564 goto exit;
1565 }
1566
Mingming Yin4a72d652014-01-03 18:54:18 -08001567 if (popcount(devices) == 2) {
1568 if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
1569 AUDIO_DEVICE_OUT_SPEAKER)) {
Tanya Finkel00130052014-07-14 04:26:56 -07001570 if (my_data->external_spk_1)
1571 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1;
1572 else if (my_data->external_spk_2)
1573 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2;
1574 else
1575 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
Mingming Yin4a72d652014-01-03 18:54:18 -08001576 } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
1577 AUDIO_DEVICE_OUT_SPEAKER)) {
1578 if (audio_extn_get_anc_enabled())
1579 snd_device = SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET;
Tanya Finkel00130052014-07-14 04:26:56 -07001580 else if (my_data->external_spk_1)
1581 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1;
1582 else if (my_data->external_spk_2)
1583 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2;
Mingming Yin4a72d652014-01-03 18:54:18 -08001584 else
1585 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
1586 } else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
1587 AUDIO_DEVICE_OUT_SPEAKER)) {
1588 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI;
1589 } else if (devices == (AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET |
1590 AUDIO_DEVICE_OUT_SPEAKER)) {
1591 snd_device = SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET;
1592 } else {
1593 ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
1594 goto exit;
1595 }
1596 if (snd_device != SND_DEVICE_NONE) {
1597 goto exit;
1598 }
1599 }
1600
1601 if (popcount(devices) != 1) {
1602 ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
1603 goto exit;
1604 }
1605
Narsinga Rao Chella05573b72013-11-15 15:21:40 -08001606 if ((mode == AUDIO_MODE_IN_CALL) ||
1607 voice_extn_compress_voip_is_active(adev)) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001608 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1609 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Narsinga Rao Chella05573b72013-11-15 15:21:40 -08001610 if ((adev->voice.tty_mode != TTY_MODE_OFF) &&
1611 !voice_extn_compress_voip_is_active(adev)) {
1612 switch (adev->voice.tty_mode) {
1613 case TTY_MODE_FULL:
1614 snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES;
1615 break;
1616 case TTY_MODE_VCO:
1617 snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES;
1618 break;
1619 case TTY_MODE_HCO:
1620 snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET;
1621 break;
1622 default:
1623 ALOGE("%s: Invalid TTY mode (%#x)",
1624 __func__, adev->voice.tty_mode);
1625 }
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001626 } else if (audio_extn_get_anc_enabled()) {
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001627 if (audio_extn_should_use_fb_anc())
1628 snd_device = SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET;
1629 else
1630 snd_device = SND_DEVICE_OUT_VOICE_ANC_HEADSET;
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001631 } else {
Eric Laurentb23d5282013-05-14 15:27:20 -07001632 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001633 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001634 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Mingming Yin514a8bc2014-07-29 15:22:21 -07001635 if (adev->bt_wb_speech_enabled)
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001636 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
1637 else
1638 snd_device = SND_DEVICE_OUT_BT_SCO;
Eric Laurentb23d5282013-05-14 15:27:20 -07001639 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
1640 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001641 } else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
1642 devices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
1643 snd_device = SND_DEVICE_OUT_USB_HEADSET;
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -07001644 } else if (devices & AUDIO_DEVICE_OUT_FM_TX) {
1645 snd_device = SND_DEVICE_OUT_TRANSMISSION_FM;
Eric Laurentb23d5282013-05-14 15:27:20 -07001646 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Ravi Kumar Alamandaceb40822013-11-06 11:01:47 -08001647 if (audio_extn_should_use_handset_anc(channel_count))
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001648 snd_device = SND_DEVICE_OUT_ANC_HANDSET;
Eric Laurentb23d5282013-05-14 15:27:20 -07001649 else
Mingming Yin8e5a4f62013-10-07 15:23:41 -07001650 snd_device = SND_DEVICE_OUT_VOICE_HANDSET;
Eric Laurentb23d5282013-05-14 15:27:20 -07001651 }
1652 if (snd_device != SND_DEVICE_NONE) {
1653 goto exit;
1654 }
1655 }
1656
Eric Laurentb23d5282013-05-14 15:27:20 -07001657 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1658 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001659 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADSET
1660 && audio_extn_get_anc_enabled()) {
1661 if (audio_extn_should_use_fb_anc())
1662 snd_device = SND_DEVICE_OUT_ANC_FB_HEADSET;
1663 else
1664 snd_device = SND_DEVICE_OUT_ANC_HEADSET;
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -07001665 } else
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001666 snd_device = SND_DEVICE_OUT_HEADPHONES;
Eric Laurentb23d5282013-05-14 15:27:20 -07001667 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
Tanya Finkel00130052014-07-14 04:26:56 -07001668 if (my_data->external_spk_1)
1669 snd_device = SND_DEVICE_OUT_SPEAKER_EXTERNAL_1;
1670 else if (my_data->external_spk_2)
1671 snd_device = SND_DEVICE_OUT_SPEAKER_EXTERNAL_2;
1672 else if (adev->speaker_lr_swap)
Eric Laurentb23d5282013-05-14 15:27:20 -07001673 snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE;
1674 else
1675 snd_device = SND_DEVICE_OUT_SPEAKER;
1676 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Mingming Yin514a8bc2014-07-29 15:22:21 -07001677 if (adev->bt_wb_speech_enabled)
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001678 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
1679 else
1680 snd_device = SND_DEVICE_OUT_BT_SCO;
Eric Laurentb23d5282013-05-14 15:27:20 -07001681 } else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
1682 snd_device = SND_DEVICE_OUT_HDMI ;
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001683 } else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
1684 devices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
Mingming Yin5a7c5d62014-03-05 17:45:03 -08001685 ALOGD("%s: setting USB hadset channel capability(2) for Proxy", __func__);
1686 audio_extn_set_afe_proxy_channel_mixer(adev, 2);
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001687 snd_device = SND_DEVICE_OUT_USB_HEADSET;
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -07001688 } else if (devices & AUDIO_DEVICE_OUT_FM_TX) {
1689 snd_device = SND_DEVICE_OUT_TRANSMISSION_FM;
Eric Laurentb23d5282013-05-14 15:27:20 -07001690 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
1691 snd_device = SND_DEVICE_OUT_HANDSET;
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001692 } else if (devices & AUDIO_DEVICE_OUT_PROXY) {
Mingming Yin5a7c5d62014-03-05 17:45:03 -08001693 channel_count = audio_extn_get_afe_proxy_channel_count();
1694 ALOGD("%s: setting sink capability(%d) for Proxy", __func__, channel_count);
1695 audio_extn_set_afe_proxy_channel_mixer(adev, channel_count);
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001696 snd_device = SND_DEVICE_OUT_AFE_PROXY;
Eric Laurentb23d5282013-05-14 15:27:20 -07001697 } else {
1698 ALOGE("%s: Unknown device(s) %#x", __func__, devices);
1699 }
1700exit:
1701 ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
1702 return snd_device;
1703}
1704
1705snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device)
1706{
1707 struct platform_data *my_data = (struct platform_data *)platform;
1708 struct audio_device *adev = my_data->adev;
1709 audio_source_t source = (adev->active_input == NULL) ?
1710 AUDIO_SOURCE_DEFAULT : adev->active_input->source;
1711
1712 audio_mode_t mode = adev->mode;
1713 audio_devices_t in_device = ((adev->active_input == NULL) ?
1714 AUDIO_DEVICE_NONE : adev->active_input->device)
1715 & ~AUDIO_DEVICE_BIT_IN;
1716 audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
1717 AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
1718 snd_device_t snd_device = SND_DEVICE_NONE;
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001719 int channel_count = popcount(channel_mask);
Eric Laurentb23d5282013-05-14 15:27:20 -07001720
1721 ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
1722 __func__, out_device, in_device);
Tanya Finkel00130052014-07-14 04:26:56 -07001723 if (my_data->external_mic) {
1724 if (((out_device != AUDIO_DEVICE_NONE) && (mode == AUDIO_MODE_IN_CALL)) ||
1725 voice_extn_compress_voip_is_active(adev) || audio_extn_hfp_is_active(adev)) {
1726 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1727 out_device & AUDIO_DEVICE_OUT_EARPIECE ||
1728 out_device & AUDIO_DEVICE_OUT_SPEAKER )
1729 snd_device = SND_DEVICE_IN_HANDSET_MIC_EXTERNAL;
1730 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
1731 in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1732 snd_device = SND_DEVICE_IN_HANDSET_MIC_EXTERNAL;
1733 }
1734 }
1735
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -07001736 if (snd_device != AUDIO_DEVICE_NONE)
Tanya Finkel00130052014-07-14 04:26:56 -07001737 goto exit;
1738
Helen Zeng067b96b2013-11-26 12:10:29 -08001739 if ((out_device != AUDIO_DEVICE_NONE) && ((mode == AUDIO_MODE_IN_CALL) ||
Satya Krishna Pindiproli071950f2014-05-21 14:45:28 +05301740 voice_extn_compress_voip_is_active(adev) || audio_extn_hfp_is_active(adev))) {
Narsinga Rao Chella05573b72013-11-15 15:21:40 -08001741 if ((adev->voice.tty_mode != TTY_MODE_OFF) &&
1742 !voice_extn_compress_voip_is_active(adev)) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001743 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1744 out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001745 switch (adev->voice.tty_mode) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001746 case TTY_MODE_FULL:
1747 snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC;
1748 break;
1749 case TTY_MODE_VCO:
1750 snd_device = SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC;
1751 break;
1752 case TTY_MODE_HCO:
1753 snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC;
1754 break;
1755 default:
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -07001756 ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->voice.tty_mode);
Eric Laurentb23d5282013-05-14 15:27:20 -07001757 }
1758 goto exit;
1759 }
1760 }
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -07001761 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001762 if (out_device & AUDIO_DEVICE_OUT_EARPIECE &&
1763 audio_extn_should_use_handset_anc(channel_count)) {
1764 snd_device = SND_DEVICE_IN_AANC_HANDSET_MIC;
Banajit Goswamide0ea452014-04-07 12:11:47 -07001765 adev->acdb_settings |= ANC_FLAG;
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001766 } else if (my_data->fluence_type == FLUENCE_NONE ||
Mingming Yin8e5a4f62013-10-07 15:23:41 -07001767 my_data->fluence_in_voice_call == false) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001768 snd_device = SND_DEVICE_IN_HANDSET_MIC;
Venkata Narendra Kumar Gutta1bbbf542014-09-04 19:11:25 +05301769 if (audio_extn_hfp_is_active(adev))
1770 platform_set_echo_reference(adev->platform, true);
Eric Laurentb23d5282013-05-14 15:27:20 -07001771 } else {
Ravi Kumar Alamandaceb40822013-11-06 11:01:47 -08001772 snd_device = SND_DEVICE_IN_VOICE_DMIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001773 }
1774 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1775 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
Venkata Narendra Kumar Gutta1bbbf542014-09-04 19:11:25 +05301776 if (audio_extn_hfp_is_active(adev))
1777 platform_set_echo_reference(adev->platform, true);
Eric Laurentb23d5282013-05-14 15:27:20 -07001778 } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
Vicky Sehrawate240e5d2014-08-12 17:17:04 -07001779 if (adev->bt_wb_speech_enabled) {
1780 if (adev->bluetooth_nrec)
1781 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
1782 else
1783 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
1784 } else {
1785 if (adev->bluetooth_nrec)
1786 snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
1787 else
1788 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
1789 }
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -07001790 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
1791 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
Mingming Yin8e5a4f62013-10-07 15:23:41 -07001792 if (my_data->fluence_type != FLUENCE_NONE &&
1793 my_data->fluence_in_voice_call &&
1794 my_data->fluence_in_spkr_mode) {
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -08001795 if(my_data->fluence_type & FLUENCE_QUAD_MIC) {
Mingming Yin8e5a4f62013-10-07 15:23:41 -07001796 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_QMIC;
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -08001797 } else {
Narsinga Rao Chella61e0f9b2014-03-06 21:25:22 -08001798 if (my_data->fluence_mode == FLUENCE_BROADSIDE)
1799 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BROADSIDE;
1800 else
1801 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC;
Mingming Yin8e5a4f62013-10-07 15:23:41 -07001802 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001803 } else {
1804 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
Venkata Narendra Kumar Gutta1bbbf542014-09-04 19:11:25 +05301805 if (audio_extn_hfp_is_active(adev))
1806 platform_set_echo_reference(adev->platform, true);
Eric Laurentb23d5282013-05-14 15:27:20 -07001807 }
1808 }
1809 } else if (source == AUDIO_SOURCE_CAMCORDER) {
1810 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
1811 in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1812 snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
1813 }
1814 } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
1815 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001816 if (channel_count == 2) {
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -08001817 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO;
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001818 } else if (adev->active_input->enable_ns)
1819 snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
1820 else if (my_data->fluence_type != FLUENCE_NONE &&
1821 my_data->fluence_in_voice_rec) {
1822 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001823 } else {
1824 snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
1825 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001826 }
1827 } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
1828 if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
1829 in_device = AUDIO_DEVICE_IN_BACK_MIC;
1830 if (adev->active_input) {
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001831 if (adev->active_input->enable_aec &&
1832 adev->active_input->enable_ns) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001833 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001834 if (my_data->fluence_type & FLUENCE_DUAL_MIC &&
1835 my_data->fluence_in_spkr_mode) {
Narsinga Rao Chella61e0f9b2014-03-06 21:25:22 -08001836 if (my_data->fluence_mode == FLUENCE_BROADSIDE)
1837 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE;
1838 else
1839 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001840 } else
1841 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
Eric Laurentb23d5282013-05-14 15:27:20 -07001842 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001843 if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
1844 snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001845 } else
1846 snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
Eric Laurentb23d5282013-05-14 15:27:20 -07001847 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001848 snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
Eric Laurentb23d5282013-05-14 15:27:20 -07001849 }
Venkata Narendra Kumar Gutta1bbbf542014-09-04 19:11:25 +05301850 platform_set_echo_reference(adev->platform, true);
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001851 } else if (adev->active_input->enable_aec) {
1852 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
Narsinga Rao Chella61e0f9b2014-03-06 21:25:22 -08001853 if (my_data->fluence_type & FLUENCE_DUAL_MIC &&
1854 my_data->fluence_in_spkr_mode) {
1855 if (my_data->fluence_mode == FLUENCE_BROADSIDE)
1856 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE;
1857 else
1858 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001859 } else
1860 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
1861 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
1862 if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
1863 snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001864 } else
1865 snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
1866 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
1867 snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
1868 }
Venkata Narendra Kumar Gutta1bbbf542014-09-04 19:11:25 +05301869 platform_set_echo_reference(adev->platform, true);
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001870 } else if (adev->active_input->enable_ns) {
1871 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
Narsinga Rao Chella61e0f9b2014-03-06 21:25:22 -08001872 if (my_data->fluence_type & FLUENCE_DUAL_MIC &&
1873 my_data->fluence_in_spkr_mode) {
1874 if (my_data->fluence_mode == FLUENCE_BROADSIDE)
1875 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE;
1876 else
1877 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001878 } else
1879 snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
1880 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
1881 if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
1882 snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001883 } else
1884 snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
1885 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
1886 snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
1887 }
Venkata Narendra Kumar Gutta1bbbf542014-09-04 19:11:25 +05301888 platform_set_echo_reference(adev->platform, false);
Eric Laurentb23d5282013-05-14 15:27:20 -07001889 } else
Venkata Narendra Kumar Gutta1bbbf542014-09-04 19:11:25 +05301890 platform_set_echo_reference(adev->platform, false);
Eric Laurentb23d5282013-05-14 15:27:20 -07001891 }
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -08001892 } else if (source == AUDIO_SOURCE_MIC) {
Apoorv Raghuvanshic0536542013-11-14 16:25:59 -08001893 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC &&
1894 channel_count == 1 ) {
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -08001895 if(my_data->fluence_type & FLUENCE_DUAL_MIC &&
Ravi Kumar Alamanda7076b162014-03-07 11:40:24 -08001896 my_data->fluence_in_audio_rec) {
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -08001897 snd_device = SND_DEVICE_IN_HANDSET_DMIC;
Venkata Narendra Kumar Gutta1bbbf542014-09-04 19:11:25 +05301898 platform_set_echo_reference(adev->platform, true);
Ravi Kumar Alamanda7076b162014-03-07 11:40:24 -08001899 }
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -08001900 }
Mingming Yinab429782013-11-07 11:16:55 -08001901 } else if (source == AUDIO_SOURCE_FM_RX ||
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08001902 source == AUDIO_SOURCE_FM_RX_A2DP) {
Preetam Singh Ranawatde84f1a2013-11-01 14:58:16 -07001903 snd_device = SND_DEVICE_IN_CAPTURE_FM;
Eric Laurentb23d5282013-05-14 15:27:20 -07001904 } else if (source == AUDIO_SOURCE_DEFAULT) {
1905 goto exit;
1906 }
1907
1908
1909 if (snd_device != SND_DEVICE_NONE) {
1910 goto exit;
1911 }
1912
1913 if (in_device != AUDIO_DEVICE_NONE &&
1914 !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
1915 !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
1916 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Apoorv Raghuvanshi6178a3f2013-10-19 12:38:54 -07001917 if (audio_extn_ssr_get_enabled() && channel_count == 6)
1918 snd_device = SND_DEVICE_IN_QUAD_MIC;
Walter Yangbc136bd2014-01-17 11:24:23 +08001919 else if (my_data->fluence_type & (FLUENCE_DUAL_MIC | FLUENCE_QUAD_MIC) &&
1920 channel_count == 2)
Apoorv Raghuvanshi6bd8dbf2013-10-19 18:37:52 -07001921 snd_device = SND_DEVICE_IN_HANDSET_STEREO_DMIC;
Apoorv Raghuvanshi6178a3f2013-10-19 12:38:54 -07001922 else
1923 snd_device = SND_DEVICE_IN_HANDSET_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001924 } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1925 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
1926 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
1927 snd_device = SND_DEVICE_IN_HEADSET_MIC;
1928 } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
Vicky Sehrawate240e5d2014-08-12 17:17:04 -07001929 if (adev->bt_wb_speech_enabled) {
1930 if (adev->bluetooth_nrec)
1931 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
1932 else
1933 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
1934 } else {
1935 if (adev->bluetooth_nrec)
1936 snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
1937 else
1938 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
1939 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001940 } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
1941 snd_device = SND_DEVICE_IN_HDMI_MIC;
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001942 } else if (in_device & AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET ||
1943 in_device & AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET) {
1944 snd_device = SND_DEVICE_IN_USB_HEADSET_MIC;
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -07001945 } else if (in_device & AUDIO_DEVICE_IN_FM_RX) {
1946 snd_device = SND_DEVICE_IN_CAPTURE_FM;
Eric Laurentb23d5282013-05-14 15:27:20 -07001947 } else {
1948 ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
1949 ALOGW("%s: Using default handset-mic", __func__);
1950 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1951 }
1952 } else {
1953 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
1954 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1955 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1956 snd_device = SND_DEVICE_IN_HEADSET_MIC;
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -07001957 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER ||
1958 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
1959 if (channel_count == 2)
Apoorv Raghuvanshi6bd8dbf2013-10-19 18:37:52 -07001960 snd_device = SND_DEVICE_IN_SPEAKER_STEREO_DMIC;
1961 else
1962 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001963 } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
Vicky Sehrawate240e5d2014-08-12 17:17:04 -07001964 if (adev->bt_wb_speech_enabled) {
1965 if (adev->bluetooth_nrec)
1966 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
1967 else
1968 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
1969 } else {
1970 if (adev->bluetooth_nrec)
1971 snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
1972 else
1973 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
1974 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001975 } else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
1976 snd_device = SND_DEVICE_IN_HDMI_MIC;
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001977 } else if (out_device & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
1978 out_device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
1979 snd_device = SND_DEVICE_IN_USB_HEADSET_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001980 } else {
1981 ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
1982 ALOGW("%s: Using default handset-mic", __func__);
1983 snd_device = SND_DEVICE_IN_HANDSET_MIC;
1984 }
1985 }
1986exit:
1987 ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
1988 return snd_device;
1989}
1990
1991int platform_set_hdmi_channels(void *platform, int channel_count)
1992{
1993 struct platform_data *my_data = (struct platform_data *)platform;
1994 struct audio_device *adev = my_data->adev;
1995 struct mixer_ctl *ctl;
1996 const char *channel_cnt_str = NULL;
1997 const char *mixer_ctl_name = "HDMI_RX Channels";
1998 switch (channel_count) {
1999 case 8:
2000 channel_cnt_str = "Eight"; break;
2001 case 7:
2002 channel_cnt_str = "Seven"; break;
2003 case 6:
2004 channel_cnt_str = "Six"; break;
2005 case 5:
2006 channel_cnt_str = "Five"; break;
2007 case 4:
2008 channel_cnt_str = "Four"; break;
2009 case 3:
2010 channel_cnt_str = "Three"; break;
2011 default:
2012 channel_cnt_str = "Two"; break;
2013 }
2014 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2015 if (!ctl) {
2016 ALOGE("%s: Could not get ctl for mixer cmd - %s",
2017 __func__, mixer_ctl_name);
2018 return -EINVAL;
2019 }
2020 ALOGV("HDMI channel count: %s", channel_cnt_str);
2021 mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
2022 return 0;
2023}
2024
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07002025int platform_edid_get_max_channels(void *platform)
Eric Laurentb23d5282013-05-14 15:27:20 -07002026{
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07002027 struct platform_data *my_data = (struct platform_data *)platform;
2028 struct audio_device *adev = my_data->adev;
Eric Laurentb23d5282013-05-14 15:27:20 -07002029 char block[MAX_SAD_BLOCKS * SAD_BLOCK_SIZE];
2030 char *sad = block;
2031 int num_audio_blocks;
2032 int channel_count;
2033 int max_channels = 0;
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07002034 int i, ret, count;
Eric Laurentb23d5282013-05-14 15:27:20 -07002035
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07002036 struct mixer_ctl *ctl;
2037
2038 ctl = mixer_get_ctl_by_name(adev->mixer, AUDIO_DATA_BLOCK_MIXER_CTL);
2039 if (!ctl) {
2040 ALOGE("%s: Could not get ctl for mixer cmd - %s",
2041 __func__, AUDIO_DATA_BLOCK_MIXER_CTL);
Eric Laurentb23d5282013-05-14 15:27:20 -07002042 return 0;
2043 }
2044
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07002045 mixer_ctl_update(ctl);
2046
2047 count = mixer_ctl_get_num_values(ctl);
Eric Laurentb23d5282013-05-14 15:27:20 -07002048
2049 /* Read SAD blocks, clamping the maximum size for safety */
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07002050 if (count > (int)sizeof(block))
2051 count = (int)sizeof(block);
Eric Laurentb23d5282013-05-14 15:27:20 -07002052
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07002053 ret = mixer_ctl_get_array(ctl, block, count);
2054 if (ret != 0) {
2055 ALOGE("%s: mixer_ctl_get_array() failed to get EDID info", __func__);
2056 return 0;
2057 }
Eric Laurentb23d5282013-05-14 15:27:20 -07002058
2059 /* Calculate the number of SAD blocks */
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07002060 num_audio_blocks = count / SAD_BLOCK_SIZE;
Eric Laurentb23d5282013-05-14 15:27:20 -07002061
2062 for (i = 0; i < num_audio_blocks; i++) {
2063 /* Only consider LPCM blocks */
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07002064 if ((sad[0] >> 3) != EDID_FORMAT_LPCM) {
2065 sad += 3;
Eric Laurentb23d5282013-05-14 15:27:20 -07002066 continue;
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07002067 }
Eric Laurentb23d5282013-05-14 15:27:20 -07002068
2069 channel_count = (sad[0] & 0x7) + 1;
2070 if (channel_count > max_channels)
2071 max_channels = channel_count;
2072
2073 /* Advance to next block */
2074 sad += 3;
2075 }
2076
2077 return max_channels;
2078}
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002079
2080static int platform_set_slowtalk(struct platform_data *my_data, bool state)
2081{
2082 int ret = 0;
2083 struct audio_device *adev = my_data->adev;
2084 struct mixer_ctl *ctl;
2085 const char *mixer_ctl_name = "Slowtalk Enable";
2086 uint32_t set_values[ ] = {0,
2087 ALL_SESSION_VSID};
2088
2089 set_values[0] = state;
2090 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2091 if (!ctl) {
2092 ALOGE("%s: Could not get ctl for mixer cmd - %s",
2093 __func__, mixer_ctl_name);
2094 ret = -EINVAL;
2095 } else {
2096 ALOGV("Setting slowtalk state: %d", state);
2097 ret = mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
2098 my_data->slowtalk = state;
2099 }
2100
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08002101 if (my_data->csd != NULL) {
2102 ret = my_data->csd->slow_talk(ALL_SESSION_VSID, state);
2103 if (ret < 0) {
2104 ALOGE("%s: csd_client_disable_device, failed, error %d",
2105 __func__, ret);
2106 }
2107 }
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002108 return ret;
2109}
2110
Avinash Vaishd5fa4572014-09-15 14:41:14 +05302111static int set_hd_voice(struct platform_data *my_data, bool state)
2112{
2113 struct audio_device *adev = my_data->adev;
2114 struct mixer_ctl *ctl;
2115 char *mixer_ctl_name = "HD Voice Enable";
2116 int ret = 0;
2117 uint32_t set_values[ ] = {0,
2118 ALL_SESSION_VSID};
2119
2120 set_values[0] = state;
2121 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2122 if (!ctl) {
2123 ALOGE("%s: Could not get ctl for mixer cmd - %s",
2124 __func__, mixer_ctl_name);
2125 return -EINVAL;
2126 } else {
2127 ALOGV("Setting HD Voice state: %d", state);
2128 ret = mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
2129 my_data->hd_voice = state;
2130 }
2131
2132 return ret;
2133}
Tanya Finkel00130052014-07-14 04:26:56 -07002134
2135static int update_external_device_status(struct platform_data *my_data,
2136 char* event_name, bool status)
2137{
2138 int ret = 0;
2139 struct audio_usecase *usecase;
2140 struct listnode *node;
2141
2142 ALOGD("Recieved external event switch %s", event_name);
2143
2144 if (!strcmp(event_name, EVENT_EXTERNAL_SPK_1))
2145 my_data->external_spk_1 = status;
2146 else if (!strcmp(event_name, EVENT_EXTERNAL_SPK_2))
2147 my_data->external_spk_2 = status;
2148 else if (!strcmp(event_name, EVENT_EXTERNAL_MIC))
2149 my_data->external_mic = status;
2150 else {
2151 ALOGE("The audio event type is not found");
2152 return -EINVAL;
2153 }
2154
2155 list_for_each(node, &my_data->adev->usecase_list) {
2156 usecase = node_to_item(node, struct audio_usecase, list);
2157 select_devices(my_data->adev, usecase->id);
2158 }
2159
2160 return ret;
2161}
2162
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002163int platform_set_parameters(void *platform, struct str_parms *parms)
2164{
2165 struct platform_data *my_data = (struct platform_data *)platform;
2166 char *str;
Vidyakumar Athota3ade2792013-12-02 11:02:20 -08002167 char value[256] = {0};
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002168 int val;
Shiv Maliyappanahalli3e064fd2013-12-16 15:54:40 -08002169 int ret = 0, err;
Krishnankutty Kolathappilly061a9492014-01-31 18:12:13 -08002170 char *kv_pairs = str_parms_to_str(parms);
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002171
Krishnankutty Kolathappilly061a9492014-01-31 18:12:13 -08002172 ALOGV_IF(kv_pairs != NULL, "%s: enter: %s", __func__, kv_pairs);
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002173
Shiv Maliyappanahalli3e064fd2013-12-16 15:54:40 -08002174 err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SLOWTALK, value, sizeof(value));
2175 if (err >= 0) {
Vidyakumar Athota3ade2792013-12-02 11:02:20 -08002176 bool state = false;
2177 if (!strncmp("true", value, sizeof("true"))) {
2178 state = true;
2179 }
2180
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002181 str_parms_del(parms, AUDIO_PARAMETER_KEY_SLOWTALK);
Vidyakumar Athota3ade2792013-12-02 11:02:20 -08002182 ret = platform_set_slowtalk(my_data, state);
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002183 if (ret)
2184 ALOGE("%s: Failed to set slow talk err: %d", __func__, ret);
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002185 }
2186
Avinash Vaishd5fa4572014-09-15 14:41:14 +05302187 err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_HD_VOICE, value, sizeof(value));
2188 if (err >= 0) {
2189 bool state = false;
2190 if (!strncmp("true", value, sizeof("true"))) {
2191 state = true;
2192 }
2193
2194 str_parms_del(parms, AUDIO_PARAMETER_KEY_HD_VOICE);
2195 if (my_data->hd_voice != state) {
2196 ret = set_hd_voice(my_data, state);
2197 if (ret)
2198 ALOGE("%s: Failed to set HD voice err: %d", __func__, ret);
2199 } else {
2200 ALOGV("%s: HD Voice already set to %d", __func__, state);
2201 }
2202 }
2203
Shiv Maliyappanahalli3e064fd2013-12-16 15:54:40 -08002204 err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_VOLUME_BOOST,
Ben Rombergerc1dc70d2013-12-19 15:11:17 -08002205 value, sizeof(value));
Shiv Maliyappanahalli3e064fd2013-12-16 15:54:40 -08002206 if (err >= 0) {
Ben Rombergerc1dc70d2013-12-19 15:11:17 -08002207 str_parms_del(parms, AUDIO_PARAMETER_KEY_VOLUME_BOOST);
2208
2209 if (my_data->acdb_reload_vocvoltable == NULL) {
2210 ALOGE("%s: acdb_reload_vocvoltable is NULL", __func__);
2211 } else if (!strcmp(value, "on")) {
2212 if (!my_data->acdb_reload_vocvoltable(VOICE_FEATURE_SET_VOLUME_BOOST)) {
2213 my_data->voice_feature_set = 1;
2214 }
2215 } else {
2216 if (!my_data->acdb_reload_vocvoltable(VOICE_FEATURE_SET_DEFAULT)) {
2217 my_data->voice_feature_set = 0;
2218 }
2219 }
2220 }
2221
Tanya Finkel00130052014-07-14 04:26:56 -07002222 err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_EXT_AUDIO_DEVICE,
2223 value, sizeof(value));
2224 if (err >= 0) {
2225 char *event_name, *status_str;
2226 bool status = false;
2227 str_parms_del(parms, AUDIO_PARAMETER_KEY_EXT_AUDIO_DEVICE);
2228 event_name = strtok_r(value, ",", &status_str);
2229 ALOGV("%s: recieved update of external audio device %s %s",
2230 __func__,
2231 event_name, status_str);
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -07002232 if (!strncmp(status_str, "ON", sizeof("ON")))
Tanya Finkel00130052014-07-14 04:26:56 -07002233 status = true;
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -07002234 else if (!strncmp(status_str, "OFF", sizeof("OFF")))
Tanya Finkel00130052014-07-14 04:26:56 -07002235 status = false;
2236 update_external_device_status(my_data, event_name, status);
2237 }
2238
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002239 ALOGV("%s: exit with code(%d)", __func__, ret);
Krishnankutty Kolathappilly061a9492014-01-31 18:12:13 -08002240 free(kv_pairs);
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002241 return ret;
2242}
2243
Vidyakumar Athota2850d532013-11-19 16:02:12 -08002244int platform_set_incall_recording_session_id(void *platform,
2245 uint32_t session_id, int rec_mode)
Shiv Maliyappanahallida107642013-10-17 11:16:13 -07002246{
2247 int ret = 0;
2248 struct platform_data *my_data = (struct platform_data *)platform;
2249 struct audio_device *adev = my_data->adev;
2250 struct mixer_ctl *ctl;
2251 const char *mixer_ctl_name = "Voc VSID";
2252 int num_ctl_values;
2253 int i;
2254
2255 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2256 if (!ctl) {
2257 ALOGE("%s: Could not get ctl for mixer cmd - %s",
2258 __func__, mixer_ctl_name);
2259 ret = -EINVAL;
2260 } else {
2261 num_ctl_values = mixer_ctl_get_num_values(ctl);
2262 for (i = 0; i < num_ctl_values; i++) {
2263 if (mixer_ctl_set_value(ctl, i, session_id)) {
2264 ALOGV("Error: invalid session_id: %x", session_id);
2265 ret = -EINVAL;
2266 break;
2267 }
2268 }
2269 }
2270
Vidyakumar Athota2850d532013-11-19 16:02:12 -08002271 if (my_data->csd != NULL) {
2272 ret = my_data->csd->start_record(ALL_SESSION_VSID, rec_mode);
2273 if (ret < 0) {
2274 ALOGE("%s: csd_client_start_record failed, error %d",
2275 __func__, ret);
2276 }
2277 }
2278
2279 return ret;
2280}
2281
2282int platform_stop_incall_recording_usecase(void *platform)
2283{
2284 int ret = 0;
2285 struct platform_data *my_data = (struct platform_data *)platform;
2286
2287 if (my_data->csd != NULL) {
2288 ret = my_data->csd->stop_record(ALL_SESSION_VSID);
2289 if (ret < 0) {
2290 ALOGE("%s: csd_client_stop_record failed, error %d",
2291 __func__, ret);
2292 }
2293 }
2294
2295 return ret;
2296}
2297
2298int platform_start_incall_music_usecase(void *platform)
2299{
2300 int ret = 0;
2301 struct platform_data *my_data = (struct platform_data *)platform;
2302
2303 if (my_data->csd != NULL) {
2304 ret = my_data->csd->start_playback(ALL_SESSION_VSID);
2305 if (ret < 0) {
2306 ALOGE("%s: csd_client_start_playback failed, error %d",
2307 __func__, ret);
2308 }
2309 }
2310
2311 return ret;
2312}
2313
2314int platform_stop_incall_music_usecase(void *platform)
2315{
2316 int ret = 0;
2317 struct platform_data *my_data = (struct platform_data *)platform;
2318
2319 if (my_data->csd != NULL) {
2320 ret = my_data->csd->stop_playback(ALL_SESSION_VSID);
2321 if (ret < 0) {
2322 ALOGE("%s: csd_client_stop_playback failed, error %d",
2323 __func__, ret);
2324 }
2325 }
2326
Shiv Maliyappanahallida107642013-10-17 11:16:13 -07002327 return ret;
2328}
2329
Vidyakumar Athota21b3bb92014-04-25 11:08:08 -07002330int platform_update_lch(void *platform, struct voice_session *session,
2331 enum voice_lch_mode lch_mode)
2332{
2333 int ret = 0;
2334 struct platform_data *my_data = (struct platform_data *)platform;
2335
2336 if ((my_data->csd != NULL) && (my_data->csd->set_lch != NULL))
2337 ret = my_data->csd->set_lch(session->vsid, lch_mode);
2338 else
2339 ret = pcm_ioctl(session->pcm_tx, SNDRV_VOICE_IOCTL_LCH, &lch_mode);
2340
2341 return ret;
2342}
2343
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002344void platform_get_parameters(void *platform,
2345 struct str_parms *query,
2346 struct str_parms *reply)
2347{
2348 struct platform_data *my_data = (struct platform_data *)platform;
2349 char *str = NULL;
2350 char value[256] = {0};
2351 int ret;
Krishnankutty Kolathappilly061a9492014-01-31 18:12:13 -08002352 char *kv_pairs = NULL;
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002353
Shiv Maliyappanahalli9d899292013-11-20 14:43:01 -08002354 ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_SLOWTALK,
2355 value, sizeof(value));
2356 if (ret >= 0) {
Vidyakumar Athota3ade2792013-12-02 11:02:20 -08002357 str_parms_add_str(reply, AUDIO_PARAMETER_KEY_SLOWTALK,
2358 my_data->slowtalk?"true":"false");
Shiv Maliyappanahalli9d899292013-11-20 14:43:01 -08002359 }
2360
Avinash Vaishd5fa4572014-09-15 14:41:14 +05302361 ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_HD_VOICE,
2362 value, sizeof(value));
2363 if (ret >= 0) {
2364 str_parms_add_str(reply, AUDIO_PARAMETER_KEY_HD_VOICE,
2365 my_data->hd_voice?"true":"false");
2366 }
2367
Ben Rombergerc1dc70d2013-12-19 15:11:17 -08002368 ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_VOLUME_BOOST,
2369 value, sizeof(value));
2370 if (ret >= 0) {
2371 if (my_data->voice_feature_set == VOICE_FEATURE_SET_VOLUME_BOOST) {
2372 strlcpy(value, "on", sizeof(value));
2373 } else {
2374 strlcpy(value, "off", sizeof(value));
2375 }
2376
2377 str_parms_add_str(reply, AUDIO_PARAMETER_KEY_VOLUME_BOOST, value);
2378 }
2379
Krishnankutty Kolathappilly061a9492014-01-31 18:12:13 -08002380 kv_pairs = str_parms_to_str(reply);
2381 ALOGV_IF(kv_pairs != NULL, "%s: exit: returns - %s", __func__, kv_pairs);
Narsinga Rao Chellacde45d12014-02-13 11:44:31 -08002382 free(kv_pairs);
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002383}
2384
Haynes Mathew George7ff216f2013-09-11 19:51:41 -07002385/* Delay in Us */
2386int64_t platform_render_latency(audio_usecase_t usecase)
2387{
2388 switch (usecase) {
2389 case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
2390 return DEEP_BUFFER_PLATFORM_DELAY;
2391 case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
2392 return LOW_LATENCY_PLATFORM_DELAY;
2393 default:
2394 return 0;
2395 }
2396}
Preetam Singh Ranawatde84f1a2013-11-01 14:58:16 -07002397
Mingming Yine62d7842013-10-25 16:26:03 -07002398int platform_update_usecase_from_source(int source, int usecase)
Preetam Singh Ranawatde84f1a2013-11-01 14:58:16 -07002399{
Mingming Yinab429782013-11-07 11:16:55 -08002400 ALOGV("%s: input source :%d", __func__, source);
2401 if(source == AUDIO_SOURCE_FM_RX_A2DP)
Mingming Yine62d7842013-10-25 16:26:03 -07002402 usecase = USECASE_AUDIO_RECORD_FM_VIRTUAL;
2403 return usecase;
Preetam Singh Ranawatde84f1a2013-11-01 14:58:16 -07002404}
Kiran Kandide144c82013-11-20 15:58:32 -08002405
Dhananjay Kumar45b71742014-05-29 21:47:27 +05302406bool platform_listen_device_needs_event(snd_device_t snd_device)
Kiran Kandide144c82013-11-20 15:58:32 -08002407{
Dhananjay Kumar45b71742014-05-29 21:47:27 +05302408 bool needs_event = false;
2409
Kiran Kandide144c82013-11-20 15:58:32 -08002410 if ((snd_device >= SND_DEVICE_IN_BEGIN) &&
2411 (snd_device < SND_DEVICE_IN_END) &&
2412 (snd_device != SND_DEVICE_IN_CAPTURE_FM) &&
2413 (snd_device != SND_DEVICE_IN_CAPTURE_VI_FEEDBACK))
Dhananjay Kumar45b71742014-05-29 21:47:27 +05302414 needs_event = true;
2415
2416 return needs_event;
2417}
2418
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -07002419bool platform_listen_usecase_needs_event(audio_usecase_t uc_id __unused)
2420{
2421 return false;
2422}
2423
2424bool platform_sound_trigger_device_needs_event(snd_device_t snd_device)
2425{
2426 bool needs_event = false;
2427
2428 if ((snd_device >= SND_DEVICE_IN_BEGIN) &&
2429 (snd_device < SND_DEVICE_IN_END) &&
2430 (snd_device != SND_DEVICE_IN_CAPTURE_FM) &&
2431 (snd_device != SND_DEVICE_IN_CAPTURE_VI_FEEDBACK))
2432 needs_event = true;
2433
2434 return needs_event;
2435}
2436
2437bool platform_sound_trigger_usecase_needs_event(audio_usecase_t uc_id __unused)
Dhananjay Kumar45b71742014-05-29 21:47:27 +05302438{
2439 return false;
Kiran Kandide144c82013-11-20 15:58:32 -08002440}
ApurupaPattapuc6a3a9e2014-01-10 14:46:02 -08002441
2442/* Read offload buffer size from a property.
2443 * If value is not power of 2 round it to
2444 * power of 2.
2445 */
2446uint32_t platform_get_compress_offload_buffer_size(audio_offload_info_t* info)
2447{
2448 char value[PROPERTY_VALUE_MAX] = {0};
2449 uint32_t fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
2450 if((property_get("audio.offload.buffer.size.kb", value, "")) &&
2451 atoi(value)) {
2452 fragment_size = atoi(value) * 1024;
2453 }
2454
Mingming Yin3ee55c62014-08-04 14:23:35 -07002455 // For FLAC use max size since it is loss less, and has sampling rates
2456 // upto 192kHZ
2457 if (info != NULL && !info->has_video &&
2458 info->format == AUDIO_FORMAT_FLAC) {
2459 fragment_size = MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE;
2460 ALOGV("FLAC fragment size %d", fragment_size);
2461 }
2462
ApurupaPattapuc6a3a9e2014-01-10 14:46:02 -08002463 if (info != NULL && info->has_video && info->is_streaming) {
2464 fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE_FOR_AV_STREAMING;
2465 ALOGV("%s: offload fragment size reduced for AV streaming to %d",
ApurupaPattapu31d09d72014-03-05 11:13:32 -08002466 __func__, fragment_size);
ApurupaPattapuc6a3a9e2014-01-10 14:46:02 -08002467 }
2468
2469 fragment_size = ALIGN( fragment_size, 1024);
2470
2471 if(fragment_size < MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE)
2472 fragment_size = MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE;
2473 else if(fragment_size > MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE)
2474 fragment_size = MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE;
2475 ALOGV("%s: fragment_size %d", __func__, fragment_size);
2476 return fragment_size;
2477}
2478
2479uint32_t platform_get_pcm_offload_buffer_size(audio_offload_info_t* info)
2480{
2481 uint32_t fragment_size = MIN_PCM_OFFLOAD_FRAGMENT_SIZE;
2482 uint32_t bits_per_sample = 16;
2483
2484 if (info->format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD) {
2485 bits_per_sample = 32;
2486 }
2487
2488 if (!info->has_video) {
2489 fragment_size = MAX_PCM_OFFLOAD_FRAGMENT_SIZE;
2490
2491 } else if (info->has_video && info->is_streaming) {
2492 fragment_size = (PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING
2493 * info->sample_rate
ApurupaPattapub57da782014-04-08 10:41:07 -07002494 * (bits_per_sample >> 3)
ApurupaPattapuc6a3a9e2014-01-10 14:46:02 -08002495 * popcount(info->channel_mask))/1000;
2496
2497 } else if (info->has_video) {
2498 fragment_size = (PCM_OFFLOAD_BUFFER_DURATION_FOR_AV
2499 * info->sample_rate
ApurupaPattapub57da782014-04-08 10:41:07 -07002500 * (bits_per_sample >> 3)
ApurupaPattapuc6a3a9e2014-01-10 14:46:02 -08002501 * popcount(info->channel_mask))/1000;
2502 }
2503
ApurupaPattapub57da782014-04-08 10:41:07 -07002504 char value[PROPERTY_VALUE_MAX] = {0};
2505 if((property_get("audio.offload.pcm.buffer.size", value, "")) &&
2506 atoi(value)) {
2507 fragment_size = atoi(value) * 1024;
2508 ALOGV("Using buffer size from sys prop %d", fragment_size);
2509 }
2510
ApurupaPattapuc6a3a9e2014-01-10 14:46:02 -08002511 fragment_size = ALIGN( fragment_size, 1024);
2512
2513 if(fragment_size < MIN_PCM_OFFLOAD_FRAGMENT_SIZE)
2514 fragment_size = MIN_PCM_OFFLOAD_FRAGMENT_SIZE;
2515 else if(fragment_size > MAX_PCM_OFFLOAD_FRAGMENT_SIZE)
2516 fragment_size = MAX_PCM_OFFLOAD_FRAGMENT_SIZE;
2517
2518 ALOGV("%s: fragment_size %d", __func__, fragment_size);
2519 return fragment_size;
2520}
2521
Mingming Yin3ee55c62014-08-04 14:23:35 -07002522bool platform_check_24_bit_support() {
2523
2524 char value[PROPERTY_VALUE_MAX] = {0};
2525 property_get("audio.offload.24bit.enable", value, "0");
2526 if (atoi(value)) {
2527 ALOGW("Property audio.offload.24bit.enable is set");
2528 return true;
2529 }
2530 return false;
2531}
2532
2533int platform_set_codec_backend_cfg(struct audio_device* adev,
2534 unsigned int bit_width, unsigned int sample_rate)
2535{
Amit Shekhared7fb5c2014-08-01 17:18:53 -07002536 ALOGV("%s bit width: %d, sample rate: %d", __func__, bit_width, sample_rate);
Mingming Yin3ee55c62014-08-04 14:23:35 -07002537
2538 int ret = 0;
2539 if (bit_width != adev->cur_codec_backend_bit_width) {
2540 const char * mixer_ctl_name = "SLIM_0_RX Format";
2541 struct mixer_ctl *ctl;
2542 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2543 if (!ctl) {
2544 ALOGE("%s: Could not get ctl for mixer command - %s",
2545 __func__, mixer_ctl_name);
2546 return -EINVAL;
2547 }
2548
2549 if (bit_width == 24) {
2550 mixer_ctl_set_enum_by_string(ctl, "S24_LE");
2551 } else {
2552 mixer_ctl_set_enum_by_string(ctl, "S16_LE");
2553 sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
2554 }
2555 adev->cur_codec_backend_bit_width = bit_width;
2556 ALOGE("Backend bit width is set to %d ", bit_width);
2557 }
2558
Amit Shekhared7fb5c2014-08-01 17:18:53 -07002559 /*
2560 * Backend sample rate configuration follows:
2561 * 16 bit playback - 48khz for streams at any valid sample rate
2562 * 24 bit playback - 48khz for stream sample rate less than 48khz
2563 * 24 bit playback - 96khz for sample rate range of 48khz to 96khz
2564 * 24 bit playback - 192khz for sample rate range of 96khz to 192 khz
2565 * Upper limit is inclusive in the sample rate range.
2566 */
2567 // TODO: This has to be more dynamic based on policy file
2568 if (sample_rate != adev->cur_codec_backend_samplerate) {
Mingming Yin3ee55c62014-08-04 14:23:35 -07002569 char *rate_str = NULL;
2570 const char * mixer_ctl_name = "SLIM_0_RX SampleRate";
2571 struct mixer_ctl *ctl;
2572
2573 switch (sample_rate) {
2574 case 8000:
Mingming Yin3ee55c62014-08-04 14:23:35 -07002575 case 11025:
Mingming Yin3ee55c62014-08-04 14:23:35 -07002576 case 16000:
Mingming Yin3ee55c62014-08-04 14:23:35 -07002577 case 22050:
Mingming Yin3ee55c62014-08-04 14:23:35 -07002578 case 32000:
Mingming Yin3ee55c62014-08-04 14:23:35 -07002579 case 44100:
Mingming Yin3ee55c62014-08-04 14:23:35 -07002580 case 48000:
2581 rate_str = "KHZ_48";
2582 break;
2583 case 64000:
Mingming Yin3ee55c62014-08-04 14:23:35 -07002584 case 88200:
Mingming Yin3ee55c62014-08-04 14:23:35 -07002585 case 96000:
2586 rate_str = "KHZ_96";
2587 break;
2588 case 176400:
Mingming Yin3ee55c62014-08-04 14:23:35 -07002589 case 192000:
2590 rate_str = "KHZ_192";
2591 break;
2592 default:
2593 rate_str = "KHZ_48";
2594 break;
2595 }
2596
2597 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2598 if(!ctl) {
2599 ALOGE("%s: Could not get ctl for mixer command - %s",
2600 __func__, mixer_ctl_name);
2601 return -EINVAL;
2602 }
2603
2604 ALOGV("Set sample rate as rate_str = %s", rate_str);
2605 mixer_ctl_set_enum_by_string(ctl, rate_str);
2606 adev->cur_codec_backend_samplerate = sample_rate;
2607 }
2608
2609 return ret;
2610}
2611
2612bool platform_check_codec_backend_cfg(struct audio_device* adev,
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -07002613 struct audio_usecase* usecase __unused,
Mingming Yin3ee55c62014-08-04 14:23:35 -07002614 unsigned int* new_bit_width,
2615 unsigned int* new_sample_rate)
2616{
2617 bool backend_change = false;
2618 struct listnode *node;
2619 struct stream_out *out = NULL;
Amit Shekhar278e3362014-09-08 14:08:19 -07002620 unsigned int bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
2621 unsigned int sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
Mingming Yin3ee55c62014-08-04 14:23:35 -07002622
2623 // For voice calls use default configuration
2624 // force routing is not required here, caller will do it anyway
2625 if (adev->mode == AUDIO_MODE_IN_CALL ||
2626 adev->mode == AUDIO_MODE_IN_COMMUNICATION) {
2627 ALOGW("%s:Use default bw and sr for voice/voip calls ",__func__);
2628 *new_bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
2629 *new_sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
2630 backend_change = true;
2631 }
2632
Amit Shekhar278e3362014-09-08 14:08:19 -07002633 /*
2634 * The backend should be configured at highest bit width and/or
2635 * sample rate amongst all playback usecases.
2636 * If the selected sample rate and/or bit width differ with
2637 * current backend sample rate and/or bit width, then, we set the
2638 * backend re-configuration flag.
2639 *
2640 * Exception: 16 bit playbacks is allowed through 16 bit/48 khz backend only
2641 */
Mingming Yin3ee55c62014-08-04 14:23:35 -07002642 if (!backend_change) {
Mingming Yin3ee55c62014-08-04 14:23:35 -07002643 list_for_each(node, &adev->usecase_list) {
2644 struct audio_usecase *curr_usecase;
2645 curr_usecase = node_to_item(node, struct audio_usecase, list);
Amit Shekhared7fb5c2014-08-01 17:18:53 -07002646 if (curr_usecase->type == PCM_PLAYBACK) {
Mingming Yin3ee55c62014-08-04 14:23:35 -07002647 struct stream_out *out =
2648 (struct stream_out*) curr_usecase->stream.out;
2649 if (out != NULL ) {
2650 ALOGV("Offload playback running bw %d sr %d",
2651 out->bit_width, out->sample_rate);
Amit Shekhar278e3362014-09-08 14:08:19 -07002652 if (bit_width < out->bit_width)
2653 bit_width = out->bit_width;
2654 if (sample_rate < out->sample_rate)
2655 sample_rate = out->sample_rate;
Mingming Yin3ee55c62014-08-04 14:23:35 -07002656 }
2657 }
2658 }
2659 }
2660
Amit Shekhar278e3362014-09-08 14:08:19 -07002661 // 16 bit playbacks is allowed through 16 bit/48 khz backend only
Preetam Singh Ranawata4a37d82014-09-25 16:56:38 +05302662 if ((16 == bit_width) ||
2663 ((24 == bit_width) && (SND_DEVICE_OUT_SPEAKER == usecase->devices))) {
Amit Shekhar278e3362014-09-08 14:08:19 -07002664 sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
Preetam Singh Ranawata4a37d82014-09-25 16:56:38 +05302665 }
Mingming Yin3ee55c62014-08-04 14:23:35 -07002666 // Force routing if the expected bitwdith or samplerate
2667 // is not same as current backend comfiguration
Amit Shekhar278e3362014-09-08 14:08:19 -07002668 if ((bit_width != adev->cur_codec_backend_bit_width) ||
2669 (sample_rate != adev->cur_codec_backend_samplerate)) {
2670 *new_bit_width = bit_width;
2671 *new_sample_rate = sample_rate;
Mingming Yin3ee55c62014-08-04 14:23:35 -07002672 backend_change = true;
Amit Shekhar278e3362014-09-08 14:08:19 -07002673 ALOGI("%s Codec backend needs to be updated. new bit width: %d new sample rate: %d",
2674 __func__, *new_bit_width, *new_sample_rate);
Mingming Yin3ee55c62014-08-04 14:23:35 -07002675 }
2676
2677 return backend_change;
2678}
2679
2680bool platform_check_and_set_codec_backend_cfg(struct audio_device* adev, struct audio_usecase *usecase)
2681{
2682 // check if 24bit configuration is enabled first
2683 if (!platform_check_24_bit_support()) {
2684 ALOGW("24bit not enable, no need to check for backend change");
2685 return false;
2686 }
2687
2688 ALOGV("platform_check_and_set_codec_backend_cfg usecase = %d",usecase->id );
2689
2690 unsigned int new_bit_width, old_bit_width;
2691 unsigned int new_sample_rate, old_sample_rate;
2692
2693 new_bit_width = old_bit_width = adev->cur_codec_backend_bit_width;
2694 new_sample_rate = old_sample_rate = adev->cur_codec_backend_samplerate;
2695
2696 ALOGW("Codec backend bitwidth %d, samplerate %d", old_bit_width, old_sample_rate);
2697 if (platform_check_codec_backend_cfg(adev, usecase,
2698 &new_bit_width, &new_sample_rate)) {
2699 platform_set_codec_backend_cfg(adev, new_bit_width, new_sample_rate);
Mingming Yin3ee55c62014-08-04 14:23:35 -07002700 return true;
2701 }
2702
2703 return false;
2704}
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07002705
2706int platform_set_snd_device_backend(snd_device_t device, const char *backend)
2707{
2708 int ret = 0;
2709
2710 if ((device < SND_DEVICE_MIN) || (device >= SND_DEVICE_MAX)) {
2711 ALOGE("%s: Invalid snd_device = %d",
2712 __func__, device);
2713 ret = -EINVAL;
2714 goto done;
2715 }
2716
2717 if (backend_table[device]) {
2718 free(backend_table[device]);
2719 }
2720 backend_table[device] = strdup(backend);
2721done:
2722 return ret;
2723}
2724
2725int platform_set_usecase_pcm_id(audio_usecase_t usecase, int32_t type, int32_t pcm_id)
2726{
2727 int ret = 0;
2728 if ((usecase <= USECASE_INVALID) || (usecase >= AUDIO_USECASE_MAX)) {
2729 ALOGE("%s: invalid usecase case idx %d", __func__, usecase);
2730 ret = -EINVAL;
2731 goto done;
2732 }
2733
2734 if ((type != 0) && (type != 1)) {
2735 ALOGE("%s: invalid usecase type", __func__);
2736 ret = -EINVAL;
2737 }
2738 pcm_device_table[usecase][type] = pcm_id;
2739done:
2740 return ret;
2741}