blob: c043264970d554b6992c8241b69a478e52a67b0d [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
Pradnya Chaphekar4403bd72014-09-09 09:50:01 -070023/*#define VERY_VERY_VERBOSE_LOGGING*/
24#ifdef VERY_VERY_VERBOSE_LOGGING
25#define ALOGVV ALOGV
26#else
27#define ALOGVV(a...) do { } while(0)
28#endif
Eric Laurentb23d5282013-05-14 15:27:20 -070029
30#include <stdlib.h>
31#include <dlfcn.h>
Anish Kumar55e6df22014-08-26 17:38:05 -070032#include <fcntl.h>
Vidyakumar Athota21b3bb92014-04-25 11:08:08 -070033#include <sys/ioctl.h>
Eric Laurentb23d5282013-05-14 15:27:20 -070034#include <cutils/log.h>
35#include <cutils/properties.h>
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -070036#include <cutils/str_parms.h>
Eric Laurentb23d5282013-05-14 15:27:20 -070037#include <audio_hw.h>
38#include <platform_api.h>
39#include "platform.h"
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -070040#include "audio_extn.h"
Narsinga Rao Chella05573b72013-11-15 15:21:40 -080041#include "voice_extn.h"
Pradnya Chaphekar4403bd72014-09-09 09:50:01 -070042#include "edid.h"
ApurupaPattapuc6a3a9e2014-01-10 14:46:02 -080043#include "sound/compress_params.h"
Anish Kumar55e6df22014-08-26 17:38:05 -070044#include "sound/msmcal-hwdep.h"
Eric Laurentb23d5282013-05-14 15:27:20 -070045
Anish Kumar55e6df22014-08-26 17:38:05 -070046#define SOUND_TRIGGER_DEVICE_HANDSET_MONO_LOW_POWER_ACDB_ID (100)
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -070047#define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
Damir Didjustof1d46c72013-11-06 17:59:04 -080048#define MIXER_XML_PATH_AUXPCM "/system/etc/mixer_paths_auxpcm.xml"
Helen Zeng6a16ad72014-02-23 22:04:44 -080049#define MIXER_XML_PATH_I2S "/system/etc/mixer_paths_i2s.xml"
50
51#define PLATFORM_INFO_XML_PATH "/system/etc/audio_platform_info.xml"
52#define PLATFORM_INFO_XML_PATH_I2S "/system/etc/audio_platform_info_i2s.xml"
53
Eric Laurentb23d5282013-05-14 15:27:20 -070054#define LIB_ACDB_LOADER "libacdbloader.so"
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -070055#define AUDIO_DATA_BLOCK_MIXER_CTL "HDMI EDID"
Walter Yang6f800052014-07-14 16:15:38 -070056#define CVD_VERSION_MIXER_CTL "CVD Version"
Eric Laurentb23d5282013-05-14 15:27:20 -070057
ApurupaPattapuc6a3a9e2014-01-10 14:46:02 -080058#define MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE (256 * 1024)
59#define MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE (2 * 1024)
60#define COMPRESS_OFFLOAD_FRAGMENT_SIZE_FOR_AV_STREAMING (2 * 1024)
61#define COMPRESS_OFFLOAD_FRAGMENT_SIZE (32 * 1024)
62
63/* Used in calculating fragment size for pcm offload */
ApurupaPattapub57da782014-04-08 10:41:07 -070064#define PCM_OFFLOAD_BUFFER_DURATION_FOR_AV 1000 /* 1 sec */
65#define PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING 80 /* 80 millisecs */
ApurupaPattapuc6a3a9e2014-01-10 14:46:02 -080066
67/* MAX PCM fragment size cannot be increased further due
68 * to flinger's cblk size of 1mb,and it has to be a multiple of
69 * 24 - lcm of channels supported by DSP
70 */
71#define MAX_PCM_OFFLOAD_FRAGMENT_SIZE (240 * 1024)
ApurupaPattapub57da782014-04-08 10:41:07 -070072#define MIN_PCM_OFFLOAD_FRAGMENT_SIZE (4 * 1024)
ApurupaPattapuc6a3a9e2014-01-10 14:46:02 -080073
74#define ALIGN( num, to ) (((num) + (to-1)) & (~(to-1)))
Eric Laurentb23d5282013-05-14 15:27:20 -070075/*
Eric Laurentb23d5282013-05-14 15:27:20 -070076 * This file will have a maximum of 38 bytes:
77 *
78 * 4 bytes: number of audio blocks
79 * 4 bytes: total length of Short Audio Descriptor (SAD) blocks
80 * Maximum 10 * 3 bytes: SAD blocks
81 */
82#define MAX_SAD_BLOCKS 10
83#define SAD_BLOCK_SIZE 3
84
Walter Yang6f800052014-07-14 16:15:38 -070085#define MAX_CVD_VERSION_STRING_SIZE 100
86
Eric Laurentb23d5282013-05-14 15:27:20 -070087/* EDID format ID for LPCM audio */
88#define EDID_FORMAT_LPCM 1
89
Subhash Chandra Bose Naripeddy54274672014-03-10 14:51:02 -070090/* fallback app type if the default app type from acdb loader fails */
91#define DEFAULT_APP_TYPE 0x11130
92
sangwoo1b9f4b32013-06-21 18:22:55 -070093/* Retry for delay in FW loading*/
94#define RETRY_NUMBER 10
95#define RETRY_US 500000
Apoorv Raghuvanshi84fa2fe2013-12-04 11:57:47 -080096#define MAX_SND_CARD 8
sangwoo1b9f4b32013-06-21 18:22:55 -070097
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -070098#define SAMPLE_RATE_8KHZ 8000
99#define SAMPLE_RATE_16KHZ 16000
100
Ben Rombergera04fabc2014-11-14 12:16:03 -0800101#define MAX_SET_CAL_BYTE_SIZE 65536
102
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700103#define AUDIO_PARAMETER_KEY_FLUENCE_TYPE "fluence"
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700104#define AUDIO_PARAMETER_KEY_SLOWTALK "st_enable"
Avinash Vaishd5fa4572014-09-15 14:41:14 +0530105#define AUDIO_PARAMETER_KEY_HD_VOICE "hd_voice"
Ben Rombergerc1dc70d2013-12-19 15:11:17 -0800106#define AUDIO_PARAMETER_KEY_VOLUME_BOOST "volume_boost"
Ben Rombergera04fabc2014-11-14 12:16:03 -0800107#define AUDIO_PARAMETER_KEY_AUD_CALDATA "cal_data"
108#define AUDIO_PARAMETER_KEY_AUD_CALRESULT "cal_result"
109
110
Tanya Finkel00130052014-07-14 04:26:56 -0700111/* Query external audio device connection status */
112#define AUDIO_PARAMETER_KEY_EXT_AUDIO_DEVICE "ext_audio_device"
113
114#define EVENT_EXTERNAL_SPK_1 "qc_ext_spk_1"
115#define EVENT_EXTERNAL_SPK_2 "qc_ext_spk_2"
116#define EVENT_EXTERNAL_MIC "qc_ext_mic"
Anish Kumar55e6df22014-08-26 17:38:05 -0700117#define MAX_CAL_NAME 20
118
119char cal_name_info[WCD9XXX_MAX_CAL][MAX_CAL_NAME] = {
120 [WCD9XXX_ANC_CAL] = "anc_cal",
121 [WCD9XXX_MBHC_CAL] = "mbhc_cal",
122 [WCD9XXX_MAD_CAL] = "mad_cal",
123};
Ben Rombergerc1dc70d2013-12-19 15:11:17 -0800124
125enum {
126 VOICE_FEATURE_SET_DEFAULT,
127 VOICE_FEATURE_SET_VOLUME_BOOST
128};
sangwoo53b2cf02013-07-25 19:18:44 -0700129
Eric Laurentb23d5282013-05-14 15:27:20 -0700130struct audio_block_header
131{
132 int reserved;
133 int length;
134};
135
Ben Rombergera04fabc2014-11-14 12:16:03 -0800136typedef struct acdb_audio_cal_cfg {
137 uint32_t persist;
138 uint32_t snd_dev_id;
139 audio_devices_t dev_id;
140 int32_t acdb_dev_id;
141 uint32_t app_type;
142 uint32_t topo_id;
143 uint32_t sampling_rate;
144 uint32_t cal_type;
145 uint32_t module_id;
146 uint32_t param_id;
147} acdb_audio_cal_cfg_t;
148
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800149/* Audio calibration related functions */
Eric Laurentb23d5282013-05-14 15:27:20 -0700150typedef void (*acdb_deallocate_t)();
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -0700151typedef int (*acdb_init_t)(const char *, char *);
Subhash Chandra Bose Naripeddy54274672014-03-10 14:51:02 -0700152typedef void (*acdb_send_audio_cal_t)(int, int, int , int);
Eric Laurentb23d5282013-05-14 15:27:20 -0700153typedef void (*acdb_send_voice_cal_t)(int, int);
Ben Rombergerc1dc70d2013-12-19 15:11:17 -0800154typedef int (*acdb_reload_vocvoltable_t)(int);
Subhash Chandra Bose Naripeddy54274672014-03-10 14:51:02 -0700155typedef int (*acdb_get_default_app_type_t)(void);
Anish Kumar55e6df22014-08-26 17:38:05 -0700156typedef int (*acdb_loader_get_calibration_t)(char *attr, int size, void *data);
157acdb_loader_get_calibration_t acdb_loader_get_calibration;
Ben Rombergera04fabc2014-11-14 12:16:03 -0800158typedef int (*acdb_set_audio_cal_t) (void *, void *, uint32_t);
159typedef int (*acdb_get_audio_cal_t) (void *, void *, uint32_t*);
Eric Laurentb23d5282013-05-14 15:27:20 -0700160
Eric Laurentb23d5282013-05-14 15:27:20 -0700161struct platform_data {
162 struct audio_device *adev;
163 bool fluence_in_spkr_mode;
164 bool fluence_in_voice_call;
165 bool fluence_in_voice_rec;
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800166 bool fluence_in_audio_rec;
Tanya Finkel00130052014-07-14 04:26:56 -0700167 bool external_spk_1;
168 bool external_spk_2;
169 bool external_mic;
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700170 int fluence_type;
Narsinga Rao Chella61e0f9b2014-03-06 21:25:22 -0800171 int fluence_mode;
Venkata Narendra Kumar Gutta88fd0bc2014-03-27 19:47:56 +0530172 char fluence_cap[PROPERTY_VALUE_MAX];
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700173 bool slowtalk;
Avinash Vaishd5fa4572014-09-15 14:41:14 +0530174 bool hd_voice;
Venkata Narendra Kumar Gutta1bbbf542014-09-04 19:11:25 +0530175 bool ec_ref_enabled;
Helen Zeng6a16ad72014-02-23 22:04:44 -0800176 bool is_i2s_ext_modem;
Ravi Kumar Alamanda48c921d2013-10-29 06:07:44 -0700177 /* Audio calibration related functions */
Ben Rombergerc1dc70d2013-12-19 15:11:17 -0800178 void *acdb_handle;
179 int voice_feature_set;
180 acdb_init_t acdb_init;
181 acdb_deallocate_t acdb_deallocate;
182 acdb_send_audio_cal_t acdb_send_audio_cal;
Ben Rombergera04fabc2014-11-14 12:16:03 -0800183 acdb_set_audio_cal_t acdb_set_audio_cal;
184 acdb_get_audio_cal_t acdb_get_audio_cal;
Ben Rombergerc1dc70d2013-12-19 15:11:17 -0800185 acdb_send_voice_cal_t acdb_send_voice_cal;
186 acdb_reload_vocvoltable_t acdb_reload_vocvoltable;
Subhash Chandra Bose Naripeddy54274672014-03-10 14:51:02 -0700187 acdb_get_default_app_type_t acdb_get_default_app_type;
Ravi Kumar Alamanda48c921d2013-10-29 06:07:44 -0700188
189 void *hw_info;
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800190 struct csd_data *csd;
Pradnya Chaphekar4403bd72014-09-09 09:50:01 -0700191 void *edid_info;
192 bool edid_valid;
Eric Laurentb23d5282013-05-14 15:27:20 -0700193};
194
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700195static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700196 [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {DEEP_BUFFER_PCM_DEVICE,
197 DEEP_BUFFER_PCM_DEVICE},
198 [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
Preetam Singh Ranawatde84f1a2013-11-01 14:58:16 -0700199 LOWLATENCY_PCM_DEVICE},
200 [USECASE_AUDIO_PLAYBACK_MULTI_CH] = {MULTIMEDIA2_PCM_DEVICE,
201 MULTIMEDIA2_PCM_DEVICE},
Krishnankutty Kolathappillya43f96e2013-11-01 12:17:53 -0700202 [USECASE_AUDIO_PLAYBACK_OFFLOAD] =
203 {PLAYBACK_OFFLOAD_DEVICE, PLAYBACK_OFFLOAD_DEVICE},
Subhash Chandra Bose Naripeddy16ff4f82014-04-01 21:03:10 -0700204#ifdef MULTIPLE_OFFLOAD_ENABLED
205 [USECASE_AUDIO_PLAYBACK_OFFLOAD2] =
206 {PLAYBACK_OFFLOAD_DEVICE2, PLAYBACK_OFFLOAD_DEVICE2},
207 [USECASE_AUDIO_PLAYBACK_OFFLOAD3] =
208 {PLAYBACK_OFFLOAD_DEVICE3, PLAYBACK_OFFLOAD_DEVICE3},
209 [USECASE_AUDIO_PLAYBACK_OFFLOAD4] =
210 {PLAYBACK_OFFLOAD_DEVICE4, PLAYBACK_OFFLOAD_DEVICE4},
211 [USECASE_AUDIO_PLAYBACK_OFFLOAD5] =
212 {PLAYBACK_OFFLOAD_DEVICE5, PLAYBACK_OFFLOAD_DEVICE5},
213 [USECASE_AUDIO_PLAYBACK_OFFLOAD6] =
214 {PLAYBACK_OFFLOAD_DEVICE6, PLAYBACK_OFFLOAD_DEVICE6},
215 [USECASE_AUDIO_PLAYBACK_OFFLOAD7] =
216 {PLAYBACK_OFFLOAD_DEVICE7, PLAYBACK_OFFLOAD_DEVICE7},
217 [USECASE_AUDIO_PLAYBACK_OFFLOAD8] =
218 {PLAYBACK_OFFLOAD_DEVICE8, PLAYBACK_OFFLOAD_DEVICE8},
219 [USECASE_AUDIO_PLAYBACK_OFFLOAD9] =
220 {PLAYBACK_OFFLOAD_DEVICE9, PLAYBACK_OFFLOAD_DEVICE9},
221#endif
Shiv Maliyappanahallida107642013-10-17 11:16:13 -0700222 [USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE, AUDIO_RECORD_PCM_DEVICE},
Mingming Yine62d7842013-10-25 16:26:03 -0700223 [USECASE_AUDIO_RECORD_COMPRESS] = {COMPRESS_CAPTURE_DEVICE, COMPRESS_CAPTURE_DEVICE},
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700224 [USECASE_AUDIO_RECORD_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
225 LOWLATENCY_PCM_DEVICE},
Preetam Singh Ranawatde84f1a2013-11-01 14:58:16 -0700226 [USECASE_AUDIO_RECORD_FM_VIRTUAL] = {MULTIMEDIA2_PCM_DEVICE,
227 MULTIMEDIA2_PCM_DEVICE},
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -0700228 [USECASE_AUDIO_PLAYBACK_FM] = {FM_PLAYBACK_PCM_DEVICE, FM_CAPTURE_PCM_DEVICE},
Vimal Puthanveed5b4d3f12013-11-05 15:57:39 -0800229 [USECASE_AUDIO_HFP_SCO] = {HFP_PCM_RX, HFP_SCO_RX},
Vimal Puthanveed47e64852013-12-20 13:23:39 -0800230 [USECASE_AUDIO_HFP_SCO_WB] = {HFP_PCM_RX, HFP_SCO_RX},
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700231 [USECASE_VOICE_CALL] = {VOICE_CALL_PCM_DEVICE, VOICE_CALL_PCM_DEVICE},
232 [USECASE_VOICE2_CALL] = {VOICE2_CALL_PCM_DEVICE, VOICE2_CALL_PCM_DEVICE},
233 [USECASE_VOLTE_CALL] = {VOLTE_CALL_PCM_DEVICE, VOLTE_CALL_PCM_DEVICE},
234 [USECASE_QCHAT_CALL] = {QCHAT_CALL_PCM_DEVICE, QCHAT_CALL_PCM_DEVICE},
Vicky Sehrawat7e4fc152014-02-12 17:58:59 -0800235 [USECASE_VOWLAN_CALL] = {VOWLAN_CALL_PCM_DEVICE, VOWLAN_CALL_PCM_DEVICE},
Narsinga Rao Chella05573b72013-11-15 15:21:40 -0800236 [USECASE_COMPRESS_VOIP_CALL] = {COMPRESS_VOIP_CALL_PCM_DEVICE, COMPRESS_VOIP_CALL_PCM_DEVICE},
Shiv Maliyappanahallida107642013-10-17 11:16:13 -0700237 [USECASE_INCALL_REC_UPLINK] = {AUDIO_RECORD_PCM_DEVICE,
238 AUDIO_RECORD_PCM_DEVICE},
239 [USECASE_INCALL_REC_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
240 AUDIO_RECORD_PCM_DEVICE},
241 [USECASE_INCALL_REC_UPLINK_AND_DOWNLINK] = {AUDIO_RECORD_PCM_DEVICE,
242 AUDIO_RECORD_PCM_DEVICE},
Helen Zenge56b4852013-12-03 16:54:40 -0800243 [USECASE_INCALL_REC_UPLINK_COMPRESS] = {COMPRESS_CAPTURE_DEVICE,
244 COMPRESS_CAPTURE_DEVICE},
245 [USECASE_INCALL_REC_DOWNLINK_COMPRESS] = {COMPRESS_CAPTURE_DEVICE,
246 COMPRESS_CAPTURE_DEVICE},
247 [USECASE_INCALL_REC_UPLINK_AND_DOWNLINK_COMPRESS] = {COMPRESS_CAPTURE_DEVICE,
248 COMPRESS_CAPTURE_DEVICE},
Shiv Maliyappanahallif3b9a422013-10-22 16:38:08 -0700249 [USECASE_INCALL_MUSIC_UPLINK] = {INCALL_MUSIC_UPLINK_PCM_DEVICE,
250 INCALL_MUSIC_UPLINK_PCM_DEVICE},
251 [USECASE_INCALL_MUSIC_UPLINK2] = {INCALL_MUSIC_UPLINK2_PCM_DEVICE,
252 INCALL_MUSIC_UPLINK2_PCM_DEVICE},
Gopikrishnaiah Anandanf538cef2013-10-28 14:06:03 -0700253 [USECASE_AUDIO_SPKR_CALIB_RX] = {SPKR_PROT_CALIB_RX_PCM_DEVICE, -1},
254 [USECASE_AUDIO_SPKR_CALIB_TX] = {-1, SPKR_PROT_CALIB_TX_PCM_DEVICE},
Ravi Kumar Alamanda060bc5a2014-09-05 13:51:35 -0700255
256 [USECASE_AUDIO_PLAYBACK_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
257 AFE_PROXY_RECORD_PCM_DEVICE},
258 [USECASE_AUDIO_RECORD_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
259 AFE_PROXY_RECORD_PCM_DEVICE},
260
Eric Laurentb23d5282013-05-14 15:27:20 -0700261};
262
263/* Array to store sound devices */
264static const char * const device_table[SND_DEVICE_MAX] = {
265 [SND_DEVICE_NONE] = "none",
266 /* Playback sound devices */
267 [SND_DEVICE_OUT_HANDSET] = "handset",
268 [SND_DEVICE_OUT_SPEAKER] = "speaker",
Tanya Finkel00130052014-07-14 04:26:56 -0700269 [SND_DEVICE_OUT_SPEAKER_EXTERNAL_1] = "speaker-ext-1",
270 [SND_DEVICE_OUT_SPEAKER_EXTERNAL_2] = "speaker-ext-2",
Eric Laurentb23d5282013-05-14 15:27:20 -0700271 [SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
272 [SND_DEVICE_OUT_HEADPHONES] = "headphones",
273 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
Tanya Finkel00130052014-07-14 04:26:56 -0700274 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1] = "speaker-and-headphones-ext-1",
275 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2] = "speaker-and-headphones-ext-2",
Eric Laurentb23d5282013-05-14 15:27:20 -0700276 [SND_DEVICE_OUT_VOICE_HANDSET] = "voice-handset",
277 [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
278 [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
279 [SND_DEVICE_OUT_HDMI] = "hdmi",
280 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
281 [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700282 [SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
Eric Laurentb23d5282013-05-14 15:27:20 -0700283 [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
284 [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
285 [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
Ravi Kumar Alamanda060bc5a2014-09-05 13:51:35 -0700286 [SND_DEVICE_OUT_VOICE_TX] = "voice-tx",
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -0700287 [SND_DEVICE_OUT_AFE_PROXY] = "afe-proxy",
288 [SND_DEVICE_OUT_USB_HEADSET] = "usb-headphones",
289 [SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = "speaker-and-usb-headphones",
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -0700290 [SND_DEVICE_OUT_TRANSMISSION_FM] = "transmission-fm",
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -0700291 [SND_DEVICE_OUT_ANC_HEADSET] = "anc-headphones",
292 [SND_DEVICE_OUT_ANC_FB_HEADSET] = "anc-fb-headphones",
293 [SND_DEVICE_OUT_VOICE_ANC_HEADSET] = "voice-anc-headphones",
294 [SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET] = "voice-anc-fb-headphones",
295 [SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET] = "speaker-and-anc-headphones",
296 [SND_DEVICE_OUT_ANC_HANDSET] = "anc-handset",
Gopikrishnaiah Anandanf538cef2013-10-28 14:06:03 -0700297 [SND_DEVICE_OUT_SPEAKER_PROTECTED] = "speaker-protected",
Anish Kumar46c7b872014-09-09 01:49:44 -0700298 [SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = "voice-speaker-protected",
Eric Laurentb23d5282013-05-14 15:27:20 -0700299
300 /* Capture sound devices */
301 [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
Tanya Finkel00130052014-07-14 04:26:56 -0700302 [SND_DEVICE_IN_HANDSET_MIC_EXTERNAL] = "handset-mic-ext",
Eric Laurentb23d5282013-05-14 15:27:20 -0700303 [SND_DEVICE_IN_HANDSET_MIC_AEC] = "handset-mic",
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800304 [SND_DEVICE_IN_HANDSET_MIC_NS] = "handset-mic",
305 [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = "handset-mic",
306 [SND_DEVICE_IN_HANDSET_DMIC] = "dmic-endfire",
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800307 [SND_DEVICE_IN_HANDSET_DMIC_AEC] = "dmic-endfire",
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800308 [SND_DEVICE_IN_HANDSET_DMIC_NS] = "dmic-endfire",
309 [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = "dmic-endfire",
310 [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800311 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "speaker-mic",
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800312 [SND_DEVICE_IN_SPEAKER_MIC_NS] = "speaker-mic",
313 [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = "speaker-mic",
314 [SND_DEVICE_IN_SPEAKER_DMIC] = "speaker-dmic-endfire",
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800315 [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = "speaker-dmic-endfire",
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800316 [SND_DEVICE_IN_SPEAKER_DMIC_NS] = "speaker-dmic-endfire",
317 [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = "speaker-dmic-endfire",
318 [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
319 [SND_DEVICE_IN_HEADSET_MIC_FLUENCE] = "headset-mic",
Eric Laurentb23d5282013-05-14 15:27:20 -0700320 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
321 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
322 [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
323 [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
Vicky Sehrawate240e5d2014-08-12 17:17:04 -0700324 [SND_DEVICE_IN_BT_SCO_MIC_NREC] = "bt-sco-mic",
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700325 [SND_DEVICE_IN_BT_SCO_MIC_WB] = "bt-sco-mic-wb",
Vicky Sehrawate240e5d2014-08-12 17:17:04 -0700326 [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = "bt-sco-mic-wb",
Eric Laurentb23d5282013-05-14 15:27:20 -0700327 [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700328 [SND_DEVICE_IN_VOICE_DMIC] = "voice-dmic-ef",
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700329 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = "voice-speaker-dmic-ef",
Vidyakumar Athotaadfe4e32013-12-13 14:51:26 -0800330 [SND_DEVICE_IN_VOICE_SPEAKER_QMIC] = "voice-speaker-qmic",
Eric Laurentb23d5282013-05-14 15:27:20 -0700331 [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = "voice-tty-full-headset-mic",
332 [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = "voice-tty-vco-handset-mic",
333 [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = "voice-tty-hco-headset-mic",
Ravi Kumar Alamanda060bc5a2014-09-05 13:51:35 -0700334 [SND_DEVICE_IN_VOICE_RX] = "voice-rx",
335
Eric Laurentb23d5282013-05-14 15:27:20 -0700336 [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800337 [SND_DEVICE_IN_VOICE_REC_MIC_NS] = "voice-rec-mic",
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800338 [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = "voice-rec-dmic-ef",
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700339 [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = "voice-rec-dmic-ef-fluence",
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -0700340 [SND_DEVICE_IN_USB_HEADSET_MIC] = "usb-headset-mic",
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -0700341 [SND_DEVICE_IN_CAPTURE_FM] = "capture-fm",
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -0700342 [SND_DEVICE_IN_AANC_HANDSET_MIC] = "aanc-handset-mic",
Apoorv Raghuvanshi6178a3f2013-10-19 12:38:54 -0700343 [SND_DEVICE_IN_QUAD_MIC] = "quad-mic",
Apoorv Raghuvanshi6bd8dbf2013-10-19 18:37:52 -0700344 [SND_DEVICE_IN_HANDSET_STEREO_DMIC] = "handset-stereo-dmic-ef",
345 [SND_DEVICE_IN_SPEAKER_STEREO_DMIC] = "speaker-stereo-dmic-ef",
Gopikrishnaiah Anandanf538cef2013-10-28 14:06:03 -0700346 [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = "vi-feedback",
Narsinga Rao Chella61e0f9b2014-03-06 21:25:22 -0800347 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BROADSIDE] = "voice-speaker-dmic-broadside",
348 [SND_DEVICE_IN_SPEAKER_DMIC_BROADSIDE] = "speaker-dmic-broadside",
349 [SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE] = "speaker-dmic-broadside",
350 [SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE] = "speaker-dmic-broadside",
351 [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE] = "speaker-dmic-broadside",
Narsinga Rao Chella975572e2014-10-21 11:49:00 -0700352 [SND_DEVICE_IN_HANDSET_QMIC] = "quad-mic",
353 [SND_DEVICE_IN_SPEAKER_QMIC_AEC] = "quad-mic",
354 [SND_DEVICE_IN_SPEAKER_QMIC_NS] = "quad-mic",
355 [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = "quad-mic",
Eric Laurentb23d5282013-05-14 15:27:20 -0700356};
357
Amit Shekhar5a39c912014-10-14 15:39:30 -0700358// Platform specific backend bit width table
359static int backend_bit_width_table[SND_DEVICE_MAX] = {0};
360
Eric Laurentb23d5282013-05-14 15:27:20 -0700361/* ACDB IDs (audio DSP path configuration IDs) for each sound device */
Ben Romberger55886882014-01-10 13:49:02 -0800362static int acdb_device_table[SND_DEVICE_MAX] = {
Eric Laurentb23d5282013-05-14 15:27:20 -0700363 [SND_DEVICE_NONE] = -1,
364 [SND_DEVICE_OUT_HANDSET] = 7,
Vidyakumar Athotac29d4ab2013-11-14 16:58:02 -0800365 [SND_DEVICE_OUT_SPEAKER] = 14,
Tanya Finkel00130052014-07-14 04:26:56 -0700366 [SND_DEVICE_OUT_SPEAKER_EXTERNAL_1] = 14,
367 [SND_DEVICE_OUT_SPEAKER_EXTERNAL_2] = 14,
Vidyakumar Athotac29d4ab2013-11-14 16:58:02 -0800368 [SND_DEVICE_OUT_SPEAKER_REVERSE] = 14,
Eric Laurentb23d5282013-05-14 15:27:20 -0700369 [SND_DEVICE_OUT_HEADPHONES] = 10,
370 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
Tanya Finkel00130052014-07-14 04:26:56 -0700371 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1] = 10,
372 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2] = 10,
Eric Laurentb23d5282013-05-14 15:27:20 -0700373 [SND_DEVICE_OUT_VOICE_HANDSET] = 7,
Vidyakumar Athotac29d4ab2013-11-14 16:58:02 -0800374 [SND_DEVICE_OUT_VOICE_SPEAKER] = 14,
Eric Laurentb23d5282013-05-14 15:27:20 -0700375 [SND_DEVICE_OUT_VOICE_HEADPHONES] = 10,
376 [SND_DEVICE_OUT_HDMI] = 18,
Vidyakumar Athotac29d4ab2013-11-14 16:58:02 -0800377 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 14,
Eric Laurentb23d5282013-05-14 15:27:20 -0700378 [SND_DEVICE_OUT_BT_SCO] = 22,
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700379 [SND_DEVICE_OUT_BT_SCO_WB] = 39,
Eric Laurentb23d5282013-05-14 15:27:20 -0700380 [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
381 [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
382 [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
Ravi Kumar Alamanda060bc5a2014-09-05 13:51:35 -0700383 [SND_DEVICE_OUT_VOICE_TX] = 45,
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -0700384 [SND_DEVICE_OUT_AFE_PROXY] = 0,
Vidyakumar Athotab9522202014-01-14 20:08:27 -0800385 [SND_DEVICE_OUT_USB_HEADSET] = 45,
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -0700386 [SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] = 14,
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -0700387 [SND_DEVICE_OUT_TRANSMISSION_FM] = 0,
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -0700388 [SND_DEVICE_OUT_ANC_HEADSET] = 26,
Ravi Kumar Alamanda48c921d2013-10-29 06:07:44 -0700389 [SND_DEVICE_OUT_ANC_FB_HEADSET] = 27,
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -0700390 [SND_DEVICE_OUT_VOICE_ANC_HEADSET] = 26,
Ravi Kumar Alamanda48c921d2013-10-29 06:07:44 -0700391 [SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET] = 27,
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -0700392 [SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET] = 26,
393 [SND_DEVICE_OUT_ANC_HANDSET] = 103,
Anish Kumar46c7b872014-09-09 01:49:44 -0700394 [SND_DEVICE_OUT_SPEAKER_PROTECTED] = 124,
395 [SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED] = 101,
Eric Laurentb23d5282013-05-14 15:27:20 -0700396
397 [SND_DEVICE_IN_HANDSET_MIC] = 4,
Tanya Finkel00130052014-07-14 04:26:56 -0700398 [SND_DEVICE_IN_HANDSET_MIC_EXTERNAL] = 4,
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800399 [SND_DEVICE_IN_HANDSET_MIC_AEC] = 106,
400 [SND_DEVICE_IN_HANDSET_MIC_NS] = 107,
401 [SND_DEVICE_IN_HANDSET_MIC_AEC_NS] = 108,
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800402 [SND_DEVICE_IN_HANDSET_DMIC] = 41,
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800403 [SND_DEVICE_IN_HANDSET_DMIC_AEC] = 109,
404 [SND_DEVICE_IN_HANDSET_DMIC_NS] = 110,
405 [SND_DEVICE_IN_HANDSET_DMIC_AEC_NS] = 111,
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800406 [SND_DEVICE_IN_SPEAKER_MIC] = 11,
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800407 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = 112,
408 [SND_DEVICE_IN_SPEAKER_MIC_NS] = 113,
409 [SND_DEVICE_IN_SPEAKER_MIC_AEC_NS] = 114,
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800410 [SND_DEVICE_IN_SPEAKER_DMIC] = 43,
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800411 [SND_DEVICE_IN_SPEAKER_DMIC_AEC] = 115,
412 [SND_DEVICE_IN_SPEAKER_DMIC_NS] = 116,
413 [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS] = 117,
Eric Laurentb23d5282013-05-14 15:27:20 -0700414 [SND_DEVICE_IN_HEADSET_MIC] = 8,
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800415 [SND_DEVICE_IN_HEADSET_MIC_FLUENCE] = 47,
Eric Laurentb23d5282013-05-14 15:27:20 -0700416 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = 11,
417 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = 8,
418 [SND_DEVICE_IN_HDMI_MIC] = 4,
419 [SND_DEVICE_IN_BT_SCO_MIC] = 21,
Vicky Sehrawate240e5d2014-08-12 17:17:04 -0700420 [SND_DEVICE_IN_BT_SCO_MIC_NREC] = 122,
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -0700421 [SND_DEVICE_IN_BT_SCO_MIC_WB] = 38,
Vicky Sehrawate240e5d2014-08-12 17:17:04 -0700422 [SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = 123,
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800423 [SND_DEVICE_IN_CAMCORDER_MIC] = 4,
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700424 [SND_DEVICE_IN_VOICE_DMIC] = 41,
Mingming Yin8e5a4f62013-10-07 15:23:41 -0700425 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC] = 43,
Vidyakumar Athotaadfe4e32013-12-13 14:51:26 -0800426 [SND_DEVICE_IN_VOICE_SPEAKER_QMIC] = 19,
Eric Laurentb23d5282013-05-14 15:27:20 -0700427 [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = 16,
428 [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = 36,
429 [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = 16,
Ravi Kumar Alamanda060bc5a2014-09-05 13:51:35 -0700430 [SND_DEVICE_IN_VOICE_RX] = 44,
431
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800432 [SND_DEVICE_IN_VOICE_REC_MIC] = 4,
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -0800433 [SND_DEVICE_IN_VOICE_REC_MIC_NS] = 107,
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -0800434 [SND_DEVICE_IN_VOICE_REC_DMIC_STEREO] = 34,
435 [SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE] = 41,
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -0700436 [SND_DEVICE_IN_USB_HEADSET_MIC] = 44,
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -0700437 [SND_DEVICE_IN_CAPTURE_FM] = 0,
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -0700438 [SND_DEVICE_IN_AANC_HANDSET_MIC] = 104,
Apoorv Raghuvanshi6178a3f2013-10-19 12:38:54 -0700439 [SND_DEVICE_IN_QUAD_MIC] = 46,
Apoorv Raghuvanshi6bd8dbf2013-10-19 18:37:52 -0700440 [SND_DEVICE_IN_HANDSET_STEREO_DMIC] = 34,
441 [SND_DEVICE_IN_SPEAKER_STEREO_DMIC] = 35,
Gopikrishnaiah Anandanf538cef2013-10-28 14:06:03 -0700442 [SND_DEVICE_IN_CAPTURE_VI_FEEDBACK] = 102,
Narsinga Rao Chella61e0f9b2014-03-06 21:25:22 -0800443 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BROADSIDE] = 12,
444 [SND_DEVICE_IN_SPEAKER_DMIC_BROADSIDE] = 12,
445 [SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE] = 119,
446 [SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE] = 121,
447 [SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE] = 120,
Narsinga Rao Chella975572e2014-10-21 11:49:00 -0700448 [SND_DEVICE_IN_HANDSET_QMIC] = 125,
449 [SND_DEVICE_IN_SPEAKER_QMIC_AEC] = 126,
450 [SND_DEVICE_IN_SPEAKER_QMIC_NS] = 127,
451 [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = 129,
Eric Laurentb23d5282013-05-14 15:27:20 -0700452};
453
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700454struct name_to_index {
Ben Romberger61764e32014-01-10 13:49:02 -0800455 char name[100];
456 unsigned int index;
457};
458
459#define TO_NAME_INDEX(X) #X, X
460
461/* Used to get index from parsed sting */
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700462static struct name_to_index snd_device_name_index[SND_DEVICE_MAX] = {
Ben Romberger61764e32014-01-10 13:49:02 -0800463 {TO_NAME_INDEX(SND_DEVICE_OUT_HANDSET)},
464 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER)},
Tanya Finkel00130052014-07-14 04:26:56 -0700465 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_EXTERNAL_1)},
466 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_EXTERNAL_2)},
Ben Romberger61764e32014-01-10 13:49:02 -0800467 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_REVERSE)},
468 {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)},
469 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)},
Tanya Finkel00130052014-07-14 04:26:56 -0700470 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1)},
471 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2)},
Ben Romberger61764e32014-01-10 13:49:02 -0800472 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET)},
473 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER)},
474 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HEADPHONES)},
475 {TO_NAME_INDEX(SND_DEVICE_OUT_HDMI)},
476 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HDMI)},
477 {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO)},
478 {TO_NAME_INDEX(SND_DEVICE_OUT_BT_SCO_WB)},
479 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES)},
480 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES)},
481 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET)},
482 {TO_NAME_INDEX(SND_DEVICE_OUT_AFE_PROXY)},
483 {TO_NAME_INDEX(SND_DEVICE_OUT_USB_HEADSET)},
484 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET)},
485 {TO_NAME_INDEX(SND_DEVICE_OUT_TRANSMISSION_FM)},
486 {TO_NAME_INDEX(SND_DEVICE_OUT_ANC_HEADSET)},
487 {TO_NAME_INDEX(SND_DEVICE_OUT_ANC_FB_HEADSET)},
488 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_ANC_HEADSET)},
489 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET)},
490 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET)},
491 {TO_NAME_INDEX(SND_DEVICE_OUT_ANC_HANDSET)},
492 {TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_PROTECTED)},
Anish Kumar46c7b872014-09-09 01:49:44 -0700493 {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED)},
Ben Romberger61764e32014-01-10 13:49:02 -0800494 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC)},
Tanya Finkel00130052014-07-14 04:26:56 -0700495 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_EXTERNAL)},
Ben Romberger61764e32014-01-10 13:49:02 -0800496 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC)},
497 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_NS)},
498 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC_NS)},
499 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC)},
500 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC)},
501 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_NS)},
502 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_DMIC_AEC_NS)},
503 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC)},
504 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC)},
505 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_NS)},
506 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_MIC_AEC_NS)},
507 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC)},
508 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC)},
509 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_NS)},
510 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS)},
511 {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC)},
512 {TO_NAME_INDEX(SND_DEVICE_IN_HEADSET_MIC_FLUENCE)},
513 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_MIC)},
514 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_HEADSET_MIC)},
515 {TO_NAME_INDEX(SND_DEVICE_IN_HDMI_MIC)},
516 {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC)},
Vicky Sehrawate240e5d2014-08-12 17:17:04 -0700517 {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_NREC)},
Ben Romberger61764e32014-01-10 13:49:02 -0800518 {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB)},
Vicky Sehrawate240e5d2014-08-12 17:17:04 -0700519 {TO_NAME_INDEX(SND_DEVICE_IN_BT_SCO_MIC_WB_NREC)},
Ben Romberger61764e32014-01-10 13:49:02 -0800520 {TO_NAME_INDEX(SND_DEVICE_IN_CAMCORDER_MIC)},
521 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_DMIC)},
522 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_DMIC)},
523 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_QMIC)},
524 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC)},
525 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC)},
526 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC)},
527 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC)},
528 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_MIC_NS)},
529 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_STEREO)},
530 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE)},
531 {TO_NAME_INDEX(SND_DEVICE_IN_USB_HEADSET_MIC)},
532 {TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_FM)},
533 {TO_NAME_INDEX(SND_DEVICE_IN_AANC_HANDSET_MIC)},
534 {TO_NAME_INDEX(SND_DEVICE_IN_QUAD_MIC)},
535 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_STEREO_DMIC)},
536 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_STEREO_DMIC)},
537 {TO_NAME_INDEX(SND_DEVICE_IN_CAPTURE_VI_FEEDBACK)},
Narsinga Rao Chella61e0f9b2014-03-06 21:25:22 -0800538 {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BROADSIDE)},
539 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_BROADSIDE)},
540 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE)},
541 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE)},
542 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE)},
Narsinga Rao Chella975572e2014-10-21 11:49:00 -0700543 {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_QMIC)},
544 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC)},
545 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_NS)},
546 {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)},
Ben Romberger61764e32014-01-10 13:49:02 -0800547};
548
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700549static char * backend_table[SND_DEVICE_MAX] = {0};
550
551static struct name_to_index usecase_name_index[AUDIO_USECASE_MAX] = {
552 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_DEEP_BUFFER)},
553 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_LOW_LATENCY)},
554 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_MULTI_CH)},
555 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD)},
Alexy Joseph2f89cfa2014-10-06 12:15:01 -0700556#ifdef MULTIPLE_OFFLOAD_ENABLED
557 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD2)},
558 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD3)},
559 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD4)},
560 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD5)},
561 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD6)},
562 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD7)},
563 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD8)},
564 {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD9)},
565#endif
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700566 {TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
567 {TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
568 {TO_NAME_INDEX(USECASE_VOICE_CALL)},
569 {TO_NAME_INDEX(USECASE_VOICE2_CALL)},
570 {TO_NAME_INDEX(USECASE_VOLTE_CALL)},
571 {TO_NAME_INDEX(USECASE_QCHAT_CALL)},
572 {TO_NAME_INDEX(USECASE_VOWLAN_CALL)},
573 {TO_NAME_INDEX(USECASE_INCALL_REC_UPLINK)},
574 {TO_NAME_INDEX(USECASE_INCALL_REC_DOWNLINK)},
575 {TO_NAME_INDEX(USECASE_INCALL_REC_UPLINK_AND_DOWNLINK)},
576 {TO_NAME_INDEX(USECASE_AUDIO_HFP_SCO)},
577};
578
Pradnya Chaphekar8a9dcd82014-09-09 09:49:10 -0700579#define NO_COLS 2
580#ifdef PLATFORM_APQ8084
581static int msm_device_to_be_id [][NO_COLS] = {
582 {AUDIO_DEVICE_OUT_EARPIECE , 2},
583 {AUDIO_DEVICE_OUT_SPEAKER , 2},
584 {AUDIO_DEVICE_OUT_WIRED_HEADSET , 2},
585 {AUDIO_DEVICE_OUT_WIRED_HEADPHONE , 2},
586 {AUDIO_DEVICE_OUT_BLUETOOTH_SCO , 11},
587 {AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET , 11},
588 {AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT , 11},
589 {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP , -1},
590 {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES , -1},
591 {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER , -1},
592 {AUDIO_DEVICE_OUT_AUX_DIGITAL , 4},
593 {AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET , 9},
594 {AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET , 9},
595 {AUDIO_DEVICE_OUT_USB_ACCESSORY , -1},
596 {AUDIO_DEVICE_OUT_USB_DEVICE , -1},
597 {AUDIO_DEVICE_OUT_REMOTE_SUBMIX , 9},
598 {AUDIO_DEVICE_OUT_PROXY , 9},
599 {AUDIO_DEVICE_OUT_FM , 7},
600 {AUDIO_DEVICE_OUT_FM_TX , 8},
601 {AUDIO_DEVICE_OUT_ALL , -1},
602 {AUDIO_DEVICE_NONE , -1},
603 {AUDIO_DEVICE_OUT_DEFAULT , -1},
604};
605#elif PLATFORM_MSM8994
606static int msm_device_to_be_id [][NO_COLS] = {
607 {AUDIO_DEVICE_OUT_EARPIECE , 2},
608 {AUDIO_DEVICE_OUT_SPEAKER , 2},
609 {AUDIO_DEVICE_OUT_WIRED_HEADSET , 2},
610 {AUDIO_DEVICE_OUT_WIRED_HEADPHONE , 2},
611 {AUDIO_DEVICE_OUT_BLUETOOTH_SCO , 38},
612 {AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET , 38},
613 {AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT , 38},
614 {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP , -1},
615 {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES , -1},
616 {AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER , -1},
617 {AUDIO_DEVICE_OUT_AUX_DIGITAL , 4},
618 {AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET , 9},
619 {AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET , 9},
620 {AUDIO_DEVICE_OUT_USB_ACCESSORY , -1},
621 {AUDIO_DEVICE_OUT_USB_DEVICE , -1},
622 {AUDIO_DEVICE_OUT_REMOTE_SUBMIX , 9},
623 {AUDIO_DEVICE_OUT_PROXY , 9},
624/* Add the correct be ids */
625 {AUDIO_DEVICE_OUT_FM , 7},
626 {AUDIO_DEVICE_OUT_FM_TX , 8},
627 {AUDIO_DEVICE_OUT_ALL , -1},
628 {AUDIO_DEVICE_NONE , -1},
629 {AUDIO_DEVICE_OUT_DEFAULT , -1},
630};
631#else
632static int msm_device_to_be_id [][NO_COLS] = {
633 {AUDIO_DEVICE_NONE, -1},
634};
635#endif
636static int msm_be_id_array_len =
637 sizeof(msm_device_to_be_id) / sizeof(msm_device_to_be_id[0]);
638
639
Haynes Mathew George7ff216f2013-09-11 19:51:41 -0700640#define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
641#define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
642
Venkata Narendra Kumar Gutta1bbbf542014-09-04 19:11:25 +0530643void platform_set_echo_reference(void *platform, bool enable)
Eric Laurentb23d5282013-05-14 15:27:20 -0700644{
Venkata Narendra Kumar Gutta1bbbf542014-09-04 19:11:25 +0530645 struct platform_data *my_data = (struct platform_data *)platform;
646 struct audio_device *adev = my_data->adev;
647
Ravi Kumar Alamandad1c85bb2014-11-17 18:36:24 -0800648 if (my_data->ec_ref_enabled) {
649 my_data->ec_ref_enabled = false;
650 ALOGV("%s: disabling echo-reference", __func__);
651 audio_route_reset_and_update_path(adev->audio_route, "echo-reference");
Venkata Narendra Kumar Gutta1bbbf542014-09-04 19:11:25 +0530652 }
Eric Laurentb23d5282013-05-14 15:27:20 -0700653
Ravi Kumar Alamandad1c85bb2014-11-17 18:36:24 -0800654 if (enable) {
655 my_data->ec_ref_enabled = true;
656 ALOGD("%s: enabling echo-reference", __func__);
657 audio_route_apply_and_update_path(adev->audio_route, "echo-reference");
658 }
659
Eric Laurentb23d5282013-05-14 15:27:20 -0700660}
661
Helen Zeng6a16ad72014-02-23 22:04:44 -0800662static struct csd_data *open_csd_client(bool i2s_ext_modem)
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800663{
664 struct csd_data *csd = calloc(1, sizeof(struct csd_data));
665
Haynes Mathew Georgeb51ceb12014-06-30 13:56:18 -0700666 if (!csd) {
667 ALOGE("failed to allocate csd_data mem");
668 return NULL;
669 }
670
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800671 csd->csd_client = dlopen(LIB_CSD_CLIENT, RTLD_NOW);
672 if (csd->csd_client == NULL) {
673 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_CSD_CLIENT);
674 goto error;
675 } else {
676 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_CSD_CLIENT);
677
678 csd->deinit = (deinit_t)dlsym(csd->csd_client,
679 "csd_client_deinit");
680 if (csd->deinit == NULL) {
681 ALOGE("%s: dlsym error %s for csd_client_deinit", __func__,
682 dlerror());
683 goto error;
684 }
685 csd->disable_device = (disable_device_t)dlsym(csd->csd_client,
686 "csd_client_disable_device");
687 if (csd->disable_device == NULL) {
688 ALOGE("%s: dlsym error %s for csd_client_disable_device",
689 __func__, dlerror());
690 goto error;
691 }
Vidyakumar Athota545dbd32013-11-13 17:30:53 -0800692 csd->enable_device_config = (enable_device_config_t)dlsym(csd->csd_client,
693 "csd_client_enable_device_config");
694 if (csd->enable_device_config == NULL) {
695 ALOGE("%s: dlsym error %s for csd_client_enable_device_config",
696 __func__, dlerror());
697 goto error;
698 }
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800699 csd->enable_device = (enable_device_t)dlsym(csd->csd_client,
700 "csd_client_enable_device");
701 if (csd->enable_device == NULL) {
702 ALOGE("%s: dlsym error %s for csd_client_enable_device",
703 __func__, dlerror());
704 goto error;
705 }
706 csd->start_voice = (start_voice_t)dlsym(csd->csd_client,
707 "csd_client_start_voice");
708 if (csd->start_voice == NULL) {
709 ALOGE("%s: dlsym error %s for csd_client_start_voice",
710 __func__, dlerror());
711 goto error;
712 }
713 csd->stop_voice = (stop_voice_t)dlsym(csd->csd_client,
714 "csd_client_stop_voice");
715 if (csd->stop_voice == NULL) {
716 ALOGE("%s: dlsym error %s for csd_client_stop_voice",
717 __func__, dlerror());
718 goto error;
719 }
720 csd->volume = (volume_t)dlsym(csd->csd_client,
721 "csd_client_volume");
722 if (csd->volume == NULL) {
723 ALOGE("%s: dlsym error %s for csd_client_volume",
724 __func__, dlerror());
725 goto error;
726 }
727 csd->mic_mute = (mic_mute_t)dlsym(csd->csd_client,
728 "csd_client_mic_mute");
729 if (csd->mic_mute == NULL) {
730 ALOGE("%s: dlsym error %s for csd_client_mic_mute",
731 __func__, dlerror());
732 goto error;
733 }
734 csd->slow_talk = (slow_talk_t)dlsym(csd->csd_client,
735 "csd_client_slow_talk");
736 if (csd->slow_talk == NULL) {
737 ALOGE("%s: dlsym error %s for csd_client_slow_talk",
738 __func__, dlerror());
739 goto error;
740 }
741 csd->start_playback = (start_playback_t)dlsym(csd->csd_client,
742 "csd_client_start_playback");
743 if (csd->start_playback == NULL) {
744 ALOGE("%s: dlsym error %s for csd_client_start_playback",
745 __func__, dlerror());
746 goto error;
747 }
748 csd->stop_playback = (stop_playback_t)dlsym(csd->csd_client,
749 "csd_client_stop_playback");
750 if (csd->stop_playback == NULL) {
751 ALOGE("%s: dlsym error %s for csd_client_stop_playback",
752 __func__, dlerror());
753 goto error;
754 }
Vidyakumar Athota21b3bb92014-04-25 11:08:08 -0700755 csd->set_lch = (set_lch_t)dlsym(csd->csd_client, "csd_client_set_lch");
756 if (csd->set_lch == NULL) {
757 ALOGE("%s: dlsym error %s for csd_client_set_lch",
758 __func__, dlerror());
759 /* Ignore the error as this is not mandatory function for
760 * basic voice call to work.
761 */
762 }
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800763 csd->start_record = (start_record_t)dlsym(csd->csd_client,
764 "csd_client_start_record");
765 if (csd->start_record == NULL) {
766 ALOGE("%s: dlsym error %s for csd_client_start_record",
767 __func__, dlerror());
768 goto error;
769 }
770 csd->stop_record = (stop_record_t)dlsym(csd->csd_client,
771 "csd_client_stop_record");
772 if (csd->stop_record == NULL) {
773 ALOGE("%s: dlsym error %s for csd_client_stop_record",
774 __func__, dlerror());
775 goto error;
776 }
Helen Zeng6a16ad72014-02-23 22:04:44 -0800777
778 csd->get_sample_rate = (get_sample_rate_t)dlsym(csd->csd_client,
779 "csd_client_get_sample_rate");
780 if (csd->get_sample_rate == NULL) {
781 ALOGE("%s: dlsym error %s for csd_client_get_sample_rate",
782 __func__, dlerror());
783
784 goto error;
785 }
786
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800787 csd->init = (init_t)dlsym(csd->csd_client, "csd_client_init");
788
789 if (csd->init == NULL) {
790 ALOGE("%s: dlsym error %s for csd_client_init",
791 __func__, dlerror());
792 goto error;
793 } else {
Helen Zeng6a16ad72014-02-23 22:04:44 -0800794 csd->init(i2s_ext_modem);
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -0800795 }
796 }
797 return csd;
798
799error:
800 free(csd);
801 csd = NULL;
802 return csd;
803}
804
805void close_csd_client(struct csd_data *csd)
806{
807 if (csd != NULL) {
808 csd->deinit();
809 dlclose(csd->csd_client);
810 free(csd);
811 csd = NULL;
812 }
813}
814
Helen Zeng6a16ad72014-02-23 22:04:44 -0800815static bool platform_is_i2s_ext_modem(const char *snd_card_name,
816 struct platform_data *plat_data)
817{
818 plat_data->is_i2s_ext_modem = false;
819
820 if (!strncmp(snd_card_name, "apq8084-taiko-i2s-mtp-snd-card",
821 sizeof("apq8084-taiko-i2s-mtp-snd-card")) ||
822 !strncmp(snd_card_name, "apq8084-taiko-i2s-cdp-snd-card",
823 sizeof("apq8084-taiko-i2s-cdp-snd-card"))) {
824 plat_data->is_i2s_ext_modem = true;
825 }
826 ALOGV("%s, is_i2s_ext_modem:%d",__func__, plat_data->is_i2s_ext_modem);
827
828 return plat_data->is_i2s_ext_modem;
Helen Zeng008aebd2014-02-23 19:13:12 -0800829}
830
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -0700831static void set_platform_defaults()
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700832{
833 int32_t dev;
834 for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
835 backend_table[dev] = NULL;
836 }
Amit Shekhar5a39c912014-10-14 15:39:30 -0700837 for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
838 backend_bit_width_table[dev] = 16;
839 }
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700840
841 // TBD - do these go to the platform-info.xml file.
842 // will help in avoiding strdups here
843 backend_table[SND_DEVICE_IN_BT_SCO_MIC] = strdup("bt-sco");
844 backend_table[SND_DEVICE_IN_BT_SCO_MIC_WB] = strdup("bt-sco-wb");
Vicky Sehrawate240e5d2014-08-12 17:17:04 -0700845 backend_table[SND_DEVICE_IN_BT_SCO_MIC_NREC] = strdup("bt-sco");
846 backend_table[SND_DEVICE_IN_BT_SCO_MIC_WB_NREC] = strdup("bt-sco-wb");
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700847 backend_table[SND_DEVICE_OUT_BT_SCO] = strdup("bt-sco");
848 backend_table[SND_DEVICE_OUT_BT_SCO_WB] = strdup("bt-sco-wb");
849 backend_table[SND_DEVICE_OUT_HDMI] = strdup("hdmi");
850 backend_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("speaker-and-hdmi");
Ravi Kumar Alamanda060bc5a2014-09-05 13:51:35 -0700851 backend_table[SND_DEVICE_OUT_VOICE_TX] = strdup("afe-proxy");
852 backend_table[SND_DEVICE_IN_VOICE_RX] = strdup("afe-proxy");
853
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -0700854 backend_table[SND_DEVICE_OUT_AFE_PROXY] = strdup("afe-proxy");
855 backend_table[SND_DEVICE_OUT_USB_HEADSET] = strdup("usb-headphones");
856 backend_table[SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET] =
857 strdup("speaker-and-usb-headphones");
858 backend_table[SND_DEVICE_IN_USB_HEADSET_MIC] = strdup("usb-headset-mic");
859 backend_table[SND_DEVICE_IN_CAPTURE_FM] = strdup("capture-fm");
860 backend_table[SND_DEVICE_OUT_TRANSMISSION_FM] = strdup("transmission-fm");
861}
862
Walter Yang6f800052014-07-14 16:15:38 -0700863void get_cvd_version(char *cvd_version, struct audio_device *adev)
864{
865 struct mixer_ctl *ctl;
866 int count;
867 int ret = 0;
868
869 ctl = mixer_get_ctl_by_name(adev->mixer, CVD_VERSION_MIXER_CTL);
870 if (!ctl) {
871 ALOGE("%s: Could not get ctl for mixer cmd - %s", __func__, CVD_VERSION_MIXER_CTL);
872 goto done;
873 }
874 mixer_ctl_update(ctl);
875
876 count = mixer_ctl_get_num_values(ctl);
877 if (count > MAX_CVD_VERSION_STRING_SIZE)
878 count = MAX_CVD_VERSION_STRING_SIZE;
879
880 ret = mixer_ctl_get_array(ctl, cvd_version, count);
881 if (ret != 0) {
882 ALOGE("%s: ERROR! mixer_ctl_get_array() failed to get CVD Version", __func__);
883 goto done;
884 }
885
886done:
887 return;
888}
889
Anish Kumar55e6df22014-08-26 17:38:05 -0700890static int hw_util_open(int card_no)
891{
892 int fd = -1;
893 char dev_name[256];
894
895 snprintf(dev_name, sizeof(dev_name), "/dev/snd/hwC%uD%u",
896 card_no, WCD9XXX_CODEC_HWDEP_NODE);
897 ALOGD("%s Opening device %s\n", __func__, dev_name);
898 fd = open(dev_name, O_WRONLY);
899 if (fd < 0) {
900 ALOGE("%s: cannot open device '%s'\n", __func__, dev_name);
901 return fd;
902 }
903 ALOGD("%s success", __func__);
904 return fd;
905}
906
907struct param_data {
908 int use_case;
909 int acdb_id;
910 int get_size;
911 int buff_size;
912 int data_size;
913 void *buff;
914};
915
916static int send_codec_cal(acdb_loader_get_calibration_t acdb_loader_get_calibration, int fd)
917{
918 int ret = 0, type;
919
920 for (type = WCD9XXX_ANC_CAL; type < WCD9XXX_MAX_CAL; type++) {
921 struct wcdcal_ioctl_buffer codec_buffer;
922 struct param_data calib;
923
924 if (!strcmp(cal_name_info[type], "mad_cal"))
925 calib.acdb_id = SOUND_TRIGGER_DEVICE_HANDSET_MONO_LOW_POWER_ACDB_ID;
926 calib.get_size = 1;
927 ret = acdb_loader_get_calibration(cal_name_info[type], sizeof(struct param_data),
928 &calib);
929 if (ret < 0) {
930 ALOGE("%s get_calibration failed\n", __func__);
931 return ret;
932 }
933 calib.get_size = 0;
934 calib.buff = malloc(calib.buff_size);
935 ret = acdb_loader_get_calibration(cal_name_info[type],
936 sizeof(struct param_data), &calib);
937 if (ret < 0) {
938 ALOGE("%s get_calibration failed\n", __func__);
939 free(calib.buff);
940 return ret;
941 }
942 codec_buffer.buffer = calib.buff;
943 codec_buffer.size = calib.data_size;
944 codec_buffer.cal_type = type;
945 if (ioctl(fd, SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE, &codec_buffer) < 0)
946 ALOGE("Failed to call ioctl for %s err=%d",
947 cal_name_info[type], errno);
948 ALOGD("%s cal sent for %s", __func__, cal_name_info[type]);
949 free(calib.buff);
950 }
951 return ret;
952}
953
954static void audio_hwdep_send_cal(struct platform_data *plat_data)
955{
956 int fd;
957
958 fd = hw_util_open(plat_data->adev->snd_card);
959 if (fd == -1) {
960 ALOGE("%s error open\n", __func__);
961 return;
962 }
963
964 acdb_loader_get_calibration = (acdb_loader_get_calibration_t)
965 dlsym(plat_data->acdb_handle, "acdb_loader_get_calibration");
966
967 if (acdb_loader_get_calibration == NULL) {
968 ALOGE("%s: ERROR. dlsym Error:%s acdb_loader_get_calibration", __func__,
969 dlerror());
970 return;
971 }
972 if (send_codec_cal(acdb_loader_get_calibration, fd) < 0)
973 ALOGE("%s: Could not send anc cal", __FUNCTION__);
974}
975
Eric Laurentb23d5282013-05-14 15:27:20 -0700976void *platform_init(struct audio_device *adev)
977{
Vidyakumar Athota77327dd2014-08-07 16:44:25 -0700978 char platform[PROPERTY_VALUE_MAX];
979 char baseband[PROPERTY_VALUE_MAX];
Eric Laurentb23d5282013-05-14 15:27:20 -0700980 char value[PROPERTY_VALUE_MAX];
Apoorv Raghuvanshi84fa2fe2013-12-04 11:57:47 -0800981 struct platform_data *my_data = NULL;
982 int retry_num = 0, snd_card_num = 0;
Ravi Kumar Alamanda48c921d2013-10-29 06:07:44 -0700983 const char *snd_card_name;
Walter Yang6f800052014-07-14 16:15:38 -0700984 char *cvd_version = NULL;
sangwoo1b9f4b32013-06-21 18:22:55 -0700985
Eric Laurentb23d5282013-05-14 15:27:20 -0700986 my_data = calloc(1, sizeof(struct platform_data));
987
Haynes Mathew Georgeb51ceb12014-06-30 13:56:18 -0700988 if (!my_data) {
989 ALOGE("failed to allocate platform data");
990 return NULL;
991 }
992
Apoorv Raghuvanshi84fa2fe2013-12-04 11:57:47 -0800993 while (snd_card_num < MAX_SND_CARD) {
994 adev->mixer = mixer_open(snd_card_num);
995
996 while (!adev->mixer && retry_num < RETRY_NUMBER) {
997 usleep(RETRY_US);
998 adev->mixer = mixer_open(snd_card_num);
999 retry_num++;
1000 }
1001
1002 if (!adev->mixer) {
1003 ALOGE("%s: Unable to open the mixer card: %d", __func__,
1004 snd_card_num);
1005 retry_num = 0;
1006 snd_card_num++;
1007 continue;
1008 }
1009
1010 snd_card_name = mixer_get_name(adev->mixer);
1011 ALOGV("%s: snd_card_name: %s", __func__, snd_card_name);
1012
1013 my_data->hw_info = hw_info_init(snd_card_name);
1014 if (!my_data->hw_info) {
1015 ALOGE("%s: Failed to init hardware info", __func__);
1016 } else {
Helen Zeng6a16ad72014-02-23 22:04:44 -08001017 if (platform_is_i2s_ext_modem(snd_card_name, my_data)) {
1018 ALOGD("%s: Call MIXER_XML_PATH_I2S", __func__);
1019
1020 adev->audio_route = audio_route_init(snd_card_num,
1021 MIXER_XML_PATH_I2S);
1022 } else if (audio_extn_read_xml(adev, snd_card_num, MIXER_XML_PATH,
1023 MIXER_XML_PATH_AUXPCM) == -ENOSYS) {
Apoorv Raghuvanshi84fa2fe2013-12-04 11:57:47 -08001024 adev->audio_route = audio_route_init(snd_card_num,
1025 MIXER_XML_PATH);
Helen Zeng6a16ad72014-02-23 22:04:44 -08001026 }
Apoorv Raghuvanshi84fa2fe2013-12-04 11:57:47 -08001027 if (!adev->audio_route) {
1028 ALOGE("%s: Failed to init audio route controls, aborting.",
1029 __func__);
1030 free(my_data);
1031 return NULL;
1032 }
1033 adev->snd_card = snd_card_num;
1034 ALOGD("%s: Opened sound card:%d", __func__, snd_card_num);
1035 break;
1036 }
1037 retry_num = 0;
1038 snd_card_num++;
1039 }
1040
1041 if (snd_card_num >= MAX_SND_CARD) {
1042 ALOGE("%s: Unable to find correct sound card, aborting.", __func__);
1043 free(my_data);
1044 return NULL;
Ravi Kumar Alamanda48c921d2013-10-29 06:07:44 -07001045 }
1046
Eric Laurentb23d5282013-05-14 15:27:20 -07001047 my_data->adev = adev;
Eric Laurentb23d5282013-05-14 15:27:20 -07001048 my_data->fluence_in_spkr_mode = false;
1049 my_data->fluence_in_voice_call = false;
1050 my_data->fluence_in_voice_rec = false;
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -08001051 my_data->fluence_in_audio_rec = false;
Tanya Finkel00130052014-07-14 04:26:56 -07001052 my_data->external_spk_1 = false;
1053 my_data->external_spk_2 = false;
1054 my_data->external_mic = false;
Mingming Yin8e5a4f62013-10-07 15:23:41 -07001055 my_data->fluence_type = FLUENCE_NONE;
Narsinga Rao Chella61e0f9b2014-03-06 21:25:22 -08001056 my_data->fluence_mode = FLUENCE_ENDFIRE;
Avinash Vaishd5fa4572014-09-15 14:41:14 +05301057 my_data->slowtalk = false;
1058 my_data->hd_voice = false;
Pradnya Chaphekar4403bd72014-09-09 09:50:01 -07001059 my_data->edid_info = NULL;
Eric Laurentb23d5282013-05-14 15:27:20 -07001060
Venkata Narendra Kumar Gutta88fd0bc2014-03-27 19:47:56 +05301061 property_get("ro.qc.sdk.audio.fluencetype", my_data->fluence_cap, "");
1062 if (!strncmp("fluencepro", my_data->fluence_cap, sizeof("fluencepro"))) {
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -08001063 my_data->fluence_type = FLUENCE_QUAD_MIC | FLUENCE_DUAL_MIC;
Venkata Narendra Kumar Gutta88fd0bc2014-03-27 19:47:56 +05301064 } else if (!strncmp("fluence", my_data->fluence_cap, sizeof("fluence"))) {
Mingming Yin8e5a4f62013-10-07 15:23:41 -07001065 my_data->fluence_type = FLUENCE_DUAL_MIC;
1066 } else {
1067 my_data->fluence_type = FLUENCE_NONE;
Eric Laurentb23d5282013-05-14 15:27:20 -07001068 }
1069
Mingming Yin8e5a4f62013-10-07 15:23:41 -07001070 if (my_data->fluence_type != FLUENCE_NONE) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001071 property_get("persist.audio.fluence.voicecall",value,"");
Mingming Yin8e5a4f62013-10-07 15:23:41 -07001072 if (!strncmp("true", value, sizeof("true"))) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001073 my_data->fluence_in_voice_call = true;
1074 }
1075
1076 property_get("persist.audio.fluence.voicerec",value,"");
Mingming Yin8e5a4f62013-10-07 15:23:41 -07001077 if (!strncmp("true", value, sizeof("true"))) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001078 my_data->fluence_in_voice_rec = true;
1079 }
1080
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -08001081 property_get("persist.audio.fluence.audiorec",value,"");
1082 if (!strncmp("true", value, sizeof("true"))) {
1083 my_data->fluence_in_audio_rec = true;
1084 }
1085
Eric Laurentb23d5282013-05-14 15:27:20 -07001086 property_get("persist.audio.fluence.speaker",value,"");
Mingming Yin8e5a4f62013-10-07 15:23:41 -07001087 if (!strncmp("true", value, sizeof("true"))) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001088 my_data->fluence_in_spkr_mode = true;
1089 }
Narsinga Rao Chella61e0f9b2014-03-06 21:25:22 -08001090
1091 property_get("persist.audio.fluence.mode",value,"");
1092 if (!strncmp("broadside", value, sizeof("broadside"))) {
1093 my_data->fluence_mode = FLUENCE_BROADSIDE;
1094 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001095 }
1096
Ben Rombergerc1dc70d2013-12-19 15:11:17 -08001097 my_data->voice_feature_set = VOICE_FEATURE_SET_DEFAULT;
Eric Laurentb23d5282013-05-14 15:27:20 -07001098 my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
1099 if (my_data->acdb_handle == NULL) {
1100 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
1101 } else {
1102 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
1103 my_data->acdb_deallocate = (acdb_deallocate_t)dlsym(my_data->acdb_handle,
1104 "acdb_loader_deallocate_ACDB");
Ben Rombergerc1dc70d2013-12-19 15:11:17 -08001105 if (!my_data->acdb_deallocate)
1106 ALOGE("%s: Could not find the symbol acdb_loader_deallocate_ACDB from %s",
1107 __func__, LIB_ACDB_LOADER);
1108
Eric Laurentb23d5282013-05-14 15:27:20 -07001109 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 -07001110 "acdb_loader_send_audio_cal_v2");
Eric Laurentb23d5282013-05-14 15:27:20 -07001111 if (!my_data->acdb_send_audio_cal)
Ben Rombergerc1dc70d2013-12-19 15:11:17 -08001112 ALOGE("%s: Could not find the symbol acdb_send_audio_cal from %s",
Eric Laurentb23d5282013-05-14 15:27:20 -07001113 __func__, LIB_ACDB_LOADER);
Ben Rombergerc1dc70d2013-12-19 15:11:17 -08001114
Ben Rombergera04fabc2014-11-14 12:16:03 -08001115 my_data->acdb_set_audio_cal = (acdb_set_audio_cal_t)dlsym(my_data->acdb_handle,
1116 "acdb_loader_set_audio_cal_v2");
1117 if (!my_data->acdb_set_audio_cal)
1118 ALOGE("%s: Could not find the symbol acdb_set_audio_cal_v2 from %s",
1119 __func__, LIB_ACDB_LOADER);
1120
1121 my_data->acdb_get_audio_cal = (acdb_get_audio_cal_t)dlsym(my_data->acdb_handle,
1122 "acdb_loader_get_audio_cal_v2");
1123 if (!my_data->acdb_get_audio_cal)
1124 ALOGE("%s: Could not find the symbol acdb_get_audio_cal_v2 from %s",
1125 __func__, LIB_ACDB_LOADER);
1126
Eric Laurentb23d5282013-05-14 15:27:20 -07001127 my_data->acdb_send_voice_cal = (acdb_send_voice_cal_t)dlsym(my_data->acdb_handle,
1128 "acdb_loader_send_voice_cal");
Ben Rombergerc1dc70d2013-12-19 15:11:17 -08001129 if (!my_data->acdb_send_voice_cal)
1130 ALOGE("%s: Could not find the symbol acdb_loader_send_voice_cal from %s",
1131 __func__, LIB_ACDB_LOADER);
1132
1133 my_data->acdb_reload_vocvoltable = (acdb_reload_vocvoltable_t)dlsym(my_data->acdb_handle,
1134 "acdb_loader_reload_vocvoltable");
1135 if (!my_data->acdb_reload_vocvoltable)
1136 ALOGE("%s: Could not find the symbol acdb_loader_reload_vocvoltable from %s",
1137 __func__, LIB_ACDB_LOADER);
1138
Subhash Chandra Bose Naripeddy54274672014-03-10 14:51:02 -07001139 my_data->acdb_get_default_app_type = (acdb_get_default_app_type_t)dlsym(
1140 my_data->acdb_handle,
1141 "acdb_loader_get_default_app_type");
1142 if (!my_data->acdb_get_default_app_type)
1143 ALOGE("%s: Could not find the symbol acdb_get_default_app_type from %s",
1144 __func__, LIB_ACDB_LOADER);
1145
Eric Laurentb23d5282013-05-14 15:27:20 -07001146 my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
Ben Romberger490d3472014-01-15 17:11:59 -08001147 "acdb_loader_init_v2");
Walter Yang6f800052014-07-14 16:15:38 -07001148 if (my_data->acdb_init == NULL) {
Ben Romberger490d3472014-01-15 17:11:59 -08001149 ALOGE("%s: dlsym error %s for acdb_loader_init_v2", __func__, dlerror());
Walter Yang6f800052014-07-14 16:15:38 -07001150 goto acdb_init_fail;
1151 }
1152
1153 cvd_version = calloc(1, MAX_CVD_VERSION_STRING_SIZE);
1154 if (!cvd_version)
1155 ALOGE("failed to allocate cvd_version");
Eric Laurentb23d5282013-05-14 15:27:20 -07001156 else
Walter Yang6f800052014-07-14 16:15:38 -07001157 get_cvd_version(cvd_version, adev);
1158
1159 my_data->acdb_init(snd_card_name, cvd_version);
1160 if (cvd_version)
1161 free(cvd_version);
Eric Laurentb23d5282013-05-14 15:27:20 -07001162 }
1163
Walter Yang6f800052014-07-14 16:15:38 -07001164acdb_init_fail:
1165
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -07001166 set_platform_defaults();
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001167
Ben Romberger55886882014-01-10 13:49:02 -08001168 /* Initialize ACDB ID's */
Helen Zeng6a16ad72014-02-23 22:04:44 -08001169 if (my_data->is_i2s_ext_modem)
1170 platform_info_init(PLATFORM_INFO_XML_PATH_I2S);
1171 else
1172 platform_info_init(PLATFORM_INFO_XML_PATH);
Ben Romberger55886882014-01-10 13:49:02 -08001173
Vidyakumar Athota77327dd2014-08-07 16:44:25 -07001174 /* If platform is apq8084 and baseband is MDM, load CSD Client specific
1175 * symbols. Voice call is handled by MDM and apps processor talks to
1176 * MDM through CSD Client
1177 */
1178 property_get("ro.board.platform", platform, "");
1179 property_get("ro.baseband", baseband, "");
1180 if (!strncmp("apq8084", platform, sizeof("apq8084")) &&
1181 !strncmp("mdm", baseband, (sizeof("mdm")-1))) {
1182 my_data->csd = open_csd_client(my_data->is_i2s_ext_modem);
1183 } else {
1184 my_data->csd = NULL;
1185 }
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001186
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001187 /* init usb */
1188 audio_extn_usb_init(adev);
Apoorv Raghuvanshi84fa2fe2013-12-04 11:57:47 -08001189 /* update sound cards appropriately */
1190 audio_extn_usb_set_proxy_sound_card(adev->snd_card);
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001191
Pradnya Chaphekar8a9dcd82014-09-09 09:49:10 -07001192 /* init dap hal */
1193 audio_extn_dap_hal_init(adev->snd_card);
1194
Apoorv Raghuvanshi6178a3f2013-10-19 12:38:54 -07001195 /* Read one time ssr property */
Mingming Yin49be8032013-12-19 12:51:25 -08001196 audio_extn_ssr_update_enabled();
Gopikrishnaiah Anandanf538cef2013-10-28 14:06:03 -07001197 audio_extn_spkr_prot_init(adev);
Dhananjay Kumar89ea3bd2014-04-29 15:45:57 +05301198
1199 audio_extn_dolby_set_license(adev);
Anish Kumar55e6df22014-08-26 17:38:05 -07001200 audio_hwdep_send_cal(my_data);
Dhananjay Kumar89ea3bd2014-04-29 15:45:57 +05301201
Lior Barenboim0b61bc72014-05-13 13:01:37 +03001202 /* init audio device arbitration */
1203 audio_extn_dev_arbi_init();
1204
Eric Laurentb23d5282013-05-14 15:27:20 -07001205 return my_data;
1206}
1207
1208void platform_deinit(void *platform)
1209{
Ravi Kumar Alamanda48c921d2013-10-29 06:07:44 -07001210 struct platform_data *my_data = (struct platform_data *)platform;
1211
1212 hw_info_deinit(my_data->hw_info);
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001213 close_csd_client(my_data->csd);
1214
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001215 int32_t dev;
1216 for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
1217 if (backend_table[dev]) {
1218 free(backend_table[dev]);
1219 backend_table[dev]= NULL;
1220 }
1221 }
1222
Lior Barenboim0b61bc72014-05-13 13:01:37 +03001223 /* deinit audio device arbitration */
1224 audio_extn_dev_arbi_deinit();
1225
Pradnya Chaphekar4403bd72014-09-09 09:50:01 -07001226 if (my_data->edid_info) {
1227 free(my_data->edid_info);
1228 my_data->edid_info = NULL;
1229 }
1230
Eric Laurentb23d5282013-05-14 15:27:20 -07001231 free(platform);
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001232 /* deinit usb */
1233 audio_extn_usb_deinit();
Pradnya Chaphekar8a9dcd82014-09-09 09:49:10 -07001234 audio_extn_dap_hal_deinit();
Eric Laurentb23d5282013-05-14 15:27:20 -07001235}
1236
1237const char *platform_get_snd_device_name(snd_device_t snd_device)
1238{
1239 if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX)
1240 return device_table[snd_device];
1241 else
1242 return "";
1243}
1244
Ravi Kumar Alamanda48c921d2013-10-29 06:07:44 -07001245int platform_get_snd_device_name_extn(void *platform, snd_device_t snd_device,
1246 char *device_name)
1247{
1248 struct platform_data *my_data = (struct platform_data *)platform;
1249
1250 if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) {
1251 strlcpy(device_name, device_table[snd_device], DEVICE_NAME_MAX_SIZE);
1252 hw_info_append_hw_type(my_data->hw_info, snd_device, device_name);
1253 } else {
1254 strlcpy(device_name, "", DEVICE_NAME_MAX_SIZE);
1255 return -EINVAL;
1256 }
1257
1258 return 0;
1259}
1260
Eric Laurentb23d5282013-05-14 15:27:20 -07001261void platform_add_backend_name(char *mixer_path, snd_device_t snd_device)
1262{
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001263 if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
1264 ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
1265 return;
1266 }
1267
1268 const char * suffix = backend_table[snd_device];
1269
1270 if (suffix != NULL) {
1271 strlcat(mixer_path, " ", MIXER_PATH_MAX_LENGTH);
1272 strlcat(mixer_path, suffix, MIXER_PATH_MAX_LENGTH);
Vidyakumar Athota1c6419a2014-01-10 14:47:34 -08001273 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001274}
1275
1276int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
1277{
1278 int device_id;
1279 if (device_type == PCM_PLAYBACK)
1280 device_id = pcm_device_table[usecase][0];
1281 else
1282 device_id = pcm_device_table[usecase][1];
1283 return device_id;
1284}
1285
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001286static int find_index(struct name_to_index * table, int32_t len, const char * name)
Ben Romberger61764e32014-01-10 13:49:02 -08001287{
1288 int ret = 0;
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001289 int32_t i;
Ben Romberger61764e32014-01-10 13:49:02 -08001290
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001291 if (table == NULL) {
1292 ALOGE("%s: table is NULL", __func__);
Ben Romberger61764e32014-01-10 13:49:02 -08001293 ret = -ENODEV;
1294 goto done;
1295 }
1296
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001297 if (name == NULL) {
1298 ALOGE("null key");
1299 ret = -ENODEV;
1300 goto done;
1301 }
1302
1303 for (i=0; i < len; i++) {
1304 const char* tn = table[i].name;
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -07001305 size_t len = strlen(tn);
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001306 if (strncmp(tn, name, len) == 0) {
1307 if (strlen(name) != len) {
1308 continue; // substring
1309 }
1310 ret = table[i].index;
Ben Romberger61764e32014-01-10 13:49:02 -08001311 goto done;
1312 }
1313 }
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001314 ALOGE("%s: Could not find index for name = %s",
1315 __func__, name);
Ben Romberger61764e32014-01-10 13:49:02 -08001316 ret = -ENODEV;
1317done:
1318 return ret;
1319}
1320
Venkata Narendra Kumar Gutta88fd0bc2014-03-27 19:47:56 +05301321int platform_set_fluence_type(void *platform, char *value)
1322{
1323 int ret = 0;
1324 int fluence_type = FLUENCE_NONE;
1325 int fluence_flag = NONE_FLAG;
1326 struct platform_data *my_data = (struct platform_data *)platform;
1327 struct audio_device *adev = my_data->adev;
1328
1329 ALOGV("%s: fluence type:%d", __func__, my_data->fluence_type);
1330
1331 /* only dual mic turn on and off is supported as of now through setparameters */
1332 if (!strncmp(AUDIO_PARAMETER_VALUE_DUALMIC,value, sizeof(AUDIO_PARAMETER_VALUE_DUALMIC))) {
1333 if (!strncmp("fluencepro", my_data->fluence_cap, sizeof("fluencepro")) ||
1334 !strncmp("fluence", my_data->fluence_cap, sizeof("fluence"))) {
1335 ALOGV("fluence dualmic feature enabled \n");
1336 fluence_type = FLUENCE_DUAL_MIC;
1337 fluence_flag = DMIC_FLAG;
1338 } else {
1339 ALOGE("%s: Failed to set DUALMIC", __func__);
1340 ret = -1;
1341 goto done;
1342 }
1343 } else if (!strncmp(AUDIO_PARAMETER_KEY_NO_FLUENCE, value, sizeof(AUDIO_PARAMETER_KEY_NO_FLUENCE))) {
1344 ALOGV("fluence disabled");
1345 fluence_type = FLUENCE_NONE;
1346 } else {
1347 ALOGE("Invalid fluence value : %s",value);
1348 ret = -1;
1349 goto done;
1350 }
1351
1352 if (fluence_type != my_data->fluence_type) {
1353 ALOGV("%s: Updating fluence_type to :%d", __func__, fluence_type);
1354 my_data->fluence_type = fluence_type;
1355 adev->acdb_settings = (adev->acdb_settings & FLUENCE_MODE_CLEAR) | fluence_flag;
1356 }
1357done:
1358 return ret;
1359}
1360
1361int platform_get_fluence_type(void *platform, char *value, uint32_t len)
1362{
1363 int ret = 0;
1364 struct platform_data *my_data = (struct platform_data *)platform;
1365
1366 if (my_data->fluence_type == FLUENCE_QUAD_MIC) {
1367 strlcpy(value, "quadmic", len);
1368 } else if (my_data->fluence_type == FLUENCE_DUAL_MIC) {
1369 strlcpy(value, "dualmic", len);
1370 } else if (my_data->fluence_type == FLUENCE_NONE) {
1371 strlcpy(value, "none", len);
1372 } else
1373 ret = -1;
1374
1375 return ret;
1376}
1377
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07001378int platform_get_snd_device_index(char *device_name)
1379{
1380 return find_index(snd_device_name_index, SND_DEVICE_MAX, device_name);
1381}
1382
1383int platform_get_usecase_index(const char *usecase_name)
1384{
1385 return find_index(usecase_name_index, AUDIO_USECASE_MAX, usecase_name);
1386}
1387
Ben Romberger55886882014-01-10 13:49:02 -08001388int platform_set_snd_device_acdb_id(snd_device_t snd_device, unsigned int acdb_id)
1389{
1390 int ret = 0;
1391
1392 if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
1393 ALOGE("%s: Invalid snd_device = %d",
1394 __func__, snd_device);
1395 ret = -EINVAL;
1396 goto done;
1397 }
1398
1399 acdb_device_table[snd_device] = acdb_id;
1400done:
1401 return ret;
1402}
1403
Subhash Chandra Bose Naripeddy54274672014-03-10 14:51:02 -07001404int platform_get_default_app_type(void *platform)
1405{
1406 struct platform_data *my_data = (struct platform_data *)platform;
1407
1408 if (my_data->acdb_get_default_app_type)
1409 return my_data->acdb_get_default_app_type();
1410 else
1411 return DEFAULT_APP_TYPE;
1412}
1413
Subhash Chandra Bose Naripeddy19dc03b2014-03-10 14:43:05 -07001414int platform_get_snd_device_acdb_id(snd_device_t snd_device)
1415{
1416 if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
1417 ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
1418 return -EINVAL;
1419 }
1420 return acdb_device_table[snd_device];
1421}
1422
Amit Shekhar5a39c912014-10-14 15:39:30 -07001423int platform_set_snd_device_bit_width(snd_device_t snd_device, unsigned int bit_width)
1424{
1425 int ret = 0;
1426
1427 if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
1428 ALOGE("%s: Invalid snd_device = %d",
1429 __func__, snd_device);
1430 ret = -EINVAL;
1431 goto done;
1432 }
1433
1434 backend_bit_width_table[snd_device] = bit_width;
1435done:
1436 return ret;
1437}
1438
1439int platform_get_snd_device_bit_width(snd_device_t snd_device)
1440{
1441 if ((snd_device < SND_DEVICE_MIN) || (snd_device >= SND_DEVICE_MAX)) {
1442 ALOGE("%s: Invalid snd_device = %d", __func__, snd_device);
1443 return DEFAULT_OUTPUT_SAMPLING_RATE;
1444 }
1445 return backend_bit_width_table[snd_device];
1446}
1447
Subhash Chandra Bose Naripeddy54274672014-03-10 14:51:02 -07001448int platform_send_audio_calibration(void *platform, snd_device_t snd_device,
1449 int app_type, int sample_rate)
Eric Laurentb23d5282013-05-14 15:27:20 -07001450{
1451 struct platform_data *my_data = (struct platform_data *)platform;
1452 int acdb_dev_id, acdb_dev_type;
1453
Anish Kumarf16721c2014-08-01 15:09:25 -07001454 acdb_dev_id = acdb_device_table[audio_extn_get_spkr_prot_snd_device(snd_device)];
Eric Laurentb23d5282013-05-14 15:27:20 -07001455 if (acdb_dev_id < 0) {
1456 ALOGE("%s: Could not find acdb id for device(%d)",
1457 __func__, snd_device);
1458 return -EINVAL;
1459 }
1460 if (my_data->acdb_send_audio_cal) {
Subhash Chandra Bose Naripeddy54274672014-03-10 14:51:02 -07001461 ALOGV("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
Eric Laurentb23d5282013-05-14 15:27:20 -07001462 __func__, snd_device, acdb_dev_id);
1463 if (snd_device >= SND_DEVICE_OUT_BEGIN &&
1464 snd_device < SND_DEVICE_OUT_END)
1465 acdb_dev_type = ACDB_DEV_TYPE_OUT;
1466 else
1467 acdb_dev_type = ACDB_DEV_TYPE_IN;
Subhash Chandra Bose Naripeddy54274672014-03-10 14:51:02 -07001468 my_data->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type, app_type,
1469 sample_rate);
Eric Laurentb23d5282013-05-14 15:27:20 -07001470 }
1471 return 0;
1472}
1473
1474int platform_switch_voice_call_device_pre(void *platform)
1475{
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001476 struct platform_data *my_data = (struct platform_data *)platform;
1477 int ret = 0;
1478
Vidyakumar Athota1fd21792013-11-15 14:50:57 -08001479 if (my_data->csd != NULL &&
Ravi Kumar Alamandabe149392014-10-20 17:07:43 -07001480 voice_is_in_call(my_data->adev)) {
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001481 /* This must be called before disabling mixer controls on APQ side */
1482 ret = my_data->csd->disable_device();
1483 if (ret < 0) {
1484 ALOGE("%s: csd_client_disable_device, failed, error %d",
1485 __func__, ret);
1486 }
1487 }
1488 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001489}
1490
Vidyakumar Athota545dbd32013-11-13 17:30:53 -08001491int platform_switch_voice_call_enable_device_config(void *platform,
1492 snd_device_t out_snd_device,
1493 snd_device_t in_snd_device)
1494{
1495 struct platform_data *my_data = (struct platform_data *)platform;
1496 int acdb_rx_id, acdb_tx_id;
1497 int ret = 0;
1498
Vidyakumar Athota1c6419a2014-01-10 14:47:34 -08001499 if (my_data->csd == NULL)
1500 return ret;
1501
1502 if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
1503 audio_extn_spkr_prot_is_enabled())
1504 acdb_rx_id = acdb_device_table[SND_DEVICE_OUT_SPEAKER_PROTECTED];
1505 else
1506 acdb_rx_id = acdb_device_table[out_snd_device];
1507
Vidyakumar Athota545dbd32013-11-13 17:30:53 -08001508 acdb_tx_id = acdb_device_table[in_snd_device];
1509
Vidyakumar Athota1c6419a2014-01-10 14:47:34 -08001510 if (acdb_rx_id > 0 && acdb_tx_id > 0) {
1511 ret = my_data->csd->enable_device_config(acdb_rx_id, acdb_tx_id);
1512 if (ret < 0) {
1513 ALOGE("%s: csd_enable_device_config, failed, error %d",
1514 __func__, ret);
Vidyakumar Athota545dbd32013-11-13 17:30:53 -08001515 }
Vidyakumar Athota1c6419a2014-01-10 14:47:34 -08001516 } else {
1517 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1518 acdb_rx_id, acdb_tx_id);
Vidyakumar Athota545dbd32013-11-13 17:30:53 -08001519 }
Vidyakumar Athota1c6419a2014-01-10 14:47:34 -08001520
Vidyakumar Athota545dbd32013-11-13 17:30:53 -08001521 return ret;
1522}
1523
Eric Laurentb23d5282013-05-14 15:27:20 -07001524int platform_switch_voice_call_device_post(void *platform,
1525 snd_device_t out_snd_device,
1526 snd_device_t in_snd_device)
1527{
1528 struct platform_data *my_data = (struct platform_data *)platform;
1529 int acdb_rx_id, acdb_tx_id;
1530
1531 if (my_data->acdb_send_voice_cal == NULL) {
1532 ALOGE("%s: dlsym error for acdb_send_voice_call", __func__);
1533 } else {
Anish Kumar46c7b872014-09-09 01:49:44 -07001534 if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
1535 audio_extn_spkr_prot_is_enabled())
1536 out_snd_device = SND_DEVICE_OUT_VOICE_SPEAKER_PROTECTED;
1537
Vidyakumar Athota1fd21792013-11-15 14:50:57 -08001538 acdb_rx_id = acdb_device_table[out_snd_device];
1539 acdb_tx_id = acdb_device_table[in_snd_device];
1540
Eric Laurentb23d5282013-05-14 15:27:20 -07001541 if (acdb_rx_id > 0 && acdb_tx_id > 0)
1542 my_data->acdb_send_voice_cal(acdb_rx_id, acdb_tx_id);
1543 else
1544 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1545 acdb_rx_id, acdb_tx_id);
1546 }
1547
Vidyakumar Athota1fd21792013-11-15 14:50:57 -08001548 return 0;
1549}
1550
1551int platform_switch_voice_call_usecase_route_post(void *platform,
1552 snd_device_t out_snd_device,
1553 snd_device_t in_snd_device)
1554{
1555 struct platform_data *my_data = (struct platform_data *)platform;
1556 int acdb_rx_id, acdb_tx_id;
1557 int ret = 0;
1558
Vidyakumar Athota1c6419a2014-01-10 14:47:34 -08001559 if (my_data->csd == NULL)
1560 return ret;
1561
1562 if (out_snd_device == SND_DEVICE_OUT_VOICE_SPEAKER &&
1563 audio_extn_spkr_prot_is_enabled())
1564 acdb_rx_id = acdb_device_table[SND_DEVICE_OUT_SPEAKER_PROTECTED];
1565 else
1566 acdb_rx_id = acdb_device_table[out_snd_device];
1567
Vidyakumar Athota1fd21792013-11-15 14:50:57 -08001568 acdb_tx_id = acdb_device_table[in_snd_device];
1569
Vidyakumar Athota1c6419a2014-01-10 14:47:34 -08001570 if (acdb_rx_id > 0 && acdb_tx_id > 0) {
1571 ret = my_data->csd->enable_device(acdb_rx_id, acdb_tx_id,
1572 my_data->adev->acdb_settings);
1573 if (ret < 0) {
1574 ALOGE("%s: csd_enable_device, failed, error %d", __func__, ret);
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001575 }
Vidyakumar Athota1c6419a2014-01-10 14:47:34 -08001576 } else {
1577 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
1578 acdb_rx_id, acdb_tx_id);
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001579 }
Vidyakumar Athota1c6419a2014-01-10 14:47:34 -08001580
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001581 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001582}
1583
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001584int platform_start_voice_call(void *platform, uint32_t vsid)
Eric Laurentb23d5282013-05-14 15:27:20 -07001585{
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001586 struct platform_data *my_data = (struct platform_data *)platform;
1587 int ret = 0;
1588
1589 if (my_data->csd != NULL) {
1590 ret = my_data->csd->start_voice(vsid);
1591 if (ret < 0) {
1592 ALOGE("%s: csd_start_voice error %d\n", __func__, ret);
1593 }
1594 }
1595 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001596}
1597
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001598int platform_stop_voice_call(void *platform, uint32_t vsid)
Eric Laurentb23d5282013-05-14 15:27:20 -07001599{
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001600 struct platform_data *my_data = (struct platform_data *)platform;
1601 int ret = 0;
1602
1603 if (my_data->csd != NULL) {
1604 ret = my_data->csd->stop_voice(vsid);
1605 if (ret < 0) {
1606 ALOGE("%s: csd_stop_voice error %d\n", __func__, ret);
1607 }
1608 }
1609 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001610}
1611
Helen Zeng6a16ad72014-02-23 22:04:44 -08001612int platform_get_sample_rate(void *platform, uint32_t *rate)
1613{
1614 struct platform_data *my_data = (struct platform_data *)platform;
1615 int ret = 0;
1616
1617 if ((my_data->csd != NULL) && my_data->is_i2s_ext_modem) {
1618 ret = my_data->csd->get_sample_rate(rate);
1619 if (ret < 0) {
1620 ALOGE("%s: csd_get_sample_rate error %d\n", __func__, ret);
1621 }
1622 }
1623 return ret;
1624}
1625
Eric Laurentb23d5282013-05-14 15:27:20 -07001626int platform_set_voice_volume(void *platform, int volume)
1627{
1628 struct platform_data *my_data = (struct platform_data *)platform;
1629 struct audio_device *adev = my_data->adev;
1630 struct mixer_ctl *ctl;
sangwoo53b2cf02013-07-25 19:18:44 -07001631 const char *mixer_ctl_name = "Voice Rx Gain";
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001632 int vol_index = 0, ret = 0;
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001633 uint32_t set_values[ ] = {0,
1634 ALL_SESSION_VSID,
1635 DEFAULT_VOLUME_RAMP_DURATION_MS};
Eric Laurentb23d5282013-05-14 15:27:20 -07001636
1637 // Voice volume levels are mapped to adsp volume levels as follows.
1638 // 100 -> 5, 80 -> 4, 60 -> 3, 40 -> 2, 20 -> 1 0 -> 0
1639 // But this values don't changed in kernel. So, below change is need.
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001640 vol_index = (int)percent_to_index(volume, MIN_VOL_INDEX, MAX_VOL_INDEX);
1641 set_values[0] = vol_index;
Eric Laurentb23d5282013-05-14 15:27:20 -07001642
1643 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1644 if (!ctl) {
1645 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1646 __func__, mixer_ctl_name);
1647 return -EINVAL;
1648 }
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001649 ALOGV("Setting voice volume index: %d", set_values[0]);
1650 mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
Eric Laurentb23d5282013-05-14 15:27:20 -07001651
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001652 if (my_data->csd != NULL) {
Vidyakumar Athotac37f42a2014-03-11 11:57:48 -07001653 ret = my_data->csd->volume(ALL_SESSION_VSID, volume,
1654 DEFAULT_VOLUME_RAMP_DURATION_MS);
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001655 if (ret < 0) {
1656 ALOGE("%s: csd_volume error %d", __func__, ret);
1657 }
1658 }
1659 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001660}
1661
1662int platform_set_mic_mute(void *platform, bool state)
1663{
1664 struct platform_data *my_data = (struct platform_data *)platform;
1665 struct audio_device *adev = my_data->adev;
1666 struct mixer_ctl *ctl;
1667 const char *mixer_ctl_name = "Voice Tx Mute";
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001668 int ret = 0;
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001669 uint32_t set_values[ ] = {0,
1670 ALL_SESSION_VSID,
Vidyakumar Athotac37f42a2014-03-11 11:57:48 -07001671 DEFAULT_MUTE_RAMP_DURATION_MS};
Eric Laurentb23d5282013-05-14 15:27:20 -07001672
Narsinga Rao Chella05573b72013-11-15 15:21:40 -08001673 set_values[0] = state;
1674 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1675 if (!ctl) {
1676 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1677 __func__, mixer_ctl_name);
1678 return -EINVAL;
1679 }
1680 ALOGV("Setting voice mute state: %d", state);
1681 mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
Eric Laurentb23d5282013-05-14 15:27:20 -07001682
Narsinga Rao Chella05573b72013-11-15 15:21:40 -08001683 if (my_data->csd != NULL) {
Vidyakumar Athotac37f42a2014-03-11 11:57:48 -07001684 ret = my_data->csd->mic_mute(ALL_SESSION_VSID, state,
1685 DEFAULT_MUTE_RAMP_DURATION_MS);
Narsinga Rao Chella05573b72013-11-15 15:21:40 -08001686 if (ret < 0) {
1687 ALOGE("%s: csd_mic_mute error %d", __func__, ret);
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08001688 }
1689 }
1690 return ret;
Eric Laurentb23d5282013-05-14 15:27:20 -07001691}
1692
Shiv Maliyappanahallic6fd8ee2014-03-07 15:31:55 -08001693int platform_set_device_mute(void *platform, bool state, char *dir)
1694{
1695 struct platform_data *my_data = (struct platform_data *)platform;
1696 struct audio_device *adev = my_data->adev;
1697 struct mixer_ctl *ctl;
1698 char *mixer_ctl_name = NULL;
1699 int ret = 0;
1700 uint32_t set_values[ ] = {0,
1701 ALL_SESSION_VSID,
1702 0};
1703 if(dir == NULL) {
1704 ALOGE("%s: Invalid direction:%s", __func__, dir);
1705 return -EINVAL;
1706 }
1707
1708 if (!strncmp("rx", dir, sizeof("rx"))) {
1709 mixer_ctl_name = "Voice Rx Device Mute";
1710 } else if (!strncmp("tx", dir, sizeof("tx"))) {
1711 mixer_ctl_name = "Voice Tx Device Mute";
1712 } else {
1713 return -EINVAL;
1714 }
1715
1716 set_values[0] = state;
1717 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
1718 if (!ctl) {
1719 ALOGE("%s: Could not get ctl for mixer cmd - %s",
1720 __func__, mixer_ctl_name);
1721 return -EINVAL;
1722 }
1723
1724 ALOGV("%s: Setting device mute state: %d, mixer ctrl:%s",
1725 __func__,state, mixer_ctl_name);
1726 mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
1727
1728 return ret;
1729}
1730
Eric Laurentb23d5282013-05-14 15:27:20 -07001731snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices)
1732{
1733 struct platform_data *my_data = (struct platform_data *)platform;
1734 struct audio_device *adev = my_data->adev;
1735 audio_mode_t mode = adev->mode;
1736 snd_device_t snd_device = SND_DEVICE_NONE;
1737
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001738 audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
1739 AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
1740 int channel_count = popcount(channel_mask);
1741
Eric Laurentb23d5282013-05-14 15:27:20 -07001742 ALOGV("%s: enter: output devices(%#x)", __func__, devices);
1743 if (devices == AUDIO_DEVICE_NONE ||
1744 devices & AUDIO_DEVICE_BIT_IN) {
1745 ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
1746 goto exit;
1747 }
1748
Mingming Yin4a72d652014-01-03 18:54:18 -08001749 if (popcount(devices) == 2) {
1750 if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
1751 AUDIO_DEVICE_OUT_SPEAKER)) {
Tanya Finkel00130052014-07-14 04:26:56 -07001752 if (my_data->external_spk_1)
1753 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1;
1754 else if (my_data->external_spk_2)
1755 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2;
1756 else
1757 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
Mingming Yin4a72d652014-01-03 18:54:18 -08001758 } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
1759 AUDIO_DEVICE_OUT_SPEAKER)) {
1760 if (audio_extn_get_anc_enabled())
1761 snd_device = SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET;
Tanya Finkel00130052014-07-14 04:26:56 -07001762 else if (my_data->external_spk_1)
1763 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1;
1764 else if (my_data->external_spk_2)
1765 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2;
Mingming Yin4a72d652014-01-03 18:54:18 -08001766 else
1767 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
1768 } else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
1769 AUDIO_DEVICE_OUT_SPEAKER)) {
1770 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI;
1771 } else if (devices == (AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET |
1772 AUDIO_DEVICE_OUT_SPEAKER)) {
1773 snd_device = SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET;
1774 } else {
1775 ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
1776 goto exit;
1777 }
1778 if (snd_device != SND_DEVICE_NONE) {
1779 goto exit;
1780 }
1781 }
1782
1783 if (popcount(devices) != 1) {
1784 ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
1785 goto exit;
1786 }
1787
Ravi Kumar Alamandabe149392014-10-20 17:07:43 -07001788 if (voice_is_in_call(adev) ||
Narsinga Rao Chella05573b72013-11-15 15:21:40 -08001789 voice_extn_compress_voip_is_active(adev)) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001790 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1791 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Narsinga Rao Chella05573b72013-11-15 15:21:40 -08001792 if ((adev->voice.tty_mode != TTY_MODE_OFF) &&
1793 !voice_extn_compress_voip_is_active(adev)) {
1794 switch (adev->voice.tty_mode) {
1795 case TTY_MODE_FULL:
1796 snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES;
1797 break;
1798 case TTY_MODE_VCO:
1799 snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES;
1800 break;
1801 case TTY_MODE_HCO:
1802 snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET;
1803 break;
1804 default:
1805 ALOGE("%s: Invalid TTY mode (%#x)",
1806 __func__, adev->voice.tty_mode);
1807 }
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001808 } else if (audio_extn_get_anc_enabled()) {
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001809 if (audio_extn_should_use_fb_anc())
1810 snd_device = SND_DEVICE_OUT_VOICE_ANC_FB_HEADSET;
1811 else
1812 snd_device = SND_DEVICE_OUT_VOICE_ANC_HEADSET;
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001813 } else {
Eric Laurentb23d5282013-05-14 15:27:20 -07001814 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001815 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001816 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Mingming Yin514a8bc2014-07-29 15:22:21 -07001817 if (adev->bt_wb_speech_enabled)
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001818 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
1819 else
1820 snd_device = SND_DEVICE_OUT_BT_SCO;
Eric Laurentb23d5282013-05-14 15:27:20 -07001821 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
1822 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001823 } else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
1824 devices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
1825 snd_device = SND_DEVICE_OUT_USB_HEADSET;
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -07001826 } else if (devices & AUDIO_DEVICE_OUT_FM_TX) {
1827 snd_device = SND_DEVICE_OUT_TRANSMISSION_FM;
Eric Laurentb23d5282013-05-14 15:27:20 -07001828 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
Ravi Kumar Alamandaceb40822013-11-06 11:01:47 -08001829 if (audio_extn_should_use_handset_anc(channel_count))
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001830 snd_device = SND_DEVICE_OUT_ANC_HANDSET;
Eric Laurentb23d5282013-05-14 15:27:20 -07001831 else
Mingming Yin8e5a4f62013-10-07 15:23:41 -07001832 snd_device = SND_DEVICE_OUT_VOICE_HANDSET;
Ravi Kumar Alamanda060bc5a2014-09-05 13:51:35 -07001833 } else if (devices & AUDIO_DEVICE_OUT_TELEPHONY_TX)
1834 snd_device = SND_DEVICE_OUT_VOICE_TX;
1835
Eric Laurentb23d5282013-05-14 15:27:20 -07001836 if (snd_device != SND_DEVICE_NONE) {
1837 goto exit;
1838 }
1839 }
1840
Eric Laurentb23d5282013-05-14 15:27:20 -07001841 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1842 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001843 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADSET
1844 && audio_extn_get_anc_enabled()) {
1845 if (audio_extn_should_use_fb_anc())
1846 snd_device = SND_DEVICE_OUT_ANC_FB_HEADSET;
1847 else
1848 snd_device = SND_DEVICE_OUT_ANC_HEADSET;
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -07001849 } else
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001850 snd_device = SND_DEVICE_OUT_HEADPHONES;
Eric Laurentb23d5282013-05-14 15:27:20 -07001851 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
Tanya Finkel00130052014-07-14 04:26:56 -07001852 if (my_data->external_spk_1)
1853 snd_device = SND_DEVICE_OUT_SPEAKER_EXTERNAL_1;
1854 else if (my_data->external_spk_2)
1855 snd_device = SND_DEVICE_OUT_SPEAKER_EXTERNAL_2;
1856 else if (adev->speaker_lr_swap)
Eric Laurentb23d5282013-05-14 15:27:20 -07001857 snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE;
1858 else
1859 snd_device = SND_DEVICE_OUT_SPEAKER;
1860 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Mingming Yin514a8bc2014-07-29 15:22:21 -07001861 if (adev->bt_wb_speech_enabled)
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001862 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
1863 else
1864 snd_device = SND_DEVICE_OUT_BT_SCO;
Eric Laurentb23d5282013-05-14 15:27:20 -07001865 } else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
1866 snd_device = SND_DEVICE_OUT_HDMI ;
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001867 } else if (devices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
1868 devices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
Mingming Yin5a7c5d62014-03-05 17:45:03 -08001869 ALOGD("%s: setting USB hadset channel capability(2) for Proxy", __func__);
1870 audio_extn_set_afe_proxy_channel_mixer(adev, 2);
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001871 snd_device = SND_DEVICE_OUT_USB_HEADSET;
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -07001872 } else if (devices & AUDIO_DEVICE_OUT_FM_TX) {
1873 snd_device = SND_DEVICE_OUT_TRANSMISSION_FM;
Eric Laurentb23d5282013-05-14 15:27:20 -07001874 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
1875 snd_device = SND_DEVICE_OUT_HANDSET;
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001876 } else if (devices & AUDIO_DEVICE_OUT_PROXY) {
Mingming Yin5a7c5d62014-03-05 17:45:03 -08001877 channel_count = audio_extn_get_afe_proxy_channel_count();
1878 ALOGD("%s: setting sink capability(%d) for Proxy", __func__, channel_count);
1879 audio_extn_set_afe_proxy_channel_mixer(adev, channel_count);
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07001880 snd_device = SND_DEVICE_OUT_AFE_PROXY;
Eric Laurentb23d5282013-05-14 15:27:20 -07001881 } else {
1882 ALOGE("%s: Unknown device(s) %#x", __func__, devices);
1883 }
1884exit:
1885 ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
1886 return snd_device;
1887}
1888
1889snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device)
1890{
1891 struct platform_data *my_data = (struct platform_data *)platform;
1892 struct audio_device *adev = my_data->adev;
1893 audio_source_t source = (adev->active_input == NULL) ?
1894 AUDIO_SOURCE_DEFAULT : adev->active_input->source;
1895
1896 audio_mode_t mode = adev->mode;
1897 audio_devices_t in_device = ((adev->active_input == NULL) ?
1898 AUDIO_DEVICE_NONE : adev->active_input->device)
1899 & ~AUDIO_DEVICE_BIT_IN;
1900 audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
1901 AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
1902 snd_device_t snd_device = SND_DEVICE_NONE;
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001903 int channel_count = popcount(channel_mask);
Eric Laurentb23d5282013-05-14 15:27:20 -07001904
1905 ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
1906 __func__, out_device, in_device);
Tanya Finkel00130052014-07-14 04:26:56 -07001907 if (my_data->external_mic) {
Ravi Kumar Alamandabe149392014-10-20 17:07:43 -07001908 if ((out_device != AUDIO_DEVICE_NONE && voice_is_in_call(adev)) ||
Tanya Finkel00130052014-07-14 04:26:56 -07001909 voice_extn_compress_voip_is_active(adev) || audio_extn_hfp_is_active(adev)) {
1910 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1911 out_device & AUDIO_DEVICE_OUT_EARPIECE ||
1912 out_device & AUDIO_DEVICE_OUT_SPEAKER )
1913 snd_device = SND_DEVICE_IN_HANDSET_MIC_EXTERNAL;
1914 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
1915 in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1916 snd_device = SND_DEVICE_IN_HANDSET_MIC_EXTERNAL;
1917 }
1918 }
1919
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -07001920 if (snd_device != AUDIO_DEVICE_NONE)
Tanya Finkel00130052014-07-14 04:26:56 -07001921 goto exit;
1922
Ravi Kumar Alamandabe149392014-10-20 17:07:43 -07001923 if ((out_device != AUDIO_DEVICE_NONE) && ((voice_is_in_call(adev)) ||
Satya Krishna Pindiproli071950f2014-05-21 14:45:28 +05301924 voice_extn_compress_voip_is_active(adev) || audio_extn_hfp_is_active(adev))) {
Narsinga Rao Chella05573b72013-11-15 15:21:40 -08001925 if ((adev->voice.tty_mode != TTY_MODE_OFF) &&
1926 !voice_extn_compress_voip_is_active(adev)) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001927 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
1928 out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07001929 switch (adev->voice.tty_mode) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001930 case TTY_MODE_FULL:
1931 snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC;
1932 break;
1933 case TTY_MODE_VCO:
1934 snd_device = SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC;
1935 break;
1936 case TTY_MODE_HCO:
1937 snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC;
1938 break;
1939 default:
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -07001940 ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->voice.tty_mode);
Eric Laurentb23d5282013-05-14 15:27:20 -07001941 }
1942 goto exit;
1943 }
1944 }
Narsinga Rao Chella97db8702014-10-03 13:34:45 -07001945 if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
1946 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001947 if (out_device & AUDIO_DEVICE_OUT_EARPIECE &&
1948 audio_extn_should_use_handset_anc(channel_count)) {
1949 snd_device = SND_DEVICE_IN_AANC_HANDSET_MIC;
Banajit Goswamide0ea452014-04-07 12:11:47 -07001950 adev->acdb_settings |= ANC_FLAG;
Apoorv Raghuvanshi9eaf94e2013-10-04 16:13:44 -07001951 } else if (my_data->fluence_type == FLUENCE_NONE ||
Mingming Yin8e5a4f62013-10-07 15:23:41 -07001952 my_data->fluence_in_voice_call == false) {
Eric Laurentb23d5282013-05-14 15:27:20 -07001953 snd_device = SND_DEVICE_IN_HANDSET_MIC;
Venkata Narendra Kumar Gutta1bbbf542014-09-04 19:11:25 +05301954 if (audio_extn_hfp_is_active(adev))
1955 platform_set_echo_reference(adev->platform, true);
Eric Laurentb23d5282013-05-14 15:27:20 -07001956 } else {
Ravi Kumar Alamandaceb40822013-11-06 11:01:47 -08001957 snd_device = SND_DEVICE_IN_VOICE_DMIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07001958 }
1959 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
1960 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
Venkata Narendra Kumar Gutta1bbbf542014-09-04 19:11:25 +05301961 if (audio_extn_hfp_is_active(adev))
1962 platform_set_echo_reference(adev->platform, true);
Eric Laurentb23d5282013-05-14 15:27:20 -07001963 } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
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 }
Narsinga Rao Chella97db8702014-10-03 13:34:45 -07001975 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
Mingming Yin8e5a4f62013-10-07 15:23:41 -07001976 if (my_data->fluence_type != FLUENCE_NONE &&
1977 my_data->fluence_in_voice_call &&
1978 my_data->fluence_in_spkr_mode) {
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -08001979 if(my_data->fluence_type & FLUENCE_QUAD_MIC) {
Mingming Yin8e5a4f62013-10-07 15:23:41 -07001980 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_QMIC;
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -08001981 } else {
Narsinga Rao Chella61e0f9b2014-03-06 21:25:22 -08001982 if (my_data->fluence_mode == FLUENCE_BROADSIDE)
1983 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BROADSIDE;
1984 else
1985 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC;
Mingming Yin8e5a4f62013-10-07 15:23:41 -07001986 }
Eric Laurentb23d5282013-05-14 15:27:20 -07001987 } else {
1988 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
Venkata Narendra Kumar Gutta1bbbf542014-09-04 19:11:25 +05301989 if (audio_extn_hfp_is_active(adev))
1990 platform_set_echo_reference(adev->platform, true);
Eric Laurentb23d5282013-05-14 15:27:20 -07001991 }
Ravi Kumar Alamanda060bc5a2014-09-05 13:51:35 -07001992 } else if (out_device & AUDIO_DEVICE_OUT_TELEPHONY_TX)
1993 snd_device = SND_DEVICE_IN_VOICE_RX;
Eric Laurentb23d5282013-05-14 15:27:20 -07001994 } else if (source == AUDIO_SOURCE_CAMCORDER) {
1995 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
1996 in_device & AUDIO_DEVICE_IN_BACK_MIC) {
1997 snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
1998 }
1999 } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
2000 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08002001 if (channel_count == 2) {
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -08002002 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO;
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08002003 } else if (adev->active_input->enable_ns)
2004 snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
2005 else if (my_data->fluence_type != FLUENCE_NONE &&
2006 my_data->fluence_in_voice_rec) {
2007 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08002008 } else {
2009 snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
2010 }
Eric Laurentb23d5282013-05-14 15:27:20 -07002011 }
2012 } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
2013 if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
2014 in_device = AUDIO_DEVICE_IN_BACK_MIC;
2015 if (adev->active_input) {
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08002016 if (adev->active_input->enable_aec &&
2017 adev->active_input->enable_ns) {
Eric Laurentb23d5282013-05-14 15:27:20 -07002018 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
Narsinga Rao Chella975572e2014-10-21 11:49:00 -07002019 if (my_data->fluence_in_spkr_mode) {
2020 if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
2021 snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
2022 } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
2023 if (my_data->fluence_mode == FLUENCE_BROADSIDE)
2024 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE;
2025 else
2026 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS;
2027 }
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08002028 } else
2029 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
Eric Laurentb23d5282013-05-14 15:27:20 -07002030 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08002031 if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
2032 snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08002033 } else
2034 snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
Eric Laurentb23d5282013-05-14 15:27:20 -07002035 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08002036 snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
Eric Laurentb23d5282013-05-14 15:27:20 -07002037 }
Venkata Narendra Kumar Gutta1bbbf542014-09-04 19:11:25 +05302038 platform_set_echo_reference(adev->platform, true);
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08002039 } else if (adev->active_input->enable_aec) {
2040 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
Narsinga Rao Chella975572e2014-10-21 11:49:00 -07002041 if (my_data->fluence_in_spkr_mode) {
2042 if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
2043 snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC;
2044 } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
2045 if (my_data->fluence_mode == FLUENCE_BROADSIDE)
2046 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE;
2047 else
2048 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC;
2049 }
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08002050 } else
2051 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
2052 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2053 if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
2054 snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08002055 } else
2056 snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
2057 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2058 snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
2059 }
Venkata Narendra Kumar Gutta1bbbf542014-09-04 19:11:25 +05302060 platform_set_echo_reference(adev->platform, true);
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08002061 } else if (adev->active_input->enable_ns) {
2062 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
Narsinga Rao Chella975572e2014-10-21 11:49:00 -07002063 if (my_data->fluence_in_spkr_mode) {
2064 if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
2065 snd_device = SND_DEVICE_IN_SPEAKER_QMIC_NS;
2066 } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
2067 if (my_data->fluence_mode == FLUENCE_BROADSIDE)
2068 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE;
2069 else
2070 snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS;
2071 }
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08002072 } else
2073 snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
2074 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2075 if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
2076 snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08002077 } else
2078 snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
2079 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2080 snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
2081 }
Venkata Narendra Kumar Gutta1bbbf542014-09-04 19:11:25 +05302082 platform_set_echo_reference(adev->platform, false);
Eric Laurentb23d5282013-05-14 15:27:20 -07002083 } else
Venkata Narendra Kumar Gutta1bbbf542014-09-04 19:11:25 +05302084 platform_set_echo_reference(adev->platform, false);
Eric Laurentb23d5282013-05-14 15:27:20 -07002085 }
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -08002086 } else if (source == AUDIO_SOURCE_MIC) {
Apoorv Raghuvanshic0536542013-11-14 16:25:59 -08002087 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC &&
2088 channel_count == 1 ) {
Narsinga Rao Chella975572e2014-10-21 11:49:00 -07002089 if(my_data->fluence_in_audio_rec) {
2090 if(my_data->fluence_type & FLUENCE_QUAD_MIC) {
2091 snd_device = SND_DEVICE_IN_HANDSET_QMIC;
2092 platform_set_echo_reference(adev->platform, true);
2093 } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
2094 snd_device = SND_DEVICE_IN_HANDSET_DMIC;
2095 platform_set_echo_reference(adev->platform, true);
2096 }
Ravi Kumar Alamanda7076b162014-03-07 11:40:24 -08002097 }
Ravi Kumar Alamandab034ddb2013-11-06 15:52:18 -08002098 }
Mingming Yinab429782013-11-07 11:16:55 -08002099 } else if (source == AUDIO_SOURCE_FM_RX ||
Ravi Kumar Alamanda198185e2013-11-07 15:42:19 -08002100 source == AUDIO_SOURCE_FM_RX_A2DP) {
Preetam Singh Ranawatde84f1a2013-11-01 14:58:16 -07002101 snd_device = SND_DEVICE_IN_CAPTURE_FM;
Eric Laurentb23d5282013-05-14 15:27:20 -07002102 } else if (source == AUDIO_SOURCE_DEFAULT) {
2103 goto exit;
2104 }
2105
2106
2107 if (snd_device != SND_DEVICE_NONE) {
2108 goto exit;
2109 }
2110
2111 if (in_device != AUDIO_DEVICE_NONE &&
2112 !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
2113 !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
2114 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Apoorv Raghuvanshi6178a3f2013-10-19 12:38:54 -07002115 if (audio_extn_ssr_get_enabled() && channel_count == 6)
2116 snd_device = SND_DEVICE_IN_QUAD_MIC;
Walter Yangbc136bd2014-01-17 11:24:23 +08002117 else if (my_data->fluence_type & (FLUENCE_DUAL_MIC | FLUENCE_QUAD_MIC) &&
2118 channel_count == 2)
Apoorv Raghuvanshi6bd8dbf2013-10-19 18:37:52 -07002119 snd_device = SND_DEVICE_IN_HANDSET_STEREO_DMIC;
Apoorv Raghuvanshi6178a3f2013-10-19 12:38:54 -07002120 else
2121 snd_device = SND_DEVICE_IN_HANDSET_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07002122 } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
2123 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
2124 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2125 snd_device = SND_DEVICE_IN_HEADSET_MIC;
2126 } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
Vicky Sehrawate240e5d2014-08-12 17:17:04 -07002127 if (adev->bt_wb_speech_enabled) {
2128 if (adev->bluetooth_nrec)
2129 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
2130 else
2131 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
2132 } else {
2133 if (adev->bluetooth_nrec)
2134 snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
2135 else
2136 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
2137 }
Eric Laurentb23d5282013-05-14 15:27:20 -07002138 } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
2139 snd_device = SND_DEVICE_IN_HDMI_MIC;
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07002140 } else if (in_device & AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET ||
2141 in_device & AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET) {
2142 snd_device = SND_DEVICE_IN_USB_HEADSET_MIC;
Apoorv Raghuvanshi6e262842013-10-06 14:39:35 -07002143 } else if (in_device & AUDIO_DEVICE_IN_FM_RX) {
2144 snd_device = SND_DEVICE_IN_CAPTURE_FM;
Eric Laurentb23d5282013-05-14 15:27:20 -07002145 } else {
2146 ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
2147 ALOGW("%s: Using default handset-mic", __func__);
2148 snd_device = SND_DEVICE_IN_HANDSET_MIC;
2149 }
2150 } else {
2151 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
2152 snd_device = SND_DEVICE_IN_HANDSET_MIC;
2153 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
2154 snd_device = SND_DEVICE_IN_HEADSET_MIC;
Narsinga Rao Chella97db8702014-10-03 13:34:45 -07002155 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -07002156 if (channel_count == 2)
Apoorv Raghuvanshi6bd8dbf2013-10-19 18:37:52 -07002157 snd_device = SND_DEVICE_IN_SPEAKER_STEREO_DMIC;
2158 else
2159 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
Narsinga Rao Chella97db8702014-10-03 13:34:45 -07002160 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
2161 snd_device = SND_DEVICE_IN_HANDSET_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07002162 } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
Vicky Sehrawate240e5d2014-08-12 17:17:04 -07002163 if (adev->bt_wb_speech_enabled) {
2164 if (adev->bluetooth_nrec)
2165 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB_NREC;
2166 else
2167 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
2168 } else {
2169 if (adev->bluetooth_nrec)
2170 snd_device = SND_DEVICE_IN_BT_SCO_MIC_NREC;
2171 else
2172 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
2173 }
Eric Laurentb23d5282013-05-14 15:27:20 -07002174 } else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
2175 snd_device = SND_DEVICE_IN_HDMI_MIC;
Apoorv Raghuvanshi5792d4b2013-10-07 18:40:05 -07002176 } else if (out_device & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET ||
2177 out_device & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET) {
2178 snd_device = SND_DEVICE_IN_USB_HEADSET_MIC;
Eric Laurentb23d5282013-05-14 15:27:20 -07002179 } else {
2180 ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
2181 ALOGW("%s: Using default handset-mic", __func__);
2182 snd_device = SND_DEVICE_IN_HANDSET_MIC;
2183 }
2184 }
2185exit:
2186 ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
2187 return snd_device;
2188}
2189
2190int platform_set_hdmi_channels(void *platform, int channel_count)
2191{
2192 struct platform_data *my_data = (struct platform_data *)platform;
2193 struct audio_device *adev = my_data->adev;
2194 struct mixer_ctl *ctl;
2195 const char *channel_cnt_str = NULL;
2196 const char *mixer_ctl_name = "HDMI_RX Channels";
2197 switch (channel_count) {
2198 case 8:
2199 channel_cnt_str = "Eight"; break;
2200 case 7:
2201 channel_cnt_str = "Seven"; break;
2202 case 6:
2203 channel_cnt_str = "Six"; break;
2204 case 5:
2205 channel_cnt_str = "Five"; break;
2206 case 4:
2207 channel_cnt_str = "Four"; break;
2208 case 3:
2209 channel_cnt_str = "Three"; break;
2210 default:
2211 channel_cnt_str = "Two"; break;
2212 }
2213 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2214 if (!ctl) {
2215 ALOGE("%s: Could not get ctl for mixer cmd - %s",
2216 __func__, mixer_ctl_name);
2217 return -EINVAL;
2218 }
2219 ALOGV("HDMI channel count: %s", channel_cnt_str);
2220 mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
2221 return 0;
2222}
2223
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07002224int platform_edid_get_max_channels(void *platform)
Eric Laurentb23d5282013-05-14 15:27:20 -07002225{
Pradnya Chaphekar4403bd72014-09-09 09:50:01 -07002226 int channel_count;
2227 int max_channels = 2;
2228 int i = 0, ret = 0;
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07002229 struct platform_data *my_data = (struct platform_data *)platform;
2230 struct audio_device *adev = my_data->adev;
Pradnya Chaphekar4403bd72014-09-09 09:50:01 -07002231 edid_audio_info *info = NULL;
2232 ret = platform_get_edid_info(platform);
2233 info = (edid_audio_info *)my_data->edid_info;
Eric Laurentb23d5282013-05-14 15:27:20 -07002234
Pradnya Chaphekar4403bd72014-09-09 09:50:01 -07002235 if(ret == 0 && info != NULL) {
2236 for (i = 0; i < info->audio_blocks && i < MAX_EDID_BLOCKS; i++) {
2237 ALOGV("%s:format %d channel %d", __func__,
2238 info->audio_blocks_array[i].format_id,
2239 info->audio_blocks_array[i].channels);
2240 if (info->audio_blocks_array[i].format_id == LPCM) {
2241 channel_count = info->audio_blocks_array[i].channels;
2242 if (channel_count > max_channels) {
2243 max_channels = channel_count;
2244 }
2245 }
Haynes Mathew George47cd4cb2013-07-19 11:58:50 -07002246 }
Eric Laurentb23d5282013-05-14 15:27:20 -07002247 }
Eric Laurentb23d5282013-05-14 15:27:20 -07002248 return max_channels;
2249}
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002250
2251static int platform_set_slowtalk(struct platform_data *my_data, bool state)
2252{
2253 int ret = 0;
2254 struct audio_device *adev = my_data->adev;
2255 struct mixer_ctl *ctl;
2256 const char *mixer_ctl_name = "Slowtalk Enable";
2257 uint32_t set_values[ ] = {0,
2258 ALL_SESSION_VSID};
2259
2260 set_values[0] = state;
2261 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2262 if (!ctl) {
2263 ALOGE("%s: Could not get ctl for mixer cmd - %s",
2264 __func__, mixer_ctl_name);
2265 ret = -EINVAL;
2266 } else {
2267 ALOGV("Setting slowtalk state: %d", state);
2268 ret = mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
2269 my_data->slowtalk = state;
2270 }
2271
Vidyakumar Athotad9d9ff32013-11-13 11:46:52 -08002272 if (my_data->csd != NULL) {
2273 ret = my_data->csd->slow_talk(ALL_SESSION_VSID, state);
2274 if (ret < 0) {
2275 ALOGE("%s: csd_client_disable_device, failed, error %d",
2276 __func__, ret);
2277 }
2278 }
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002279 return ret;
2280}
2281
Avinash Vaishd5fa4572014-09-15 14:41:14 +05302282static int set_hd_voice(struct platform_data *my_data, bool state)
2283{
2284 struct audio_device *adev = my_data->adev;
2285 struct mixer_ctl *ctl;
2286 char *mixer_ctl_name = "HD Voice Enable";
2287 int ret = 0;
2288 uint32_t set_values[ ] = {0,
2289 ALL_SESSION_VSID};
2290
2291 set_values[0] = state;
2292 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2293 if (!ctl) {
2294 ALOGE("%s: Could not get ctl for mixer cmd - %s",
2295 __func__, mixer_ctl_name);
2296 return -EINVAL;
2297 } else {
2298 ALOGV("Setting HD Voice state: %d", state);
2299 ret = mixer_ctl_set_array(ctl, set_values, ARRAY_SIZE(set_values));
2300 my_data->hd_voice = state;
2301 }
2302
2303 return ret;
2304}
Tanya Finkel00130052014-07-14 04:26:56 -07002305
2306static int update_external_device_status(struct platform_data *my_data,
2307 char* event_name, bool status)
2308{
2309 int ret = 0;
2310 struct audio_usecase *usecase;
2311 struct listnode *node;
2312
2313 ALOGD("Recieved external event switch %s", event_name);
2314
2315 if (!strcmp(event_name, EVENT_EXTERNAL_SPK_1))
2316 my_data->external_spk_1 = status;
2317 else if (!strcmp(event_name, EVENT_EXTERNAL_SPK_2))
2318 my_data->external_spk_2 = status;
2319 else if (!strcmp(event_name, EVENT_EXTERNAL_MIC))
2320 my_data->external_mic = status;
2321 else {
2322 ALOGE("The audio event type is not found");
2323 return -EINVAL;
2324 }
2325
2326 list_for_each(node, &my_data->adev->usecase_list) {
2327 usecase = node_to_item(node, struct audio_usecase, list);
2328 select_devices(my_data->adev, usecase->id);
2329 }
2330
2331 return ret;
2332}
2333
Ben Rombergera04fabc2014-11-14 12:16:03 -08002334static int parse_audiocal_cfg(struct str_parms *parms, acdb_audio_cal_cfg_t *cal)
2335{
2336 int err;
2337 unsigned int val;
2338 char value[64];
2339 int ret = 0;
2340
2341 if(parms == NULL || cal == NULL)
2342 return ret;
2343
2344 err = str_parms_get_str(parms, "cal_persist", value, sizeof(value));
2345 if (err >= 0) {
2346 str_parms_del(parms, "cal_persist");
2347 cal->persist = (uint32_t) strtoul(value, NULL, 0);
2348 ret = ret | 0x1;
2349 }
2350 err = str_parms_get_str(parms, "cal_apptype", value, sizeof(value));
2351 if (err >= 0) {
2352 str_parms_del(parms, "cal_apptype");
2353 cal->app_type = (uint32_t) strtoul(value, NULL, 0);
2354 ret = ret | 0x2;
2355 }
2356 err = str_parms_get_str(parms, "cal_caltype", value, sizeof(value));
2357 if (err >= 0) {
2358 str_parms_del(parms, "cal_caltype");
2359 cal->cal_type = (uint32_t) strtoul(value, NULL, 0);
2360 ret = ret | 0x4;
2361 }
2362 err = str_parms_get_str(parms, "cal_samplerate", value, sizeof(value));
2363 if (err >= 0) {
2364 str_parms_del(parms, "cal_samplerate");
2365 cal->sampling_rate = (uint32_t) strtoul(value, NULL, 0);
2366 ret = ret | 0x8;
2367 }
2368 err = str_parms_get_str(parms, "cal_devid", value, sizeof(value));
2369 if (err >= 0) {
2370 str_parms_del(parms, "cal_devid");
2371 cal->dev_id = (uint32_t) strtoul(value, NULL, 0);
2372 ret = ret | 0x10;
2373 }
2374 err = str_parms_get_str(parms, "cal_snddevid", value, sizeof(value));
2375 if (err >= 0) {
2376 str_parms_del(parms, "cal_snddevid");
2377 cal->snd_dev_id = (uint32_t) strtoul(value, NULL, 0);
2378 ret = ret | 0x20;
2379 }
2380 err = str_parms_get_str(parms, "cal_topoid", value, sizeof(value));
2381 if (err >= 0) {
2382 str_parms_del(parms, "cal_topoid");
2383 cal->topo_id = (uint32_t) strtoul(value, NULL, 0);
2384 ret = ret | 0x40;
2385 }
2386 err = str_parms_get_str(parms, "cal_moduleid", value, sizeof(value));
2387 if (err >= 0) {
2388 str_parms_del(parms, "cal_moduleid");
2389 cal->module_id = (uint32_t) strtoul(value, NULL, 0);
2390 ret = ret | 0x80;
2391 }
2392 err = str_parms_get_str(parms, "cal_paramid", value, sizeof(value));
2393 if (err >= 0) {
2394 str_parms_del(parms, "cal_paramid");
2395 cal->param_id = (uint32_t) strtoul(value, NULL, 0);
2396 ret = ret | 0x100;
2397 }
2398 return ret;
2399}
2400
2401static void set_audiocal(void *platform, struct str_parms *parms, char *value, int len) {
2402 struct platform_data *my_data = (struct platform_data *)platform;
2403 acdb_audio_cal_cfg_t cal={0};
2404 uint8_t *dptr = NULL;
2405 int32_t dlen;
2406 int err, ret;
2407 if(value == NULL || platform == NULL || parms == NULL) {
2408 ALOGE("[%s] received null pointer, failed",__func__);
2409 goto done_key_audcal;
2410 }
2411
2412 /* parse audio calibration keys */
2413 ret = parse_audiocal_cfg(parms, &cal);
2414
2415 /* handle audio calibration data now */
2416 err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_AUD_CALDATA, value, len);
2417 if (err >= 0) {
2418 str_parms_del(parms, AUDIO_PARAMETER_KEY_AUD_CALDATA);
2419 dlen = strlen(value);
2420 if(dlen <= 0) {
2421 ALOGE("[%s] null data received",__func__);
2422 goto done_key_audcal;
2423 }
2424 dptr = (uint8_t*) calloc(dlen, sizeof(uint8_t));
2425 if(dptr == NULL) {
2426 ALOGE("[%s] memory allocation failed for %d",__func__, dlen);
2427 goto done_key_audcal;
2428 }
2429 dlen = b64decode(value, strlen(value), dptr);
2430 if(dlen<=0) {
2431 ALOGE("[%s] data decoding failed %d", __func__, dlen);
2432 goto done_key_audcal;
2433 }
2434
2435 if(cal.dev_id) {
2436 if(audio_is_input_device(cal.dev_id)) {
2437 cal.snd_dev_id = platform_get_input_snd_device(platform, cal.dev_id);
2438 } else {
2439 cal.snd_dev_id = platform_get_output_snd_device(platform, cal.dev_id);
2440 }
2441 }
2442 cal.acdb_dev_id = platform_get_snd_device_acdb_id(cal.snd_dev_id);
2443 ALOGD("Setting audio calibration for snd_device(%d) acdb_id(%d)",
2444 cal.snd_dev_id, cal.acdb_dev_id);
2445 if(cal.acdb_dev_id == -EINVAL) {
2446 ALOGE("[%s] Invalid acdb_device id %d for snd device id %d",
2447 __func__, cal.acdb_dev_id, cal.snd_dev_id);
2448 goto done_key_audcal;
2449 }
2450 if(my_data->acdb_set_audio_cal) {
2451 ret = my_data->acdb_set_audio_cal((void *)&cal, (void*)dptr, dlen);
2452 }
2453 }
2454done_key_audcal:
2455 if(dptr != NULL)
2456 free(dptr);
2457}
2458
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002459int platform_set_parameters(void *platform, struct str_parms *parms)
2460{
2461 struct platform_data *my_data = (struct platform_data *)platform;
2462 char *str;
Ben Rombergera04fabc2014-11-14 12:16:03 -08002463 char *value=NULL;
2464 int val, len;
Shiv Maliyappanahalli3e064fd2013-12-16 15:54:40 -08002465 int ret = 0, err;
Krishnankutty Kolathappilly061a9492014-01-31 18:12:13 -08002466 char *kv_pairs = str_parms_to_str(parms);
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002467
Krishnankutty Kolathappilly061a9492014-01-31 18:12:13 -08002468 ALOGV_IF(kv_pairs != NULL, "%s: enter: %s", __func__, kv_pairs);
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002469
Ben Rombergera04fabc2014-11-14 12:16:03 -08002470 len = strlen(kv_pairs);
2471 value = (char*)calloc(len, sizeof(char));
2472 if(value == NULL) {
2473 ret = -ENOMEM;
2474 ALOGE("[%s] failed to allocate memory",__func__);
2475 goto done;
2476 }
2477 err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SLOWTALK, value, len);
Shiv Maliyappanahalli3e064fd2013-12-16 15:54:40 -08002478 if (err >= 0) {
Vidyakumar Athota3ade2792013-12-02 11:02:20 -08002479 bool state = false;
2480 if (!strncmp("true", value, sizeof("true"))) {
2481 state = true;
2482 }
2483
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002484 str_parms_del(parms, AUDIO_PARAMETER_KEY_SLOWTALK);
Vidyakumar Athota3ade2792013-12-02 11:02:20 -08002485 ret = platform_set_slowtalk(my_data, state);
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002486 if (ret)
2487 ALOGE("%s: Failed to set slow talk err: %d", __func__, ret);
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002488 }
2489
Ben Rombergera04fabc2014-11-14 12:16:03 -08002490 err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_HD_VOICE, value, len);
Avinash Vaishd5fa4572014-09-15 14:41:14 +05302491 if (err >= 0) {
2492 bool state = false;
2493 if (!strncmp("true", value, sizeof("true"))) {
2494 state = true;
2495 }
2496
2497 str_parms_del(parms, AUDIO_PARAMETER_KEY_HD_VOICE);
2498 if (my_data->hd_voice != state) {
2499 ret = set_hd_voice(my_data, state);
2500 if (ret)
2501 ALOGE("%s: Failed to set HD voice err: %d", __func__, ret);
2502 } else {
2503 ALOGV("%s: HD Voice already set to %d", __func__, state);
2504 }
2505 }
2506
Shiv Maliyappanahalli3e064fd2013-12-16 15:54:40 -08002507 err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_VOLUME_BOOST,
Ben Rombergera04fabc2014-11-14 12:16:03 -08002508 value, len);
Shiv Maliyappanahalli3e064fd2013-12-16 15:54:40 -08002509 if (err >= 0) {
Ben Rombergerc1dc70d2013-12-19 15:11:17 -08002510 str_parms_del(parms, AUDIO_PARAMETER_KEY_VOLUME_BOOST);
2511
2512 if (my_data->acdb_reload_vocvoltable == NULL) {
2513 ALOGE("%s: acdb_reload_vocvoltable is NULL", __func__);
2514 } else if (!strcmp(value, "on")) {
2515 if (!my_data->acdb_reload_vocvoltable(VOICE_FEATURE_SET_VOLUME_BOOST)) {
2516 my_data->voice_feature_set = 1;
2517 }
2518 } else {
2519 if (!my_data->acdb_reload_vocvoltable(VOICE_FEATURE_SET_DEFAULT)) {
2520 my_data->voice_feature_set = 0;
2521 }
2522 }
2523 }
2524
Tanya Finkel00130052014-07-14 04:26:56 -07002525 err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_EXT_AUDIO_DEVICE,
Ben Rombergera04fabc2014-11-14 12:16:03 -08002526 value, len);
Tanya Finkel00130052014-07-14 04:26:56 -07002527 if (err >= 0) {
2528 char *event_name, *status_str;
2529 bool status = false;
2530 str_parms_del(parms, AUDIO_PARAMETER_KEY_EXT_AUDIO_DEVICE);
2531 event_name = strtok_r(value, ",", &status_str);
2532 ALOGV("%s: recieved update of external audio device %s %s",
2533 __func__,
2534 event_name, status_str);
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -07002535 if (!strncmp(status_str, "ON", sizeof("ON")))
Tanya Finkel00130052014-07-14 04:26:56 -07002536 status = true;
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -07002537 else if (!strncmp(status_str, "OFF", sizeof("OFF")))
Tanya Finkel00130052014-07-14 04:26:56 -07002538 status = false;
2539 update_external_device_status(my_data, event_name, status);
2540 }
2541
Ben Rombergera04fabc2014-11-14 12:16:03 -08002542 /* handle audio calibration parameters */
2543 set_audiocal(platform, parms, value, len);
2544
2545done:
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002546 ALOGV("%s: exit with code(%d)", __func__, ret);
Krishnankutty Kolathappilly061a9492014-01-31 18:12:13 -08002547 free(kv_pairs);
Ben Rombergera04fabc2014-11-14 12:16:03 -08002548 if(value != NULL)
2549 free(value);
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002550 return ret;
2551}
2552
Vidyakumar Athota2850d532013-11-19 16:02:12 -08002553int platform_set_incall_recording_session_id(void *platform,
2554 uint32_t session_id, int rec_mode)
Shiv Maliyappanahallida107642013-10-17 11:16:13 -07002555{
2556 int ret = 0;
2557 struct platform_data *my_data = (struct platform_data *)platform;
2558 struct audio_device *adev = my_data->adev;
2559 struct mixer_ctl *ctl;
2560 const char *mixer_ctl_name = "Voc VSID";
2561 int num_ctl_values;
2562 int i;
2563
2564 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2565 if (!ctl) {
2566 ALOGE("%s: Could not get ctl for mixer cmd - %s",
2567 __func__, mixer_ctl_name);
2568 ret = -EINVAL;
2569 } else {
2570 num_ctl_values = mixer_ctl_get_num_values(ctl);
2571 for (i = 0; i < num_ctl_values; i++) {
2572 if (mixer_ctl_set_value(ctl, i, session_id)) {
2573 ALOGV("Error: invalid session_id: %x", session_id);
2574 ret = -EINVAL;
2575 break;
2576 }
2577 }
2578 }
2579
Vidyakumar Athota2850d532013-11-19 16:02:12 -08002580 if (my_data->csd != NULL) {
2581 ret = my_data->csd->start_record(ALL_SESSION_VSID, rec_mode);
2582 if (ret < 0) {
2583 ALOGE("%s: csd_client_start_record failed, error %d",
2584 __func__, ret);
2585 }
2586 }
2587
2588 return ret;
2589}
2590
2591int platform_stop_incall_recording_usecase(void *platform)
2592{
2593 int ret = 0;
2594 struct platform_data *my_data = (struct platform_data *)platform;
2595
2596 if (my_data->csd != NULL) {
2597 ret = my_data->csd->stop_record(ALL_SESSION_VSID);
2598 if (ret < 0) {
2599 ALOGE("%s: csd_client_stop_record failed, error %d",
2600 __func__, ret);
2601 }
2602 }
2603
2604 return ret;
2605}
2606
2607int platform_start_incall_music_usecase(void *platform)
2608{
2609 int ret = 0;
2610 struct platform_data *my_data = (struct platform_data *)platform;
2611
2612 if (my_data->csd != NULL) {
2613 ret = my_data->csd->start_playback(ALL_SESSION_VSID);
2614 if (ret < 0) {
2615 ALOGE("%s: csd_client_start_playback failed, error %d",
2616 __func__, ret);
2617 }
2618 }
2619
2620 return ret;
2621}
2622
2623int platform_stop_incall_music_usecase(void *platform)
2624{
2625 int ret = 0;
2626 struct platform_data *my_data = (struct platform_data *)platform;
2627
2628 if (my_data->csd != NULL) {
2629 ret = my_data->csd->stop_playback(ALL_SESSION_VSID);
2630 if (ret < 0) {
2631 ALOGE("%s: csd_client_stop_playback failed, error %d",
2632 __func__, ret);
2633 }
2634 }
2635
Shiv Maliyappanahallida107642013-10-17 11:16:13 -07002636 return ret;
2637}
2638
Vidyakumar Athota21b3bb92014-04-25 11:08:08 -07002639int platform_update_lch(void *platform, struct voice_session *session,
2640 enum voice_lch_mode lch_mode)
2641{
2642 int ret = 0;
2643 struct platform_data *my_data = (struct platform_data *)platform;
2644
2645 if ((my_data->csd != NULL) && (my_data->csd->set_lch != NULL))
2646 ret = my_data->csd->set_lch(session->vsid, lch_mode);
2647 else
2648 ret = pcm_ioctl(session->pcm_tx, SNDRV_VOICE_IOCTL_LCH, &lch_mode);
2649
2650 return ret;
2651}
2652
Ben Rombergera04fabc2014-11-14 12:16:03 -08002653static void get_audiocal(void *platform, void *keys, void *pReply) {
2654 struct platform_data *my_data = (struct platform_data *)platform;
2655 struct str_parms *query = (struct str_parms *)keys;
2656 struct str_parms *reply=(struct str_parms *)pReply;
2657 acdb_audio_cal_cfg_t cal={0};
2658 uint8_t *dptr = NULL;
2659 char value[512] = {0};
2660 char *rparms=NULL;
2661 int ret=0, err;
2662 uint32_t param_len;
2663
2664 if(query==NULL || platform==NULL || reply==NULL) {
2665 ALOGE("[%s] received null pointer",__func__);
2666 ret=-EINVAL;
2667 goto done;
2668 }
2669 /* parse audiocal configuration keys */
2670 ret = parse_audiocal_cfg(query, &cal);
2671 if(ret == 0) {
2672 /* No calibration keys found */
2673 goto done;
2674 }
2675 err = str_parms_get_str(query, AUDIO_PARAMETER_KEY_AUD_CALDATA, value, sizeof(value));
2676 if (err >= 0) {
2677 str_parms_del(query, AUDIO_PARAMETER_KEY_AUD_CALDATA);
2678 } else {
2679 goto done;
2680 }
2681
2682 if(cal.dev_id & AUDIO_DEVICE_BIT_IN) {
2683 cal.snd_dev_id = platform_get_input_snd_device(platform, cal.dev_id);
2684 } else if(cal.dev_id) {
2685 cal.snd_dev_id = platform_get_output_snd_device(platform, cal.dev_id);
2686 }
2687 cal.acdb_dev_id = platform_get_snd_device_acdb_id(cal.snd_dev_id);
2688 if (cal.acdb_dev_id < 0) {
2689 ALOGE("%s: Failed. Could not find acdb id for snd device(%d)",
2690 __func__, cal.snd_dev_id);
2691 ret = -EINVAL;
2692 goto done_key_audcal;
2693 }
2694 ALOGD("[%s] Getting audio calibration for snd_device(%d) acdb_id(%d)",
2695 __func__, cal.snd_dev_id, cal.acdb_dev_id);
2696
2697 param_len = MAX_SET_CAL_BYTE_SIZE;
2698 dptr = (uint8_t*)calloc(param_len, sizeof(uint8_t));
2699 if(dptr == NULL) {
2700 ALOGE("[%s] Memory allocation failed for length %d",__func__,param_len);
2701 ret = -ENOMEM;
2702 goto done_key_audcal;
2703 }
2704 if (my_data->acdb_get_audio_cal != NULL) {
2705 ret = my_data->acdb_get_audio_cal((void*)&cal, (void*)dptr, &param_len);
2706 if (ret == 0) {
2707 int dlen;
2708 if(param_len == 0 || param_len == MAX_SET_CAL_BYTE_SIZE) {
2709 ret = -EINVAL;
2710 goto done_key_audcal;
2711 }
2712 /* Allocate memory for encoding */
2713 rparms = (char*)calloc((param_len*2), sizeof(char));
2714 if(rparms == NULL) {
2715 ALOGE("[%s] Memory allocation failed for size %d",
2716 __func__, param_len*2);
2717 ret = -ENOMEM;
2718 goto done_key_audcal;
2719 }
2720 if(cal.persist==0 && cal.module_id && cal.param_id) {
2721 err = b64encode(dptr+12, param_len-12, rparms);
2722 } else {
2723 err = b64encode(dptr, param_len, rparms);
2724 }
2725 if(err < 0) {
2726 ALOGE("[%s] failed to convert data to string", __func__);
2727 ret = -EINVAL;
2728 goto done_key_audcal;
2729 }
2730 str_parms_add_int(reply, AUDIO_PARAMETER_KEY_AUD_CALRESULT, ret);
2731 str_parms_add_str(reply, AUDIO_PARAMETER_KEY_AUD_CALDATA, rparms);
2732 }
2733 }
2734done_key_audcal:
2735 if(ret != 0) {
2736 str_parms_add_int(reply, AUDIO_PARAMETER_KEY_AUD_CALRESULT, ret);
2737 str_parms_add_str(reply, AUDIO_PARAMETER_KEY_AUD_CALDATA, "");
2738 }
2739done:
2740 if(dptr != NULL)
2741 free(dptr);
2742 if(rparms != NULL)
2743 free(rparms);
2744}
2745
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002746void platform_get_parameters(void *platform,
2747 struct str_parms *query,
2748 struct str_parms *reply)
2749{
2750 struct platform_data *my_data = (struct platform_data *)platform;
2751 char *str = NULL;
Ben Rombergera04fabc2014-11-14 12:16:03 -08002752 char value[512] = {0};
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002753 int ret;
Krishnankutty Kolathappilly061a9492014-01-31 18:12:13 -08002754 char *kv_pairs = NULL;
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002755
Shiv Maliyappanahalli9d899292013-11-20 14:43:01 -08002756 ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_SLOWTALK,
2757 value, sizeof(value));
2758 if (ret >= 0) {
Vidyakumar Athota3ade2792013-12-02 11:02:20 -08002759 str_parms_add_str(reply, AUDIO_PARAMETER_KEY_SLOWTALK,
2760 my_data->slowtalk?"true":"false");
Shiv Maliyappanahalli9d899292013-11-20 14:43:01 -08002761 }
2762
Avinash Vaishd5fa4572014-09-15 14:41:14 +05302763 ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_HD_VOICE,
2764 value, sizeof(value));
2765 if (ret >= 0) {
2766 str_parms_add_str(reply, AUDIO_PARAMETER_KEY_HD_VOICE,
2767 my_data->hd_voice?"true":"false");
2768 }
2769
Ben Rombergerc1dc70d2013-12-19 15:11:17 -08002770 ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_VOLUME_BOOST,
2771 value, sizeof(value));
2772 if (ret >= 0) {
2773 if (my_data->voice_feature_set == VOICE_FEATURE_SET_VOLUME_BOOST) {
2774 strlcpy(value, "on", sizeof(value));
2775 } else {
2776 strlcpy(value, "off", sizeof(value));
2777 }
2778
2779 str_parms_add_str(reply, AUDIO_PARAMETER_KEY_VOLUME_BOOST, value);
2780 }
2781
Ben Rombergera04fabc2014-11-14 12:16:03 -08002782 /* Handle audio calibration keys */
2783 get_audiocal(platform, query, reply);
2784
2785done:
Krishnankutty Kolathappilly061a9492014-01-31 18:12:13 -08002786 kv_pairs = str_parms_to_str(reply);
2787 ALOGV_IF(kv_pairs != NULL, "%s: exit: returns - %s", __func__, kv_pairs);
Narsinga Rao Chellacde45d12014-02-13 11:44:31 -08002788 free(kv_pairs);
Shiv Maliyappanahalli34b585f2013-10-01 15:49:05 -07002789}
2790
Haynes Mathew George7ff216f2013-09-11 19:51:41 -07002791/* Delay in Us */
2792int64_t platform_render_latency(audio_usecase_t usecase)
2793{
2794 switch (usecase) {
2795 case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
2796 return DEEP_BUFFER_PLATFORM_DELAY;
2797 case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
2798 return LOW_LATENCY_PLATFORM_DELAY;
2799 default:
2800 return 0;
2801 }
2802}
Preetam Singh Ranawatde84f1a2013-11-01 14:58:16 -07002803
Mingming Yine62d7842013-10-25 16:26:03 -07002804int platform_update_usecase_from_source(int source, int usecase)
Preetam Singh Ranawatde84f1a2013-11-01 14:58:16 -07002805{
Mingming Yinab429782013-11-07 11:16:55 -08002806 ALOGV("%s: input source :%d", __func__, source);
2807 if(source == AUDIO_SOURCE_FM_RX_A2DP)
Mingming Yine62d7842013-10-25 16:26:03 -07002808 usecase = USECASE_AUDIO_RECORD_FM_VIRTUAL;
2809 return usecase;
Preetam Singh Ranawatde84f1a2013-11-01 14:58:16 -07002810}
Kiran Kandide144c82013-11-20 15:58:32 -08002811
Dhananjay Kumar45b71742014-05-29 21:47:27 +05302812bool platform_listen_device_needs_event(snd_device_t snd_device)
Kiran Kandide144c82013-11-20 15:58:32 -08002813{
Dhananjay Kumar45b71742014-05-29 21:47:27 +05302814 bool needs_event = false;
2815
Kiran Kandide144c82013-11-20 15:58:32 -08002816 if ((snd_device >= SND_DEVICE_IN_BEGIN) &&
2817 (snd_device < SND_DEVICE_IN_END) &&
2818 (snd_device != SND_DEVICE_IN_CAPTURE_FM) &&
2819 (snd_device != SND_DEVICE_IN_CAPTURE_VI_FEEDBACK))
Dhananjay Kumar45b71742014-05-29 21:47:27 +05302820 needs_event = true;
2821
2822 return needs_event;
2823}
2824
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -07002825bool platform_listen_usecase_needs_event(audio_usecase_t uc_id __unused)
2826{
2827 return false;
2828}
2829
2830bool platform_sound_trigger_device_needs_event(snd_device_t snd_device)
2831{
2832 bool needs_event = false;
2833
2834 if ((snd_device >= SND_DEVICE_IN_BEGIN) &&
2835 (snd_device < SND_DEVICE_IN_END) &&
2836 (snd_device != SND_DEVICE_IN_CAPTURE_FM) &&
2837 (snd_device != SND_DEVICE_IN_CAPTURE_VI_FEEDBACK))
2838 needs_event = true;
2839
2840 return needs_event;
2841}
2842
2843bool platform_sound_trigger_usecase_needs_event(audio_usecase_t uc_id __unused)
Dhananjay Kumar45b71742014-05-29 21:47:27 +05302844{
2845 return false;
Kiran Kandide144c82013-11-20 15:58:32 -08002846}
ApurupaPattapuc6a3a9e2014-01-10 14:46:02 -08002847
2848/* Read offload buffer size from a property.
2849 * If value is not power of 2 round it to
2850 * power of 2.
2851 */
2852uint32_t platform_get_compress_offload_buffer_size(audio_offload_info_t* info)
2853{
2854 char value[PROPERTY_VALUE_MAX] = {0};
2855 uint32_t fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE;
2856 if((property_get("audio.offload.buffer.size.kb", value, "")) &&
2857 atoi(value)) {
2858 fragment_size = atoi(value) * 1024;
2859 }
2860
Mingming Yin3ee55c62014-08-04 14:23:35 -07002861 // For FLAC use max size since it is loss less, and has sampling rates
2862 // upto 192kHZ
2863 if (info != NULL && !info->has_video &&
2864 info->format == AUDIO_FORMAT_FLAC) {
2865 fragment_size = MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE;
2866 ALOGV("FLAC fragment size %d", fragment_size);
2867 }
2868
ApurupaPattapuc6a3a9e2014-01-10 14:46:02 -08002869 if (info != NULL && info->has_video && info->is_streaming) {
2870 fragment_size = COMPRESS_OFFLOAD_FRAGMENT_SIZE_FOR_AV_STREAMING;
2871 ALOGV("%s: offload fragment size reduced for AV streaming to %d",
ApurupaPattapu31d09d72014-03-05 11:13:32 -08002872 __func__, fragment_size);
ApurupaPattapuc6a3a9e2014-01-10 14:46:02 -08002873 }
2874
2875 fragment_size = ALIGN( fragment_size, 1024);
2876
2877 if(fragment_size < MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE)
2878 fragment_size = MIN_COMPRESS_OFFLOAD_FRAGMENT_SIZE;
2879 else if(fragment_size > MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE)
2880 fragment_size = MAX_COMPRESS_OFFLOAD_FRAGMENT_SIZE;
2881 ALOGV("%s: fragment_size %d", __func__, fragment_size);
2882 return fragment_size;
2883}
2884
2885uint32_t platform_get_pcm_offload_buffer_size(audio_offload_info_t* info)
2886{
2887 uint32_t fragment_size = MIN_PCM_OFFLOAD_FRAGMENT_SIZE;
2888 uint32_t bits_per_sample = 16;
2889
2890 if (info->format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD) {
2891 bits_per_sample = 32;
2892 }
2893
2894 if (!info->has_video) {
2895 fragment_size = MAX_PCM_OFFLOAD_FRAGMENT_SIZE;
2896
2897 } else if (info->has_video && info->is_streaming) {
2898 fragment_size = (PCM_OFFLOAD_BUFFER_DURATION_FOR_AV_STREAMING
2899 * info->sample_rate
ApurupaPattapub57da782014-04-08 10:41:07 -07002900 * (bits_per_sample >> 3)
ApurupaPattapuc6a3a9e2014-01-10 14:46:02 -08002901 * popcount(info->channel_mask))/1000;
2902
2903 } else if (info->has_video) {
2904 fragment_size = (PCM_OFFLOAD_BUFFER_DURATION_FOR_AV
2905 * info->sample_rate
ApurupaPattapub57da782014-04-08 10:41:07 -07002906 * (bits_per_sample >> 3)
ApurupaPattapuc6a3a9e2014-01-10 14:46:02 -08002907 * popcount(info->channel_mask))/1000;
2908 }
2909
ApurupaPattapub57da782014-04-08 10:41:07 -07002910 char value[PROPERTY_VALUE_MAX] = {0};
2911 if((property_get("audio.offload.pcm.buffer.size", value, "")) &&
2912 atoi(value)) {
2913 fragment_size = atoi(value) * 1024;
2914 ALOGV("Using buffer size from sys prop %d", fragment_size);
2915 }
2916
ApurupaPattapuc6a3a9e2014-01-10 14:46:02 -08002917 fragment_size = ALIGN( fragment_size, 1024);
2918
2919 if(fragment_size < MIN_PCM_OFFLOAD_FRAGMENT_SIZE)
2920 fragment_size = MIN_PCM_OFFLOAD_FRAGMENT_SIZE;
2921 else if(fragment_size > MAX_PCM_OFFLOAD_FRAGMENT_SIZE)
2922 fragment_size = MAX_PCM_OFFLOAD_FRAGMENT_SIZE;
2923
2924 ALOGV("%s: fragment_size %d", __func__, fragment_size);
2925 return fragment_size;
2926}
2927
Mingming Yin3ee55c62014-08-04 14:23:35 -07002928int platform_set_codec_backend_cfg(struct audio_device* adev,
2929 unsigned int bit_width, unsigned int sample_rate)
2930{
Amit Shekhared7fb5c2014-08-01 17:18:53 -07002931 ALOGV("%s bit width: %d, sample rate: %d", __func__, bit_width, sample_rate);
Mingming Yin3ee55c62014-08-04 14:23:35 -07002932
2933 int ret = 0;
2934 if (bit_width != adev->cur_codec_backend_bit_width) {
2935 const char * mixer_ctl_name = "SLIM_0_RX Format";
2936 struct mixer_ctl *ctl;
2937 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2938 if (!ctl) {
2939 ALOGE("%s: Could not get ctl for mixer command - %s",
2940 __func__, mixer_ctl_name);
2941 return -EINVAL;
2942 }
2943
2944 if (bit_width == 24) {
2945 mixer_ctl_set_enum_by_string(ctl, "S24_LE");
2946 } else {
2947 mixer_ctl_set_enum_by_string(ctl, "S16_LE");
2948 sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
2949 }
2950 adev->cur_codec_backend_bit_width = bit_width;
2951 ALOGE("Backend bit width is set to %d ", bit_width);
2952 }
2953
Amit Shekhared7fb5c2014-08-01 17:18:53 -07002954 /*
2955 * Backend sample rate configuration follows:
2956 * 16 bit playback - 48khz for streams at any valid sample rate
2957 * 24 bit playback - 48khz for stream sample rate less than 48khz
2958 * 24 bit playback - 96khz for sample rate range of 48khz to 96khz
2959 * 24 bit playback - 192khz for sample rate range of 96khz to 192 khz
2960 * Upper limit is inclusive in the sample rate range.
2961 */
2962 // TODO: This has to be more dynamic based on policy file
2963 if (sample_rate != adev->cur_codec_backend_samplerate) {
Mingming Yin3ee55c62014-08-04 14:23:35 -07002964 char *rate_str = NULL;
2965 const char * mixer_ctl_name = "SLIM_0_RX SampleRate";
2966 struct mixer_ctl *ctl;
2967
2968 switch (sample_rate) {
2969 case 8000:
Mingming Yin3ee55c62014-08-04 14:23:35 -07002970 case 11025:
Mingming Yin3ee55c62014-08-04 14:23:35 -07002971 case 16000:
Mingming Yin3ee55c62014-08-04 14:23:35 -07002972 case 22050:
Mingming Yin3ee55c62014-08-04 14:23:35 -07002973 case 32000:
Mingming Yin3ee55c62014-08-04 14:23:35 -07002974 case 44100:
Mingming Yin3ee55c62014-08-04 14:23:35 -07002975 case 48000:
2976 rate_str = "KHZ_48";
2977 break;
2978 case 64000:
Mingming Yin3ee55c62014-08-04 14:23:35 -07002979 case 88200:
Mingming Yin3ee55c62014-08-04 14:23:35 -07002980 case 96000:
2981 rate_str = "KHZ_96";
2982 break;
2983 case 176400:
Mingming Yin3ee55c62014-08-04 14:23:35 -07002984 case 192000:
2985 rate_str = "KHZ_192";
2986 break;
2987 default:
2988 rate_str = "KHZ_48";
2989 break;
2990 }
2991
2992 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
2993 if(!ctl) {
2994 ALOGE("%s: Could not get ctl for mixer command - %s",
2995 __func__, mixer_ctl_name);
2996 return -EINVAL;
2997 }
2998
2999 ALOGV("Set sample rate as rate_str = %s", rate_str);
3000 mixer_ctl_set_enum_by_string(ctl, rate_str);
3001 adev->cur_codec_backend_samplerate = sample_rate;
3002 }
3003
3004 return ret;
3005}
3006
3007bool platform_check_codec_backend_cfg(struct audio_device* adev,
Ravi Kumar Alamandabdf14162014-09-05 16:14:17 -07003008 struct audio_usecase* usecase __unused,
Mingming Yin3ee55c62014-08-04 14:23:35 -07003009 unsigned int* new_bit_width,
3010 unsigned int* new_sample_rate)
3011{
3012 bool backend_change = false;
3013 struct listnode *node;
3014 struct stream_out *out = NULL;
Amit Shekhar278e3362014-09-08 14:08:19 -07003015 unsigned int bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
3016 unsigned int sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
Mingming Yin3ee55c62014-08-04 14:23:35 -07003017
3018 // For voice calls use default configuration
3019 // force routing is not required here, caller will do it anyway
Narsinga Rao Chella44376cc2014-10-24 13:27:14 -07003020 if (voice_is_in_call(adev) || adev->mode == AUDIO_MODE_IN_COMMUNICATION) {
Mingming Yin3ee55c62014-08-04 14:23:35 -07003021 ALOGW("%s:Use default bw and sr for voice/voip calls ",__func__);
Narsinga Rao Chella44376cc2014-10-24 13:27:14 -07003022 bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
3023 sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
3024 } else {
3025 /*
3026 * The backend should be configured at highest bit width and/or
3027 * sample rate amongst all playback usecases.
3028 * If the selected sample rate and/or bit width differ with
3029 * current backend sample rate and/or bit width, then, we set the
3030 * backend re-configuration flag.
3031 *
3032 * Exception: 16 bit playbacks is allowed through 16 bit/48 khz backend only
3033 */
Mingming Yin3ee55c62014-08-04 14:23:35 -07003034 list_for_each(node, &adev->usecase_list) {
3035 struct audio_usecase *curr_usecase;
3036 curr_usecase = node_to_item(node, struct audio_usecase, list);
Amit Shekhared7fb5c2014-08-01 17:18:53 -07003037 if (curr_usecase->type == PCM_PLAYBACK) {
Mingming Yin3ee55c62014-08-04 14:23:35 -07003038 struct stream_out *out =
3039 (struct stream_out*) curr_usecase->stream.out;
3040 if (out != NULL ) {
3041 ALOGV("Offload playback running bw %d sr %d",
3042 out->bit_width, out->sample_rate);
Amit Shekhar278e3362014-09-08 14:08:19 -07003043 if (bit_width < out->bit_width)
3044 bit_width = out->bit_width;
3045 if (sample_rate < out->sample_rate)
3046 sample_rate = out->sample_rate;
Mingming Yin3ee55c62014-08-04 14:23:35 -07003047 }
3048 }
3049 }
3050 }
3051
Amit Shekhar5a39c912014-10-14 15:39:30 -07003052 // 16 bit playback on speakers is allowed through 48 khz backend only
3053 if (16 == bit_width) {
3054 sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
3055 }
3056 // 24 bit playback on speakers is allowed through 48 khz backend only
3057 // bit width re-configured based on platform info
3058 if ((24 == bit_width) &&
3059 (usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER)) {
3060 bit_width = (uint32_t)platform_get_snd_device_bit_width(SND_DEVICE_OUT_SPEAKER);
Amit Shekhar278e3362014-09-08 14:08:19 -07003061 sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
Preetam Singh Ranawata4a37d82014-09-25 16:56:38 +05303062 }
Mingming Yin3ee55c62014-08-04 14:23:35 -07003063 // Force routing if the expected bitwdith or samplerate
3064 // is not same as current backend comfiguration
Amit Shekhar278e3362014-09-08 14:08:19 -07003065 if ((bit_width != adev->cur_codec_backend_bit_width) ||
3066 (sample_rate != adev->cur_codec_backend_samplerate)) {
3067 *new_bit_width = bit_width;
3068 *new_sample_rate = sample_rate;
Mingming Yin3ee55c62014-08-04 14:23:35 -07003069 backend_change = true;
Amit Shekhar278e3362014-09-08 14:08:19 -07003070 ALOGI("%s Codec backend needs to be updated. new bit width: %d new sample rate: %d",
3071 __func__, *new_bit_width, *new_sample_rate);
Mingming Yin3ee55c62014-08-04 14:23:35 -07003072 }
3073
3074 return backend_change;
3075}
3076
3077bool platform_check_and_set_codec_backend_cfg(struct audio_device* adev, struct audio_usecase *usecase)
3078{
Mingming Yin3ee55c62014-08-04 14:23:35 -07003079 ALOGV("platform_check_and_set_codec_backend_cfg usecase = %d",usecase->id );
3080
3081 unsigned int new_bit_width, old_bit_width;
3082 unsigned int new_sample_rate, old_sample_rate;
3083
3084 new_bit_width = old_bit_width = adev->cur_codec_backend_bit_width;
3085 new_sample_rate = old_sample_rate = adev->cur_codec_backend_samplerate;
3086
3087 ALOGW("Codec backend bitwidth %d, samplerate %d", old_bit_width, old_sample_rate);
3088 if (platform_check_codec_backend_cfg(adev, usecase,
3089 &new_bit_width, &new_sample_rate)) {
3090 platform_set_codec_backend_cfg(adev, new_bit_width, new_sample_rate);
Mingming Yin3ee55c62014-08-04 14:23:35 -07003091 return true;
3092 }
3093
3094 return false;
3095}
Haynes Mathew Georgef4da6fe2014-06-20 19:14:25 -07003096
3097int platform_set_snd_device_backend(snd_device_t device, const char *backend)
3098{
3099 int ret = 0;
3100
3101 if ((device < SND_DEVICE_MIN) || (device >= SND_DEVICE_MAX)) {
3102 ALOGE("%s: Invalid snd_device = %d",
3103 __func__, device);
3104 ret = -EINVAL;
3105 goto done;
3106 }
3107
3108 if (backend_table[device]) {
3109 free(backend_table[device]);
3110 }
3111 backend_table[device] = strdup(backend);
3112done:
3113 return ret;
3114}
3115
3116int platform_set_usecase_pcm_id(audio_usecase_t usecase, int32_t type, int32_t pcm_id)
3117{
3118 int ret = 0;
3119 if ((usecase <= USECASE_INVALID) || (usecase >= AUDIO_USECASE_MAX)) {
3120 ALOGE("%s: invalid usecase case idx %d", __func__, usecase);
3121 ret = -EINVAL;
3122 goto done;
3123 }
3124
3125 if ((type != 0) && (type != 1)) {
3126 ALOGE("%s: invalid usecase type", __func__);
3127 ret = -EINVAL;
3128 }
3129 pcm_device_table[usecase][type] = pcm_id;
3130done:
3131 return ret;
3132}
Pradnya Chaphekar8a9dcd82014-09-09 09:49:10 -07003133
3134void platform_get_device_to_be_id_map(int **device_to_be_id, int *length)
3135{
3136 *device_to_be_id = msm_device_to_be_id;
3137 *length = msm_be_id_array_len;
3138}
Pradnya Chaphekar4403bd72014-09-09 09:50:01 -07003139
3140int platform_set_stream_channel_map(void *platform, audio_channel_mask_t channel_mask, int snd_id)
3141{
3142 int ret = 0;
3143 int channels = audio_channel_count_from_out_mask(channel_mask);
3144
3145 char channel_map[8];
3146 memset(channel_map, 0, sizeof(channel_map));
3147 /* Following are all most common standard WAV channel layouts
3148 overridden by channel mask if its allowed and different */
3149 switch (channels) {
3150 case 1:
3151 /* AUDIO_CHANNEL_OUT_MONO */
3152 channel_map[0] = PCM_CHANNEL_FC;
3153 case 2:
3154 /* AUDIO_CHANNEL_OUT_STEREO */
3155 channel_map[0] = PCM_CHANNEL_FL;
3156 channel_map[1] = PCM_CHANNEL_FR;
3157 case 3:
3158 /* AUDIO_CHANNEL_OUT_2POINT1 */
3159 channel_map[0] = PCM_CHANNEL_FL;
3160 channel_map[1] = PCM_CHANNEL_FR;
3161 channel_map[2] = PCM_CHANNEL_FC;
3162 break;
3163 case 4:
3164 /* AUDIO_CHANNEL_OUT_QUAD_SIDE */
3165 channel_map[0] = PCM_CHANNEL_FL;
3166 channel_map[1] = PCM_CHANNEL_FR;
3167 channel_map[2] = PCM_CHANNEL_LS;
3168 channel_map[3] = PCM_CHANNEL_RS;
3169 if (channel_mask == AUDIO_CHANNEL_OUT_QUAD_BACK)
3170 {
3171 channel_map[2] = PCM_CHANNEL_LB;
3172 channel_map[3] = PCM_CHANNEL_RB;
3173 }
3174 if (channel_mask == AUDIO_CHANNEL_OUT_SURROUND)
3175 {
3176 channel_map[2] = PCM_CHANNEL_FC;
3177 channel_map[3] = PCM_CHANNEL_CS;
3178 }
3179 break;
3180 case 5:
3181 /* AUDIO_CHANNEL_OUT_PENTA */
3182 channel_map[0] = PCM_CHANNEL_FL;
3183 channel_map[1] = PCM_CHANNEL_FR;
3184 channel_map[2] = PCM_CHANNEL_FC;
3185 channel_map[3] = PCM_CHANNEL_LB;
3186 channel_map[4] = PCM_CHANNEL_RB;
3187 break;
3188 case 6:
3189 /* AUDIO_CHANNEL_OUT_5POINT1 */
3190 channel_map[0] = PCM_CHANNEL_FL;
3191 channel_map[1] = PCM_CHANNEL_FR;
3192 channel_map[2] = PCM_CHANNEL_FC;
3193 channel_map[3] = PCM_CHANNEL_LFE;
3194 channel_map[4] = PCM_CHANNEL_LB;
3195 channel_map[5] = PCM_CHANNEL_RB;
3196 if (channel_mask == AUDIO_CHANNEL_OUT_5POINT1_SIDE)
3197 {
3198 channel_map[4] = PCM_CHANNEL_LS;
3199 channel_map[5] = PCM_CHANNEL_RS;
3200 }
3201 break;
3202 case 7:
3203 /* AUDIO_CHANNEL_OUT_6POINT1 */
3204 channel_map[0] = PCM_CHANNEL_FL;
3205 channel_map[1] = PCM_CHANNEL_FR;
3206 channel_map[2] = PCM_CHANNEL_FC;
3207 channel_map[3] = PCM_CHANNEL_LFE;
3208 channel_map[4] = PCM_CHANNEL_LB;
3209 channel_map[5] = PCM_CHANNEL_RB;
3210 channel_map[6] = PCM_CHANNEL_CS;
3211 case 8:
3212 /* AUDIO_CHANNEL_OUT_7POINT1 */
3213 channel_map[0] = PCM_CHANNEL_FL;
3214 channel_map[1] = PCM_CHANNEL_FR;
3215 channel_map[2] = PCM_CHANNEL_FC;
3216 channel_map[3] = PCM_CHANNEL_LFE;
3217 channel_map[4] = PCM_CHANNEL_LB;
3218 channel_map[5] = PCM_CHANNEL_RB;
3219 channel_map[6] = PCM_CHANNEL_LS;
3220 channel_map[7] = PCM_CHANNEL_RS;
3221 break;
3222 default:
3223 ALOGE("unsupported channels %d for setting channel map", channels);
3224 return -1;
3225 }
3226 ret = platform_set_channel_map(platform, channels, channel_map, snd_id);
3227 return ret;
3228}
3229
3230int platform_get_edid_info(void *platform)
3231{
3232 struct platform_data *my_data = (struct platform_data *)platform;
3233 struct audio_device *adev = my_data->adev;
3234 char block[MAX_SAD_BLOCKS * SAD_BLOCK_SIZE];
3235 char *sad = block;
3236 int num_audio_blocks;
3237 int channel_count = 2;
3238 int i, ret, count;
3239
3240 struct mixer_ctl *ctl;
3241 char edid_data[MAX_SAD_BLOCKS * SAD_BLOCK_SIZE + 1] = {0};
3242 edid_audio_info *info;
3243
3244 if (my_data->edid_valid) {
3245 /* use cached edid */
3246 return 0;
3247 }
3248
3249 if (my_data->edid_info == NULL) {
3250 my_data->edid_info =
3251 (struct edid_audio_info *)calloc(1, sizeof(struct edid_audio_info));
3252 }
3253
3254 info = my_data->edid_info;
3255
3256 ctl = mixer_get_ctl_by_name(adev->mixer, AUDIO_DATA_BLOCK_MIXER_CTL);
3257 if (!ctl) {
3258 ALOGE("%s: Could not get ctl for mixer cmd - %s",
3259 __func__, AUDIO_DATA_BLOCK_MIXER_CTL);
3260 goto fail;
3261 }
3262
3263 mixer_ctl_update(ctl);
3264
3265 count = mixer_ctl_get_num_values(ctl);
3266
3267 /* Read SAD blocks, clamping the maximum size for safety */
3268 if (count > (int)sizeof(block))
3269 count = (int)sizeof(block);
3270
3271 ret = mixer_ctl_get_array(ctl, block, count);
3272 if (ret != 0) {
3273 ALOGE("%s: mixer_ctl_get_array() failed to get EDID info", __func__);
3274 goto fail;
3275 }
3276 edid_data[0] = count;
3277 memcpy(&edid_data[1], block, count);
3278
3279 if (!edid_get_sink_caps(info, edid_data)) {
3280 ALOGE("%s: Failed to get HDMI sink capabilities", __func__);
3281 goto fail;
3282 }
3283 my_data->edid_valid = true;
3284 return 0;
3285fail:
3286 if (my_data->edid_info) {
3287 free(my_data->edid_info);
3288 my_data->edid_info = NULL;
3289 my_data->edid_valid = false;
3290 }
3291 ALOGE("%s: return -EINVAL", __func__);
3292 return -EINVAL;
3293}
3294
3295
3296int platform_set_channel_allocation(void *platform, int channel_alloc)
3297{
3298 struct mixer_ctl *ctl;
3299 const char *mixer_ctl_name = "HDMI RX CA";
3300 int ret;
3301 struct platform_data *my_data = (struct platform_data *)platform;
3302 struct audio_device *adev = my_data->adev;
3303
3304 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
3305 if (!ctl) {
3306 ALOGE("%s: Could not get ctl for mixer cmd - %s",
3307 __func__, mixer_ctl_name);
3308 ret = EINVAL;
3309 }
3310 ALOGD(":%s channel allocation = 0x%x", __func__, channel_alloc);
3311 ret = mixer_ctl_set_value(ctl, 0, channel_alloc);
3312
3313 if (ret < 0) {
3314 ALOGE("%s: Could not set ctl, error:%d ", __func__, ret);
3315 }
3316
3317 return ret;
3318}
3319
3320int platform_set_channel_map(void *platform, int ch_count, char *ch_map, int snd_id)
3321{
3322 struct mixer_ctl *ctl;
3323 char mixer_ctl_name[44]; // max length of name is 44 as defined
3324 int ret;
3325 unsigned int i;
3326 int set_values[8] = {0};
3327 char device_num[13]; // device number up to 2 digit
3328 struct platform_data *my_data = (struct platform_data *)platform;
3329 struct audio_device *adev = my_data->adev;
3330 ALOGV("%s channel_count:%d",__func__, ch_count);
3331 if (NULL == ch_map) {
3332 ALOGE("%s: Invalid channel mapping used", __func__);
3333 return -EINVAL;
3334 }
3335 strlcpy(mixer_ctl_name, "Playback Channel Map", sizeof(mixer_ctl_name));
3336 if (snd_id >= 0) {
3337 snprintf(device_num, sizeof(device_num), "%d", snd_id);
3338 strncat(mixer_ctl_name, device_num, 13);
3339 }
3340
3341 ALOGD("%s mixer_ctl_name:%s", __func__, mixer_ctl_name);
3342
3343 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
3344 if (!ctl) {
3345 ALOGE("%s: Could not get ctl for mixer cmd - %s",
3346 __func__, mixer_ctl_name);
3347 return -EINVAL;
3348 }
3349 for (i = 0; i< ARRAY_SIZE(set_values); i++) {
3350 set_values[i] = ch_map[i];
3351 }
3352
3353 ALOGD("%s: set mapping(%d %d %d %d %d %d %d %d) for channel:%d", __func__,
3354 set_values[0], set_values[1], set_values[2], set_values[3], set_values[4],
3355 set_values[5], set_values[6], set_values[7], ch_count);
3356
3357 ret = mixer_ctl_set_array(ctl, set_values, ch_count);
3358 if (ret < 0) {
3359 ALOGE("%s: Could not set ctl, error:%d ch_count:%d",
3360 __func__, ret, ch_count);
3361 }
3362 return ret;
3363}
3364
3365unsigned char platform_map_to_edid_format(int audio_format)
3366{
3367
3368 unsigned char format;
3369 switch (audio_format & AUDIO_FORMAT_MAIN_MASK) {
3370 case AUDIO_FORMAT_AC3:
3371 ALOGV("%s: AC3", __func__);
3372 format = AC3;
3373 break;
3374 case AUDIO_FORMAT_AAC:
3375 ALOGV("%s:AAC", __func__);
3376 format = AAC;
3377 break;
3378 case AUDIO_FORMAT_E_AC3:
3379 ALOGV("%s:E_AC3", __func__);
3380 format = DOLBY_DIGITAL_PLUS;
3381 break;
3382 case AUDIO_FORMAT_PCM_16_BIT:
3383 default:
3384 ALOGV("%s:PCM", __func__);
3385 format = LPCM;
3386 break;
3387 }
3388 return format;
3389}
3390
3391bool platform_is_edid_supported_format(void *platform, int format)
3392{
3393 struct platform_data *my_data = (struct platform_data *)platform;
3394 struct audio_device *adev = my_data->adev;
3395 edid_audio_info *info = NULL;
3396 int num_audio_blocks;
3397 int i, ret, count;
3398 unsigned char format_id = platform_map_to_edid_format(format);
3399
3400 ret = platform_get_edid_info(platform);
3401 info = (edid_audio_info *)my_data->edid_info;
3402 if (ret == 0 && info != NULL) {
3403 for (i = 0; i < info->audio_blocks && i < MAX_EDID_BLOCKS; i++) {
3404 if (info->audio_blocks_array[i].format_id == format_id)
3405 ALOGV("%s:platform_is_edid_supported_format true %x",
3406 __func__, format);
3407 return true;
3408 }
3409 }
3410 ALOGV("%s:platform_is_edid_supported_format false %x",
3411 __func__, format);
3412 return false;
3413}
3414
3415int platform_set_edid_channels_configuration(void *platform, int channels) {
3416
3417 struct platform_data *my_data = (struct platform_data *)platform;
3418 struct audio_device *adev = my_data->adev;
3419 edid_audio_info *info = NULL;
3420 int num_audio_blocks;
3421 int channel_count = 2;
3422 int i, ret, count;
3423 char default_channelMap[MAX_CHANNELS_SUPPORTED] = {0};
3424
3425 ret = platform_get_edid_info(platform);
3426 info = (edid_audio_info *)my_data->edid_info;
3427 if(ret == 0 && info != NULL) {
3428 if (channels > 2) {
3429
3430 ALOGV("%s:able to get HDMI sink capabilities multi channel playback",
3431 __func__);
3432 for (i = 0; i < info->audio_blocks && i < MAX_EDID_BLOCKS; i++) {
3433 if (info->audio_blocks_array[i].format_id == LPCM &&
3434 info->audio_blocks_array[i].channels > channel_count &&
3435 info->audio_blocks_array[i].channels <= MAX_HDMI_CHANNEL_CNT) {
3436 channel_count = info->audio_blocks_array[i].channels;
3437 }
3438 }
3439 ALOGVV("%s:channel_count:%d", __func__, channel_count);
3440 /*
3441 * Channel map is set for supported hdmi max channel count even
3442 * though the input channel count set on adm is less than or equal to
3443 * max supported channel count
3444 */
3445 platform_set_channel_map(platform, channel_count, info->channel_map, -1);
3446 platform_set_channel_allocation(platform, info->channel_allocation);
3447 } else {
3448 default_channelMap[0] = PCM_CHANNEL_FL;
3449 default_channelMap[1] = PCM_CHANNEL_FR;
3450 platform_set_channel_map(platform,2,default_channelMap,-1);
3451 platform_set_channel_allocation(platform,0);
3452 }
3453 }
3454
3455 return 0;
3456}
3457
3458void platform_cache_edid(void * platform)
3459{
3460 platform_get_edid_info(platform);
3461}
3462
3463void platform_invalidate_edid(void * platform)
3464{
3465 struct platform_data *my_data = (struct platform_data *)platform;
3466 my_data->edid_valid = false;
3467 if (my_data->edid_info) {
3468 memset(my_data->edid_info, 0, sizeof(struct edid_audio_info));
3469 }
3470}