asoc: audio:update aw882xx driver to v1.9.0.7

update aw882xx driver to v1.9.0.7
support get algo params from ram.
skt-prof-mode = 1 to support by product.

Change-Id: Id3d8ebc09cd616ad159486405ec95d67419eaf21
Signed-off-by: guoyf2 <guoyf2@lenovo.com>
Reviewed-on: https://gerrit.mot.com/2264458
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: Yunfei Guo <guoyf2@motorola.com>
Reviewed-by: Xiangpo Zhao <zhaoxp3@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
guoyf2 authored and Gilberto Gambugge committed 2023-06-01 00:39:50 -03:00
1 parent 4ea53be588
commit aedadd21e6
7 files changed
+519 -51

No files matched your search

+111 -49
View File
@@ -35,7 +35,7 @@
#include "aw_log.h" #include "aw_log.h"
#include "aw_dsp.h" #include "aw_dsp.h"
#define AW882XX_DRIVER_VERSION "v1.9.0.6" #define AW882XX_DRIVER_VERSION "v1.9.0.7"
#define AW882XX_I2C_NAME "aw882xxacf_smartpa" #define AW882XX_I2C_NAME "aw882xxacf_smartpa"
#define AW_READ_CHIPID_RETRIES 5 /* 5 times */ #define AW_READ_CHIPID_RETRIES 5 /* 5 times */
@@ -54,12 +54,9 @@ static uint32_t g_spin_en = 0;
static unsigned int g_runin_test; static unsigned int g_runin_test;
#endif #endif
#ifdef AW882XX_SPIN_FOR_LOW_LATENCY_ONLY
static unsigned int g_skt_prof_id = 0;
#endif
static DEFINE_MUTEX(g_aw882xx_lock); static DEFINE_MUTEX(g_aw882xx_lock);
struct aw_container *g_awinic_cfg = NULL; struct aw_container *g_awinic_cfg = NULL;
struct aw_container *g_awinic_skt_cfg = NULL;
#define AW882XX_MOTO_MAX_GAIN (127) #define AW882XX_MOTO_MAX_GAIN (127)
@@ -493,6 +490,7 @@ static int aw882xx_mute(struct snd_soc_dai *dai, int mute, int stream)
if (mute) { if (mute) {
aw882xx->pstream = false; aw882xx->pstream = false;
aw882xx->aw_pa->pre_prof_id = AW_DEFAULT_PRO_ID;
cancel_delayed_work_sync(&aw882xx->dc_work); cancel_delayed_work_sync(&aw882xx->dc_work);
cancel_delayed_work_sync(&aw882xx->start_work); cancel_delayed_work_sync(&aw882xx->start_work);
mutex_lock(&aw882xx->lock); mutex_lock(&aw882xx->lock);
@@ -900,6 +898,8 @@ static void aw882xx_request_firmware(struct work_struct *work)
container_of(work, struct aw882xx, fw_work.work); container_of(work, struct aw882xx, fw_work.work);
const struct firmware *cont = NULL; const struct firmware *cont = NULL;
struct aw_container *aw_cfg = NULL; struct aw_container *aw_cfg = NULL;
const struct firmware *skt_cont = NULL;
struct aw_container *aw_skt_cfg = NULL;
int ret = -1; int ret = -1;
aw882xx->fw_status = AW_DEV_FW_FAILED; aw882xx->fw_status = AW_DEV_FW_FAILED;
@@ -950,6 +950,56 @@ static void aw882xx_request_firmware(struct work_struct *work)
} }
mutex_unlock(&g_aw882xx_lock); mutex_unlock(&g_aw882xx_lock);
/*load skt bin*/
if (aw882xx->skt_prof_mode == AW_PARAMS_DATA_MODE) {
ret = request_firmware(&skt_cont, AW_ALGO_SKT_BIN, aw882xx->dev);
if ((ret) || (!skt_cont)) {
aw_dev_info(aw882xx->dev, "load [%s] failed!", AW_ALGO_SKT_BIN);
return;
}
aw_dev_info(aw882xx->dev, "load [%s] , file size: [%zu]",
AW_ALGO_SKT_BIN, skt_cont ? skt_cont->size : 0);
if (g_awinic_skt_cfg == NULL) {
aw_skt_cfg = vzalloc(skt_cont->size + sizeof(int));
if (aw_skt_cfg == NULL) {
release_firmware(skt_cont);
aw_dev_err(aw882xx->dev, "malloc failed");
return;
}
aw_skt_cfg->len = skt_cont->size;
memcpy(aw_skt_cfg->data, skt_cont->data, skt_cont->size);
release_firmware(skt_cont);
ret = aw_dev_load_acf_check(aw_skt_cfg);
if (ret) {
aw_dev_err(aw882xx->dev, "Load [%s] failed ....!", AW_ALGO_SKT_BIN);
vfree(aw_skt_cfg);
aw_skt_cfg = NULL;
return;
}
g_awinic_skt_cfg = aw_skt_cfg;
/*set init algo prof*/
aw882xx->aw_pa->pre_prof_id = AW_DEFAULT_PRO_ID;
} else {
aw_skt_cfg = g_awinic_skt_cfg;
release_firmware(skt_cont);
aw_dev_info(aw882xx->dev, "[%s] already loaded...", AW_ALGO_SKT_BIN);
}
/*parse skt bin*/
if ((aw882xx->aw_pa->channel == AW_DEV_CH_PRI_L) || (aw882xx->aw_pa->channel == AW_DEV_CH_SEC_L)) {
ret = aw_dev_parse_skt_bin(aw882xx->aw_pa, aw_skt_cfg);
if (ret < 0) {
aw_dev_info(aw882xx->dev, "parse skt bin failed");
return;
}
}
}
mutex_lock(&aw882xx->lock); mutex_lock(&aw882xx->lock);
/*aw device init*/ /*aw device init*/
ret = aw_device_init(aw882xx->aw_pa, aw_cfg); ret = aw_device_init(aw882xx->aw_pa, aw_cfg);
@@ -1095,10 +1145,22 @@ static int aw882xx_set_rx_en(struct snd_kcontrol *kcontrol,
g_algo_rx_en = ctrl_value; g_algo_rx_en = ctrl_value;
aw_dev_info(aw882xx->dev, "set value %d", ctrl_value); aw_dev_info(aw882xx->dev, "set value %d", ctrl_value);
if (ctrl_value) { if (aw882xx->skt_prof_mode == AW_PARAMS_PATH_MODE) {
ret = aw_dev_set_algo_params_path(aw_dev); if (ctrl_value) {
if (ret < 0) ret = aw_dev_set_algo_params_path(aw_dev);
aw_dev_err(aw882xx->dev, "set algo params path failed, ret=%d", ret); if (ret < 0)
aw_dev_err(aw882xx->dev, "set algo params path failed, ret=%d", ret);
}
} else {
if (aw882xx->aw_pa->pre_prof_id != AW_DEFAULT_PRO_ID) {
aw882xx->cur_algo_prof_id = aw882xx->aw_pa->pre_prof_id;
aw882xx->aw_pa->pre_prof_id = AW_DEFAULT_PRO_ID;
ret = aw_dev_skt_prof_mode(aw_dev, aw882xx->cur_algo_prof_id);
if (ret < 0) {
aw_dev_err(aw882xx->dev, "set algo prof failed");
return -EINVAL;
}
}
} }
return 0; return 0;
} }
@@ -1264,21 +1326,12 @@ static int aw882xx_set_spin(struct snd_kcontrol *kcontrol,
aw_dev = aw882xx->aw_pa; aw_dev = aw882xx->aw_pa;
ctrl_value = ucontrol->value.integer.value[0]; ctrl_value = ucontrol->value.integer.value[0];
#ifdef AW882XX_SPIN_FOR_LOW_LATENCY_ONLY
if (g_skt_prof_id == (AW882XX_SCENE_FASTTRACK_ID+1)) {
#else
if (aw882xx->pstream) { if (aw882xx->pstream) {
#endif
ret = aw_dev_set_spin(ctrl_value); ret = aw_dev_set_spin(ctrl_value);
if (ret) if (ret)
aw_dev_err(aw882xx->dev, "set spin error, ret=%d", ret); aw_dev_err(aw882xx->dev, "set spin error, ret=%d", ret);
} else { } else {
#ifdef AW882XX_SPIN_FOR_LOW_LATENCY_ONLY
aw_dev_info(aw882xx->dev, "fasttrack stream no start");
#else
aw_dev_info(aw882xx->dev, "stream no start only record"); aw_dev_info(aw882xx->dev, "stream no start only record");
#endif
} }
g_spin_value = ctrl_value; g_spin_value = ctrl_value;
@@ -1602,6 +1655,7 @@ static int aw882xx_set_prof_id(struct snd_kcontrol *kcontrol,
struct aw882xx *aw882xx = struct aw882xx *aw882xx =
aw_componet_codec_ops.codec_get_drvdata(codec); aw_componet_codec_ops.codec_get_drvdata(codec);
int ctrl_value; int ctrl_value;
int ret = -1;
aw_dev_dbg(aw882xx->dev, "ucontrol->value.integer.value[0]=%ld", aw_dev_dbg(aw882xx->dev, "ucontrol->value.integer.value[0]=%ld",
ucontrol->value.integer.value[0]); ucontrol->value.integer.value[0]);
@@ -1610,7 +1664,15 @@ static int aw882xx_set_prof_id(struct snd_kcontrol *kcontrol,
ctrl_value = ucontrol->value.integer.value[0]; ctrl_value = ucontrol->value.integer.value[0];
aw_dev_set_algo_prof(aw_dev, ctrl_value); if (aw882xx->skt_prof_mode == AW_PARAMS_PATH_MODE) {
aw_dev_set_algo_prof(aw_dev, ctrl_value);
} else {
ret = aw_dev_skt_prof_mode(aw_dev, ctrl_value);
if (ret < 0) {
aw_dev_err(aw882xx->dev, "set_prof failed!, ret = %d", ret);
}
aw882xx->cur_algo_prof_id = ctrl_value;
}
return 0; return 0;
} }
@@ -1628,10 +1690,14 @@ static int aw882xx_get_prof_id(struct snd_kcontrol *kcontrol,
aw_dev = aw882xx->aw_pa; aw_dev = aw882xx->aw_pa;
if (aw882xx->pstream) { if (aw882xx->pstream) {
ret = aw_dev_get_algo_prof(aw_dev, &ctrl_value); if (aw882xx->skt_prof_mode == AW_PARAMS_PATH_MODE) {
if (ret) { ret = aw_dev_get_algo_prof(aw_dev, &ctrl_value);
aw_dev_err(aw882xx->dev, "get algo prof id failed!, ret = %d", ret); if (ret) {
ctrl_value = 0; aw_dev_err(aw882xx->dev, "get algo prof id failed!, ret = %d", ret);
ctrl_value = 0;
}
} else {
ctrl_value = aw882xx->cur_algo_prof_id;
} }
ucontrol->value.integer.value[0] = ctrl_value; ucontrol->value.integer.value[0] = ctrl_value;
} else { } else {
@@ -1692,7 +1758,7 @@ static void aw882xx_update_algo_scene_st(struct aw882xx *aw882xx,
static int aw882xx_update_algo_profile(struct aw882xx *aw882xx) static int aw882xx_update_algo_profile(struct aw882xx *aw882xx)
{ {
int ret = 0; int ret = -1;
int new_skt_prof_id = 0; int new_skt_prof_id = 0;
int cur_skt_prof_id = aw882xx->cur_algo_prof_id; int cur_skt_prof_id = aw882xx->cur_algo_prof_id;
struct aw_device *aw_dev = NULL; struct aw_device *aw_dev = NULL;
@@ -1712,32 +1778,15 @@ static int aw882xx_update_algo_profile(struct aw882xx *aw882xx)
aw_dev = aw882xx->aw_pa; aw_dev = aw882xx->aw_pa;
/* set new scene pramas to skt */ /* set new scene pramas to skt */
ret = aw_dev_set_algo_prof(aw_dev, aw882xx->cur_algo_prof_id); if (aw882xx->skt_prof_mode == AW_PARAMS_PATH_MODE) {
if (ret < 0) { ret = aw_dev_set_algo_prof(aw_dev, aw882xx->cur_algo_prof_id);
aw_dev_err(aw882xx->dev, "set algo prof failed"); } else {
return -1; ret = aw_dev_skt_prof_mode(aw_dev, aw882xx->cur_algo_prof_id);
if (ret < 0) {
aw_dev_err(aw882xx->dev, "set algo prof failed");
return -1;
}
} }
aw_dev_info(aw882xx->dev, "algo scene hold, cur scene %d",
new_skt_prof_id);
#ifdef AW882XX_SPIN_FOR_LOW_LATENCY_ONLY
aw_dev_info(aw882xx->dev, "g_skt_prof_id=%d\n",g_skt_prof_id);
if (new_skt_prof_id == (AW882XX_SCENE_FASTTRACK_ID+1)){
ret = aw_dev_set_spin(g_spin_value);
if (ret)
aw_dev_err(aw882xx->dev, "set spin error when switch prof id to %d, ret=%d", ret, new_skt_prof_id);
} else if ((g_skt_prof_id == (AW882XX_SCENE_FASTTRACK_ID+1))
&& (new_skt_prof_id != (AW882XX_SCENE_FASTTRACK_ID+1))){
ret = aw_dev_set_spin(1);
if (ret)
aw_dev_err(aw882xx->dev, "set spin error when switch prof id to %d, ret=%d", ret, new_skt_prof_id);
}
g_skt_prof_id = new_skt_prof_id;
#endif
return 0; return 0;
} }
@@ -2490,6 +2539,15 @@ static int aw882xx_parse_dt(struct device *dev, struct aw882xx *aw882xx,
__func__, aw882xx->fade_flag); __func__, aw882xx->fade_flag);
} }
ret = of_property_read_u32(np, "skt-prof-mode", &aw882xx->skt_prof_mode);
if (ret) {
aw882xx->skt_prof_mode = AW_PARAMS_PATH_MODE;
dev_err(dev, "%s: skt-prof-mode get failed,use default value!\n", __func__);
} else {
dev_info(dev, "%s: skt-prof-mode = %d\n",
__func__, aw882xx->skt_prof_mode);
}
return 0; return 0;
} }
@@ -3196,6 +3254,10 @@ static int aw882xx_i2c_remove(struct i2c_client *i2c)
vfree(g_awinic_cfg); vfree(g_awinic_cfg);
g_awinic_cfg = NULL; g_awinic_cfg = NULL;
} }
if (g_awinic_skt_cfg) {
vfree(g_awinic_skt_cfg);
g_awinic_skt_cfg = NULL;
}
} }
mutex_unlock(&g_aw882xx_lock); mutex_unlock(&g_aw882xx_lock);
+10 -1
View File
@@ -20,6 +20,8 @@
#define AW882XX_LOAD_FW_DELAY_TIME (0) #define AW882XX_LOAD_FW_DELAY_TIME (0)
#define AW_START_RETRIES (5) #define AW_START_RETRIES (5)
#define AW882XX_RUNIN_TEST #define AW882XX_RUNIN_TEST
#define AW_ALGO_SKT_BIN "aw_skt.bin"
#define AW_DEFAULT_PRO_ID (0xFFFFFFFF)
#define CONFIG_AW882XX_ALGO_BIN_PARAMS #define CONFIG_AW882XX_ALGO_BIN_PARAMS
#define AW_I2C_RETRIES 5 /* 5 times */ #define AW_I2C_RETRIES 5 /* 5 times */
@@ -75,6 +77,13 @@ struct aw882xx_scene_info {
int is_active; int is_active;
int active_cnt; int active_cnt;
}; };
enum {
AW_PARAMS_PATH_MODE = 0,
AW_PARAMS_DATA_MODE,
};
#endif #endif
@@ -218,7 +227,7 @@ struct aw882xx {
int aw882xx_algo_prof_id; int aw882xx_algo_prof_id;
int cur_algo_prof_id; int cur_algo_prof_id;
#endif #endif
unsigned int skt_prof_mode;
unsigned int fade_flag; unsigned int fade_flag;
unsigned char index; unsigned char index;
+26
View File
@@ -18,12 +18,14 @@ struct aw_msg_hdr {
#define CUSTOMER_NAME_MAX (16) #define CUSTOMER_NAME_MAX (16)
#define CFG_VERSION_MAX (4) #define CFG_VERSION_MAX (4)
#define DEV_NAME_MAX (16) #define DEV_NAME_MAX (16)
#define PROFILE_STR_MAX (32)
#define ACF_FILE_ID (0xa15f908) #define ACF_FILE_ID (0xa15f908)
enum aw_cfg_hdr_version { enum aw_cfg_hdr_version {
AW_CFG_HDR_VER_0_0_0_1 = 0x00000001, AW_CFG_HDR_VER_0_0_0_1 = 0x00000001,
AW_CFG_HDR_VER_1_0_0_0 = 0x01000000,
}; };
enum aw_cfg_dde_type { enum aw_cfg_dde_type {
@@ -53,6 +55,12 @@ enum profile_data_type {
AW_PROFILE_DATA_TYPE_MAX, AW_PROFILE_DATA_TYPE_MAX,
}; };
enum algo_profile_data_type {
AW_PROFILE_DATA_TYPE_ALGO_DSP,
AW_PROFILE_DATA_TYPE_ALGO_MAX,
};
enum aw_prof_type { enum aw_prof_type {
AW_PROFILE_MUSIC = 0, AW_PROFILE_MUSIC = 0,
AW_PROFILE_VOICE, AW_PROFILE_VOICE,
@@ -100,6 +108,22 @@ struct aw_cfg_dde {
uint32_t reserve[5]; uint32_t reserve[5];
}; };
struct aw_cfg_dde_v_1_0_0_0 {
uint32_t type; /*DDE type id*/
char dev_name[DEV_NAME_MAX];
uint16_t dev_index; /*dev id*/
uint16_t dev_bus; /*dev bus id*/
uint16_t dev_addr; /*dev addr id*/
uint16_t dev_profile; /*dev profile id*/
uint32_t data_type; /*data type id*/
uint32_t data_size;
uint32_t data_offset;
uint32_t data_crc;
char dev_profile_str[PROFILE_STR_MAX];
uint32_t chip_id;
uint32_t reserve[4];
};
struct aw_sec_data_desc { struct aw_sec_data_desc {
uint32_t len; uint32_t len;
unsigned char *data; unsigned char *data;
@@ -108,6 +132,7 @@ struct aw_sec_data_desc {
struct aw_prof_desc { struct aw_prof_desc {
uint32_t id; uint32_t id;
uint32_t prof_st; uint32_t prof_st;
char *prf_str;
struct aw_sec_data_desc sec_desc[AW_PROFILE_DATA_TYPE_MAX]; struct aw_sec_data_desc sec_desc[AW_PROFILE_DATA_TYPE_MAX];
}; };
@@ -117,6 +142,7 @@ struct aw_all_prof_info {
struct aw_prof_info { struct aw_prof_info {
int count; int count;
char **prof_name_list;
struct aw_prof_desc *prof_desc; struct aw_prof_desc *prof_desc;
}; };
+331
View File
@@ -150,6 +150,102 @@ static int aw_dev_check_cfg_by_hdr(struct aw_container *aw_cfg)
return 0; return 0;
} }
static int aw_dev_parse_check_acf_by_hdr_v_1_0_0_0(struct aw_container *aw_cfg)
{
struct aw_cfg_hdr *cfg_hdr = NULL;
struct aw_cfg_dde_v_1_0_0_0 *cfg_dde = NULL;
unsigned int end_data_offset = 0;
unsigned int act_data = 0;
unsigned int hdr_ddt_len = 0;
uint8_t act_crc8 = 0;
int i;
cfg_hdr = (struct aw_cfg_hdr *)aw_cfg->data;
/*check file type id is awinic acf file*/
if (cfg_hdr->a_id != ACF_FILE_ID) {
aw_pr_err("not acf type file");
return -EINVAL;
}
hdr_ddt_len = cfg_hdr->a_hdr_offset + cfg_hdr->a_ddt_size;
if (hdr_ddt_len > aw_cfg->len) {
aw_pr_err("hdrlen with ddt_len [%d] overflow file size[%d]",
cfg_hdr->a_hdr_offset, aw_cfg->len);
return -EINVAL;
}
/*check data size*/
cfg_dde = (struct aw_cfg_dde_v_1_0_0_0 *)((char *)aw_cfg->data + cfg_hdr->a_hdr_offset);
act_data += hdr_ddt_len;
for (i = 0; i < cfg_hdr->a_ddt_num; i++)
act_data += cfg_dde[i].data_size;
if (act_data != aw_cfg->len) {
aw_pr_err("act_data[%d] not equal to file size[%d]!",
act_data, aw_cfg->len);
return -EINVAL;
}
for (i = 0; i < cfg_hdr->a_ddt_num; i++) {
/* data check */
end_data_offset = cfg_dde[i].data_offset + cfg_dde[i].data_size;
if (end_data_offset > aw_cfg->len) {
aw_pr_err("a_ddt_num[%d] end_data_offset[%d] overflow file size[%d]",
i, end_data_offset, aw_cfg->len);
return -EINVAL;
}
/* crc check */
act_crc8 = aw_dev_crc8_check(aw_cfg->data + cfg_dde[i].data_offset, cfg_dde[i].data_size);
if (act_crc8 != cfg_dde[i].data_crc) {
aw_pr_err("a_ddt_num[%d] crc8 check failed, act_crc8:0x%x != data_crc 0x%x",
i, (uint32_t)act_crc8, cfg_dde[i].data_crc);
return -EINVAL;
}
}
aw_pr_info("project name [%s]", cfg_hdr->a_project);
aw_pr_info("custom name [%s]", cfg_hdr->a_custom);
aw_pr_info("version name [%d.%d.%d.%d]", cfg_hdr->a_version[3], cfg_hdr->a_version[2],
cfg_hdr->a_version[1], cfg_hdr->a_version[0]);
aw_pr_info("author id %d", cfg_hdr->a_author_id);
return 0;
}
static int aw_dev_parse_raw_dsp_skt(struct aw_device *aw_dev,
uint8_t *data, uint32_t data_len, struct aw_prof_desc *prof_desc)
{
aw_dev_info(aw_dev->dev, "data_size:%d enter", data_len);
prof_desc->sec_desc[AW_PROFILE_DATA_TYPE_ALGO_DSP].data = data;
prof_desc->sec_desc[AW_PROFILE_DATA_TYPE_ALGO_DSP].len = data_len;
return 0;
}
static int aw_dev_get_chan_group(struct aw_device *aw_dev, int *chan_group)
{
switch (aw_dev->channel) {
case AW_DEV_CH_PRI_L:
case AW_DEV_CH_PRI_R:
*chan_group = AW_DEV_CH_GROUP_PRI;
break;
case AW_DEV_CH_SEC_L:
case AW_DEV_CH_SEC_R:
*chan_group = AW_DEV_CH_GROUP_SEC;
break;
default:
aw_pr_err("can not find chan_group, channel %d ", aw_dev->channel);
return -EINVAL;
}
aw_pr_dbg("chan_group[%d] ", *chan_group);
return 0;
}
int aw_dev_load_acf_check(struct aw_container *aw_cfg) int aw_dev_load_acf_check(struct aw_container *aw_cfg)
{ {
struct aw_cfg_hdr *cfg_hdr = NULL; struct aw_cfg_hdr *cfg_hdr = NULL;
@@ -169,6 +265,8 @@ int aw_dev_load_acf_check(struct aw_container *aw_cfg)
switch (cfg_hdr->a_hdr_version) { switch (cfg_hdr->a_hdr_version) {
case AW_CFG_HDR_VER_0_0_0_1: case AW_CFG_HDR_VER_0_0_0_1:
return aw_dev_check_cfg_by_hdr(aw_cfg); return aw_dev_check_cfg_by_hdr(aw_cfg);
case AW_CFG_HDR_VER_1_0_0_0:
return aw_dev_parse_check_acf_by_hdr_v_1_0_0_0(aw_cfg);
default: default:
aw_pr_err("unsupported hdr_version [0x%x]", cfg_hdr->a_hdr_version); aw_pr_err("unsupported hdr_version [0x%x]", cfg_hdr->a_hdr_version);
return -EINVAL; return -EINVAL;
@@ -452,6 +550,234 @@ static int aw_dev_cfg_get_vaild_prof(struct aw_device *aw_dev,
return 0; return 0;
} }
/******************ACF bin format V1.0.0.0************************/
static int aw_dev_parse_get_scene_count_v1_0_0_0(struct aw_device *aw_dev,
struct aw_container *aw_cfg, int *count)
{
struct aw_cfg_hdr *cfg_hdr = (struct aw_cfg_hdr *)aw_cfg->data;
struct aw_cfg_dde_v_1_0_0_0 *cfg_dde =
(struct aw_cfg_dde_v_1_0_0_0 *)(aw_cfg->data + cfg_hdr->a_hdr_offset);
int i = 0;
int chan_group = -1;
int ret = -1;
ret = aw_dev_get_chan_group(aw_dev, &chan_group);
if (ret < 0) {
aw_dev_err(aw_dev->dev, "get chan_group failed ");
return ret;
}
for (i = 0; i < cfg_hdr->a_ddt_num; ++i) {
if ((cfg_dde[i].data_type == ACF_SEC_TYPE_DSP) &&
(cfg_dde[i].type == AW_SKT_TYPE_ID) &&
(chan_group == cfg_dde[i].dev_index)) {
(*count)++;
}
}
if ((*count) == 0) {
aw_dev_err(aw_dev->dev, "can't find scene");
return -EINVAL;
}
aw_dev_info(aw_dev->dev, "scene count is %d", (*count));
return 0;
}
static int aw_dev_parse_create_prof_name_list_v_1_0_0_0(struct aw_device *aw_dev)
{
struct aw_prof_info *prof_info = &aw_dev->skt_prof_info;
struct aw_prof_desc *prof_desc= prof_info->prof_desc;
int i;
if (prof_desc == NULL) {
aw_dev_err(aw_dev->dev, "prof_desc is NULL");
return -EINVAL;
}
prof_info->prof_name_list = devm_kzalloc(aw_dev->dev,
prof_info->count * PROFILE_STR_MAX,
GFP_KERNEL);
if (prof_info->prof_name_list == NULL) {
aw_dev_err(aw_dev->dev, "prof_name_list devm_kzalloc failed");
return -ENOMEM;
}
for (i = 0; i < prof_info->count; i++) {
prof_info->prof_name_list[i] = prof_desc[i].prf_str;
aw_dev_info(aw_dev->dev, "prof name list[%d]:%s, id=%d", i, prof_info->prof_name_list[i], prof_desc[i].id);
}
return 0;
}
static int aw_dev_parse_skt_type_v_1_0_0_0(struct aw_device *aw_dev,
struct aw_cfg_hdr *prof_hdr)
{
int i = 0;
int ret = -1;
int scene_count = 0;
struct aw_prof_info *prof_info = &aw_dev->skt_prof_info;
struct aw_cfg_dde_v_1_0_0_0 *cfg_dde =
(struct aw_cfg_dde_v_1_0_0_0 *)((char *)prof_hdr + prof_hdr->a_hdr_offset);
int chan_group = -1;
aw_dev_info(aw_dev->dev, "enter");
ret = aw_dev_get_chan_group(aw_dev, &chan_group);
if (ret < 0) {
aw_dev_err(aw_dev->dev, "get chan_group failed ");
return ret;
}
for (i = 0; i < prof_hdr->a_ddt_num; i++) {
if ((cfg_dde[i].type == AW_SKT_TYPE_ID) &&
(cfg_dde[i].data_type == ACF_SEC_TYPE_DSP) &&
(chan_group == cfg_dde[i].dev_index)) {
ret = aw_dev_parse_raw_dsp_skt(aw_dev,
(uint8_t *)prof_hdr + cfg_dde[i].data_offset,
cfg_dde[i].data_size, &prof_info->prof_desc[scene_count]);
if (ret < 0) {
aw_dev_err(aw_dev->dev, "parse dsp bin data failed");
return ret;
}
prof_info->prof_desc[scene_count].prf_str = cfg_dde[i].dev_profile_str;
prof_info->prof_desc[scene_count].id = cfg_dde[i].dev_profile;
scene_count++;
}
}
aw_dev_dbg(aw_dev->dev, "scene_count = %d", scene_count);
return 0;
}
static int aw_dev_parse_acf_by_hdr_v_1_0_0_0(struct aw_device *aw_dev, struct aw_container *aw_cfg)
{
struct aw_prof_info *prof_info = &aw_dev->skt_prof_info;
struct aw_cfg_hdr *cfg_hdr = (struct aw_cfg_hdr *)aw_cfg->data;
int ret;
ret = aw_dev_parse_get_scene_count_v1_0_0_0(aw_dev, aw_cfg, &prof_info->count);
if (ret < 0) {
aw_dev_err(aw_dev->dev, "get scene count failed");
return ret;
}
prof_info->prof_desc = devm_kzalloc(aw_dev->dev,
prof_info->count * sizeof(struct aw_prof_desc),
GFP_KERNEL);
if (prof_info->prof_desc == NULL) {
aw_dev_err(aw_dev->dev, "prof_desc devm_kzalloc failed");
return -ENOMEM;
}
ret = aw_dev_parse_skt_type_v_1_0_0_0(aw_dev, cfg_hdr);
if (ret < 0) {
aw_dev_err(aw_dev->dev, " failed");
return ret;
}
ret = aw_dev_parse_create_prof_name_list_v_1_0_0_0(aw_dev);
if (ret < 0) {
aw_dev_err(aw_dev->dev, "create prof name list failed");
return ret;
}
return 0;
}
int aw_dev_parse_skt_bin(struct aw_device *aw_dev, struct aw_container *aw_cfg)
{
struct aw_cfg_hdr *cfg_hdr = NULL;
int ret = -1;
if (aw_dev == NULL || aw_cfg == NULL) {
aw_dev_err(aw_dev->dev, "pointer is NULL");
return -ENOMEM;
}
cfg_hdr = (struct aw_cfg_hdr *)aw_cfg->data;
if (cfg_hdr->a_hdr_version == AW_CFG_HDR_VER_1_0_0_0) {
ret = aw_dev_parse_acf_by_hdr_v_1_0_0_0(aw_dev, aw_cfg);
if (ret < 0) {
aw_dev_err(aw_dev->dev, "hdr_cersion[0x%x] parse failed",
cfg_hdr->a_hdr_version);
return ret;
}
} else {
aw_dev_err(aw_dev->dev, "skt bin format [0x%x] unsupported", cfg_hdr->a_hdr_version);
}
return 0;
}
struct aw_sec_data_desc *aw_dev_get_algo_prof_data(struct aw_device *aw_dev, int prof_id)
{
struct aw_sec_data_desc *prof_data = NULL;
struct aw_prof_info *prof_info = &aw_dev->skt_prof_info;
int i;
aw_dev_dbg(aw_dev->dev, "prof num = %d", prof_info->count);
for (i = 0; i < prof_info->count; i++) {
if (prof_id == prof_info->prof_desc[i].id) {
prof_data = &prof_info->prof_desc[i].sec_desc[AW_PROFILE_DATA_TYPE_ALGO_DSP];
break;
}
}
return prof_data;
}
int aw_dev_skt_prof_mode(struct aw_device *aw_dev, int prof_id)
{
struct aw_sec_data_desc *prof_data = NULL;
int ret = -1;
struct list_head *dev_list = NULL;
struct list_head *pos = NULL;
struct aw_device *local_dev = NULL;
ret = aw_dev_get_list_head(&dev_list);
if (ret) {
aw_dev_err(aw_dev->dev, "get dev list failed ");
return ret;
}
aw_dev_info(aw_dev->dev, "set_cur_prof=%d,pre_prof=%d",
prof_id, aw_dev->pre_prof_id);
if (prof_id != aw_dev->pre_prof_id) {
list_for_each (pos, dev_list) {
local_dev = container_of(pos, struct aw_device, list_node);
if ((local_dev->channel == AW_DEV_CH_PRI_L) || (local_dev->channel == AW_DEV_CH_SEC_L)) {
prof_data = aw_dev_get_algo_prof_data(local_dev, prof_id);
if (prof_data) {
ret = aw_dev_set_algo_prof_data(local_dev, prof_data->data, prof_data->len);
if (ret < 0) {
aw_dev_err(local_dev->dev, "set algo prof [%d] failed", prof_id);
return -EINVAL;
}
} else {
aw_dev_err(local_dev->dev, "prof data is NULL");
return -EINVAL;
}
}
}
aw_dev->pre_prof_id = prof_id;
aw_dev_info(aw_dev->dev, "set algo prof [%d] ok", prof_id);
}
return 0;
}
static int aw_dev_cfg_load(struct aw_device *aw_dev, struct aw_container *aw_cfg) static int aw_dev_cfg_load(struct aw_device *aw_dev, struct aw_container *aw_cfg)
{ {
struct aw_cfg_hdr *cfg_hdr = NULL; struct aw_cfg_hdr *cfg_hdr = NULL;
@@ -1503,6 +1829,11 @@ int aw_dev_get_spin(int *spin_mode)
return aw_dsp_read_spin(spin_mode); return aw_dsp_read_spin(spin_mode);
} }
int aw_dev_set_algo_prof_data(struct aw_device *aw_dev, void *prof_data, unsigned int prof_len)
{
return aw_dsp_set_algo_prof_data(aw_dev, prof_data, prof_len);
}
int aw_dev_set_algo_prof(struct aw_device *aw_dev, int prof_id) int aw_dev_set_algo_prof(struct aw_device *aw_dev, int prof_id)
{ {
return aw_dsp_set_algo_prof(aw_dev, prof_id); return aw_dsp_set_algo_prof(aw_dev, prof_id);
+12 -1
View File
@@ -58,6 +58,12 @@ enum AW_DEV_FW_STATUS {
AW_DEV_FW_OK, AW_DEV_FW_OK,
}; };
enum {
AW_DEV_CH_GROUP_PRI = 0,
AW_DEV_CH_GROUP_SEC = 1,
AW_DEV_CH_GROUP_MAX,
};
struct aw_device_ops { struct aw_device_ops {
int (*aw_i2c_write)(struct aw_device *aw_dev, unsigned char reg_addr, unsigned int reg_data); int (*aw_i2c_write)(struct aw_device *aw_dev, unsigned char reg_addr, unsigned int reg_data);
int (*aw_i2c_read)(struct aw_device *aw_dev, unsigned char reg_addr, unsigned int *reg_data); int (*aw_i2c_read)(struct aw_device *aw_dev, unsigned char reg_addr, unsigned int *reg_data);
@@ -234,6 +240,7 @@ struct aw_device {
char monitor_name[AW_NAME_MAX]; char monitor_name[AW_NAME_MAX];
void *private_data; void *private_data;
char algo_path[AW_ALGO_PATH_MAX]; char algo_path[AW_ALGO_PATH_MAX];
int pre_prof_id;
struct aw_int_desc int_desc; struct aw_int_desc int_desc;
struct aw_pwd_desc pwd_desc; struct aw_pwd_desc pwd_desc;
@@ -249,6 +256,7 @@ struct aw_device {
struct aw_ipeak_desc ipeak_desc; struct aw_ipeak_desc ipeak_desc;
struct aw_volume_desc volume_desc; struct aw_volume_desc volume_desc;
struct aw_prof_info prof_info; struct aw_prof_info prof_info;
struct aw_prof_info skt_prof_info;
struct aw_cali_desc cali_desc; struct aw_cali_desc cali_desc;
struct aw_monitor_desc monitor_desc; struct aw_monitor_desc monitor_desc;
struct aw_soft_rst soft_rst; struct aw_soft_rst soft_rst;
@@ -258,10 +266,11 @@ struct aw_device {
struct list_head list_node; struct list_head list_node;
}; };
struct aw_sec_data_desc *aw_dev_get_algo_prof_data(struct aw_device *aw_dev, int prof_id);
int aw_dev_load_acf_check(struct aw_container *aw_cfg); int aw_dev_load_acf_check(struct aw_container *aw_cfg);
void aw_dev_deinit(struct aw_device *aw_dev); void aw_dev_deinit(struct aw_device *aw_dev);
int aw_device_init(struct aw_device *aw_dev, struct aw_container *aw_cfg); int aw_device_init(struct aw_device *aw_dev, struct aw_container *aw_cfg);
int aw_dev_parse_skt_bin(struct aw_device *aw_dev, struct aw_container *aw_cfg);
int aw_device_start(struct aw_device *aw_dev); int aw_device_start(struct aw_device *aw_dev);
int aw_device_stop(struct aw_device *aw_dev); int aw_device_stop(struct aw_device *aw_dev);
int aw_dev_reg_update(struct aw_device *aw_dev, bool force); int aw_dev_reg_update(struct aw_device *aw_dev, bool force);
@@ -298,6 +307,8 @@ int aw_dev_get_afe_module_en(int type, int *status);
int aw_dev_set_copp_module_en(bool enable); int aw_dev_set_copp_module_en(bool enable);
int aw_dev_set_spin(int spin_mode); int aw_dev_set_spin(int spin_mode);
int aw_dev_get_spin(int *spin_mode); int aw_dev_get_spin(int *spin_mode);
int aw_dev_skt_prof_mode(struct aw_device *aw_dev, int prof_id);
int aw_dev_set_algo_prof_data(struct aw_device *aw_dev, void *prof_data, unsigned int prof_len);
int aw_dev_set_algo_prof(struct aw_device *aw_dev, int prof_id); int aw_dev_set_algo_prof(struct aw_device *aw_dev, int prof_id);
int aw_dev_get_algo_prof(struct aw_device *aw_dev, int *prof_id); int aw_dev_get_algo_prof(struct aw_device *aw_dev, int *prof_id);
int aw_dev_set_algo_params_path(struct aw_device *aw_dev); int aw_dev_set_algo_params_path(struct aw_device *aw_dev);
+28
View File
@@ -29,6 +29,8 @@ static DEFINE_MUTEX(g_aw_dsp_lock);
#define AW_MSG_ID_ALGO_PARAMS_PATH (0x00000014) #define AW_MSG_ID_ALGO_PARAMS_PATH (0x00000014)
#define AW_MSG_ID_VERSION (0x00000008) #define AW_MSG_ID_VERSION (0x00000008)
#define AW_MSG_ID_VERSION_NEW (0x00000012) #define AW_MSG_ID_VERSION_NEW (0x00000012)
#define AW_MSG_ID_SET_ALGO_PROF_PRI (0x10013D25)
#define AW_MSG_ID_SET_ALGO_PROF_SEC (0x10013D2C)
/*dsp params id*/ /*dsp params id*/
@@ -389,6 +391,32 @@ static int aw_write_data_to_dsp(uint32_t param_id, void *data, int size)
} }
/************************* dsp communication function *****************************/ /************************* dsp communication function *****************************/
int aw_dsp_set_algo_prof_data(struct aw_device *aw_dev, void *data, unsigned int size)
{
int ret = 0;
uint32_t params_id = 0;
if (aw_dev->channel == AW_DEV_CH_PRI_L) {
params_id = AW_MSG_ID_SET_ALGO_PROF_PRI;
} else if (aw_dev->channel == AW_DEV_CH_SEC_L) {
params_id = AW_MSG_ID_SET_ALGO_PROF_SEC;
} else {
aw_dev_err(aw_dev->dev, "unsupport dev channel");
return -EINVAL;
}
aw_dev_dbg(aw_dev->dev, "params_id=%u,prof_data:%p, len=%u", params_id, data, size);
ret = aw_qcom_write_data_to_dsp(params_id, data, size);
if (ret < 0) {
aw_pr_err("write prof_id failed ");
return ret;
}
aw_pr_dbg("write prof_id done");
return 0;
}
int aw_dsp_set_algo_prof(struct aw_device *aw_dev, int prof_id) int aw_dsp_set_algo_prof(struct aw_device *aw_dev, int prof_id)
{ {
+1
View File
@@ -67,6 +67,7 @@ int aw_dsp_set_copp_module_en(bool enable);
int aw_dsp_write_spin(int spin_mode); int aw_dsp_write_spin(int spin_mode);
int aw_dsp_read_spin(int *spin_mode); int aw_dsp_read_spin(int *spin_mode);
int aw_get_algo_version(struct aw_device *aw_dev, char *algo_ver_buf); int aw_get_algo_version(struct aw_device *aw_dev, char *algo_ver_buf);
int aw_dsp_set_algo_prof_data(struct aw_device *aw_dev, void *data, unsigned int size);
int aw_dsp_set_algo_prof(struct aw_device *aw_dev, int prof_id); int aw_dsp_set_algo_prof(struct aw_device *aw_dev, int prof_id);
int aw_dsp_get_algo_prof(struct aw_device *aw_dev, int *prof_id); int aw_dsp_get_algo_prof(struct aw_device *aw_dev, int *prof_id);
int aw_dsp_set_algo_params_path(struct aw_device *aw_dev); int aw_dsp_set_algo_params_path(struct aw_device *aw_dev);