dsp: afe: Add support for VAD in AFE native driver

Update to AFE native driver to send VAD calibration
to DSP. Add support for per service API version query
in q6core driver.

Change-Id: I6234879054e7b5622a40912da16072fd8dbd83fe
Signed-off-by: Mangesh Kunchamwar <mangeshk@codeaurora.org>
This commit is contained in:
Mangesh Kunchamwar 2018-04-26 17:58:58 +05:30
parent cd74176d75
commit 4e1e71885e
9 changed files with 658 additions and 3 deletions

View file

@ -92,11 +92,16 @@ ifdef CONFIG_SND_SOC_MSM_QDSP6V2_INTF
Q6_OBJS += msm_audio_ion.o
Q6_OBJS += avtimer.o
Q6_OBJS += q6_init.o
endif
ifdef CONFIG_DTS_SRS_TM
Q6_OBJS += msm-dts-srs-tm-config.o
endif
ifdef CONFIG_AFE_HWDEP
Q6_OBJS += q6afecal-hwdep.o
endif
ifdef CONFIG_MSM_ADSP_LOADER
ADSP_LOADER_OBJS += adsp-loader.o
endif

View file

@ -28,6 +28,7 @@
#include <dsp/msm-audio-event-notify.h>
#include <ipc/apr_tal.h>
#include "adsp_err.h"
#include "q6afecal-hwdep.h"
#define WAKELOCK_TIMEOUT 5000
enum {
@ -126,6 +127,10 @@ struct afe_ctl {
int dev_acdb_id[AFE_MAX_PORTS];
routing_cb rt_cb;
struct audio_uevent_data *uevent_data;
/* cal info for AFE */
struct afe_fw_info *fw_data;
u32 island_mode[AFE_MAX_PORTS];
struct vad_config vad_cfg[AFE_MAX_PORTS];
};
static atomic_t afe_ports_mad_type[SLIMBUS_PORT_LAST - SLIMBUS_0_RX];
@ -1810,6 +1815,148 @@ static int afe_send_port_topology_id(u16 port_id)
}
static int afe_get_island_mode(u16 port_id, u32 *island_mode)
{
int ret = 0;
int index = 0;
*island_mode = 0;
index = q6audio_get_port_index(port_id);
if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
}
*island_mode = this_afe.island_mode[index];
return ret;
}
/*
* afe_send_port_island_mode -
* for sending island mode to AFE
*
* @port_id: AFE port id number
*
* Returns 0 on success or error on failure.
*/
int afe_send_port_island_mode(u16 port_id)
{
struct afe_param_id_island_cfg_t island_cfg;
struct param_hdr_v3 param_info;
u32 island_mode = 0;
int ret = 0;
memset(&island_cfg, 0, sizeof(island_cfg));
memset(&param_info, 0, sizeof(param_info));
ret = afe_get_island_mode(port_id, &island_mode);
if (ret) {
pr_err("%s: AFE port[%d] get island mode is invalid!\n",
__func__, port_id);
return ret;
}
param_info.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
param_info.instance_id = INSTANCE_ID_0;
param_info.param_id = AFE_PARAM_ID_ISLAND_CONFIG;
param_info.param_size = sizeof(island_cfg);
island_cfg.island_cfg_minor_version = AFE_API_VERSION_ISLAND_CONFIG;
island_cfg.island_enable = island_mode;
ret = q6afe_pack_and_set_param_in_band(port_id,
q6audio_get_port_index(port_id),
param_info, (u8 *) &island_cfg);
if (ret) {
pr_err("%s: AFE set island mode enable for port 0x%x failed %d\n",
__func__, port_id, ret);
return ret;
}
pr_debug("%s: AFE set island mode 0x%x enable for port 0x%x ret %d\n",
__func__, island_mode, port_id, ret);
return ret;
}
EXPORT_SYMBOL(afe_send_port_island_mode);
static int afe_get_vad_preroll_cfg(u16 port_id, u32 *preroll_cfg)
{
int ret = 0;
int index = 0;
*preroll_cfg = 0;
index = q6audio_get_port_index(port_id);
if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
__func__, index);
return -EINVAL;
}
*preroll_cfg = this_afe.vad_cfg[index].pre_roll;
return ret;
}
static int afe_send_port_vad_cfg_params(u16 port_id)
{
struct afe_param_id_vad_cfg_t vad_cfg;
struct param_hdr_v3 param_info;
u32 pre_roll_cfg = 0;
struct firmware_cal *hwdep_cal = NULL;
int ret = 0;
memset(&vad_cfg, 0, sizeof(vad_cfg));
memset(&param_info, 0, sizeof(param_info));
ret = afe_get_vad_preroll_cfg(port_id, &pre_roll_cfg);
if (ret) {
pr_err("%s: AFE port[%d] get preroll cfg is invalid!\n",
__func__, port_id);
return ret;
}
param_info.module_id = AFE_MODULE_VAD;
param_info.instance_id = INSTANCE_ID_0;
param_info.param_id = AFE_PARAM_ID_VAD_CFG;
param_info.param_size = sizeof(vad_cfg);
vad_cfg.vad_cfg_minor_version = AFE_API_VERSION_VAD_CFG;
vad_cfg.pre_roll_in_ms = pre_roll_cfg;
ret = q6afe_pack_and_set_param_in_band(port_id,
q6audio_get_port_index(port_id),
param_info, (u8 *) &vad_cfg);
if (ret) {
pr_err("%s: AFE set vad cfg for port 0x%x failed %d\n",
__func__, port_id, ret);
return ret;
}
memset(&param_info, 0, sizeof(param_info));
hwdep_cal = q6afecal_get_fw_cal(this_afe.fw_data, Q6AFE_VAD_CORE_CAL);
if (!hwdep_cal) {
pr_err("%s: error in retrieving vad core calibration",
__func__);
return -EINVAL;
}
param_info.module_id = AFE_MODULE_VAD;
param_info.instance_id = INSTANCE_ID_0;
param_info.param_id = AFE_PARAM_ID_VAD_CORE_CFG;
param_info.param_size = hwdep_cal->size;
ret = q6afe_pack_and_set_param_in_band(port_id,
q6audio_get_port_index(port_id),
param_info, (u8 *) hwdep_cal->data);
if (ret) {
pr_err("%s: AFE set vad cfg for port 0x%x failed %d\n",
__func__, port_id, ret);
return ret;
}
pr_debug("%s: AFE set preroll cfg %d vad core cfg port 0x%x ret %d\n",
__func__, pre_roll_cfg, port_id, ret);
return ret;
}
static int remap_cal_data(struct cal_block_data *cal_block, int cal_index)
{
int ret = 0;
@ -2804,6 +2951,44 @@ void afe_set_cal_mode(u16 port_id, enum afe_cal_mode afe_cal_mode)
}
EXPORT_SYMBOL(afe_set_cal_mode);
/**
* afe_set_vad_cfg -
* set configuration for VAD
*
* @port_id: AFE port id number
* @vad_enable: enable/disable vad
* @preroll_config: Preroll configuration
*
*/
void afe_set_vad_cfg(u32 vad_enable, u32 preroll_config,
u32 port_id)
{
uint16_t port_index;
port_index = afe_get_port_index(port_id);
this_afe.vad_cfg[port_index].is_enable = vad_enable;
this_afe.vad_cfg[port_index].pre_roll = preroll_config;
}
EXPORT_SYMBOL(afe_set_vad_cfg);
/**
* afe_set_island_mode_cfg -
* set island mode configuration
*
* @port_id: AFE port id number
* @enable_flag: Enable or Disable
*
*/
void afe_set_island_mode_cfg(u16 port_id, u32 enable_flag)
{
uint16_t port_index;
port_index = afe_get_port_index(port_id);
this_afe.island_mode[port_index] = enable_flag;
}
EXPORT_SYMBOL(afe_set_island_mode_cfg);
/**
* afe_set_routing_callback -
* Update callback function for routing
@ -3245,8 +3430,21 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config,
}
mutex_lock(&this_afe.afe_cmd_lock);
/* Also send the topology id here: */
port_index = afe_get_port_index(port_id);
if (q6core_get_avcs_api_version_per_service(
APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) {
/* send VAD configuration if is enabled */
if (this_afe.vad_cfg[port_index].is_enable) {
ret = afe_send_port_vad_cfg_params(port_id);
if (ret)
pr_err("%s: afe send VAD config failed %d\n",
__func__, ret);
goto fail_cmd;
}
}
/* Also send the topology id here: */
if (!(this_afe.afe_cal_mode[port_index] == AFE_CAL_MODE_NONE)) {
/* One time call: only for first time */
afe_send_custom_topology();
@ -7354,6 +7552,9 @@ int __init afe_init(void)
this_afe.afe_cal_mode[i] = AFE_CAL_MODE_DEFAULT;
this_afe.afe_sample_rates[i] = 0;
this_afe.dev_acdb_id[i] = 0;
this_afe.island_mode[i] = 0;
this_afe.vad_cfg[i].is_enable = 0;
this_afe.vad_cfg[i].pre_roll = 0;
init_waitqueue_head(&this_afe.wait[i]);
}
wakeup_source_init(&wl.ws, "spkr-prot");
@ -7394,3 +7595,29 @@ void afe_exit(void)
mutex_destroy(&this_afe.afe_cmd_lock);
wakeup_source_trash(&wl.ws);
}
/*
* afe_cal_init_hwdep -
* Initiliaze AFE HW dependent Node
*
* @card: pointer to sound card
*
*/
int afe_cal_init_hwdep(void *card)
{
int ret = 0;
this_afe.fw_data = kzalloc(sizeof(*(this_afe.fw_data)),
GFP_KERNEL);
if (!this_afe.fw_data)
return -ENOMEM;
set_bit(Q6AFE_VAD_CORE_CAL, this_afe.fw_data->cal_bit);
ret = q6afe_cal_create_hwdep(this_afe.fw_data, Q6AFE_HWDEP_NODE, card);
if (ret < 0) {
pr_err("%s: couldn't create hwdep for AFE %d\n", __func__, ret);
return ret;
}
return ret;
}
EXPORT_SYMBOL(afe_cal_init_hwdep);

235
dsp/q6afecal-hwdep.c Normal file
View file

@ -0,0 +1,235 @@
/*
* Copyright (c) 2015, 2017 - 2018 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.
*
*/
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/ioctl.h>
#include <sound/hwdep.h>
#include <sound/msmcal-hwdep.h>
#include <sound/soc.h>
#include "q6afecal-hwdep.h"
const int cal_size_info[Q6AFE_MAX_CAL] = {
[Q6AFE_VAD_CORE_CAL] = 132,
};
const char *cal_name_info[Q6AFE_MAX_CAL] = {
[Q6AFE_VAD_CORE_CAL] = "vad_core",
};
#define AFE_HW_NAME_LENGTH 40
/*
* q6afecal_get_fw_cal -
* To get calibration from AFE HW dependent node
*
* @fw_data: pointer to firmware data
* type: AFE calibration type
*
*/
struct firmware_cal *q6afecal_get_fw_cal(struct afe_fw_info *fw_data,
enum q6afe_cal_type type)
{
if (!fw_data) {
pr_err("%s: fw_data is NULL\n", __func__);
return NULL;
}
if (type >= Q6AFE_MAX_CAL ||
type < Q6AFE_MIN_CAL) {
pr_err("%s: wrong cal type sent %d\n", __func__, type);
return NULL;
}
mutex_lock(&fw_data->lock);
if (!test_bit(Q6AFECAL_RECEIVED,
&fw_data->q6afecal_state[type])) {
pr_err("%s: cal not sent by userspace %d\n",
__func__, type);
mutex_unlock(&fw_data->lock);
return NULL;
}
set_bit(Q6AFECAL_INITIALISED, &fw_data->q6afecal_state[type]);
mutex_unlock(&fw_data->lock);
return fw_data->fw[type];
}
EXPORT_SYMBOL(q6afecal_get_fw_cal);
static int q6afecal_hwdep_ioctl_shared(struct snd_hwdep *hw,
struct q6afecal_ioctl_buffer fw_user)
{
struct afe_fw_info *fw_data = hw->private_data;
struct firmware_cal **fw = fw_data->fw;
void *data;
if (!test_bit(fw_user.cal_type, fw_data->cal_bit)) {
pr_err("%s: q6afe didn't set this %d!!\n",
__func__, fw_user.cal_type);
return -EFAULT;
}
if (fw_user.cal_type >= Q6AFE_MAX_CAL ||
fw_user.cal_type < Q6AFE_MIN_CAL) {
pr_err("%s: wrong cal type sent %d\n",
__func__, fw_user.cal_type);
return -EFAULT;
}
if (fw_user.size > cal_size_info[fw_user.cal_type] ||
fw_user.size <= 0) {
pr_err("%s: incorrect firmware size %d for %s\n",
__func__, fw_user.size,
cal_name_info[fw_user.cal_type]);
return -EFAULT;
}
data = fw[fw_user.cal_type]->data;
if (copy_from_user(data, fw_user.buffer, fw_user.size))
return -EFAULT;
fw[fw_user.cal_type]->size = fw_user.size;
mutex_lock(&fw_data->lock);
set_bit(Q6AFECAL_RECEIVED, &fw_data->q6afecal_state[fw_user.cal_type]);
mutex_unlock(&fw_data->lock);
return 0;
}
#ifdef CONFIG_COMPAT
struct q6afecal_ioctl_buffer32 {
u32 size;
compat_uptr_t buffer;
enum q6afe_cal_type cal_type;
};
enum {
SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE32 =
_IOW('U', 0x1, struct q6afecal_ioctl_buffer32),
};
static int q6afecal_hwdep_ioctl_compat(struct snd_hwdep *hw, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct q6afecal_ioctl_buffer __user *argp = (void __user *)arg;
struct q6afecal_ioctl_buffer32 fw_user32;
struct q6afecal_ioctl_buffer fw_user_compat;
if (cmd != SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE32) {
pr_err("%s: wrong ioctl command sent %u!\n", __func__, cmd);
return -ENOIOCTLCMD;
}
if (copy_from_user(&fw_user32, argp, sizeof(fw_user32))) {
pr_err("%s: failed to copy\n", __func__);
return -EFAULT;
}
fw_user_compat.size = fw_user32.size;
fw_user_compat.buffer = compat_ptr(fw_user32.buffer);
fw_user_compat.cal_type = fw_user32.cal_type;
return q6afecal_hwdep_ioctl_shared(hw, fw_user_compat);
}
#else
#define q6afecal_hwdep_ioctl_compat NULL
#endif
static int q6afecal_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct q6afecal_ioctl_buffer __user *argp = (void __user *)arg;
struct q6afecal_ioctl_buffer fw_user;
if (cmd != SNDRV_IOCTL_HWDEP_VAD_CAL_TYPE) {
pr_err("%s: wrong ioctl command sent %d!\n", __func__, cmd);
return -ENOIOCTLCMD;
}
if (copy_from_user(&fw_user, argp, sizeof(fw_user))) {
pr_err("%s: failed to copy\n", __func__);
return -EFAULT;
}
return q6afecal_hwdep_ioctl_shared(hw, fw_user);
}
static int q6afecal_hwdep_release(struct snd_hwdep *hw, struct file *file)
{
struct afe_fw_info *fw_data = hw->private_data;
mutex_lock(&fw_data->lock);
/* clear all the calibrations */
memset(fw_data->q6afecal_state, 0,
sizeof(fw_data->q6afecal_state));
mutex_unlock(&fw_data->lock);
return 0;
}
/**
* q6afe_cal_create_hwdep -
* for creating HW dependent node for AFE
*
* @data: Pointer to hold fw data
* @node: node type
* @card: Pointer to sound card
*
*/
int q6afe_cal_create_hwdep(void *data, int node, void *card)
{
char hwname[AFE_HW_NAME_LENGTH];
struct snd_hwdep *hwdep;
struct firmware_cal **fw;
struct afe_fw_info *fw_data = data;
int err, cal_bit;
if (!fw_data || !card) {
pr_err("%s: Invalid parameters\n", __func__);
return -EINVAL;
}
fw = fw_data->fw;
snprintf(hwname, strlen("Q6AFE"), "Q6AFE");
err = snd_hwdep_new(((struct snd_soc_card *)card)->snd_card,
hwname, node, &hwdep);
if (err < 0) {
pr_err("%s: new hwdep for q6afe failed %d\n", __func__, err);
return err;
}
snprintf(hwdep->name, strlen("Q6AFECAL"), "Q6AFECAL");
hwdep->iface = SNDRV_HWDEP_IFACE_AUDIO_BE;
hwdep->private_data = fw_data;
hwdep->ops.ioctl_compat = q6afecal_hwdep_ioctl_compat;
hwdep->ops.ioctl = q6afecal_hwdep_ioctl;
hwdep->ops.release = q6afecal_hwdep_release;
mutex_init(&fw_data->lock);
for_each_set_bit(cal_bit, fw_data->cal_bit, Q6AFE_MAX_CAL) {
set_bit(Q6AFECAL_UNINITIALISED,
&fw_data->q6afecal_state[cal_bit]);
fw[cal_bit] = kzalloc(sizeof *(fw[cal_bit]), GFP_KERNEL);
if (!fw[cal_bit]) {
pr_err("%s: no memory for %s cal\n",
__func__, cal_name_info[cal_bit]);
goto end;
}
}
for_each_set_bit(cal_bit, fw_data->cal_bit, Q6AFE_MAX_CAL) {
fw[cal_bit]->data = kzalloc(cal_size_info[cal_bit],
GFP_KERNEL);
if (!fw[cal_bit]->data)
goto exit;
set_bit(Q6AFECAL_INITIALISED,
&fw_data->q6afecal_state[cal_bit]);
}
return 0;
exit:
for_each_set_bit(cal_bit, fw_data->cal_bit, Q6AFE_MAX_CAL) {
kfree(fw[cal_bit]->data);
fw[cal_bit]->data = NULL;
}
end:
for_each_set_bit(cal_bit, fw_data->cal_bit, Q6AFE_MAX_CAL) {
kfree(fw[cal_bit]);
fw[cal_bit] = NULL;
}
return -ENOMEM;
}
EXPORT_SYMBOL(q6afe_cal_create_hwdep);

53
dsp/q6afecal-hwdep.h Normal file
View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2014,2018, 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 __Q6AFECAL_HWDEP_H__
#define __Q6AFECAL_HWDEP_H__
#include <sound/msmcal-hwdep.h>
enum q6afe_cal_states {
Q6AFECAL_UNINITIALISED,
Q6AFECAL_INITIALISED,
Q6AFECAL_RECEIVED
};
struct afe_fw_info {
struct firmware_cal *fw[Q6AFE_MAX_CAL];
DECLARE_BITMAP(cal_bit, Q6AFE_MAX_CAL);
/* for calibration tracking */
unsigned long q6afecal_state[Q6AFE_MAX_CAL];
struct mutex lock;
};
struct firmware_cal {
u8 *data;
size_t size;
};
#if IS_ENABLED(CONFIG_AFE_HWDEP)
int q6afe_cal_create_hwdep(void *fw, int node, void *card);
struct firmware_cal *q6afecal_get_fw_cal(struct afe_fw_info *fw_data,
enum q6afe_cal_type type);
#else /* CONFIG_AFE_HWDEP */
static inline int q6afe_cal_create_hwdep(void *fw, int node, void *card)
{
return 0;
}
static inline struct firmware_cal *q6afecal_get_fw_cal(
struct afe_fw_info *fw_data,
enum q6afe_cal_type type)
{
return NULL;
}
#endif /* CONFIG_AFE_HWDEP */
#endif /* __Q6AFECAL_HWDEP_H__ */

View file

@ -513,10 +513,9 @@ int q6core_get_service_version(uint32_t service_id,
}
EXPORT_SYMBOL(q6core_get_service_version);
size_t q6core_get_fwk_version_size(uint32_t service_id)
static int q6core_get_avcs_fwk_version(void)
{
int ret = 0;
uint32_t num_services;
mutex_lock(&(q6core_lcl.ver_lock));
pr_debug("%s: q6core_avcs_ver_info.status(%d)\n", __func__,
@ -547,7 +546,15 @@ size_t q6core_get_fwk_version_size(uint32_t service_id)
break;
}
mutex_unlock(&(q6core_lcl.ver_lock));
return ret;
}
size_t q6core_get_fwk_version_size(uint32_t service_id)
{
int ret = 0;
uint32_t num_services;
ret = q6core_get_avcs_fwk_version();
if (ret)
goto done;
@ -570,6 +577,42 @@ size_t q6core_get_fwk_version_size(uint32_t service_id)
}
EXPORT_SYMBOL(q6core_get_fwk_version_size);
/**
* q6core_get_avcs_version_per_service -
* to get api version of a particular service
*
* @service_id: id of the service
*
* Returns valid version on success or error (negative value) on failure
*/
int q6core_get_avcs_api_version_per_service(uint32_t service_id)
{
struct avcs_fwk_ver_info *cached_ver_info = NULL;
int i;
uint32_t num_services;
int ret = 0;
if (service_id == AVCS_SERVICE_ID_ALL)
return -EINVAL;
ret = q6core_get_avcs_fwk_version();
if (ret < 0) {
pr_err("%s: failure in getting AVCS version\n", __func__);
return ret;
}
cached_ver_info = q6core_lcl.q6core_avcs_ver_info.ver_info;
num_services = cached_ver_info->avcs_fwk_version.num_services;
for (i = 0; i < num_services; i++) {
if (cached_ver_info->services[i].service_id == service_id)
return cached_ver_info->services[i].api_version;
}
pr_err("%s: No service matching service ID %d\n", __func__, service_id);
return -EINVAL;
}
EXPORT_SYMBOL(q6core_get_avcs_api_version_per_service);
/**
* core_set_license -
* command to set license for module

View file

@ -3941,6 +3941,32 @@ struct avs_dec_depacketizer_id_param_t {
uint32_t dec_depacketizer_id;
};
/* ID of the parameter used by #AFE_MODULE_AUDIO_DEV_INTERFACE to configure
* the island mode for a given AFE port.
*/
#define AFE_PARAM_ID_ISLAND_CONFIG 0x000102B4
/* Version information used to handle future additions to codec DMA
* configuration (for backward compatibility).
*/
#define AFE_API_VERSION_ISLAND_CONFIG 0x1
/* Payload of the AFE_PARAM_ID_ISLAND_CONFIG parameter used by
* AFE_MODULE_AUDIO_DEV_INTERFACE.
*/
struct afe_param_id_island_cfg_t {
uint32_t island_cfg_minor_version;
/* Tracks the configuration of this parameter.
* Supported values: #AFE_API_VERSION_ISLAND_CONFIG
*/
uint32_t island_enable;
/* Specifies whether island mode should be enabled or disabled for the
* use-case being setup.
* Supported values: 0 - Disable, 1 - Enable
*/
} __packed;
/* ID of the parameter used by #AFE_MODULE_AUDIO_DEV_INTERFACE to configure
* the Codec DMA interface.
*/
@ -9814,6 +9840,7 @@ struct asm_aptx_dec_fmt_blk_v2 {
#define AVCS_SERVICE_ID_ALL (0xFFFFFFFF)
#define APRV2_IDS_SERVICE_ID_ADSP_CVP_V (0xB)
#define APRV2_IDS_SERVICE_ID_ADSP_AFE_V (0x4)
struct avcs_get_fwk_version {
/*
@ -11265,4 +11292,32 @@ struct admx_sec_primary_mic_ch {
uint16_t reserved1;
} __packed;
/** ID of the Voice Activity Detection (VAD) module, which is used to
* configure AFE VAD.
*/
#define AFE_MODULE_VAD 0x000102B9
/** ID of the parameter used by #AFE_MODULE_VAD to configure the VAD.
*/
#define AFE_PARAM_ID_VAD_CFG 0x000102BA
#define AFE_API_VERSION_VAD_CFG 0x1
/* Payload of the AFE_PARAM_ID_VAD_CONFIG parameter used by
* AFE_MODULE_VAD.
*/
struct afe_param_id_vad_cfg_t {
uint32_t vad_cfg_minor_version;
/** Tracks the configuration of this parameter.
* Supported Values: #AFE_API_VERSION_VAD_CFG
*/
uint32_t pre_roll_in_ms;
/** Pre-roll period in ms.
* Supported Values: 0x0 to 0x3E8
*/
} __packed;
#define AFE_PARAM_ID_VAD_CORE_CFG 0x000102BB
#endif /*_APR_AUDIO_V2_H_ */

View file

@ -41,7 +41,12 @@
#define AFE_CLK_VERSION_V1 1
#define AFE_CLK_VERSION_V2 2
#define AFE_API_VERSION_SUPPORT_SPV3 2
#define AFE_API_VERSION_V3 3
/* for VAD and Island mode */
#define AFE_API_VERSION_V4 4
typedef int (*routing_cb)(int port);
enum {
@ -248,6 +253,16 @@ enum afe_cal_mode {
AFE_CAL_MODE_NONE,
};
enum afe_vad_cfg_type {
AFE_VAD_ENABLE = 0x00,
AFE_VAD_PREROLL,
};
struct vad_config {
u32 is_enable;
u32 pre_roll;
};
struct afe_audio_buffer {
dma_addr_t phys;
void *data;
@ -323,6 +338,9 @@ int afe_rt_proxy_port_write(phys_addr_t buf_addr_p,
int afe_rt_proxy_port_read(phys_addr_t buf_addr_p,
u32 mem_map_handle, int bytes);
void afe_set_cal_mode(u16 port_id, enum afe_cal_mode afe_cal_mode);
void afe_set_vad_cfg(u32 vad_enable, u32 preroll_config,
u32 port_id);
void afe_set_island_mode_cfg(u16 port_id, u32 enable_flag);
int afe_port_start(u16 port_id, union afe_port_config *afe_config,
u32 rate);
int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config,
@ -396,4 +414,6 @@ int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port,
void afe_set_routing_callback(routing_cb cb);
int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats,
u16 port);
int afe_cal_init_hwdep(void *card);
int afe_send_port_island_mode(u16 port_id);
#endif /* __Q6AFE_V2_H__ */

View file

@ -35,6 +35,7 @@ struct audio_uevent_data {
int q6core_init_uevent_data(struct audio_uevent_data *uevent_data, char *name);
void q6core_destroy_uevent_data(struct audio_uevent_data *uevent_data);
int q6core_send_uevent(struct audio_uevent_data *uevent_data, char *name);
int q6core_get_avcs_api_version_per_service(uint32_t service_id);
#define ADSP_CMD_SET_DTS_EAGLE_DATA_ID 0x00012919
#define DTS_EAGLE_LICENSE_ID 0x00028346

View file

@ -3,6 +3,7 @@
#define WCD9XXX_CODEC_HWDEP_NODE 1000
#define AQT1000_CODEC_HWDEP_NODE 1001
#define Q6AFE_HWDEP_NODE 1002
enum wcd_cal_type {
WCD9XXX_MIN_CAL,
WCD9XXX_ANC_CAL = WCD9XXX_MIN_CAL,
@ -21,4 +22,19 @@ struct wcdcal_ioctl_buffer {
#define SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE \
_IOW('U', 0x1, struct wcdcal_ioctl_buffer)
enum q6afe_cal_type {
Q6AFE_MIN_CAL,
Q6AFE_VAD_CORE_CAL = Q6AFE_MIN_CAL,
Q6AFE_MAX_CAL,
};
struct q6afecal_ioctl_buffer {
__u32 size;
__u8 __user *buffer;
enum q6afe_cal_type cal_type;
};
#define SNDRV_IOCTL_HWDEP_VAD_CAL_TYPE \
_IOW('U', 0x1, struct q6afecal_ioctl_buffer)
#endif /*_CALIB_HWDEP_H*/