audio: Select device based on supported mic count
source_mic_type is obtained using max mic count. Default value
is dual mic.
If fluence is enabled, device is selected based on fluence type set
and mic count supported.
For VoiceRecognition source, channel count should be 1 to enable
fluence.
Add support for 3 and 4 channel recording.
Change-Id: I4c7229230b79830a66e25cc49d80f1e7090c0212
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index ad565de..2a7895c 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -2009,6 +2009,8 @@
switch (channel_count) {
case 1:
case 2:
+ case 3:
+ case 4:
case 6:
break;
default:
@@ -3985,8 +3987,10 @@
bool is_low_latency = false;
*stream_in = NULL;
- if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0)
+ if (check_input_parameters(config->sample_rate, config->format, channel_count) != 0) {
+ ALOGE("%s: invalid input parameters", __func__);
return -EINVAL;
+ }
in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 0e85353..8ce4ccb 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -259,6 +259,8 @@
char cvd_version[MAX_CVD_VERSION_STRING_SIZE];
char snd_card_name[MAX_SND_CARD_STRING_SIZE];
int metainfo_key;
+ int source_mic_type;
+ int max_mic_count;
};
static bool is_external_codec = false;
@@ -441,6 +443,7 @@
[SND_DEVICE_IN_SPEAKER_QMIC_NS] = "quad-mic",
[SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = "quad-mic",
[SND_DEVICE_IN_THREE_MIC] = "three-mic",
+ [SND_DEVICE_IN_HANDSET_TMIC] = "three-mic",
};
// Platform specific backend bit width table
@@ -552,7 +555,8 @@
[SND_DEVICE_IN_SPEAKER_QMIC_AEC] = 126,
[SND_DEVICE_IN_SPEAKER_QMIC_NS] = 127,
[SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = 129,
- [SND_DEVICE_IN_THREE_MIC] = 46,
+ [SND_DEVICE_IN_THREE_MIC] = 46, /* for APSS Surround Sound Recording */
+ [SND_DEVICE_IN_HANDSET_TMIC] = 125, /* for 3mic recording with fluence */
};
struct name_to_index {
@@ -666,6 +670,8 @@
{TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC)},
{TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_NS)},
{TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_THREE_MIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_TMIC)},
};
static char * backend_tag_table[SND_DEVICE_MAX] = {0};
@@ -1143,7 +1149,7 @@
}
-static void set_platform_defaults()
+static void set_platform_defaults(struct platform_data * my_data)
{
int32_t dev, count = 0;
const char *MEDIA_MIMETYPE_AUDIO_ALAC = "audio/alac";
@@ -1182,6 +1188,7 @@
hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("SLIMBUS_0_RX-and-HDMI_RX");
hw_interface_table[SND_DEVICE_OUT_VOICE_TX] = strdup("AFE_PCM_RX");
+ my_data->max_mic_count = PLATFORM_DEFAULT_MIC_COUNT;
/*remove ALAC & APE from DSP decoder list based on software decoder availability*/
for (count = 0; count < (int32_t) (sizeof(dsp_only_decoders_mime)/sizeof(dsp_only_decoders_mime[0]));
count++) {
@@ -1521,6 +1528,27 @@
return found;
}
+static void get_source_mic_type(struct platform_data * my_data)
+{
+ // support max to mono, example if max count is 3, usecase supports Three, dual and mono mic
+ switch (my_data->max_mic_count) {
+ case 4:
+ my_data->source_mic_type |= SOURCE_QUAD_MIC;
+ case 3:
+ my_data->source_mic_type |= SOURCE_THREE_MIC;;
+ case 2:
+ my_data->source_mic_type |= SOURCE_DUAL_MIC;
+ case 1:
+ my_data->source_mic_type |= SOURCE_MONO_MIC;
+ break;
+ default:
+ ALOGE("%s: max_mic_count (%d), is not supported, setting to default",
+ __func__, my_data->max_mic_count);
+ my_data->source_mic_type = SOURCE_MONO_MIC | SOURCE_DUAL_MIC;
+ break;
+ }
+}
+
void *platform_init(struct audio_device *adev)
{
char value[PROPERTY_VALUE_MAX];
@@ -1776,7 +1804,7 @@
acdb_init_fail:
- set_platform_defaults();
+ set_platform_defaults(my_data);
/* Initialize ACDB and PCM ID's */
if (is_external_codec)
@@ -1784,6 +1812,14 @@
else
platform_info_init(PLATFORM_INFO_XML_PATH, my_data);
+ /* obtain source mic type from max mic count*/
+ get_source_mic_type(my_data);
+ ALOGD("%s: Fluence_Type(%d) max_mic_count(%d) mic_type(0x%x) fluence_in_voice_call(%d)"
+ " fluence_in_voice_rec(%d) fluence_in_spkr_mode(%d) ",
+ __func__, my_data->fluence_type, my_data->max_mic_count, my_data->source_mic_type,
+ my_data->fluence_in_voice_call, my_data->fluence_in_voice_rec,
+ my_data->fluence_in_spkr_mode);
+
/* init usb */
audio_extn_usb_init(adev);
/* update sound cards appropriately */
@@ -2957,8 +2993,8 @@
snd_device_t snd_device = SND_DEVICE_NONE;
int channel_count = popcount(channel_mask);
- ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
- __func__, out_device, in_device);
+ ALOGV("%s: enter: out_device(%#x) in_device(%#x) channel_count (%d) channel_mask (0x%x)",
+ __func__, out_device, in_device, channel_count, channel_mask);
if (my_data->external_mic) {
if ((out_device != AUDIO_DEVICE_NONE) && ((mode == AUDIO_MODE_IN_CALL) ||
voice_extn_compress_voip_is_active(adev) || audio_extn_hfp_is_active(adev))) {
@@ -3004,7 +3040,8 @@
out_device & AUDIO_DEVICE_OUT_LINE) {
if (out_device & AUDIO_DEVICE_OUT_EARPIECE &&
audio_extn_should_use_handset_anc(channel_count) &&
- my_data->fluence_type != FLUENCE_NONE) {
+ my_data->fluence_type != FLUENCE_NONE &&
+ my_data->source_mic_type & SOURCE_DUAL_MIC) {
snd_device = SND_DEVICE_IN_VOICE_FLUENCE_DMIC_AANC;
adev->acdb_settings |= DMIC_FLAG;
ALOGD("Selecting AANC, Fluence combo device");
@@ -3041,7 +3078,8 @@
if (my_data->fluence_type != FLUENCE_NONE &&
my_data->fluence_in_voice_call &&
my_data->fluence_in_spkr_mode) {
- if(my_data->fluence_type & FLUENCE_QUAD_MIC) {
+ if((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+ (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
adev->acdb_settings |= QMIC_FLAG;
snd_device = SND_DEVICE_IN_VOICE_SPEAKER_QMIC;
} else {
@@ -3061,27 +3099,45 @@
} else if (source == AUDIO_SOURCE_CAMCORDER) {
if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC ||
in_device & AUDIO_DEVICE_IN_BACK_MIC) {
- if (my_data->fluence_type & FLUENCE_DUAL_MIC &&
- channel_count == 2)
+ if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC) &&
+ (channel_count == 2))
snd_device = SND_DEVICE_IN_HANDSET_STEREO_DMIC;
else
snd_device = SND_DEVICE_IN_CAMCORDER_MIC;
}
} else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if (channel_count == 2) {
+ if (my_data->fluence_in_voice_rec && channel_count == 1) {
+ if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+ (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
+ snd_device = SND_DEVICE_IN_HANDSET_QMIC;
+ } else if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+ (my_data->source_mic_type & SOURCE_THREE_MIC)) {
+ snd_device = SND_DEVICE_IN_HANDSET_TMIC;
+ } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
+ }
+ platform_set_echo_reference(adev, true, out_device);
+ } else if (((channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK) ||
+ (channel_mask == AUDIO_CHANNEL_IN_STEREO)) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO;
- adev->acdb_settings |= DMIC_FLAG;
- } else if (adev->active_input->enable_ns)
- snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
- else if (my_data->fluence_type != FLUENCE_NONE &&
- my_data->fluence_in_voice_rec) {
- snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
- adev->acdb_settings |= DMIC_FLAG;
- } else {
- snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
+ } else if (((int)channel_mask == AUDIO_CHANNEL_INDEX_MASK_3) &&
+ (my_data->source_mic_type & SOURCE_THREE_MIC)) {
+ snd_device = SND_DEVICE_IN_THREE_MIC;
+ } else if (((int)channel_mask == AUDIO_CHANNEL_INDEX_MASK_4) &&
+ (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
+ snd_device = SND_DEVICE_IN_QUAD_MIC;
}
- }
+ if (snd_device == SND_DEVICE_NONE) {
+ if (adev->active_input->enable_ns)
+ snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
+ else
+ snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
+ }
+ }
} else if ((source == AUDIO_SOURCE_VOICE_COMMUNICATION) ||
(mode == AUDIO_MODE_IN_COMMUNICATION)) {
if (out_device & AUDIO_DEVICE_OUT_SPEAKER)
@@ -3092,9 +3148,11 @@
adev->active_input->enable_ns) {
if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
if (my_data->fluence_in_spkr_mode) {
- if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
+ if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+ (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
- } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
if (my_data->fluence_mode == FLUENCE_BROADSIDE)
snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE;
else
@@ -3104,7 +3162,8 @@
} else
snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
} else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
adev->acdb_settings |= DMIC_FLAG;
} else
@@ -3117,9 +3176,11 @@
adev->active_input->enable_aec) {
if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
if (my_data->fluence_in_spkr_mode) {
- if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
+ if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+ (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC;
- } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
if (my_data->fluence_mode == FLUENCE_BROADSIDE)
snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE;
else
@@ -3129,7 +3190,8 @@
} else
snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
} else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
adev->acdb_settings |= DMIC_FLAG;
} else
@@ -3142,9 +3204,11 @@
adev->active_input->enable_ns) {
if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
if (my_data->fluence_in_spkr_mode) {
- if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
+ if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+ (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
snd_device = SND_DEVICE_IN_SPEAKER_QMIC_NS;
- } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
if (my_data->fluence_mode == FLUENCE_BROADSIDE)
snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE;
else
@@ -3154,7 +3218,8 @@
} else
snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
} else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
adev->acdb_settings |= DMIC_FLAG;
} else
@@ -3170,10 +3235,15 @@
if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC &&
channel_count == 1 ) {
if(my_data->fluence_in_audio_rec) {
- if(my_data->fluence_type & FLUENCE_QUAD_MIC) {
+ if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+ (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
snd_device = SND_DEVICE_IN_HANDSET_QMIC;
platform_set_echo_reference(adev, true, out_device);
- } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ } else if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+ (my_data->source_mic_type & SOURCE_THREE_MIC)) {
+ snd_device = SND_DEVICE_IN_HANDSET_TMIC;
+ } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
snd_device = SND_DEVICE_IN_HANDSET_DMIC;
platform_set_echo_reference(adev, true, out_device);
}
@@ -3198,8 +3268,8 @@
if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
if (adev->active_input && (audio_extn_ssr_get_stream() == adev->active_input))
snd_device = SND_DEVICE_IN_QUAD_MIC;
- else if (my_data->fluence_type & (FLUENCE_DUAL_MIC | FLUENCE_QUAD_MIC) &&
- channel_count == 2)
+ else if ((my_data->fluence_type & (FLUENCE_DUAL_MIC | FLUENCE_QUAD_MIC)) &&
+ (channel_count == 2) && (my_data->source_mic_type & SOURCE_DUAL_MIC))
snd_device = SND_DEVICE_IN_HANDSET_STEREO_DMIC;
else
snd_device = SND_DEVICE_IN_HANDSET_MIC;
@@ -3237,7 +3307,7 @@
} else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
snd_device = SND_DEVICE_IN_HEADSET_MIC;
} else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
- if (channel_count > 1)
+ if ((channel_count > 1) && (my_data->source_mic_type & SOURCE_DUAL_MIC))
snd_device = SND_DEVICE_IN_SPEAKER_STEREO_DMIC;
else
snd_device = SND_DEVICE_IN_SPEAKER_MIC;
@@ -3471,6 +3541,15 @@
}
}
#endif
+
+ err = str_parms_get_str(parms, PLATFORM_MAX_MIC_COUNT,
+ value, sizeof(value));
+ if (err >= 0) {
+ str_parms_del(parms, PLATFORM_MAX_MIC_COUNT);
+ my_data->max_mic_count = atoi(value);
+ ALOGV("%s: max_mic_count %d", __func__, my_data->max_mic_count);
+ }
+
native_audio_set_params(platform, parms, value, sizeof(value));
audio_extn_spkr_prot_set_parameters(parms, value, len);
ALOGV("%s: exit with code(%d)", __func__, ret);
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index 9380561..8f9a517 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -32,6 +32,13 @@
FLUENCE_BROADSIDE = 0x2,
};
+enum {
+ SOURCE_MONO_MIC = 0x1, /* Target contains 1 mic */
+ SOURCE_DUAL_MIC = 0x2, /* Target contains 2 mics */
+ SOURCE_THREE_MIC = 0x4, /* Target contains 3 mics */
+ SOURCE_QUAD_MIC = 0x8, /* Target contains 4 mics */
+};
+
#define PLATFORM_IMAGE_NAME "modem"
/*
@@ -178,6 +185,7 @@
SND_DEVICE_IN_SPEAKER_QMIC_NS,
SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS,
SND_DEVICE_IN_THREE_MIC,
+ SND_DEVICE_IN_HANDSET_TMIC,
SND_DEVICE_IN_END,
SND_DEVICE_MAX = SND_DEVICE_IN_END,
@@ -278,6 +286,9 @@
#define AFE_PROXY_PLAYBACK_PCM_DEVICE 7
#define AFE_PROXY_RECORD_PCM_DEVICE 8
+#define PLATFORM_MAX_MIC_COUNT "input_mic_max_count"
+#define PLATFORM_DEFAULT_MIC_COUNT 2
+
#define LIB_CSD_CLIENT "libcsd-client.so"
/* CSD-CLIENT related functions */
typedef int (*init_t)();
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index a84f310..daeacf8 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -254,6 +254,8 @@
char cvd_version[MAX_CVD_VERSION_STRING_SIZE];
char snd_card_name[MAX_SND_CARD_STRING_SIZE];
int metainfo_key;
+ int source_mic_type;
+ int max_mic_count;
};
static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
@@ -433,6 +435,7 @@
[SND_DEVICE_IN_SPEAKER_QMIC_NS] = "quad-mic",
[SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = "quad-mic",
[SND_DEVICE_IN_THREE_MIC] = "three-mic",
+ [SND_DEVICE_IN_HANDSET_TMIC] = "three-mic",
};
// Platform specific backend bit width table
@@ -538,7 +541,8 @@
[SND_DEVICE_IN_SPEAKER_QMIC_AEC] = 126,
[SND_DEVICE_IN_SPEAKER_QMIC_NS] = 127,
[SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = 129,
- [SND_DEVICE_IN_THREE_MIC] = 46,
+ [SND_DEVICE_IN_THREE_MIC] = 46, /* for APSS Surround Sound Recording */
+ [SND_DEVICE_IN_HANDSET_TMIC] = 125, /* for 3mic recording with fluence */
};
struct name_to_index {
@@ -643,6 +647,8 @@
{TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC)},
{TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_NS)},
{TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_THREE_MIC)},
+ {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_TMIC)},
};
static char * backend_tag_table[SND_DEVICE_MAX] = {0};
@@ -1042,7 +1048,7 @@
return plat_data->is_i2s_ext_modem;
}
-static void set_platform_defaults()
+static void set_platform_defaults(struct platform_data * my_data)
{
int32_t dev;
unsigned int count = 0;
@@ -1083,6 +1089,7 @@
hw_interface_table[SND_DEVICE_OUT_SPEAKER_AND_HDMI] = strdup("SLIMBUS_0_RX-and-HDMI_RX");
hw_interface_table[SND_DEVICE_OUT_VOICE_TX] = strdup("AFE_PCM_RX");
+ my_data->max_mic_count = PLATFORM_DEFAULT_MIC_COUNT;
/*remove ALAC & APE from DSP decoder list based on software decoder availability*/
for (count = 0; count < (int32_t)(sizeof(dsp_only_decoders_mime)/sizeof(dsp_only_decoders_mime[0]));
@@ -1319,6 +1326,27 @@
return result;
}
+static void get_source_mic_type(struct platform_data * my_data)
+{
+ // support max to mono, example if max count is 3, usecase supports Three, dual and mono mic
+ switch (my_data->max_mic_count) {
+ case 4:
+ my_data->source_mic_type |= SOURCE_QUAD_MIC;
+ case 3:
+ my_data->source_mic_type |= SOURCE_THREE_MIC;
+ case 2:
+ my_data->source_mic_type |= SOURCE_DUAL_MIC;
+ case 1:
+ my_data->source_mic_type |= SOURCE_MONO_MIC;
+ break;
+ default:
+ ALOGE("%s: max_mic_count (%d), is not supported, setting to default",
+ __func__, my_data->max_mic_count);
+ my_data->source_mic_type = SOURCE_MONO_MIC | SOURCE_DUAL_MIC;
+ break;
+ }
+}
+
void *platform_init(struct audio_device *adev)
{
char platform[PROPERTY_VALUE_MAX];
@@ -1599,7 +1627,7 @@
acdb_init_fail:
- set_platform_defaults();
+ set_platform_defaults(my_data);
/* Initialize ACDB ID's */
if (my_data->is_i2s_ext_modem)
@@ -1620,6 +1648,14 @@
my_data->csd = NULL;
}
+ /* obtain source mic type from max mic count*/
+ get_source_mic_type(my_data);
+ ALOGD("%s: Fluence_Type(%d) max_mic_count(%d) mic_type(0x%x) fluence_in_voice_call(%d)"
+ " fluence_in_voice_rec(%d) fluence_in_spkr_mode(%d) ",
+ __func__, my_data->fluence_type, my_data->max_mic_count, my_data->source_mic_type,
+ my_data->fluence_in_voice_call, my_data->fluence_in_voice_rec,
+ my_data->fluence_in_spkr_mode);
+
/* init usb */
audio_extn_usb_init(adev);
/* update sound cards appropriately */
@@ -2716,8 +2752,8 @@
snd_device_t snd_device = SND_DEVICE_NONE;
int channel_count = popcount(channel_mask);
- ALOGV("%s: enter: out_device(%#x) in_device(%#x)",
- __func__, out_device, in_device);
+ ALOGV("%s: enter: out_device(%#x) in_device(%#x) channel_count (%d) channel_mask (0x%x)",
+ __func__, out_device, in_device, channel_count, channel_mask);
if (my_data->external_mic) {
if ((out_device != AUDIO_DEVICE_NONE) && ((mode == AUDIO_MODE_IN_CALL) ||
voice_extn_compress_voip_is_active(adev) || audio_extn_hfp_is_active(adev))) {
@@ -2762,7 +2798,8 @@
out_device & AUDIO_DEVICE_OUT_LINE) {
if (out_device & AUDIO_DEVICE_OUT_EARPIECE &&
audio_extn_should_use_handset_anc(channel_count)) {
- if(my_data->fluence_type != FLUENCE_NONE) {
+ if ((my_data->fluence_type != FLUENCE_NONE) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
snd_device = SND_DEVICE_IN_VOICE_FLUENCE_DMIC_AANC;
adev->acdb_settings |= DMIC_FLAG;
} else {
@@ -2797,7 +2834,8 @@
if (my_data->fluence_type != FLUENCE_NONE &&
my_data->fluence_in_voice_call &&
my_data->fluence_in_spkr_mode) {
- if(my_data->fluence_type & FLUENCE_QUAD_MIC) {
+ if((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+ (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
snd_device = SND_DEVICE_IN_VOICE_SPEAKER_QMIC;
} else {
if (my_data->fluence_mode == FLUENCE_BROADSIDE)
@@ -2819,20 +2857,34 @@
}
} else if (source == AUDIO_SOURCE_VOICE_RECOGNITION) {
if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if (channel_count == 2) {
- snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO;
- } else if (my_data->fluence_type != FLUENCE_NONE &&
- my_data->fluence_in_voice_rec) {
- if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
- snd_device = SND_DEVICE_IN_HANDSET_QMIC;
- } else {
+ if (my_data->fluence_in_voice_rec && channel_count == 1) {
+ if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+ (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
+ snd_device = SND_DEVICE_IN_HANDSET_QMIC;
+ } else if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+ (my_data->source_mic_type & SOURCE_THREE_MIC)) {
+ snd_device = SND_DEVICE_IN_HANDSET_TMIC;
+ } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
}
- platform_set_echo_reference(adev->platform, true, out_device);
- } else if (adev->active_input->enable_ns) {
- snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
- } else {
- snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
+ platform_set_echo_reference(adev, true, out_device);
+ } else if (((channel_mask == AUDIO_CHANNEL_IN_FRONT_BACK) ||
+ (channel_mask == AUDIO_CHANNEL_IN_STEREO)) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
+ snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_STEREO;
+ } else if (((int)channel_mask == AUDIO_CHANNEL_INDEX_MASK_3) &&
+ (my_data->source_mic_type & SOURCE_THREE_MIC)) {
+ snd_device = SND_DEVICE_IN_THREE_MIC;
+ } else if (((int)channel_mask == AUDIO_CHANNEL_INDEX_MASK_4) &&
+ (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
+ snd_device = SND_DEVICE_IN_QUAD_MIC;
+ }
+ if (snd_device == SND_DEVICE_NONE) {
+ if (adev->active_input->enable_ns)
+ snd_device = SND_DEVICE_IN_VOICE_REC_MIC_NS;
+ else
+ snd_device = SND_DEVICE_IN_VOICE_REC_MIC;
}
}
} else if (source == AUDIO_SOURCE_VOICE_COMMUNICATION) {
@@ -2843,9 +2895,11 @@
adev->active_input->enable_ns) {
if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
if (my_data->fluence_in_spkr_mode) {
- if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
+ if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+ (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS;
- } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
if (my_data->fluence_mode == FLUENCE_BROADSIDE)
snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_NS_BROADSIDE;
else
@@ -2854,9 +2908,10 @@
} else
snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC_NS;
} else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC))
snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC_NS;
- } else
+ else
snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC_NS;
} else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
@@ -2865,9 +2920,11 @@
} else if (adev->active_input->enable_aec) {
if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
if (my_data->fluence_in_spkr_mode) {
- if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
+ if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+ (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
snd_device = SND_DEVICE_IN_SPEAKER_QMIC_AEC;
- } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
if (my_data->fluence_mode == FLUENCE_BROADSIDE)
snd_device = SND_DEVICE_IN_SPEAKER_DMIC_AEC_BROADSIDE;
else
@@ -2876,9 +2933,10 @@
} else
snd_device = SND_DEVICE_IN_SPEAKER_MIC_AEC;
} else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC))
snd_device = SND_DEVICE_IN_HANDSET_DMIC_AEC;
- } else
+ else
snd_device = SND_DEVICE_IN_HANDSET_MIC_AEC;
} else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
@@ -2887,9 +2945,11 @@
} else if (adev->active_input->enable_ns) {
if (in_device & AUDIO_DEVICE_IN_BACK_MIC) {
if (my_data->fluence_in_spkr_mode) {
- if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
+ if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+ (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
snd_device = SND_DEVICE_IN_SPEAKER_QMIC_NS;
- } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
if (my_data->fluence_mode == FLUENCE_BROADSIDE)
snd_device = SND_DEVICE_IN_SPEAKER_DMIC_NS_BROADSIDE;
else
@@ -2898,9 +2958,10 @@
} else
snd_device = SND_DEVICE_IN_SPEAKER_MIC_NS;
} else if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
- if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC))
snd_device = SND_DEVICE_IN_HANDSET_DMIC_NS;
- } else
+ else
snd_device = SND_DEVICE_IN_HANDSET_MIC_NS;
} else if (in_device & AUDIO_DEVICE_IN_WIRED_HEADSET) {
snd_device = SND_DEVICE_IN_HEADSET_MIC_FLUENCE;
@@ -2913,10 +2974,15 @@
if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC &&
channel_count == 1 ) {
if(my_data->fluence_in_audio_rec) {
- if(my_data->fluence_type & FLUENCE_QUAD_MIC) {
+ if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+ (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
snd_device = SND_DEVICE_IN_HANDSET_QMIC;
platform_set_echo_reference(adev, true, out_device);
- } else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
+ } else if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+ (my_data->source_mic_type & SOURCE_THREE_MIC)) {
+ snd_device = SND_DEVICE_IN_HANDSET_TMIC;
+ } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
+ (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
snd_device = SND_DEVICE_IN_HANDSET_DMIC;
platform_set_echo_reference(adev, true, out_device);
}
@@ -2941,8 +3007,8 @@
if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC) {
if (adev->active_input && (audio_extn_ssr_get_stream() == adev->active_input))
snd_device = SND_DEVICE_IN_QUAD_MIC;
- else if (my_data->fluence_type & (FLUENCE_DUAL_MIC | FLUENCE_QUAD_MIC) &&
- channel_count == 2)
+ else if ((my_data->fluence_type & (FLUENCE_DUAL_MIC | FLUENCE_QUAD_MIC)) &&
+ (channel_count == 2) && (my_data->source_mic_type & SOURCE_DUAL_MIC))
snd_device = SND_DEVICE_IN_HANDSET_STEREO_DMIC;
else
snd_device = SND_DEVICE_IN_HANDSET_MIC;
@@ -2980,10 +3046,18 @@
} else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
snd_device = SND_DEVICE_IN_HEADSET_MIC;
} else if (out_device & AUDIO_DEVICE_OUT_SPEAKER) {
- if (channel_count == 2)
+ if ((my_data->source_mic_type & SOURCE_DUAL_MIC) &&
+ (channel_count == 2)) {
snd_device = SND_DEVICE_IN_SPEAKER_STEREO_DMIC;
- else
+ } else if ((my_data->source_mic_type & SOURCE_MONO_MIC) &&
+ (channel_count == 1)) {
+ snd_device = SND_DEVICE_IN_SPEAKER_MIC;
+ } else {
+ ALOGE("%s: something wrong: source type (%d) channel_count (%d) .."
+ " no combination found .. setting to mono", __func__,
+ my_data->source_mic_type, channel_count);
snd_device = SND_DEVICE_IN_SPEAKER_MIC;
+ }
} else if (out_device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
out_device & AUDIO_DEVICE_OUT_LINE) {
snd_device = SND_DEVICE_IN_HANDSET_MIC;
@@ -3426,6 +3500,14 @@
update_external_device_status(my_data, event_name, status);
}
+ err = str_parms_get_str(parms, PLATFORM_MAX_MIC_COUNT,
+ value, sizeof(value));
+ if (err >= 0) {
+ str_parms_del(parms, PLATFORM_MAX_MIC_COUNT);
+ my_data->max_mic_count = atoi(value);
+ ALOGV("%s: max_mic_count %d", __func__, my_data->max_mic_count);
+ }
+
/* handle audio calibration parameters */
set_audiocal(platform, parms, value, len);
native_audio_set_params(platform, parms, value, len);
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 7fe7271..3cd4361 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -32,6 +32,13 @@
FLUENCE_BROADSIDE = 0x2,
};
+enum {
+ SOURCE_MONO_MIC = 0x1, /* Target contains 1 mic */
+ SOURCE_DUAL_MIC = 0x2, /* Target contains 2 mics */
+ SOURCE_THREE_MIC = 0x4, /* Target contains 3 mics */
+ SOURCE_QUAD_MIC = 0x8, /* Target contains 4 mics */
+};
+
/*
* Below are the devices for which is back end is same, SLIMBUS_0_RX.
* All these devices are handled by the internal HW codec. We can
@@ -171,6 +178,7 @@
SND_DEVICE_IN_SPEAKER_QMIC_NS,
SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS,
SND_DEVICE_IN_THREE_MIC,
+ SND_DEVICE_IN_HANDSET_TMIC,
SND_DEVICE_IN_END,
SND_DEVICE_MAX = SND_DEVICE_IN_END,
@@ -371,6 +379,9 @@
#define FM_RX_VOLUME "Internal FM RX Volume"
#endif
+#define PLATFORM_MAX_MIC_COUNT "input_mic_max_count"
+#define PLATFORM_DEFAULT_MIC_COUNT 2
+
#define LIB_CSD_CLIENT "libcsd-client.so"
/* CSD-CLIENT related functions */
typedef int (*init_t)(bool);