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

Commit 6160c712 authored by Naresh Tanniru's avatar Naresh Tanniru Committed by Satya Krishna Pindiproli
Browse files

audio: hal: add DSP clock recovery support

-Changes to add DSP clock recovery support

Conflicts:
        qahw_api/test/qahw_playback_test.c
	    hal/audio_extn/utils.c

CRs-Fixed: 2036937
Change-Id: I32e18e415c4a7dfdc7ae13d0e50c1ca76d739cc0
parent b183432a
Loading
Loading
Loading
Loading
+20 −1
Original line number Diff line number Diff line
@@ -177,6 +177,19 @@ struct audio_out_start_delay_param {
   uint64_t        start_delay; /* session start delay in microseconds*/
};

struct audio_out_enable_drift_correction {
   bool        enable; /* enable drift correction*/
};

struct audio_out_correct_drift {
    /*
     * adjust time in microseconds, a positive value
     * to advance the clock or a negative value to
     * delay the clock.
     */
    int64_t        adjust_time;
};

/* type of asynchronous write callback events. Mutually exclusive
 * event enums append those defined for stream_callback_event_t in audio.h */
typedef enum {
@@ -203,6 +216,8 @@ typedef union {
    struct audio_avt_device_drift_param drift_params;
    struct audio_out_render_window_param render_window_param;
    struct audio_out_start_delay_param start_delay;
    struct audio_out_enable_drift_correction drift_enable_param;
    struct audio_out_correct_drift drift_correction_param;
    struct audio_adsp_event adsp_event_params;
} audio_extn_param_payload;

@@ -213,6 +228,10 @@ typedef enum {
    AUDIO_EXTN_PARAM_AVT_DEVICE_DRIFT,
    AUDIO_EXTN_PARAM_OUT_RENDER_WINDOW, /* PARAM to set render window */
    AUDIO_EXTN_PARAM_OUT_START_DELAY,
    /* enable adsp drift correction this must be called before out_write */
    AUDIO_EXTN_PARAM_OUT_ENABLE_DRIFT_CORRECTION,
    /* param to set drift value to be adjusted by dsp */
    AUDIO_EXTN_PARAM_OUT_CORRECT_DRIFT,
    AUDIO_EXTN_PARAM_ADSP_STREAM_CMD
} audio_extn_param_id;

+9 −1
Original line number Diff line number Diff line
@@ -1367,6 +1367,14 @@ int audio_extn_out_set_param_data(struct stream_out *out,
            ret = audio_extn_utils_compress_set_start_delay(out,
                    (struct audio_out_start_delay_param *)(payload));
            break;
        case AUDIO_EXTN_PARAM_OUT_ENABLE_DRIFT_CORRECTION:
            ret = audio_extn_utils_compress_enable_drift_correction(out,
                    (struct audio_out_enable_drift_correction *)(payload));
            break;
        case AUDIO_EXTN_PARAM_OUT_CORRECT_DRIFT:
            ret = audio_extn_utils_compress_correct_drift(out,
                    (struct audio_out_correct_drift *)(payload));
            break;
        case AUDIO_EXTN_PARAM_ADSP_STREAM_CMD:
            ret = audio_extn_adsp_hdlr_stream_set_param(out->adsp_hdlr_stream_handle,
                    ADSP_HDLR_STREAM_CMD_REGISTER_EVENT,
+6 −0
Original line number Diff line number Diff line
@@ -864,4 +864,10 @@ int audio_extn_utils_compress_set_render_window(
int audio_extn_utils_compress_set_start_delay(
            struct stream_out *out,
            struct audio_out_start_delay_param *start_delay_param);
int audio_extn_utils_compress_enable_drift_correction(
            struct stream_out *out,
            struct audio_out_enable_drift_correction *drift_enable);
int audio_extn_utils_compress_correct_drift(
            struct stream_out *out,
            struct audio_out_correct_drift *drift_correction_param);
#endif /* AUDIO_EXTN_H */
+127 −29
Original line number Diff line number Diff line
@@ -1609,36 +1609,39 @@ int audio_extn_utils_get_avt_device_drift(
{
    int ret = 0, count = 0;
    char avt_device_drift_mixer_ctl_name[MIXER_PATH_MAX_LENGTH] = {0};
    const char *backend = NULL;
    struct mixer_ctl *ctl = NULL;
    struct audio_avt_device_drift_stats drift_stats;
    struct audio_device *adev = NULL;

    if (usecase != NULL && usecase->type == PCM_PLAYBACK) {
        adev = usecase->stream.out->dev;
        switch(usecase->out_snd_device) {
            case SND_DEVICE_OUT_HDMI:
                strlcpy(avt_device_drift_mixer_ctl_name,
                        "HDMI RX Drift",
                        MIXER_PATH_MAX_LENGTH);
                break;
            case SND_DEVICE_OUT_DISPLAY_PORT:
                strlcpy(avt_device_drift_mixer_ctl_name,
                        "DISPLAY Port RX Drift",
                        MIXER_PATH_MAX_LENGTH);
                break;
            default :
        backend = platform_get_snd_device_backend_interface(usecase->out_snd_device);
        if (!backend) {
            ALOGE("%s: Unsupported device %d", __func__,
                   usecase->stream.out->devices);
            ret = -EINVAL;
            goto done;
        }
        strlcpy(avt_device_drift_mixer_ctl_name,
                backend,
                MIXER_PATH_MAX_LENGTH);

        count = strlen(backend);
        if (MIXER_PATH_MAX_LENGTH - count > 0) {
            strlcat(&avt_device_drift_mixer_ctl_name[count],
                    " DRIFT",
                    MIXER_PATH_MAX_LENGTH - count);
        } else {
        ALOGE("%s: Invalid usecase",__func__);
            ret = -EINVAL;
            goto done;
        }

    if(ret)
    } else {
        ALOGE("%s: Invalid usecase",__func__);
        ret = -EINVAL;
        goto done;
    }

    adev = usecase->stream.out->dev;
    ctl = mixer_get_ctl_by_name(adev->mixer, avt_device_drift_mixer_ctl_name);
    if (!ctl) {
        ALOGE("%s: Could not get ctl for mixer cmd - %s",
@@ -1849,11 +1852,8 @@ int audio_extn_utils_compress_set_render_window(
        goto exit;
    }

    if ((out->render_mode == RENDER_MODE_AUDIO_MASTER) ||
        (out->render_mode == RENDER_MODE_AUDIO_STC_MASTER)) {
        memcpy(&out->render_window, render_window,
               sizeof(struct audio_out_render_window_param));
    } else {
    if ((out->render_mode != RENDER_MODE_AUDIO_MASTER) &&
        (out->render_mode != RENDER_MODE_AUDIO_STC_MASTER)) {
        ALOGD("%s:: only supported in timestamp mode, current "
              "render mode mode %d", __func__, out->render_mode);
        goto exit;
@@ -1915,11 +1915,8 @@ int audio_extn_utils_compress_set_start_delay(
        goto exit;
    }

   if ((out->render_mode == RENDER_MODE_AUDIO_MASTER) ||
       (out->render_mode == RENDER_MODE_AUDIO_STC_MASTER)) {
        /* store it to reconfigure in start_output_stream() */
        out->delay_param.start_delay = delay_param->start_delay;
    } else {
   if ((out->render_mode != RENDER_MODE_AUDIO_MASTER) &&
       (out->render_mode != RENDER_MODE_AUDIO_STC_MASTER)) {
        ALOGD("%s:: only supported in timestamp mode, current "
              "render mode mode %d", __func__, out->render_mode);
        goto exit;
@@ -2016,3 +2013,104 @@ int audio_extn_utils_get_snd_card_num()

    return snd_card_num;
}

#ifdef SNDRV_COMPRESS_ENABLE_ADJUST_SESSION_CLOCK
int audio_extn_utils_compress_enable_drift_correction(
        struct stream_out *out,
        struct audio_out_enable_drift_correction *drift)
{
    struct snd_compr_metadata metadata;
    int ret = -EINVAL;

    if(drift == NULL) {
        ALOGE("%s:: Invalid param", __func__);
        goto exit;
    }

    ALOGD("%s:: drift enable %d", __func__,drift->enable);

    if (!is_offload_usecase(out->usecase)) {
        ALOGE("%s:: not supported for non offload session", __func__);
        goto exit;
    }

    if (!out->compr) {
        ALOGW("%s:: offload session not yet opened,"
                "start delay will be configure later", __func__);
        goto exit;
    }

    metadata.key = SNDRV_COMPRESS_ENABLE_ADJUST_SESSION_CLOCK;
    metadata.value[0] = drift->enable;
    out->drift_correction_enabled = drift->enable;

    ret = compress_set_metadata(out->compr, &metadata);
    if(ret) {
        ALOGE("%s::error %s", __func__, compress_get_error(out->compr));
        out->drift_correction_enabled = false;
    }

exit:
    return ret;
}
#else
int audio_extn_utils_compress_enable_drift_correction(
        struct stream_out *out __unused,
        struct audio_out_enable_drift_correction *drift __unused)
{
    ALOGD("%s:: configuring drift enablement not supported", __func__);
    return 0;
}
#endif

#ifdef SNDRV_COMPRESS_ADJUST_SESSION_CLOCK
int audio_extn_utils_compress_correct_drift(
        struct stream_out *out,
        struct audio_out_correct_drift *drift_param)
{
    struct snd_compr_metadata metadata;
    int ret = -EINVAL;

    if (drift_param == NULL) {
        ALOGE("%s:: Invalid drift_param", __func__);
        goto exit;
    }

    ALOGD("%s:: adjust time 0x%"PRIx64" ", __func__,
            drift_param->adjust_time);

    if (!is_offload_usecase(out->usecase)) {
        ALOGE("%s:: not supported for non offload session", __func__);
        goto exit;
    }

    if (!out->compr) {
        ALOGW("%s:: offload session not yet opened", __func__);
        goto exit;
    }

    if (!out->drift_correction_enabled) {
        ALOGE("%s:: drift correction not enabled", __func__);
        goto exit;
    }

    metadata.key = SNDRV_COMPRESS_ADJUST_SESSION_CLOCK;
    metadata.value[0] = 0xFFFFFFFF & drift_param->adjust_time; /* lsb */
    metadata.value[1] = \
             (0xFFFFFFFF00000000 & drift_param->adjust_time) >> 32; /* msb*/

    ret = compress_set_metadata(out->compr, &metadata);
    if(ret)
        ALOGE("%s::error %s", __func__, compress_get_error(out->compr));
exit:
    return ret;
}
#else
int audio_extn_utils_compress_correct_drift(
        struct stream_out *out __unused,
        struct audio_out_correct_drift *drift_param __unused)
{
    ALOGD("%s:: setting adjust clock not supported", __func__);
    return 0;
}
#endif
+0 −11
Original line number Diff line number Diff line
@@ -2208,9 +2208,6 @@ static int stop_output_stream(struct stream_out *out)
    if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)
        audio_extn_keep_alive_start();

    /*reset delay_param to 0*/
    out->delay_param.start_delay = 0;

    ALOGV("%s: exit: status(%d)", __func__, ret);
    return ret;
}
@@ -2390,11 +2387,6 @@ int start_output_stream(struct stream_out *out)

        audio_extn_utils_compress_set_render_mode(out);
        audio_extn_utils_compress_set_clk_rec_mode(uc_info);
        /* set render window if it was set before compress_open() */
        if (out->render_window.render_ws != 0 && out->render_window.render_we != 0)
            audio_extn_utils_compress_set_render_window(out,
                                            &out->render_window);
        audio_extn_utils_compress_set_start_delay(out, &out->delay_param);

        audio_extn_dts_create_state_notifier_node(out->usecase);
        audio_extn_dts_notify_playback_state(out->usecase, 0, out->sample_rate,
@@ -4197,9 +4189,6 @@ int adev_open_output_stream(struct audio_hw_device *dev,
            out->render_mode = RENDER_MODE_AUDIO_NO_TIMESTAMP;
        }

        memset(&out->render_window, 0,
                sizeof(struct audio_out_render_window_param));

        out->send_new_metadata = 1;
        out->send_next_track_params = false;
        out->is_compr_metadata_avail = false;
Loading