summaryrefslogtreecommitdiff
path: root/emulator/audio/driver
diff options
context:
space:
mode:
authorJyoti Bhayana <jbhayana@google.com>2022-01-20 14:47:54 -0800
committerJyoti Bhayana <jbhayana@google.com>2022-02-10 18:28:03 +0000
commit3ffa826892751f388d7daa92027091c256de735d (patch)
tree3869a48dcf17b4550dcbb008233aecd9faae7224 /emulator/audio/driver
parent7e09168c2e755dccd06015db094f4e860462dd80 (diff)
downloadcar-3ffa826892751f388d7daa92027091c256de735d.tar.gz
Modifying the Audio HAL to support BT HFP for Trout
Trout will be using virtio sound based mixer controls to enable BT HFP. Modifying the Audio HAL to support those mixer controls. Bug:199794969 Test: Trout source code compiles fine with BT HFP feature enabled. Cannot test functionally as missing HFP code on the host side. Change-Id: Ia1983307791c1e1092d114289b5d82cd1c030f9b
Diffstat (limited to 'emulator/audio/driver')
-rw-r--r--emulator/audio/driver/Android.bp21
-rw-r--r--emulator/audio/driver/audio_extn/audio_extn.h38
-rw-r--r--emulator/audio/driver/audio_extn/hfp.c143
-rw-r--r--emulator/audio/driver/audio_hw.c4
-rw-r--r--emulator/audio/driver/audio_hw.h1
5 files changed, 206 insertions, 1 deletions
diff --git a/emulator/audio/driver/Android.bp b/emulator/audio/driver/Android.bp
index 945c628..8b9f53e 100644
--- a/emulator/audio/driver/Android.bp
+++ b/emulator/audio/driver/Android.bp
@@ -24,13 +24,31 @@ package {
default_applicable_licenses: ["device_generic_car_license"],
}
+soong_config_module_type {
+ name: "audio_extn_cc_defaults",
+ module_type: "cc_defaults",
+ config_namespace: "audio_extn_config",
+ bool_variables: ["isHFPEnabled"],
+ properties: ["srcs", "cflags"],
+}
+
+audio_extn_cc_defaults {
+ name: "audio_extn_hfp",
+ soong_config_variables: {
+ isHFPEnabled: {
+ cflags: ["-DHFP_ENABLED"],
+ srcs: ["audio_extn/hfp.c"],
+ },
+ },
+}
+
cc_library_shared {
vendor: true,
vintf_fragments: ["android.hardware.audio@6.0-impl.xml"],
name: "audio.primary.caremu",
relative_install_path: "hw",
-
+ defaults: ["audio_extn_hfp"],
srcs: [
"audio_hw.c",
"audio_vbuffer.c",
@@ -38,6 +56,7 @@ cc_library_shared {
],
include_dirs: ["external/tinyalsa/include"],
+ local_include_dirs: ["audio_extn"],
export_include_dirs: [
"include"
],
diff --git a/emulator/audio/driver/audio_extn/audio_extn.h b/emulator/audio/driver/audio_extn/audio_extn.h
new file mode 100644
index 0000000..13050c6
--- /dev/null
+++ b/emulator/audio/driver/audio_extn/audio_extn.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AUDIO_EXTN_H
+#define AUDIO_EXTN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "audio_hw.h"
+#include <cutils/str_parms.h>
+
+#ifndef HFP_ENABLED
+#define audio_extn_hfp_set_parameters(adev, parms) (0)
+#else
+int audio_extn_hfp_set_parameters(struct generic_audio_device *adev,
+ struct str_parms *parms);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AUDIO_EXTN_H */
diff --git a/emulator/audio/driver/audio_extn/hfp.c b/emulator/audio/driver/audio_extn/hfp.c
new file mode 100644
index 0000000..fbe4000
--- /dev/null
+++ b/emulator/audio/driver/audio_extn/hfp.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifdef HFP_ENABLED
+
+#define LOG_TAG "audio_hw_hfp"
+#define LOG_NDDEBUG 0
+
+#include "audio_extn.h"
+#include <cutils/log.h>
+#include <cutils/str_parms.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#define AUDIO_PARAMETER_HFP_ENABLE "hfp_enable"
+#define AUDIO_PARAMETER_HFP_SET_SAMPLING_RATE "hfp_set_sampling_rate"
+#define AUDIO_PARAMETER_HFP_VOLUME "hfp_volume"
+#define AUDIO_PARAMETER_HFP_VALUE_MAX 128
+
+static int hfp_set_enable(struct generic_audio_device *adev, bool enable) {
+ struct mixer_ctl *ctl;
+ ALOGD("%s: enter enable : %d", __func__, enable);
+
+ ctl = mixer_get_ctl_by_name(adev->mixer, AUDIO_PARAMETER_HFP_ENABLE);
+ if (!ctl) {
+ ALOGE("%s: Could not get mixer ctl for - %s", __func__,
+ AUDIO_PARAMETER_HFP_ENABLE);
+ return -EINVAL;
+ }
+
+ if (mixer_ctl_set_value(ctl, 0, enable) < 0) {
+ ALOGE("%s: Couldn't set mixer ctrl for %s", __func__,
+ AUDIO_PARAMETER_HFP_ENABLE);
+ return -EINVAL;
+ }
+
+ adev->hfp_running = enable;
+ ALOGD("%s: exit: status success", __func__);
+ return 0;
+}
+
+static int hfp_set_sampling_rate(struct generic_audio_device *adev, int rate) {
+ struct mixer_ctl *ctl;
+ ALOGD("%s: enter rate = %d", __func__, rate);
+
+ ctl =
+ mixer_get_ctl_by_name(adev->mixer, AUDIO_PARAMETER_HFP_SET_SAMPLING_RATE);
+ if (!ctl) {
+ ALOGE("%s: Could not get mixer ctl for - %s", __func__,
+ AUDIO_PARAMETER_HFP_SET_SAMPLING_RATE);
+ return -EINVAL;
+ }
+
+ if (mixer_ctl_set_value(ctl, 0, rate) < 0) {
+ ALOGE("%s: Couldn't set mixer ctrl for %s", __func__,
+ AUDIO_PARAMETER_HFP_SET_SAMPLING_RATE);
+ return -EINVAL;
+ }
+
+ ALOGD("%s: exit: status success", __func__);
+ return 0;
+}
+
+static int hfp_set_volume(struct generic_audio_device *adev, int vol) {
+ struct mixer_ctl *ctl;
+ ALOGD("%s: enter vol = %d", __func__, vol);
+
+ ctl = mixer_get_ctl_by_name(adev->mixer, AUDIO_PARAMETER_HFP_VOLUME);
+ if (!ctl) {
+ ALOGE("%s: Could not get mixer ctl for - %s", __func__,
+ AUDIO_PARAMETER_HFP_VOLUME);
+ return -EINVAL;
+ }
+
+ if (mixer_ctl_set_value(ctl, 0, vol) < 0) {
+ ALOGE("%s: Couldn't set mixer ctrl for %s", __func__,
+ AUDIO_PARAMETER_HFP_VOLUME);
+ return -EINVAL;
+ }
+
+ ALOGD("%s: exit: status success", __func__);
+ return 0;
+}
+
+int audio_extn_hfp_set_parameters(struct generic_audio_device *adev,
+ struct str_parms *parms) {
+ int ret = 0, rate, vol;
+ char value[AUDIO_PARAMETER_HFP_VALUE_MAX] = {0};
+
+ ret = str_parms_get_str(parms, AUDIO_PARAMETER_HFP_ENABLE, value,
+ sizeof(value));
+ if (ret >= 0) {
+ if (!strncmp(value, "true", sizeof(value))) {
+ if (!adev->hfp_running)
+ ret = hfp_set_enable(adev, true);
+ else
+ ALOGW("%s: HFP is already active.", __func__);
+ } else {
+ if (adev->hfp_running)
+ ret = hfp_set_enable(adev, false);
+ else
+ ALOGW("%s: ignore STOP, HFP not active", __func__);
+ }
+
+ if (ret < 0)
+ goto exit;
+ }
+
+ memset(value, 0, sizeof(value));
+ ret = str_parms_get_str(parms, AUDIO_PARAMETER_HFP_SET_SAMPLING_RATE, value,
+ sizeof(value));
+ if (ret >= 0) {
+ rate = strtol(value, NULL, 10);
+ ret = hfp_set_sampling_rate(adev, rate);
+ if (ret < 0)
+ goto exit;
+ }
+
+ memset(value, 0, sizeof(value));
+ ret = str_parms_get_str(parms, AUDIO_PARAMETER_HFP_VOLUME, value,
+ sizeof(value));
+ if (ret >= 0) {
+ vol = strtol(value, NULL, 10);
+ ret = hfp_set_volume(adev, vol);
+ }
+
+exit:
+ ALOGD("%s exit: status", __func__);
+ return ret;
+}
+#endif /*HFP_ENABLED*/
diff --git a/emulator/audio/driver/audio_hw.c b/emulator/audio/driver/audio_hw.c
index 36796c4..2580756 100644
--- a/emulator/audio/driver/audio_hw.c
+++ b/emulator/audio/driver/audio_hw.c
@@ -22,6 +22,7 @@
#define LOG_TAG "audio_hw_generic_caremu"
// #define LOG_NDEBUG 0
+#include "audio_extn.h"
#include "audio_hw.h"
#include "include/audio_hw_control.h"
@@ -1250,6 +1251,7 @@ static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
results = 0;
ALOGD("%s Changed play zone id to %d", __func__, adev->last_zone_selected_to_play);
}
+ results = audio_extn_hfp_set_parameters(adev, parms);
str_parms_destroy(parms);
pthread_mutex_unlock(&adev->lock);
return results;
@@ -1665,6 +1667,8 @@ static int adev_open(const hw_module_t *module,
adev->last_zone_selected_to_play = DEFAULT_ZONE_TO_LEFT_SPEAKER;
+ adev->hfp_running = false;
+
device_handle = adev;
audio_device_ref_count++;
diff --git a/emulator/audio/driver/audio_hw.h b/emulator/audio/driver/audio_hw.h
index 1f9aa51..c243222 100644
--- a/emulator/audio/driver/audio_hw.h
+++ b/emulator/audio/driver/audio_hw.h
@@ -37,6 +37,7 @@ struct generic_audio_device {
int next_tone_frequency_to_assign; // Protected by this->lock
// Play on Speaker zone selection
int last_zone_selected_to_play; // Protected by this->lock
+ bool hfp_running;
};
static struct generic_audio_device *device_handle;