Compare commits

...

10 Commits

Author SHA1 Message Date
Alexander Winkowski 9e8a35eb12
hal: Set sample rate to 96 KHz for ultrasound
Change-Id: I812378aeedde583d7ebec249bd9e36dda3ced028
2024-11-16 05:02:09 +00:00
Alexander Winkowski 369fcd53d4
hal: Ignore ultrasound usecase in select_devices()
This matches stock audio HAL from veux.

Change-Id: I1abb3b703024abe1b4723e11e82016fcbb9dbcc2
2024-11-16 05:02:09 +00:00
Alexander Winkowski 7b05e8f445
hal: Select speaker when it's active
If handset and speaker use different interfaces, then
they can't be enabled simultaneously. On veux, this causes
top speaker to be disabled during ultrasound emitting.

This matches stock audio HAL from veux.

Change-Id: Id5afafbce56f2192bde9729e4c5c1349b37c390e
2024-11-16 05:02:09 +00:00
Alexander Winkowski 1da52220dd
hal: Add SND_DEVICE_IN_ULTRASOUND_MIC to ACDB table
This matches stock audio HAL from veux.

Change-Id: I8e6c4dbf6fb53d4819ebac31c600db78bbfc6db0
2024-11-16 05:02:09 +00:00
Alexander Winkowski 4cb98637b0
hal: Remove SND_DEVICE_OUT_ULTRASOUND_HANDSET
Use SND_DEVICE_OUT_VOICE_HANDSET to avoid audio HAL crashes
when switching output devices (reproducible with WhatApp calls).

This matches stock audio HAL from veux.

Change-Id: I469aec5034e7abe8fa9c9a45cfb82b6fc7e840b5
2024-11-16 05:02:08 +00:00
Alexander Winkowski 66b1a74b5c
hal: Remove default ultrasound PCM ID
This value is device-specific.

Change-Id: Ic80d33c66e65a363bb6629a02b7b59767e0e5a0b
2024-11-16 05:02:08 +00:00
Alexander Winkowski afd6b63494
hal: ultrasound: Implement RampDown
This matches stock audio HAL from veux.

Change-Id: Ie2b74420747c12a5fe372832198a148393c32108
2024-11-16 05:02:04 +00:00
Alexander Winkowski 1eeb1abcef
hal: ultrasound: Set stream.out
This matches stock audio HAL from veux.

Change-Id: I481fad4e6bb01a5994f2119fa177787a7a12415d
2024-11-16 04:58:51 +00:00
Alexander Winkowski 101d58923c
hal: ultrasound: Declare internal symbols as `static`
Change-Id: Ibf2d40d12db57d21da48e733be8e76f2908c835d
2024-11-16 04:58:51 +00:00
Alexander Winkowski d92854cd7b
hal: ultrasound: Refactor errors handling
This also fixes memory leak when calloc() fails for tx_usecase.

Change-Id: If2027c43d08fba3388329fabbd63b6b26698ff3c
2024-11-16 04:58:01 +00:00
5 changed files with 154 additions and 58 deletions

View File

@ -27,6 +27,8 @@
#define ULTRASOUND_CALIBRATION_FILE "/mnt/vendor/persist/audio/us_cal"
#define ULTRASOUND_CALIBRATION_MIXER "Ultrasound Calibration Data"
#define ULTRASOUND_RAMPDOWN_MIXER "Ultrasound RampDown"
#define ULTRASOUND_SUSPEND_MIXER "Ultrasound Suspend"
enum {
ULTRASOUND_STATUS_DEFAULT,
@ -34,7 +36,7 @@ enum {
ULTRASOUND_STATUS_STOPPED,
};
struct pcm_config pcm_config_us = {
static struct pcm_config pcm_config_us = {
.channels = 1,
.rate = 96000,
.period_size = 1024,
@ -50,7 +52,7 @@ struct ultrasound_device {
static struct ultrasound_device *us = NULL;
void us_cal_load(void)
static void us_cal_load(void)
{
FILE *f;
char buff[5] = {0}, us_cal[64];
@ -82,28 +84,83 @@ void us_cal_load(void)
ALOGE("%s: Could not set ctl, error:%d ", __func__, rc);
}
static void us_ramp_down(void)
{
struct mixer_ctl *ctl;
int rc;
ALOGD("%s: enter", __func__);
ctl = mixer_get_ctl_by_name(us->adev->mixer, ULTRASOUND_RAMPDOWN_MIXER);
if (!ctl) {
ALOGD("%s: Could not get ctl for mixer cmd - %s",
__func__, ULTRASOUND_RAMPDOWN_MIXER);
goto exit;
}
rc = mixer_ctl_set_enum_by_string(ctl, "On");
if (rc < 0) {
ALOGE("%s: Could not set ctl, error:%d ", __func__, rc);
goto exit;
}
usleep(10000);
exit:
ALOGD("%s: exit", __func__);
}
void us_suspend(int val)
{
struct mixer_ctl *ctl;
int rc;
ALOGD("%s: enter", __func__);
ALOGD("%s: suspend: %d", __func__, val);
ctl = mixer_get_ctl_by_name(us->adev->mixer, ULTRASOUND_SUSPEND_MIXER);
if (!ctl) {
ALOGD("%s: Could not get ctl for mixer cmd - %s",
__func__, ULTRASOUND_SUSPEND_MIXER);
goto exit;
}
if (val)
us_ramp_down();
rc = mixer_ctl_set_value(ctl, 0, val);
if (rc < 0)
ALOGE("%s: Could not set ctl, error:%d ", __func__, rc);
exit:
ALOGD("%s: exit", __func__);
}
int us_init(struct audio_device *adev)
{
int rc = 0;
ALOGD("%s: enter", __func__);
if (us) {
ALOGI("%s: ultrasound has been initialized!", __func__);
return 0;
goto exit;
}
us = calloc(1, sizeof(struct ultrasound_device));
if (!us) {
ALOGE("%s: Out of memory!", __func__);
return -ENOMEM;
rc = -ENOMEM;
goto exit;
}
us->adev = adev;
us_cal_load();
ALOGD("%s: exit, status(0)", __func__);
return 0;
exit:
ALOGD("%s: exit, status(%d)", __func__, rc);
return rc;
}
void us_deinit(void)
@ -119,7 +176,7 @@ void us_deinit(void)
ALOGD("%s: exit", __func__);
}
int stop_us(void)
static int stop_us(void)
{
struct audio_usecase *rx_usecase, *tx_usecase;
int rc = 0;
@ -127,6 +184,8 @@ int stop_us(void)
ALOGD("%s: enter usecase: ultrasound", __func__);
us->state = ULTRASOUND_STATUS_STOPPED;
us_ramp_down();
if (us->rx_pcm) {
pcm_close(us->rx_pcm);
us->rx_pcm = NULL;
@ -168,13 +227,15 @@ int stop_us(void)
int us_start(void)
{
int rx_device_id, tx_device_id;
int rc = 0, 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;
if (!us || us->state == ULTRASOUND_STATUS_STARTED) {
rc = -EPERM;
goto exit;
}
ALOGD("%s: enter usecase: ultrasound", __func__);
rx_device_id = platform_get_pcm_device_id(USECASE_AUDIO_ULTRASOUND_RX, PCM_PLAYBACK);
@ -182,40 +243,45 @@ int us_start(void)
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;
rc = -EINVAL;
goto exit;
}
rx_usecase = calloc(1, sizeof(struct audio_usecase));
if (!rx_usecase) {
ALOGE("%s: Out of memory!", __func__);
return -ENOMEM;
rc = -ENOMEM;
goto exit;
}
rx_usecase->type = PCM_PLAYBACK;
rx_usecase->out_snd_device = SND_DEVICE_OUT_ULTRASOUND_HANDSET;
if (compare_device_type(&us->adev->primary_output->device_list,
AUDIO_DEVICE_OUT_SPEAKER))
rx_usecase->out_snd_device = SND_DEVICE_OUT_SPEAKER;
else
rx_usecase->out_snd_device = SND_DEVICE_OUT_VOICE_HANDSET;
rx_usecase->id = USECASE_AUDIO_ULTRASOUND_RX;
rx_usecase->stream.out = us->adev->primary_output;
list_init(&rx_usecase->device_list);
assign_devices(&rx_usecase->device_list, &us->adev->primary_output->device_list);
list_add_tail(&us->adev->usecase_list, &rx_usecase->list);
enable_snd_device(us->adev, SND_DEVICE_OUT_ULTRASOUND_HANDSET);
enable_snd_device(us->adev, rx_usecase->out_snd_device);
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;
rc = -EIO;
goto exit;
}
tx_usecase = calloc(1, sizeof(struct audio_usecase));
if (!tx_usecase) {
ALOGE("%s: Out of memory!", __func__);
return -ENOMEM;
rc = -ENOMEM;
goto exit;
}
tx_usecase->type = PCM_CAPTURE;
@ -231,40 +297,48 @@ int us_start(void)
__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;
ALOGE("%s: %s", __func__, pcm_get_error(us->tx_pcm));
rc = -EIO;
goto exit;
}
if (pcm_start(us->rx_pcm) < 0) {
ALOGE("%s: pcm start for RX failed; error = %s", __func__,
pcm_get_error(us->rx_pcm));
stop_us();
return -EINVAL;
rc = -EINVAL;
goto exit;
}
if (pcm_start(us->tx_pcm) < 0) {
ALOGE("%s: pcm start for TX failed; error = %s", __func__,
pcm_get_error(us->tx_pcm));
stop_us();
return -EINVAL;
rc = -EINVAL;
goto exit;
}
us->state = ULTRASOUND_STATUS_STARTED;
ALOGD("%s: exit, status(0)", __func__);
return 0;
exit:
ALOGD("%s: exit, status(%d)", __func__, rc);
if (rc && rc != -EPERM)
stop_us();
return rc;
}
int us_stop(void)
{
int rc = 0;
ALOGD("%s: enter", __func__);
if (!us || us->state != ULTRASOUND_STATUS_STARTED)
return -EPERM;
if (!us || us->state != ULTRASOUND_STATUS_STARTED) {
rc -EPERM;
goto exit;
}
stop_us();
return 0;
exit:
ALOGD("%s: exit, status(%d)", __func__, rc);
return rc;
}

View File

@ -23,11 +23,13 @@
#define us_deinit() (0)
#define us_start() (0)
#define us_stop() (0)
#define us_suspend() (0)
#else
int us_init(struct audio_device *adev);
void us_deinit(void);
int us_start(void);
int us_stop(void);
void us_suspend(int val);
#endif
#endif

View File

@ -1518,9 +1518,6 @@ 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;
@ -1778,10 +1775,6 @@ 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);
@ -2138,11 +2131,6 @@ static void check_usecases_codec_backend(struct audio_device *adev,
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,
@ -2159,11 +2147,34 @@ static void check_usecases_codec_backend(struct audio_device *adev,
ALOGD("%s:becf: check_usecases (%s) is active on (%s) - disabling ..",
__func__, use_case_table[usecase->id],
platform_get_snd_device_name(usecase->out_snd_device));
#ifdef ELLIPTIC_ULTRASOUND_ENABLED
if (usecase->id == USECASE_AUDIO_ULTRASOUND_RX)
us_suspend(1);
#endif
disable_audio_route(adev, usecase);
switch_device[usecase->id] = true;
/* Enable existing usecase on derived playback device */
derive_snd_device[usecase->id] = uc_derive_snd_device;
num_uc_to_switch++;
#ifdef ELLIPTIC_ULTRASOUND_ENABLED
if (usecase->id == USECASE_AUDIO_ULTRASOUND_RX) {
derive_snd_device[usecase->id] = uc_derive_snd_device;
switch (snd_device) {
case SND_DEVICE_OUT_HANDSET:
case SND_DEVICE_OUT_VOICE_HANDSET:
case SND_DEVICE_OUT_VOICE_HANDSET_TMUS:
case SND_DEVICE_OUT_VOICE_TTY_HCO_HANDSET:
case SND_DEVICE_OUT_VOICE_HAC_HANDSET:
case SND_DEVICE_OUT_ANC_HANDSET:
case SND_DEVICE_OUT_VOIP_HANDSET:
derive_snd_device[usecase->id] = snd_device;
break;
default:
derive_snd_device[usecase->id] = SND_DEVICE_OUT_SPEAKER;
break;
}
}
#endif
}
}
}
@ -2215,6 +2226,10 @@ static void check_usecases_codec_backend(struct audio_device *adev,
} else {
enable_snd_device(adev, derive_snd_device[usecase->id]);
}
#ifdef ELLIPTIC_ULTRASOUND_ENABLED
if (usecase->id == USECASE_AUDIO_ULTRASOUND_RX)
us_suspend(0);
#endif
}
}
@ -3039,6 +3054,14 @@ int select_devices(struct audio_device *adev, audio_usecase_t uc_id)
return -EINVAL;
}
#ifdef ELLIPTIC_ULTRASOUND_ENABLED
if (usecase->id == USECASE_AUDIO_ULTRASOUND_RX ||
usecase->id == USECASE_AUDIO_ULTRASOUND_TX) {
ALOGE("%s: Ultrasound usecase(%d)", __func__, uc_id);
return -EINVAL;
}
#endif
if ((usecase->type == VOICE_CALL) ||
(usecase->type == VOIP_CALL) ||
(usecase->type == PCM_HFP_CALL)||

View File

@ -613,8 +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},
[USECASE_AUDIO_ULTRASOUND_RX] = {-1, -1},
[USECASE_AUDIO_ULTRASOUND_TX] = {-1, -1},
};
/* Array to store sound devices */
@ -729,7 +729,6 @@ 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",
@ -1212,6 +1211,7 @@ static int acdb_device_table[SND_DEVICE_MAX] = {
[SND_DEVICE_IN_SYNTH_MIC] = 11,
[SND_DEVICE_IN_SPEAKER_MIC2] = 11,
[SND_DEVICE_IN_SPEAKER_MIC3] = 11,
[SND_DEVICE_IN_ULTRASOUND_MIC] = 4,
};
struct name_to_index {
@ -2138,11 +2138,7 @@ 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
#ifdef ELLIPTIC_ULTRASOUND_ENABLED
&& usecase->id != USECASE_AUDIO_ULTRASOUND_RX
#endif
) {
usecase->type == PCM_PLAYBACK) {
int new_snd_device[2] = {0};
int i, num_devices = 1;
@ -2690,7 +2686,6 @@ 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");
@ -10694,6 +10689,11 @@ static bool platform_check_codec_backend_cfg(struct audio_device* adev,
}
}
#ifdef ELLIPTIC_ULTRASOUND_ENABLED
if (!backend_idx)
sample_rate = 96000;
#endif
ALOGI("%s:becf: afe: Codec selected backend: %d updated bit width: %d and sample rate: %d",
__func__, backend_idx , bit_width, sample_rate);

View File

@ -214,7 +214,6 @@ enum {
SND_DEVICE_OUT_HAPTICS,
SND_DEVICE_OUT_ICC,
SND_DEVICE_OUT_SYNTH_SPKR,
SND_DEVICE_OUT_ULTRASOUND_HANDSET,
SND_DEVICE_OUT_END,
/*
@ -712,8 +711,6 @@ 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