Loading asoc/msm-compress-q6-v2.c +47 −9 Original line number Diff line number Diff line Loading @@ -3170,13 +3170,18 @@ static int msm_compr_get_metadata(struct snd_compr_stream *cstream, struct msm_compr_audio *prtd; struct audio_client *ac; int ret = -EINVAL; uint64_t ses_time = 0, frames = 0, abs_time = 0; uint64_t *val = NULL; int64_t av_offset = 0; int32_t clock_id = -EINVAL; pr_debug("%s\n", __func__); if (!metadata || !cstream || !cstream->runtime) return ret; if (metadata->key != SNDRV_COMPRESS_PATH_DELAY) { if (metadata->key != SNDRV_COMPRESS_PATH_DELAY && metadata->key != SNDRV_COMPRESS_DSP_POSITION) { pr_err("%s, unsupported key %d\n", __func__, metadata->key); return ret; } Loading @@ -3187,17 +3192,50 @@ static int msm_compr_get_metadata(struct snd_compr_stream *cstream, return ret; } switch (metadata->key) { case SNDRV_COMPRESS_PATH_DELAY: ac = prtd->audio_client; ret = q6asm_get_path_delay(prtd->audio_client); if (ret) { pr_err("%s: get_path_delay failed, ret=%d\n", __func__, ret); pr_err("%s: get_path_delay failed, ret=%d\n", __func__, ret); return ret; } pr_debug("%s, path delay(in us) %u\n", __func__, ac->path_delay); pr_debug("%s, path delay(in us) %u\n", __func__, ac->path_delay); metadata->value[0] = ac->path_delay; break; case SNDRV_COMPRESS_DSP_POSITION: clock_id = metadata->value[0]; pr_debug("%s, clock_id %d\n", __func__, clock_id); ret = q6asm_get_session_time_v2(prtd->audio_client, &ses_time, &abs_time); if (ret) { pr_err("%s: q6asm_get_session_time_v2 failed, ret=%d\n", __func__, ret); return ret; } frames = div64_u64((ses_time * prtd->sample_rate), 1000000); ret = avcs_core_query_timer_offset(&av_offset, clock_id); if (ret) { pr_err("%s: avcs query failed, ret=%d\n", __func__, ret); return ret; } val = (uint64_t *) &metadata->value[1]; val[0] = frames; val[1] = abs_time + av_offset; pr_debug("%s, vals frames %lld, time %lld, avoff %lld, abst %lld, sess_time %llu sr %d\n", __func__, val[0], val[1], av_offset, abs_time, ses_time, prtd->sample_rate); break; default: pr_err("%s, unsupported key %d\n", __func__, metadata->key); break; } return ret; } Loading asoc/msm-pcm-q6-v2.c +96 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <linux/of_device.h> #include <sound/tlv.h> #include <sound/pcm_params.h> #include <sound/devdep_params.h> #include <dsp/msm_audio_ion.h> #include <dsp/q6audio-v2.h> #include <dsp/q6core.h> Loading Loading @@ -1156,12 +1157,106 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream, return 0; } static int msm_pcm_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void __user *arg) { struct msm_audio *prtd = NULL; struct snd_soc_pcm_runtime *rtd = NULL; uint64_t ses_time = 0, abs_time = 0; int64_t av_offset = 0; int32_t clock_id = -EINVAL; int rc = 0; struct snd_pcm_prsnt_position userarg; if (!substream || !substream->private_data) { pr_err("%s: Invalid %s\n", __func__, (!substream) ? "substream" : "private_data"); return -EINVAL; } if (!substream->runtime) { pr_err("%s substream runtime not found\n", __func__); return -EINVAL; } prtd = substream->runtime->private_data; if (!prtd) { pr_err("%s prtd is null.\n", __func__); return -EINVAL; } rtd = substream->private_data; switch (cmd) { case SNDRV_PCM_IOCTL_DSP_POSITION: dev_dbg(rtd->dev, "%s: SNDRV_PCM_DSP_POSITION", __func__); if (!arg) { dev_err(rtd->dev, "%s: Invalid params DSP_POSITION\n", __func__); rc = -EINVAL; goto done; } memset(&userarg, 0, sizeof(userarg)); if (copy_from_user(&userarg, arg, sizeof(userarg))) { dev_err(rtd->dev, "%s: err copyuser DSP_POSITION\n", __func__); rc = -EFAULT; goto done; } clock_id = userarg.clock_id; rc = q6asm_get_session_time_v2(prtd->audio_client, &ses_time, &abs_time); if (rc) { pr_err("%s: q6asm_get_session_time_v2 failed, rc=%d\n", __func__, rc); goto done; } userarg.frames = div64_u64((ses_time * prtd->samp_rate), 1000000); rc = avcs_core_query_timer_offset(&av_offset, clock_id); if (rc) { pr_err("%s: avcs offset query failed, rc=%d\n", __func__, rc); goto done; } userarg.timestamp = abs_time + av_offset; if (copy_to_user(arg, &userarg, sizeof(userarg))) { dev_err(rtd->dev, "%s: err copy to user DSP_POSITION\n", __func__); rc = -EFAULT; goto done; } pr_debug("%s, vals f %lld, t %lld, avoff %lld, abst %lld, sess_time %llu sr %d\n", __func__, userarg.frames, userarg.timestamp, av_offset, abs_time, ses_time, prtd->samp_rate); break; default: rc = snd_pcm_lib_ioctl(substream, cmd, arg); break; } done: return rc; } #ifdef CONFIG_COMPAT static int msm_pcm_compat_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void __user *arg) { return msm_pcm_ioctl(substream, cmd, arg); } #else #define msm_pcm_compat_ioctl NULL #endif static const struct snd_pcm_ops msm_pcm_ops = { .open = msm_pcm_open, .copy_user = msm_pcm_copy, .hw_params = msm_pcm_hw_params, .close = msm_pcm_close, .ioctl = snd_pcm_lib_ioctl, .ioctl = msm_pcm_ioctl, .compat_ioctl = msm_pcm_compat_ioctl, .prepare = msm_pcm_prepare, .trigger = msm_pcm_trigger, .pointer = msm_pcm_pointer, Loading dsp/avtimer.c +55 −0 Original line number Diff line number Diff line Loading @@ -309,6 +309,61 @@ int avcs_core_query_timer(uint64_t *avtimer_tick) } EXPORT_SYMBOL(avcs_core_query_timer); /* * avcs_core_query_timer_offset: * derive offset between system clock & avtimer clock * * @ avoffset: offset between system clock & avtimer clock * @ clock_id: clock id to get the system time * */ int avcs_core_query_timer_offset(int64_t *av_offset, int32_t clock_id) { uint32_t avtimer_msw = 0, avtimer_lsw = 0; uint64_t avtimer_tick_temp, avtimer_tick, sys_time = 0; struct timespec ts; if ((avtimer.p_avtimer_lsw == NULL) || (avtimer.p_avtimer_msw == NULL)) { return -EINVAL; } memset(&ts, 0, sizeof(struct timespec)); avtimer_lsw = ioread32(avtimer.p_avtimer_lsw); avtimer_msw = ioread32(avtimer.p_avtimer_msw); switch (clock_id) { case CLOCK_MONOTONIC_RAW: getrawmonotonic(&ts); break; case CLOCK_BOOTTIME: get_monotonic_boottime(&ts); break; case CLOCK_MONOTONIC: ktime_get_ts(&ts); break; case CLOCK_REALTIME: ktime_get_real_ts(&ts); break; default: pr_debug("%s: unsupported clock id %d\n", __func__, clock_id); return -EINVAL; } sys_time = ts.tv_sec * 1000000LL + div64_u64(ts.tv_nsec, 1000); avtimer_tick_temp = (uint64_t)((uint64_t)avtimer_msw << 32) | avtimer_lsw; avtimer_tick = mul_u64_u32_div(avtimer_tick_temp, avtimer.clk_mult, avtimer.clk_div); *av_offset = sys_time - avtimer_tick; pr_debug("%s: sys_time: %llu, offset %lld, avtimer tick %lld\n", __func__, sys_time, *av_offset, avtimer_tick); return 0; } EXPORT_SYMBOL(avcs_core_query_timer_offset); #if IS_ENABLED(CONFIG_AVTIMER_LEGACY) static void avcs_set_isp_fptr(bool enable) { Loading dsp/q6asm.c +40 −12 Original line number Diff line number Diff line Loading @@ -1868,12 +1868,20 @@ static void q6asm_process_mtmx_get_param_rsp(struct audio_client *ac, switch (cmdrsp->param_info.param_id) { case ASM_SESSION_MTMX_STRTR_PARAM_SESSION_TIME_V3: time = &cmdrsp->param_data.session_time; dev_vdbg(ac->dev, "%s: GET_TIME_V3, time_lsw=%x, time_msw=%x\n", dev_vdbg(ac->dev, "%s: GET_TIME_V3, time_lsw=%x, time_msw=%x, abs l %x, m %x\n", __func__, time->session_time_lsw, time->session_time_msw); ac->time_stamp = (uint64_t)(((uint64_t) time->session_time_msw, time->absolute_time_lsw, time->absolute_time_msw); ac->dsp_ts.abs_time_stamp = (uint64_t)(((uint64_t) time->absolute_time_msw << 32) | time->absolute_time_lsw); ac->dsp_ts.time_stamp = (uint64_t)(((uint64_t) time->session_time_msw << 32) | time->session_time_lsw); ac->dsp_ts.last_time_stamp = (uint64_t)(((uint64_t) time->time_stamp_msw << 32) | time->time_stamp_lsw); if (time->flags & ASM_SESSION_MTMX_STRTR_PARAM_STIME_TSTMP_FLG_BMASK) dev_warn_ratelimited(ac->dev, Loading Loading @@ -2361,7 +2369,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) dev_vdbg(ac->dev, "%s: ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3, payload[0] = %d, payload[1] = %d, payload[2] = %d\n", __func__, payload[0], payload[1], payload[2]); ac->time_stamp = (uint64_t)(((uint64_t)payload[2] << 32) | ac->dsp_ts.time_stamp = (uint64_t)(((uint64_t)payload[2] << 32) | payload[1]); } else { dev_err(ac->dev, "%s: payload size of %x is less than expected.n", Loading Loading @@ -9762,15 +9771,17 @@ int q6asm_write_nolock(struct audio_client *ac, uint32_t len, uint32_t msw_ts, EXPORT_SYMBOL(q6asm_write_nolock); /** * q6asm_get_session_time - * q6asm_get_session_time_v2 - * command to retrieve timestamp info * * @ac: Audio client handle * @tstamp: pointer to fill with timestamp info * @ses_time: pointer to fill with session timestamp info * @abs_time: pointer to fill with AVS timestamp info * * Returns 0 on success or error on failure */ int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp) int q6asm_get_session_time_v2(struct audio_client *ac, uint64_t *ses_time, uint64_t *abs_time) { struct asm_mtmx_strtr_get_params mtmx_params; int rc; Loading @@ -9783,8 +9794,8 @@ int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp) pr_err("%s: AC APR handle NULL\n", __func__); return -EINVAL; } if (tstamp == NULL) { pr_err("%s: tstamp NULL\n", __func__); if (ses_time == NULL) { pr_err("%s: tstamp args are NULL\n", __func__); return -EINVAL; } Loading Loading @@ -9822,12 +9833,29 @@ int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp) goto fail_cmd; } *tstamp = ac->time_stamp; *ses_time = ac->dsp_ts.time_stamp; if (abs_time != NULL) *abs_time = ac->dsp_ts.abs_time_stamp; return 0; fail_cmd: return -EINVAL; } EXPORT_SYMBOL(q6asm_get_session_time_v2); /** * q6asm_get_session_time - * command to retrieve timestamp info * * @ac: Audio client handle * @tstamp: pointer to fill with timestamp info * * Returns 0 on success or error on failure */ int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp) { return q6asm_get_session_time_v2(ac, tstamp, NULL); } EXPORT_SYMBOL(q6asm_get_session_time); /** Loading Loading @@ -9879,7 +9907,7 @@ int q6asm_get_session_time_legacy(struct audio_client *ac, uint64_t *tstamp) goto fail_cmd; } *tstamp = ac->time_stamp; *tstamp = ac->dsp_ts.time_stamp; return 0; fail_cmd: Loading include/dsp/q6asm-v2.h +9 −2 Original line number Diff line number Diff line Loading @@ -207,6 +207,12 @@ struct shared_io_config { uint32_t bufcnt; }; struct dsp_timestamp { uint64_t time_stamp; uint64_t abs_time_stamp; uint64_t last_time_stamp; }; struct audio_client { int session; app_cb cb; Loading @@ -218,7 +224,7 @@ struct audio_client { atomic_t mem_state; void *priv; uint32_t io_mode; uint64_t time_stamp; struct dsp_timestamp dsp_ts; struct apr_svc *apr; struct apr_svc *mmap_apr; struct apr_svc *apr2; Loading Loading @@ -683,7 +689,8 @@ int q6asm_set_multich_gain(struct audio_client *ac, uint32_t channels, int q6asm_set_mute(struct audio_client *ac, int muteflag); int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp); int q6asm_get_session_time_v2(struct audio_client *ac, uint64_t *ses_time, uint64_t *abs_time); int q6asm_get_session_time_legacy(struct audio_client *ac, uint64_t *tstamp); int q6asm_send_stream_cmd(struct audio_client *ac, Loading Loading
asoc/msm-compress-q6-v2.c +47 −9 Original line number Diff line number Diff line Loading @@ -3170,13 +3170,18 @@ static int msm_compr_get_metadata(struct snd_compr_stream *cstream, struct msm_compr_audio *prtd; struct audio_client *ac; int ret = -EINVAL; uint64_t ses_time = 0, frames = 0, abs_time = 0; uint64_t *val = NULL; int64_t av_offset = 0; int32_t clock_id = -EINVAL; pr_debug("%s\n", __func__); if (!metadata || !cstream || !cstream->runtime) return ret; if (metadata->key != SNDRV_COMPRESS_PATH_DELAY) { if (metadata->key != SNDRV_COMPRESS_PATH_DELAY && metadata->key != SNDRV_COMPRESS_DSP_POSITION) { pr_err("%s, unsupported key %d\n", __func__, metadata->key); return ret; } Loading @@ -3187,17 +3192,50 @@ static int msm_compr_get_metadata(struct snd_compr_stream *cstream, return ret; } switch (metadata->key) { case SNDRV_COMPRESS_PATH_DELAY: ac = prtd->audio_client; ret = q6asm_get_path_delay(prtd->audio_client); if (ret) { pr_err("%s: get_path_delay failed, ret=%d\n", __func__, ret); pr_err("%s: get_path_delay failed, ret=%d\n", __func__, ret); return ret; } pr_debug("%s, path delay(in us) %u\n", __func__, ac->path_delay); pr_debug("%s, path delay(in us) %u\n", __func__, ac->path_delay); metadata->value[0] = ac->path_delay; break; case SNDRV_COMPRESS_DSP_POSITION: clock_id = metadata->value[0]; pr_debug("%s, clock_id %d\n", __func__, clock_id); ret = q6asm_get_session_time_v2(prtd->audio_client, &ses_time, &abs_time); if (ret) { pr_err("%s: q6asm_get_session_time_v2 failed, ret=%d\n", __func__, ret); return ret; } frames = div64_u64((ses_time * prtd->sample_rate), 1000000); ret = avcs_core_query_timer_offset(&av_offset, clock_id); if (ret) { pr_err("%s: avcs query failed, ret=%d\n", __func__, ret); return ret; } val = (uint64_t *) &metadata->value[1]; val[0] = frames; val[1] = abs_time + av_offset; pr_debug("%s, vals frames %lld, time %lld, avoff %lld, abst %lld, sess_time %llu sr %d\n", __func__, val[0], val[1], av_offset, abs_time, ses_time, prtd->sample_rate); break; default: pr_err("%s, unsupported key %d\n", __func__, metadata->key); break; } return ret; } Loading
asoc/msm-pcm-q6-v2.c +96 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <linux/of_device.h> #include <sound/tlv.h> #include <sound/pcm_params.h> #include <sound/devdep_params.h> #include <dsp/msm_audio_ion.h> #include <dsp/q6audio-v2.h> #include <dsp/q6core.h> Loading Loading @@ -1156,12 +1157,106 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream, return 0; } static int msm_pcm_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void __user *arg) { struct msm_audio *prtd = NULL; struct snd_soc_pcm_runtime *rtd = NULL; uint64_t ses_time = 0, abs_time = 0; int64_t av_offset = 0; int32_t clock_id = -EINVAL; int rc = 0; struct snd_pcm_prsnt_position userarg; if (!substream || !substream->private_data) { pr_err("%s: Invalid %s\n", __func__, (!substream) ? "substream" : "private_data"); return -EINVAL; } if (!substream->runtime) { pr_err("%s substream runtime not found\n", __func__); return -EINVAL; } prtd = substream->runtime->private_data; if (!prtd) { pr_err("%s prtd is null.\n", __func__); return -EINVAL; } rtd = substream->private_data; switch (cmd) { case SNDRV_PCM_IOCTL_DSP_POSITION: dev_dbg(rtd->dev, "%s: SNDRV_PCM_DSP_POSITION", __func__); if (!arg) { dev_err(rtd->dev, "%s: Invalid params DSP_POSITION\n", __func__); rc = -EINVAL; goto done; } memset(&userarg, 0, sizeof(userarg)); if (copy_from_user(&userarg, arg, sizeof(userarg))) { dev_err(rtd->dev, "%s: err copyuser DSP_POSITION\n", __func__); rc = -EFAULT; goto done; } clock_id = userarg.clock_id; rc = q6asm_get_session_time_v2(prtd->audio_client, &ses_time, &abs_time); if (rc) { pr_err("%s: q6asm_get_session_time_v2 failed, rc=%d\n", __func__, rc); goto done; } userarg.frames = div64_u64((ses_time * prtd->samp_rate), 1000000); rc = avcs_core_query_timer_offset(&av_offset, clock_id); if (rc) { pr_err("%s: avcs offset query failed, rc=%d\n", __func__, rc); goto done; } userarg.timestamp = abs_time + av_offset; if (copy_to_user(arg, &userarg, sizeof(userarg))) { dev_err(rtd->dev, "%s: err copy to user DSP_POSITION\n", __func__); rc = -EFAULT; goto done; } pr_debug("%s, vals f %lld, t %lld, avoff %lld, abst %lld, sess_time %llu sr %d\n", __func__, userarg.frames, userarg.timestamp, av_offset, abs_time, ses_time, prtd->samp_rate); break; default: rc = snd_pcm_lib_ioctl(substream, cmd, arg); break; } done: return rc; } #ifdef CONFIG_COMPAT static int msm_pcm_compat_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void __user *arg) { return msm_pcm_ioctl(substream, cmd, arg); } #else #define msm_pcm_compat_ioctl NULL #endif static const struct snd_pcm_ops msm_pcm_ops = { .open = msm_pcm_open, .copy_user = msm_pcm_copy, .hw_params = msm_pcm_hw_params, .close = msm_pcm_close, .ioctl = snd_pcm_lib_ioctl, .ioctl = msm_pcm_ioctl, .compat_ioctl = msm_pcm_compat_ioctl, .prepare = msm_pcm_prepare, .trigger = msm_pcm_trigger, .pointer = msm_pcm_pointer, Loading
dsp/avtimer.c +55 −0 Original line number Diff line number Diff line Loading @@ -309,6 +309,61 @@ int avcs_core_query_timer(uint64_t *avtimer_tick) } EXPORT_SYMBOL(avcs_core_query_timer); /* * avcs_core_query_timer_offset: * derive offset between system clock & avtimer clock * * @ avoffset: offset between system clock & avtimer clock * @ clock_id: clock id to get the system time * */ int avcs_core_query_timer_offset(int64_t *av_offset, int32_t clock_id) { uint32_t avtimer_msw = 0, avtimer_lsw = 0; uint64_t avtimer_tick_temp, avtimer_tick, sys_time = 0; struct timespec ts; if ((avtimer.p_avtimer_lsw == NULL) || (avtimer.p_avtimer_msw == NULL)) { return -EINVAL; } memset(&ts, 0, sizeof(struct timespec)); avtimer_lsw = ioread32(avtimer.p_avtimer_lsw); avtimer_msw = ioread32(avtimer.p_avtimer_msw); switch (clock_id) { case CLOCK_MONOTONIC_RAW: getrawmonotonic(&ts); break; case CLOCK_BOOTTIME: get_monotonic_boottime(&ts); break; case CLOCK_MONOTONIC: ktime_get_ts(&ts); break; case CLOCK_REALTIME: ktime_get_real_ts(&ts); break; default: pr_debug("%s: unsupported clock id %d\n", __func__, clock_id); return -EINVAL; } sys_time = ts.tv_sec * 1000000LL + div64_u64(ts.tv_nsec, 1000); avtimer_tick_temp = (uint64_t)((uint64_t)avtimer_msw << 32) | avtimer_lsw; avtimer_tick = mul_u64_u32_div(avtimer_tick_temp, avtimer.clk_mult, avtimer.clk_div); *av_offset = sys_time - avtimer_tick; pr_debug("%s: sys_time: %llu, offset %lld, avtimer tick %lld\n", __func__, sys_time, *av_offset, avtimer_tick); return 0; } EXPORT_SYMBOL(avcs_core_query_timer_offset); #if IS_ENABLED(CONFIG_AVTIMER_LEGACY) static void avcs_set_isp_fptr(bool enable) { Loading
dsp/q6asm.c +40 −12 Original line number Diff line number Diff line Loading @@ -1868,12 +1868,20 @@ static void q6asm_process_mtmx_get_param_rsp(struct audio_client *ac, switch (cmdrsp->param_info.param_id) { case ASM_SESSION_MTMX_STRTR_PARAM_SESSION_TIME_V3: time = &cmdrsp->param_data.session_time; dev_vdbg(ac->dev, "%s: GET_TIME_V3, time_lsw=%x, time_msw=%x\n", dev_vdbg(ac->dev, "%s: GET_TIME_V3, time_lsw=%x, time_msw=%x, abs l %x, m %x\n", __func__, time->session_time_lsw, time->session_time_msw); ac->time_stamp = (uint64_t)(((uint64_t) time->session_time_msw, time->absolute_time_lsw, time->absolute_time_msw); ac->dsp_ts.abs_time_stamp = (uint64_t)(((uint64_t) time->absolute_time_msw << 32) | time->absolute_time_lsw); ac->dsp_ts.time_stamp = (uint64_t)(((uint64_t) time->session_time_msw << 32) | time->session_time_lsw); ac->dsp_ts.last_time_stamp = (uint64_t)(((uint64_t) time->time_stamp_msw << 32) | time->time_stamp_lsw); if (time->flags & ASM_SESSION_MTMX_STRTR_PARAM_STIME_TSTMP_FLG_BMASK) dev_warn_ratelimited(ac->dev, Loading Loading @@ -2361,7 +2369,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) dev_vdbg(ac->dev, "%s: ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3, payload[0] = %d, payload[1] = %d, payload[2] = %d\n", __func__, payload[0], payload[1], payload[2]); ac->time_stamp = (uint64_t)(((uint64_t)payload[2] << 32) | ac->dsp_ts.time_stamp = (uint64_t)(((uint64_t)payload[2] << 32) | payload[1]); } else { dev_err(ac->dev, "%s: payload size of %x is less than expected.n", Loading Loading @@ -9762,15 +9771,17 @@ int q6asm_write_nolock(struct audio_client *ac, uint32_t len, uint32_t msw_ts, EXPORT_SYMBOL(q6asm_write_nolock); /** * q6asm_get_session_time - * q6asm_get_session_time_v2 - * command to retrieve timestamp info * * @ac: Audio client handle * @tstamp: pointer to fill with timestamp info * @ses_time: pointer to fill with session timestamp info * @abs_time: pointer to fill with AVS timestamp info * * Returns 0 on success or error on failure */ int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp) int q6asm_get_session_time_v2(struct audio_client *ac, uint64_t *ses_time, uint64_t *abs_time) { struct asm_mtmx_strtr_get_params mtmx_params; int rc; Loading @@ -9783,8 +9794,8 @@ int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp) pr_err("%s: AC APR handle NULL\n", __func__); return -EINVAL; } if (tstamp == NULL) { pr_err("%s: tstamp NULL\n", __func__); if (ses_time == NULL) { pr_err("%s: tstamp args are NULL\n", __func__); return -EINVAL; } Loading Loading @@ -9822,12 +9833,29 @@ int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp) goto fail_cmd; } *tstamp = ac->time_stamp; *ses_time = ac->dsp_ts.time_stamp; if (abs_time != NULL) *abs_time = ac->dsp_ts.abs_time_stamp; return 0; fail_cmd: return -EINVAL; } EXPORT_SYMBOL(q6asm_get_session_time_v2); /** * q6asm_get_session_time - * command to retrieve timestamp info * * @ac: Audio client handle * @tstamp: pointer to fill with timestamp info * * Returns 0 on success or error on failure */ int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp) { return q6asm_get_session_time_v2(ac, tstamp, NULL); } EXPORT_SYMBOL(q6asm_get_session_time); /** Loading Loading @@ -9879,7 +9907,7 @@ int q6asm_get_session_time_legacy(struct audio_client *ac, uint64_t *tstamp) goto fail_cmd; } *tstamp = ac->time_stamp; *tstamp = ac->dsp_ts.time_stamp; return 0; fail_cmd: Loading
include/dsp/q6asm-v2.h +9 −2 Original line number Diff line number Diff line Loading @@ -207,6 +207,12 @@ struct shared_io_config { uint32_t bufcnt; }; struct dsp_timestamp { uint64_t time_stamp; uint64_t abs_time_stamp; uint64_t last_time_stamp; }; struct audio_client { int session; app_cb cb; Loading @@ -218,7 +224,7 @@ struct audio_client { atomic_t mem_state; void *priv; uint32_t io_mode; uint64_t time_stamp; struct dsp_timestamp dsp_ts; struct apr_svc *apr; struct apr_svc *mmap_apr; struct apr_svc *apr2; Loading Loading @@ -683,7 +689,8 @@ int q6asm_set_multich_gain(struct audio_client *ac, uint32_t channels, int q6asm_set_mute(struct audio_client *ac, int muteflag); int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp); int q6asm_get_session_time_v2(struct audio_client *ac, uint64_t *ses_time, uint64_t *abs_time); int q6asm_get_session_time_legacy(struct audio_client *ac, uint64_t *tstamp); int q6asm_send_stream_cmd(struct audio_client *ac, Loading