Merge "hal: Modify EAGLE framework to use generic audio device node"
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 3e38d2b..c0b6de1 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -421,7 +421,6 @@
audio_format_t format,
uint32_t sample_rate,
uint32_t bit_width,
- audio_channel_mask_t channel_mask,
struct stream_app_type_cfg *app_type_cfg);
int audio_extn_utils_send_app_type_cfg(struct audio_usecase *usecase);
void audio_extn_utils_send_audio_calibration(struct audio_device *adev,
diff --git a/hal/audio_extn/spkr_protection.c b/hal/audio_extn/spkr_protection.c
index 15f2a3a..e5201cc 100644
--- a/hal/audio_extn/spkr_protection.c
+++ b/hal/audio_extn/spkr_protection.c
@@ -779,7 +779,6 @@
__func__, NUM_ATTEMPTS);
t0_spk_1 = SAFE_SPKR_TEMP_Q6;
}
- fclose(fp);
}
if (spk_2_tzn > 0) {
snprintf(wsa_path, MAX_PATH, TZ_WSA, spk_2_tzn);
@@ -810,7 +809,6 @@
__func__, NUM_ATTEMPTS);
t0_spk_2 = SAFE_SPKR_TEMP_Q6;
}
- fclose(fp);
}
}
pthread_mutex_unlock(&adev->lock);
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index dbd54f7..75bb336 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -436,6 +436,7 @@
* than all sample rates in list for the input bit width.
*/
sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+
list_for_each(node_i, &so_info->sample_rate_list) {
ss_info = node_to_item(node_i, struct stream_sample_rate, list);
if ((sample_rate <= ss_info->sample_rate) &&
@@ -443,7 +444,7 @@
app_type_cfg->app_type = so_info->app_type_cfg.app_type;
app_type_cfg->sample_rate = sample_rate;
app_type_cfg->bit_width = so_info->app_type_cfg.bit_width;
- ALOGV("%s Assuming default sample rate. app_type_cfg->app_type %d, app_type_cfg->sample_rate %d, app_type_cfg->bit_width %d",
+ ALOGV("%s Assuming sample rate. app_type_cfg->app_type %d, app_type_cfg->sample_rate %d, app_type_cfg->bit_width %d",
__func__, app_type_cfg->app_type, app_type_cfg->sample_rate, app_type_cfg->bit_width);
return true;
}
@@ -458,14 +459,12 @@
audio_format_t format,
uint32_t sample_rate,
uint32_t bit_width,
- audio_channel_mask_t channel_mask,
struct stream_app_type_cfg *app_type_cfg)
{
struct listnode *node_i, *node_j, *node_k;
struct streams_output_cfg *so_info;
struct stream_format *sf_info;
struct stream_sample_rate *ss_info;
- char value[PROPERTY_VALUE_MAX] = {0};
if ((24 == bit_width) &&
(devices & AUDIO_DEVICE_OUT_SPEAKER)) {
@@ -476,16 +475,6 @@
ALOGI("%s Allowing 24-bit playback on speaker ONLY at default sampling rate", __func__);
}
- property_get("audio.playback.mch.downsample",value,"");
- if (!strncmp("true", value, sizeof("true"))) {
- if ((popcount(channel_mask) > 2) &&
- (sample_rate > CODEC_BACKEND_DEFAULT_SAMPLE_RATE) &&
- !(flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH)) {
- sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
- ALOGD("%s: MCH session defaulting sample rate to %d",
- __func__, sample_rate);
- }
- }
ALOGV("%s: flags: %x, format: %x sample_rate %d",
__func__, flags, format, sample_rate);
list_for_each(node_i, streams_output_cfg_list) {
@@ -527,7 +516,6 @@
struct mixer_ctl *ctl;
int pcm_device_id, acdb_dev_id, snd_device = usecase->out_snd_device;
int32_t sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
- char value[PROPERTY_VALUE_MAX] = {0};
ALOGV("%s", __func__);
@@ -573,18 +561,14 @@
if ((24 == usecase->stream.out->bit_width) &&
(usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER)) {
sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+ } else if ((snd_device != SND_DEVICE_OUT_HEADPHONES_44_1 &&
+ usecase->stream.out->sample_rate == OUTPUT_SAMPLING_RATE_44100) ||
+ (usecase->stream.out->sample_rate < OUTPUT_SAMPLING_RATE_44100)) {
+ sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
} else {
sample_rate = out->app_type_cfg.sample_rate;
}
- property_get("audio.playback.mch.downsample",value,"");
- if (!strncmp("true", value, sizeof("true"))) {
- if ((popcount(out->channel_mask) > 2) &&
- (out->sample_rate > CODEC_BACKEND_DEFAULT_SAMPLE_RATE) &&
- !(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH))
- sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
- }
-
app_type_cfg[len++] = out->app_type_cfg.app_type;
app_type_cfg[len++] = acdb_dev_id;
if (((out->format == AUDIO_FORMAT_E_AC3) ||
@@ -593,6 +577,7 @@
app_type_cfg[len++] = sample_rate * 4;
else
app_type_cfg[len++] = sample_rate;
+
mixer_ctl_set_array(ctl, app_type_cfg, len);
ALOGI("%s app_type %d, acdb_dev_id %d, sample_rate %d",
__func__, out->app_type_cfg.app_type, acdb_dev_id, sample_rate);
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 435138d..7e66aeb 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -582,6 +582,8 @@
struct audio_usecase *usecase;
bool switch_device[AUDIO_USECASE_MAX];
int i, num_uc_to_switch = 0;
+ int backend_idx = DEFAULT_CODEC_BACKEND;
+ int usecase_backend_idx = DEFAULT_CODEC_BACKEND;
/*
* This function is to make sure that all the usecases that are active on
@@ -598,23 +600,34 @@
* If there is a backend configuration change for the device when a
* new stream starts, then ADM needs to be closed and re-opened with the new
* configuraion. This call check if we need to re-route all the streams
- * associated with the backend. Touch tone + 24 bit playback.
+ * associated with the backend. Touch tone + 24 bit + native playback.
*/
- bool force_routing = platform_check_and_set_codec_backend_cfg(adev, uc_info);
-
+ bool force_routing = platform_check_and_set_codec_backend_cfg(adev, uc_info,
+ snd_device);
+ backend_idx = platform_get_backend_index(snd_device);
/* Disable all the usecases on the shared backend other than the
- specified usecase */
+ * specified usecase.
+ */
for (i = 0; i < AUDIO_USECASE_MAX; i++)
switch_device[i] = false;
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
+
+ if (usecase == uc_info)
+ continue;
+ usecase_backend_idx = platform_get_backend_index(usecase->out_snd_device);
+ ALOGV("%s: backend_idx: %d,"
+ "usecase_backend_idx: %d, curr device: %s, usecase device:"
+ "%s", __func__, backend_idx, usecase_backend_idx, platform_get_snd_device_name(snd_device),
+ platform_get_snd_device_name(usecase->out_snd_device));
+
if (usecase->type != PCM_CAPTURE &&
- usecase != uc_info &&
(usecase->out_snd_device != snd_device || force_routing) &&
- usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) {
- ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..",
- __func__, use_case_table[usecase->id],
+ usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND &&
+ usecase_backend_idx == backend_idx) {
+ ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..", __func__,
+ use_case_table[usecase->id],
platform_get_snd_device_name(usecase->out_snd_device));
disable_audio_route(adev, usecase);
switch_device[usecase->id] = true;
@@ -814,7 +827,7 @@
(usecase->type == VOIP_CALL) ||
(usecase->type == PCM_HFP_CALL)) {
out_snd_device = platform_get_output_snd_device(adev->platform,
- usecase->stream.out->devices);
+ usecase->stream.out);
in_snd_device = platform_get_input_snd_device(adev->platform, usecase->stream.out->devices);
usecase->devices = usecase->stream.out->devices;
} else {
@@ -854,7 +867,7 @@
in_snd_device = SND_DEVICE_NONE;
if (out_snd_device == SND_DEVICE_NONE) {
out_snd_device = platform_get_output_snd_device(adev->platform,
- usecase->stream.out->devices);
+ usecase->stream.out);
if (usecase->stream.out == adev->primary_output &&
adev->active_input &&
adev->active_input->source == AUDIO_SOURCE_VOICE_COMMUNICATION &&
@@ -954,7 +967,6 @@
usecase->stream.out->format,
usecase->stream.out->sample_rate,
usecase->stream.out->bit_width,
- usecase->stream.out->channel_mask,
&usecase->stream.out->app_type_cfg);
ALOGI("%s Selected apptype: %d", __func__, usecase->stream.out->app_type_cfg.app_type);
}
@@ -2979,8 +2991,7 @@
audio_extn_utils_update_stream_app_type_cfg(adev->platform,
&adev->streams_output_cfg_list,
devices, flags, format, out->sample_rate,
- out->bit_width, out->channel_mask,
- &out->app_type_cfg);
+ out->bit_width, &out->app_type_cfg);
if ((out->usecase == USECASE_AUDIO_PLAYBACK_PRIMARY) ||
(flags & AUDIO_OUTPUT_FLAG_PRIMARY)) {
/* Ensure the default output is not selected twice */
@@ -3640,8 +3651,6 @@
adev->bluetooth_nrec = true;
adev->acdb_settings = TTY_MODE_OFF;
/* adev->cur_hdmi_channels = 0; by calloc() */
- adev->cur_codec_backend_samplerate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
- adev->cur_codec_backend_bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
voice_init(adev);
list_init(&adev->usecase_list);
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index d12959d..1c6fd1a 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -192,6 +192,20 @@
typedef int (*acdb_set_audio_cal_t) (void *, void *, uint32_t);
typedef int (*acdb_get_audio_cal_t) (void *, void *, uint32_t*);
+typedef struct codec_backend_cfg {
+ uint32_t sample_rate;
+ uint32_t bit_width;
+ char *bitwidth_mixer_ctl;
+ char *samplerate_mixer_ctl;
+} codec_backend_cfg_t;
+
+typedef struct {
+ bool platform_na_prop_enabled;
+ bool ui_na_prop_enabled;
+} native_audio_prop;
+
+static native_audio_prop na_props = {0, 0};
+
struct platform_data {
struct audio_device *adev;
bool fluence_in_spkr_mode;
@@ -226,6 +240,7 @@
struct csd_data *csd;
void *edid_info;
bool edid_valid;
+ codec_backend_cfg_t current_backend_cfg[MAX_CODEC_BACKENDS];
};
static bool is_external_codec = false;
@@ -311,6 +326,7 @@
[SND_DEVICE_OUT_SPEAKER_WSA] = "wsa-speaker",
[SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
[SND_DEVICE_OUT_HEADPHONES] = "headphones",
+ [SND_DEVICE_OUT_HEADPHONES_44_1] = "headphones-44.1",
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1] = "speaker-and-headphones-ext-1",
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2] = "speaker-and-headphones-ext-2",
@@ -415,6 +431,7 @@
[SND_DEVICE_OUT_SPEAKER_WSA] = 135,
[SND_DEVICE_OUT_SPEAKER_REVERSE] = 14,
[SND_DEVICE_OUT_HEADPHONES] = 10,
+ [SND_DEVICE_OUT_HEADPHONES_44_1] = 10,
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1] = 10,
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2] = 10,
@@ -521,6 +538,7 @@
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_WSA)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_REVERSE)},
{TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES_44_1)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2)},
@@ -1075,7 +1093,7 @@
backend_table[dev] = NULL;
}
for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
- backend_bit_width_table[dev] = 16;
+ backend_bit_width_table[dev] = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
}
// TBD - do these go to the platform-info.xml file.
@@ -1097,6 +1115,7 @@
backend_table[SND_DEVICE_IN_USB_HEADSET_MIC] = strdup("usb-headset-mic");
backend_table[SND_DEVICE_IN_CAPTURE_FM] = strdup("capture-fm");
backend_table[SND_DEVICE_OUT_TRANSMISSION_FM] = strdup("transmission-fm");
+ backend_table[SND_DEVICE_OUT_HEADPHONES_44_1] = strdup("headphones-44.1");
}
void get_cvd_version(char *cvd_version, struct audio_device *adev)
@@ -1231,6 +1250,7 @@
char *cvd_version = NULL;
const char *mixer_ctl_name = "Set HPX ActiveBe";
struct mixer_ctl *ctl = NULL;
+ int idx;
my_data = calloc(1, sizeof(struct platform_data));
if (!my_data) {
@@ -1474,6 +1494,26 @@
audio_extn_dev_arbi_init();
my_data->edid_info = NULL;
+
+ /* initialize backend config */
+ for (idx = 0; idx < MAX_CODEC_BACKENDS; idx++) {
+ my_data->current_backend_cfg[idx].sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ if (idx == HEADPHONE_44_1_BACKEND)
+ my_data->current_backend_cfg[idx].sample_rate = OUTPUT_SAMPLING_RATE_44100;
+ my_data->current_backend_cfg[idx].bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
+ }
+
+ my_data->current_backend_cfg[DEFAULT_CODEC_BACKEND].bitwidth_mixer_ctl =
+ strdup("SLIM_0_RX Format");
+ my_data->current_backend_cfg[DEFAULT_CODEC_BACKEND].samplerate_mixer_ctl =
+ strdup("SLIM_0_RX SampleRate");
+
+ my_data->current_backend_cfg[HEADPHONE_44_1_BACKEND].bitwidth_mixer_ctl =
+ strdup("SLIM_5_RX Format");
+ my_data->current_backend_cfg[HEADPHONE_44_1_BACKEND].samplerate_mixer_ctl =
+ strdup("SLIM_5_RX SampleRate");
+
+ my_data->edid_info = NULL;
return my_data;
}
@@ -1730,6 +1770,109 @@
return backend_bit_width_table[snd_device];
}
+int platform_set_native_support(bool codec_support)
+{
+ na_props.platform_na_prop_enabled = na_props.ui_na_prop_enabled
+ = codec_support;
+ ALOGV("%s: na_props.platform_na_prop_enabled: %d", __func__,
+ na_props.platform_na_prop_enabled);
+ return 0;
+}
+
+int platform_get_native_support()
+{
+ int ret;
+ if (na_props.platform_na_prop_enabled) {
+ ret = na_props.ui_na_prop_enabled;
+ } else {
+ ret = na_props.platform_na_prop_enabled;
+ }
+ ALOGV("%s: na_props.ui_na_prop_enabled: %d", __func__,
+ na_props.ui_na_prop_enabled);
+ return ret;
+}
+
+void native_audio_get_params(struct str_parms *query,
+ struct str_parms *reply,
+ char *value, int len)
+{
+ int ret;
+ ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_NATIVE_AUDIO,
+ value, len);
+ if (ret >= 0) {
+ if (na_props.platform_na_prop_enabled) {
+ str_parms_add_str(reply, AUDIO_PARAMETER_KEY_NATIVE_AUDIO,
+ na_props.ui_na_prop_enabled ? "true" : "false");
+ ALOGV("%s: na_props.ui_na_prop_enabled: %d", __func__,
+ na_props.ui_na_prop_enabled);
+ } else {
+ str_parms_add_str(reply, AUDIO_PARAMETER_KEY_NATIVE_AUDIO,
+ "false");
+ ALOGV("%s: native audio not supported: %d", __func__,
+ na_props.platform_na_prop_enabled);
+ }
+ }
+}
+
+int native_audio_set_params(struct platform_data *platform,
+ struct str_parms *parms, char *value, int len)
+{
+ int ret = 0;
+ struct audio_usecase *usecase;
+ struct listnode *node;
+
+ ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_NATIVE_AUDIO,
+ value, len);
+ if (ret >= 0) {
+ if (na_props.platform_na_prop_enabled) {
+ if (!strncmp("true", value, sizeof("true")))
+ na_props.ui_na_prop_enabled = true;
+ else
+ na_props.ui_na_prop_enabled = false;
+
+ str_parms_del(parms, AUDIO_PARAMETER_KEY_NATIVE_AUDIO);
+
+ /* Iterate through the usecase list and trigger device switch for
+ all the appropriate usecases */
+ list_for_each(node, &(platform->adev)->usecase_list) {
+ usecase = node_to_item(node, struct audio_usecase, list);
+
+ if (is_offload_usecase(usecase->id) &&
+ (usecase->stream.out->devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
+ usecase->stream.out->devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) &&
+ OUTPUT_SAMPLING_RATE_44100 == usecase->stream.out->sample_rate) {
+ select_devices(platform->adev, usecase->id);
+ ALOGV("%s: triggering dynamic device switch for usecase: "
+ "%d, device: %d", __func__, usecase->id,
+ usecase->stream.out->devices);
+ }
+ }
+ } else {
+ ALOGV("%s: native audio not supported: %d", __func__,
+ na_props.platform_na_prop_enabled);
+ }
+ }
+ return ret;
+}
+
+int platform_get_backend_index(snd_device_t snd_device)
+{
+ int32_t port = DEFAULT_CODEC_BACKEND;
+
+ if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) {
+ if (backend_table[snd_device] != NULL &&
+ !strcmp(backend_table[snd_device], "headphones-44.1"))
+ port = HEADPHONE_44_1_BACKEND;
+ else
+ port = DEFAULT_CODEC_BACKEND;
+ } else {
+ ALOGV("%s: Invalid device - %d ", __func__, snd_device);
+ }
+
+ ALOGV("%s: backend port - %d", __func__, port);
+ return port;
+}
+
int platform_send_audio_calibration(void *platform, struct audio_usecase *usecase,
int app_type, int sample_rate)
{
@@ -2016,12 +2159,14 @@
return ret;
}
-snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices)
+snd_device_t platform_get_output_snd_device(void *platform, struct stream_out *out)
{
struct platform_data *my_data = (struct platform_data *)platform;
struct audio_device *adev = my_data->adev;
audio_mode_t mode = adev->mode;
snd_device_t snd_device = SND_DEVICE_NONE;
+ audio_devices_t devices = out->devices;
+ unsigned int sample_rate = out->sample_rate;
#ifdef RECORD_PLAY_CONCURRENCY
bool use_voip_out_devices = false;
bool prop_rec_play_enabled = false;
@@ -2142,7 +2287,10 @@
if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
- if (devices & AUDIO_DEVICE_OUT_WIRED_HEADSET
+ if (OUTPUT_SAMPLING_RATE_44100 == sample_rate &&
+ platform_get_native_support()) {
+ snd_device = SND_DEVICE_OUT_HEADPHONES_44_1;
+ }else if (devices & AUDIO_DEVICE_OUT_WIRED_HEADSET
&& audio_extn_get_anc_enabled()) {
#ifdef RECORD_PLAY_CONCURRENCY
if (use_voip_out_devices) {
@@ -2756,6 +2904,7 @@
static void set_audiocal(void *platform, struct str_parms *parms, char *value, int len) {
struct platform_data *my_data = (struct platform_data *)platform;
+ struct stream_out out={0};
acdb_audio_cal_cfg_t cal={0};
uint8_t *dptr = NULL;
int32_t dlen;
@@ -2792,7 +2941,8 @@
if(audio_is_input_device(cal.dev_id)) {
cal.snd_dev_id = platform_get_input_snd_device(platform, cal.dev_id);
} else {
- cal.snd_dev_id = platform_get_output_snd_device(platform, cal.dev_id);
+ out.devices = cal.dev_id;
+ cal.snd_dev_id = platform_get_output_snd_device(platform, &out);
}
}
cal.acdb_dev_id = platform_get_snd_device_acdb_id(cal.snd_dev_id);
@@ -2885,6 +3035,7 @@
}
}
#endif
+ native_audio_set_params(platform, parms, value, sizeof(value));
ALOGV("%s: exit with code(%d)", __func__, ret);
return ret;
}
@@ -2991,6 +3142,7 @@
static void get_audiocal(void *platform, void *keys, void *pReply) {
struct platform_data *my_data = (struct platform_data *)platform;
+ struct stream_out out={0};
struct str_parms *query = (struct str_parms *)keys;
struct str_parms *reply=(struct str_parms *)pReply;
acdb_audio_cal_cfg_t cal={0};
@@ -3021,7 +3173,8 @@
if(cal.dev_id & AUDIO_DEVICE_BIT_IN) {
cal.snd_dev_id = platform_get_input_snd_device(platform, cal.dev_id);
} else if(cal.dev_id) {
- cal.snd_dev_id = platform_get_output_snd_device(platform, cal.dev_id);
+ out.devices = cal.dev_id;
+ cal.snd_dev_id = platform_get_output_snd_device(platform, &out);
}
cal.acdb_dev_id = platform_get_snd_device_acdb_id(cal.snd_dev_id);
if (cal.acdb_dev_id < 0) {
@@ -3117,6 +3270,7 @@
str_parms_add_str(reply, AUDIO_PARAMETER_KEY_VOLUME_BOOST, value);
}
+ native_audio_get_params(query, reply, value, sizeof(value));
ret = str_parms_get_str(query, AUDIO_PARAMETER_IS_HW_DECODER_SESSION_ALLOWED,
value, sizeof(value));
@@ -3377,29 +3531,59 @@
return fragment_size;
}
+int platform_is_external_codec (char *snd_card_name)
+{
+
+ if (!strncmp(snd_card_name, "msm8952-tomtom-snd-card",
+ sizeof("msm8952-tomtom-snd-card")) ||
+ !strncmp(snd_card_name, "msm8976-tasha-snd-card",
+ sizeof("msm8976-tasha-snd-card")))
+ {
+ /* external codec, for rest/old of the external codecs
+ we dont support this funtionality(chaning AFE params)
+ at the monment
+ */
+ return 1;
+ }
+ else {
+ /* internal codec */
+ return 0;
+ }
+}
+
int platform_set_codec_backend_cfg(struct audio_device* adev,
+ snd_device_t snd_device,
unsigned int bit_width, unsigned int sample_rate)
{
- ALOGV("%s bit width: %d, sample rate: %d", __func__, bit_width, sample_rate);
-
int ret = 0;
- const char *snd_card_name = mixer_get_name(adev->mixer);
+ int backend_idx = DEFAULT_CODEC_BACKEND;
+ struct platform_data *my_data = (struct platform_data *)adev->platform;
+ ALOGV("%s bit width: %d, sample rate: %d\n", __func__, bit_width, sample_rate);
- if (bit_width != adev->cur_codec_backend_bit_width) {
- const char * mixer_ctl_name;
- if (!strncmp(snd_card_name, "msm8952-tomtom-snd-card",
- sizeof("msm8952-tomtom-snd-card")) ||
- !strncmp(snd_card_name, "msm8976-tasha-snd-card",
- sizeof("msm8976-tasha-snd-card"))) {
- mixer_ctl_name = "SLIM_0_RX Format";
- }
- else
- mixer_ctl_name = "MI2S_RX Format";
+ const char *snd_card_name = mixer_get_name(adev->mixer);
+ int is_external_codec = platform_is_external_codec(snd_card_name);
+
+
+
+ backend_idx = platform_get_backend_index(snd_device);
+ ALOGV("%s bit width: %d, sample rate: %d backend_idx - %d\n",
+ __func__, bit_width, sample_rate, backend_idx);
+
+ if (bit_width !=
+ my_data->current_backend_cfg[backend_idx].bit_width) {
+
struct mixer_ctl *ctl;
- ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!is_external_codec) {
+ ctl = mixer_get_ctl_by_name(adev->mixer,
+ "MI2S_RX Format");
+
+ } else {
+ ctl = mixer_get_ctl_by_name(adev->mixer,
+ my_data->current_backend_cfg[backend_idx].bitwidth_mixer_ctl);
+ }
if (!ctl) {
ALOGE("%s: Could not get ctl for mixer command - %s",
- __func__, mixer_ctl_name);
+ __func__, my_data->current_backend_cfg[backend_idx].bitwidth_mixer_ctl);
return -EINVAL;
}
@@ -3407,10 +3591,12 @@
mixer_ctl_set_enum_by_string(ctl, "S24_LE");
} else {
mixer_ctl_set_enum_by_string(ctl, "S16_LE");
- sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ if (backend_idx != HEADPHONE_44_1_BACKEND)
+ sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
}
- adev->cur_codec_backend_bit_width = bit_width;
- ALOGE("Backend bit width is set to %d ", bit_width);
+ my_data->current_backend_cfg[backend_idx].bit_width = bit_width;
+ ALOGD("%s: %s mixer set to %d bit", __func__,
+ my_data->current_backend_cfg[backend_idx].bitwidth_mixer_ctl, bit_width);
}
/*
@@ -3422,9 +3608,12 @@
* Upper limit is inclusive in the sample rate range.
*/
// TODO: This has to be more dynamic based on policy file
- if (sample_rate != adev->cur_codec_backend_samplerate) {
+
+ if ((sample_rate != my_data->current_backend_cfg[(int)backend_idx].sample_rate) &&
+ (is_external_codec) ) {
+ /* sample rate update is needed only for external codecs which
+ support 24 bit playback*/
char *rate_str = NULL;
- const char * mixer_ctl_name = "SLIM_0_RX SampleRate";
struct mixer_ctl *ctl;
switch (sample_rate) {
@@ -3433,10 +3622,12 @@
case 16000:
case 22050:
case 32000:
- case 44100:
case 48000:
rate_str = "KHZ_48";
break;
+ case 44100:
+ rate_str = "KHZ_44P1";
+ break;
case 64000:
case 88200:
case 96000:
@@ -3451,32 +3642,46 @@
break;
}
- ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ ctl = mixer_get_ctl_by_name(adev->mixer,
+ my_data->current_backend_cfg[backend_idx].samplerate_mixer_ctl);
if(!ctl) {
ALOGE("%s: Could not get ctl for mixer command - %s",
- __func__, mixer_ctl_name);
+ __func__, my_data->current_backend_cfg[backend_idx].samplerate_mixer_ctl);
return -EINVAL;
}
- ALOGV("Set sample rate as rate_str = %s", rate_str);
+ ALOGD("%s: %s set to %s", __func__,
+ my_data->current_backend_cfg[backend_idx].samplerate_mixer_ctl, rate_str);
mixer_ctl_set_enum_by_string(ctl, rate_str);
- adev->cur_codec_backend_samplerate = sample_rate;
+ my_data->current_backend_cfg[backend_idx].sample_rate = sample_rate;
}
return ret;
}
bool platform_check_codec_backend_cfg(struct audio_device* adev,
- struct audio_usecase* usecase __unused,
+ struct audio_usecase* usecase,
+ snd_device_t snd_device,
unsigned int* new_bit_width,
unsigned int* new_sample_rate)
{
bool backend_change = false;
struct listnode *node;
struct stream_out *out = NULL;
- unsigned int bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
- unsigned int sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
char value[PROPERTY_VALUE_MAX] = {0};
+ unsigned int bit_width;
+ unsigned int sample_rate;
+ int backend_idx = DEFAULT_CODEC_BACKEND;
+ int usecase_backend_idx = DEFAULT_CODEC_BACKEND;
+ struct platform_data *my_data = (struct platform_data *)adev->platform;
+
+ backend_idx = platform_get_backend_index(snd_device);
+
+ bit_width = *new_bit_width;
+ sample_rate = *new_sample_rate;
+
+ ALOGI("%s Codec selected backend: %d current bit width: %d and sample rate: %d",
+ __func__, backend_idx, bit_width, sample_rate);
// For voice calls use default configuration
// force routing is not required here, caller will do it anyway
@@ -3497,52 +3702,50 @@
list_for_each(node, &adev->usecase_list) {
struct audio_usecase *curr_usecase;
curr_usecase = node_to_item(node, struct audio_usecase, list);
- if (curr_usecase->type == PCM_PLAYBACK) {
+ if (curr_usecase->type == PCM_PLAYBACK &&
+ usecase != curr_usecase) {
struct stream_out *out =
(struct stream_out*) curr_usecase->stream.out;
- if (out != NULL ) {
- ALOGV("Offload playback running bw %d sr %d",
- out->bit_width, out->sample_rate);
+ usecase_backend_idx = platform_get_backend_index(curr_usecase->out_snd_device);
+
+ if (out != NULL &&
+ usecase_backend_idx == backend_idx) {
+ ALOGV("%s: usecase Offload playback running bw %d sr %d device %s be_idx %d",
+ __func__, out->bit_width, out->sample_rate,
+ platform_get_snd_device_name(curr_usecase->out_snd_device), usecase_backend_idx);
if (bit_width < out->bit_width)
bit_width = out->bit_width;
if (sample_rate < out->sample_rate)
sample_rate = out->sample_rate;
+ if (out->sample_rate < OUTPUT_SAMPLING_RATE_44100)
+ sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
}
}
}
}
+ if (backend_idx != HEADPHONE_44_1_BACKEND) {
+ // 16 bit playbacks are allowed through 16 bit/48 khz backend only for
+ // all non-native streams
+ if (16 == bit_width) {
+ sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ ALOGD("%s: resetting sample_rate back to default, "
+ "backend_idx: %d", __func__, backend_idx);
+ }
- // 16 bit playback on speakers is allowed through 48 khz backend only
- if (16 == bit_width) {
- sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ // 24 bit playback on speakers is allowed through 48 khz backend only
+ // bit width re-configured based on platform info
+ if ((24 == bit_width) &&
+ (usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER)) {
+ bit_width = (uint32_t)platform_get_snd_device_bit_width(SND_DEVICE_OUT_SPEAKER);
+ sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ }
}
-
- //check if mulitchannel clip needs to be down sampled to 48k
- property_get("audio.playback.mch.downsample",value,"");
- if (!strncmp("true", value, sizeof("true"))) {
- out = usecase->stream.out;
- if ((popcount(out->channel_mask) > 2) &&
- (out->sample_rate > CODEC_BACKEND_DEFAULT_SAMPLE_RATE) &&
- !(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH)) {
- sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
- /* update out sample rate to reflect current backend sample rate */
- out->sample_rate = sample_rate;
- ALOGD("%s: MCH session defaulting sample rate to %d",
- __func__, sample_rate);
- }
- }
-
- // 24 bit playback on speakers is allowed through 48 khz backend only
- // bit width re-configured based on platform info
- if ((24 == bit_width) &&
- (usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER)) {
- bit_width = (uint32_t)platform_get_snd_device_bit_width(SND_DEVICE_OUT_SPEAKER);
- sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
- }
+ ALOGI("%s Codec selected backend: %d updated bit width: %d and sample rate: %d",
+ __func__, backend_idx, bit_width, sample_rate);
// Force routing if the expected bitwdith or samplerate
// is not same as current backend comfiguration
- if ((bit_width != adev->cur_codec_backend_bit_width) ||
- (sample_rate != adev->cur_codec_backend_samplerate)) {
+ if ((bit_width != my_data->current_backend_cfg[backend_idx].bit_width) ||
+ (sample_rate != my_data->current_backend_cfg[backend_idx].sample_rate)) {
*new_bit_width = bit_width;
*new_sample_rate = sample_rate;
backend_change = true;
@@ -3553,20 +3756,27 @@
return backend_change;
}
-bool platform_check_and_set_codec_backend_cfg(struct audio_device* adev, struct audio_usecase *usecase)
+bool platform_check_and_set_codec_backend_cfg(struct audio_device* adev,
+ struct audio_usecase *usecase, snd_device_t snd_device)
{
- ALOGV("platform_check_and_set_codec_backend_cfg usecase = %d",usecase->id );
+ unsigned int new_bit_width;
+ unsigned int new_sample_rate;
+ int backend_idx = DEFAULT_CODEC_BACKEND;
+ struct platform_data *my_data = (struct platform_data *)adev->platform;
- unsigned int new_bit_width, old_bit_width;
- unsigned int new_sample_rate, old_sample_rate;
+ ALOGV("%s: usecase = %d", __func__, usecase->id );
- new_bit_width = old_bit_width = adev->cur_codec_backend_bit_width;
- new_sample_rate = old_sample_rate = adev->cur_codec_backend_samplerate;
+ backend_idx = platform_get_backend_index(snd_device);
- ALOGW("Codec backend bitwidth %d, samplerate %d", old_bit_width, old_sample_rate);
- if (platform_check_codec_backend_cfg(adev, usecase,
+ new_bit_width = usecase->stream.out->bit_width;
+ new_sample_rate = usecase->stream.out->sample_rate;
+
+ ALOGI("%s: Usecase bitwidth %d, samplerate %d, backend_idx %d",
+ __func__, new_bit_width, new_sample_rate, backend_idx);
+ if (platform_check_codec_backend_cfg(adev, usecase, snd_device,
&new_bit_width, &new_sample_rate)) {
- platform_set_codec_backend_cfg(adev, new_bit_width, new_sample_rate);
+ platform_set_codec_backend_cfg(adev, snd_device,
+ new_bit_width, new_sample_rate);
return true;
}
@@ -3815,10 +4025,15 @@
ALOGE("%s: Invalid channel mapping used", __func__);
return -EINVAL;
}
- strlcpy(mixer_ctl_name, "Playback Channel Map", sizeof(mixer_ctl_name));
+
+ /*
+ * If snd_id is greater than 0, stream channel mapping
+ * If snd_id is below 0, typically -1, device channel mapping
+ */
if (snd_id >= 0) {
- snprintf(device_num, sizeof(device_num), "%d", snd_id);
- strlcat(mixer_ctl_name, device_num, sizeof(device_num));
+ snprintf(mixer_ctl_name, sizeof(mixer_ctl_name), "Playback Channel Map%d", snd_id);
+ } else {
+ strlcpy(mixer_ctl_name, "Playback Device Channel Map", sizeof(mixer_ctl_name));
}
ALOGD("%s mixer_ctl_name:%s", __func__, mixer_ctl_name);
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index d564839..9f0015a 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -37,7 +37,11 @@
/*
* 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
- * enable any one of these devices at any time
+ * enable any one of these devices at any time. An exception here is
+ * 44.1k headphone which uses different backend. This is filtered
+ * as different hal internal device in the code but remains same
+ * as standard android device AUDIO_DEVICE_OUT_WIRED_HEADPHONE
+ * for other layers.
*/
#define AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND \
(AUDIO_DEVICE_OUT_EARPIECE | AUDIO_DEVICE_OUT_SPEAKER | \
@@ -60,6 +64,7 @@
SND_DEVICE_OUT_SPEAKER_REVERSE,
SND_DEVICE_OUT_SPEAKER_WSA,
SND_DEVICE_OUT_HEADPHONES,
+ SND_DEVICE_OUT_HEADPHONES_44_1,
SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1,
SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2,
@@ -162,6 +167,16 @@
};
#define DEFAULT_OUTPUT_SAMPLING_RATE 48000
+#define OUTPUT_SAMPLING_RATE_44100 44100
+#define MAX_PORT 6
+#define ALL_CODEC_BACKEND_PORT 0
+#define HEADPHONE_44_1_BACKEND_PORT 5
+enum {
+ DEFAULT_CODEC_BACKEND,
+ HEADPHONE_44_1_BACKEND,
+ MAX_CODEC_BACKENDS
+};
+#define AUDIO_PARAMETER_KEY_NATIVE_AUDIO "audio.nat.codec.enabled"
#define ALL_SESSION_VSID 0xFFFFFFFF
#define DEFAULT_MUTE_RAMP_DURATION_MS 20
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 4f90850..0a17a22 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -171,6 +171,20 @@
typedef int (*acdb_set_audio_cal_t) (void *, void *, uint32_t);
typedef int (*acdb_get_audio_cal_t) (void *, void *, uint32_t*);
+typedef struct codec_backend_cfg {
+ uint32_t sample_rate;
+ uint32_t bit_width;
+ char *bitwidth_mixer_ctl;
+ char *samplerate_mixer_ctl;
+} codec_backend_cfg_t;
+
+typedef struct {
+ bool platform_na_prop_enabled;
+ bool ui_na_prop_enabled;
+} native_audio_prop;
+
+static native_audio_prop na_props = {0, 0};
+
struct platform_data {
struct audio_device *adev;
bool fluence_in_spkr_mode;
@@ -203,6 +217,7 @@
struct csd_data *csd;
void *edid_info;
bool edid_valid;
+ codec_backend_cfg_t current_backend_cfg[MAX_CODEC_BACKENDS];
};
static int pcm_device_table[AUDIO_USECASE_MAX][2] = {
@@ -287,6 +302,7 @@
[SND_DEVICE_OUT_SPEAKER_EXTERNAL_2] = "speaker-ext-2",
[SND_DEVICE_OUT_SPEAKER_REVERSE] = "speaker-reverse",
[SND_DEVICE_OUT_HEADPHONES] = "headphones",
+ [SND_DEVICE_OUT_HEADPHONES_44_1] = "headphones-44.1",
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = "speaker-and-headphones",
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1] = "speaker-and-headphones-ext-1",
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2] = "speaker-and-headphones-ext-2",
@@ -384,6 +400,7 @@
[SND_DEVICE_OUT_SPEAKER_EXTERNAL_2] = 130,
[SND_DEVICE_OUT_SPEAKER_REVERSE] = 14,
[SND_DEVICE_OUT_HEADPHONES] = 10,
+ [SND_DEVICE_OUT_HEADPHONES_44_1] = 10,
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES] = 10,
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1] = 130,
[SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2] = 130,
@@ -475,7 +492,7 @@
#define TO_NAME_INDEX(X) #X, X
-/* Used to get index from parsed sting */
+/* Used to get index from parsed string */
static struct name_to_index snd_device_name_index[SND_DEVICE_MAX] = {
{TO_NAME_INDEX(SND_DEVICE_OUT_HANDSET)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER)},
@@ -483,6 +500,7 @@
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_EXTERNAL_2)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_REVERSE)},
{TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES)},
+ {TO_NAME_INDEX(SND_DEVICE_OUT_HEADPHONES_44_1)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1)},
{TO_NAME_INDEX(SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2)},
@@ -878,7 +896,7 @@
backend_table[dev] = NULL;
}
for (dev = 0; dev < SND_DEVICE_MAX; dev++) {
- backend_bit_width_table[dev] = 16;
+ backend_bit_width_table[dev] = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
}
// TBD - do these go to the platform-info.xml file.
@@ -901,6 +919,8 @@
backend_table[SND_DEVICE_IN_USB_HEADSET_MIC] = strdup("usb-headset-mic");
backend_table[SND_DEVICE_IN_CAPTURE_FM] = strdup("capture-fm");
backend_table[SND_DEVICE_OUT_TRANSMISSION_FM] = strdup("transmission-fm");
+ backend_table[SND_DEVICE_OUT_HEADPHONES] = strdup("headphones");
+ backend_table[SND_DEVICE_OUT_HEADPHONES_44_1] = strdup("headphones-44.1");
}
void get_cvd_version(char *cvd_version, struct audio_device *adev)
@@ -1030,6 +1050,7 @@
char mixer_xml_file[MIXER_PATH_MAX_LENGTH]= {0};
const char *mixer_ctl_name = "Set HPX ActiveBe";
struct mixer_ctl *ctl = NULL;
+ int idx;
my_data = calloc(1, sizeof(struct platform_data));
@@ -1300,6 +1321,24 @@
/* init audio device arbitration */
audio_extn_dev_arbi_init();
+ /* initialize backend config */
+ for (idx = 0; idx < MAX_CODEC_BACKENDS; idx++) {
+ my_data->current_backend_cfg[idx].sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ if (idx == HEADPHONE_44_1_BACKEND)
+ my_data->current_backend_cfg[idx].sample_rate = OUTPUT_SAMPLING_RATE_44100;
+ my_data->current_backend_cfg[idx].bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
+ }
+
+ my_data->current_backend_cfg[DEFAULT_CODEC_BACKEND].bitwidth_mixer_ctl =
+ strdup("SLIM_0_RX Format");
+ my_data->current_backend_cfg[DEFAULT_CODEC_BACKEND].samplerate_mixer_ctl =
+ strdup("SLIM_0_RX SampleRate");
+
+ my_data->current_backend_cfg[HEADPHONE_44_1_BACKEND].bitwidth_mixer_ctl =
+ strdup("SLIM_5_RX Format");
+ my_data->current_backend_cfg[HEADPHONE_44_1_BACKEND].samplerate_mixer_ctl =
+ strdup("SLIM_5_RX SampleRate");
+
my_data->edid_info = NULL;
return my_data;
}
@@ -1565,6 +1604,111 @@
return backend_bit_width_table[snd_device];
}
+int platform_set_native_support(bool codec_support)
+{
+ na_props.platform_na_prop_enabled = na_props.ui_na_prop_enabled
+ = codec_support;
+ ALOGV("%s: na_props.platform_na_prop_enabled: %d", __func__,
+ na_props.platform_na_prop_enabled);
+ return 0;
+}
+
+int platform_get_native_support()
+{
+ int ret;
+ if (na_props.platform_na_prop_enabled) {
+ ret = na_props.ui_na_prop_enabled;
+ } else {
+ ret = na_props.platform_na_prop_enabled;
+ }
+ ALOGV("%s: na_props.ui_na_prop_enabled: %d", __func__,
+ na_props.ui_na_prop_enabled);
+ return ret;
+}
+
+void native_audio_get_params(struct str_parms *query,
+ struct str_parms *reply,
+ char *value, int len)
+{
+ int ret;
+ ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_NATIVE_AUDIO,
+ value, len);
+ if (ret >= 0) {
+ if (na_props.platform_na_prop_enabled) {
+ str_parms_add_str(reply, AUDIO_PARAMETER_KEY_NATIVE_AUDIO,
+ na_props.ui_na_prop_enabled ? "true" : "false");
+ ALOGV("%s: na_props.ui_na_prop_enabled: %d", __func__,
+ na_props.ui_na_prop_enabled);
+ } else {
+ str_parms_add_str(reply, AUDIO_PARAMETER_KEY_NATIVE_AUDIO,
+ "false");
+ ALOGV("%s: native audio not supported: %d", __func__,
+ na_props.platform_na_prop_enabled);
+ }
+ }
+}
+
+int native_audio_set_params(struct platform_data *platform,
+ struct str_parms *parms, char *value, int len)
+{
+ int ret = 0;
+ struct audio_usecase *usecase;
+ struct listnode *node;
+
+ ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_NATIVE_AUDIO,
+ value, len);
+ if (ret >= 0) {
+ if (na_props.platform_na_prop_enabled) {
+ if (!strncmp("true", value, sizeof("true")))
+ na_props.ui_na_prop_enabled = true;
+ else
+ na_props.ui_na_prop_enabled = false;
+
+ str_parms_del(parms, AUDIO_PARAMETER_KEY_NATIVE_AUDIO);
+
+ /*
+ * Iterate through the usecase list and trigger device switch for
+ * all the appropriate usecases
+ */
+ list_for_each(node, &(platform->adev)->usecase_list) {
+ usecase = node_to_item(node, struct audio_usecase, list);
+
+ if (is_offload_usecase(usecase->id) &&
+ (usecase->stream.out->devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
+ usecase->stream.out->devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) &&
+ OUTPUT_SAMPLING_RATE_44100 == usecase->stream.out->sample_rate) {
+ select_devices(platform->adev, usecase->id);
+ ALOGV("%s: triggering dynamic device switch for usecase: "
+ "%d, device: %d", __func__, usecase->id,
+ usecase->stream.out->devices);
+ }
+ }
+ } else {
+ ALOGV("%s: native audio not supported: %d", __func__,
+ na_props.platform_na_prop_enabled);
+ }
+ }
+ return ret;
+}
+
+int platform_get_backend_index(snd_device_t snd_device)
+{
+ int32_t port = DEFAULT_CODEC_BACKEND;
+
+ if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) {
+ if (backend_table[snd_device] != NULL &&
+ strcmp(backend_table[snd_device], "headphones-44.1") == 0)
+ port = HEADPHONE_44_1_BACKEND;
+ else
+ port = DEFAULT_CODEC_BACKEND;
+ } else {
+ ALOGV("%s: Invalid device - %d ", __func__, snd_device);
+ }
+
+ ALOGV("%s: backend port - %d", __func__, port);
+ return port;
+}
+
int platform_send_audio_calibration(void *platform, struct audio_usecase *usecase,
int app_type, int sample_rate)
{
@@ -1575,7 +1719,7 @@
if (usecase->type == PCM_PLAYBACK)
snd_device = platform_get_output_snd_device(adev->platform,
- usecase->stream.out->devices);
+ usecase->stream.out);
else if ((usecase->type == PCM_HFP_CALL) || (usecase->type == PCM_CAPTURE))
snd_device = platform_get_input_snd_device(adev->platform,
adev->primary_output->devices);
@@ -1856,12 +2000,14 @@
return ret;
}
-snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices)
+snd_device_t platform_get_output_snd_device(void *platform, struct stream_out *out)
{
struct platform_data *my_data = (struct platform_data *)platform;
struct audio_device *adev = my_data->adev;
audio_mode_t mode = adev->mode;
snd_device_t snd_device = SND_DEVICE_NONE;
+ audio_devices_t devices = out->devices;
+ unsigned int sample_rate = out->sample_rate;
audio_channel_mask_t channel_mask = (adev->active_input == NULL) ?
AUDIO_CHANNEL_IN_MONO : adev->active_input->channel_mask;
@@ -1974,8 +2120,11 @@
snd_device = SND_DEVICE_OUT_ANC_FB_HEADSET;
else
snd_device = SND_DEVICE_OUT_ANC_HEADSET;
- } else
- snd_device = SND_DEVICE_OUT_HEADPHONES;
+ } else if (platform_get_native_support() &&
+ OUTPUT_SAMPLING_RATE_44100 == sample_rate)
+ snd_device = SND_DEVICE_OUT_HEADPHONES_44_1;
+ else
+ snd_device = SND_DEVICE_OUT_HEADPHONES;
} else if (devices & AUDIO_DEVICE_OUT_SPEAKER) {
if (my_data->external_spk_1)
snd_device = SND_DEVICE_OUT_SPEAKER_EXTERNAL_1;
@@ -2528,6 +2677,7 @@
static void set_audiocal(void *platform, struct str_parms *parms, char *value, int len) {
struct platform_data *my_data = (struct platform_data *)platform;
+ struct stream_out out;
acdb_audio_cal_cfg_t cal={0};
uint8_t *dptr = NULL;
int32_t dlen;
@@ -2564,7 +2714,8 @@
if(audio_is_input_device(cal.dev_id)) {
cal.snd_dev_id = platform_get_input_snd_device(platform, cal.dev_id);
} else {
- cal.snd_dev_id = platform_get_output_snd_device(platform, cal.dev_id);
+ out.devices = cal.dev_id;
+ cal.snd_dev_id = platform_get_output_snd_device(platform, &out);
}
}
cal.acdb_dev_id = platform_get_snd_device_acdb_id(cal.snd_dev_id);
@@ -2680,7 +2831,7 @@
/* handle audio calibration parameters */
set_audiocal(platform, parms, value, len);
-
+ native_audio_set_params(platform, parms, value, len);
done:
ALOGV("%s: exit with code(%d)", __func__, ret);
if(kv_pairs != NULL)
@@ -2792,6 +2943,7 @@
static void get_audiocal(void *platform, void *keys, void *pReply) {
struct platform_data *my_data = (struct platform_data *)platform;
+ struct stream_out out;
struct str_parms *query = (struct str_parms *)keys;
struct str_parms *reply=(struct str_parms *)pReply;
acdb_audio_cal_cfg_t cal={0};
@@ -2822,7 +2974,8 @@
if(cal.dev_id & AUDIO_DEVICE_BIT_IN) {
cal.snd_dev_id = platform_get_input_snd_device(platform, cal.dev_id);
} else if(cal.dev_id) {
- cal.snd_dev_id = platform_get_output_snd_device(platform, cal.dev_id);
+ out.devices = cal.dev_id;
+ cal.snd_dev_id = platform_get_output_snd_device(platform, &out);
}
cal.acdb_dev_id = platform_get_snd_device_acdb_id(cal.snd_dev_id);
if (cal.acdb_dev_id < 0) {
@@ -2921,6 +3074,7 @@
/* Handle audio calibration keys */
get_audiocal(platform, query, reply);
+ native_audio_get_params(query, reply, value, sizeof(value));
done:
kv_pairs = str_parms_to_str(reply);
@@ -3065,29 +3219,39 @@
}
int platform_set_codec_backend_cfg(struct audio_device* adev,
+ snd_device_t snd_device,
unsigned int bit_width, unsigned int sample_rate)
{
- ALOGV("%s bit width: %d, sample rate: %d", __func__, bit_width, sample_rate);
-
int ret = 0;
- if (bit_width != adev->cur_codec_backend_bit_width) {
- const char * mixer_ctl_name = "SLIM_0_RX Format";
+ int backend_idx = DEFAULT_CODEC_BACKEND;
+ struct platform_data *my_data = (struct platform_data *)adev->platform;
+
+ backend_idx = platform_get_backend_index(snd_device);
+ ALOGV("%s bit width: %d, sample rate: %d backend_idx - %d",
+ __func__, bit_width, sample_rate, backend_idx);
+
+ if (bit_width !=
+ my_data->current_backend_cfg[backend_idx].bit_width) {
+
struct mixer_ctl *ctl;
- ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ ctl = mixer_get_ctl_by_name(adev->mixer,
+ my_data->current_backend_cfg[backend_idx].bitwidth_mixer_ctl);
if (!ctl) {
ALOGE("%s: Could not get ctl for mixer command - %s",
- __func__, mixer_ctl_name);
+ __func__, my_data->current_backend_cfg[backend_idx].bitwidth_mixer_ctl);
return -EINVAL;
}
if (bit_width == 24) {
- mixer_ctl_set_enum_by_string(ctl, "S24_LE");
+ mixer_ctl_set_enum_by_string(ctl, "S24_LE");
} else {
mixer_ctl_set_enum_by_string(ctl, "S16_LE");
- sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ if (backend_idx != HEADPHONE_44_1_BACKEND)
+ sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
}
- adev->cur_codec_backend_bit_width = bit_width;
- ALOGE("Backend bit width is set to %d ", bit_width);
+ my_data->current_backend_cfg[backend_idx].bit_width = bit_width;
+ ALOGD("%s: %s mixer set to %d bit", __func__,
+ my_data->current_backend_cfg[backend_idx].bitwidth_mixer_ctl, bit_width);
}
/*
@@ -3098,10 +3262,9 @@
* 24 bit playback - 192khz for sample rate range of 96khz to 192 khz
* Upper limit is inclusive in the sample rate range.
*/
- // TODO: This has to be more dynamic based on policy file
- if (sample_rate != adev->cur_codec_backend_samplerate) {
+ if (sample_rate !=
+ my_data->current_backend_cfg[backend_idx].sample_rate) {
char *rate_str = NULL;
- const char * mixer_ctl_name = "SLIM_0_RX SampleRate";
struct mixer_ctl *ctl;
switch (sample_rate) {
@@ -3110,10 +3273,12 @@
case 16000:
case 22050:
case 32000:
- case 44100:
case 48000:
rate_str = "KHZ_48";
break;
+ case 44100:
+ rate_str = "KHZ_44P1";
+ break;
case 64000:
case 88200:
case 96000:
@@ -3128,33 +3293,46 @@
break;
}
- ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ ctl = mixer_get_ctl_by_name(adev->mixer,
+ my_data->current_backend_cfg[backend_idx].samplerate_mixer_ctl);
if(!ctl) {
ALOGE("%s: Could not get ctl for mixer command - %s",
- __func__, mixer_ctl_name);
+ __func__, my_data->current_backend_cfg[backend_idx].samplerate_mixer_ctl);
return -EINVAL;
}
- ALOGV("Set sample rate as rate_str = %s", rate_str);
+ ALOGD("%s: %s set to %s", __func__,
+ my_data->current_backend_cfg[backend_idx].samplerate_mixer_ctl, rate_str);
mixer_ctl_set_enum_by_string(ctl, rate_str);
- adev->cur_codec_backend_samplerate = sample_rate;
+ my_data->current_backend_cfg[backend_idx].sample_rate = sample_rate;
}
return ret;
}
bool platform_check_codec_backend_cfg(struct audio_device* adev,
- struct audio_usecase* usecase __unused,
+ struct audio_usecase* usecase,
+ snd_device_t snd_device,
unsigned int* new_bit_width,
unsigned int* new_sample_rate)
{
bool backend_change = false;
struct listnode *node;
struct stream_out *out = NULL;
- unsigned int bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
- unsigned int sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ unsigned int bit_width;
+ unsigned int sample_rate;
char value[PROPERTY_VALUE_MAX] = {0};
+ int backend_idx = DEFAULT_CODEC_BACKEND;
+ int usecase_backend_idx = DEFAULT_CODEC_BACKEND;
+ struct platform_data *my_data = (struct platform_data *)adev->platform;
+ backend_idx = platform_get_backend_index(snd_device);
+
+ bit_width = *new_bit_width;
+ sample_rate = *new_sample_rate;
+
+ ALOGI("%s Codec selected backend: %d current bit width: %d and sample rate: %d",
+ __func__, backend_idx, bit_width, sample_rate);
// For voice calls use default configuration
// force routing is not required here, caller will do it anyway
if (voice_is_in_call(adev) || adev->mode == AUDIO_MODE_IN_COMMUNICATION) {
@@ -3174,51 +3352,63 @@
list_for_each(node, &adev->usecase_list) {
struct audio_usecase *curr_usecase;
curr_usecase = node_to_item(node, struct audio_usecase, list);
- if (curr_usecase->type == PCM_PLAYBACK) {
+ if (curr_usecase->type == PCM_PLAYBACK &&
+ usecase != curr_usecase) {
struct stream_out *out =
(struct stream_out*) curr_usecase->stream.out;
- if (out != NULL ) {
- ALOGV("Offload playback running bw %d sr %d",
- out->bit_width, out->sample_rate);
+ usecase_backend_idx = platform_get_backend_index(curr_usecase->out_snd_device);
+
+ if (out != NULL &&
+ usecase_backend_idx == backend_idx) {
+ ALOGV("%s: usecase Offload playback running bw %d sr %d device %s be_idx %d",
+ __func__, out->bit_width, out->sample_rate,
+ platform_get_snd_device_name(curr_usecase->out_snd_device), usecase_backend_idx);
if (bit_width < out->bit_width)
bit_width = out->bit_width;
if (sample_rate < out->sample_rate)
sample_rate = out->sample_rate;
+ if (out->sample_rate < OUTPUT_SAMPLING_RATE_44100)
+ sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
}
}
}
}
-
- // 16 bit playback on speakers is allowed through 48 khz backend only
- if (16 == bit_width) {
- sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
- }
-
- //check if mulitchannel clip needs to be down sampled to 48k
- property_get("audio.playback.mch.downsample",value,"");
- if (!strncmp("true", value, sizeof("true"))) {
- out = usecase->stream.out;
- if ((popcount(out->channel_mask) > 2) &&
- (out->sample_rate > CODEC_BACKEND_DEFAULT_SAMPLE_RATE) &&
- !(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH)) {
- /* update out sample rate to reflect current backend sample rate */
+ if (backend_idx != HEADPHONE_44_1_BACKEND) {
+ // 16 bit playbacks are allowed through 16 bit/48 khz backend only for
+ // all non-native streams
+ if (16 == bit_width) {
sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
- ALOGD("%s: MCH session defaulting sample rate to %d",
- __func__, sample_rate);
+ ALOGD("%s: resetting sample_rate back to default, "
+ "backend_idx: %d", __func__, backend_idx);
+ }
+
+ //check if mulitchannel clip needs to be down sampled to 48k
+ property_get("audio.playback.mch.downsample",value,"");
+ if (!strncmp("true", value, sizeof("true"))) {
+ out = usecase->stream.out;
+ if ((popcount(out->channel_mask) > 2) &&
+ (out->sample_rate > CODEC_BACKEND_DEFAULT_SAMPLE_RATE) &&
+ !(out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH)) {
+ /* update out sample rate to reflect current backend sample rate */
+ sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
+ ALOGD("%s: MCH session defaulting sample rate to %d",
+ __func__, sample_rate);
+ }
+ }
+ // 24 bit playback on speakers is allowed through 48 khz backend only
+ // bit width re-configured based on platform info
+ if ((24 == bit_width) &&
+ (usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER)) {
+ bit_width = (uint32_t)platform_get_snd_device_bit_width(SND_DEVICE_OUT_SPEAKER);
+ sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
}
}
-
- // 24 bit playback on speakers is allowed through 48 khz backend only
- // bit width re-configured based on platform info
- if ((24 == bit_width) &&
- (usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER)) {
- bit_width = (uint32_t)platform_get_snd_device_bit_width(SND_DEVICE_OUT_SPEAKER);
- sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
- }
+ ALOGI("%s Codec selected backend: %d updated bit width: %d and sample rate: %d",
+ __func__, backend_idx, bit_width, sample_rate);
// Force routing if the expected bitwdith or samplerate
// is not same as current backend comfiguration
- if ((bit_width != adev->cur_codec_backend_bit_width) ||
- (sample_rate != adev->cur_codec_backend_samplerate)) {
+ if ((bit_width != my_data->current_backend_cfg[backend_idx].bit_width) ||
+ (sample_rate != my_data->current_backend_cfg[backend_idx].sample_rate)) {
*new_bit_width = bit_width;
*new_sample_rate = sample_rate;
backend_change = true;
@@ -3229,20 +3419,27 @@
return backend_change;
}
-bool platform_check_and_set_codec_backend_cfg(struct audio_device* adev, struct audio_usecase *usecase)
+bool platform_check_and_set_codec_backend_cfg(struct audio_device* adev,
+ struct audio_usecase *usecase, snd_device_t snd_device)
{
- ALOGV("platform_check_and_set_codec_backend_cfg usecase = %d",usecase->id );
+ unsigned int new_bit_width;
+ unsigned int new_sample_rate;
+ int backend_idx = DEFAULT_CODEC_BACKEND;
+ struct platform_data *my_data = (struct platform_data *)adev->platform;
- unsigned int new_bit_width, old_bit_width;
- unsigned int new_sample_rate, old_sample_rate;
+ ALOGV("%s: usecase = %d", __func__, usecase->id );
- new_bit_width = old_bit_width = adev->cur_codec_backend_bit_width;
- new_sample_rate = old_sample_rate = adev->cur_codec_backend_samplerate;
+ backend_idx = platform_get_backend_index(snd_device);
- ALOGW("Codec backend bitwidth %d, samplerate %d", old_bit_width, old_sample_rate);
- if (platform_check_codec_backend_cfg(adev, usecase,
+ new_bit_width = usecase->stream.out->bit_width;
+ new_sample_rate = usecase->stream.out->sample_rate;
+
+ ALOGI("%s: Usecase bitwidth %d, samplerate %d, backend_idx %d",
+ __func__, new_bit_width, new_sample_rate, backend_idx);
+ if (platform_check_codec_backend_cfg(adev, usecase, snd_device,
&new_bit_width, &new_sample_rate)) {
- platform_set_codec_backend_cfg(adev, new_bit_width, new_sample_rate);
+ platform_set_codec_backend_cfg(adev, snd_device,
+ new_bit_width, new_sample_rate);
return true;
}
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 41e2c55..4b90f8b 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -35,7 +35,11 @@
/*
* 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
- * enable any one of these devices at any time
+ * enable any one of these devices at any time. An exception here is
+ * 44.1k headphone which uses different backend. This is filtered
+ * as different hal internal device in the code but remains same
+ * as standard android device AUDIO_DEVICE_OUT_WIRED_HEADPHONE
+ * for other layers.
*/
#define AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND \
(AUDIO_DEVICE_OUT_EARPIECE | AUDIO_DEVICE_OUT_SPEAKER | \
@@ -57,6 +61,7 @@
SND_DEVICE_OUT_SPEAKER_EXTERNAL_2,
SND_DEVICE_OUT_SPEAKER_REVERSE,
SND_DEVICE_OUT_HEADPHONES,
+ SND_DEVICE_OUT_HEADPHONES_44_1,
SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES,
SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_1,
SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES_EXTERNAL_2,
@@ -151,7 +156,16 @@
};
-#define DEFAULT_OUTPUT_SAMPLING_RATE 48000
+#define DEFAULT_OUTPUT_SAMPLING_RATE 48000
+#define OUTPUT_SAMPLING_RATE_44100 44100
+
+enum {
+ DEFAULT_CODEC_BACKEND,
+ HEADPHONE_44_1_BACKEND,
+ MAX_CODEC_BACKENDS
+};
+
+#define AUDIO_PARAMETER_KEY_NATIVE_AUDIO "audio.nat.codec.enabled"
#define ALL_SESSION_VSID 0xFFFFFFFF
#define DEFAULT_MUTE_RAMP_DURATION_MS 20
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 2f9af6c..5542a6d 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -38,6 +38,9 @@
int platform_get_snd_device_acdb_id(snd_device_t snd_device);
int platform_set_snd_device_bit_width(snd_device_t snd_device, unsigned int bit_width);
int platform_get_snd_device_bit_width(snd_device_t snd_device);
+int platform_set_native_support(bool codec_support);
+int platform_get_native_support();
+int platform_get_backend_index(snd_device_t snd_device);
int platform_send_audio_calibration(void *platform, struct audio_usecase *usecase,
int app_type, int sample_rate);
int platform_get_default_app_type(void *platform);
@@ -57,7 +60,7 @@
int platform_set_mic_mute(void *platform, bool state);
int platform_get_sample_rate(void *platform, uint32_t *rate);
int platform_set_device_mute(void *platform, bool state, char *dir);
-snd_device_t platform_get_output_snd_device(void *platform, audio_devices_t devices);
+snd_device_t platform_get_output_snd_device(void *platform, struct stream_out *out);
snd_device_t platform_get_input_snd_device(void *platform, audio_devices_t out_device);
int platform_set_hdmi_channels(void *platform, int channel_count);
int platform_edid_get_max_channels(void *platform);
@@ -91,7 +94,8 @@
uint32_t platform_get_pcm_offload_buffer_size(audio_offload_info_t* info);
uint32_t platform_get_compress_passthrough_buffer_size(audio_offload_info_t* info);
-bool platform_check_and_set_codec_backend_cfg(struct audio_device* adev, struct audio_usecase *usecase);
+bool platform_check_and_set_codec_backend_cfg(struct audio_device* adev,
+ struct audio_usecase *usecase, snd_device_t snd_device);
int platform_get_usecase_index(const char * usecase);
int platform_set_usecase_pcm_id(audio_usecase_t usecase, int32_t type, int32_t pcm_id);
void platform_set_echo_reference(void *platform, bool enable);
diff --git a/hal/platform_info.c b/hal/platform_info.c
index 6a35be5..50e19c6 100644
--- a/hal/platform_info.c
+++ b/hal/platform_info.c
@@ -44,6 +44,7 @@
ROOT,
ACDB,
BITWIDTH,
+ NATIVESUPPORT,
PCM_ID,
BACKEND_NAME,
INTERFACE_NAME,
@@ -54,6 +55,7 @@
static void process_acdb_id(const XML_Char **attr);
static void process_bit_width(const XML_Char **attr);
+static void process_native_support(const XML_Char **attr);
static void process_pcm_id(const XML_Char **attr);
static void process_backend_name(const XML_Char **attr);
static void process_interface_name(const XML_Char **attr);
@@ -64,6 +66,7 @@
[ROOT] = process_root,
[ACDB] = process_acdb_id,
[BITWIDTH] = process_bit_width,
+ [NATIVESUPPORT] = process_native_support,
[PCM_ID] = process_pcm_id,
[BACKEND_NAME] = process_backend_name,
[INTERFACE_NAME] = process_interface_name,
@@ -281,7 +284,30 @@
(char *)attr[5]);
if (ret < 0) {
ALOGE("%s: Audio Interface not set!", __func__);
+ goto done;
+ }
+done:
+ return;
+}
+
+static void process_native_support(const XML_Char **attr)
+{
+ int index;
+
+ if (strcmp(attr[0], "name") != 0) {
+ ALOGE("%s: 'name' not found, no NATIVE_AUDIO_44.1 set!", __func__);
+ goto done;
+ }
+
+ if (strcmp(attr[2], "codec_support") != 0) {
+ ALOGE("%s: NATIVE_AUDIO_44.1 in platform info xml has no codec_support set!",
+ __func__);
+ goto done;
+ }
+
+ if (platform_set_native_support(atoi((char *)attr[3])) < 0) {
+ ALOGE("%s: NATIVE_AUDIO_44 was not set!", __func__);
goto done;
}
@@ -344,6 +370,8 @@
section = INTERFACE_NAME;
} else if (strcmp(tag_name, "tz_names") == 0) {
section = TZ_NAME;
+ } else if (strcmp(tag_name, "native_configs") == 0) {
+ section = NATIVESUPPORT;
} else if (strcmp(tag_name, "device") == 0) {
if ((section != ACDB) && (section != BACKEND_NAME) && (section != BITWIDTH) &&
(section != INTERFACE_NAME) && (section != TZ_NAME)) {
@@ -362,6 +390,14 @@
section_process_fn fn = section_table[PCM_ID];
fn(attr);
+ } else if (strcmp(tag_name, "feature") == 0) {
+ if (section != NATIVESUPPORT) {
+ ALOGE("usecase tag only supported with NATIVESUPPORT section");
+ return;
+ }
+
+ section_process_fn fn = section_table[NATIVESUPPORT];
+ fn(attr);
}
return;
@@ -379,6 +415,8 @@
section = ROOT;
} else if (strcmp(tag_name, "interface_names") == 0) {
section = ROOT;
+ } else if (strcmp(tag_name, "native_configs") == 0) {
+ section = ROOT;
}
}