blob: 50c6490ac8ea46dca238431fe9772acd2ce63bb5 [file] [log] [blame]
Eric Laurentb23d5282013-05-14 15:27:20 -07001/*
Vineeta Srivastava4b89e372014-06-19 14:21:42 -07002 * Copyright (C) 2013-2014 The Android Open Source Project
Eric Laurentb23d5282013-05-14 15:27:20 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "msm8960_platform"
18/*#define LOG_NDEBUG 0*/
19#define LOG_NDDEBUG 0
20
21#include <stdlib.h>
22#include <dlfcn.h>
23#include <cutils/log.h>
24#include <cutils/properties.h>
25#include <audio_hw.h>
26#include <platform_api.h>
27#include "platform.h"
28
29#define LIB_ACDB_LOADER "libacdbloader.so"
30#define LIB_CSD_CLIENT "libcsd-client.so"
31
32#define DUALMIC_CONFIG_NONE 0 /* Target does not contain 2 mics */
33#define DUALMIC_CONFIG_ENDFIRE 1
34#define DUALMIC_CONFIG_BROADSIDE 2
35
36/*
37 * This is the sysfs path for the HDMI audio data block
38 */
39#define AUDIO_DATA_BLOCK_PATH "/sys/class/graphics/fb1/audio_data_block"
sangwoo1b9f4b32013-06-21 18:22:55 -070040#define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
Eric Laurentb23d5282013-05-14 15:27:20 -070041
42/*
43 * This file will have a maximum of 38 bytes:
44 *
45 * 4 bytes: number of audio blocks
46 * 4 bytes: total length of Short Audio Descriptor (SAD) blocks
47 * Maximum 10 * 3 bytes: SAD blocks
48 */
49#define MAX_SAD_BLOCKS 10
50#define SAD_BLOCK_SIZE 3
51
52/* EDID format ID for LPCM audio */
53#define EDID_FORMAT_LPCM 1
54
55struct audio_block_header
56{
57 int reserved;
58 int length;
59};
60
61
62typedef void (*acdb_deallocate_t)();
63typedef int (*acdb_init_t)();
64typedef void (*acdb_send_audio_cal_t)(int, int);
65typedef void (*acdb_send_voice_cal_t)(int, int);
66
67typedef int (*csd_client_init_t)();
68typedef int (*csd_client_deinit_t)();
69typedef int (*csd_disable_device_t)();
70typedef int (*csd_enable_device_t)(int, int, uint32_t);
71typedef int (*csd_volume_t)(int);
72typedef int (*csd_mic_mute_t)(int);
73typedef int (*csd_start_voice_t)();
74typedef int (*csd_stop_voice_t)();
75
76
77/* Audio calibration related functions */
78struct platform_data {
79 struct audio_device *adev;
80 bool fluence_in_spkr_mode;
81 bool fluence_in_voice_call;
82 bool fluence_in_voice_rec;
83 int dualmic_config;
Ravi Kumar Alamanda1f60cf82015-04-23 19:45:17 -070084 bool speaker_lr_swap;
Eric Laurentb23d5282013-05-14 15:27:20 -070085
86 void *acdb_handle;
87 acdb_init_t acdb_init;
88 acdb_deallocate_t acdb_deallocate;
89 acdb_send_audio_cal_t acdb_send_audio_cal;
90 acdb_send_voice_cal_t acdb_send_voice_cal;
91
92 /* CSD Client related functions for voice call */
93 void *csd_client;
94 csd_client_init_t csd_client_init;
95 csd_client_deinit_t csd_client_deinit;
96 csd_disable_device_t csd_disable_device;
97 csd_enable_device_t csd_enable_device;
98 csd_volume_t csd_volume;
99 csd_mic_mute_t csd_mic_mute;
100 csd_start_voice_t csd_start_voice;
101 csd_stop_voice_t csd_stop_voice;
102};
103
104static const int pcm_device_table[AUDIO_USECASE_MAX][2] = {
105 [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {0, 0},
106 [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {14, 14},
107 [USECASE_AUDIO_PLAYBACK_MULTI_CH] = {1, 1},
108 [USECASE_AUDIO_RECORD] = {0, 0},
109 [USECASE_AUDIO_RECORD_LOW_LATENCY] = {14, 14},
110 [USECASE_VOICE_CALL] = {12, 12},
111};
112
113/* Array to store sound devices */
114static const char * const device_table[SND_DEVICE_MAX] = {
115 [SND_DEVICE_NONE] = "none",
116 /* Playback sound devices */
117 [SND_DEVICE_OUT_HANDSET] = "handset",
118 [SND_DEVICE_OUT_SPEAKER] = "speaker",
119 [SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
120 [SND_DEVICE_OUT_HEADPHONES] = "headphones",
121 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
122 [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
123 [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
124 [SND_DEVICE_OUT_HDMI] = "hdmi",
125 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
126 [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700127 [SND_DEVICE_OUT_BT_SCO_WB] = "bt-sco-headset-wb",
Eric Laurentb23d5282013-05-14 15:27:20 -0700128 [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = "voice-handset-tmus",
Eric Laurent788f41f2015-08-24 12:21:50 -0700129 [SND_DEVICE_OUT_VOICE_HANDSET] = "voice-handset-tmus",
130 [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = "voice-handset-tmus",
Eric Laurentb23d5282013-05-14 15:27:20 -0700131 [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
132 [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
133 [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
Eric Laurentb1b07992017-06-29 09:20:02 -0700134 [SND_DEVICE_OUT_USB_HEADSET] = "usb-headset",
135 [SND_DEVICE_OUT_USB_HEADPHONES] = "usb-headphones",
136 [SND_DEVICE_OUT_VOICE_USB_HEADSET] = "usb-headset",
137 [SND_DEVICE_OUT_VOICE_USB_HEADPHONES] = "usb-headphones",
138
Eric Laurentb23d5282013-05-14 15:27:20 -0700139
140 /* Capture sound devices */
141 [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
142 [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
143 [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
144 [SND_DEVICE_IN_HANDSET_MIC_AEC] = "handset-mic",
145 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "voice-speaker-mic",
146 [SND_DEVICE_IN_HEADSET_MIC_AEC] = "headset-mic",
147 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
148 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
149 [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
150 [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700151 [SND_DEVICE_IN_BT_SCO_MIC_WB] = "bt-sco-mic-wb",
Eric Laurentb23d5282013-05-14 15:27:20 -0700152 [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
153 [SND_DEVICE_IN_VOICE_DMIC_EF] = "voice-dmic-ef",
154 [SND_DEVICE_IN_VOICE_DMIC_BS] = "voice-dmic-bs",
155 [SND_DEVICE_IN_VOICE_DMIC_EF_TMUS] = "voice-dmic-ef-tmus",
156 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_EF] = "voice-speaker-dmic-ef",
157 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BS] = "voice-speaker-dmic-bs",
158 [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = "voice-tty-full-headset-mic",
159 [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = "voice-tty-vco-handset-mic",
160 [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = "voice-tty-hco-headset-mic",
161 [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
162 [SND_DEVICE_IN_VOICE_REC_DMIC_EF] = "voice-rec-dmic-ef",
163 [SND_DEVICE_IN_VOICE_REC_DMIC_BS] = "voice-rec-dmic-bs",
164 [SND_DEVICE_IN_VOICE_REC_DMIC_EF_FLUENCE] = "voice-rec-dmic-ef-fluence",
165 [SND_DEVICE_IN_VOICE_REC_DMIC_BS_FLUENCE] = "voice-rec-dmic-bs-fluence",
166};
167
168/* ACDB IDs (audio DSP path configuration IDs) for each sound device */
169static const int acdb_device_table[SND_DEVICE_MAX] = {
170 [SND_DEVICE_NONE] = -1,
171 [SND_DEVICE_OUT_HANDSET] = 7,
172 [SND_DEVICE_OUT_SPEAKER] = 14,
173 [SND_DEVICE_OUT_SPEAKER_REVERSE] = 14,
174 [SND_DEVICE_OUT_HEADPHONES] = 10,
175 [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
176 [SND_DEVICE_OUT_VOICE_SPEAKER] = 14,
177 [SND_DEVICE_OUT_VOICE_HEADPHONES] = 10,
178 [SND_DEVICE_OUT_HDMI] = 18,
179 [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 14,
180 [SND_DEVICE_OUT_BT_SCO] = 22,
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700181 [SND_DEVICE_OUT_BT_SCO_WB] = 39,
Eric Laurentb23d5282013-05-14 15:27:20 -0700182 [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = 81,
Eric Laurent788f41f2015-08-24 12:21:50 -0700183 [SND_DEVICE_OUT_VOICE_HANDSET] = 81,
184 [SND_DEVICE_OUT_VOICE_HAC_HANDSET] = 81,
Eric Laurentb23d5282013-05-14 15:27:20 -0700185 [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
186 [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
187 [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
Eric Laurentb1b07992017-06-29 09:20:02 -0700188 [SND_DEVICE_OUT_USB_HEADSET] = 45,
189 [SND_DEVICE_OUT_USB_HEADPHONES] = 45,
190 [SND_DEVICE_OUT_VOICE_USB_HEADSET] = 45,
191 [SND_DEVICE_OUT_VOICE_USB_HEADPHONES] = 45,
Eric Laurentb23d5282013-05-14 15:27:20 -0700192
193 [SND_DEVICE_IN_HANDSET_MIC] = 4,
194 [SND_DEVICE_IN_SPEAKER_MIC] = 4,
195 [SND_DEVICE_IN_HEADSET_MIC] = 8,
196 [SND_DEVICE_IN_HANDSET_MIC_AEC] = 40,
197 [SND_DEVICE_IN_SPEAKER_MIC_AEC] = 42,
198 [SND_DEVICE_IN_HEADSET_MIC_AEC] = 47,
199 [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = 11,
200 [SND_DEVICE_IN_VOICE_HEADSET_MIC] = 8,
201 [SND_DEVICE_IN_HDMI_MIC] = 4,
202 [SND_DEVICE_IN_BT_SCO_MIC] = 21,
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700203 [SND_DEVICE_IN_BT_SCO_MIC_WB] = 38,
Eric Laurentb23d5282013-05-14 15:27:20 -0700204 [SND_DEVICE_IN_CAMCORDER_MIC] = 61,
205 [SND_DEVICE_IN_VOICE_DMIC_EF] = 6,
206 [SND_DEVICE_IN_VOICE_DMIC_BS] = 5,
207 [SND_DEVICE_IN_VOICE_DMIC_EF_TMUS] = 91,
208 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_EF] = 13,
209 [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BS] = 12,
210 [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = 16,
211 [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = 36,
212 [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = 16,
213 [SND_DEVICE_IN_VOICE_REC_MIC] = 62,
214 /* TODO: Update with proper acdb ids */
215 [SND_DEVICE_IN_VOICE_REC_DMIC_EF] = 62,
216 [SND_DEVICE_IN_VOICE_REC_DMIC_BS] = 62,
217 [SND_DEVICE_IN_VOICE_REC_DMIC_EF_FLUENCE] = 6,
218 [SND_DEVICE_IN_VOICE_REC_DMIC_BS_FLUENCE] = 5,
219};
220
Haynes Mathew George7ff216f2013-09-11 19:51:41 -0700221#define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
222#define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
223
Eric Laurentb23d5282013-05-14 15:27:20 -0700224static pthread_once_t check_op_once_ctl = PTHREAD_ONCE_INIT;
225static bool is_tmus = false;
226
227static void check_operator()
228{
229 char value[PROPERTY_VALUE_MAX];
230 int mccmnc;
231 property_get("gsm.sim.operator.numeric",value,"0");
232 mccmnc = atoi(value);
233 ALOGD("%s: tmus mccmnc %d", __func__, mccmnc);
234 switch(mccmnc) {
235 /* TMUS MCC(310), MNC(490, 260, 026) */
236 case 310490:
237 case 310260:
238 case 310026:
239 is_tmus = true;
240 break;
241 }
242}
243
244bool is_operator_tmus()
245{
246 pthread_once(&check_op_once_ctl, check_operator);
247 return is_tmus;
248}
249
250static int set_echo_reference(struct mixer *mixer, const char* ec_ref)
251{
252 struct mixer_ctl *ctl;
253 const char *mixer_ctl_name = "EC_REF_RX";
254
255 ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name);
256 if (!ctl) {
257 ALOGE("%s: Could not get ctl for mixer cmd - %s",
258 __func__, mixer_ctl_name);
259 return -EINVAL;
260 }
261 ALOGV("Setting EC Reference: %s", ec_ref);
262 mixer_ctl_set_enum_by_string(ctl, ec_ref);
263 return 0;
264}
265
266void *platform_init(struct audio_device *adev)
267{
268 char platform[PROPERTY_VALUE_MAX];
269 char baseband[PROPERTY_VALUE_MAX];
270 char value[PROPERTY_VALUE_MAX];
271 struct platform_data *my_data;
272
sangwoo1b9f4b32013-06-21 18:22:55 -0700273 adev->mixer = mixer_open(MIXER_CARD);
274
275 if (!adev->mixer) {
276 ALOGE("Unable to open the mixer, aborting.");
277 return NULL;
278 }
279
280 adev->audio_route = audio_route_init(MIXER_CARD, MIXER_XML_PATH);
281 if (!adev->audio_route) {
282 ALOGE("%s: Failed to init audio route controls, aborting.", __func__);
283 return NULL;
284 }
285
Eric Laurentb23d5282013-05-14 15:27:20 -0700286 my_data = calloc(1, sizeof(struct platform_data));
287
288 my_data->adev = adev;
289 my_data->dualmic_config = DUALMIC_CONFIG_NONE;
290 my_data->fluence_in_spkr_mode = false;
291 my_data->fluence_in_voice_call = false;
292 my_data->fluence_in_voice_rec = false;
293
294 property_get("persist.audio.dualmic.config",value,"");
295 if (!strcmp("broadside", value)) {
296 my_data->dualmic_config = DUALMIC_CONFIG_BROADSIDE;
297 adev->acdb_settings |= DMIC_FLAG;
298 } else if (!strcmp("endfire", value)) {
299 my_data->dualmic_config = DUALMIC_CONFIG_ENDFIRE;
300 adev->acdb_settings |= DMIC_FLAG;
301 }
302
303 if (my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
304 property_get("persist.audio.fluence.voicecall",value,"");
305 if (!strcmp("true", value)) {
306 my_data->fluence_in_voice_call = true;
307 }
308
309 property_get("persist.audio.fluence.voicerec",value,"");
310 if (!strcmp("true", value)) {
311 my_data->fluence_in_voice_rec = true;
312 }
313
314 property_get("persist.audio.fluence.speaker",value,"");
315 if (!strcmp("true", value)) {
316 my_data->fluence_in_spkr_mode = true;
317 }
318 }
319
320 my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
321 if (my_data->acdb_handle == NULL) {
322 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
323 } else {
324 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
325 my_data->acdb_deallocate = (acdb_deallocate_t)dlsym(my_data->acdb_handle,
326 "acdb_loader_deallocate_ACDB");
327 my_data->acdb_send_audio_cal = (acdb_send_audio_cal_t)dlsym(my_data->acdb_handle,
328 "acdb_loader_send_audio_cal");
329 if (!my_data->acdb_send_audio_cal)
330 ALOGW("%s: Could not find the symbol acdb_send_audio_cal from %s",
331 __func__, LIB_ACDB_LOADER);
332 my_data->acdb_send_voice_cal = (acdb_send_voice_cal_t)dlsym(my_data->acdb_handle,
333 "acdb_loader_send_voice_cal");
334 my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
335 "acdb_loader_init_ACDB");
336 if (my_data->acdb_init == NULL)
337 ALOGE("%s: dlsym error %s for acdb_loader_init_ACDB", __func__, dlerror());
338 else
339 my_data->acdb_init();
340 }
341
342 /* If platform is Fusion3, load CSD Client specific symbols
343 * Voice call is handled by MDM and apps processor talks to
344 * MDM through CSD Client
345 */
346 property_get("ro.board.platform", platform, "");
347 property_get("ro.baseband", baseband, "");
348 if (!strcmp("msm8960", platform) && !strcmp("mdm", baseband)) {
349 my_data->csd_client = dlopen(LIB_CSD_CLIENT, RTLD_NOW);
350 if (my_data->csd_client == NULL)
351 ALOGE("%s: DLOPEN failed for %s", __func__, LIB_CSD_CLIENT);
352 }
353
354 if (my_data->csd_client) {
355 ALOGV("%s: DLOPEN successful for %s", __func__, LIB_CSD_CLIENT);
356 my_data->csd_client_deinit = (csd_client_deinit_t)dlsym(my_data->csd_client,
357 "csd_client_deinit");
358 my_data->csd_disable_device = (csd_disable_device_t)dlsym(my_data->csd_client,
359 "csd_client_disable_device");
360 my_data->csd_enable_device = (csd_enable_device_t)dlsym(my_data->csd_client,
361 "csd_client_enable_device");
362 my_data->csd_start_voice = (csd_start_voice_t)dlsym(my_data->csd_client,
363 "csd_client_start_voice");
364 my_data->csd_stop_voice = (csd_stop_voice_t)dlsym(my_data->csd_client,
365 "csd_client_stop_voice");
366 my_data->csd_volume = (csd_volume_t)dlsym(my_data->csd_client,
367 "csd_client_volume");
368 my_data->csd_mic_mute = (csd_mic_mute_t)dlsym(my_data->csd_client,
369 "csd_client_mic_mute");
370 my_data->csd_client_init = (csd_client_init_t)dlsym(my_data->csd_client,
371 "csd_client_init");
372
373 if (my_data->csd_client_init == NULL) {
374 ALOGE("%s: dlsym error %s for csd_client_init", __func__, dlerror());
375 } else {
376 my_data->csd_client_init();
377 }
378 }
379
380 return my_data;
381}
382
383void platform_deinit(void *platform)
384{
385 free(platform);
386}
387
388const char *platform_get_snd_device_name(snd_device_t snd_device)
389{
390 if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX)
391 return device_table[snd_device];
392 else
Ravi Kumar Alamanda64026462014-09-15 00:08:58 -0700393 return "none";
Eric Laurentb23d5282013-05-14 15:27:20 -0700394}
395
Ravi Kumar Alamanda299760a2013-11-01 17:29:09 -0500396void platform_add_backend_name(void *platform __unused, char *mixer_path,
397 snd_device_t snd_device)
Eric Laurentb23d5282013-05-14 15:27:20 -0700398{
399 if (snd_device == SND_DEVICE_IN_BT_SCO_MIC)
400 strcat(mixer_path, " bt-sco");
401 else if(snd_device == SND_DEVICE_OUT_BT_SCO)
402 strcat(mixer_path, " bt-sco");
403 else if (snd_device == SND_DEVICE_OUT_HDMI)
404 strcat(mixer_path, " hdmi");
405 else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HDMI)
406 strcat(mixer_path, " speaker-and-hdmi");
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700407 else if (snd_device == SND_DEVICE_OUT_BT_SCO_WB ||
408 snd_device == SND_DEVICE_IN_BT_SCO_MIC_WB)
409 strcat(mixer_path, " bt-sco-wb");
Eric Laurentb23d5282013-05-14 15:27:20 -0700410}
411
412int platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
413{
414 int device_id;
415 if (device_type == PCM_PLAYBACK)
416 device_id = pcm_device_table[usecase][0];
417 else
418 device_id = pcm_device_table[usecase][1];
419 return device_id;
420}
421
Haynes Mathew George98c95622014-06-20 19:14:25 -0700422int platform_get_snd_device_index(char *snd_device_index_name __unused)
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700423{
424 return -ENODEV;
425}
426
Haynes Mathew George98c95622014-06-20 19:14:25 -0700427int platform_set_snd_device_acdb_id(snd_device_t snd_device __unused,
428 unsigned int acdb_id __unused)
Haynes Mathew George5bc18842014-06-16 16:36:20 -0700429{
430 return -ENODEV;
431}
432
Yamit Mehtae3b99562016-09-16 22:44:00 +0530433int platform_get_default_app_type_v2(void *platform, usecase_type_t type __unused,
434 int *app_type __unused)
435{
436 ALOGE("%s: Not implemented", __func__);
437 return -ENOSYS;
438}
439
Ravi Kumar Alamanda63863002015-04-22 11:15:25 -0700440int platform_get_snd_device_acdb_id(snd_device_t snd_device __unused)
441{
442 ALOGE("%s: Not implemented", __func__);
443 return -ENOSYS;
444}
445
Eric Laurent788f41f2015-08-24 12:21:50 -0700446void platform_add_operator_specific_device(snd_device_t snd_device __unused,
447 const char *operator __unused,
448 const char *mixer_path __unused,
449 unsigned int acdb_id __unused)
keunhui.park2f7306a2015-07-16 16:48:06 +0900450{
451}
452
Eric Laurentb23d5282013-05-14 15:27:20 -0700453int platform_send_audio_calibration(void *platform, snd_device_t snd_device)
454{
455 struct platform_data *my_data = (struct platform_data *)platform;
456 int acdb_dev_id, acdb_dev_type;
457
458 acdb_dev_id = acdb_device_table[snd_device];
459 if (acdb_dev_id < 0) {
460 ALOGE("%s: Could not find acdb id for device(%d)",
461 __func__, snd_device);
462 return -EINVAL;
463 }
464 if (my_data->acdb_send_audio_cal) {
Eric Laurent994a6932013-07-17 11:51:42 -0700465 ("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
Eric Laurentb23d5282013-05-14 15:27:20 -0700466 __func__, snd_device, acdb_dev_id);
467 if (snd_device >= SND_DEVICE_OUT_BEGIN &&
468 snd_device < SND_DEVICE_OUT_END)
469 acdb_dev_type = ACDB_DEV_TYPE_OUT;
470 else
471 acdb_dev_type = ACDB_DEV_TYPE_IN;
472 my_data->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type);
473 }
474 return 0;
475}
476
477int platform_switch_voice_call_device_pre(void *platform)
478{
479 struct platform_data *my_data = (struct platform_data *)platform;
480 int ret = 0;
481
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -0700482 if (my_data->csd_client != NULL &&
483 voice_is_in_call(my_data->adev)) {
Eric Laurentb23d5282013-05-14 15:27:20 -0700484 /* This must be called before disabling the mixer controls on APQ side */
485 if (my_data->csd_disable_device == NULL) {
486 ALOGE("%s: dlsym error for csd_disable_device", __func__);
487 } else {
488 ret = my_data->csd_disable_device();
489 if (ret < 0) {
490 ALOGE("%s: csd_client_disable_device, failed, error %d",
491 __func__, ret);
492 }
493 }
494 }
495 return ret;
496}
497
498int platform_switch_voice_call_device_post(void *platform,
499 snd_device_t out_snd_device,
500 snd_device_t in_snd_device)
501{
502 struct platform_data *my_data = (struct platform_data *)platform;
503 int acdb_rx_id, acdb_tx_id;
504 int ret = 0;
505
506 if (my_data->csd_client) {
507 if (my_data->csd_enable_device == NULL) {
508 ALOGE("%s: dlsym error for csd_enable_device",
509 __func__);
510 } else {
511 acdb_rx_id = acdb_device_table[out_snd_device];
512 acdb_tx_id = acdb_device_table[in_snd_device];
513
514 if (acdb_rx_id > 0 || acdb_tx_id > 0) {
515 ret = my_data->csd_enable_device(acdb_rx_id, acdb_tx_id,
516 my_data->adev->acdb_settings);
517 if (ret < 0) {
518 ALOGE("%s: csd_enable_device, failed, error %d",
519 __func__, ret);
520 }
521 } else {
522 ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
523 acdb_rx_id, acdb_tx_id);
524 }
525 }
526 }
527
528 return ret;
529}
530
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700531int platform_start_voice_call(void *platform, uint32_t vsid __unused)
Eric Laurentb23d5282013-05-14 15:27:20 -0700532{
533 struct platform_data *my_data = (struct platform_data *)platform;
534 int ret = 0;
535
536 if (my_data->csd_client) {
537 if (my_data->csd_start_voice == NULL) {
538 ALOGE("dlsym error for csd_client_start_voice");
539 ret = -ENOSYS;
540 } else {
541 ret = my_data->csd_start_voice();
542 if (ret < 0) {
543 ALOGE("%s: csd_start_voice error %d\n", __func__, ret);
544 }
545 }
546 }
547
548 return ret;
549}
550
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700551int platform_stop_voice_call(void *platform, uint32_t vsid __unused)
Eric Laurentb23d5282013-05-14 15:27:20 -0700552{
553 struct platform_data *my_data = (struct platform_data *)platform;
554 int ret = 0;
555
556 if (my_data->csd_client) {
557 if (my_data->csd_stop_voice == NULL) {
558 ALOGE("dlsym error for csd_stop_voice");
559 } else {
560 ret = my_data->csd_stop_voice();
561 if (ret < 0) {
562 ALOGE("%s: csd_stop_voice error %d\n", __func__, ret);
563 }
564 }
565 }
566
567 return ret;
568}
569
vivek mehtab6506412015-08-07 16:55:17 -0700570void platform_set_speaker_gain_in_combo(struct audio_device *adev __unused,
Eric Laurent788f41f2015-08-24 12:21:50 -0700571 snd_device_t snd_device __unused,
vivek mehtab6506412015-08-07 16:55:17 -0700572 bool enable __unused) {
573}
574
Eric Laurentb23d5282013-05-14 15:27:20 -0700575int platform_set_voice_volume(void *platform, int volume)
576{
577 struct platform_data *my_data = (struct platform_data *)platform;
578 int ret = 0;
579
580 if (my_data->csd_client) {
581 if (my_data->csd_volume == NULL) {
582 ALOGE("%s: dlsym error for csd_volume", __func__);
583 } else {
584 ret = my_data->csd_volume(volume);
585 if (ret < 0) {
586 ALOGE("%s: csd_volume error %d", __func__, ret);
587 }
588 }
589 } else {
590 ALOGE("%s: No CSD Client present", __func__);
591 }
592
593 return ret;
594}
595
596int platform_set_mic_mute(void *platform, bool state)
597{
598 struct platform_data *my_data = (struct platform_data *)platform;
599 int ret = 0;
600
601 if (my_data->adev->mode == AUDIO_MODE_IN_CALL) {
602 if (my_data->csd_client) {
603 if (my_data->csd_mic_mute == NULL) {
604 ALOGE("%s: dlsym error for csd_mic_mute", __func__);
605 } else {
606 ret = my_data->csd_mic_mute(state);
607 if (ret < 0) {
608 ALOGE("%s: csd_mic_mute error %d", __func__, ret);
609 }
610 }
611 } else {
612 ALOGE("%s: No CSD Client present", __func__);
613 }
614 }
615
616 return ret;
617}
618
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700619int platform_set_device_mute(void *platform __unused, bool state __unused, char *dir __unused)
620{
Haynes Mathew George24ca9ad2014-06-18 15:14:18 -0700621 ALOGE("%s: Not implemented", __func__);
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700622 return -ENOSYS;
623}
624
Eric Laurentb23d5282013-05-14 15:27:20 -0700625snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices)
626{
627 struct platform_data *my_data = (struct platform_data *)platform;
628 struct audio_device *adev = my_data->adev;
629 audio_mode_t mode = adev->mode;
630 snd_device_t snd_device = SND_DEVICE_NONE;
631
632 ALOGV("%s: enter: output devices(%#x)", __func__, devices);
633 if (devices == AUDIO_DEVICE_NONE ||
634 devices & AUDIO_DEVICE_BIT_IN) {
635 ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
636 goto exit;
637 }
638
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -0700639 if (voice_is_in_call(adev)) {
Eric Laurentb23d5282013-05-14 15:27:20 -0700640 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
641 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Haynes Mathew George24ca9ad2014-06-18 15:14:18 -0700642 if (adev->voice.tty_mode == TTY_MODE_FULL)
Eric Laurentb23d5282013-05-14 15:27:20 -0700643 snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES;
Haynes Mathew George24ca9ad2014-06-18 15:14:18 -0700644 else if (adev->voice.tty_mode == TTY_MODE_VCO)
Eric Laurentb23d5282013-05-14 15:27:20 -0700645 snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES;
Haynes Mathew George24ca9ad2014-06-18 15:14:18 -0700646 else if (adev->voice.tty_mode == TTY_MODE_HCO)
Eric Laurentb23d5282013-05-14 15:27:20 -0700647 snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET;
648 else
649 snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
650 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700651 if (adev->bt_wb_speech_enabled) {
652 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
653 } else {
654 snd_device = SND_DEVICE_OUT_BT_SCO;
655 }
Eric Laurentb23d5282013-05-14 15:27:20 -0700656 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
657 snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
658 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
659 if (is_operator_tmus())
660 snd_device = SND_DEVICE_OUT_VOICE_HANDSET_TMUS;
661 else
662 snd_device = SND_DEVICE_OUT_HANDSET;
663 }
664 if (snd_device != SND_DEVICE_NONE) {
665 goto exit;
666 }
667 }
668
669 if (popcount(devices) == 2) {
670 if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
671 AUDIO_DEVICE_OUT_SPEAKER)) {
672 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
673 } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
674 AUDIO_DEVICE_OUT_SPEAKER)) {
675 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
676 } else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
677 AUDIO_DEVICE_OUT_SPEAKER)) {
678 snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI;
679 } else {
680 ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
681 goto exit;
682 }
683 if (snd_device != SND_DEVICE_NONE) {
684 goto exit;
685 }
686 }
687
688 if (popcount(devices) != 1) {
689 ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
690 goto exit;
691 }
692
693 if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
694 devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
695 snd_device = SND_DEVICE_OUT_HEADPHONES;
696 } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
Ravi Kumar Alamanda1f60cf82015-04-23 19:45:17 -0700697 if (my_data->speaker_lr_swap)
Eric Laurentb23d5282013-05-14 15:27:20 -0700698 snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE;
699 else
700 snd_device = SND_DEVICE_OUT_SPEAKER;
701 } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700702 if (adev->bt_wb_speech_enabled) {
703 snd_device = SND_DEVICE_OUT_BT_SCO_WB;
704 } else {
705 snd_device = SND_DEVICE_OUT_BT_SCO;
706 }
Eric Laurentb23d5282013-05-14 15:27:20 -0700707 } else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
708 snd_device = SND_DEVICE_OUT_HDMI ;
709 } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
710 snd_device = SND_DEVICE_OUT_HANDSET;
711 } else {
712 ALOGE("%s: Unknown device(s) %#x", __func__, devices);
713 }
714exit:
715 ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
716 return snd_device;
717}
718
719snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device)
720{
721 struct platform_data *my_data = (struct platform_data *)platform;
722 struct audio_device *adev = my_data->adev;
723 audio_source_t source = (adev->active_input == NULL) ?
724 AUDIO_SOURCE_DEFAULT : adev->active_input->source;
725
726 audio_mode_t mode = adev->mode;
727 audio_devices_t in_device = ((adev->active_input == NULL) ?
728 AUDIO_DEVICE_NONE : adev->active_input->device)
729 & ~AUDIO_DEVICE_BIT_IN;
730 audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
731 AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
732 snd_device_t snd_device = SND_DEVICE_NONE;
733
734 ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
735 __func__, out_device, in_device);
Ravi Kumar Alamandab09e4a02014-10-20 17:07:43 -0700736 if ((out_device != AUDIO_DEVICE_NONE) && voice_is_in_call(adev)) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700737 if (adev->voice.tty_mode != TTY_MODE_OFF) {
Eric Laurentb23d5282013-05-14 15:27:20 -0700738 if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
739 out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700740 switch (adev->voice.tty_mode) {
Eric Laurentb23d5282013-05-14 15:27:20 -0700741 case TTY_MODE_FULL:
742 snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC;
743 break;
744 case TTY_MODE_VCO:
745 snd_device = SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC;
746 break;
747 case TTY_MODE_HCO:
748 snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC;
749 break;
750 default:
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700751 ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->voice.tty_mode);
Eric Laurentb23d5282013-05-14 15:27:20 -0700752 }
753 goto exit;
754 }
755 }
756 if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
757 out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
758 if (my_data->fluence_in_voice_call == false) {
759 snd_device = SND_DEVICE_IN_HANDSET_MIC;
760 } else {
761 if (my_data->dualmic_config == DUALMIC_CONFIG_ENDFIRE) {
762 if (is_operator_tmus())
763 snd_device = SND_DEVICE_IN_VOICE_DMIC_EF_TMUS;
764 else
765 snd_device = SND_DEVICE_IN_VOICE_DMIC_EF;
766 } else if(my_data->dualmic_config == DUALMIC_CONFIG_BROADSIDE)
767 snd_device = SND_DEVICE_IN_VOICE_DMIC_BS;
768 else
769 snd_device = SND_DEVICE_IN_HANDSET_MIC;
770 }
771 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
772 snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
773 } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700774 if (adev->bt_wb_speech_enabled) {
775 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
776 } else {
777 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
778 }
Eric Laurentb23d5282013-05-14 15:27:20 -0700779 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
780 if (my_data->fluence_in_voice_call && my_data->fluence_in_spkr_mode &&
781 my_data->dualmic_config == DUALMIC_CONFIG_ENDFIRE) {
782 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC_EF;
783 } else if (my_data->fluence_in_voice_call && my_data->fluence_in_spkr_mode &&
784 my_data->dualmic_config == DUALMIC_CONFIG_BROADSIDE) {
785 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BS;
786 } else {
787 snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
788 }
789 }
790 } else if (source == AUDIO_SOURCE_CAMCORDER) {
791 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
792 in_device & AUDIO_DEVICE_IN_BACK_MIC) {
793 snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
794 }
795 } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
796 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
797 if (my_data->dualmic_config == DUALMIC_CONFIG_ENDFIRE) {
798 if (channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK)
799 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_EF;
800 else if (my_data->fluence_in_voice_rec)
801 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_EF_FLUENCE;
802 } else if (my_data->dualmic_config == DUALMIC_CONFIG_BROADSIDE) {
803 if (channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK)
804 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_BS;
805 else if (my_data->fluence_in_voice_rec)
806 snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_BS_FLUENCE;
807 }
808
809 if (snd_device == SND_DEVICE_NONE) {
810 snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
811 }
812 }
Eric Laurent50a38ed2015-10-14 18:48:06 -0700813 } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION ||
814 mode == AUDIO_MODE_IN_COMMUNICATION) {
Eric Laurentb23d5282013-05-14 15:27:20 -0700815 if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
816 in_device = AUDIO_DEVICE_IN_BACK_MIC;
817 if (adev->active_input) {
818 if (adev->active_input->enable_aec) {
819 if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
820 snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
821 } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
822 snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
823 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
824 snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
825 }
826 set_echo_reference(adev->mixer, "SLIM_RX");
827 } else
828 set_echo_reference(adev->mixer, "NONE");
829 }
830 } else if (source == AUDIO_SOURCE_DEFAULT) {
831 goto exit;
832 }
833
834
835 if (snd_device != SND_DEVICE_NONE) {
836 goto exit;
837 }
838
839 if (in_device != AUDIO_DEVICE_NONE &&
840 !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
841 !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
842 if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
843 snd_device = SND_DEVICE_IN_HANDSET_MIC;
844 } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
845 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
846 } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
847 snd_device = SND_DEVICE_IN_HEADSET_MIC;
848 } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700849 if (adev->bt_wb_speech_enabled) {
850 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
851 } else {
852 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
853 }
Eric Laurentb23d5282013-05-14 15:27:20 -0700854 } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
855 snd_device = SND_DEVICE_IN_HDMI_MIC;
856 } else {
857 ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
858 ALOGW("%s: Using default handset-mic", __func__);
859 snd_device = SND_DEVICE_IN_HANDSET_MIC;
860 }
861 } else {
862 if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
863 snd_device = SND_DEVICE_IN_HANDSET_MIC;
864 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
865 snd_device = SND_DEVICE_IN_HEADSET_MIC;
866 } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
867 snd_device = SND_DEVICE_IN_SPEAKER_MIC;
868 } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
869 snd_device = SND_DEVICE_IN_HANDSET_MIC;
870 } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
Ravi Kumar Alamanda9f306542014-04-02 15:11:49 -0700871 if (adev->bt_wb_speech_enabled) {
872 snd_device = SND_DEVICE_IN_BT_SCO_MIC_WB;
873 } else {
874 snd_device = SND_DEVICE_IN_BT_SCO_MIC;
875 }
Eric Laurentb23d5282013-05-14 15:27:20 -0700876 } else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
877 snd_device = SND_DEVICE_IN_HDMI_MIC;
878 } else {
879 ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
880 ALOGW("%s: Using default handset-mic", __func__);
881 snd_device = SND_DEVICE_IN_HANDSET_MIC;
882 }
883 }
884exit:
885 ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
886 return snd_device;
887}
888
889int platform_set_hdmi_channels(void *platform, int channel_count)
890{
891 struct platform_data *my_data = (struct platform_data *)platform;
892 struct audio_device *adev = my_data->adev;
893 struct mixer_ctl *ctl;
894 const char *channel_cnt_str = NULL;
895 const char *mixer_ctl_name = "HDMI_RX Channels";
896 switch (channel_count) {
897 case 8:
898 channel_cnt_str = "Eight"; break;
899 case 7:
900 channel_cnt_str = "Seven"; break;
901 case 6:
902 channel_cnt_str = "Six"; break;
903 case 5:
904 channel_cnt_str = "Five"; break;
905 case 4:
906 channel_cnt_str = "Four"; break;
907 case 3:
908 channel_cnt_str = "Three"; break;
909 default:
910 channel_cnt_str = "Two"; break;
911 }
912 ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
913 if (!ctl) {
914 ALOGE("%s: Could not get ctl for mixer cmd - %s",
915 __func__, mixer_ctl_name);
916 return -EINVAL;
917 }
918 ALOGV("HDMI channel count: %s", channel_cnt_str);
919 mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
920 return 0;
921}
922
Haynes Mathew George24ca9ad2014-06-18 15:14:18 -0700923int platform_edid_get_max_channels(void *platform __unused)
Eric Laurentb23d5282013-05-14 15:27:20 -0700924{
925 FILE *file;
926 struct audio_block_header header;
927 char block[MAX_SAD_BLOCKS * SAD_BLOCK_SIZE];
928 char *sad = block;
929 int num_audio_blocks;
930 int channel_count;
931 int max_channels = 0;
932 int i;
933
934 file = fopen(AUDIO_DATA_BLOCK_PATH, "rb");
935 if (file == NULL) {
936 ALOGE("Unable to open '%s'", AUDIO_DATA_BLOCK_PATH);
937 return 0;
938 }
939
940 /* Read audio block header */
941 fread(&header, 1, sizeof(header), file);
942
943 /* Read SAD blocks, clamping the maximum size for safety */
944 if (header.length > (int)sizeof(block))
945 header.length = (int)sizeof(block);
946 fread(&block, header.length, 1, file);
947
948 fclose(file);
949
950 /* Calculate the number of SAD blocks */
951 num_audio_blocks = header.length / SAD_BLOCK_SIZE;
952
953 for (i = 0; i < num_audio_blocks; i++) {
954 /* Only consider LPCM blocks */
955 if ((sad[0] >> 3) != EDID_FORMAT_LPCM)
956 continue;
957
958 channel_count = (sad[0] & 0x7) + 1;
959 if (channel_count > max_channels)
960 max_channels = channel_count;
961
962 /* Advance to next block */
963 sad += 3;
964 }
965
966 return max_channels;
967}
Haynes Mathew George7ff216f2013-09-11 19:51:41 -0700968
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700969int platform_set_incall_recording_session_id(void *platform __unused,
970 uint32_t session_id __unused, int rec_mode __unused)
971{
Haynes Mathew George24ca9ad2014-06-18 15:14:18 -0700972 ALOGE("%s: Not implemented", __func__);
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700973 return -ENOSYS;
974}
975
976int platform_stop_incall_recording_usecase(void *platform __unused)
977{
Haynes Mathew George24ca9ad2014-06-18 15:14:18 -0700978 ALOGE("%s: Not implemented", __func__);
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700979 return -ENOSYS;
980}
981
982int platform_start_incall_music_usecase(void *platform __unused)
983{
Haynes Mathew George24ca9ad2014-06-18 15:14:18 -0700984 ALOGE("%s: Not implemented", __func__);
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700985 return -ENOSYS;
986}
987
988int platform_stop_incall_music_usecase(void *platform __unused)
989{
Haynes Mathew George24ca9ad2014-06-18 15:14:18 -0700990 ALOGE("%s: Not implemented", __func__);
Vineeta Srivastava4b89e372014-06-19 14:21:42 -0700991 return -ENOSYS;
992}
993
Ravi Kumar Alamandac4f57312015-06-26 17:41:02 -0700994int platform_set_parameters(void *platform __unused,
995 struct str_parms *parms __unused)
996{
997 ALOGE("%s: Not implemented", __func__);
998 return -ENOSYS;
999}
1000
Haynes Mathew George7ff216f2013-09-11 19:51:41 -07001001/* Delay in Us */
1002int64_t platform_render_latency(audio_usecase_t usecase)
1003{
1004 switch (usecase) {
1005 case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
1006 return DEEP_BUFFER_PLATFORM_DELAY;
1007 case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
1008 return LOW_LATENCY_PLATFORM_DELAY;
1009 default:
1010 return 0;
1011 }
1012}
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001013
Haynes Mathew George24ca9ad2014-06-18 15:14:18 -07001014int platform_switch_voice_call_enable_device_config(void *platform __unused,
1015 snd_device_t out_snd_device __unused,
1016 snd_device_t in_snd_device __unused)
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001017{
1018 return 0;
1019}
1020
Haynes Mathew George24ca9ad2014-06-18 15:14:18 -07001021int platform_switch_voice_call_usecase_route_post(void *platform __unused,
1022 snd_device_t out_snd_device __unused,
1023 snd_device_t in_snd_device __unused)
Ravi Kumar Alamanda83281a92014-05-19 18:14:57 -07001024{
1025 return 0;
1026}
Haynes Mathew George24ca9ad2014-06-18 15:14:18 -07001027
1028int platform_get_sample_rate(void *platform __unused, uint32_t *rate __unused)
1029{
1030 return -ENOSYS;
1031}
Haynes Mathew George98c95622014-06-20 19:14:25 -07001032
1033int platform_get_usecase_index(const char * usecase __unused)
1034{
1035 return -ENOSYS;
1036}
1037
1038int platform_set_usecase_pcm_id(audio_usecase_t usecase __unused, int32_t type __unused,
1039 int32_t pcm_id __unused)
1040{
1041 return -ENOSYS;
1042}
1043
1044int platform_set_snd_device_backend(snd_device_t device __unused,
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001045 const char *backend __unused,
1046 const char *hw_interface __unused)
Haynes Mathew George98c95622014-06-20 19:14:25 -07001047{
1048 return -ENOSYS;
1049}
Eric Laurentcefbbac2014-09-04 13:54:10 -05001050
vivek mehta1a9b7c02015-06-25 11:49:38 -07001051void platform_set_echo_reference(struct audio_device *adev __unused,
1052 bool enable __unused,
1053 audio_devices_t out_device __unused)
Eric Laurentcefbbac2014-09-04 13:54:10 -05001054{
1055 return;
1056}
Ravi Kumar Alamanda1f60cf82015-04-23 19:45:17 -07001057
1058int platform_swap_lr_channels(struct audio_device *adev, bool swap_channels)
1059{
1060 // only update the selected device if there is active pcm playback
1061 struct audio_usecase *usecase;
1062 struct listnode *node;
1063 struct platform_data *my_data = (struct platform_data *)adev->platform;
1064 int status = 0;
1065
1066 if (my_data->speaker_lr_swap != swap_channels) {
1067 my_data->speaker_lr_swap = swap_channels;
1068
1069 list_for_each(node, &adev->usecase_list) {
1070 usecase = node_to_item(node, struct audio_usecase, list);
1071 if (usecase->type == PCM_PLAYBACK &&
1072 usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER) {
1073 const char *mixer_path;
1074 if (swap_channels) {
1075 mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER_REVERSE);
1076 audio_route_apply_and_update_path(adev->audio_route, mixer_path);
1077 } else {
1078 mixer_path = platform_get_snd_device_name(SND_DEVICE_OUT_SPEAKER);
1079 audio_route_apply_and_update_path(adev->audio_route, mixer_path);
1080 }
1081 break;
1082 }
1083 }
1084 }
1085 return status;
1086}
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001087
1088bool platform_send_gain_dep_cal(void *platform __unused,
1089 int level __unused)
1090{
vivek mehtafb4d7bd2016-04-29 03:16:47 -07001091 return true;
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001092}
1093
Haynes Mathew George2d809e02016-09-22 17:38:16 -07001094int platform_can_split_snd_device(snd_device_t in_snd_device __unused,
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001095 int *num_devices __unused,
1096 snd_device_t *out_snd_devices __unused)
1097{
Haynes Mathew George2d809e02016-09-22 17:38:16 -07001098 return -ENOSYS;
Ravi Kumar Alamandab7ea4f52015-06-08 16:44:05 -07001099}
1100
1101bool platform_check_backends_match(snd_device_t snd_device1 __unused,
1102 snd_device_t snd_device2 __unused)
1103{
1104 return true;
1105}
vivek mehtade4849c2016-03-03 17:23:38 -08001106
1107int platform_get_snd_device_name_extn(void *platform __unused,
1108 snd_device_t snd_device,
1109 char *device_name)
1110{
David Benjamin1565f992016-09-21 12:10:34 -04001111 strlcpy(device_name, platform_get_snd_device_name(snd_device),
1112 DEVICE_NAME_MAX_SIZE);
vivek mehtade4849c2016-03-03 17:23:38 -08001113 return 0;
1114}
1115
David Linee3fe402017-03-13 10:00:42 -07001116bool platform_check_and_set_playback_backend_cfg(struct audio_device* adev __unused,
1117 struct audio_usecase *usecase __unused,
1118 snd_device_t snd_device __unused)
1119{
1120 return false;
1121}
1122
vivek mehta4ed66e62016-04-15 23:33:34 -07001123bool platform_check_and_set_capture_backend_cfg(struct audio_device* adev __unused,
1124 struct audio_usecase *usecase __unused)
1125{
1126 return false;
1127}
1128
vivek mehtaa8d7c922016-05-25 14:40:44 -07001129bool platform_add_gain_level_mapping(struct amp_db_and_gain_table *tbl_entry __unused)
1130{
1131 return false;
1132}
1133
1134int platform_get_gain_level_mapping(struct amp_db_and_gain_table *mapping_tbl __unused,
1135 int table_size __unused)
1136{
1137 return 0;
1138}
Haynes Mathew Georgec735fb02016-06-30 18:00:28 -07001139
Tom Cherry8721b4d2016-07-14 16:12:23 -07001140int platform_snd_card_update(void *platform __unused,
Haynes Mathew Georgec735fb02016-06-30 18:00:28 -07001141 card_status_t status __unused)
1142{
1143 return -1;
1144}
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -08001145
1146int platform_get_snd_device_backend_index(snd_device_t snd_device)
1147{
1148 return -ENOSYS;
1149}
1150
1151void platform_check_and_update_copp_sample_rate(void* platform, snd_device_t snd_device,
1152 unsigned int stream_sr, int* sample_rate)
1153{
1154
1155}
1156
1157int platform_send_audio_calibration_v2(void *platform, struct audio_usecase *usecase,
1158 int app_type, int sample_rate)
1159{
1160 return -ENOSYS;
1161}
1162
1163bool platform_supports_app_type_cfg() { return false; }
1164
vivek mehtaa68fea62017-06-08 19:04:02 -07001165void platform_add_app_type(const char *uc_type __unused,
1166 const char *mode __unused,
1167 int bw __unused, int app_type __unused,
1168 int max_sr __unused) {}
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -08001169
vivek mehtaa68fea62017-06-08 19:04:02 -07001170int platform_get_app_type_v2(void *platform __unused,
1171 enum usecase_type_t type __unused,
1172 const char *mode __unused,
1173 int bw __unused, int sr __unused,
1174 int *app_type __unused) {
1175 return -ENOSYS;
1176}
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -08001177
vivek mehtaa68fea62017-06-08 19:04:02 -07001178int platform_get_snd_device_backend_index(snd_device_t snd_device) {
Haynes Mathew Georgee5ff0fc2017-02-16 20:33:38 -08001179 return -ENOSYS;
1180}
vivek mehta90933872017-06-15 18:04:39 -07001181
1182int platform_set_sidetone(struct audio_device *adev,
1183 snd_device_t out_snd_device,
1184 bool enable, char *str)
1185{
1186 int ret;
1187 if (out_snd_device == SND_DEVICE_OUT_USB_HEADSET ||
1188 out_snd_device == SND_DEVICE_OUT_VOICE_USB_HEADSET) {
1189 ret = audio_extn_usb_enable_sidetone(out_snd_device, enable);
1190 if (ret)
1191 ALOGI("%s: usb device %d does not support device sidetone\n",
1192 __func__, out_snd_device);
1193 } else {
1194 ALOGV("%s: sidetone out device(%d) mixer cmd = %s\n",
1195 __func__, out_snd_device, str);
1196 if (enable)
1197 audio_route_apply_and_update_path(adev->audio_route, str);
1198 else
1199 audio_route_reset_and_update_path(adev->audio_route, str);
1200 }
1201 return 0;
1202}
Haynes Mathew George96483a22017-03-28 14:52:47 -07001203
1204int platform_get_mmap_data_fd(void *platform __unused, int fe_dev __unused, int dir __unused,
1205 int *fd __unused, uint32_t *size __unused)
1206{
1207 return -ENOSYS;
1208}