audio: hal: Initialize AFE configs by querying the kernel
- AFE configuration is not reset to default after a 24 bit playback.
- To fix this initialize the configurations by querying the
kernel for mixer bitwidth, samplerate, and channel configurations
everytime.
Change-Id: Id68a41e36f40ce0d6720d92ee0ce048a266e48fa
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 7f32f4d..3ea6646 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -629,6 +629,9 @@
int audio_extn_utils_get_snd_card_num();
bool audio_extn_is_dsp_bit_width_enforce_mode_supported(audio_output_flags_t flags);
bool audio_extn_utils_is_dolby_format(audio_format_t format);
+int audio_extn_utils_get_bit_width_from_string(const char *);
+int audio_extn_utils_get_sample_rate_from_string(const char *);
+int audio_extn_utils_get_channels_from_string(const char *);
#ifdef DS2_DOLBY_DAP_ENABLED
#define LIB_DS2_DAP_HAL "vendor/lib/libhwdaphal.so"
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index c01e6f7..de233ea 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -106,6 +106,11 @@
#define MAX_CHANNELS_SUPPORTED 8
#endif
+typedef struct {
+ const char *id_string;
+ const int value;
+} mixer_config_lookup;
+
struct string_to_enum {
const char *name;
uint32_t value;
@@ -2363,4 +2368,63 @@
return false;
}
+int audio_extn_utils_get_bit_width_from_string(const char *id_string)
+{
+ int i;
+ const mixer_config_lookup mixer_bitwidth_config[] = {{"S24_3LE", 24},
+ {"S32_LE", 32},
+ {"S24_LE", 24},
+ {"S16_LE", 16}};
+ int num_configs = sizeof(mixer_bitwidth_config) / sizeof(mixer_bitwidth_config[0]);
+ for (i = 0; i < num_configs; i++) {
+ if (!strcmp(id_string, mixer_bitwidth_config[i].id_string))
+ return mixer_bitwidth_config[i].value;
+ }
+
+ return -EINVAL;
+}
+
+int audio_extn_utils_get_sample_rate_from_string(const char *id_string)
+{
+ int i;
+ const mixer_config_lookup mixer_samplerate_config[] = {{"KHZ_32", 32000},
+ {"KHZ_48", 48000},
+ {"KHZ_96", 96000},
+ {"KHZ_144", 144000},
+ {"KHZ_192", 192000},
+ {"KHZ_384", 384000},
+ {"KHZ_44P1", 44100},
+ {"KHZ_88P2", 88200},
+ {"KHZ_176P4", 176400},
+ {"KHZ_352P8", 352800}};
+ int num_configs = sizeof(mixer_samplerate_config) / sizeof(mixer_samplerate_config[0]);
+
+ for (i = 0; i < num_configs; i++) {
+ if (!strcmp(id_string, mixer_samplerate_config[i].id_string))
+ return mixer_samplerate_config[i].value;
+ }
+
+ return -EINVAL;
+}
+
+int audio_extn_utils_get_channels_from_string(const char *id_string)
+{
+ int i;
+ const mixer_config_lookup mixer_channels_config[] = {{"One", 1},
+ {"Two", 2},
+ {"Three",3},
+ {"Four", 4},
+ {"Five", 5},
+ {"Six", 6},
+ {"Seven", 7},
+ {"Eight", 8}};
+ int num_configs = sizeof(mixer_channels_config) / sizeof(mixer_channels_config[0]);
+
+ for (i = 0; i < num_configs; i++) {
+ if (!strcmp(id_string, mixer_channels_config[i].id_string))
+ return mixer_channels_config[i].value;
+ }
+
+ return -EINVAL;
+}
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 45b02e3..4987f8b 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -972,6 +972,8 @@
#define ULL_PLATFORM_DELAY (6*1000LL)
#define MMAP_PLATFORM_DELAY (3*1000LL)
+static const char *platform_get_mixer_control(struct mixer_ctl *);
+
static void update_interface(const char *snd_card_name) {
if (!strncmp(snd_card_name, "apq8009-tashalite-snd-card",
sizeof("apq8009-tashalite-snd-card"))) {
@@ -2149,6 +2151,8 @@
int idx;
int wsaCount =0;
bool is_wsa_combo_supported = false;
+ const char *id_string = NULL;
+ int cfg_value = -1;
snd_card_num = audio_extn_utils_get_snd_card_num();
if(snd_card_num < 0) {
@@ -2599,6 +2603,41 @@
my_data->current_backend_cfg[HDMI_TX_BACKEND].channels_mixer_ctl =
strdup("QUAT_MI2S_TX Channels");
+ for (idx = 0; idx < MAX_CODEC_BACKENDS; idx++) {
+ if (my_data->current_backend_cfg[idx].bitwidth_mixer_ctl) {
+ ctl = mixer_get_ctl_by_name(adev->mixer,
+ my_data->current_backend_cfg[idx].bitwidth_mixer_ctl);
+ id_string = platform_get_mixer_control(ctl);
+ if (id_string) {
+ cfg_value = audio_extn_utils_get_bit_width_from_string(id_string);
+ if (cfg_value > 0)
+ my_data->current_backend_cfg[idx].bit_width = cfg_value;
+ }
+ }
+
+ if (my_data->current_backend_cfg[idx].samplerate_mixer_ctl) {
+ ctl = mixer_get_ctl_by_name(adev->mixer,
+ my_data->current_backend_cfg[idx].samplerate_mixer_ctl);
+ id_string = platform_get_mixer_control(ctl);
+ if (id_string) {
+ cfg_value = audio_extn_utils_get_sample_rate_from_string(id_string);
+ if (cfg_value > 0)
+ my_data->current_backend_cfg[idx].sample_rate = cfg_value;
+ }
+ }
+
+ if (my_data->current_backend_cfg[idx].channels_mixer_ctl) {
+ ctl = mixer_get_ctl_by_name(adev->mixer,
+ my_data->current_backend_cfg[idx].channels_mixer_ctl);
+ id_string = platform_get_mixer_control(ctl);
+ if (id_string) {
+ cfg_value = audio_extn_utils_get_channels_from_string(id_string);
+ if (cfg_value > 0)
+ my_data->current_backend_cfg[idx].channels = cfg_value;
+ }
+ }
+ }
+
ret = audio_extn_utils_get_codec_version(snd_card_name,
my_data->adev->snd_card,
my_data->codec_version);
@@ -7847,3 +7886,20 @@
return -1;
}
#endif
+
+static const char *platform_get_mixer_control(struct mixer_ctl *ctl)
+{
+ int id = -1;
+ const char *id_string = NULL;
+
+ if (!ctl) {
+ ALOGD("%s: mixer ctl not obtained", __func__);
+ } else {
+ id = mixer_ctl_get_value(ctl, 0);
+ if (id >= 0) {
+ id_string = mixer_ctl_get_enum_string(ctl, id);
+ }
+ }
+
+ return id_string;
+}
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 64dde86..371f3fc 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -1018,6 +1018,8 @@
return ret;
}
+static const char *platform_get_mixer_control(struct mixer_ctl *);
+
bool platform_send_gain_dep_cal(void *platform, int level) {
bool ret_val = false;
struct platform_data *my_data = (struct platform_data *)platform;
@@ -1880,6 +1882,9 @@
char *tmp = NULL;
char mixer_xml_file[MIXER_PATH_MAX_LENGTH]= {0};
int idx;
+ struct mixer_ctl *ctl = NULL;
+ const char *id_string = NULL;
+ int cfg_value = -1;
adev->snd_card = audio_extn_utils_get_snd_card_num();
if (adev->snd_card < 0) {
@@ -2342,6 +2347,41 @@
my_data->current_backend_cfg[HDMI_TX_BACKEND].channels_mixer_ctl =
strdup("QUAT_MI2S_TX Channels");
+ for (idx = 0; idx < MAX_CODEC_BACKENDS; idx++) {
+ if (my_data->current_backend_cfg[idx].bitwidth_mixer_ctl) {
+ ctl = mixer_get_ctl_by_name(adev->mixer,
+ my_data->current_backend_cfg[idx].bitwidth_mixer_ctl);
+ id_string = platform_get_mixer_control(ctl);
+ if (id_string) {
+ cfg_value = audio_extn_utils_get_bit_width_from_string(id_string);
+ if (cfg_value > 0)
+ my_data->current_backend_cfg[idx].bit_width = cfg_value;
+ }
+ }
+
+ if (my_data->current_backend_cfg[idx].samplerate_mixer_ctl) {
+ ctl = mixer_get_ctl_by_name(adev->mixer,
+ my_data->current_backend_cfg[idx].samplerate_mixer_ctl);
+ id_string = platform_get_mixer_control(ctl);
+ if (id_string) {
+ cfg_value = audio_extn_utils_get_sample_rate_from_string(id_string);
+ if (cfg_value > 0)
+ my_data->current_backend_cfg[idx].sample_rate = cfg_value;
+ }
+ }
+
+ if (my_data->current_backend_cfg[idx].channels_mixer_ctl) {
+ ctl = mixer_get_ctl_by_name(adev->mixer,
+ my_data->current_backend_cfg[idx].channels_mixer_ctl);
+ id_string = platform_get_mixer_control(ctl);
+ if (id_string) {
+ cfg_value = audio_extn_utils_get_channels_from_string(id_string);
+ if (cfg_value > 0)
+ my_data->current_backend_cfg[idx].channels = cfg_value;
+ }
+ }
+ }
+
ret = audio_extn_utils_get_codec_version(snd_card_name,
my_data->adev->snd_card,
my_data->codec_version);
@@ -7585,3 +7625,20 @@
return -1;
}
#endif
+
+static const char *platform_get_mixer_control(struct mixer_ctl *ctl)
+{
+ int id = -1;
+ const char *id_string = NULL;
+
+ if (!ctl) {
+ ALOGD("%s: mixer ctl not obtained", __func__);
+ } else {
+ id = mixer_ctl_get_value(ctl, 0);
+ if (id >= 0) {
+ id_string = mixer_ctl_get_enum_string(ctl, id);
+ }
+ }
+
+ return id_string;
+}