ASoC: msm: add support for new ADSP event APIs

Add support to handle new ADSP ASM stream event APIs for
different applications.

Change-Id: Id1e7b9b2841449ceb70099722d834b51c198f04e
Signed-off-by: Kuirong Wang <kuirongw@codeaurora.org>
Signed-off-by: Vidyakumar Athota <vathota@codeaurora.org>
This commit is contained in:
Kuirong Wang 2017-03-21 15:45:44 -07:00 committed by Vidyakumar Athota
parent 87cac622d8
commit a50c958774
5 changed files with 499 additions and 41 deletions

View file

@ -6333,6 +6333,62 @@ struct asm_stream_cmd_get_pp_params_v2 {
#define ASM_STREAM_CMD_SET_ENCDEC_PARAM 0x00010C10
#define ASM_STREAM_CMD_SET_ENCDEC_PARAM_V2 0x00013218
struct asm_stream_cmd_set_encdec_param_v2 {
u16 service_id;
/* 0 - ASM_ENCODER_SVC; 1 - ASM_DECODER_SVC */
u16 reserved;
u32 param_id;
/* ID of the parameter. */
u32 param_size;
/*
* Data size of this parameter, in bytes. The size is a multiple
* of 4 bytes.
*/
} __packed;
#define ASM_STREAM_CMD_REGISTER_ENCDEC_EVENTS 0x00013219
#define ASM_STREAM_CMD_ENCDEC_EVENTS 0x0001321A
#define AVS_PARAM_ID_RTIC_SHARED_MEMORY_ADDR 0x00013237
struct avs_rtic_shared_mem_addr {
struct apr_hdr hdr;
struct asm_stream_cmd_set_encdec_param_v2 encdec;
u32 shm_buf_addr_lsw;
/* Lower 32 bit of the RTIC shared memory */
u32 shm_buf_addr_msw;
/* Upper 32 bit of the RTIC shared memory */
u32 buf_size;
/* Size of buffer */
u16 shm_buf_mem_pool_id;
/* ADSP_MEMORY_MAP_SHMEM8_4K_POOL */
u16 shm_buf_num_regions;
/* number of regions to map */
u32 shm_buf_flag;
/* buffer property flag */
struct avs_shared_map_region_payload map_region;
/* memory map region*/
} __packed;
#define AVS_PARAM_ID_RTIC_EVENT_ACK 0x00013238
struct avs_param_rtic_event_ack {
struct apr_hdr hdr;
struct asm_stream_cmd_set_encdec_param_v2 encdec;
} __packed;
#define ASM_PARAM_ID_ENCDEC_BITRATE 0x00010C13
struct asm_bitrate_param {

View file

@ -618,8 +618,13 @@ int q6asm_get_session_time_legacy(struct audio_client *ac, uint64_t *tstamp);
int q6asm_send_audio_effects_params(struct audio_client *ac, char *params,
uint32_t params_length);
int q6asm_send_stream_cmd(struct audio_client *ac, uint32_t opcode,
void *param, uint32_t params_length);
int q6asm_send_stream_cmd(struct audio_client *ac,
struct msm_adsp_event_data *data);
int q6asm_send_ion_fd(struct audio_client *ac, int fd);
int q6asm_send_rtic_event_ack(struct audio_client *ac,
void *param, uint32_t params_length);
/* Client can set the IO mode to either AIO/SIO mode */
int q6asm_set_io_mode(struct audio_client *ac, uint32_t mode);

View file

@ -32,6 +32,7 @@
#include <asm/dma.h>
#include <linux/dma-mapping.h>
#include <linux/msm_audio_ion.h>
#include <linux/msm_audio.h>
#include <sound/timer.h>
#include <sound/tlv.h>
@ -725,7 +726,8 @@ static void compr_event_handler(uint32_t opcode,
spin_unlock_irqrestore(&prtd->lock, flags);
break;
case ASM_STREAM_PP_EVENT:
pr_debug("%s: ASM_STREAM_PP_EVENT\n", __func__);
case ASM_STREAM_CMD_ENCDEC_EVENTS:
pr_debug("%s: ASM_STREAM_EVENT(0x%x)\n", __func__, opcode);
rtd = cstream->private_data;
if (!rtd) {
pr_err("%s: rtd is NULL\n", __func__);
@ -738,7 +740,6 @@ static void compr_event_handler(uint32_t opcode,
__func__, ret);
return;
}
break;
case ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY:
case ASM_DATA_EVENT_ENC_SR_CM_CHANGE_NOTIFY: {
@ -3616,7 +3617,8 @@ static int msm_compr_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
snd_soc_component_get_drvdata(comp);
struct snd_compr_stream *cstream = NULL;
struct msm_compr_audio *prtd;
int ret = 0, param_length = 0;
int ret = 0;
struct msm_adsp_event_data *event_data = NULL;
if (fe_id >= MSM_FRONTEND_DAI_MAX) {
pr_err("%s Received invalid fe_id %lu\n",
@ -3627,20 +3629,131 @@ static int msm_compr_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
cstream = pdata->cstream[fe_id];
if (cstream == NULL) {
pr_err("%s cstream is null.\n", __func__);
pr_err("%s cstream is null\n", __func__);
ret = -EINVAL;
goto done;
}
prtd = cstream->runtime->private_data;
if (!prtd) {
pr_err("%s: prtd is null.\n", __func__);
pr_err("%s: prtd is null\n", __func__);
ret = -EINVAL;
goto done;
}
if (prtd->audio_client == NULL) {
pr_err("%s: audio_client is null.\n", __func__);
pr_err("%s: audio_client is null\n", __func__);
ret = -EINVAL;
goto done;
}
event_data = (struct msm_adsp_event_data *)ucontrol->value.bytes.data;
if ((event_data->event_type < ADSP_STREAM_PP_EVENT) ||
(event_data->event_type >= ADSP_STREAM_EVENT_MAX)) {
pr_err("%s: invalid event_type=%d",
__func__, event_data->event_type);
ret = -EINVAL;
goto done;
}
if ((sizeof(struct msm_adsp_event_data) + event_data->payload_len) >=
sizeof(ucontrol->value.bytes.data)) {
pr_err("%s param length=%d exceeds limit",
__func__, event_data->payload_len);
ret = -EINVAL;
goto done;
}
ret = q6asm_send_stream_cmd(prtd->audio_client, event_data);
if (ret < 0)
pr_err("%s: failed to send stream event cmd, err = %d\n",
__func__, ret);
done:
return ret;
}
static int msm_compr_ion_fd_map_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
unsigned long fe_id = kcontrol->private_value;
struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
snd_soc_component_get_drvdata(comp);
struct snd_compr_stream *cstream = NULL;
struct msm_compr_audio *prtd;
int fd;
int ret = 0;
if (fe_id >= MSM_FRONTEND_DAI_MAX) {
pr_err("%s Received out of bounds invalid fe_id %lu\n",
__func__, fe_id);
ret = -EINVAL;
goto done;
}
cstream = pdata->cstream[fe_id];
if (cstream == NULL) {
pr_err("%s cstream is null\n", __func__);
ret = -EINVAL;
goto done;
}
prtd = cstream->runtime->private_data;
if (!prtd) {
pr_err("%s: prtd is null\n", __func__);
ret = -EINVAL;
goto done;
}
if (prtd->audio_client == NULL) {
pr_err("%s: audio_client is null\n", __func__);
ret = -EINVAL;
goto done;
}
memcpy(&fd, ucontrol->value.bytes.data, sizeof(fd));
ret = q6asm_send_ion_fd(prtd->audio_client, fd);
if (ret < 0)
pr_err("%s: failed to register ion fd\n", __func__);
done:
return ret;
}
static int msm_compr_rtic_event_ack_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
unsigned long fe_id = kcontrol->private_value;
struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
snd_soc_component_get_drvdata(comp);
struct snd_compr_stream *cstream = NULL;
struct msm_compr_audio *prtd;
int ret = 0;
int param_length = 0;
if (fe_id >= MSM_FRONTEND_DAI_MAX) {
pr_err("%s Received invalid fe_id %lu\n",
__func__, fe_id);
ret = -EINVAL;
goto done;
}
cstream = pdata->cstream[fe_id];
if (cstream == NULL) {
pr_err("%s cstream is null\n", __func__);
ret = -EINVAL;
goto done;
}
prtd = cstream->runtime->private_data;
if (!prtd) {
pr_err("%s: prtd is null\n", __func__);
ret = -EINVAL;
goto done;
}
if (prtd->audio_client == NULL) {
pr_err("%s: audio_client is null\n", __func__);
ret = -EINVAL;
goto done;
}
@ -3655,12 +3768,11 @@ static int msm_compr_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
goto done;
}
ret = q6asm_send_stream_cmd(prtd->audio_client,
ASM_STREAM_CMD_REGISTER_PP_EVENTS,
ret = q6asm_send_rtic_event_ack(prtd->audio_client,
ucontrol->value.bytes.data + sizeof(param_length),
param_length);
if (ret < 0)
pr_err("%s: failed to register pp event. err = %d\n",
pr_err("%s: failed to send rtic event ack, err = %d\n",
__func__, ret);
done:
return ret;
@ -4234,6 +4346,96 @@ static int msm_compr_add_channel_map_control(struct snd_soc_pcm_runtime *rtd)
return 0;
}
static int msm_compr_add_io_fd_cmd_control(struct snd_soc_pcm_runtime *rtd)
{
const char *mixer_ctl_name = "Playback ION FD";
const char *deviceNo = "NN";
char *mixer_str = NULL;
int ctl_len = 0, ret = 0;
struct snd_kcontrol_new fe_ion_fd_config_control[1] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "?",
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
.info = msm_adsp_stream_cmd_info,
.put = msm_compr_ion_fd_map_put,
.private_value = 0,
}
};
if (!rtd) {
pr_err("%s NULL rtd\n", __func__);
ret = -EINVAL;
goto done;
}
ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
mixer_str = kzalloc(ctl_len, GFP_KERNEL);
if (!mixer_str) {
ret = -ENOMEM;
goto done;
}
snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device);
fe_ion_fd_config_control[0].name = mixer_str;
fe_ion_fd_config_control[0].private_value = rtd->dai_link->be_id;
pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
ret = snd_soc_add_platform_controls(rtd->platform,
fe_ion_fd_config_control,
ARRAY_SIZE(fe_ion_fd_config_control));
if (ret < 0)
pr_err("%s: failed to add ctl %s\n", __func__, mixer_str);
kfree(mixer_str);
done:
return ret;
}
static int msm_compr_add_event_ack_cmd_control(struct snd_soc_pcm_runtime *rtd)
{
const char *mixer_ctl_name = "Playback Event Ack";
const char *deviceNo = "NN";
char *mixer_str = NULL;
int ctl_len = 0, ret = 0;
struct snd_kcontrol_new fe_event_ack_config_control[1] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "?",
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
.info = msm_adsp_stream_cmd_info,
.put = msm_compr_rtic_event_ack_put,
.private_value = 0,
}
};
if (!rtd) {
pr_err("%s NULL rtd\n", __func__);
ret = -EINVAL;
goto done;
}
ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1;
mixer_str = kzalloc(ctl_len, GFP_KERNEL);
if (!mixer_str) {
ret = -ENOMEM;
goto done;
}
snprintf(mixer_str, ctl_len, "%s %d", mixer_ctl_name, rtd->pcm->device);
fe_event_ack_config_control[0].name = mixer_str;
fe_event_ack_config_control[0].private_value = rtd->dai_link->be_id;
pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
ret = snd_soc_add_platform_controls(rtd->platform,
fe_event_ack_config_control,
ARRAY_SIZE(fe_event_ack_config_control));
if (ret < 0)
pr_err("%s: failed to add ctl %s\n", __func__, mixer_str);
kfree(mixer_str);
done:
return ret;
}
static int msm_compr_new(struct snd_soc_pcm_runtime *rtd)
{
int rc;
@ -4257,6 +4459,16 @@ static int msm_compr_new(struct snd_soc_pcm_runtime *rtd)
pr_err("%s: Could not add Compr ADSP Stream Callback Control\n",
__func__);
rc = msm_compr_add_io_fd_cmd_control(rtd);
if (rc)
pr_err("%s: Could not add Compr ion fd Control\n",
__func__);
rc = msm_compr_add_event_ack_cmd_control(rtd);
if (rc)
pr_err("%s: Could not add Compr event ack Control\n",
__func__);
rc = msm_compr_add_query_audio_effect_control(rtd);
if (rc)
pr_err("%s: Could not add Compr Query Audio Effect Control\n",

View file

@ -30,6 +30,7 @@
#include <asm/dma.h>
#include <linux/dma-mapping.h>
#include <linux/msm_audio_ion.h>
#include <linux/msm_audio.h>
#include <linux/of_device.h>
#include <sound/tlv.h>
@ -226,8 +227,9 @@ static void event_handler(uint32_t opcode,
}
break;
}
case ASM_STREAM_PP_EVENT: {
pr_debug("%s: ASM_STREAM_PP_EVENT\n", __func__);
case ASM_STREAM_PP_EVENT:
case ASM_STREAM_CMD_ENCDEC_EVENTS: {
pr_debug("%s: ASM_STREAM_EVENT (0x%x)\n", __func__, opcode);
if (!substream) {
pr_err("%s: substream is NULL.\n", __func__);
return;
@ -1075,7 +1077,8 @@ static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
struct msm_plat_data *pdata = dev_get_drvdata(platform->dev);
struct snd_pcm_substream *substream;
struct msm_audio *prtd;
int ret = 0, param_length = 0;
int ret = 0;
struct msm_adsp_event_data *event_data = NULL;
if (!pdata) {
pr_err("%s pdata is NULL\n", __func__);
@ -1103,22 +1106,26 @@ static int msm_pcm_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
goto done;
}
memcpy(&param_length, ucontrol->value.bytes.data,
sizeof(param_length));
if ((param_length + sizeof(param_length))
>= sizeof(ucontrol->value.bytes.data)) {
pr_err("%s param length=%d exceeds limit",
__func__, param_length);
event_data = (struct msm_adsp_event_data *)ucontrol->value.bytes.data;
if ((event_data->event_type < ADSP_STREAM_PP_EVENT) ||
(event_data->event_type >= ADSP_STREAM_EVENT_MAX)) {
pr_err("%s: invalid event_type=%d",
__func__, event_data->event_type);
ret = -EINVAL;
goto done;
}
ret = q6asm_send_stream_cmd(prtd->audio_client,
ASM_STREAM_CMD_REGISTER_PP_EVENTS,
ucontrol->value.bytes.data + sizeof(param_length),
param_length);
if ((sizeof(struct msm_adsp_event_data) + event_data->payload_len) >=
sizeof(ucontrol->value.bytes.data)) {
pr_err("%s param length=%d exceeds limit",
__func__, event_data->payload_len);
ret = -EINVAL;
goto done;
}
ret = q6asm_send_stream_cmd(prtd->audio_client, event_data);
if (ret < 0)
pr_err("%s: failed to register pp event. err = %d\n",
pr_err("%s: failed to send stream event cmd, err = %d\n",
__func__, ret);
done:
return ret;

View file

@ -155,6 +155,13 @@ static int out_cold_index;
static char *out_buffer;
static char *in_buffer;
static uint32_t adsp_reg_event_opcode[] = {ASM_STREAM_CMD_REGISTER_PP_EVENTS,
ASM_STREAM_CMD_REGISTER_ENCDEC_EVENTS};
static uint32_t adsp_raise_event_opcode[] = {ASM_STREAM_PP_EVENT,
ASM_STREAM_CMD_ENCDEC_EVENTS};
static inline void q6asm_set_flag_in_token(union asm_token_struct *asm_token,
int flag, int flag_offset)
{
@ -1094,37 +1101,44 @@ fail:
return NULL;
}
int q6asm_send_stream_cmd(struct audio_client *ac, uint32_t opcode,
void *param, uint32_t params_length)
int q6asm_send_stream_cmd(struct audio_client *ac,
struct msm_adsp_event_data *data)
{
char *asm_params = NULL;
struct apr_hdr hdr;
int sz, rc;
if (!param || !ac) {
if (!data || !ac) {
pr_err("%s: %s is NULL\n", __func__,
(!param) ? "param" : "ac");
(!data) ? "data" : "ac");
rc = -EINVAL;
goto done;
}
sz = sizeof(struct apr_hdr) + params_length;
if (data->event_type >= ARRAY_SIZE(adsp_reg_event_opcode)) {
pr_err("%s: event %u out of boundary of array size of (%lu)\n",
__func__, data->event_type,
(long)ARRAY_SIZE(adsp_reg_event_opcode));
rc = -EINVAL;
goto done;
}
sz = sizeof(struct apr_hdr) + data->payload_len;
asm_params = kzalloc(sz, GFP_KERNEL);
if (!asm_params) {
rc = -ENOMEM;
goto done;
}
q6asm_add_hdr_async(ac, &hdr, sizeof(struct apr_hdr) +
params_length, TRUE);
q6asm_add_hdr_async(ac, &hdr, sz, TRUE);
atomic_set(&ac->cmd_state_pp, -1);
hdr.opcode = opcode;
hdr.opcode = adsp_reg_event_opcode[data->event_type];
memcpy(asm_params, &hdr, sizeof(struct apr_hdr));
memcpy(asm_params + sizeof(struct apr_hdr),
param, params_length);
data->payload, data->payload_len);
rc = apr_send_pkt(ac->apr, (uint32_t *) asm_params);
if (rc < 0) {
pr_err("%s: audio adsp pp register failed\n", __func__);
pr_err("%s: stream event cmd apr pkt failed\n", __func__);
rc = -EINVAL;
goto fail_send_param;
}
@ -1132,13 +1146,13 @@ int q6asm_send_stream_cmd(struct audio_client *ac, uint32_t opcode,
rc = wait_event_timeout(ac->cmd_wait,
(atomic_read(&ac->cmd_state_pp) >= 0), 1 * HZ);
if (!rc) {
pr_err("%s: timeout, adsp pp register\n", __func__);
pr_err("%s: timeout for stream event cmd resp\n", __func__);
rc = -ETIMEDOUT;
goto fail_send_param;
}
if (atomic_read(&ac->cmd_state_pp) > 0) {
pr_err("%s: DSP returned error[%s] adsp pp register\n",
pr_err("%s: DSP returned error[%s] for stream event cmd\n",
__func__, adsp_err_get_err_str(
atomic_read(&ac->cmd_state_pp)));
rc = adsp_err_get_lnx_err_code(
@ -1776,6 +1790,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
case ASM_STREAM_CMD_OPEN_TRANSCODE_LOOPBACK:
case ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2:
case ASM_STREAM_CMD_SET_ENCDEC_PARAM:
case ASM_STREAM_CMD_SET_ENCDEC_PARAM_V2:
case ASM_STREAM_CMD_REGISTER_ENCDEC_EVENTS:
case ASM_DATA_CMD_REMOVE_INITIAL_SILENCE:
case ASM_DATA_CMD_REMOVE_TRAILING_SILENCE:
case ASM_SESSION_CMD_REGISTER_FOR_RX_UNDERFLOW_EVENTS:
@ -1790,7 +1806,9 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
__func__, payload[0], payload[1]);
if (wakeup_flag) {
if (payload[0] ==
ASM_STREAM_CMD_SET_PP_PARAMS_V2)
ASM_STREAM_CMD_SET_PP_PARAMS_V2
|| payload[0] ==
ASM_STREAM_CMD_REGISTER_ENCDEC_EVENTS)
atomic_set(&ac->cmd_state_pp,
payload[1]);
else
@ -1800,7 +1818,9 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
}
return 0;
}
if (payload[0] == ASM_STREAM_CMD_SET_PP_PARAMS_V2) {
if (payload[0] == ASM_STREAM_CMD_SET_PP_PARAMS_V2 ||
payload[0] ==
ASM_STREAM_CMD_REGISTER_ENCDEC_EVENTS) {
if (atomic_read(&ac->cmd_state_pp) &&
wakeup_flag) {
atomic_set(&ac->cmd_state_pp, 0);
@ -2040,8 +2060,16 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
q6asm_process_mtmx_get_param_rsp(ac, (void *) payload);
break;
case ASM_STREAM_PP_EVENT:
case ASM_STREAM_CMD_ENCDEC_EVENTS:
pr_debug("%s: ASM_STREAM_PP_EVENT payload[0][0x%x] payload[1][0x%x]",
__func__, payload[0], payload[1]);
for (i = 0; i < ARRAY_SIZE(adsp_raise_event_opcode); i++)
if (adsp_raise_event_opcode[i] == data->opcode)
break;
if (i >= ARRAY_SIZE(adsp_raise_event_opcode))
return 0;
/* repack payload for asm_stream_pp_event
* package is composed of event type + size + actual payload
*/
@ -2052,10 +2080,10 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
if (!pp_event_package)
return -ENOMEM;
pp_event_package->event_type = ASM_STREAM_PP_EVENT;
pp_event_package->event_type = i;
pp_event_package->payload_len = payload_size;
memcpy((void *)pp_event_package->payload,
data->payload, payload_size);
data->payload, payload_size);
ac->cb(data->opcode, data->token,
(void *)pp_event_package, ac->priv);
kfree(pp_event_package);
@ -7128,6 +7156,156 @@ fail_cmd:
return rc;
}
int q6asm_send_ion_fd(struct audio_client *ac, int fd)
{
struct ion_client *client;
struct ion_handle *handle;
ion_phys_addr_t paddr;
size_t pa_len = 0;
void *vaddr;
int ret;
int sz = 0;
struct avs_rtic_shared_mem_addr shm;
if (ac == NULL) {
pr_err("%s: APR handle NULL\n", __func__);
ret = -EINVAL;
goto fail_cmd;
}
if (ac->apr == NULL) {
pr_err("%s: AC APR handle NULL\n", __func__);
ret = -EINVAL;
goto fail_cmd;
}
ret = msm_audio_ion_import("audio_mem_client",
&client,
&handle,
fd,
NULL,
0,
&paddr,
&pa_len,
&vaddr);
if (ret) {
pr_err("%s: audio ION import failed, rc = %d\n",
__func__, ret);
ret = -ENOMEM;
goto fail_cmd;
}
/* get payload length */
sz = sizeof(struct avs_rtic_shared_mem_addr);
q6asm_add_hdr_async(ac, &shm.hdr, sz, TRUE);
atomic_set(&ac->cmd_state, -1);
shm.shm_buf_addr_lsw = lower_32_bits(paddr);
shm.shm_buf_addr_msw = msm_audio_populate_upper_32_bits(paddr);
shm.buf_size = pa_len;
shm.shm_buf_num_regions = 1;
shm.shm_buf_mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL;
shm.shm_buf_flag = 0x00;
shm.encdec.param_id = AVS_PARAM_ID_RTIC_SHARED_MEMORY_ADDR;
shm.encdec.param_size = sizeof(struct avs_rtic_shared_mem_addr) -
sizeof(struct apr_hdr) -
sizeof(struct asm_stream_cmd_set_encdec_param_v2);
shm.encdec.service_id = OUT;
shm.encdec.reserved = 0;
shm.map_region.shm_addr_lsw = shm.shm_buf_addr_lsw;
shm.map_region.shm_addr_msw = shm.shm_buf_addr_msw;
shm.map_region.mem_size_bytes = pa_len;
shm.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM_V2;
ret = apr_send_pkt(ac->apr, (uint32_t *) &shm);
if (ret < 0) {
pr_err("%s: set-params send failed paramid[0x%x] rc %d\n",
__func__, shm.encdec.param_id, ret);
ret = -EINVAL;
goto fail_cmd;
}
ret = wait_event_timeout(ac->cmd_wait,
(atomic_read(&ac->cmd_state) >= 0), 1*HZ);
if (!ret) {
pr_err("%s: timeout, shm.encdec paramid[0x%x]\n", __func__,
shm.encdec.param_id);
ret = -ETIMEDOUT;
goto fail_cmd;
}
if (atomic_read(&ac->cmd_state) > 0) {
pr_err("%s: DSP returned error[%s] shm.encdec paramid[0x%x]\n",
__func__,
adsp_err_get_err_str(atomic_read(&ac->cmd_state)),
shm.encdec.param_id);
ret = adsp_err_get_lnx_err_code(atomic_read(&ac->cmd_state));
goto fail_cmd;
}
ret = 0;
fail_cmd:
return ret;
}
int q6asm_send_rtic_event_ack(struct audio_client *ac,
void *param, uint32_t params_length)
{
char *asm_params = NULL;
int sz, rc;
struct avs_param_rtic_event_ack ack;
if (!param || !ac) {
pr_err("%s: %s is NULL\n", __func__,
(!param) ? "param" : "ac");
rc = -EINVAL;
goto done;
}
sz = sizeof(struct avs_param_rtic_event_ack) + params_length;
asm_params = kzalloc(sz, GFP_KERNEL);
if (!asm_params) {
rc = -ENOMEM;
goto done;
}
q6asm_add_hdr_async(ac, &ack.hdr,
sizeof(struct avs_param_rtic_event_ack) +
params_length, TRUE);
atomic_set(&ac->cmd_state, -1);
ack.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM_V2;
ack.encdec.param_id = AVS_PARAM_ID_RTIC_EVENT_ACK;
ack.encdec.param_size = params_length;
ack.encdec.reserved = 0;
ack.encdec.service_id = OUT;
memcpy(asm_params, &ack, sizeof(struct avs_param_rtic_event_ack));
memcpy(asm_params + sizeof(struct avs_param_rtic_event_ack),
param, params_length);
rc = apr_send_pkt(ac->apr, (uint32_t *) asm_params);
if (rc < 0) {
pr_err("%s: apr pkt failed for rtic event ack\n", __func__);
rc = -EINVAL;
goto fail_send_param;
}
rc = wait_event_timeout(ac->cmd_wait,
(atomic_read(&ac->cmd_state) >= 0), 1 * HZ);
if (!rc) {
pr_err("%s: timeout for rtic event ack cmd\n", __func__);
rc = -ETIMEDOUT;
goto fail_send_param;
}
if (atomic_read(&ac->cmd_state) > 0) {
pr_err("%s: DSP returned error[%s] for rtic event ack cmd\n",
__func__, adsp_err_get_err_str(
atomic_read(&ac->cmd_state)));
rc = adsp_err_get_lnx_err_code(
atomic_read(&ac->cmd_state));
goto fail_send_param;
}
rc = 0;
fail_send_param:
kfree(asm_params);
done:
return rc;
}
int q6asm_set_softpause(struct audio_client *ac,
struct asm_softpause_params *pause_param)
{