ASoC: msm: Integrate Eagle framework to support HeadphoneX

Add support to integrate the Eagle framework for HeadphoneX
audio post processing feature

Initial K integration targeting mainlining

Change-Id: I7825605a44f58709beb960a25ab3784c4953c6f4
Git-commit: ec82dc50e620494f2f4022e439c9f000ed67566e
Git-repo: https://github.com/dtsinc/DTS-Eagle-Integration_CAF-Android-kernel
[snariped@codeaurora.org: resolve trivial merge conflicts]
Signed-off-by: Subhash Chandra Bose Naripeddy <snariped@codeaurora.org>
This commit is contained in:
Darren 2014-07-08 17:25:00 -07:00 committed by Subhash Chandra Bose Naripeddy
parent 286b0d283d
commit 611fc3bbc1
14 changed files with 1705 additions and 4 deletions

View File

@ -2405,6 +2405,8 @@ struct afe_port_cmdrsp_get_param_v2 {
#define VPM_TX_DM_FLUENCE_COPP_TOPOLOGY 0x00010F72
#define VPM_TX_QMIC_FLUENCE_COPP_TOPOLOGY 0x00010F75
#define VPM_TX_DM_RFECNS_COPP_TOPOLOGY 0x00010F86
#define ADM_CMD_COPP_OPEN_TOPOLOGY_ID_DTS_HPX_0 0x00010347
#define ADM_CMD_COPP_OPEN_TOPOLOGY_ID_DTS_HPX_1 0x00010348
/* Memory map regions command payload used by the
* #ASM_CMD_SHARED_MEM_MAP_REGIONS ,#ADM_CMD_SHARED_MEM_MAP_REGIONS
@ -6916,6 +6918,21 @@ struct srs_trumedia_params {
} __packed;
/* SRS TruMedia end */
/* DTS Eagle */
#define AUDPROC_MODULE_ID_DTS_HPX_PREMIX 0x0001077C
#define AUDPROC_MODULE_ID_DTS_HPX_POSTMIX 0x0001077B
#define ASM_STREAM_POSTPROC_TOPO_ID_DTS_HPX 0x00010DED
struct asm_dts_eagle_param {
struct apr_hdr hdr;
struct asm_stream_cmd_set_pp_params_v2 param;
struct asm_stream_param_data_v2 data;
} __packed;
struct asm_dts_eagle_param_get {
struct apr_hdr hdr;
struct asm_stream_cmd_get_pp_params_v2 param;
} __packed;
/* LSM Specific */
#define VW_FEAT_DIM (39)

View File

@ -35,6 +35,12 @@ struct route_payload {
int srs_trumedia_open(int port_id, int copp_idx, int srs_tech_id,
void *srs_params);
int adm_dts_eagle_set(int port_id, int copp_idx, int param_id,
void *data, int size);
int adm_dts_eagle_get(int port_id, int copp_idx, int param_id,
void *data, int size);
int adm_get_params(int port_id, int copp_idx, uint32_t module_id,
uint32_t param_id, uint32_t params_length, char *params);

View File

@ -378,6 +378,11 @@ int q6asm_equalizer(struct audio_client *ac, void *eq);
/* Send Volume Command */
int q6asm_set_volume(struct audio_client *ac, int volume);
int q6asm_dts_eagle_set(struct audio_client *ac, int param_id, int size,
void *data);
int q6asm_dts_eagle_get(struct audio_client *ac, int param_id,
int size, void *data);
/* Set SoftPause Params */
int q6asm_set_softpause(struct audio_client *ac,
struct asm_softpause_params *param);

View File

@ -94,6 +94,18 @@ int core_get_low_power_segments(
struct avcs_cmd_rsp_get_low_power_segments_info_t **);
bool q6core_is_adsp_ready(void);
#define ADSP_CMD_SET_DTS_EAGLE_DATA_ID 0x00012919
#define DTS_EAGLE_LICENSE_ID 0x00028346
struct adsp_dts_eagle {
struct apr_hdr hdr;
uint32_t id;
uint32_t overwrite;
uint32_t size;
char data[];
};
int core_dts_eagle_set(int size, char *data);
int core_dts_eagle_get(int id, int size, char *data);
#define ADSP_CMD_SET_DOLBY_MANUFACTURER_ID 0x00012918
struct adsp_dolby_manufacturer_id {

View File

@ -133,7 +133,25 @@
#define EQ_BAND_BOOST 5
#define EQ_BAND_CUT 6
#define DTS_EAGLE_MODULE 0x00005000
#define EAGLE_DRIVER_ID 0xF2
#define DTS_EAGLE_IOCTL_GET_CACHE_SIZE _IOR(EAGLE_DRIVER_ID, 0, int)
#define DTS_EAGLE_IOCTL_SET_CACHE_SIZE _IOW(EAGLE_DRIVER_ID, 1, int)
#define DTS_EAGLE_IOCTL_GET_PARAM _IOR(EAGLE_DRIVER_ID, 2, void*)
#define DTS_EAGLE_IOCTL_SET_PARAM _IOW(EAGLE_DRIVER_ID, 3, void*)
#define DTS_EAGLE_IOCTL_SET_CACHE_BLOCK _IOW(EAGLE_DRIVER_ID, 4, void*)
#define DTS_EAGLE_IOCTL_SET_ACTIVE_DEVICE _IOW(EAGLE_DRIVER_ID, 5, void*)
#define DTS_EAGLE_IOCTL_GET_LICENSE _IOR(EAGLE_DRIVER_ID, 6, void*)
#define DTS_EAGLE_IOCTL_SET_LICENSE _IOW(EAGLE_DRIVER_ID, 7, void*)
#define DTS_EAGLE_IOCTL_SEND_LICENSE _IOW(EAGLE_DRIVER_ID, 8, int)
#define DTS_EAGLE_IOCTL_SET_VOLUME_COMMANDS _IOW(EAGLE_DRIVER_ID, 9, void*)
struct dts_eagle_param_desc {
__u32 id;
__s32 size;
__s32 offset;
__u32 device;
} __packed;
#define COMMAND_PAYLOAD_LEN 3
#define COMMAND_PAYLOAD_SZ (COMMAND_PAYLOAD_LEN * sizeof(uint32_t))

View File

@ -93,6 +93,15 @@ config DOLBY_DAP
device, end point dependent post processing parameters and
the various posrt processing parameters
config DTS_EAGLE
bool "Enable DTS Eagle Support"
depends on SND_SOC_MSM_QDSP6V2_INTF
help
To add DTS Eagle support on QDSP6 targets.
Eagle is a DTS pre/post processing
package that includes HeadphoneX. The configuration
includes sending tuning parameters of various modules.
config DTS_SRS_TM
bool "Enable DTS SRS"
depends on SND_SOC_MSM_QDSP6V2_INTF

View File

@ -7,6 +7,7 @@ snd-soc-qdsp6v2-objs += msm-dai-q6-v2.o msm-pcm-q6-v2.o msm-pcm-routing-v2.o \
msm-audio-effects-q6-v2.o msm-pcm-loopback-v2.o
obj-$(CONFIG_SND_SOC_QDSP6V2) += snd-soc-qdsp6v2.o msm-pcm-dtmf-v2.o \
msm-dai-stub-v2.o
obj-$(CONFIG_DTS_EAGLE) += msm-dts-eagle.o
obj-$(CONFIG_DOLBY_DAP) += msm-dolby-dap-config.o
obj-$(CONFIG_DTS_SRS_TM) += msm-dts-srs-tm-config.o
obj-$(CONFIG_QTI_PP) += msm-qti-pp-config.o

View File

@ -44,6 +44,7 @@
#include "msm-pcm-routing-v2.h"
#include "audio_ocmem.h"
#include "msm-audio-effects-q6-v2.h"
#include "msm-dts-eagle.h"
#define DSP_PP_BUFFERING_IN_MSEC 25
#define PARTIAL_DRAIN_ACK_EARLY_BY_MSEC 150
@ -209,6 +210,15 @@ static int msm_compr_set_volume(struct snd_compr_stream *cstream,
if (rc < 0) {
pr_err("%s: Send Volume command failed rc=%d\n",
__func__, rc);
} else {
pr_debug("%s: now calling msm_dts_eagle_set_volume\n",
__func__);
rc = msm_dts_eagle_set_volume(prtd->audio_client,
volume_l, volume_r);
if (rc < 0) {
pr_err("%s: Send Volume command failed (DTS_EAGLE) rc=%d\n",
__func__, rc);
}
}
}
@ -1909,6 +1919,10 @@ static int msm_compr_audio_effects_config_put(struct snd_kcontrol *kcontrol,
&(audio_effects->equalizer),
values);
break;
case DTS_EAGLE_MODULE:
pr_debug("%s: DTS_EAGLE_MODULE\n", __func__);
msm_dts_eagle_handler_pre(prtd->audio_client, values);
break;
default:
pr_err("%s Invalid effects config module\n", __func__);
return -EINVAL;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,102 @@
/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __MSM_DTS_EAGLE_H__
#define __MSM_DTS_EAGLE_H__
struct snd_soc_pcm_runtime;
struct msm_pcm_routing_bdai_data;
struct snd_pcm;
struct audio_client;
struct param_outband {
size_t size;
void *kvaddr;
phys_addr_t paddr;
};
#ifdef CONFIG_DTS_EAGLE
void msm_dts_ion_memmap(struct param_outband *po);
int msm_dts_eagle_handler_pre(struct audio_client *ac, long *arg);
int msm_dts_eagle_set_volume(struct audio_client *ac, int lgain, int rgain);
int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg);
int msm_dts_eagle_init_post(int port_id, int copp_id, int topology);
int msm_dts_eagle_deinit_post(int port_id, int topology);
int msm_dts_eagle_init_pre(struct audio_client *ac);
int msm_dts_eagle_deinit_pre(struct audio_client *ac);
int msm_dts_eagle_pcm_new(struct snd_soc_pcm_runtime *runtime);
void msm_dts_eagle_pcm_free(struct snd_pcm *pcm);
#else
static inline void msm_dts_ion_memmap(struct param_outband *po)
{
pr_debug("%s\n", __func__);
}
static inline int msm_dts_eagle_handler_pre(struct audio_client *ac, long *arg)
{
pr_debug("%s\n", __func__);
return -EFAULT;
}
static inline int msm_dts_eagle_set_volume(struct audio_client *ac,
int lgain, int rgain) {
pr_debug("%s\n", __func__);
return 0;
}
static inline int msm_dts_eagle_ioctl(unsigned int cmd, unsigned long arg)
{
return -EPERM;
}
static inline int msm_dts_eagle_init_post(int port_id, int coppid, int topology)
{
return 0;
}
static inline int msm_dts_eagle_deinit_post(int port_id, int topology)
{
return 0;
}
static inline int msm_dts_eagle_init_pre(struct audio_client *ac)
{
return 0;
}
static inline int msm_dts_eagle_deinit_pre(struct audio_client *ac)
{
return 0;
}
static inline int msm_dts_eagle_pcm_new(struct snd_soc_pcm_runtime *runtime)
{
pr_debug("%s\n", __func__);
return 0;
}
static inline void msm_dts_eagle_pcm_free(struct snd_pcm *pcm)
{
pr_debug("%s\n", __func__);
}
#endif
#endif

View File

@ -40,6 +40,7 @@
#include "q6voice.h"
#include "sound/q6lsm.h"
#include "audio_cal_utils.h"
#include "msm-dts-eagle.h"
static int get_cal_path(int path_type);
@ -99,6 +100,11 @@ static void msm_pcm_routing_cfg_pp(int port_id, int copp_idx, int topology,
is_custom_stereo_on) < 0)
pr_err("%s: err init dolby dap\n", __func__);
break;
case ADM_CMD_COPP_OPEN_TOPOLOGY_ID_DTS_HPX_0:
case ADM_CMD_COPP_OPEN_TOPOLOGY_ID_DTS_HPX_1:
pr_debug("%s: DTS_EAGLE_COPP_TOPOLOGY_ID\n", __func__);
msm_dts_eagle_init_post(port_id, copp_idx, topology);
break;
default:
/* custom topology specific feature param handlers */
break;
@ -116,6 +122,11 @@ static void msm_pcm_routing_deinit_pp(int port_id, int topology)
pr_debug("%s: DOLBY_ADM_COPP_TOPOLOGY_ID\n", __func__);
msm_dolby_dap_deinit(port_id);
break;
case ADM_CMD_COPP_OPEN_TOPOLOGY_ID_DTS_HPX_0:
case ADM_CMD_COPP_OPEN_TOPOLOGY_ID_DTS_HPX_1:
pr_debug("%s: DTS_EAGLE_COPP_TOPOLOGY_ID\n", __func__);
msm_dts_eagle_deinit_post(port_id, topology);
break;
default:
/* custom topology specific feature deinit handlers */
break;

View File

@ -24,6 +24,9 @@
#include <sound/q6afe-v2.h>
#include "audio_cal_utils.h"
#include <sound/asound.h>
#include "msm-dts-eagle.h"
#define TIMEOUT_MS 1000
#define RESET_COPP_ID 99
@ -35,12 +38,15 @@
#define ULL_SUPPORTED_BITS_PER_SAMPLE 16
#define ULL_SUPPORTED_SAMPLE_RATE 48000
#define CMD_GET_HDR_SZ 16
enum {
ADM_CUSTOM_TOP_CAL = 0,
ADM_AUDPROC_CAL,
ADM_AUDVOL_CAL,
ADM_RTAC_INFO_CAL,
ADM_RTAC_APR_CAL,
ADM_DTS_EAGLE,
ADM_MAX_CAL_TYPES
};
@ -73,6 +79,8 @@ struct adm_ctl {
atomic_t mem_map_cal_handles[ADM_MAX_CAL_TYPES];
atomic_t mem_map_cal_index;
struct param_outband outband_memmap;
int set_custom_topology;
int ec_ref_rx;
};
@ -222,6 +230,162 @@ static int adm_get_next_available_copp(int port_idx)
return idx;
}
int adm_dts_eagle_set(int port_id, int copp_idx, int param_id,
void *data, int size)
{
struct adm_cmd_set_pp_params_v5 admp;
int p_idx, ret = 0, *update_params_value;
pr_debug("DTS_EAGLE_ADM - %s: port id %i, copp idx %i, param id 0x%X\n",
__func__, port_id, copp_idx, param_id);
port_id = afe_convert_virtual_to_portid(port_id);
p_idx = adm_validate_and_get_port_index(port_id);
pr_debug("DTS_EAGLE_ADM - %s: after lookup, port id %i, port idx %i\n",
__func__, port_id, p_idx);
if (p_idx < 0) {
pr_err("DTS_EAGLE_ADM - %s: invalid port index %i, port id %i, copp idx %i\n",
__func__, p_idx, port_id, copp_idx);
return -EINVAL;
}
update_params_value = (int *)this_adm.outband_memmap.kvaddr;
if (update_params_value == NULL) {
pr_err("DTS_EAGLE_ADM - %s: NULL memmap. Non Eagle topology selected?\n",
__func__);
ret = -EINVAL;
goto fail_cmd;
}
*update_params_value++ = AUDPROC_MODULE_ID_DTS_HPX_POSTMIX;
*update_params_value++ = param_id;
*update_params_value++ = size;
memcpy(update_params_value, data, size);
admp.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
admp.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, sizeof(admp));
admp.hdr.src_svc = APR_SVC_ADM;
admp.hdr.src_domain = APR_DOMAIN_APPS;
admp.hdr.src_port = port_id;
admp.hdr.dest_svc = APR_SVC_ADM;
admp.hdr.dest_domain = APR_DOMAIN_ADSP;
admp.hdr.dest_port = atomic_read(&this_adm.copp.id[p_idx][copp_idx]);
admp.hdr.token = p_idx << 16 | copp_idx;
admp.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5;
admp.payload_addr_lsw = lower_32_bits(this_adm.outband_memmap.paddr);
admp.payload_addr_msw = upper_32_bits(this_adm.outband_memmap.paddr);
admp.mem_map_handle = atomic_read(&this_adm.mem_map_cal_handles[
atomic_read(&this_adm.mem_map_cal_index)]);
admp.payload_size = size + 12 /*see update_params_value header above*/;
pr_debug("DTS_EAGLE_ADM - %s: Command was sent now check Q6 - port id = %d, size %d, module id %x, param id %x.\n",
__func__, admp.hdr.dest_port,
admp.payload_size, AUDPROC_MODULE_ID_DTS_HPX_POSTMIX,
param_id);
ret = apr_send_pkt(this_adm.apr, (uint32_t *)&admp);
if (ret < 0) {
pr_err("DTS_EAGLE_ADM - %s: ADM enable for port %d failed\n",
__func__, port_id);
ret = -EINVAL;
goto fail_cmd;
}
ret = wait_event_timeout(this_adm.copp.wait[p_idx][copp_idx], 1,
msecs_to_jiffies(TIMEOUT_MS));
if (!ret) {
pr_err("DTS_EAGLE_ADM - %s: set params timed out port = %d\n",
__func__, port_id);
ret = -EINVAL;
}
fail_cmd:
return ret;
}
int adm_dts_eagle_get(int port_id, int copp_idx, int param_id,
void *data, int size)
{
struct adm_cmd_get_pp_params_v5 *admp = NULL;
int p_idx, sz, ret = 0, orig_size = size;
pr_debug("DTS_EAGLE_ADM - %s: port id %i, copp idx %i, param id 0x%X\n",
__func__, port_id, copp_idx, param_id);
port_id = afe_convert_virtual_to_portid(port_id);
p_idx = adm_validate_and_get_port_index(port_id);
if (p_idx < 0) {
pr_err("DTS_EAGLE_ADM - %s: invalid port index %i, port id %i, copp idx %i\n",
__func__, p_idx, port_id, copp_idx);
return -EINVAL;
}
if (size <= 0 || !data) {
pr_err("DTS_EAGLE_ADM - %s: invalid size %i or pointer %p.\n",
__func__, size, data);
return -EINVAL;
}
size = (size+3) & 0xFFFFFFFC;
sz = sizeof(struct adm_cmd_get_pp_params_v5) + size + CMD_GET_HDR_SZ;
admp = kzalloc(sz, GFP_KERNEL);
if (!admp) {
pr_err("DTS_EAGLE_ADM - %s, adm params memory alloc failed",
__func__);
return -ENOMEM;
}
admp->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
admp->hdr.pkt_size = sz;
admp->hdr.src_svc = APR_SVC_ADM;
admp->hdr.src_domain = APR_DOMAIN_APPS;
admp->hdr.src_port = port_id;
admp->hdr.dest_svc = APR_SVC_ADM;
admp->hdr.dest_domain = APR_DOMAIN_ADSP;
admp->hdr.dest_port = atomic_read(&this_adm.copp.id[p_idx][copp_idx]);
admp->hdr.token = p_idx << 16 | copp_idx;
admp->hdr.opcode = ADM_CMD_GET_PP_PARAMS_V5;
admp->data_payload_addr_lsw = 0;
admp->data_payload_addr_msw = 0;
admp->mem_map_handle = 0;
admp->module_id = AUDPROC_MODULE_ID_DTS_HPX_POSTMIX;
admp->param_id = param_id;
admp->param_max_size = size + CMD_GET_HDR_SZ;
admp->reserved = 0;
ret = apr_send_pkt(this_adm.apr, (uint32_t *)admp);
if (ret < 0) {
pr_err("DTS_EAGLE_ADM - %s: Failed to get EAGLE Params on port %d\n",
__func__, port_id);
ret = -EINVAL;
goto fail_cmd;
}
ret = wait_event_timeout(this_adm.copp.wait[p_idx][copp_idx], 1,
msecs_to_jiffies(TIMEOUT_MS));
if (!ret) {
pr_err("DTS_EAGLE_ADM - %s: EAGLE get params timed out port = %d\n",
__func__, port_id);
ret = -EINVAL;
goto fail_cmd;
}
if (adm_get_parameters[0] > 0 &&
(adm_get_parameters[0] * sizeof(int)) == orig_size) {
ret = 0;
memcpy(data, &adm_get_parameters[1], orig_size);
} else {
ret = -EINVAL;
pr_err("DTS_EAGLE_ADM - %s: EAGLE get params problem getting data, size was %zu, expected was %i - check callback error value",
__func__, (adm_get_parameters[0] * sizeof(int)),
orig_size);
}
fail_cmd:
kfree(admp);
return ret;
}
int srs_trumedia_open(int port_id, int copp_idx, int srs_tech_id,
void *srs_params)
{
@ -1486,6 +1650,18 @@ int adm_open(int port_id, int path, int rate, int channel_mode,
}
}
if ((topology == ADM_CMD_COPP_OPEN_TOPOLOGY_ID_DTS_HPX_0 ||
topology == ADM_CMD_COPP_OPEN_TOPOLOGY_ID_DTS_HPX_1) &&
!perf_mode) {
int res;
atomic_set(&this_adm.mem_map_cal_index, ADM_DTS_EAGLE);
msm_dts_ion_memmap(&this_adm.outband_memmap);
res = adm_memory_map_regions(&this_adm.outband_memmap.paddr, 0,
(uint32_t *)&this_adm.outband_memmap.size, 1);
if (res < 0)
pr_err("%s: DTS_EAGLE mmap did not work!", __func__);
}
/* Create a COPP if port id are not enabled */
if (atomic_read(&this_adm.copp.cnt[port_idx][copp_idx]) == 0) {
pr_debug("%s: open ADM: port_idx: %d, copp_idx: %d\n", __func__,
@ -1684,6 +1860,13 @@ int adm_matrix_map(int path, struct route_payload payload_map, int perf_mode)
for (i = 0; i < payload_map.num_copps; i++) {
port_idx = afe_get_port_index(payload_map.port_id[i]);
copp_idx = payload_map.copp_idx[i];
if ((atomic_read(
&this_adm.copp.topology[port_idx][copp_idx]) !=
ADM_CMD_COPP_OPEN_TOPOLOGY_ID_DTS_HPX_0) ||
(atomic_read(
&this_adm.copp.topology[port_idx][copp_idx]) !=
ADM_CMD_COPP_OPEN_TOPOLOGY_ID_DTS_HPX_1))
continue;
rtac_add_adm_device(payload_map.port_id[i],
atomic_read(&this_adm.copp.id
[port_idx][copp_idx]),
@ -1738,6 +1921,18 @@ int adm_close(int port_id, int perf_mode, int copp_idx)
pr_debug("%s: Closing ADM port_idx:%d copp_idx:%d copp_id:0x%x\n",
__func__, port_idx, copp_idx, copp_id);
if ((!perf_mode) && (this_adm.outband_memmap.paddr != 0)) {
atomic_set(&this_adm.mem_map_cal_index, ADM_DTS_EAGLE);
ret = adm_memory_unmap_regions();
if (ret < 0) {
pr_err("%s: adm mem unmmap err %d",
__func__, ret);
} else {
atomic_set(&this_adm.mem_map_cal_handles
[ADM_DTS_EAGLE], 0);
}
}
close.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
APR_HDR_LEN(APR_HDR_SIZE),
APR_PKT_VER);

View File

@ -43,6 +43,8 @@
#define TRUE 0x01
#define FALSE 0x00
#define CMD_GET_HDR_SZ 16
enum {
ASM_TOPOLOGY_CAL = 0,
ASM_CUSTOM_TOP_CAL,
@ -94,6 +96,13 @@ static struct audio_client common_client;
static int set_custom_topology;
static int topology_map_handle;
struct generic_get_data_ {
int valid;
int size_in_ints;
int ints[];
};
static struct generic_get_data_ *generic_get_data;
#ifdef CONFIG_DEBUG_FS
#define OUT_BUFFER_SIZE 56
#define IN_BUFFER_SIZE 24
@ -1519,9 +1528,21 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
}
case ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2:
pr_debug("%s: ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2\n", __func__);
if (payload[0] != 0)
pr_err("%s: ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 returned error = 0x%x\n",
__func__, payload[0]);
if (payload[0] != 0) {
pr_err("%s: ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 returned error = 0x%x\n",
__func__, payload[0]);
} else if (generic_get_data) {
generic_get_data->valid = 1;
generic_get_data->size_in_ints = payload[3];
for (i = 0; i < generic_get_data->size_in_ints; i++)
generic_get_data->ints[i] = payload[4+i];
pr_debug("DTS_EAGLE_ASM callback size in ints = %i\n",
generic_get_data->size_in_ints);
atomic_set(&ac->cmd_state, 0);
wake_up(&ac->cmd_wait);
break;
}
rtac_make_asm_callback(ac->session, payload,
data->payload_size);
break;
@ -2001,6 +2022,10 @@ static int __q6asm_open_write(struct audio_client *ac, uint32_t format,
open.postprocopo_id = q6asm_get_asm_topology();
/* For DTS EAGLE only, force 24 bit */
if (open.postprocopo_id == ASM_STREAM_POSTPROC_TOPO_ID_DTS_HPX)
open.bits_per_sample = 24;
switch (format) {
case FORMAT_LINEAR_PCM:
open.dec_fmt_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2;
@ -3867,6 +3892,129 @@ fail_cmd:
return rc;
}
int q6asm_dts_eagle_set(struct audio_client *ac, int param_id, int size,
void *data)
{
int sz = sizeof(struct asm_dts_eagle_param) + size, rc = 0;
struct asm_dts_eagle_param *ad = kzalloc(sz, GFP_KERNEL);
if (!ad) {
pr_err("DTS_EAGLE_ASM - %s: error allocating mem of size %i\n",
__func__, sz);
return -ENOMEM;
}
if (!ac || ac->apr == NULL || size <= 0 || !data) {
pr_err("DTS_EAGLE_ASM - %s: APR handle NULL, invalid size %i or pointer %p.\n",
__func__, size, data);
return -EINVAL;
}
q6asm_add_hdr_async(ac, &ad->hdr, sz, 1);
ad->hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2;
ad->param.data_payload_addr_lsw = 0;
ad->param.data_payload_addr_msw = 0;
ad->param.mem_map_handle = 0;
ad->param.data_payload_size = size +
sizeof(struct asm_stream_param_data_v2);
ad->data.module_id = AUDPROC_MODULE_ID_DTS_HPX_PREMIX;
ad->data.param_id = param_id;
ad->data.param_size = size;
ad->data.reserved = 0;
atomic_set(&ac->cmd_state, 1);
memcpy(((char *)ad) + sizeof(struct asm_dts_eagle_param), data, size);
rc = apr_send_pkt(ac->apr, (uint32_t *)ad);
if (rc < 0) {
pr_err("DTS_EAGLE_ASM - %s: set-params send failed paramid[0x%x]\n",
__func__, ad->data.param_id);
rc = -EINVAL;
goto fail_cmd;
}
rc = wait_event_timeout(ac->cmd_wait,
(atomic_read(&ac->cmd_state) == 0), 1*HZ);
if (!rc) {
pr_err("DTS_EAGLE_ASM - %s: timeout, set-params paramid[0x%x]\n",
__func__, ad->data.param_id);
rc = -EINVAL;
goto fail_cmd;
}
rc = 0;
fail_cmd:
kfree(ad);
return rc;
}
int q6asm_dts_eagle_get(struct audio_client *ac, int param_id, int size,
void *data)
{
struct asm_dts_eagle_param_get *ad;
int rc = 0, sz;
if (!ac || ac->apr == NULL || size <= 0 || !data) {
pr_err("DTS_EAGLE_ASM - %s: APR handle NULL, invalid size %i or pointer %p.\n",
__func__, size, data);
return -EINVAL;
}
sz = sizeof(struct asm_dts_eagle_param_get) + CMD_GET_HDR_SZ + size;
ad = kzalloc(sz, GFP_KERNEL);
if (!ad) {
pr_err("DTS_EAGLE_ASM - %s: error allocating memory of size %i\n",
__func__, sz);
return -ENOMEM;
}
q6asm_add_hdr(ac, &ad->hdr, sz, TRUE);
ad->hdr.opcode = ASM_STREAM_CMD_GET_PP_PARAMS_V2;
ad->param.data_payload_addr_lsw = 0;
ad->param.data_payload_addr_msw = 0;
ad->param.mem_map_handle = 0;
ad->param.module_id = AUDPROC_MODULE_ID_DTS_HPX_PREMIX;
ad->param.param_id = param_id;
ad->param.param_max_size = size + CMD_GET_HDR_SZ;
ad->param.reserved = 0;
atomic_set(&ac->cmd_state, 1);
generic_get_data = kzalloc(size + sizeof(struct generic_get_data_),
GFP_KERNEL);
if (!generic_get_data) {
pr_err("DTS_EAGLE_ASM - %s: error allocating mem of size %i\n",
__func__, size);
rc = -ENOMEM;
goto fail_cmd;
}
rc = apr_send_pkt(ac->apr, (uint32_t *)ad);
if (rc < 0) {
pr_err("DTS_EAGLE_ASM - %s: Commmand 0x%x failed\n",
__func__, ad->hdr.opcode);
goto fail_cmd;
}
rc = wait_event_timeout(ac->cmd_wait,
(atomic_read(&ac->cmd_state) == 0), 1*HZ);
if (!rc) {
pr_err("DTS_EAGLE_ASM - %s: timeout in getting session time from DSP\n",
__func__);
rc = -EINVAL;
goto fail_cmd;
}
if (generic_get_data->valid) {
rc = 0;
memcpy(data, generic_get_data->ints, size);
} else {
rc = -EINVAL;
pr_err("DTS_EAGLE_ASM - %s: EAGLE get params problem getting data - check callback error value\n",
__func__);
}
fail_cmd:
kfree(ad);
kfree(generic_get_data);
generic_get_data = NULL;
return rc;
}
int q6asm_set_volume(struct audio_client *ac, int volume)
{
struct asm_volume_ctrl_master_gain vol;

View File

@ -60,6 +60,13 @@ struct q6core_str {
static struct q6core_str q6core_lcl;
struct generic_get_data_ {
int valid;
int size_in_ints;
int ints[];
};
static struct generic_get_data_ *generic_get_data;
static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv)
{
uint32_t *payload1;
@ -158,13 +165,24 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv)
default:
pr_err("%s: Message id from adsp core svc: 0x%x\n",
__func__, data->opcode);
if (generic_get_data) {
generic_get_data->valid = 1;
generic_get_data->size_in_ints =
data->payload_size/sizeof(int);
pr_debug("DTS_EAGLE_CORE callback size = %i\n",
data->payload_size);
memcpy(generic_get_data->ints, data->payload,
data->payload_size);
q6core_lcl.bus_bw_resp_received = 1;
wake_up(&q6core_lcl.bus_bw_req_wait);
break;
}
break;
}
return 0;
}
void ocm_core_open(void)
{
if (q6core_lcl.core_handle_q == NULL)
@ -315,6 +333,115 @@ fail_cmd:
return ret;
}
int core_dts_eagle_set(int size, char *data)
{
struct adsp_dts_eagle *payload = NULL;
int rc = 0, size_aligned4byte;
pr_debug("DTS_EAGLE_CORE - %s\n", __func__);
if (size <= 0 || !data) {
pr_err("DTS_EAGLE_CORE - %s: invalid size %i or pointer %p.\n",
__func__, size, data);
return -EINVAL;
}
size_aligned4byte = (size+3) & 0xFFFFFFFC;
ocm_core_open();
if (q6core_lcl.core_handle_q) {
payload = kzalloc(sizeof(struct adsp_dts_eagle) +
size_aligned4byte, GFP_KERNEL);
if (!payload) {
pr_err("DTS_EAGLE_CORE - %s: out of memory (aligned size %i).\n",
__func__, size_aligned4byte);
return -ENOMEM;
}
payload->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_EVENT,
APR_HDR_LEN(APR_HDR_SIZE),
APR_PKT_VER);
payload->hdr.pkt_size = sizeof(struct adsp_dts_eagle) +
size_aligned4byte;
payload->hdr.src_port = 0;
payload->hdr.dest_port = 0;
payload->hdr.token = 0;
payload->hdr.opcode = ADSP_CMD_SET_DTS_EAGLE_DATA_ID;
payload->id = DTS_EAGLE_LICENSE_ID;
payload->overwrite = 1;
payload->size = size;
memcpy(payload->data, data, size);
rc = apr_send_pkt(q6core_lcl.core_handle_q,
(uint32_t *)payload);
if (rc < 0) {
pr_err("DTS_EAGLE_CORE - %s: failed op[0x%x]rc[%d]\n",
__func__, payload->hdr.opcode, rc);
}
kfree(payload);
}
return rc;
}
int core_dts_eagle_get(int id, int size, char *data)
{
struct apr_hdr ah;
int rc = 0;
pr_debug("DTS_EAGLE_CORE - %s\n", __func__);
if (size <= 0 || !data) {
pr_err("DTS_EAGLE_CORE - %s: invalid size %i or pointer %p.\n",
__func__, size, data);
return -EINVAL;
}
ocm_core_open();
if (q6core_lcl.core_handle_q) {
ah.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_EVENT,
APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
ah.pkt_size = sizeof(struct apr_hdr);
ah.src_port = 0;
ah.dest_port = 0;
ah.token = 0;
ah.opcode = id;
q6core_lcl.bus_bw_resp_received = 0;
generic_get_data = kzalloc(sizeof(struct generic_get_data_)
+ size, GFP_KERNEL);
if (!generic_get_data) {
pr_err("DTS_EAGLE_CORE - %s: error allocating memory of size %i\n",
__func__, size);
return -ENOMEM;
}
rc = apr_send_pkt(q6core_lcl.core_handle_q,
(uint32_t *)&ah);
if (rc < 0) {
pr_err("DTS_EAGLE_CORE - %s: failed op[0x%x]rc[%d]\n",
__func__, ah.opcode, rc);
goto fail_cmd_2;
}
rc = wait_event_timeout(q6core_lcl.bus_bw_req_wait,
(q6core_lcl.bus_bw_resp_received == 1),
msecs_to_jiffies(TIMEOUT_MS));
if (!rc) {
pr_err("DTS_EAGLE_CORE - %s: EAGLE get params timed out\n",
__func__);
rc = -EINVAL;
goto fail_cmd_2;
}
if (generic_get_data->valid) {
rc = 0;
memcpy(data, generic_get_data->ints, size);
} else {
rc = -EINVAL;
pr_err("DTS_EAGLE_CORE - %s: EAGLE get params problem getting data - check callback error value\n",
__func__);
}
}
fail_cmd_2:
kfree(generic_get_data);
generic_get_data = NULL;
return rc;
}
uint32_t core_set_dolby_manufacturer_id(int manufacturer_id)
{
struct adsp_dolby_manufacturer_id payload;