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:
parent
87cac622d8
commit
a50c958774
5 changed files with 499 additions and 41 deletions
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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(¶m_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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue