From 5f1a003329a18a3dbaa4758af5d3a1b18e9f6b0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Triszka?= Date: Thu, 11 May 2017 03:19:29 +0200 Subject: [PATCH] hal: Add open source HAL for Elliptic Ultrasound MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Author: Balázs Triszka Date: Thu May 11 03:19:29 2017 +0200 msm8998: ultrasound: Initial open source hal for Elliptic Ultrasound * Needed for proximity sensor on Xiaomi Mi MIX [Arasthel]: Change PCM id for Mi MIX 2 implementation Change-Id: Iaef2266bc1b853d7a9d1e2a906014c6c91019d5f Signed-off-by: Balázs Triszka Author: Michael Bestas Date: Sat Feb 10 00:28:00 2018 +0200 msm8998: ultrasound: Remove unused code * Params ultrasound_set_manual_calibration and ultrasound_set_sensitivity do not exist. Change-Id: I0004949db19b6ab7d49f20e422984e06a970cfe9 Author: Demon Singur Date: Sat Apr 21 09:08:03 2018 +0000 msm8998: hal: Update ultrasound route hacks Change-Id: If002503dfba0f005f73a4455d68bbcce9d2f617e Change-Id: I119316f264afbda9faf24950edfbca3891aa9769 Author: Vol Zhdanov Date: Fri Feb 1 02:16:26 2019 +0000 hal: fix channels swap for elliptic ultrasound devices Change-Id: Id45b075c4ad098c95fcb617da10c56d38565b9c8 Change-Id: Icb18f5b41483d33188be103e13b6c915b6e681b8 --- hal/Android.mk | 5 + hal/audio_extn/ultrasound.c | 254 ++++++++++++++++++++++++++++++++++++ hal/audio_extn/ultrasound.h | 33 +++++ hal/audio_hw.c | 37 ++++++ hal/audio_hw.h | 5 + hal/msm8974/platform.c | 18 ++- hal/msm8974/platform.h | 4 + 7 files changed, 355 insertions(+), 1 deletion(-) create mode 100644 hal/audio_extn/ultrasound.c create mode 100644 hal/audio_extn/ultrasound.h diff --git a/hal/Android.mk b/hal/Android.mk index 123393c4..83adb1ab 100644 --- a/hal/Android.mk +++ b/hal/Android.mk @@ -423,6 +423,11 @@ ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXT_AMPLIFIER)),true) LOCAL_SHARED_LIBRARIES += libhardware endif +ifeq ($(strip $(AUDIO_FEATURE_ELLIPTIC_ULTRASOUND_SUPPORT)),true) + LOCAL_CFLAGS += -DELLIPTIC_ULTRASOUND_ENABLED + LOCAL_SRC_FILES += audio_extn/ultrasound.c +endif + # Memory optimization specific feature ifeq ($(strip $(TARGET_1G_DDR_RAM)), true) LOCAL_CFLAGS += -DPURGE_UNUSED_MEM diff --git a/hal/audio_extn/ultrasound.c b/hal/audio_extn/ultrasound.c new file mode 100644 index 00000000..1a001e1c --- /dev/null +++ b/hal/audio_extn/ultrasound.c @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2017-2018 The LineageOS Project + * Copyright (c) 2017 Balázs Triszka + * + * 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. + */ + +#define LOG_TAG "ultrasound" + +#include +#include +#include +#include "audio_hw.h" +#include "platform_api.h" +#include +#include "ultrasound.h" + +#define ULTRASOUND_CALIBRATION_FILE "/mnt/vendor/persist/audio/us_cal" +#define ULTRASOUND_CALIBRATION_MIXER "Ultrasound Calibration Data" + +enum { + ULTRASOUND_STATUS_DEFAULT, + ULTRASOUND_STATUS_STARTED, + ULTRASOUND_STATUS_STOPPED, +}; + +struct pcm_config pcm_config_us = { + .channels = 1, + .rate = 96000, + .period_size = 1024, + .period_count = 2, + .format = PCM_FORMAT_S16_LE, +}; + +struct ultrasound_device { + struct pcm *rx_pcm, *tx_pcm; + int state; + struct audio_device *adev; +}; + +static struct ultrasound_device *us = NULL; + +void us_cal_load(void) +{ + FILE *f; + char buff[5] = {0}, us_cal[64]; + struct mixer_ctl *ctl; + int rc; + + f = fopen(ULTRASOUND_CALIBRATION_FILE, "r"); + if (!f) { + ALOGE("%s: Cannot open calibration file: %s", + __func__, ULTRASOUND_CALIBRATION_FILE); + return; + } + + for (size_t i = 0; i < sizeof(us_cal); i++) { + fread(buff, 1, sizeof(buff), f); + us_cal[i] = strtol(buff, 0, 16); + } + fclose(f); + + ctl = mixer_get_ctl_by_name(us->adev->mixer, ULTRASOUND_CALIBRATION_MIXER); + if (!ctl) { + ALOGE("%s: Could not get ctl for mixer cmd - %s", + __func__, ULTRASOUND_CALIBRATION_MIXER); + return; + } + + rc = mixer_ctl_set_array(ctl, us_cal, sizeof(us_cal)); + if (rc < 0) + ALOGE("%s: Could not set ctl, error:%d ", __func__, rc); +} + +int us_init(struct audio_device *adev) +{ + ALOGD("%s: enter", __func__); + + if (us) { + ALOGI("%s: ultrasound has been initialized!", __func__); + return 0; + } + + us = calloc(1, sizeof(struct ultrasound_device)); + if (!us) { + ALOGE("%s: Out of memory!", __func__); + return -ENOMEM; + } + + us->adev = adev; + + us_cal_load(); + + ALOGD("%s: exit, status(0)", __func__); + + return 0; +} + +void us_deinit(void) +{ + ALOGD("%s: enter", __func__); + + if (us) { + free(us); + us = NULL; + } + + ALOGD("%s: exit", __func__); +} + +int stop_us(void) +{ + struct audio_usecase *rx_usecase, *tx_usecase; + int rc = 0; + + ALOGD("%s: enter usecase: ultrasound", __func__); + + us->state = ULTRASOUND_STATUS_STOPPED; + if (us->rx_pcm) { + pcm_close(us->rx_pcm); + us->rx_pcm = NULL; + } + + if (us->tx_pcm) { + pcm_close(us->tx_pcm); + us->tx_pcm = NULL; + } + + rx_usecase = get_usecase_from_list(us->adev, USECASE_AUDIO_ULTRASOUND_RX); + if (!rx_usecase) { + ALOGE("%s: Could not find the usecase (%d) in the list", + __func__, USECASE_AUDIO_ULTRASOUND_RX); + rc = -EINVAL; + } else { + disable_audio_route(us->adev, rx_usecase); + disable_snd_device(us->adev, rx_usecase->out_snd_device); + list_remove(&rx_usecase->list); + free(rx_usecase); + } + + tx_usecase = get_usecase_from_list(us->adev, USECASE_AUDIO_ULTRASOUND_TX); + if (!rx_usecase) { + ALOGE("%s: Could not find the usecase (%d) in the list", + __func__, USECASE_AUDIO_ULTRASOUND_TX); + rc = -EINVAL; + } else { + disable_audio_route(us->adev, tx_usecase); + disable_snd_device(us->adev, tx_usecase->in_snd_device); + list_remove(&tx_usecase->list); + free(tx_usecase); + } + + ALOGD("%s: exit: status(%d)", __func__, rc); + + return rc; +} + +int us_start(void) +{ + int rx_device_id, tx_device_id; + struct audio_usecase *rx_usecase, *tx_usecase; + + ALOGD("%s: enter", __func__); + + if (!us || us->state == ULTRASOUND_STATUS_STARTED) + return -EPERM; + + ALOGD("%s: enter usecase: ultrasound", __func__); + rx_device_id = platform_get_pcm_device_id(USECASE_AUDIO_ULTRASOUND_RX, PCM_PLAYBACK); + tx_device_id = platform_get_pcm_device_id(USECASE_AUDIO_ULTRASOUND_TX, PCM_CAPTURE); + if (rx_device_id < 0 || tx_device_id < 0) { + ALOGE("%s: Invalid PCM devices (rx: %d tx: %d) for the usecase(ultrasound)", + __func__, rx_device_id, tx_device_id); + stop_us(); + ALOGE("%s: exit: status(%d)", __func__, -EIO); + return -EIO; + } + + rx_usecase = calloc(1, sizeof(struct audio_usecase)); + if (!rx_usecase) { + ALOGE("%s: Out of memory!", __func__); + return -ENOMEM; + } + + rx_usecase->type = PCM_PLAYBACK; + rx_usecase->out_snd_device = SND_DEVICE_OUT_ULTRASOUND_HANDSET; + rx_usecase->id = USECASE_AUDIO_ULTRASOUND_RX; + list_add_tail(&us->adev->usecase_list, &rx_usecase->list); + + enable_snd_device(us->adev, SND_DEVICE_OUT_ULTRASOUND_HANDSET); + enable_audio_route(us->adev, rx_usecase); + ALOGV("%s: Opening PCM playback device card_id(%d) device_id(%d)", + __func__, us->adev->snd_card, rx_device_id); + us->rx_pcm = pcm_open(us->adev->snd_card, rx_device_id, PCM_OUT, &pcm_config_us); + if (us->rx_pcm && !pcm_is_ready(us->rx_pcm)) { + ALOGE("%s: %s", __func__, pcm_get_error(us->rx_pcm)); + stop_us(); + ALOGE("%s: exit: status(%d)", __func__, -EIO); + return -EIO; + } + + tx_usecase = calloc(1, sizeof(struct audio_usecase)); + if (!tx_usecase) { + ALOGE("%s: Out of memory!", __func__); + return -ENOMEM; + } + + tx_usecase->type = PCM_CAPTURE; + tx_usecase->in_snd_device = SND_DEVICE_IN_ULTRASOUND_MIC; + tx_usecase->id = USECASE_AUDIO_ULTRASOUND_TX; + list_add_tail(&us->adev->usecase_list, &tx_usecase->list); + + enable_snd_device(us->adev, SND_DEVICE_IN_ULTRASOUND_MIC); + enable_audio_route(us->adev, tx_usecase); + ALOGV("%s: Opening PCM capture device card_id(%d) device_id(%d)", + __func__, us->adev->snd_card, tx_device_id); + us->tx_pcm = pcm_open(us->adev->snd_card, tx_device_id, PCM_IN, &pcm_config_us); + if (us->tx_pcm && !pcm_is_ready(us->tx_pcm)) { + ALOGD("%s: %s", __func__, pcm_get_error(us->tx_pcm)); + stop_us(); + ALOGE("%s: exit: status(%d)", __func__, -EIO); + return -EIO; + } + + pcm_start(us->rx_pcm); + pcm_start(us->tx_pcm); + us->state = ULTRASOUND_STATUS_STARTED; + + ALOGD("%s: exit, status(0)", __func__); + + return 0; +} + +int us_stop(void) +{ + ALOGD("%s: enter", __func__); + + if (!us || us->state != ULTRASOUND_STATUS_STARTED) + return -EPERM; + + stop_us(); + + return 0; +} diff --git a/hal/audio_extn/ultrasound.h b/hal/audio_extn/ultrasound.h new file mode 100644 index 00000000..0bb24cab --- /dev/null +++ b/hal/audio_extn/ultrasound.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017-2018 The LineageOS Project + * Copyright (c) 2017 Balázs Triszka + * + * 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 ULTRASOUND_H +#define ULTRASOUND_H + +#ifndef ELLIPTIC_ULTRASOUND_ENABLED +#define us_init(adev) (0) +#define us_deinit() (0) +#define us_start() (0) +#define us_stop() (0) +#else +int us_init(struct audio_device *adev); +void us_deinit(void); +int us_start(void); +int us_stop(void); +#endif + +#endif diff --git a/hal/audio_hw.c b/hal/audio_hw.c index eaf46e7b..fb2ddbd9 100644 --- a/hal/audio_hw.c +++ b/hal/audio_hw.c @@ -81,6 +81,7 @@ #include "audio_extn.h" #include "voice_extn.h" #include "ip_hdlr_intf.h" +#include "ultrasound.h" #include "sound/compress_params.h" @@ -517,6 +518,10 @@ const char * const use_case_table[AUDIO_USECASE_MAX] = { [USECASE_AUDIO_RECORD_BUS_REAR_SEAT] = "rear-seat-record", [USECASE_AUDIO_PLAYBACK_SYNTHESIZER] = "synth-loopback", [USECASE_AUDIO_RECORD_ECHO_REF_EXT] = "echo-reference-external", + + /* For Elliptic Ultrasound proximity sensor */ + [USECASE_AUDIO_ULTRASOUND_RX] = "ultrasound-rx", + [USECASE_AUDIO_ULTRASOUND_TX] = "ultrasound-tx", }; static const audio_usecase_t offload_usecases[] = { @@ -1513,6 +1518,9 @@ int enable_audio_route(struct audio_device *adev, audio_extn_utils_send_app_type_cfg(adev, usecase); if (audio_extn_is_maxx_audio_enabled()) audio_extn_ma_set_device(usecase); +#ifdef ELLIPTIC_ULTRASOUND_ENABLED + if (usecase->id != USECASE_AUDIO_ULTRASOUND_TX) +#endif audio_extn_utils_send_audio_calibration(adev, usecase); if ((usecase->type == PCM_PLAYBACK) && is_offload_usecase(usecase->id)) { out = usecase->stream.out; @@ -1770,6 +1778,10 @@ int enable_snd_device(struct audio_device *adev, ST_EVENT_SND_DEVICE_BUSY); audio_extn_listen_update_device_status(snd_device, LISTEN_EVENT_SND_DEVICE_BUSY); +#ifdef ELLIPTIC_ULTRASOUND_ENABLED + if (snd_device != SND_DEVICE_OUT_ULTRASOUND_HANDSET && + snd_device != SND_DEVICE_IN_ULTRASOUND_MIC) +#endif if (platform_get_snd_device_acdb_id(snd_device) < 0) { audio_extn_sound_trigger_update_device_status(snd_device, ST_EVENT_SND_DEVICE_FREE); @@ -2125,6 +2137,12 @@ static void check_usecases_codec_backend(struct audio_device *adev, platform_get_snd_device_name(snd_device), platform_get_snd_device_name(usecase->out_snd_device), platform_check_backends_match(snd_device, usecase->out_snd_device)); + +#ifdef ELLIPTIC_ULTRASOUND_ENABLED + if (usecase->id == USECASE_AUDIO_ULTRASOUND_RX) + continue; +#endif + if ((usecase->type != PCM_CAPTURE) && (usecase != uc_info) && (usecase->type != PCM_PASSTHROUGH)) { uc_derive_snd_device = derive_playback_snd_device(adev->platform, @@ -2287,6 +2305,11 @@ static void check_usecases_capture_codec_backend(struct audio_device *adev, * TODO: Enhance below condition to handle BT sco/USB multi recording */ +#ifdef ELLIPTIC_ULTRASOUND_ENABLED + if (usecase->id == USECASE_AUDIO_ULTRASOUND_TX) + continue; +#endif + bool capture_uc_needs_routing = usecase->type != PCM_PLAYBACK && (usecase != uc_info && (usecase->in_snd_device != snd_device || force_routing)); bool call_proxy_snd_device = platform_is_call_proxy_snd_device(snd_device) || @@ -9600,6 +9623,15 @@ static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) } } + ret = str_parms_get_int(parms, "ultrasound-sensor", &val); + if (ret >= 0) { + if (val == 1) { + us_start(); + } else { + us_stop(); + } + } + amplifier_set_parameters(parms); audio_extn_auto_hal_set_parameters(adev, parms); audio_extn_set_parameters(adev, parms); @@ -11089,6 +11121,9 @@ static int adev_close(hw_device_t *device) free(device); adev = NULL; } + + us_deinit(); + pthread_mutex_unlock(&adev_init_lock); enable_gcov(); return 0; @@ -11504,6 +11539,8 @@ static int adev_open(const hw_module_t *module, const char *name, if (amplifier_open(adev) != 0) ALOGE("Amplifier initialization failed"); + us_init(adev); + *device = &adev->device.common; if (k_enable_extended_precision) diff --git a/hal/audio_hw.h b/hal/audio_hw.h index c1b6879a..08460a43 100644 --- a/hal/audio_hw.h +++ b/hal/audio_hw.h @@ -332,6 +332,11 @@ enum { /*In Car Communication Usecase*/ USECASE_ICC_CALL, + + /* Elliptic Ultrasound */ + USECASE_AUDIO_ULTRASOUND_RX, + USECASE_AUDIO_ULTRASOUND_TX, + AUDIO_USECASE_MAX }; diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c index 77960577..f8c4a7f6 100644 --- a/hal/msm8974/platform.c +++ b/hal/msm8974/platform.c @@ -613,6 +613,8 @@ static int pcm_device_table[AUDIO_USECASE_MAX][4] = { [USECASE_AUDIO_PLAYBACK_SYNTHESIZER] = {-1, -1, -1, -1}, [USECASE_AUDIO_RECORD_ECHO_REF_EXT] = {MULTIMEDIA2_PCM_DEVICE, MULTIMEDIA2_PCM_DEVICE, MSM_FRONTEND_DAI_MULTIMEDIA2, MSM_FRONTEND_DAI_MULTIMEDIA2}, + [USECASE_AUDIO_ULTRASOUND_RX] = {ULTRASOUND_PCM_DEVICE, -1}, + [USECASE_AUDIO_ULTRASOUND_TX] = {-1, ULTRASOUND_PCM_DEVICE}, }; /* Array to store sound devices */ @@ -727,6 +729,7 @@ static const char * const device_table[SND_DEVICE_MAX] = { [SND_DEVICE_OUT_HAPTICS] = "haptics", [SND_DEVICE_OUT_ICC] = "bus-speaker", [SND_DEVICE_OUT_SYNTH_SPKR] = "bus-speaker", + [SND_DEVICE_OUT_ULTRASOUND_HANDSET] = "ultrasound-handset", /* Capture sound devices */ [SND_DEVICE_IN_HANDSET_MIC] = "handset-mic", @@ -896,6 +899,7 @@ static const char * const device_table[SND_DEVICE_MAX] = { [SND_DEVICE_IN_SPEAKER_MIC2] = "speaker-mic2", [SND_DEVICE_IN_SPEAKER_MIC3] = "speaker-mic3", [SND_DEVICE_IN_HANDSET_GENERIC_6MIC_AND_SPEAKER_MIC2] = "handset-6mic-and-speaker-mic2", + [SND_DEVICE_IN_ULTRASOUND_MIC] = "ultrasound-mic", }; // Platform specific backend bit width table @@ -1572,6 +1576,8 @@ static struct name_to_index usecase_name_index[AUDIO_USECASE_MAX] = { {TO_NAME_INDEX(USECASE_AUDIO_RECORD_BUS_FRONT_PASSENGER)}, {TO_NAME_INDEX(USECASE_AUDIO_RECORD_BUS_REAR_SEAT)}, {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_SYNTHESIZER)}, + {TO_NAME_INDEX(USECASE_AUDIO_ULTRASOUND_RX)}, + {TO_NAME_INDEX(USECASE_AUDIO_ULTRASOUND_TX)}, }; static const struct name_to_index usecase_type_index[USECASE_TYPE_MAX] = { @@ -2132,7 +2138,11 @@ bool platform_send_gain_dep_cal(void *platform, int level) { usecase = node_to_item(node, struct audio_usecase, list); if (usecase != NULL && usecase->stream.out && - usecase->type == PCM_PLAYBACK) { + usecase->type == PCM_PLAYBACK +#ifdef ELLIPTIC_ULTRASOUND_ENABLED + && usecase->id != USECASE_AUDIO_ULTRASOUND_RX +#endif + ) { int new_snd_device[2] = {0}; int i, num_devices = 1; @@ -2680,6 +2690,7 @@ static void set_platform_defaults(struct platform_data * my_data) hw_interface_table[SND_DEVICE_OUT_BUS_RSE] = strdup("QUIN_TDM_RX_0"); hw_interface_table[SND_DEVICE_OUT_CALL_PROXY] = strdup("CALL_PROXY_RX"); hw_interface_table[SND_DEVICE_OUT_HAPTICS] = strdup("RX_CDC_DMA_RX_6"); + hw_interface_table[SND_DEVICE_OUT_ULTRASOUND_HANDSET] = strdup("SLIMBUS_0_RX"); hw_interface_table[SND_DEVICE_IN_HANDSET_MIC] = strdup("SLIMBUS_0_TX"); hw_interface_table[SND_DEVICE_IN_HANDSET_MIC_SB] = strdup("SLIMBUS_0_TX"); hw_interface_table[SND_DEVICE_IN_HANDSET_MIC_NN] = strdup("SLIMBUS_0_TX"); @@ -2829,6 +2840,8 @@ static void set_platform_defaults(struct platform_data * my_data) hw_interface_table[SND_DEVICE_IN_ECHO_REFERENCE] = strdup("SEC_TDM_TX_0"); hw_interface_table[SND_DEVICE_IN_SPEAKER_MIC2] = strdup("QUAT_TDM_TX_0"); hw_interface_table[SND_DEVICE_IN_SPEAKER_MIC3] = strdup("SEN_TDM_TX_0"); + hw_interface_table[SND_DEVICE_IN_ULTRASOUND_MIC] = strdup("SLIMBUS_0_TX"); + my_data->max_mic_count = PLATFORM_DEFAULT_MIC_COUNT; /*remove ALAC & APE from DSP decoder list based on software decoder availability*/ @@ -12688,6 +12701,9 @@ int platform_set_swap_channels(struct audio_device *adev, bool swap_channels) list_for_each(node, &adev->usecase_list) { usecase = node_to_item(node, struct audio_usecase, list); +#ifdef ELLIPTIC_ULTRASOUND_ENABLED + if (usecase->id != USECASE_AUDIO_ULTRASOUND_RX) +#endif if (usecase->stream.out && usecase->type == PCM_PLAYBACK && compare_device_type(&usecase->stream.out->device_list, AUDIO_DEVICE_OUT_SPEAKER)) { diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h index 266e0d18..e3883730 100644 --- a/hal/msm8974/platform.h +++ b/hal/msm8974/platform.h @@ -214,6 +214,7 @@ enum { SND_DEVICE_OUT_HAPTICS, SND_DEVICE_OUT_ICC, SND_DEVICE_OUT_SYNTH_SPKR, + SND_DEVICE_OUT_ULTRASOUND_HANDSET, SND_DEVICE_OUT_END, /* @@ -388,6 +389,7 @@ enum { SND_DEVICE_IN_SPEAKER_MIC2, SND_DEVICE_IN_SPEAKER_MIC3, SND_DEVICE_IN_HANDSET_GENERIC_6MIC_AND_SPEAKER_MIC2, + SND_DEVICE_IN_ULTRASOUND_MIC, SND_DEVICE_IN_END, SND_DEVICE_MAX = SND_DEVICE_IN_END, @@ -710,6 +712,8 @@ enum { #define AFE_PROXY_RECORD_PCM_DEVICE 8 #define AFE_PROXY_RECORD2_PCM_DEVICE 40 +#define ULTRASOUND_PCM_DEVICE 10 + #ifdef PLATFORM_MSM8x26 #ifdef EXTERNAL_BT_SUPPORTED #define HFP_SCO_RX 10 // AUXPCM Hostless