platform.c revision 7ff216f80f6e53235b4239c6fb7da9b0d5127738
1b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent/*
2b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent * Copyright (C) 2013 The Android Open Source Project
3b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent *
4b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent * Licensed under the Apache License, Version 2.0 (the "License");
5b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent * you may not use this file except in compliance with the License.
6b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent * You may obtain a copy of the License at
7b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent *
8b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent *      http://www.apache.org/licenses/LICENSE-2.0
9b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent *
10b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent * Unless required by applicable law or agreed to in writing, software
11b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent * distributed under the License is distributed on an "AS IS" BASIS,
12b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent * See the License for the specific language governing permissions and
14b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent * limitations under the License.
15b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent */
16b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
17b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent#define LOG_TAG "msm8960_platform"
18b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent/*#define LOG_NDEBUG 0*/
19b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent#define LOG_NDDEBUG 0
20b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
21b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent#include <stdlib.h>
22b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent#include <dlfcn.h>
23b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent#include <cutils/log.h>
24b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent#include <cutils/properties.h>
25b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent#include <audio_hw.h>
26b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent#include <platform_api.h>
27b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent#include "platform.h"
28b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
29b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent#define LIB_ACDB_LOADER "libacdbloader.so"
30b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent#define LIB_CSD_CLIENT "libcsd-client.so"
31b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
32b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent#define DUALMIC_CONFIG_NONE 0      /* Target does not contain 2 mics */
33b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent#define DUALMIC_CONFIG_ENDFIRE 1
34b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent#define DUALMIC_CONFIG_BROADSIDE 2
35b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
36b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent/*
37b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent * This is the sysfs path for the HDMI audio data block
38b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent */
39b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent#define AUDIO_DATA_BLOCK_PATH "/sys/class/graphics/fb1/audio_data_block"
401b9f4b3708d1ed1204bdb1dec370ad2e9db7a779sangwoo#define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
41b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
42b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent/*
43b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent * This file will have a maximum of 38 bytes:
44b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent *
45b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent * 4 bytes: number of audio blocks
46b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent * 4 bytes: total length of Short Audio Descriptor (SAD) blocks
47b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent * Maximum 10 * 3 bytes: SAD blocks
48b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent */
49b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent#define MAX_SAD_BLOCKS      10
50b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent#define SAD_BLOCK_SIZE      3
51b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
52b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent/* EDID format ID for LPCM audio */
53b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent#define EDID_FORMAT_LPCM    1
54b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
55b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentstruct audio_block_header
56b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent{
57b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    int reserved;
58b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    int length;
59b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent};
60b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
61b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
62b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurenttypedef void (*acdb_deallocate_t)();
63b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurenttypedef int  (*acdb_init_t)();
64b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurenttypedef void (*acdb_send_audio_cal_t)(int, int);
65b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurenttypedef void (*acdb_send_voice_cal_t)(int, int);
66b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
67b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurenttypedef int (*csd_client_init_t)();
68b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurenttypedef int (*csd_client_deinit_t)();
69b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurenttypedef int (*csd_disable_device_t)();
70b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurenttypedef int (*csd_enable_device_t)(int, int, uint32_t);
71b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurenttypedef int (*csd_volume_t)(int);
72b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurenttypedef int (*csd_mic_mute_t)(int);
73b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurenttypedef int (*csd_start_voice_t)();
74b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurenttypedef int (*csd_stop_voice_t)();
75b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
76b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
77b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent/* Audio calibration related functions */
78b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentstruct platform_data {
79b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    struct audio_device *adev;
80b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    bool fluence_in_spkr_mode;
81b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    bool fluence_in_voice_call;
82b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    bool fluence_in_voice_rec;
83b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    int  dualmic_config;
84b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
85b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    void *acdb_handle;
86b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    acdb_init_t acdb_init;
87b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    acdb_deallocate_t acdb_deallocate;
88b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    acdb_send_audio_cal_t acdb_send_audio_cal;
89b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    acdb_send_voice_cal_t acdb_send_voice_cal;
90b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
91b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    /* CSD Client related functions for voice call */
92b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    void *csd_client;
93b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    csd_client_init_t csd_client_init;
94b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    csd_client_deinit_t csd_client_deinit;
95b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    csd_disable_device_t csd_disable_device;
96b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    csd_enable_device_t csd_enable_device;
97b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    csd_volume_t csd_volume;
98b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    csd_mic_mute_t csd_mic_mute;
99b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    csd_start_voice_t csd_start_voice;
100b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    csd_stop_voice_t csd_stop_voice;
101b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent};
102b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
103b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentstatic const int pcm_device_table[AUDIO_USECASE_MAX][2] = {
104b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = {0, 0},
105b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = {14, 14},
106b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [USECASE_AUDIO_PLAYBACK_MULTI_CH] = {1, 1},
107b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [USECASE_AUDIO_RECORD] = {0, 0},
108b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [USECASE_AUDIO_RECORD_LOW_LATENCY] = {14, 14},
109b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [USECASE_VOICE_CALL] = {12, 12},
110b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent};
111b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
112b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent/* Array to store sound devices */
113b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentstatic const char * const device_table[SND_DEVICE_MAX] = {
114b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_NONE] = "none",
115b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    /* Playback sound devices */
116b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_HANDSET] = "handset",
117b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_SPEAKER] = "speaker",
118b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
119b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_HEADPHONES] = "headphones",
120b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
121b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_VOICE_SPEAKER] = "voice-speaker",
122b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_VOICE_HEADPHONES] = "voice-headphones",
123b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_HDMI] = "hdmi",
124b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = "speaker-and-hdmi",
125b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_BT_SCO] = "bt-sco-headset",
126b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = "voice-handset-tmus",
127b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = "voice-tty-full-headphones",
128b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = "voice-tty-vco-headphones",
129b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = "voice-tty-hco-handset",
130b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
131b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    /* Capture sound devices */
132b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",
133b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_SPEAKER_MIC] = "speaker-mic",
134b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_HEADSET_MIC] = "headset-mic",
135b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_HANDSET_MIC_AEC] = "handset-mic",
136b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_SPEAKER_MIC_AEC] = "voice-speaker-mic",
137b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_HEADSET_MIC_AEC] = "headset-mic",
138b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = "voice-speaker-mic",
139b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_HEADSET_MIC] = "voice-headset-mic",
140b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_HDMI_MIC] = "hdmi-mic",
141b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_BT_SCO_MIC] = "bt-sco-mic",
142b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_CAMCORDER_MIC] = "camcorder-mic",
143b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_DMIC_EF] = "voice-dmic-ef",
144b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_DMIC_BS] = "voice-dmic-bs",
145b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_DMIC_EF_TMUS] = "voice-dmic-ef-tmus",
146b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_EF] = "voice-speaker-dmic-ef",
147b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BS] = "voice-speaker-dmic-bs",
148b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = "voice-tty-full-headset-mic",
149b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = "voice-tty-vco-handset-mic",
150b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = "voice-tty-hco-headset-mic",
151b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_REC_MIC] = "voice-rec-mic",
152b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_REC_DMIC_EF] = "voice-rec-dmic-ef",
153b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_REC_DMIC_BS] = "voice-rec-dmic-bs",
154b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_REC_DMIC_EF_FLUENCE] = "voice-rec-dmic-ef-fluence",
155b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_REC_DMIC_BS_FLUENCE] = "voice-rec-dmic-bs-fluence",
156b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent};
157b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
158b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent/* ACDB IDs (audio DSP path configuration IDs) for each sound device */
159b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentstatic const int acdb_device_table[SND_DEVICE_MAX] = {
160b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_NONE] = -1,
161b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_HANDSET] = 7,
162b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_SPEAKER] = 14,
163b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_SPEAKER_REVERSE] = 14,
164b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_HEADPHONES] = 10,
165b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
166b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_VOICE_SPEAKER] = 14,
167b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_VOICE_HEADPHONES] = 10,
168b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_HDMI] = 18,
169b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_SPEAKER_AND_HDMI] = 14,
170b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_BT_SCO] = 22,
171b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_VOICE_HANDSET_TMUS] = 81,
172b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES] = 17,
173b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES] = 17,
174b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET] = 37,
175b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
176b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_HANDSET_MIC] = 4,
177b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_SPEAKER_MIC] = 4,
178b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_HEADSET_MIC] = 8,
179b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_HANDSET_MIC_AEC] = 40,
180b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_SPEAKER_MIC_AEC] = 42,
181b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_HEADSET_MIC_AEC] = 47,
182b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_SPEAKER_MIC] = 11,
183b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_HEADSET_MIC] = 8,
184b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_HDMI_MIC] = 4,
185b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_BT_SCO_MIC] = 21,
186b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_CAMCORDER_MIC] = 61,
187b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_DMIC_EF] = 6,
188b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_DMIC_BS] = 5,
189b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_DMIC_EF_TMUS] = 91,
190b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_EF] = 13,
191b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BS] = 12,
192b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC] = 16,
193b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC] = 36,
194b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC] = 16,
195b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_REC_MIC] = 62,
196b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    /* TODO: Update with proper acdb ids */
197b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_REC_DMIC_EF] = 62,
198b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_REC_DMIC_BS] = 62,
199b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_REC_DMIC_EF_FLUENCE] = 6,
200b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    [SND_DEVICE_IN_VOICE_REC_DMIC_BS_FLUENCE] = 5,
201b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent};
202b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
2037ff216f80f6e53235b4239c6fb7da9b0d5127738Haynes Mathew George#define DEEP_BUFFER_PLATFORM_DELAY (29*1000LL)
2047ff216f80f6e53235b4239c6fb7da9b0d5127738Haynes Mathew George#define LOW_LATENCY_PLATFORM_DELAY (13*1000LL)
2057ff216f80f6e53235b4239c6fb7da9b0d5127738Haynes Mathew George
206b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentstatic pthread_once_t check_op_once_ctl = PTHREAD_ONCE_INIT;
207b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentstatic bool is_tmus = false;
208b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
209b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentstatic void check_operator()
210b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent{
211b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    char value[PROPERTY_VALUE_MAX];
212b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    int mccmnc;
213b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    property_get("gsm.sim.operator.numeric",value,"0");
214b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    mccmnc = atoi(value);
215b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    ALOGD("%s: tmus mccmnc %d", __func__, mccmnc);
216b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    switch(mccmnc) {
217b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    /* TMUS MCC(310), MNC(490, 260, 026) */
218b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    case 310490:
219b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    case 310260:
220b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    case 310026:
221b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        is_tmus = true;
222b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        break;
223b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
224b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent}
225b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
226b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentbool is_operator_tmus()
227b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent{
228b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    pthread_once(&check_op_once_ctl, check_operator);
229b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    return is_tmus;
230b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent}
231b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
232b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentstatic int set_echo_reference(struct mixer *mixer, const char* ec_ref)
233b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent{
234b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    struct mixer_ctl *ctl;
235b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    const char *mixer_ctl_name = "EC_REF_RX";
236b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
237b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name);
238b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (!ctl) {
239b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        ALOGE("%s: Could not get ctl for mixer cmd - %s",
240b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent              __func__, mixer_ctl_name);
241b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        return -EINVAL;
242b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
243b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    ALOGV("Setting EC Reference: %s", ec_ref);
244b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    mixer_ctl_set_enum_by_string(ctl, ec_ref);
245b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    return 0;
246b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent}
247b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
248b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentvoid *platform_init(struct audio_device *adev)
249b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent{
250b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    char platform[PROPERTY_VALUE_MAX];
251b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    char baseband[PROPERTY_VALUE_MAX];
252b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    char value[PROPERTY_VALUE_MAX];
253b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    struct platform_data *my_data;
254b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
2551b9f4b3708d1ed1204bdb1dec370ad2e9db7a779sangwoo    adev->mixer = mixer_open(MIXER_CARD);
2561b9f4b3708d1ed1204bdb1dec370ad2e9db7a779sangwoo
2571b9f4b3708d1ed1204bdb1dec370ad2e9db7a779sangwoo    if (!adev->mixer) {
2581b9f4b3708d1ed1204bdb1dec370ad2e9db7a779sangwoo        ALOGE("Unable to open the mixer, aborting.");
2591b9f4b3708d1ed1204bdb1dec370ad2e9db7a779sangwoo        return NULL;
2601b9f4b3708d1ed1204bdb1dec370ad2e9db7a779sangwoo    }
2611b9f4b3708d1ed1204bdb1dec370ad2e9db7a779sangwoo
2621b9f4b3708d1ed1204bdb1dec370ad2e9db7a779sangwoo    adev->audio_route = audio_route_init(MIXER_CARD, MIXER_XML_PATH);
2631b9f4b3708d1ed1204bdb1dec370ad2e9db7a779sangwoo    if (!adev->audio_route) {
2641b9f4b3708d1ed1204bdb1dec370ad2e9db7a779sangwoo        ALOGE("%s: Failed to init audio route controls, aborting.", __func__);
2651b9f4b3708d1ed1204bdb1dec370ad2e9db7a779sangwoo        return NULL;
2661b9f4b3708d1ed1204bdb1dec370ad2e9db7a779sangwoo    }
2671b9f4b3708d1ed1204bdb1dec370ad2e9db7a779sangwoo
268b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    my_data = calloc(1, sizeof(struct platform_data));
269b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
270b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    my_data->adev = adev;
271b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    my_data->dualmic_config = DUALMIC_CONFIG_NONE;
272b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    my_data->fluence_in_spkr_mode = false;
273b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    my_data->fluence_in_voice_call = false;
274b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    my_data->fluence_in_voice_rec = false;
275b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
276b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    property_get("persist.audio.dualmic.config",value,"");
277b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (!strcmp("broadside", value)) {
278b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        my_data->dualmic_config = DUALMIC_CONFIG_BROADSIDE;
279b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        adev->acdb_settings |= DMIC_FLAG;
280b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    } else if (!strcmp("endfire", value)) {
281b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        my_data->dualmic_config = DUALMIC_CONFIG_ENDFIRE;
282b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        adev->acdb_settings |= DMIC_FLAG;
283b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
284b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
285b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (my_data->dualmic_config != DUALMIC_CONFIG_NONE) {
286b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        property_get("persist.audio.fluence.voicecall",value,"");
287b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (!strcmp("true", value)) {
288b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            my_data->fluence_in_voice_call = true;
289b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        }
290b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
291b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        property_get("persist.audio.fluence.voicerec",value,"");
292b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (!strcmp("true", value)) {
293b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            my_data->fluence_in_voice_rec = true;
294b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        }
295b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
296b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        property_get("persist.audio.fluence.speaker",value,"");
297b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (!strcmp("true", value)) {
298b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            my_data->fluence_in_spkr_mode = true;
299b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        }
300b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
301b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
302b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
303b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (my_data->acdb_handle == NULL) {
304b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        ALOGE("%s: DLOPEN failed for %s", __func__, LIB_ACDB_LOADER);
305b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    } else {
306b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        ALOGV("%s: DLOPEN successful for %s", __func__, LIB_ACDB_LOADER);
307b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        my_data->acdb_deallocate = (acdb_deallocate_t)dlsym(my_data->acdb_handle,
308b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                                                    "acdb_loader_deallocate_ACDB");
309b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        my_data->acdb_send_audio_cal = (acdb_send_audio_cal_t)dlsym(my_data->acdb_handle,
310b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                                                    "acdb_loader_send_audio_cal");
311b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (!my_data->acdb_send_audio_cal)
312b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            ALOGW("%s: Could not find the symbol acdb_send_audio_cal from %s",
313b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                  __func__, LIB_ACDB_LOADER);
314b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        my_data->acdb_send_voice_cal = (acdb_send_voice_cal_t)dlsym(my_data->acdb_handle,
315b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                                                    "acdb_loader_send_voice_cal");
316b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        my_data->acdb_init = (acdb_init_t)dlsym(my_data->acdb_handle,
317b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                                                    "acdb_loader_init_ACDB");
318b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (my_data->acdb_init == NULL)
319b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            ALOGE("%s: dlsym error %s for acdb_loader_init_ACDB", __func__, dlerror());
320b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        else
321b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            my_data->acdb_init();
322b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
323b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
324b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    /* If platform is Fusion3, load CSD Client specific symbols
325b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent     * Voice call is handled by MDM and apps processor talks to
326b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent     * MDM through CSD Client
327b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent     */
328b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    property_get("ro.board.platform", platform, "");
329b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    property_get("ro.baseband", baseband, "");
330b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (!strcmp("msm8960", platform) && !strcmp("mdm", baseband)) {
331b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        my_data->csd_client = dlopen(LIB_CSD_CLIENT, RTLD_NOW);
332b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (my_data->csd_client == NULL)
333b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            ALOGE("%s: DLOPEN failed for %s", __func__, LIB_CSD_CLIENT);
334b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
335b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
336b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (my_data->csd_client) {
337b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        ALOGV("%s: DLOPEN successful for %s", __func__, LIB_CSD_CLIENT);
338b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        my_data->csd_client_deinit = (csd_client_deinit_t)dlsym(my_data->csd_client,
339b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                                                    "csd_client_deinit");
340b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        my_data->csd_disable_device = (csd_disable_device_t)dlsym(my_data->csd_client,
341b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                                                    "csd_client_disable_device");
342b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        my_data->csd_enable_device = (csd_enable_device_t)dlsym(my_data->csd_client,
343b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                                                    "csd_client_enable_device");
344b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        my_data->csd_start_voice = (csd_start_voice_t)dlsym(my_data->csd_client,
345b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                                                    "csd_client_start_voice");
346b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        my_data->csd_stop_voice = (csd_stop_voice_t)dlsym(my_data->csd_client,
347b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                                                    "csd_client_stop_voice");
348b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        my_data->csd_volume = (csd_volume_t)dlsym(my_data->csd_client,
349b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                                                    "csd_client_volume");
350b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        my_data->csd_mic_mute = (csd_mic_mute_t)dlsym(my_data->csd_client,
351b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                                                    "csd_client_mic_mute");
352b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        my_data->csd_client_init = (csd_client_init_t)dlsym(my_data->csd_client,
353b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                                                    "csd_client_init");
354b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
355b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (my_data->csd_client_init == NULL) {
356b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            ALOGE("%s: dlsym error %s for csd_client_init", __func__, dlerror());
357b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else {
358b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            my_data->csd_client_init();
359b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        }
360b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
361b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
362b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    return my_data;
363b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent}
364b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
365b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentvoid platform_deinit(void *platform)
366b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent{
367b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    free(platform);
368b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent}
369b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
370b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentconst char *platform_get_snd_device_name(snd_device_t snd_device)
371b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent{
372b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX)
373b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        return device_table[snd_device];
374b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    else
375b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        return "";
376b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent}
377b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
378b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentvoid platform_add_backend_name(char *mixer_path, snd_device_t snd_device)
379b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent{
380b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (snd_device == SND_DEVICE_IN_BT_SCO_MIC)
381b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        strcat(mixer_path, " bt-sco");
382b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    else if(snd_device == SND_DEVICE_OUT_BT_SCO)
383b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        strcat(mixer_path, " bt-sco");
384b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    else if (snd_device == SND_DEVICE_OUT_HDMI)
385b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        strcat(mixer_path, " hdmi");
386b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HDMI)
387b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        strcat(mixer_path, " speaker-and-hdmi");
388b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent}
389b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
390b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentint platform_get_pcm_device_id(audio_usecase_t usecase, int device_type)
391b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent{
392b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    int device_id;
393b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (device_type == PCM_PLAYBACK)
394b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        device_id = pcm_device_table[usecase][0];
395b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    else
396b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        device_id = pcm_device_table[usecase][1];
397b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    return device_id;
398b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent}
399b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
400b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentint platform_send_audio_calibration(void *platform, snd_device_t snd_device)
401b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent{
402b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    struct platform_data *my_data = (struct platform_data *)platform;
403b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    int acdb_dev_id, acdb_dev_type;
404b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
405b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    acdb_dev_id = acdb_device_table[snd_device];
406b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (acdb_dev_id < 0) {
407b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        ALOGE("%s: Could not find acdb id for device(%d)",
408b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent              __func__, snd_device);
409b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        return -EINVAL;
410b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
411b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (my_data->acdb_send_audio_cal) {
412994a693158202488516c48c22534ae2035b5c8faEric Laurent        ("%s: sending audio calibration for snd_device(%d) acdb_id(%d)",
413b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent              __func__, snd_device, acdb_dev_id);
414b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (snd_device >= SND_DEVICE_OUT_BEGIN &&
415b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                snd_device < SND_DEVICE_OUT_END)
416b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            acdb_dev_type = ACDB_DEV_TYPE_OUT;
417b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        else
418b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            acdb_dev_type = ACDB_DEV_TYPE_IN;
419b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        my_data->acdb_send_audio_cal(acdb_dev_id, acdb_dev_type);
420b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
421b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    return 0;
422b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent}
423b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
424b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentint platform_switch_voice_call_device_pre(void *platform)
425b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent{
426b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    struct platform_data *my_data = (struct platform_data *)platform;
427b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    int ret = 0;
428b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
429b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (my_data->csd_client != NULL) {
430b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        /* This must be called before disabling the mixer controls on APQ side */
431b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (my_data->csd_disable_device == NULL) {
432b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            ALOGE("%s: dlsym error for csd_disable_device", __func__);
433b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else {
434b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            ret = my_data->csd_disable_device();
435b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            if (ret < 0) {
436b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                ALOGE("%s: csd_client_disable_device, failed, error %d",
437b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                      __func__, ret);
438b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            }
439b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        }
440b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
441b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    return ret;
442b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent}
443b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
444b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentint platform_switch_voice_call_device_post(void *platform,
445b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                                           snd_device_t out_snd_device,
446b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                                           snd_device_t in_snd_device)
447b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent{
448b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    struct platform_data *my_data = (struct platform_data *)platform;
449b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    int acdb_rx_id, acdb_tx_id;
450b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    int ret = 0;
451b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
452b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (my_data->csd_client) {
453b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (my_data->csd_enable_device == NULL) {
454b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            ALOGE("%s: dlsym error for csd_enable_device",
455b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                  __func__);
456b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else {
457b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            acdb_rx_id = acdb_device_table[out_snd_device];
458b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            acdb_tx_id = acdb_device_table[in_snd_device];
459b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
460b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            if (acdb_rx_id > 0 || acdb_tx_id > 0) {
461b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                ret = my_data->csd_enable_device(acdb_rx_id, acdb_tx_id,
462b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                                                    my_data->adev->acdb_settings);
463b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                if (ret < 0) {
464b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                    ALOGE("%s: csd_enable_device, failed, error %d",
465b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                          __func__, ret);
466b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                }
467b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            } else {
468b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                ALOGE("%s: Incorrect ACDB IDs (rx: %d tx: %d)", __func__,
469b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                      acdb_rx_id, acdb_tx_id);
470b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            }
471b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        }
472b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
473b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
474b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    return ret;
475b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent}
476b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
477b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentint platform_start_voice_call(void *platform)
478b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent{
479b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    struct platform_data *my_data = (struct platform_data *)platform;
480b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    int ret = 0;
481b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
482b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (my_data->csd_client) {
483b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (my_data->csd_start_voice == NULL) {
484b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            ALOGE("dlsym error for csd_client_start_voice");
485b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            ret = -ENOSYS;
486b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else {
487b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            ret = my_data->csd_start_voice();
488b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            if (ret < 0) {
489b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                ALOGE("%s: csd_start_voice error %d\n", __func__, ret);
490b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            }
491b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        }
492b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
493b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
494b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    return ret;
495b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent}
496b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
497b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentint platform_stop_voice_call(void *platform)
498b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent{
499b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    struct platform_data *my_data = (struct platform_data *)platform;
500b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    int ret = 0;
501b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
502b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (my_data->csd_client) {
503b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (my_data->csd_stop_voice == NULL) {
504b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            ALOGE("dlsym error for csd_stop_voice");
505b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else {
506b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            ret = my_data->csd_stop_voice();
507b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            if (ret < 0) {
508b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                ALOGE("%s: csd_stop_voice error %d\n", __func__, ret);
509b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            }
510b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        }
511b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
512b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
513b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    return ret;
514b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent}
515b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
516b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentint platform_set_voice_volume(void *platform, int volume)
517b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent{
518b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    struct platform_data *my_data = (struct platform_data *)platform;
519b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    int ret = 0;
520b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
521b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (my_data->csd_client) {
522b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (my_data->csd_volume == NULL) {
523b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            ALOGE("%s: dlsym error for csd_volume", __func__);
524b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else {
525b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            ret = my_data->csd_volume(volume);
526b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            if (ret < 0) {
527b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                ALOGE("%s: csd_volume error %d", __func__, ret);
528b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            }
529b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        }
530b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    } else {
531b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        ALOGE("%s: No CSD Client present", __func__);
532b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
533b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
534b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    return ret;
535b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent}
536b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
537b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentint platform_set_mic_mute(void *platform, bool state)
538b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent{
539b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    struct platform_data *my_data = (struct platform_data *)platform;
540b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    int ret = 0;
541b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
542b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (my_data->adev->mode == AUDIO_MODE_IN_CALL) {
543b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (my_data->csd_client) {
544b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            if (my_data->csd_mic_mute == NULL) {
545b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                ALOGE("%s: dlsym error for csd_mic_mute", __func__);
546b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            } else {
547b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                ret = my_data->csd_mic_mute(state);
548b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                if (ret < 0) {
549b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                    ALOGE("%s: csd_mic_mute error %d", __func__, ret);
550b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                }
551b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            }
552b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else {
553b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            ALOGE("%s: No CSD Client present", __func__);
554b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        }
555b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
556b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
557b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    return ret;
558b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent}
559b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
560b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentsnd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices)
561b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent{
562b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    struct platform_data *my_data = (struct platform_data *)platform;
563b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    struct audio_device *adev = my_data->adev;
564b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    audio_mode_t mode = adev->mode;
565b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    snd_device_t snd_device = SND_DEVICE_NONE;
566b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
567b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    ALOGV("%s: enter: output devices(%#x)", __func__, devices);
568b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (devices == AUDIO_DEVICE_NONE ||
569b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        devices & AUDIO_DEVICE_BIT_IN) {
570b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        ALOGV("%s: Invalid output devices (%#x)", __func__, devices);
571b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        goto exit;
572b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
573b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
574b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (mode == AUDIO_MODE_IN_CALL) {
575b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
576b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
577b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            if (adev->tty_mode == TTY_MODE_FULL)
578b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                snd_device = SND_DEVICE_OUT_VOICE_TTY_FULL_HEADPHONES;
579b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            else if (adev->tty_mode == TTY_MODE_VCO)
580b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                snd_device = SND_DEVICE_OUT_VOICE_TTY_VCO_HEADPHONES;
581b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            else if (adev->tty_mode == TTY_MODE_HCO)
582b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                snd_device = SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET;
583b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            else
584b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                snd_device = SND_DEVICE_OUT_VOICE_HEADPHONES;
585b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
586b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            snd_device = SND_DEVICE_OUT_BT_SCO;
587b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
588b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            snd_device = SND_DEVICE_OUT_VOICE_SPEAKER;
589b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
590b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            if (is_operator_tmus())
591b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                snd_device = SND_DEVICE_OUT_VOICE_HANDSET_TMUS;
592b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            else
593b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                snd_device = SND_DEVICE_OUT_HANDSET;
594b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        }
595b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (snd_device != SND_DEVICE_NONE) {
596b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            goto exit;
597b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        }
598b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
599b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
600b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (popcount(devices) == 2) {
601b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
602b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                        AUDIO_DEVICE_OUT_SPEAKER)) {
603b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
604b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
605b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                               AUDIO_DEVICE_OUT_SPEAKER)) {
606b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
607b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
608b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                               AUDIO_DEVICE_OUT_SPEAKER)) {
609b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI;
610b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else {
611b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
612b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            goto exit;
613b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        }
614b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (snd_device != SND_DEVICE_NONE) {
615b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            goto exit;
616b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        }
617b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
618b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
619b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (popcount(devices) != 1) {
620b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
621b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        goto exit;
622b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
623b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
624b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
625b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
626b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        snd_device = SND_DEVICE_OUT_HEADPHONES;
627b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    } else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
628b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (adev->speaker_lr_swap)
629b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            snd_device = SND_DEVICE_OUT_SPEAKER_REVERSE;
630b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        else
631b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            snd_device = SND_DEVICE_OUT_SPEAKER;
632b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    } else if (devices & AUDIO_DEVICE_OUT_ALL_SCO) {
633b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        snd_device = SND_DEVICE_OUT_BT_SCO;
634b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    } else if (devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
635b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        snd_device = SND_DEVICE_OUT_HDMI ;
636b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    } else if (devices & AUDIO_DEVICE_OUT_EARPIECE) {
637b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        snd_device = SND_DEVICE_OUT_HANDSET;
638b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    } else {
639b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        ALOGE("%s: Unknown device(s) %#x", __func__, devices);
640b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
641b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentexit:
642b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    ALOGV("%s: exit: snd_device(%s)", __func__, device_table[snd_device]);
643b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    return snd_device;
644b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent}
645b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
646b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentsnd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device)
647b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent{
648b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    struct platform_data *my_data = (struct platform_data *)platform;
649b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    struct audio_device *adev = my_data->adev;
650b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    audio_source_t  source = (adev->active_input == NULL) ?
651b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                                AUDIO_SOURCE_DEFAULT : adev->active_input->source;
652b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
653b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    audio_mode_t    mode   = adev->mode;
654b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    audio_devices_t in_device = ((adev->active_input == NULL) ?
655b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                                    AUDIO_DEVICE_NONE : adev->active_input->device)
656b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                                & ~AUDIO_DEVICE_BIT_IN;
657b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
658b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                                AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
659b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    snd_device_t snd_device = SND_DEVICE_NONE;
660b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
661b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
662b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent          __func__, out_device, in_device);
663b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (mode == AUDIO_MODE_IN_CALL) {
664b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (out_device == AUDIO_DEVICE_NONE) {
665b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            ALOGE("%s: No output device set for voice call", __func__);
666b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            goto exit;
667b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        }
668b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (adev->tty_mode != TTY_MODE_OFF) {
669b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
670b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
671b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                switch (adev->tty_mode) {
672b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                case TTY_MODE_FULL:
673b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                    snd_device = SND_DEVICE_IN_VOICE_TTY_FULL_HEADSET_MIC;
674b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                    break;
675b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                case TTY_MODE_VCO:
676b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                    snd_device = SND_DEVICE_IN_VOICE_TTY_VCO_HANDSET_MIC;
677b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                    break;
678b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                case TTY_MODE_HCO:
679b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                    snd_device = SND_DEVICE_IN_VOICE_TTY_HCO_HEADSET_MIC;
680b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                    break;
681b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                default:
682b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                    ALOGE("%s: Invalid TTY mode (%#x)", __func__, adev->tty_mode);
683b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                }
684b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                goto exit;
685b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            }
686b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        }
687b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (out_device & AUDIO_DEVICE_OUT_EARPIECE ||
688b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
689b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            if (my_data->fluence_in_voice_call == false) {
690b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                snd_device = SND_DEVICE_IN_HANDSET_MIC;
691b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            } else {
692b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                if (my_data->dualmic_config == DUALMIC_CONFIG_ENDFIRE) {
693b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                    if (is_operator_tmus())
694b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                        snd_device = SND_DEVICE_IN_VOICE_DMIC_EF_TMUS;
695b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                    else
696b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                        snd_device = SND_DEVICE_IN_VOICE_DMIC_EF;
697b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                } else if(my_data->dualmic_config == DUALMIC_CONFIG_BROADSIDE)
698b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                    snd_device = SND_DEVICE_IN_VOICE_DMIC_BS;
699b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                else
700b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                    snd_device = SND_DEVICE_IN_HANDSET_MIC;
701b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            }
702b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
703b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            snd_device = SND_DEVICE_IN_VOICE_HEADSET_MIC;
704b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else if (out_device & AUDIO_DEVICE_OUT_ALL_SCO) {
705b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            snd_device = SND_DEVICE_IN_BT_SCO_MIC ;
706b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
707b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            if (my_data->fluence_in_voice_call && my_data->fluence_in_spkr_mode &&
708b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                    my_data->dualmic_config == DUALMIC_CONFIG_ENDFIRE) {
709b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC_EF;
710b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            } else if (my_data->fluence_in_voice_call && my_data->fluence_in_spkr_mode &&
711b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                    my_data->dualmic_config == DUALMIC_CONFIG_BROADSIDE) {
712b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                snd_device = SND_DEVICE_IN_VOICE_SPEAKER_DMIC_BS;
713b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            } else {
714b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                snd_device = SND_DEVICE_IN_VOICE_SPEAKER_MIC;
715b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            }
716b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        }
717b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    } else if (source == AUDIO_SOURCE_CAMCORDER) {
718b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
719b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            in_device & AUDIO_DEVICE_IN_BACK_MIC) {
720b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
721b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        }
722b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    } else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
723b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
724b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            if (my_data->dualmic_config == DUALMIC_CONFIG_ENDFIRE) {
725b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                if (channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK)
726b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                    snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_EF;
727b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                else if (my_data->fluence_in_voice_rec)
728b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                    snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_EF_FLUENCE;
729b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            } else if (my_data->dualmic_config == DUALMIC_CONFIG_BROADSIDE) {
730b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                if (channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK)
731b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                    snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_BS;
732b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                else if (my_data->fluence_in_voice_rec)
733b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                    snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_BS_FLUENCE;
734b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            }
735b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
736b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            if (snd_device == SND_DEVICE_NONE) {
737b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
738b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            }
739b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        }
740b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    } else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
741b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
742b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            in_device = AUDIO_DEVICE_IN_BACK_MIC;
743b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (adev->active_input) {
744b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            if (adev->active_input->enable_aec) {
745b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
746b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                    snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
747b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                } else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
748b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                    snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
749b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
750b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                    snd_device = SND_DEVICE_IN_HEADSET_MIC_AEC;
751b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                }
752b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                set_echo_reference(adev->mixer, "SLIM_RX");
753b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            } else
754b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent                set_echo_reference(adev->mixer, "NONE");
755b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        }
756b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    } else if (source == AUDIO_SOURCE_DEFAULT) {
757b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        goto exit;
758b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
759b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
760b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
761b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (snd_device != SND_DEVICE_NONE) {
762b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        goto exit;
763b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
764b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
765b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (in_device != AUDIO_DEVICE_NONE &&
766b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            !(in_device & AUDIO_DEVICE_IN_VOICE_CALL) &&
767b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            !(in_device & AUDIO_DEVICE_IN_COMMUNICATION)) {
768b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
769b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            snd_device = SND_DEVICE_IN_HANDSET_MIC;
770b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
771b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            snd_device = SND_DEVICE_IN_SPEAKER_MIC;
772b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
773b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            snd_device = SND_DEVICE_IN_HEADSET_MIC;
774b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else if (in_device & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
775b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            snd_device = SND_DEVICE_IN_BT_SCO_MIC ;
776b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else if (in_device & AUDIO_DEVICE_IN_AUX_DIGITAL) {
777b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            snd_device = SND_DEVICE_IN_HDMI_MIC;
778b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else {
779b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            ALOGE("%s: Unknown input device(s) %#x", __func__, in_device);
780b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            ALOGW("%s: Using default handset-mic", __func__);
781b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            snd_device = SND_DEVICE_IN_HANDSET_MIC;
782b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        }
783b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    } else {
784b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (out_device & AUDIO_DEVICE_OUT_EARPIECE) {
785b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            snd_device = SND_DEVICE_IN_HANDSET_MIC;
786b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
787b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            snd_device = SND_DEVICE_IN_HEADSET_MIC;
788b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
789b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            snd_device = SND_DEVICE_IN_SPEAKER_MIC;
790b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
791b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            snd_device = SND_DEVICE_IN_HANDSET_MIC;
792b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else if (out_device & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET) {
793b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            snd_device = SND_DEVICE_IN_BT_SCO_MIC;
794b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else if (out_device & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
795b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            snd_device = SND_DEVICE_IN_HDMI_MIC;
796b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        } else {
797b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            ALOGE("%s: Unknown output device(s) %#x", __func__, out_device);
798b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            ALOGW("%s: Using default handset-mic", __func__);
799b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            snd_device = SND_DEVICE_IN_HANDSET_MIC;
800b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        }
801b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
802b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentexit:
803b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    ALOGV("%s: exit: in_snd_device(%s)", __func__, device_table[snd_device]);
804b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    return snd_device;
805b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent}
806b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
807b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurentint platform_set_hdmi_channels(void *platform,  int channel_count)
808b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent{
809b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    struct platform_data *my_data = (struct platform_data *)platform;
810b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    struct audio_device *adev = my_data->adev;
811b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    struct mixer_ctl *ctl;
812b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    const char *channel_cnt_str = NULL;
813b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    const char *mixer_ctl_name = "HDMI_RX Channels";
814b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    switch (channel_count) {
815b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    case 8:
816b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        channel_cnt_str = "Eight"; break;
817b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    case 7:
818b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        channel_cnt_str = "Seven"; break;
819b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    case 6:
820b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        channel_cnt_str = "Six"; break;
821b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    case 5:
822b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        channel_cnt_str = "Five"; break;
823b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    case 4:
824b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        channel_cnt_str = "Four"; break;
825b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    case 3:
826b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        channel_cnt_str = "Three"; break;
827b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    default:
828b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        channel_cnt_str = "Two"; break;
829b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
830b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
831b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (!ctl) {
832b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        ALOGE("%s: Could not get ctl for mixer cmd - %s",
833b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent              __func__, mixer_ctl_name);
834b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        return -EINVAL;
835b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
836b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    ALOGV("HDMI channel count: %s", channel_cnt_str);
837b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    mixer_ctl_set_enum_by_string(ctl, channel_cnt_str);
838b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    return 0;
839b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent}
840b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
84147cd4cbdb19543338d5c887e3d7bcd2513c5c3adHaynes Mathew Georgeint platform_edid_get_max_channels(void *platform)
842b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent{
843b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    FILE *file;
844b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    struct audio_block_header header;
845b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    char block[MAX_SAD_BLOCKS * SAD_BLOCK_SIZE];
846b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    char *sad = block;
847b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    int num_audio_blocks;
848b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    int channel_count;
849b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    int max_channels = 0;
850b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    int i;
851b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
852b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    file = fopen(AUDIO_DATA_BLOCK_PATH, "rb");
853b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (file == NULL) {
854b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        ALOGE("Unable to open '%s'", AUDIO_DATA_BLOCK_PATH);
855b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        return 0;
856b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
857b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
858b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    /* Read audio block header */
859b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    fread(&header, 1, sizeof(header), file);
860b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
861b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    /* Read SAD blocks, clamping the maximum size for safety */
862b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    if (header.length > (int)sizeof(block))
863b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        header.length = (int)sizeof(block);
864b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    fread(&block, header.length, 1, file);
865b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
866b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    fclose(file);
867b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
868b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    /* Calculate the number of SAD blocks */
869b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    num_audio_blocks = header.length / SAD_BLOCK_SIZE;
870b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
871b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    for (i = 0; i < num_audio_blocks; i++) {
872b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        /* Only consider LPCM blocks */
873b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if ((sad[0] >> 3) != EDID_FORMAT_LPCM)
874b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            continue;
875b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
876b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        channel_count = (sad[0] & 0x7) + 1;
877b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        if (channel_count > max_channels)
878b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent            max_channels = channel_count;
879b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
880b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        /* Advance to next block */
881b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent        sad += 3;
882b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    }
883b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent
884b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent    return max_channels;
885b23d5286490ad2dc0edf919d52428fa02dc2b2dcEric Laurent}
8867ff216f80f6e53235b4239c6fb7da9b0d5127738Haynes Mathew George
8877ff216f80f6e53235b4239c6fb7da9b0d5127738Haynes Mathew George/* Delay in Us */
8887ff216f80f6e53235b4239c6fb7da9b0d5127738Haynes Mathew Georgeint64_t platform_render_latency(audio_usecase_t usecase)
8897ff216f80f6e53235b4239c6fb7da9b0d5127738Haynes Mathew George{
8907ff216f80f6e53235b4239c6fb7da9b0d5127738Haynes Mathew George    switch (usecase) {
8917ff216f80f6e53235b4239c6fb7da9b0d5127738Haynes Mathew George        case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
8927ff216f80f6e53235b4239c6fb7da9b0d5127738Haynes Mathew George            return DEEP_BUFFER_PLATFORM_DELAY;
8937ff216f80f6e53235b4239c6fb7da9b0d5127738Haynes Mathew George        case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
8947ff216f80f6e53235b4239c6fb7da9b0d5127738Haynes Mathew George            return LOW_LATENCY_PLATFORM_DELAY;
8957ff216f80f6e53235b4239c6fb7da9b0d5127738Haynes Mathew George        default:
8967ff216f80f6e53235b4239c6fb7da9b0d5127738Haynes Mathew George            return 0;
8977ff216f80f6e53235b4239c6fb7da9b0d5127738Haynes Mathew George    }
8987ff216f80f6e53235b4239c6fb7da9b0d5127738Haynes Mathew George}
899