Denver:audio EVB bringup

denver audio bringup:
1.qcom 4350 platform
2. android R
3. kernel 5.4
4.wcd9370+aw88258

add aw88258 driver.

Change-Id: I4f8696b7ffa6618eb5c2cb0c690001dcec3d5900
Signed-off-by: liaohj <liaohj@lenovo.com>
Reviewed-on: https://gerrit.mot.com/1771700
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Reviewed-by: Wanlong Zhou <zhouwl@motorola.com>
Reviewed-by: Huosheng Liao <liaohs@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
liaohj 2020-10-12 11:50:22 +08:00 • committed by panyq6
commit 7088208182
12 changed files with 5575 additions and 10 deletions

View file

@ -274,6 +274,7 @@ ifeq ($(KERNEL_BUILD), 1)
obj-y += bolero/
obj-y += wsa883x/
obj-y += rouleur/
obj-y += aw882xx/
endif
# Module information used by KBuild framework
obj-$(CONFIG_WCD9XXX_CODEC_CORE) += wcd_core_dlkm.o

View file

@ -0,0 +1,8 @@
DLKM_DIR := $(TOP)/device/qcom/common/dlkm
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := aw882xx_k419.ko
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/AndroidKernelModule.mk

View file

@ -0,0 +1,9 @@
# add -Wall to try to catch everything we can.
EXTRA_CFLAGS += -Wall
EXTRA_CFLAGS += -I$(TOP)/kernel/msm-5.4/techpack/audio/include
EXTRA_CFLAGS += -I$(TOP)/kernel/msm-5.4/techpack/audio/include/uapi/
EXTRA_CFLAGS += -DCONFIG_AW882XX_CODEC -DCONFIG_AW882XX_DSP
aw882xx_k419-objs = aw882xx.o
obj-m += aw882xx_k419.o

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,279 @@
#ifndef _AW882XX_H_
#define _AW882XX_H_
//#define AW_DEBUG
/*
* i2c transaction on Linux limited to 64k
* (See Linux kernel documentation: Documentation/i2c/writing-clients)
*/
#define MAX_I2C_BUFFER_SIZE 65536
#define AW882XX_I2C_READ_MSG_NUM 2
#define AW_VOL_COUNT (3)
#define AW882XX_FLAG_START_ON_MUTE (1 << 0)
#define AW882XX_FLAG_SKIP_INTERRUPTS (1 << 1)
#define AW882XX_FLAG_SAAM_AVAILABLE (1 << 2)
#define AW882XX_FLAG_STEREO_DEVICE (1 << 3)
#define AW882XX_FLAG_MULTI_MIC_INPUTS (1 << 4)
#define AW882XX_NUM_RATES 9
#define AW882XX_SYSST_CHECK_MAX 10
#define AW882XX_MODE_SHIFT_MAX 2
#define AW882XX_DEFAULT_AFE_RX_PROT_ID 0x1000 /*AFE_PORT_ID_PRIMARY_MI2S_RX*/
#define AW882XX_DEFAULT_AFE_TX_PROT_ID 0x1001 /*AFE_PORT_ID_PRIMARY_MI2S_TX*/
#define AW_MODULE_ID_COPP (0X10013D02) /*SKT module id*/
#define AW_MODULE_PARAMS_ID_COPP_ENABLE (0X10013D14) /*SKT enable param id*/
#define DEFAULT_CALI_VALUE (7)
#define ERRO_CALI_VALUE (0)
#define AFE_PARAM_ID_AWDSP_RX_SET_ENABLE (0x10013D11)
#define AFE_PARAM_ID_AWDSP_RX_PARAMS (0x10013D12)
#define AFE_PARAM_ID_AWDSP_TX_SET_ENABLE (0x10013D13)
#define AFE_PARAM_ID_AWDSP_RX_VMAX_L (0X10013D17)
#define AFE_PARAM_ID_AWDSP_RX_VMAX_R (0X10013D18)
#define AFE_PARAM_ID_AWDSP_RX_CALI_CFG_L (0X10013D19)
#define AFE_PARAM_ID_AWDSP_RX_CALI_CFG_R (0x10013d1A)
#define AFE_PARAM_ID_AWDSP_RX_RE_L (0x10013d1B)
#define AFE_PARAM_ID_AWDSP_RX_RE_R (0X10013D1C)
#define AFE_PARAM_ID_AWDSP_RX_NOISE_L (0X10013D1D)
#define AFE_PARAM_ID_AWDSP_RX_NOISE_R (0X10013D1E)
#define AFE_PARAM_ID_AWDSP_RX_F0_L (0X10013D1F)
#define AFE_PARAM_ID_AWDSP_RX_F0_R (0X10013D20)
#define AFE_PARAM_ID_AWDSP_RX_REAL_DATA_L (0X10013D21)
#define AFE_PARAM_ID_AWDSP_RX_REAL_DATA_R (0X10013D22)
enum {
AW_FIRST_ENTRY = 0,
AW_NOT_FIRST_ENTRY = 1,
};
enum AWINIC_CALI_CMD{
AW_CALI_CMD_NONE = 0,
AW_CALI_CMD_START,
AW_CALI_CMD_END,
AW_CALI_CMD_SET_CALI_CFG,
AW_CALI_CMD_GET_CALI_CFG,
AW_CALI_CMD_GET_CALI_DATA,
AW_CALI_CMD_SET_NOISE,
AW_CALI_CMD_GET_F0,
AW_CALI_CMD_SET_CALI_RE,
AW_CALI_CMD_GET_CALI_RE,
AW_CALI_CMD_SET_VMAX,
AW_CALI_CMD_GET_VMAX,
AW_CALI_CMD_MAX,
};
#define AW882XX_CALI_CFG_NUM 3
#define AW882XX_CALI_DATA_NUM 6
#define AW882XX_PARAMS_NUM 400
struct cali_cfg{
int32_t data[AW882XX_CALI_CFG_NUM];
};
struct cali_data{
int32_t data[AW882XX_CALI_DATA_NUM];
};
struct params_data{
int32_t data[AW882XX_PARAMS_NUM];
};
struct ptr_params_data {
int len;
int32_t *data;
};
#define AW882XX_IOCTL_MAGIC 'a'
#define AW882XX_IOCTL_SET_CALI_CFG _IOWR(AW882XX_IOCTL_MAGIC, 1, struct cali_cfg)
#define AW882XX_IOCTL_GET_CALI_CFG _IOWR(AW882XX_IOCTL_MAGIC, 2, struct cali_cfg)
#define AW882XX_IOCTL_GET_CALI_DATA _IOWR(AW882XX_IOCTL_MAGIC, 3, struct cali_data)
#define AW882XX_IOCTL_SET_NOISE _IOWR(AW882XX_IOCTL_MAGIC, 4, int32_t)
#define AW882XX_IOCTL_GET_F0 _IOWR(AW882XX_IOCTL_MAGIC, 5, int32_t)
#define AW882XX_IOCTL_SET_CALI_RE _IOWR(AW882XX_IOCTL_MAGIC, 6, int32_t)
#define AW882XX_IOCTL_GET_CALI_RE _IOWR(AW882XX_IOCTL_MAGIC, 7, int32_t)
#define AW882XX_IOCTL_SET_VMAX _IOWR(AW882XX_IOCTL_MAGIC, 8, int32_t)
#define AW882XX_IOCTL_GET_VMAX _IOWR(AW882XX_IOCTL_MAGIC, 9, int32_t)
#define AW882XX_IOCTL_SET_PARAM _IOWR(AW882XX_IOCTL_MAGIC, 10,struct params_data)
#define AW882XX_IOCTL_ENABLE_CALI _IOWR(AW882XX_IOCTL_MAGIC, 11,int8_t)
#define AW882XX_IOCTL_SET_PTR_PARAM_NUM _IOWR(AW882XX_IOCTL_MAGIC, 12, struct ptr_params_data)
enum aw882xx_init {
AW882XX_INIT_ST = 0,
AW882XX_INIT_OK = 1,
AW882XX_INIT_NG = 2,
};
enum aw882xx_power_status {
AW882XX_POWER_DOWN = 0,
AW882XX_POWER_ING = 1,
AW882XX_POWER_UP = 2,
};
enum aw882xx_chipid {
AW882XX_ID = 0x1852,
};
enum aw882xx_modeshift {
AW882XX_MODE_SPK_SHIFT = 0,
AW882XX_MODE_RCV_SHIFT = 1,
};
enum aw882xx_mode_spk_rcv {
AW882XX_SPEAKER_MODE = 0,
AW882XX_RECEIVER_MODE = 1,
};
//smartpa monitor
enum aw882xx_ipeak {
IPEAK_3P50_A = 0x08,
IPEAK_3P00_A = 0x06,
IPEAK_2P75_A = 0x05,
IPEAK_2P50_A = 0x04,
IPEAK_NONE = 0xFF,
};
enum aw882xx_gain {
GAIN_NEG_0P0_DB = 0x00,
GAIN_NEG_0P5_DB = 0x01,
GAIN_NEG_1P0_DB = 0x02,
GAIN_NEG_1P5_DB = 0x03,
GAIN_NEG_3P0_DB = 0x06,
GAIN_NEG_4P5_DB = 0x09,
GAIN_NEG_6P0_DB = 0x10,
GAIN_NONE = 0xFF,
};
enum aw882xx_vmax_percentage {
VMAX_100_PERCENTAGE = 0x00000000,
VMAX_086_PERCENTAGE = 0xFFED714D,
VMAX_075_PERCENTAGE = 0xFFD80505,
VMAX_063_PERCENTAGE = 0xFFBEAE7E,
VMAX_NONE = 0xFFFFFFFF,
};
#define AW882XX_MONITOR_DEFAULT_FLAG 0
#define AW882XX_MONITOR_DEFAULT_TIMER_VAL 30000
#define AW882XX_MONITOR_VBAT_RANGE 6025
#define AW882XX_MONITOR_INT_10BIT 1023
#define AW882XX_MONITOR_TEMP_SIGN_MASK (1<<9)
#define AW882XX_MONITOR_TEMP_NEG_MASK (0XFC00)
#define AW882XX_BIT_SYSCTRL2_BST_IPEAK_MASK ( 15<< 0)
#define AW882XX_BIT_HAGCCFG4_GAIN_SHIFT (8)
#define AW882XX_BIT_HAGCCFG4_GAIN_MASK (0x00ff)
struct aw882xx_low_vol {
uint32_t vol;
uint8_t ipeak;
uint8_t gain;
};
struct aw882xx_low_temp {
int16_t temp;
uint8_t ipeak;
uint8_t gain;
uint32_t vmax;
};
struct aw882xx_monitor{
struct hrtimer timer;
uint32_t timer_val;
struct work_struct work;
uint32_t is_enable;
uint16_t pre_vol;
uint16_t vol_count;
uint8_t first_entry;
struct aw882xx_low_vol vol_cfg;
struct aw882xx_low_temp temp_cfg;
int vol_up_num;
int vol_down_num;
int temp_up_num;
int temp_down_num;
struct aw882xx_low_vol *vol_up_table;
struct aw882xx_low_vol *vol_down_table;
struct aw882xx_low_temp *temp_up_table;
struct aw882xx_low_temp *temp_down_table;
#ifdef AW_DEBUG
uint16_t test_vol;
int16_t test_temp;
#endif
};
/*control runin test function*/
#define AW882XX_RUNIN_TEST
enum AWINIC_PROFILE{
AW_PROFILE_MUSIC = 0,
AW_PROFILE_RINGTONE,
AW_PROFILE_NOTIFICATION,
AW_PROFILE_VOICE,
AW_PROFILE_MAX,
};
#define VERSION_MAX 4
#define PROJECT_NAME_MAX 24
#define VOLUME_STEP_DB (6)
#define VOLUME_MIN_NEG_90_DB (90)
#define FADE_STEP_DB (6)
typedef struct awinic_afe_param_header{
uint8_t fw[VERSION_MAX];
uint8_t cfg[VERSION_MAX];
uint8_t project[PROJECT_NAME_MAX];
uint32_t start;
uint32_t params_len;
uint8_t check_sum;
uint8_t profile_num;
uint8_t reserve[2];
}aw_afe_params_hdr_t;
struct profile_info {
struct mutex lock;
int cur_profile;
int status;
int len;
char* data[AW_PROFILE_MAX];
};
struct aw882xx {
struct regmap *regmap;
struct i2c_client *i2c;
struct snd_soc_component *component;
struct device *dev;
struct mutex lock;
struct aw882xx_monitor monitor;
#ifdef AW882XX_RUNIN_TEST
struct delayed_work adsp_status;
#endif
int sysclk;
int rate;
int pstream;
int cstream;
int reset_gpio;
int irq_gpio;
int power_flag;
unsigned char reg_addr;
unsigned int flags;
unsigned int chipid;
unsigned int init;
unsigned int spk_rcv_mode;
uint32_t cali_re;
uint32_t default_re;
uint8_t cur_gain;
uint8_t need_fade;
unsigned int cfg_num;
unsigned int afe_rx_portid;
unsigned int afe_tx_portid;
unsigned int afe_profile;
struct profile_info profile;
};
struct aw882xx_container {
int len;
unsigned char data[];
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -326,15 +326,27 @@ SND_SOC_DAILINK_DEFS(pri_mi2s_tx,
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
#if defined(CONFIG_AW882XX_STEREO_SMARTPA)
SND_SOC_DAILINK_DEFS(sec_mi2s_rx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.2")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.2")),
DAILINK_COMP_ARRAY(COMP_CODEC("aw882xxacf_smartpa.2-0034", "aw882xx-aif-2-34"),
COMP_CODEC("aw882xxacf_smartpa.2-0035", "aw882xx-aif-2-35")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(sec_mi2s_tx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.3")),
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.3")),
DAILINK_COMP_ARRAY(COMP_CODEC("aw882xxacf_smartpa.2-0034", "aw882xx-aif-2-34"),
COMP_CODEC("aw882xxacf_smartpa.2-0035", "aw882xx-aif-2-35")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
#else
SND_SOC_DAILINK_DEFS(sec_mi2s_rx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.2")),
DAILINK_COMP_ARRAY(COMP_CODEC("aw882xx_codec", "aw882xx-aif")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
SND_SOC_DAILINK_DEFS(sec_mi2s_tx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.3")),
DAILINK_COMP_ARRAY(COMP_CODEC("aw882xx_codec", "aw882xx-aif")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
#endif
SND_SOC_DAILINK_DEFS(tert_mi2s_rx,
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.4")),

View file

@ -33,6 +33,5 @@ export CONFIG_WSA881X_TEMP_SENSOR_DISABLE=m
export CONFIG_SND_SOC_HOLI=m
export CONFIG_SND_EVENT=m
export CONFIG_TDM_DISABLE=m
export CONFIG_MI2S_DISABLE=m
export CONFIG_AUXPCM_DISABLE=m
export CONFIG_DIGITAL_CDC_RSC_MGR=m

View file

@ -37,6 +37,5 @@
#define CONFIG_SND_SOC_HOLI 1
#define CONFIG_SND_EVENT 1
#define CONFIG_TDM_DISABLE 1
#define CONFIG_MI2S_DISABLE 1
#define CONFIG_AUXPCM_DISABLE 1
#define CONFIG_DIGITAL_CDC_RSC_MGR 1

View file

@ -13,6 +13,8 @@ ifeq ($(KERNEL_BUILD), 1)
AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio
endif
EXTRA_CFLAGS += -DCONFIG_SND_SOC_AWINIC_AW882XX
ifeq ($(CONFIG_SND_SOC_AUTO), y)
ifdef CONFIG_SND_SOC_SA8155
include $(AUDIO_ROOT)/config/sa8155auto.conf

View file

@ -5184,6 +5184,49 @@ int adm_set_ffecns_freeze_event(bool ffecns_freeze_event)
return rc;
}
EXPORT_SYMBOL(adm_set_ffecns_freeze_event);
#ifdef CONFIG_SND_SOC_AWINIC_AW882XX
int aw_adm_param_enable(int port_id, int module_id, int param_id, int enable)
{
int copp_idx = 0;
uint32_t enable_param;
struct param_hdr_v3 param_hdr;
int rc = 0;
pr_debug("%s port_id %d, module_id 0x%x, enable %d\n",
__func__, port_id, module_id, enable);
copp_idx = adm_get_default_copp_idx(port_id);
if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) {
pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx);
return -EINVAL;
}
if (enable < 0 || enable > 1) {
pr_err("%s: Invalid value for enable %d\n", __func__, enable);
return -EINVAL;
}
pr_debug("%s port_id %d, module_id 0x%x, copp_idx 0x%x, enable %d\n",
__func__, port_id, module_id, copp_idx, enable);
memset(&param_hdr, 0, sizeof(param_hdr));
param_hdr.module_id = module_id;
param_hdr.instance_id = INSTANCE_ID_0;
param_hdr.param_id = param_id;
param_hdr.param_size = sizeof(enable_param);
enable_param = enable;
rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr,
(uint8_t *) &enable_param);
if (rc)
pr_err("%s: Failed to set enable of module(%d) instance(%d) to %d, err %d\n",
__func__, module_id, INSTANCE_ID_0, enable, rc);
return rc;
}
EXPORT_SYMBOL(aw_adm_param_enable);
#endif
/**
* adm_param_enable -

View file

@ -24,6 +24,13 @@
#include "adsp_err.h"
#include "q6afecal-hwdep.h"
#ifdef CONFIG_SND_SOC_AWINIC_AW882XX
#define AFE_MODULE_ID_AWDSP_TX (0x10013D00)
#define AFE_MODULE_ID_AWDSP_RX (0x10013D01)
#define AFE_PARAM_ID_AWDSP_RX_SET_ENABLE (0x10013D11)
#define AFE_PARAM_ID_AWDSP_TX_SET_ENABLE (0x10013D13)
#define AFE_PARAM_ID_AWDSP_RX_PARAMS (0x10013D12)
#endif /* #ifdef CONFIG_SND_SOC_AWINIC_AW882XX */
#define WAKELOCK_TIMEOUT 5000
#define AFE_CLK_TOKEN 1024
#define AFE_NOWAIT_TOKEN 2048
@ -275,6 +282,10 @@ struct afe_ctl {
uint32_t cps_ch_mask;
struct afe_cps_hw_intf_cfg *cps_config;
int lsm_afe_ports[MAX_LSM_SESSIONS];
#ifdef CONFIG_SND_SOC_AWINIC_AW882XX
struct rtac_cal_block_data aw_cal;
atomic_t aw_state;
#endif /*CONFIG_SND_SOC_AWINIC_AW882XX*/
};
struct afe_clkinfo_per_port {
@ -1117,7 +1128,19 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
payload, data->token);
return -EINVAL;
}
#ifdef CONFIG_SND_SOC_AWINIC_AW882XX
if (atomic_read(&this_afe.aw_state) == 1) {
if (!payload[0]) {
atomic_set(&this_afe.state, 0);
} else {
pr_debug("%s: status: %d", __func__, payload[0]);
atomic_set(&this_afe.state, -1);
}
atomic_set(&this_afe.aw_state, 0);
wake_up(&this_afe.wait[data->token]);
return 0;
}
#endif /*CONFIG_SND_SOC_AWINIC_AW882XX*/
if (rtac_make_afe_callback(data->payload,
data->payload_size))
return 0;
@ -2511,6 +2534,15 @@ static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id,
case AFE_PARAM_ID_SP_V4_EX_VI_FTM_CFG:
param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_VI;
break;
#ifdef CONFIG_SND_SOC_AWINIC_AW882XX
case AFE_PARAM_ID_AWDSP_RX_SET_ENABLE:
case AFE_PARAM_ID_AWDSP_RX_PARAMS:
param_info.module_id = AFE_MODULE_ID_AWDSP_RX;
break;
case AFE_PARAM_ID_AWDSP_TX_SET_ENABLE:
param_info.module_id = AFE_MODULE_ID_AWDSP_TX;
break;
#endif /*CONFIG_SND_SOC_AWINIC_AW882XX*/
default:
pr_err("%s: default case 0x%x\n", __func__, param_id);
goto fail_cmd;
@ -3920,6 +3952,216 @@ done:
return ret;
}
#ifdef CONFIG_SND_SOC_AWINIC_AW882XX
int aw_send_afe_rx_module_enable(uint32_t rx_port_id, void *buf, int cmd_size)
{
union afe_spkr_prot_config config;
if (cmd_size > sizeof(config))
return -EINVAL;
memcpy(&config, buf, cmd_size);
if (afe_spk_prot_prepare(rx_port_id, 0,
AFE_PARAM_ID_AWDSP_RX_SET_ENABLE, &config,sizeof(union afe_spkr_prot_config))) {
pr_err("%s: set bypass failed \n", __func__);
return -EINVAL;
}
return 0;
}
EXPORT_SYMBOL(aw_send_afe_rx_module_enable);
int aw_send_afe_tx_module_enable(uint32_t tx_port_id, void *buf, int cmd_size)
{
union afe_spkr_prot_config config;
if (cmd_size > sizeof(config))
return -EINVAL;
memcpy(&config, buf, cmd_size);
if (afe_spk_prot_prepare(tx_port_id, 0,
AFE_PARAM_ID_AWDSP_TX_SET_ENABLE, &config,sizeof(union afe_spkr_prot_config))) {
pr_err("%s: set bypass failed \n", __func__);
return -EINVAL;
}
return 0;
}
EXPORT_SYMBOL(aw_send_afe_tx_module_enable);
int aw_send_afe_cal_apr(uint32_t rx_port_id, uint32_t tx_port_id,
uint32_t param_id, void *buf, int cmd_size, bool write)
{
int32_t result = 0;
uint32_t port_id = rx_port_id;
int32_t module_id = AFE_MODULE_ID_AWDSP_RX;
uint32_t port_index = 0;
uint32_t payload_size = 0;
size_t len;
struct rtac_cal_block_data *aw_cal = &(this_afe.aw_cal);
struct mem_mapping_hdr mem_hdr;
struct param_hdr_v3 param_hdr;
pr_debug("%s: enter\n", __func__);
if (param_id == AFE_PARAM_ID_AWDSP_TX_SET_ENABLE) {
port_id = tx_port_id;
module_id = AFE_MODULE_ID_AWDSP_TX;
}
if (aw_cal->map_data.dma_buf == 0) {
/*Minimal chunk size is 4K*/
aw_cal->map_data.map_size = SZ_4K;
result = msm_audio_ion_alloc(&(aw_cal->map_data.dma_buf),
aw_cal->map_data.map_size,
&(aw_cal->cal_data.paddr),&len,
&(aw_cal->cal_data.kvaddr));
if (result < 0) {
pr_err("%s: allocate buffer failed! ret = %d\n",
__func__, result);
goto err;
}
}
if (aw_cal->map_data.map_handle == 0) {
result = afe_map_rtac_block(aw_cal);
if (result < 0) {
pr_err("%s: map buffer failed! ret = %d\n",
__func__, result);
goto err;
}
}
port_index = q6audio_get_port_index(port_id);
if (port_index >= AFE_MAX_PORTS) {
pr_err("%s: Invalid AFE port = 0x%x\n", __func__, port_id);
goto err;
}
if (cmd_size > (SZ_4K - sizeof(struct param_hdr_v3))) {
pr_err("%s: Invalid payload size = %d\n", __func__, cmd_size);
result = -EINVAL;
goto err;
}
/* Pack message header with data */
param_hdr.module_id = module_id;
param_hdr.instance_id = INSTANCE_ID_0;
param_hdr.param_size = cmd_size;
if (write) {
param_hdr.param_id = param_id;
q6common_pack_pp_params(aw_cal->cal_data.kvaddr,
&param_hdr,
buf,
&payload_size);
aw_cal->cal_data.size = payload_size;
} else {
param_hdr.param_id = param_id;
aw_cal->cal_data.size = cmd_size + sizeof(struct param_hdr_v3);
}
/*Send/Get package to/from ADSP*/
mem_hdr.data_payload_addr_lsw =
lower_32_bits(aw_cal->cal_data.paddr);
mem_hdr.data_payload_addr_msw =
msm_audio_populate_upper_32_bits(aw_cal->cal_data.paddr);
mem_hdr.mem_map_handle =
aw_cal->map_data.map_handle;
pr_debug("%s: Sending aw_cal port = 0x%x, cal size = %zd, cal addr = 0x%pK\n",
__func__, port_id, aw_cal->cal_data.size, &aw_cal->cal_data.paddr);
result = afe_q6_interface_prepare();
if (result != 0) {
pr_err("%s: Q6 interface prepare failed %d\n", __func__, result);
goto err;
}
if (write) {
if (q6common_is_instance_id_supported())
result = q6afe_set_params_v3(port_id, port_index, &mem_hdr, NULL, payload_size);
else
result = q6afe_set_params_v2(port_id, port_index, &mem_hdr, NULL, payload_size);
} else {
int8_t *resp = (int8_t *)aw_cal->cal_data.kvaddr;
atomic_set(&this_afe.aw_state, 1);
if (q6common_is_instance_id_supported()) {
result = q6afe_get_params_v3(port_id, port_index, &mem_hdr, &param_hdr);
resp += sizeof(struct param_hdr_v3);
} else {
result = q6afe_get_params_v2(port_id, port_index, &mem_hdr, &param_hdr);
resp += sizeof(struct param_hdr_v1);
}
if (result) {
pr_err("%s: get response from port 0x%x failed %d\n",
__func__, port_id, result);
goto err;
}
else {
/*Copy response data to command buffer*/
memcpy(buf, resp, cmd_size);
}
}
err:
return result;
}
EXPORT_SYMBOL(aw_send_afe_cal_apr);
void aw_cal_unmap_memory(void)
{
int result = 0;
if (this_afe.aw_cal.map_data.map_handle) {
result = afe_unmap_rtac_block(&this_afe.aw_cal.map_data.map_handle);
/*Force to remap after unmap failed*/
if (result)
this_afe.aw_cal.map_data.map_handle = 0;
}
}
EXPORT_SYMBOL(aw_cal_unmap_memory);
int aw_send_rx_module_enable(uint32_t rx_port_id, void *buf, int cmd_size)
{
union afe_spkr_prot_config config;
if (cmd_size > sizeof(config))
return -EINVAL;
memcpy(&config, buf, cmd_size);
if (afe_spk_prot_prepare(rx_port_id, 0,
AFE_PARAM_ID_AWDSP_RX_SET_ENABLE,
&config,sizeof(union afe_spkr_prot_config))) {
pr_err("%s: AW set rx bypass failed\n",
__func__);
}
return 0;
}
EXPORT_SYMBOL(aw_send_rx_module_enable);
int aw_send_tx_module_enable(uint32_t tx_port_id, void *buf, int cmd_size)
{
union afe_spkr_prot_config config;
if (cmd_size > sizeof(config))
return -EINVAL;
memcpy(&config, buf, cmd_size);
if (afe_spk_prot_prepare(tx_port_id, 0,
AFE_PARAM_ID_AWDSP_TX_SET_ENABLE,
&config,sizeof(union afe_spkr_prot_config))) {
pr_err("%s: AW set tx module enable failed\n",
__func__);
}
return 0;
}
EXPORT_SYMBOL(aw_send_tx_module_enable);
#endif
static int afe_init_cdc_reg_config(void)
{
struct param_hdr_v3 param_hdr;
@ -12078,6 +12320,9 @@ void afe_exit(void)
q6core_destroy_uevent_data(this_afe.uevent_data);
#ifdef CONFIG_SND_SOC_AWINIC_AW882XX
aw_cal_unmap_memory();
#endif /*CONFIG_SND_SOC_AWINIC_AW882XX*/
afe_delete_cal_data();
config_debug_fs_exit();