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

Commit 3ccdea53 authored by Manish Dewangan's avatar Manish Dewangan
Browse files

audio: hal: Add AVD Drift Query support

- Add out set_param_data() and get_param_data() API.
- This API is needs to be used for client to set/get out stream
  specific params.
- Currently it only supports get/set of afew out params. Going forward all
  the new param needs to be supported by these APIs.
  In future key,value pair based set/get param API will be deprecated.
- Use get_param_data() API to query avtimer vs device drift support.
  Currently this API only supports drift query for HDMI device as for
  other device DSP can directly do the drift correction.

Change-Id: Iaec94b7220cdaa243d4b616fb727aae7179539d2
parent d5972fa9
Loading
Loading
Loading
Loading
+27 −1
Original line number Diff line number Diff line
@@ -138,16 +138,42 @@ struct aptx_dec_param {
   struct aptx_dec_bt_addr bt_addr;
};

struct audio_avt_device_drift_param {
   /* Flag to indicate if resync is required on the client side for
    * drift correction. Flag is set to TRUE for the first get_param response
    * after device interface starts. This flag value can be used by client
    * to identify if device interface restart has happened and if any
    * re-sync is required at their end for drift correction.
    */
    uint32_t        resync_flag;
    /* Accumulated drift value in microseconds. This value is updated
     * every 100th ms.
     * Positive drift value indicates AV timer is running faster than device.
     * Negative drift value indicates AV timer is running slower than device.
     */
    int32_t         avt_device_drift_value;
    /* Lower 32 bits of the 64-bit absolute timestamp of reference
     * timer in microseconds.
     */
    uint32_t        ref_timer_abs_ts_lsw;
    /* Upper 32 bits of the 64-bit absolute timestamp of reference
     * timer in microseconds.
     */
    uint32_t        ref_timer_abs_ts_msw;
};

typedef union {
    struct source_tracking_param st_params;
    struct sound_focus_param sf_params;
    struct aptx_dec_param aptx_params;
    struct audio_avt_device_drift_param drift_params;
} audio_extn_param_payload;

typedef enum {
    AUDIO_EXTN_PARAM_SOURCE_TRACK,
    AUDIO_EXTN_PARAM_SOUND_FOCUS,
    AUDIO_EXTN_PARAM_APTX_DEC
    AUDIO_EXTN_PARAM_APTX_DEC,
    AUDIO_EXTN_PARAM_AVT_DEVICE_DRIFT
} audio_extn_param_id;

#endif /* AUDIO_DEFS_H */
+3 −0
Original line number Diff line number Diff line
@@ -820,4 +820,7 @@ static void audio_extn_parse_aptx_dec_bt_addr(char *value);
int audio_extn_set_aptx_dec_params(struct aptx_dec_param *payload);
#endif

int audio_extn_utils_get_avt_device_drift(
                struct audio_usecase *usecase,
                struct audio_avt_device_drift_param *drift_param);
#endif /* AUDIO_EXTN_H */
+83 −0
Original line number Diff line number Diff line
@@ -155,6 +155,17 @@ const struct string_to_enum s_format_name_to_enum_table[] = {
#endif
};

/* payload structure avt_device drift query */
struct audio_avt_device_drift_stats {
    uint32_t       minor_version;
    /* Indicates the device interface direction as either
     * source (Tx) or sink (Rx).
    */
    uint16_t        device_direction;
    /*params exposed to client */
    struct audio_avt_device_drift_param drift_param;
};

static char bTable[BASE_TABLE_SIZE] = {
            'A','B','C','D','E','F','G','H','I','J','K','L',
            'M','N','O','P','Q','R','S','T','U','V','W','X',
@@ -1548,3 +1559,75 @@ void audio_utils_set_hdmi_channel_status(struct stream_out *out, char * buffer,

}
#endif

int audio_extn_utils_get_avt_device_drift(
                struct audio_usecase *usecase,
                struct audio_avt_device_drift_param *drift_param)
{
    int ret = 0, count = 0;
    char avt_device_drift_mixer_ctl_name[MIXER_PATH_MAX_LENGTH] = {0};
    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 :
                ALOGE("%s: Unsupported device %d",__func__,
                        usecase->stream.out->devices);
                ret = -EINVAL;
        }
    } else {
        ALOGE("%s: Invalid usecase %d ",__func__, usecase->type);
        ret = -EINVAL;
    }

    if(ret)
        goto done;

    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",
                __func__, avt_device_drift_mixer_ctl_name);

        ret = -EINVAL;
        goto done;
    }

    ALOGV("%s: Getting AV Timer vs Device Drift mixer ctrl name %s", __func__,
            avt_device_drift_mixer_ctl_name);

    mixer_ctl_update(ctl);
    count = mixer_ctl_get_num_values(ctl);
    if (count != sizeof(struct audio_avt_device_drift_stats)) {
        ALOGE("%s: mixer_ctl_get_num_values() invalid drift_stats data size",
                __func__);

        ret = -EINVAL;
        goto done;
    }

    ret = mixer_ctl_get_array(ctl, (void *)&drift_stats, count);
    if (ret != 0) {
        ALOGE("%s: mixer_ctl_get_array() failed to get drift_stats Params",
                __func__);

        ret = -EINVAL;
        goto done;
    }
    memcpy(drift_param, &drift_stats.drift_param,
            sizeof(struct audio_avt_device_drift_param));
done:
    return ret;
}
+55 −0
Original line number Diff line number Diff line
@@ -48,6 +48,61 @@ uint64_t timestamp;
};
#endif

static void lock_output_stream(struct stream_out *out)
{
    pthread_mutex_lock(&out->pre_lock);
    pthread_mutex_lock(&out->lock);
    pthread_mutex_unlock(&out->pre_lock);
}

/* API to send playback stream specific config parameters */
int qahwi_out_set_param_data(struct audio_stream_out *stream __unused,
                             audio_extn_param_id param_id __unused,
                             audio_extn_param_payload *payload __unused) {
    return -ENOSYS;
}

/* API to get playback stream specific config parameters */
int qahwi_out_get_param_data(struct audio_stream_out *stream,
                             audio_extn_param_id param_id,
                             audio_extn_param_payload *payload)
{
    int ret = -EINVAL;
    struct stream_out *out = (struct stream_out *)stream;
    struct audio_usecase *uc_info;

    if (!stream || !payload) {
        ALOGE("%s:: Invalid Param",__func__);
        return ret;
    }

    lock_output_stream(out);
    ALOGD("%s: enter: stream (%p) usecase(%d: %s) param_id %d", __func__,
           stream, out->usecase, use_case_table[out->usecase], param_id);

    switch (param_id) {
        case AUDIO_EXTN_PARAM_AVT_DEVICE_DRIFT:
            uc_info = get_usecase_from_list(out->dev, out->usecase);
            if (uc_info == NULL) {
                ALOGE("%s: Could not find the usecase (%d) in the list",
                       __func__, out->usecase);
                ret = -EINVAL;
            } else {
                ret = audio_extn_utils_get_avt_device_drift(uc_info,
                        (struct audio_avt_device_drift_param *)payload);
                if(ret)
                    ALOGE("%s:: avdrift query failed error %d", __func__, ret);
            }
            break;
        default:
            ALOGE("%s:: unsupported param_id %d", __func__, param_id);
            break;
    }

    pthread_mutex_unlock(&out->lock);
    return ret;
}

int qahwi_get_param_data(const struct audio_hw_device *adev,
                         audio_extn_param_id param_id,
                         audio_extn_param_payload *payload)
+10 −1
Original line number Diff line number Diff line
@@ -141,6 +141,16 @@ int qahw_out_set_parameters(qahw_stream_handle_t *stream, const char*kv_pairs);
char* qahw_out_get_parameters(const qahw_stream_handle_t *stream,
                               const char *keys);

/* API to set playback stream specific config parameters */
int qahw_out_set_param_data(qahw_stream_handle_t *out_handle,
                            qahw_param_id param_id,
                            qahw_param_payload *payload);

/* API to get playback stream specific config parameters */
int qahw_out_get_param_data(qahw_stream_handle_t *out_handle,
                            qahw_param_id param_id,
                            qahw_param_payload *payload);

/*
 * Return the audio hardware driver estimated latency in milliseconds.
 */
@@ -270,7 +280,6 @@ int qahw_open_input_stream(qahw_module_handle_t *hw_module,

int qahw_close_input_stream(qahw_stream_handle_t *in_handle);


/*
 * Return the sampling rate in Hz - eg. 44100.
 */
Loading