Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cc0a5984 authored by Alexy Joseph's avatar Alexy Joseph Committed by Gerrit - the friendly Code Review server
Browse files

hal: Add support for ULLPP for proaudio

Give option to use ULLPP for proaudio use cases.
This is achieved by sending the required mixer control
and sending the app type to the NOIRQ driver.

CRS-Fixed: 1099039
Change-Id: Iff762fb6dd56641ca83a6ec91178731f5ba779d0
parent ffa09b7e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -106,6 +106,8 @@
/* Set or Query stream profile type */
#define AUDIO_PARAMETER_STREAM_PROFILE "audio_stream_profile"

#define AUDIO_PARAMETER_KEY_VR_AUDIO_MODE "vr_audio_mode_on"

/* audio input flags for compress and timestamp mode.
 * check other input flags defined in audio.h for conflicts
 */
+19 −3
Original line number Diff line number Diff line
@@ -92,6 +92,7 @@ const struct string_to_enum s_flag_name_to_enum_table[] = {
    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DIRECT_PCM),
    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_PRIMARY),
    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_FAST),
    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_RAW),
    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DEEP_BUFFER),
    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD),
    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_NON_BLOCKING),
@@ -192,7 +193,7 @@ static audio_io_flags_t parse_flag_names(char *name)
        flag_name = strtok_r(NULL, "|", &last_r);
    }

    ALOGV("parse_flag_names: flag - %d", flag);
    ALOGV("parse_flag_names: flag - %x", flag);
    io_flags.in_flags = (audio_input_flags_t)flag;
    io_flags.out_flags = (audio_output_flags_t)flag;
    return io_flags;
@@ -676,8 +677,8 @@ void audio_extn_utils_update_stream_output_app_type_cfg(void *platform,
              __func__, sample_rate, bit_width);
    }

    ALOGV("%s: flags: %x, format: %x sample_rate %d, profile %s",
           __func__, flags, format, sample_rate, profile);
    ALOGV("%s: flags: %x, format: %x sample_rate %d, profile %s, app_type %d",
           __func__, flags, format, sample_rate, profile, app_type_cfg->app_type);
    list_for_each(node_i, streams_output_cfg_list) {
        s_info = node_to_item(node_i, struct streams_io_cfg, list);
        /* Along with flags do profile matching if set at either end.*/
@@ -725,6 +726,12 @@ static bool audio_is_this_native_usecase(struct audio_usecase *uc)
    return native_usecase;
}


static inline bool audio_is_vr_mode_on(struct audio_device *(__attribute__((unused)) adev))
{
    return adev->vr_audio_mode_enabled;
}

void audio_extn_utils_update_stream_app_type_cfg_for_usecase(
                                    struct audio_device *adev,
                                    struct audio_usecase *usecase)
@@ -789,12 +796,21 @@ static int send_app_type_cfg_for_device(struct audio_device *adev,
    if ((usecase->id != USECASE_AUDIO_PLAYBACK_DEEP_BUFFER) &&
        (usecase->id != USECASE_AUDIO_PLAYBACK_LOW_LATENCY) &&
        (usecase->id != USECASE_AUDIO_PLAYBACK_MULTI_CH) &&
        (usecase->id != USECASE_AUDIO_PLAYBACK_ULL) &&
        (!is_offload_usecase(usecase->id)) &&
        (usecase->type != PCM_CAPTURE)) {
        ALOGV("%s: a rx/tx/loopback path where app type cfg is not required %d", __func__, usecase->id);
        rc = 0;
        goto exit_send_app_type_cfg;
    }

    //if VR is active then only send the mixer control
    if (usecase->id == USECASE_AUDIO_PLAYBACK_ULL && !audio_is_vr_mode_on(adev)) {
            ALOGI("ULL doesnt need sending app type cfg, returning");
            rc = 0;
            goto exit_send_app_type_cfg;
    }

    if (usecase->type == PCM_PLAYBACK) {
        pcm_device_id = platform_get_pcm_device_id(usecase->id, PCM_PLAYBACK);
        snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
+72 −2
Original line number Diff line number Diff line
@@ -2169,6 +2169,9 @@ int start_output_stream(struct stream_out *out)
    struct audio_usecase *uc_info;
    struct audio_device *adev = out->dev;
    int snd_card_status = get_snd_card_state(adev);
    char mixer_ctl_name[128];
    struct mixer_ctl *ctl = NULL;
    char* perf_mode[] = {"ULL", "ULL_PP", "LL"};

    if ((out->usecase < 0) || (out->usecase >= AUDIO_USECASE_MAX)) {
        ret = -EINVAL;
@@ -2249,6 +2252,28 @@ int start_output_stream(struct stream_out *out)
        } else
            flags |= PCM_MONOTONIC;

        if ((adev->vr_audio_mode_enabled) &&
            (out->flags & AUDIO_OUTPUT_FLAG_RAW)) {
            snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
                    "PCM_Dev %d Topology", out->pcm_device_id);
            ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
            if (!ctl) {
                ALOGI("%s: Could not get ctl for mixer cmd might be ULL - %s",
                      __func__, mixer_ctl_name);
            } else {
                //if success use ULLPP
                ALOGI("%s: mixer ctrl %s succeeded setting up ULL for %d",
                    __func__, mixer_ctl_name, out->pcm_device_id);
                //There is a still a possibility that some sessions
                // that request for FAST|RAW when 3D audio is active
                //can go through ULLPP. Ideally we expects apps to
                //listen to audio focus and stop concurrent playback
                //Also, we will look for mode flag (voice_in_communication)
                //before enabling the realtime flag.
                mixer_ctl_set_enum_by_string(ctl, perf_mode[1]);
            }
        }

        while (1) {
            out->pcm = pcm_open(adev->snd_card, out->pcm_device_id,
                               flags, &out->config);
@@ -4245,8 +4270,8 @@ int adev_open_output_stream(struct audio_hw_device *dev,
        }
    }

    ALOGV("%s devices:%d, format:%x, out->sample_rate:%d,out->bit_width:%d out->format:%d out->flags:%x, flags:%x",
          __func__, devices, format, out->sample_rate, out->bit_width, out->format, out->flags, flags);
    ALOGV("%s devices:%d, format:%x, out->sample_rate:%d,out->bit_width:%d out->format:%d out->flags:%x, flags: %x usecase %d",
          __func__, devices, format, out->sample_rate, out->bit_width, out->format, out->flags, flags, out->usecase);

    /* TODO remove this hardcoding and check why width is zero*/
    if (out->bit_width == 0)
@@ -4277,6 +4302,7 @@ int adev_open_output_stream(struct audio_hw_device *dev,
        ret = -EEXIST;
        goto error_open;
    }

    pthread_mutex_unlock(&adev->lock);

    out->stream.common.get_sample_rate = out_get_sample_rate;
@@ -4564,6 +4590,23 @@ static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
            }
        }
    }

    //handle vr audio setparam
    ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_VR_AUDIO_MODE,
        value, sizeof(value));
    if (ret >= 0) {
        ALOGI("Setting vr mode to be %s", value);
        if (!strncmp(value, "true", 4)) {
            adev->vr_audio_mode_enabled = true;
            ALOGI("Setting vr mode to true");
        } else if (!strncmp(value, "false", 5)) {
            adev->vr_audio_mode_enabled = false;
            ALOGI("Setting vr mode to false");
        } else {
            ALOGI("wrong vr mode set");
        }
    }

    audio_extn_set_parameters(adev, parms);
done:
    str_parms_destroy(parms);
@@ -4605,6 +4648,30 @@ static char* adev_get_parameters(const struct audio_hw_device *dev,
        str_parms_add_int(reply, "SND_CARD_STATUS", val);
        goto exit;
    }
    //handle vr audio getparam

    ret = str_parms_get_str(query,
        AUDIO_PARAMETER_KEY_VR_AUDIO_MODE,
        value, sizeof(value));

    if (ret >= 0) {
        bool vr_audio_enabled = false;
        pthread_mutex_lock(&adev->lock);
        vr_audio_enabled = adev->vr_audio_mode_enabled;
        pthread_mutex_unlock(&adev->lock);

        ALOGI("getting vr mode to %d", vr_audio_enabled);

        if (vr_audio_enabled) {
            str_parms_add_str(reply, AUDIO_PARAMETER_KEY_VR_AUDIO_MODE,
                "true");
            goto exit;
        } else {
            str_parms_add_str(reply, AUDIO_PARAMETER_KEY_VR_AUDIO_MODE,
                "false");
            goto exit;
        }
    }

    pthread_mutex_lock(&adev->lock);
    audio_extn_get_parameters(adev, query, reply);
@@ -5193,6 +5260,9 @@ static int adev_open(const hw_module_t *module, const char *name,
    }

    adev->bt_wb_speech_enabled = false;
    //initialize this to false for now,
    //this will be set to true through set param
    adev->vr_audio_mode_enabled = false;

    audio_extn_ds2_enable(adev);
    *device = &adev->device.common;
+1 −0
Original line number Diff line number Diff line
@@ -428,6 +428,7 @@ struct audio_device {
    bool native_playback_enabled;
    bool asrc_mode_enabled;
    qahwi_device_t qahwi_dev;
    bool vr_audio_mode_enabled;
};

int select_devices(struct audio_device *adev,