audio-kernel: add support to query presentation position from DSP
Add support to query presentation position from DSP in system time domain. Change-Id: I42b4d234ddc256f93c01defbe2c74872a2a2cf3e Signed-off-by: Surendar Karka <skarka@codeaurora.org>
This commit is contained in:
@@ -3153,13 +3153,18 @@ static int msm_compr_get_metadata(struct snd_compr_stream *cstream,
|
|||||||
struct msm_compr_audio *prtd;
|
struct msm_compr_audio *prtd;
|
||||||
struct audio_client *ac;
|
struct audio_client *ac;
|
||||||
int ret = -EINVAL;
|
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__);
|
pr_debug("%s\n", __func__);
|
||||||
|
|
||||||
if (!metadata || !cstream || !cstream->runtime)
|
if (!metadata || !cstream || !cstream->runtime)
|
||||||
return ret;
|
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);
|
pr_err("%s, unsupported key %d\n", __func__, metadata->key);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -3170,17 +3175,50 @@ static int msm_compr_get_metadata(struct snd_compr_stream *cstream,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ac = prtd->audio_client;
|
switch (metadata->key) {
|
||||||
ret = q6asm_get_path_delay(prtd->audio_client);
|
case SNDRV_COMPRESS_PATH_DELAY:
|
||||||
if (ret) {
|
ac = prtd->audio_client;
|
||||||
pr_err("%s: get_path_delay failed, ret=%d\n", __func__, ret);
|
ret = q6asm_get_path_delay(prtd->audio_client);
|
||||||
return ret;
|
if (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);
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_debug("%s, path delay(in us) %u\n", __func__, ac->path_delay);
|
|
||||||
|
|
||||||
metadata->value[0] = ac->path_delay;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <sound/tlv.h>
|
#include <sound/tlv.h>
|
||||||
#include <sound/pcm_params.h>
|
#include <sound/pcm_params.h>
|
||||||
|
#include <sound/devdep_params.h>
|
||||||
#include <dsp/msm_audio_ion.h>
|
#include <dsp/msm_audio_ion.h>
|
||||||
#include <dsp/q6audio-v2.h>
|
#include <dsp/q6audio-v2.h>
|
||||||
#include <dsp/q6core.h>
|
#include <dsp/q6core.h>
|
||||||
@@ -1156,12 +1157,106 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream,
|
|||||||
return 0;
|
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 = {
|
static const struct snd_pcm_ops msm_pcm_ops = {
|
||||||
.open = msm_pcm_open,
|
.open = msm_pcm_open,
|
||||||
.copy_user = msm_pcm_copy,
|
.copy_user = msm_pcm_copy,
|
||||||
.hw_params = msm_pcm_hw_params,
|
.hw_params = msm_pcm_hw_params,
|
||||||
.close = msm_pcm_close,
|
.close = msm_pcm_close,
|
||||||
.ioctl = snd_pcm_lib_ioctl,
|
.ioctl = msm_pcm_ioctl,
|
||||||
|
.compat_ioctl = msm_pcm_compat_ioctl,
|
||||||
.prepare = msm_pcm_prepare,
|
.prepare = msm_pcm_prepare,
|
||||||
.trigger = msm_pcm_trigger,
|
.trigger = msm_pcm_trigger,
|
||||||
.pointer = msm_pcm_pointer,
|
.pointer = msm_pcm_pointer,
|
||||||
|
@@ -309,6 +309,61 @@ int avcs_core_query_timer(uint64_t *avtimer_tick)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(avcs_core_query_timer);
|
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)
|
#if IS_ENABLED(CONFIG_AVTIMER_LEGACY)
|
||||||
static void avcs_set_isp_fptr(bool enable)
|
static void avcs_set_isp_fptr(bool enable)
|
||||||
{
|
{
|
||||||
|
52
dsp/q6asm.c
52
dsp/q6asm.c
@@ -1868,12 +1868,20 @@ static void q6asm_process_mtmx_get_param_rsp(struct audio_client *ac,
|
|||||||
switch (cmdrsp->param_info.param_id) {
|
switch (cmdrsp->param_info.param_id) {
|
||||||
case ASM_SESSION_MTMX_STRTR_PARAM_SESSION_TIME_V3:
|
case ASM_SESSION_MTMX_STRTR_PARAM_SESSION_TIME_V3:
|
||||||
time = &cmdrsp->param_data.session_time;
|
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,
|
__func__, time->session_time_lsw,
|
||||||
time->session_time_msw);
|
time->session_time_msw,
|
||||||
ac->time_stamp = (uint64_t)(((uint64_t)
|
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_msw << 32) |
|
||||||
time->session_time_lsw);
|
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 &
|
if (time->flags &
|
||||||
ASM_SESSION_MTMX_STRTR_PARAM_STIME_TSTMP_FLG_BMASK)
|
ASM_SESSION_MTMX_STRTR_PARAM_STIME_TSTMP_FLG_BMASK)
|
||||||
dev_warn_ratelimited(ac->dev,
|
dev_warn_ratelimited(ac->dev,
|
||||||
@@ -2361,8 +2369,9 @@ 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",
|
dev_vdbg(ac->dev, "%s: ASM_SESSION_CMDRSP_GET_SESSIONTIME_V3, payload[0] = %d, payload[1] = %d, payload[2] = %d\n",
|
||||||
__func__,
|
__func__,
|
||||||
payload[0], payload[1], payload[2]);
|
payload[0], payload[1], payload[2]);
|
||||||
ac->time_stamp = (uint64_t)(((uint64_t)payload[2] << 32) |
|
ac->dsp_ts.time_stamp =
|
||||||
payload[1]);
|
(uint64_t)(((uint64_t)payload[2] << 32) |
|
||||||
|
payload[1]);
|
||||||
} else {
|
} else {
|
||||||
dev_err(ac->dev, "%s: payload size of %x is less than expected.n",
|
dev_err(ac->dev, "%s: payload size of %x is less than expected.n",
|
||||||
__func__, data->payload_size);
|
__func__, data->payload_size);
|
||||||
@@ -9761,15 +9770,17 @@ fail_cmd:
|
|||||||
EXPORT_SYMBOL(q6asm_write_nolock);
|
EXPORT_SYMBOL(q6asm_write_nolock);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* q6asm_get_session_time -
|
* q6asm_get_session_time_v2 -
|
||||||
* command to retrieve timestamp info
|
* command to retrieve timestamp info
|
||||||
*
|
*
|
||||||
* @ac: Audio client handle
|
* @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
|
* 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;
|
struct asm_mtmx_strtr_get_params mtmx_params;
|
||||||
int rc;
|
int rc;
|
||||||
@@ -9782,8 +9793,8 @@ int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp)
|
|||||||
pr_err("%s: AC APR handle NULL\n", __func__);
|
pr_err("%s: AC APR handle NULL\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (tstamp == NULL) {
|
if (ses_time == NULL) {
|
||||||
pr_err("%s: tstamp NULL\n", __func__);
|
pr_err("%s: tstamp args are NULL\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9821,12 +9832,29 @@ int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp)
|
|||||||
goto fail_cmd;
|
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;
|
return 0;
|
||||||
|
|
||||||
fail_cmd:
|
fail_cmd:
|
||||||
return -EINVAL;
|
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);
|
EXPORT_SYMBOL(q6asm_get_session_time);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -9878,7 +9906,7 @@ int q6asm_get_session_time_legacy(struct audio_client *ac, uint64_t *tstamp)
|
|||||||
goto fail_cmd;
|
goto fail_cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
*tstamp = ac->time_stamp;
|
*tstamp = ac->dsp_ts.time_stamp;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail_cmd:
|
fail_cmd:
|
||||||
|
@@ -207,6 +207,12 @@ struct shared_io_config {
|
|||||||
uint32_t bufcnt;
|
uint32_t bufcnt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct dsp_timestamp {
|
||||||
|
uint64_t time_stamp;
|
||||||
|
uint64_t abs_time_stamp;
|
||||||
|
uint64_t last_time_stamp;
|
||||||
|
};
|
||||||
|
|
||||||
struct audio_client {
|
struct audio_client {
|
||||||
int session;
|
int session;
|
||||||
app_cb cb;
|
app_cb cb;
|
||||||
@@ -218,7 +224,7 @@ struct audio_client {
|
|||||||
atomic_t mem_state;
|
atomic_t mem_state;
|
||||||
void *priv;
|
void *priv;
|
||||||
uint32_t io_mode;
|
uint32_t io_mode;
|
||||||
uint64_t time_stamp;
|
struct dsp_timestamp dsp_ts;
|
||||||
struct apr_svc *apr;
|
struct apr_svc *apr;
|
||||||
struct apr_svc *mmap_apr;
|
struct apr_svc *mmap_apr;
|
||||||
struct apr_svc *apr2;
|
struct apr_svc *apr2;
|
||||||
@@ -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_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(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_get_session_time_legacy(struct audio_client *ac, uint64_t *tstamp);
|
||||||
|
|
||||||
int q6asm_send_stream_cmd(struct audio_client *ac,
|
int q6asm_send_stream_cmd(struct audio_client *ac,
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
bool q6core_is_adsp_ready(void);
|
bool q6core_is_adsp_ready(void);
|
||||||
|
|
||||||
|
int avcs_core_query_timer_offset(int64_t *av_offset, int32_t clock_id);
|
||||||
int q6core_get_service_version(uint32_t service_id,
|
int q6core_get_service_version(uint32_t service_id,
|
||||||
struct avcs_fwk_ver_info *ver_info,
|
struct avcs_fwk_ver_info *ver_info,
|
||||||
size_t size);
|
size_t size);
|
||||||
|
@@ -61,6 +61,14 @@ struct snd_pcm_mmap_fd {
|
|||||||
int32_t actual_size;
|
int32_t actual_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct snd_pcm_prsnt_position {
|
||||||
|
uint64_t timestamp;
|
||||||
|
uint64_t frames;
|
||||||
|
int32_t clock_id;
|
||||||
|
};
|
||||||
|
|
||||||
#define SNDRV_PCM_IOCTL_MMAP_DATA_FD _IOWR('U', 0xd2, struct snd_pcm_mmap_fd)
|
#define SNDRV_PCM_IOCTL_MMAP_DATA_FD _IOWR('U', 0xd2, struct snd_pcm_mmap_fd)
|
||||||
|
#define SNDRV_PCM_IOCTL_DSP_POSITION\
|
||||||
|
_IOWR('U', 0xd3, struct snd_pcm_prsnt_position)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user