diff --git a/sound/soc/codecs/aw87xxx/aw87xxx.c b/sound/soc/codecs/aw87xxx/aw87xxx.c index a3c79298ec66..aa18ce665a47 100644 --- a/sound/soc/codecs/aw87xxx/aw87xxx.c +++ b/sound/soc/codecs/aw87xxx/aw87xxx.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * aw87xxx.c aw87xxx pa module * @@ -41,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -50,12 +52,13 @@ #include "aw_monitor.h" #include "aw_acf_bin.h" #include "aw_bin_parse.h" +#include "aw_dsp.h" /***************************************************************** -* aw87xxx marco -******************************************************************/ + * aw87xxx marco + ******************************************************************/ #define AW87XXX_I2C_NAME "aw87xxx_pa" -#define AW87XXX_DRIVER_VERSION "v2.2.0" +#define AW87XXX_DRIVER_VERSION "v2.14.0" #define AW87XXX_FW_BIN_NAME "aw87xxx_acf.bin" /************************************************************************* @@ -63,8 +66,11 @@ ************************************************************************/ static LIST_HEAD(g_aw87xxx_list); static DEFINE_MUTEX(g_aw87xxx_mutex_lock); -unsigned int g_aw87xxx_dev_cnt = 0; +unsigned int g_aw87xxx_dev_cnt; +static const char *const aw87xxx_monitor_switch[] = {"Disable", "Enable"}; +static const char *const aw87xxx_spin_switch[] = {"spin_0", "spin_90", + "spin_180", "spin_270"}; #ifdef AW_KERNEL_VER_OVER_4_19_1 static struct aw_componet_codec_ops aw_componet_codec_ops = { .add_codec_controls = snd_soc_add_component_controls, @@ -83,20 +89,54 @@ static struct aw_componet_codec_ops aw_componet_codec_ops = { * aw87xxx device update profile * ************************************************************************/ -static int aw87xxx_update_off_prof(struct aw87xxx *aw87xxx, char *profile) +#ifdef AW_ALGO_AUTH_DSP +static void aw87xxx_algo_auth_work(struct work_struct *work) +{ + struct aw87xxx *aw87xxx = container_of(work, + struct aw87xxx, auth_work.work); + + AW_DEV_LOGI(aw87xxx->dev, "enter"); + + aw87xxx_dev_algo_authentication(&aw87xxx->aw_dev); +} +#endif + +static void aw87xxx_update_voltage_max(struct aw87xxx *aw87xxx, + struct aw_data_container *data_container) +{ + int i = 0; + struct aw_voltage_desc *vol_desc = &aw87xxx->aw_dev.vol_desc; + + if (data_container == NULL || data_container->len <= 2 + || vol_desc->addr == AW_REG_NONE) + return; + + for (i = 0; i < data_container->len; i = i + 2) { + if (data_container->data[i] == vol_desc->addr) { + vol_desc->vol_max = data_container->data[i + 1]; + AW_DEV_LOGD(aw87xxx->dev, "get voltage max = 0x%02x", + data_container->data[i + 1]); + return; + } + } +} + +static int aw87xxx_power_down(struct aw87xxx *aw87xxx, char *profile) { int ret = 0; struct aw_prof_desc *prof_desc = NULL; + struct aw_prof_info *prof_info = &aw87xxx->acf_info.prof_info; struct aw_data_container *data_container = NULL; struct aw_device *aw_dev = &aw87xxx->aw_dev; AW_DEV_LOGD(aw87xxx->dev, "enter"); - mutex_lock(&aw87xxx->reg_lock); + if (!prof_info->status) { + AW_DEV_LOGE(aw87xxx->dev, "profile_cfg not load"); + return -EINVAL; + } - aw_monitor_stop(&aw87xxx->monitor); - - prof_desc = aw_acf_get_prof_desc_form_name(aw87xxx->dev, &aw87xxx->acf_info, profile); + prof_desc = aw87xxx_acf_get_prof_desc_form_name(aw87xxx->dev, &aw87xxx->acf_info, profile); if (prof_desc == NULL) goto no_bin_pwr_off; @@ -118,7 +158,7 @@ static int aw87xxx_update_off_prof(struct aw87xxx *aw87xxx, char *profile) goto pwr_off_failed; } } else { - ret = aw_dev_default_pwr_off(aw_dev, data_container); + ret = aw87xxx_dev_default_pwr_off(aw_dev, data_container); if (ret < 0) { AW_DEV_LOGE(aw87xxx->dev, "load profile[%s] failed ", profile); goto pwr_off_failed; @@ -127,19 +167,22 @@ static int aw87xxx_update_off_prof(struct aw87xxx *aw87xxx, char *profile) } aw87xxx->current_profile = prof_desc->prof_name; - mutex_unlock(&aw87xxx->reg_lock); + +#ifdef AW_ALGO_AUTH_DSP + g_algo_auth_st = AW_ALGO_AUTH_WAIT; + cancel_delayed_work_sync(&aw87xxx->auth_work); +#endif return 0; pwr_off_failed: no_bin_pwr_off: - aw_dev_hw_pwr_ctrl(&aw87xxx->aw_dev, false); + aw87xxx_dev_hw_pwr_ctrl(&aw87xxx->aw_dev, false); aw87xxx->current_profile = aw87xxx->prof_off_name; - mutex_unlock(&aw87xxx->reg_lock); return ret; } -int aw87xxx_update_profile(struct aw87xxx *aw87xxx, char *profile) +static int aw87xxx_power_on(struct aw87xxx *aw87xxx, char *profile) { int ret = -EINVAL; struct aw_prof_desc *prof_desc = NULL; @@ -154,57 +197,91 @@ int aw87xxx_update_profile(struct aw87xxx *aw87xxx, char *profile) return -EINVAL; } - if (0 == strncmp(profile, aw87xxx->prof_off_name, AW_PROFILE_STR_MAX)) - return aw87xxx_update_off_prof(aw87xxx, profile); + if (strncmp(profile, aw87xxx->prof_off_name, AW_PROFILE_STR_MAX) == 0) + return aw87xxx_power_down(aw87xxx, profile); - mutex_lock(&aw87xxx->reg_lock); - - prof_desc = aw_acf_get_prof_desc_form_name(aw87xxx->dev, &aw87xxx->acf_info, profile); + prof_desc = aw87xxx_acf_get_prof_desc_form_name(aw87xxx->dev, &aw87xxx->acf_info, profile); if (prof_desc == NULL) { AW_DEV_LOGE(aw87xxx->dev, "not found [%s] parameter", profile); - mutex_unlock(&aw87xxx->reg_lock); return -EINVAL; } if (!prof_desc->prof_st) { AW_DEV_LOGE(aw87xxx->dev, "not found data container"); - mutex_unlock(&aw87xxx->reg_lock); return -EINVAL; } data_container = &prof_desc->data_container; AW_DEV_LOGD(aw87xxx->dev, "get profile[%s] data len [%d]", profile, data_container->len); - - aw_monitor_stop(&aw87xxx->monitor); - + aw87xxx_update_voltage_max(aw87xxx, data_container); if (aw_dev->ops.pwr_on_func) { ret = aw_dev->ops.pwr_on_func(aw_dev, data_container); if (ret < 0) { AW_DEV_LOGE(aw87xxx->dev, "load profile[%s] failed ", profile); - mutex_unlock(&aw87xxx->reg_lock); - return aw87xxx_update_off_prof(aw87xxx, aw87xxx->prof_off_name); + return aw87xxx_power_down(aw87xxx, aw87xxx->prof_off_name); } } else { - ret = aw_dev_default_pwr_on(aw_dev, data_container); + ret = aw87xxx_dev_default_pwr_on(aw_dev, data_container); if (ret < 0) { AW_DEV_LOGE(aw87xxx->dev, "load profile[%s] failed ", profile); - mutex_unlock(&aw87xxx->reg_lock); - return aw87xxx_update_off_prof(aw87xxx, aw87xxx->prof_off_name); + return aw87xxx_power_down(aw87xxx, aw87xxx->prof_off_name); } } aw87xxx->current_profile = prof_desc->prof_name; - aw_monitor_start(&aw87xxx->monitor); - mutex_unlock(&aw87xxx->reg_lock); +#ifdef AW_ALGO_AUTH_DSP + INIT_DELAYED_WORK(&aw87xxx->auth_work, aw87xxx_algo_auth_work); + schedule_delayed_work(&aw87xxx->auth_work, msecs_to_jiffies(3000)); +#endif AW_DEV_LOGD(aw87xxx->dev, "load profile[%s] succeed", profile); return 0; } +int aw87xxx_update_profile(struct aw87xxx *aw87xxx, char *profile) +{ + int ret = -1; + + AW_DEV_LOGD(aw87xxx->dev, "load profile[%s] enter", profile); + + mutex_lock(&aw87xxx->reg_lock); + aw87xxx_monitor_stop(&aw87xxx->monitor); + if (strncmp(profile, aw87xxx->prof_off_name, AW_PROFILE_STR_MAX) == 0) { + ret = aw87xxx_power_down(aw87xxx, profile); + } else { + ret = aw87xxx_power_down(aw87xxx, aw87xxx->prof_off_name); + if (ret < 0) { + AW_DEV_LOGE(aw87xxx->dev, "load profile[%s] failed!", aw87xxx->prof_off_name); + mutex_unlock(&aw87xxx->reg_lock); + return ret; + } + + ret = aw87xxx_power_on(aw87xxx, profile); + if (!ret) + aw87xxx_monitor_start(&aw87xxx->monitor); + } + mutex_unlock(&aw87xxx->reg_lock); + + return ret; +} + +int aw87xxx_update_profile_esd(struct aw87xxx *aw87xxx, char *profile) +{ + int ret = -1; + + aw87xxx_dev_soft_reset(&aw87xxx->aw_dev); + if (strncmp(profile, aw87xxx->prof_off_name, AW_PROFILE_STR_MAX) == 0) + ret = aw87xxx_power_down(aw87xxx, profile); + else + ret = aw87xxx_power_on(aw87xxx, profile); + + return ret; +} + char *aw87xxx_show_current_profile(int dev_index) { struct list_head *pos = NULL; @@ -212,11 +289,6 @@ char *aw87xxx_show_current_profile(int dev_index) list_for_each(pos, &g_aw87xxx_list) { aw87xxx = list_entry(pos, struct aw87xxx, list); - if (aw87xxx == NULL) { - AW_LOGE("struct aw87xxx not ready"); - return NULL; - } - if (aw87xxx->dev_index == dev_index) { AW_DEV_LOGI(aw87xxx->dev, "current profile is [%s]", aw87xxx->current_profile); @@ -234,15 +306,18 @@ int aw87xxx_set_profile(int dev_index, char *profile) struct list_head *pos = NULL; struct aw87xxx *aw87xxx = NULL; + if (!profile) { + AW_LOGE("profile is NULL"); + return -EINVAL; + } + list_for_each(pos, &g_aw87xxx_list) { aw87xxx = list_entry(pos, struct aw87xxx, list); - if (aw87xxx == NULL) { - AW_LOGE("struct aw87xxx not ready"); - return -EINVAL; - } - - if (profile && aw87xxx->dev_index == dev_index) + if (aw87xxx->dev_index == dev_index) { + AW_DEV_LOGD(aw87xxx->dev, "set dev_index = %d, profile = %s", + dev_index, profile); return aw87xxx_update_profile(aw87xxx, profile); + } } AW_LOGE("not found struct aw87xxx, dev_index = [%d]", dev_index); @@ -250,113 +325,301 @@ int aw87xxx_set_profile(int dev_index, char *profile) } EXPORT_SYMBOL(aw87xxx_set_profile); -/************************************************************************ - * - * aw87xxx esd update profile - * - ************************************************************************/ -static int aw87xxx_esd_update_off_prof(struct aw87xxx *aw87xxx, char *profile) +int aw87xxx_set_profile_by_id(int dev_index, int profile_id) +{ + char *profile = NULL; + + profile = aw87xxx_ctos_get_prof_name(profile_id); + if (profile == NULL) { + AW_LOGE("aw87xxx, dev_index[%d] profile[%d] not support!", + dev_index, profile_id); + return -EINVAL; + } + + AW_LOGI("aw87xxx, dev_index[%d] set profile[%s] by id[%d]", + dev_index, profile, profile_id); + return aw87xxx_set_profile(dev_index, profile); +} +EXPORT_SYMBOL(aw87xxx_set_profile_by_id); + +int aw87xxx_set_boost_voltage(int dev_index, int status) { int ret = 0; - struct aw_prof_desc *prof_desc = NULL; - struct aw_data_container *data_container = NULL; - struct aw_device *aw_dev = &aw87xxx->aw_dev; + struct list_head *pos = NULL; + struct aw87xxx *aw87xxx = NULL; + struct aw_voltage_desc *vol_desc = NULL; - AW_DEV_LOGD(aw87xxx->dev, "enter"); - prof_desc = aw_acf_get_prof_desc_form_name(aw87xxx->dev, &aw87xxx->acf_info, profile); - if (prof_desc == NULL) - goto no_bin_pwr_off; + list_for_each(pos, &g_aw87xxx_list) { + aw87xxx = list_entry(pos, struct aw87xxx, list); + if (aw87xxx == NULL) { + AW_LOGE("struct aw87xxx not ready"); + return -EINVAL; + } - if (!prof_desc->prof_st) - goto no_bin_pwr_off; - - data_container = &prof_desc->data_container; - AW_DEV_LOGD(aw87xxx->dev, "get profile[%s] data len [%d]", - profile, data_container->len); - - if (aw_dev->hwen_status == AW_DEV_HWEN_OFF) { - AW_DEV_LOGI(aw87xxx->dev, "profile[%s] has already load ", profile); - } else { - if (aw_dev->ops.pwr_off_func) { - ret = aw_dev->ops.pwr_off_func(aw_dev, data_container); - if (ret < 0) { - AW_DEV_LOGE(aw87xxx->dev, "load profile[%s] failed ", profile); - goto pwr_off_failed; + if (aw87xxx->dev_index == dev_index) { + AW_DEV_LOGD(aw87xxx->dev, "enter, set dev_index = %d, status = %d", dev_index, status); + if (strncmp(aw87xxx->current_profile, aw87xxx->prof_off_name, AW_PROFILE_STR_MAX) == 0) { + AW_DEV_LOGE(aw87xxx->dev, "PA is power down, can not set voltage!"); + return -EINVAL; } - } else { - ret = aw_dev_default_pwr_off(aw_dev, data_container); - if (ret < 0) { - AW_DEV_LOGE(aw87xxx->dev, "load profile[%s] failed ", profile); - goto pwr_off_failed; + + vol_desc = &aw87xxx->aw_dev.vol_desc; + if (vol_desc->addr == AW_REG_NONE) { + AW_DEV_LOGI(aw87xxx->dev, "PA unsupport set boost voltage!"); + return -EINVAL; } + if (status == AW_VOLTAGE_HIGH) { + AW_DEV_LOGI(aw87xxx->dev, "set reg voltage max: 0x%02x = 0x%02x", + vol_desc->addr, vol_desc->vol_max); + ret = aw87xxx_dev_i2c_write_byte(&aw87xxx->aw_dev, + vol_desc->addr, vol_desc->vol_max); + if (ret < 0) + return ret; + } else if (status == AW_VOLTAGE_LOW) { + AW_DEV_LOGI(aw87xxx->dev, "set reg voltage min: 0x%02x = 0x%02x", + vol_desc->addr, vol_desc->vol_min); + ret = aw87xxx_dev_i2c_write_byte(&aw87xxx->aw_dev, + vol_desc->addr, vol_desc->vol_min); + if (ret < 0) + return ret; + } else { + AW_DEV_LOGE(aw87xxx->dev, "unsupport status: %d", status); + return -EINVAL; + } + + return 0; } } - aw87xxx->current_profile = prof_desc->prof_name; - return 0; + AW_LOGE("not found struct aw87xxx, dev_index = [%d]", dev_index); + return -EINVAL; +} +EXPORT_SYMBOL(aw87xxx_set_boost_voltage); + +int aw87xxx_get_boost_voltage(int dev_index, int *status) +{ + int ret = 0; + struct list_head *pos = NULL; + struct aw87xxx *aw87xxx = NULL; + uint8_t reg_voltage_val = 0; + struct aw_voltage_desc *vol_desc = NULL; + + list_for_each(pos, &g_aw87xxx_list) { + aw87xxx = list_entry(pos, struct aw87xxx, list); + if (aw87xxx == NULL) { + AW_LOGE("struct aw87xxx not ready"); + return -EINVAL; + } + + if (aw87xxx->dev_index == dev_index) { + if (strncmp(aw87xxx->current_profile, aw87xxx->prof_off_name, AW_PROFILE_STR_MAX) == 0) { + AW_DEV_LOGE(aw87xxx->dev, "PA is power down, can not get voltage!"); + return -EINVAL; + } + + vol_desc = &aw87xxx->aw_dev.vol_desc; + if (vol_desc->addr == AW_REG_NONE) { + AW_DEV_LOGI(aw87xxx->dev, "PA unsupport get boost voltage!"); + return -EINVAL; + } + ret = aw87xxx_dev_i2c_read_byte(&aw87xxx->aw_dev, + vol_desc->addr, ®_voltage_val); + if (ret < 0) + return ret; + + if (reg_voltage_val == vol_desc->vol_max) { + *status = AW_VOLTAGE_HIGH; + } else if (reg_voltage_val == vol_desc->vol_min) { + *status = AW_VOLTAGE_LOW; + } else { + AW_DEV_LOGE(aw87xxx->dev, "undefined reg val 0x%02x = 0x%02x", + vol_desc->addr, reg_voltage_val); + return -EINVAL; + } + + return 0; + } + } + + AW_LOGE("not found struct aw87xxx, dev_index = [%d]", dev_index); + return -EINVAL; +} +EXPORT_SYMBOL(aw87xxx_get_boost_voltage); + +/*********************************algo_auth_misc*************************************/ +static int aw87xxx_algo_auth_misc_ops_write(struct aw87xxx *aw87xxx, + unsigned int cmd, unsigned long arg) +{ + int ret = 0; + unsigned int data_len = _IOC_SIZE(cmd); + struct aw_device *aw_dev = &aw87xxx->aw_dev; + struct algo_auth_data algo_data; + + AW_DEV_LOGD(aw_dev->dev, "write algo auth data, len=%d", data_len); + + if (copy_from_user(&algo_data, (void __user *)arg, data_len)) + ret = -EFAULT; + + aw87xxx_dev_algo_auth_mode(aw_dev, &algo_data); + + AW_DEV_LOGD(aw_dev->dev, "ret=%d,mode=%d,reg_crc=0x%x,random=0x%x,id=0x%x,res=%d", + ret, algo_data.auth_mode, algo_data.reg_crc, algo_data.random, + algo_data.chip_id, algo_data.check_result); -pwr_off_failed: -no_bin_pwr_off: - aw_dev_hw_pwr_ctrl(&aw87xxx->aw_dev, false); - aw87xxx->current_profile = aw87xxx->prof_off_name; return ret; } -int aw87xxx_esd_update_profile(struct aw87xxx *aw87xxx, char *profile) +static int aw87xxx_algo_auth_misc_ops_read(struct aw87xxx *aw87xxx, + unsigned int cmd, unsigned long arg) { - int ret = -EINVAL; - struct aw_prof_desc *prof_desc = NULL; - struct aw_prof_info *prof_info = &aw87xxx->acf_info.prof_info; - struct aw_data_container *data_container = NULL; + int ret = 0; + int16_t data_len = _IOC_SIZE(cmd); struct aw_device *aw_dev = &aw87xxx->aw_dev; + struct algo_auth_data algo_data; - AW_DEV_LOGD(aw87xxx->dev, "enter"); + AW_DEV_LOGD(aw_dev->dev, "read algo auth data, len=%d", data_len); + memset(&algo_data, 0x0, sizeof(struct algo_auth_data)); - if (!prof_info->status) { - AW_DEV_LOGE(aw87xxx->dev, "profile_cfg not load"); + algo_data.auth_mode = aw_dev->auth_desc.auth_mode; + algo_data.chip_id = aw_dev->auth_desc.chip_id; + algo_data.random = aw_dev->auth_desc.random; + algo_data.reg_crc = aw_dev->auth_desc.reg_crc; + algo_data.check_result = aw_dev->auth_desc.check_result; + + if (copy_to_user((void __user *)arg, (char *)&algo_data, data_len)) + ret = -EFAULT; + + AW_DEV_LOGD(aw_dev->dev, "ret=%d,mode=%d,reg_crc=0x%x,random=0x%x,id=0x%x,res=%d", + ret, algo_data.auth_mode, algo_data.reg_crc, algo_data.random, + algo_data.chip_id, algo_data.check_result); + + return ret; +} + +static int aw87xxx_algo_auth_misc_ops(struct aw87xxx *aw87xxx, + unsigned int cmd, unsigned long arg) +{ + int ret = 0; + + switch (cmd) { + case AW_IOCTL_SET_ALGO_AUTH: { + ret = aw87xxx_algo_auth_misc_ops_write(aw87xxx, cmd, arg); + } break; + case AW_IOCTL_GET_ALGO_AUTH: { + ret = aw87xxx_algo_auth_misc_ops_read(aw87xxx, cmd, arg); + } break; + default: + AW_DEV_LOGE(aw87xxx->dev, "unsupported cmd %d", cmd); + ret = -EINVAL; + break; + } + + return ret; +} + +static long aw87xxx_algo_auth_misc_unlocked_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + int ret = 0; + struct aw87xxx *aw87xxx = NULL; + + if (((_IOC_TYPE(cmd)) != (AW_IOCTL_MAGIC_S))) { + AW_LOGE("cmd magic err"); return -EINVAL; } - - if (0 == strncmp(profile, aw87xxx->prof_off_name, AW_PROFILE_STR_MAX)) - return aw87xxx_esd_update_off_prof(aw87xxx, profile); - - prof_desc = aw_acf_get_prof_desc_form_name(aw87xxx->dev, &aw87xxx->acf_info, - profile); - if (prof_desc == NULL) { - AW_DEV_LOGE(aw87xxx->dev, "not found [%s] parameter", profile); + aw87xxx = (struct aw87xxx *)file->private_data; + ret = aw87xxx_algo_auth_misc_ops(aw87xxx, cmd, arg); + if (ret) return -EINVAL; - } - - if (!prof_desc->prof_st) { - AW_DEV_LOGE(aw87xxx->dev, "not found data container"); - return -EINVAL; - } - - data_container = &prof_desc->data_container; - AW_DEV_LOGD(aw87xxx->dev, "get profile[%s] data len [%d]", - profile, data_container->len); - - if (aw_dev->ops.pwr_on_func) { - ret = aw_dev->ops.pwr_on_func(aw_dev, data_container); - if (ret < 0) { - AW_DEV_LOGE(aw87xxx->dev, "load profile[%s] failed ", - profile); - return ret; - } - } else { - ret = aw_dev_default_pwr_on(aw_dev, data_container); - if (ret < 0) { - AW_DEV_LOGE(aw87xxx->dev, "load profile[%s] failed ", - profile); - return ret; - } - } - aw87xxx->current_profile = prof_desc->prof_name; - AW_DEV_LOGD(aw87xxx->dev, "recover load profile[%s] succeed", profile); return 0; } +#ifdef CONFIG_COMPAT +static long aw87xxx_algo_auth_misc_compat_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + int ret = 0; + struct aw87xxx *aw87xxx = NULL; + + if (((_IOC_TYPE(cmd)) != (AW_IOCTL_MAGIC_S))) { + AW_LOGE("cmd magic err"); + return -EINVAL; + } + aw87xxx = (struct aw87xxx *)file->private_data; + ret = aw87xxx_algo_auth_misc_ops(aw87xxx, cmd, arg); + if (ret) + return -EINVAL; + + return 0; +} +#endif + +static int aw87xxx_algo_auth_misc_open(struct inode *inode, struct file *file) +{ + struct list_head *pos = NULL; + struct aw87xxx *list_aw87xxx = NULL; + + list_for_each(pos, &g_aw87xxx_list) { + list_aw87xxx = list_entry(pos, struct aw87xxx, list); + if (list_aw87xxx->dev_index == 0) + break; + } + + if (list_aw87xxx == NULL) { + AW_LOGE("can't find dev num %d", 0); + return -EINVAL; + } + + file->private_data = (void *)list_aw87xxx; + + AW_DEV_LOGD(list_aw87xxx->dev, "misc open success"); + + return 0; +} + +static int aw87xxx_algo_auth_misc_release(struct inode *inode, struct file *file) +{ + file->private_data = (void *)NULL; + + AW_LOGD("misc release success"); + return 0; +} + +static const struct file_operations aw_algo_auth_misc_fops = { + .owner = THIS_MODULE, + .open = aw87xxx_algo_auth_misc_open, + .release = aw87xxx_algo_auth_misc_release, + .unlocked_ioctl = aw87xxx_algo_auth_misc_unlocked_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = aw87xxx_algo_auth_misc_compat_ioctl, +#endif +}; + +static struct miscdevice misc_algo_auth = { + .name = "awinic_ctl", + .minor = MISC_DYNAMIC_MINOR, + .fops = &aw_algo_auth_misc_fops, +}; + +static int aw87xxx_algo_auth_misc_init(struct aw_device *aw_dev) +{ + int ret; + + ret = misc_register(&misc_algo_auth); + if (ret) + AW_DEV_LOGE(aw_dev->dev, "misc register fail: %d\n", ret); + + return ret; +} + +static void aw87xxx_algo_auth_misc_deinit(struct aw_device *aw_dev) +{ + misc_deregister(&misc_algo_auth); + + AW_DEV_LOGD(aw_dev->dev, " misc unregister done"); +} + /**************************************************************************** * * aw87xxx Kcontrols @@ -368,18 +631,19 @@ static int aw87xxx_profile_switch_info(struct snd_kcontrol *kcontrol, int count = 0; char *name = NULL; char *profile_name = NULL; + int ret = 0; struct aw87xxx *aw87xxx = (struct aw87xxx *)kcontrol->private_value; if (aw87xxx == NULL) { AW_LOGE("get struct aw87xxx failed"); - return -EINVAL; + return 0; } uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; /*make sure have prof */ - count = aw_acf_get_profile_count(aw87xxx->dev, &aw87xxx->acf_info); + count = aw87xxx_acf_get_profile_count(aw87xxx->dev, &aw87xxx->acf_info); if (count <= 0) { uinfo->value.enumerated.items = 0; AW_DEV_LOGE(aw87xxx->dev, "get count[%d] failed", count); @@ -392,15 +656,19 @@ static int aw87xxx_profile_switch_info(struct snd_kcontrol *kcontrol, name = uinfo->value.enumerated.name; count = uinfo->value.enumerated.item; - profile_name = aw_acf_get_prof_name_form_index(aw87xxx->dev, + profile_name = aw87xxx_acf_get_prof_name_form_index(aw87xxx->dev, &aw87xxx->acf_info, count); if (profile_name == NULL) { - strlcpy(uinfo->value.enumerated.name, "NULL", + ret = strscpy(uinfo->value.enumerated.name, "NULL", strlen("NULL") + 1); + if (ret < 0) + AW_DEV_LOGE(aw87xxx->dev, "copy enumerated name failed"); return 0; } - strlcpy(name, profile_name, sizeof(uinfo->value.enumerated.name)); + ret = strscpy(name, profile_name, sizeof(uinfo->value.enumerated.name)); + if (ret < 0) + AW_DEV_LOGE(aw87xxx->dev, "copy enumerated name failed"); return 0; } @@ -412,14 +680,16 @@ static int aw87xxx_profile_switch_put(struct snd_kcontrol *kcontrol, char *profile_name = NULL; int index = ucontrol->value.integer.value[0]; struct aw87xxx *aw87xxx = (struct aw87xxx *)kcontrol->private_value; - struct acf_bin_info *acf_info = &aw87xxx->acf_info; + struct acf_bin_info *acf_info = NULL; if (aw87xxx == NULL) { AW_LOGE("get struct aw87xxx failed"); return -EINVAL; } - profile_name = aw_acf_get_prof_name_form_index(aw87xxx->dev, acf_info, index); + acf_info = &aw87xxx->acf_info; + + profile_name = aw87xxx_acf_get_prof_name_form_index(aw87xxx->dev, acf_info, index); if (!profile_name) { AW_DEV_LOGE(aw87xxx->dev, "not found profile name,index=[%d]", index); @@ -432,7 +702,7 @@ static int aw87xxx_profile_switch_put(struct snd_kcontrol *kcontrol, if (ret < 0) { AW_DEV_LOGE(aw87xxx->dev, "set dev_index[%d] profile failed, profile = %s", aw87xxx->dev_index, profile_name); - return ret; + return -EINVAL; } return 0; @@ -456,15 +726,15 @@ static int aw87xxx_profile_switch_get(struct snd_kcontrol *kcontrol, } profile = aw87xxx->current_profile; - //AW_DEV_LOGI(aw87xxx->dev, "current profile:[%s]", - // aw87xxx->current_profile); + AW_DEV_LOGI(aw87xxx->dev, "current profile:[%s]", + aw87xxx->current_profile); - index = aw_acf_get_prof_index_form_name(aw87xxx->dev, + index = aw87xxx_acf_get_prof_index_form_name(aw87xxx->dev, &aw87xxx->acf_info, aw87xxx->current_profile); if (index < 0) { AW_DEV_LOGE(aw87xxx->dev, "get profile index failed"); - return index; + return -EINVAL; } ucontrol->value.integer.value[0] = index; @@ -483,7 +753,7 @@ static int aw87xxx_vmax_get_info(struct snd_kcontrol *kcontrol, return 0; } -static int aw87xxxx_vmax_get(struct snd_kcontrol *kcontrol, +static int aw87xxx_vmax_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int ret = -1; @@ -495,9 +765,9 @@ static int aw87xxxx_vmax_get(struct snd_kcontrol *kcontrol, return -EINVAL; } - ret = aw_monitor_no_dsp_get_vmax(&aw87xxx->monitor, &vmax_val); + ret = aw87xxx_monitor_no_dsp_get_vmax(&aw87xxx->monitor, &vmax_val); if (ret < 0) - return ret; + return -EINVAL; ucontrol->value.integer.value[0] = vmax_val; AW_DEV_LOGI(aw87xxx->dev, "get vmax = [0x%x]", vmax_val); @@ -505,13 +775,211 @@ static int aw87xxxx_vmax_get(struct snd_kcontrol *kcontrol, return 0; } +static int aw87xxx_monitor_switch_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + int count = 0; + int ret = 0; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + count = ARRAY_SIZE(aw87xxx_monitor_switch); + + uinfo->value.enumerated.items = count; + + if (uinfo->value.enumerated.item >= count) + uinfo->value.enumerated.item = count - 1; + + ret = strscpy(uinfo->value.enumerated.name, + aw87xxx_monitor_switch[uinfo->value.enumerated.item], + strlen(aw87xxx_monitor_switch[uinfo->value.enumerated.item]) + 1); + if (ret < 0) + AW_LOGE("copy enumerated name failed"); + + return 0; +} + +static int aw87xxx_monitor_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + uint32_t ctrl_value = ucontrol->value.integer.value[0]; + struct aw87xxx *aw87xxx = (struct aw87xxx *)kcontrol->private_value; + struct aw_monitor *aw_monitor = &aw87xxx->monitor; + int ret = -1; + + ret = aw87xxx_dev_monitor_switch_set(aw_monitor, ctrl_value); + if (ret) + return -EINVAL; + + return 0; +} + +static int aw87xxx_monitor_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct aw87xxx *aw87xxx = (struct aw87xxx *)kcontrol->private_value; + struct aw_monitor *aw_monitor = &aw87xxx->monitor; + + if (aw_monitor->version == AW_MONITOR_HDR_VER_0_1_2) + ucontrol->value.integer.value[0] = aw_monitor->monitor_cfg.monitor_switch; + else + ucontrol->value.integer.value[0] = aw_monitor->monitor_hdr.monitor_switch; + + AW_DEV_LOGD(aw87xxx->dev, "monitor switch is %ld", ucontrol->value.integer.value[0]); + return 0; +} + +static int aw87xxx_algo_auth_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = sizeof(struct algo_auth_data); + return 0; +} + +/*op_flag: SNDRV_CTL_TLV_OP_READ = 0, SNDRV_CTL_TLV_OP_WRITE = 1*/ +static int aw87xxx_algo_auth_tlv_rw(struct snd_kcontrol *kcontrol, int op_flag, + unsigned int size, unsigned int __user *tlv) +{ + int ret = 0; + struct aw87xxx *aw87xxx = (struct aw87xxx *)kcontrol->private_value; + struct aw_device *aw_dev = &aw87xxx->aw_dev; + struct algo_auth_data algo_data; + + AW_DEV_LOGD(aw87xxx->dev, "op_flag = [%d]", op_flag); + + if (!tlv) { + AW_DEV_LOGE(aw87xxx->dev, "tlv is NULL"); + return -EINVAL; + } + + if (size != sizeof(struct algo_auth_data)) { + AW_DEV_LOGE(aw87xxx->dev, "size != algo_auth_data"); + return -EINVAL; + } + + switch (op_flag) { + case SNDRV_CTL_TLV_OP_READ: + AW_DEV_LOGD(aw87xxx->dev, "get algo auth data"); + memset(&algo_data, 0x0, sizeof(struct algo_auth_data)); + + algo_data.auth_mode = aw_dev->auth_desc.auth_mode; + algo_data.chip_id = aw_dev->auth_desc.chip_id; + algo_data.random = aw_dev->auth_desc.random; + algo_data.reg_crc = aw_dev->auth_desc.reg_crc; + algo_data.check_result = aw_dev->auth_desc.check_result; + + if (copy_to_user((void __user *)tlv, (char *)&algo_data, size)) + ret = -EFAULT; + break; + case SNDRV_CTL_TLV_OP_WRITE: + AW_DEV_LOGD(aw87xxx->dev, "set algo auth data"); + if (copy_from_user(&algo_data, (void __user *)tlv, size)) + ret = -EFAULT; + + aw87xxx_dev_algo_auth_mode(aw_dev, &algo_data); + break; + default: + AW_DEV_LOGD(aw_dev->dev, "unsupport op flag[0x%x]", op_flag); + return -EINVAL; + } + + AW_DEV_LOGD(aw87xxx->dev, "mode=%d,reg_crc=0x%x,random=0x%x,id=0x%x,res=%d", + algo_data.auth_mode, algo_data.reg_crc, algo_data.random, + algo_data.chip_id, algo_data.check_result); + + return ret; +} + +static int aw87xxx_spin_switch_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + int count = 0; + int ret = 0; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + count = ARRAY_SIZE(aw87xxx_spin_switch); + + uinfo->value.enumerated.items = count; + + if (uinfo->value.enumerated.item >= count) + uinfo->value.enumerated.item = count - 1; + + ret = strscpy(uinfo->value.enumerated.name, + aw87xxx_spin_switch[uinfo->value.enumerated.item], + strlen(aw87xxx_spin_switch[uinfo->value.enumerated.item]) + 1); + if (ret < 0) + AW_LOGE("copy enumerated name failed"); + + return 0; +} + +static int aw87xxx_spin_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + uint32_t ctrl_value = 0; + int ret = 0; + struct aw87xxx *aw87xxx = (struct aw87xxx *)kcontrol->private_value; + + ctrl_value = ucontrol->value.integer.value[0]; + + ret = aw87xxx_dsp_set_spin(ctrl_value); + if (ret) { + AW_DEV_LOGE(aw87xxx->dev, "write spin failed"); + return ret; + } + AW_DEV_LOGD(aw87xxx->dev, "write spin done ctrl_value=%d", ctrl_value); + return 0; +} + +static int aw87xxx_spin_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct aw87xxx *aw87xxx = (struct aw87xxx *)kcontrol->private_value; + + ucontrol->value.integer.value[0] = aw87xxx_dsp_get_spin(); + AW_DEV_LOGD(aw87xxx->dev, "current spin is %ld", ucontrol->value.integer.value[0]); + + return 0; +} + +static int aw87xxx_hal_monitor_time_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = AW_MONITOR_TIME_MIN; + uinfo->value.integer.max = AW_MONITOR_TIME_MAX; + + return 0; +} + +static int aw87xxx_hal_monitor_time_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct aw87xxx *aw87xxx = (struct aw87xxx *)kcontrol->private_value; + + if (aw87xxx == NULL) { + AW_LOGE("get struct aw87xxx failed"); + return -EINVAL; + } + + ucontrol->value.integer.value[0] = + aw87xxx->monitor.monitor_hdr.monitor_time; + + AW_LOGI("get monitor time %ld", ucontrol->value.integer.value[0]); + + return 0; +} + static int aw87xxx_kcontrol_dynamic_create(struct aw87xxx *aw87xxx, void *codec) { struct snd_kcontrol_new *aw87xxx_kcontrol = NULL; aw_snd_soc_codec_t *soc_codec = (aw_snd_soc_codec_t *)codec; - char *kctl_name[AW87XXX_KCONTROL_NUM]; - int kcontrol_num = AW87XXX_KCONTROL_NUM; + char *kctl_name[AW87XXX_PRIVATE_KCONTROL_NUM]; + int kcontrol_num = AW87XXX_PRIVATE_KCONTROL_NUM; int ret = -1; AW_DEV_LOGD(aw87xxx->dev, "enter"); @@ -552,9 +1020,24 @@ static int aw87xxx_kcontrol_dynamic_create(struct aw87xxx *aw87xxx, aw87xxx_kcontrol[1].iface = SNDRV_CTL_ELEM_IFACE_MIXER; aw87xxx_kcontrol[1].access = SNDRV_CTL_ELEM_ACCESS_READ; aw87xxx_kcontrol[1].info = aw87xxx_vmax_get_info; - aw87xxx_kcontrol[1].get = aw87xxxx_vmax_get; + aw87xxx_kcontrol[1].get = aw87xxx_vmax_get; aw87xxx_kcontrol[1].private_value = (unsigned long)aw87xxx; + kctl_name[2] = devm_kzalloc(aw87xxx->codec->dev, AW_NAME_BUF_MAX, + GFP_KERNEL); + if (kctl_name[2] == NULL) + return -ENOMEM; + + snprintf(kctl_name[2], AW_NAME_BUF_MAX, "aw87xxx_monitor_switch_%d", + aw87xxx->dev_index); + + aw87xxx_kcontrol[2].name = kctl_name[2]; + aw87xxx_kcontrol[2].iface = SNDRV_CTL_ELEM_IFACE_MIXER; + aw87xxx_kcontrol[2].info = aw87xxx_monitor_switch_info; + aw87xxx_kcontrol[2].get = aw87xxx_monitor_switch_get; + aw87xxx_kcontrol[2].put = aw87xxx_monitor_switch_put; + aw87xxx_kcontrol[2].private_value = (unsigned long)aw87xxx; + ret = aw_componet_codec_ops.add_codec_controls(aw87xxx->codec, aw87xxx_kcontrol, kcontrol_num); if (ret < 0) { @@ -563,9 +1046,87 @@ static int aw87xxx_kcontrol_dynamic_create(struct aw87xxx *aw87xxx, return ret; } - AW_DEV_LOGI(aw87xxx->dev, "add codec controls[%s,%s]", + AW_DEV_LOGI(aw87xxx->dev, "add codec controls[%s,%s,%s]", aw87xxx_kcontrol[0].name, - aw87xxx_kcontrol[1].name); + aw87xxx_kcontrol[1].name, + aw87xxx_kcontrol[2].name); + + return 0; +} + +static int aw87xxx_public_kcontrol_create(struct aw87xxx *aw87xxx, + void *codec) +{ + struct snd_kcontrol_new *aw87xxx_kcontrol = NULL; + aw_snd_soc_codec_t *soc_codec = (aw_snd_soc_codec_t *)codec; + char *kctl_name[AW87XXX_PUBLIC_KCONTROL_NUM]; + int kcontrol_num = AW87XXX_PUBLIC_KCONTROL_NUM; + int ret = -1; + + AW_DEV_LOGD(aw87xxx->dev, "enter"); + aw87xxx->codec = soc_codec; + + aw87xxx_kcontrol = devm_kzalloc(aw87xxx->dev, + sizeof(struct snd_kcontrol_new) * kcontrol_num, + GFP_KERNEL); + if (aw87xxx_kcontrol == NULL) { + AW_DEV_LOGE(aw87xxx->dev, "aw87xxx_kcontrol devm_kzalloc failed"); + return -ENOMEM; + } + + kctl_name[0] = devm_kzalloc(aw87xxx->dev, AW_NAME_BUF_MAX, + GFP_KERNEL); + if (kctl_name[0] == NULL) + return -ENOMEM; + + snprintf(kctl_name[0], AW_NAME_BUF_MAX, "aw87xxx_spin_switch"); + + aw87xxx_kcontrol[0].name = kctl_name[0]; + aw87xxx_kcontrol[0].iface = SNDRV_CTL_ELEM_IFACE_MIXER; + aw87xxx_kcontrol[0].info = aw87xxx_spin_switch_info; + aw87xxx_kcontrol[0].get = aw87xxx_spin_switch_get; + aw87xxx_kcontrol[0].put = aw87xxx_spin_switch_put; + aw87xxx_kcontrol[0].private_value = (unsigned long)aw87xxx; + + kctl_name[1] = devm_kzalloc(aw87xxx->dev, AW_NAME_BUF_MAX, + GFP_KERNEL); + if (kctl_name[1] == NULL) + return -ENOMEM; + + snprintf(kctl_name[1], AW_NAME_BUF_MAX, "aw87xxx_hal_monitor_time"); + + aw87xxx_kcontrol[1].name = kctl_name[1]; + aw87xxx_kcontrol[1].iface = SNDRV_CTL_ELEM_IFACE_MIXER; + aw87xxx_kcontrol[1].access = SNDRV_CTL_ELEM_ACCESS_READ; + aw87xxx_kcontrol[1].info = aw87xxx_hal_monitor_time_info; + aw87xxx_kcontrol[1].get = aw87xxx_hal_monitor_time_get; + aw87xxx_kcontrol[1].private_value = (unsigned long)aw87xxx; + + kctl_name[2] = devm_kzalloc(aw87xxx->dev, AW_NAME_BUF_MAX, + GFP_KERNEL); + if (kctl_name[2] == NULL) + return -ENOMEM; + + snprintf(kctl_name[2], AW_NAME_BUF_MAX, "aw_algo_auth"); + + aw87xxx_kcontrol[2].name = kctl_name[2]; + aw87xxx_kcontrol[2].iface = SNDRV_CTL_ELEM_IFACE_MIXER; + aw87xxx_kcontrol[2].access = SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK|SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE; + aw87xxx_kcontrol[2].info = aw87xxx_algo_auth_info; + aw87xxx_kcontrol[2].tlv.c = aw87xxx_algo_auth_tlv_rw; + aw87xxx_kcontrol[2].private_value = (unsigned long)aw87xxx; + + ret = aw_componet_codec_ops.add_codec_controls(aw87xxx->codec, + aw87xxx_kcontrol, kcontrol_num); + if (ret < 0) { + AW_DEV_LOGE(aw87xxx->dev, "add codec controls failed, ret = %d", + ret); + return ret; + } + + AW_DEV_LOGI(aw87xxx->dev, "add public codec controls[%s,%s,%s]", + aw87xxx_kcontrol[0].name, aw87xxx_kcontrol[1].name, + aw87xxx_kcontrol[2].name); return 0; } @@ -583,14 +1144,15 @@ int aw87xxx_add_codec_controls(void *codec) list_for_each(pos, &g_aw87xxx_list) { aw87xxx = list_entry(pos, struct aw87xxx, list); - if (aw87xxx == NULL) { - AW_LOGE("struct aw87xxx not ready"); - return ret; - } - ret = aw87xxx_kcontrol_dynamic_create(aw87xxx, codec); if (ret < 0) return ret; + + if (aw87xxx->dev_index == 0) { + ret = aw87xxx_public_kcontrol_create(aw87xxx, codec); + if (ret < 0) + return ret; + } } return 0; @@ -606,15 +1168,15 @@ EXPORT_SYMBOL(aw87xxx_add_codec_controls); static void aw87xxx_fw_cfg_free(struct aw87xxx *aw87xxx) { AW_DEV_LOGD(aw87xxx->dev, "enter"); - aw_acf_profile_free(aw87xxx->dev, &aw87xxx->acf_info); - aw_monitor_cfg_free(&aw87xxx->monitor); + aw87xxx_acf_profile_free(aw87xxx->dev, &aw87xxx->acf_info); + aw87xxx_monitor_cfg_free(&aw87xxx->monitor); } static int aw87xxx_init_default_prof(struct aw87xxx *aw87xxx) { char *profile = NULL; - profile = aw_acf_get_prof_off_name(aw87xxx->dev, &aw87xxx->acf_info); + profile = aw87xxx_acf_get_prof_off_name(aw87xxx->dev, &aw87xxx->acf_info); if (profile == NULL) { AW_DEV_LOGE(aw87xxx->dev, "get profile off name failed"); return -EINVAL; @@ -628,55 +1190,46 @@ static int aw87xxx_init_default_prof(struct aw87xxx *aw87xxx) return 0; } -static void aw87xxx_fw_load_retry(struct aw87xxx *aw87xxx) -{ - struct acf_bin_info *acf_info = &aw87xxx->acf_info; - int ram_timer_val = 2000; - - AW_DEV_LOGD(aw87xxx->dev, "failed to read [%s]", - aw87xxx->fw_name); - - if (acf_info->load_count < AW_LOAD_FW_RETRIES) { - AW_DEV_LOGD(aw87xxx->dev, - "restart hrtimer to load firmware"); - schedule_delayed_work(&aw87xxx->fw_load_work, - msecs_to_jiffies(ram_timer_val)); - } else { - acf_info->load_count = 0; - AW_DEV_LOGE(aw87xxx->dev, - "can not load firmware,please check name or file exists"); - return; - } - acf_info->load_count++; -} - -static void aw87xxx_fw_load(const struct firmware *fw, void *context) +static void aw87xxx_fw_load_work(struct work_struct *work) { int ret = -1; - struct aw87xxx *aw87xxx = context; + struct aw87xxx *aw87xxx = container_of(work, + struct aw87xxx, fw_load_work.work); struct acf_bin_info *acf_info = &aw87xxx->acf_info; + const struct firmware *cont = NULL; AW_DEV_LOGD(aw87xxx->dev, "enter"); - if (!fw) { - aw87xxx_fw_load_retry(aw87xxx); + ret = request_firmware(&cont, aw87xxx->fw_name, aw87xxx->dev); + if ((ret) || (!cont)) { + AW_DEV_LOGD(aw87xxx->dev, "load [%s] failed!", aw87xxx->fw_name); + if (acf_info->load_count == AW_READ_CHIPID_RETRIES) { + acf_info->load_count = 0; + } else { + acf_info->load_count++; + /* sleep 1s */ + msleep(1000); + AW_DEV_LOGD(aw87xxx->dev, "load [%s] try [%d]!", + aw87xxx->fw_name, acf_info->load_count); + aw87xxx_fw_load_work(work); + } return; } - AW_DEV_LOGD(aw87xxx->dev, "loaded %s - size: %ld", - aw87xxx->fw_name, (u_long)(fw ? fw->size : 0)); + AW_DEV_LOGD(aw87xxx->dev, "loaded %s - size: %zu", + aw87xxx->fw_name, (cont ? cont->size : 0)); mutex_lock(&aw87xxx->reg_lock); - acf_info->fw_data = vmalloc(fw->size); + acf_info->fw_data = vmalloc(cont->size); if (!acf_info->fw_data) { AW_DEV_LOGE(aw87xxx->dev, "fw_data kzalloc memory failed"); goto exit_vmalloc_failed; } - memset(acf_info->fw_data, 0, fw->size); - memcpy(acf_info->fw_data, fw->data, fw->size); - acf_info->fw_size = fw->size; + memset(acf_info->fw_data, 0, cont->size); + memcpy(acf_info->fw_data, cont->data, cont->size); + acf_info->fw_size = cont->size; - ret = aw_acf_parse(aw87xxx->dev, &aw87xxx->acf_info); + ret = aw87xxx_acf_parse(aw87xxx->dev, &aw87xxx->acf_info); if (ret < 0) { AW_DEV_LOGE(aw87xxx->dev, "fw_data parse failed"); goto exit_acf_parse_failed; @@ -687,36 +1240,12 @@ static void aw87xxx_fw_load(const struct firmware *fw, void *context) aw87xxx_fw_cfg_free(aw87xxx); goto exit_acf_parse_failed; } - AW_DEV_LOGI(aw87xxx->dev, "acf parse succeed"); - mutex_unlock(&aw87xxx->reg_lock); - release_firmware(fw); - return; exit_acf_parse_failed: exit_vmalloc_failed: - release_firmware(fw); mutex_unlock(&aw87xxx->reg_lock); -} - -static void aw87xxx_fw_load_work_routine(struct work_struct *work) -{ - struct aw87xxx *aw87xxx = container_of(work, - struct aw87xxx, fw_load_work.work); - struct aw_prof_info *prof_info = &aw87xxx->acf_info.prof_info; - - AW_DEV_LOGD(aw87xxx->dev, "enter"); - - if (prof_info->status == AW_ACF_WAIT) { - const struct firmware *fw; - int ret; - - ret = request_firmware(&fw, aw87xxx->fw_name, aw87xxx->dev); - if (!ret) { - AW_DEV_LOGD(aw87xxx->dev, "loader firmware %s success\n", aw87xxx->fw_name); - aw87xxx_fw_load(fw, aw87xxx); - } - } + release_firmware(cont); } static void aw87xxx_fw_load_init(struct aw87xxx *aw87xxx) @@ -728,9 +1257,9 @@ static void aw87xxx_fw_load_init(struct aw87xxx *aw87xxx) #endif AW_DEV_LOGI(aw87xxx->dev, "enter"); snprintf(aw87xxx->fw_name, AW87XXX_FW_NAME_MAX, "%s", AW87XXX_FW_BIN_NAME); - aw_acf_init(&aw87xxx->aw_dev, &aw87xxx->acf_info, aw87xxx->dev_index); + aw87xxx_acf_init(&aw87xxx->aw_dev, &aw87xxx->acf_info, aw87xxx->dev_index); - INIT_DELAYED_WORK(&aw87xxx->fw_load_work, aw87xxx_fw_load_work_routine); + INIT_DELAYED_WORK(&aw87xxx->fw_load_work, aw87xxx_fw_load_work); schedule_delayed_work(&aw87xxx->fw_load_work, msecs_to_jiffies(cfg_timer_val)); } @@ -740,7 +1269,7 @@ static void aw87xxx_fw_load_init(struct aw87xxx *aw87xxx) *aw87xxx attribute node * ****************************************************************************/ -static ssize_t aw87xxx_attr_get_reg(struct device *dev, +static ssize_t reg_show(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t len = 0; @@ -754,7 +1283,7 @@ static ssize_t aw87xxx_attr_get_reg(struct device *dev, for (i = 0; i < aw_dev->reg_max_addr; i++) { if (!(aw_dev->reg_access[i] & AW_DEV_REG_RD_ACCESS)) continue; - ret = aw_dev_i2c_read_byte(&aw87xxx->aw_dev, i, ®_val); + ret = aw87xxx_dev_i2c_read_byte(&aw87xxx->aw_dev, i, ®_val); if (ret < 0) { len += snprintf(buf + len, PAGE_SIZE - len, "read reg [0x%x] failed\n", i); @@ -771,7 +1300,7 @@ static ssize_t aw87xxx_attr_get_reg(struct device *dev, return len; } -static ssize_t aw87xxx_attr_set_reg(struct device *dev, +static ssize_t reg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { @@ -788,7 +1317,7 @@ static ssize_t aw87xxx_attr_set_reg(struct device *dev, return -EINVAL; } - ret = aw_dev_i2c_write_byte(&aw87xxx->aw_dev, + ret = aw87xxx_dev_i2c_write_byte(&aw87xxx->aw_dev, databuf[0], databuf[1]); if (ret < 0) AW_DEV_LOGE(aw87xxx->dev, "set [0x%x]=0x%x failed", @@ -804,7 +1333,7 @@ static ssize_t aw87xxx_attr_set_reg(struct device *dev, return len; } -static ssize_t aw87xxx_attr_get_profile(struct device *dev, +static ssize_t profile_show(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t len = 0; @@ -833,7 +1362,7 @@ static ssize_t aw87xxx_attr_get_profile(struct device *dev, return len; } -static ssize_t aw87xxx_attr_set_profile(struct device *dev, +static ssize_t profile_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { @@ -841,7 +1370,13 @@ static ssize_t aw87xxx_attr_set_profile(struct device *dev, int ret = 0; struct aw87xxx *aw87xxx = dev_get_drvdata(dev); - if (sscanf(buf, "%s", profile) == 1) { + if (strlen(buf) > AW_PROFILE_STR_MAX) { + AW_DEV_LOGE(aw87xxx->dev, "input profile_str_len is out of max[%d]", + AW_PROFILE_STR_MAX); + return -EINVAL; + } + + if (sscanf(buf, "%31s", profile) == 1) { AW_DEV_LOGD(aw87xxx->dev, "set profile [%s]", profile); ret = aw87xxx_update_profile(aw87xxx, profile); if (ret < 0) { @@ -854,7 +1389,7 @@ static ssize_t aw87xxx_attr_set_profile(struct device *dev, return len; } -static ssize_t aw87xxx_attr_get_hwen(struct device *dev, +static ssize_t hwen_show(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t len = 0; @@ -871,7 +1406,7 @@ static ssize_t aw87xxx_attr_get_hwen(struct device *dev, return len; } -static ssize_t aw87xxx_attr_set_hwen(struct device *dev, +static ssize_t hwen_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { @@ -887,9 +1422,9 @@ static ssize_t aw87xxx_attr_set_hwen(struct device *dev, mutex_lock(&aw87xxx->reg_lock); if (state == AW_DEV_HWEN_OFF) - aw_dev_hw_pwr_ctrl(&aw87xxx->aw_dev, false); /*OFF*/ + aw87xxx_dev_hw_pwr_ctrl(&aw87xxx->aw_dev, false); /*OFF*/ else if (state == AW_DEV_HWEN_ON) - aw_dev_hw_pwr_ctrl(&aw87xxx->aw_dev, true); /*ON*/ + aw87xxx_dev_hw_pwr_ctrl(&aw87xxx->aw_dev, true); /*ON*/ else AW_DEV_LOGE(aw87xxx->dev, "input [%d] error, hwen_on=[%d],hwen_off=[%d]", state, AW_DEV_HWEN_ON, AW_DEV_HWEN_OFF); @@ -903,7 +1438,7 @@ int aw87xxx_awrw_write(struct aw87xxx *aw87xxx, int i = 0, ret = -1; char *data_buf = NULL; int buf_len = 0; - int temp_data = 0; + unsigned int temp_data = 0; int data_str_size = 0; char *reg_data; struct aw_i2c_packet *packet = &aw87xxx->i2c_packet; @@ -934,6 +1469,8 @@ int aw87xxx_awrw_write(struct aw87xxx *aw87xxx, "0x%x", &temp_data); if (ret != 1) { AW_DEV_LOGE(aw87xxx->dev, "sscanf failed,ret=%d", ret); + vfree(data_buf); + data_buf = NULL; return ret; } reg_data[i] = temp_data; @@ -946,7 +1483,6 @@ int aw87xxx_awrw_write(struct aw87xxx *aw87xxx, AW_DEV_LOGE(aw87xxx->dev, "write failed"); vfree(data_buf); data_buf = NULL; - mutex_unlock(&aw87xxx->reg_lock); return -EFAULT; } mutex_unlock(&aw87xxx->reg_lock); @@ -996,7 +1532,7 @@ static int aw87xxx_awrw_data_check(struct aw87xxx *aw87xxx, static int aw87xxx_awrw_parse_buf(struct aw87xxx *aw87xxx, const char *buf, size_t count, int *wr_status) { - int data[AWRW_HDR_MAX] = {0}; + unsigned int data[AWRW_HDR_MAX] = {0}; struct aw_i2c_packet *packet = &aw87xxx->i2c_packet; int ret = -1; @@ -1018,7 +1554,7 @@ static int aw87xxx_awrw_parse_buf(struct aw87xxx *aw87xxx, return -EINVAL; } -static ssize_t aw87xxx_attr_awrw_store(struct device *dev, +static ssize_t awrw_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aw87xxx *aw87xxx = dev_get_drvdata(dev); @@ -1057,7 +1593,7 @@ static ssize_t aw87xxx_attr_awrw_store(struct device *dev, return count; } -static ssize_t aw87xxx_attr_awrw_show(struct device *dev, +static ssize_t awrw_show(struct device *dev, struct device_attribute *attr, char *buf) { struct aw87xxx *aw87xxx = dev_get_drvdata(dev); @@ -1073,7 +1609,7 @@ static ssize_t aw87xxx_attr_awrw_show(struct device *dev, } data_len = AWRW_DATA_BYTES * packet->reg_num; - reg_data = (char *)vmalloc(data_len); + reg_data = vmalloc(data_len); if (reg_data == NULL) { AW_DEV_LOGE(aw87xxx->dev, "memory alloc failed"); ret = -EINVAL; @@ -1081,7 +1617,7 @@ static ssize_t aw87xxx_attr_awrw_show(struct device *dev, } mutex_lock(&aw87xxx->reg_lock); - ret = aw_dev_i2c_read_msg(&aw87xxx->aw_dev, packet->reg_addr, + ret = aw87xxx_dev_i2c_read_msg(&aw87xxx->aw_dev, packet->reg_addr, (char *)reg_data, data_len); if (ret < 0) { ret = -EFAULT; @@ -1110,26 +1646,22 @@ exit: return ret; } -static ssize_t aw87xxx_drv_ver_show(struct device *dev, +static ssize_t drv_ver_show(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t len = 0; len += snprintf(buf + len, PAGE_SIZE - len, - "driver_ver: %s \n", AW87XXX_DRIVER_VERSION); + "driver_ver: %s\n", AW87XXX_DRIVER_VERSION); return len; } -static DEVICE_ATTR(reg, S_IWUSR | S_IRUGO, - aw87xxx_attr_get_reg, aw87xxx_attr_set_reg); -static DEVICE_ATTR(profile, S_IWUSR | S_IRUGO, - aw87xxx_attr_get_profile, aw87xxx_attr_set_profile); -static DEVICE_ATTR(hwen, S_IWUSR | S_IRUGO, - aw87xxx_attr_get_hwen, aw87xxx_attr_set_hwen); -static DEVICE_ATTR(awrw, S_IWUSR | S_IRUGO, - aw87xxx_attr_awrw_show, aw87xxx_attr_awrw_store); -static DEVICE_ATTR(drv_ver, S_IRUGO, aw87xxx_drv_ver_show, NULL); +static DEVICE_ATTR_RW(reg); +static DEVICE_ATTR_RW(profile); +static DEVICE_ATTR_RW(hwen); +static DEVICE_ATTR_RW(awrw); +static DEVICE_ATTR_RO(drv_ver); static struct attribute *aw87xxx_attributes[] = { &dev_attr_reg.attr, @@ -1157,9 +1689,6 @@ int aw87xxx_dtsi_dev_index_check(struct aw87xxx *cur_aw87xxx) list_for_each(pos, &g_aw87xxx_list) { list_aw87xxx = list_entry(pos, struct aw87xxx, list); - if (list_aw87xxx == NULL) - continue; - if (list_aw87xxx->dev_index == cur_aw87xxx->dev_index) { AW_DEV_LOGE(cur_aw87xxx->dev, "dev_index has already existing,check failed"); return -EINVAL; @@ -1174,6 +1703,8 @@ static int aw87xxx_dtsi_parse(struct aw87xxx *aw87xxx, { int ret = -1; int32_t dev_index = -EINVAL; + int32_t voltage_min = -EINVAL; + struct aw_voltage_desc *vol_desc = &aw87xxx->aw_dev.vol_desc; ret = of_property_read_u32(dev_node, "dev_index", &dev_index); if (ret < 0) { @@ -1208,29 +1739,22 @@ static int aw87xxx_dtsi_parse(struct aw87xxx *aw87xxx, return ret; } } - return 0; } - /* In order to compatible with stereo share only one reset gpio */ - ret = of_get_named_gpio(dev_node, "reset-shared-gpio", 0); + ret = of_property_read_u32(dev_node, "aw-voltage-min", &voltage_min); if (ret < 0) { - AW_DEV_LOGI(aw87xxx->dev, "no reset shared gpio provided, hardware reset unavailable"); - aw87xxx->aw_dev.rst_shared_gpio = AW_NO_RESET_GPIO; + AW_DEV_LOGI(aw87xxx->dev, "voltage_min parse failed, user default[0x%02x]", + AW_BOOST_VOLTAGE_MIN); + vol_desc->vol_min = AW_BOOST_VOLTAGE_MIN; } else { - aw87xxx->aw_dev.rst_shared_gpio = ret; - AW_DEV_LOGI(aw87xxx->dev, "reset shared gpio[%d] parse succeed", ret); - if (gpio_is_valid(aw87xxx->aw_dev.rst_shared_gpio)) { - ret = devm_gpio_request_one(aw87xxx->dev, - aw87xxx->aw_dev.rst_shared_gpio, - GPIOF_OUT_INIT_LOW, "aw87xxx_reset-shared"); - if (ret < 0) { - AW_DEV_LOGE(aw87xxx->dev, "aw87xxx_reset-shared reset request failed"); - return ret; - } - msleep(20); - gpio_set_value_cansleep(aw87xxx->aw_dev.rst_shared_gpio, AW_GPIO_HIGHT_LEVEL); - } + vol_desc->vol_min = voltage_min; + AW_DEV_LOGI(aw87xxx->dev, "parse aw_voltage_min=[0x%02x]", + vol_desc->vol_min); } + + aw87xxx_device_parse_port_id_dt(&aw87xxx->aw_dev); + aw87xxx_device_parse_topo_id_dt(&aw87xxx->aw_dev); + return 0; } @@ -1289,45 +1813,45 @@ static int aw87xxx_i2c_probe(struct i2c_client *client, struct aw87xxx *aw87xxx = NULL; int ret = -1; - dev_info(&client->dev, "%s\n", __func__); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { AW_DEV_LOGE(&client->dev, "check_functionality failed"); - return -ENODEV; + ret = -ENODEV; + goto exit_check_functionality_failed; } /* aw87xxx i2c_dev struct init */ aw87xxx = aw87xxx_malloc_init(client); if (aw87xxx == NULL) - return -ENOMEM; + goto exit_malloc_init_failed; i2c_set_clientdata(client, aw87xxx); /* aw87xxx dev_node parse */ ret = aw87xxx_dtsi_parse(aw87xxx, dev_node); if (ret < 0) - goto exit; + goto exit_dtsi_parse_failed; /*hw power on PA*/ - aw_dev_hw_pwr_ctrl(&aw87xxx->aw_dev, true); + aw87xxx_dev_hw_pwr_ctrl(&aw87xxx->aw_dev, true); /* aw87xxx devices private attributes init */ - ret = aw_dev_init(&aw87xxx->aw_dev); + ret = aw87xxx_dev_init(&aw87xxx->aw_dev); if (ret < 0) - goto exit; + goto exit_device_init_failed; ret = devm_snd_soc_register_component(aw87xxx->dev, &aw87xxx_component_driver, NULL, 0); if (ret < 0) { dev_err(aw87xxx->dev, "%s() register codec error %d\n", __func__, ret); - goto exit; + goto exit_check_functionality_failed; } /*product register reset */ - aw_dev_soft_reset(&aw87xxx->aw_dev); + aw87xxx_dev_soft_reset(&aw87xxx->aw_dev); /*hw power off */ - aw_dev_hw_pwr_ctrl(&aw87xxx->aw_dev, false); + aw87xxx_dev_hw_pwr_ctrl(&aw87xxx->aw_dev, false); /* create debug attrbute nodes */ ret = sysfs_create_group(&aw87xxx->dev->kobj, &aw87xxx_attribute_group); @@ -1338,7 +1862,13 @@ static int aw87xxx_i2c_probe(struct i2c_client *client, aw87xxx_fw_load_init(aw87xxx); /*monitor init*/ - aw_monitor_init(aw87xxx->dev, &aw87xxx->monitor, dev_node); + aw87xxx_monitor_init(aw87xxx->dev, &aw87xxx->monitor, dev_node); + + /* enable wake source */ + device_init_wakeup(aw87xxx->dev, true); + + if (aw87xxx->dev_index == 0) + aw87xxx_algo_auth_misc_init(&aw87xxx->aw_dev); /*add device to total list */ mutex_lock(&g_aw87xxx_mutex_lock); @@ -1346,19 +1876,34 @@ static int aw87xxx_i2c_probe(struct i2c_client *client, list_add(&aw87xxx->list, &g_aw87xxx_list); mutex_unlock(&g_aw87xxx_mutex_lock); - AW_DEV_LOGI(aw87xxx->dev, "succeed"); + AW_DEV_LOGI(aw87xxx->dev, "succeed, dev_index=[%d], g_aw87xxx_dev_cnt= [%d]", + aw87xxx->dev_index, g_aw87xxx_dev_cnt); return 0; -exit: + +exit_device_init_failed: + aw87xxx_dev_hw_pwr_ctrl(&aw87xxx->aw_dev, false); +exit_dtsi_parse_failed: AW_DEV_LOGE(aw87xxx->dev, "pa init failed"); + devm_kfree(&client->dev, aw87xxx); + aw87xxx = NULL; +exit_malloc_init_failed: +exit_check_functionality_failed: return ret; } +#ifdef AW_KERNEL_VER_OVER_6_1_0 +static void aw87xxx_i2c_remove(struct i2c_client *client) +#else static int aw87xxx_i2c_remove(struct i2c_client *client) +#endif { struct aw87xxx *aw87xxx = i2c_get_clientdata(client); - aw_monitor_exit(&aw87xxx->monitor); + if (aw87xxx->dev_index == 0) + aw87xxx_algo_auth_misc_deinit(&aw87xxx->aw_dev); + + aw87xxx_monitor_exit(&aw87xxx->monitor); /*rm attr node*/ sysfs_remove_group(&aw87xxx->dev->kobj, &aw87xxx_attribute_group); @@ -1370,7 +1915,13 @@ static int aw87xxx_i2c_remove(struct i2c_client *client) list_del(&aw87xxx->list); mutex_unlock(&g_aw87xxx_mutex_lock); + devm_kfree(&client->dev, aw87xxx); + aw87xxx = NULL; + +#ifdef AW_KERNEL_VER_OVER_6_1_0 +#else return 0; +#endif } static void aw87xxx_i2c_shutdown(struct i2c_client *client) @@ -1394,11 +1945,44 @@ static const struct of_device_id extpa_of_match[] = { {}, }; +#ifdef CONFIG_PM +static int aw87xxx_i2c_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct aw87xxx *aw87xxx = i2c_get_clientdata(client); + + AW_DEV_LOGI(&client->dev, "enter"); + aw87xxx->is_suspend = false; + + return 0; +} + +static int aw87xxx_i2c_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct aw87xxx *aw87xxx = i2c_get_clientdata(client); + + AW_DEV_LOGI(&client->dev, "enter"); + aw87xxx->is_suspend = true; + + return 0; + +} + +static const struct dev_pm_ops aw87xxx_dev_pm_ops = { + .suspend = aw87xxx_i2c_suspend, + .resume = aw87xxx_i2c_resume, +}; +#endif + static struct i2c_driver aw87xxx_i2c_driver = { .driver = { .owner = THIS_MODULE, .name = AW87XXX_I2C_NAME, .of_match_table = extpa_of_match, +#ifdef CONFIG_PM + .pm = &aw87xxx_dev_pm_ops, +#endif }, .probe = aw87xxx_i2c_probe, .remove = aw87xxx_i2c_remove, diff --git a/sound/soc/codecs/aw87xxx/aw87xxx.h b/sound/soc/codecs/aw87xxx/aw87xxx.h index 8467a17044dc..b16cda442afc 100644 --- a/sound/soc/codecs/aw87xxx/aw87xxx.h +++ b/sound/soc/codecs/aw87xxx/aw87xxx.h @@ -1,4 +1,17 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ +/* SPDX-License-Identifier: GPL-2.0 + * + * aw87xxx.h aw87xxx pa module + * + * Copyright (c) 2021 AWINIC Technology CO., LTD + * + * Author: Barry + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ #ifndef __AW87XXX_H__ #define __AW87XXX_H__ @@ -17,7 +30,8 @@ #define AW87XXX_NO_OFF_BIN (0) #define AW87XXX_OFF_BIN_OK (1) -#define AW87XXX_KCONTROL_NUM (2) +#define AW87XXX_PRIVATE_KCONTROL_NUM (3) +#define AW87XXX_PUBLIC_KCONTROL_NUM (3) #define AW_I2C_RETRIES (5) #define AW_I2C_RETRY_DELAY (2) @@ -39,10 +53,22 @@ * aw87xxx codec control compatible with kernel 4.19 * ***********************************************************/ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 1) +#if KERNEL_VERSION(4, 19, 1) <= LINUX_VERSION_CODE #define AW_KERNEL_VER_OVER_4_19_1 #endif +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE +#define AW_KERNEL_VER_OVER_5_4_0 +#endif + +#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE +#define AW_KERNEL_VER_OVER_5_10_0 +#endif +#if KERNEL_VERSION(6, 1, 0) <= LINUX_VERSION_CODE +#define AW_KERNEL_VER_OVER_6_1_0 +#endif + + #ifdef AW_KERNEL_VER_OVER_4_19_1 typedef struct snd_soc_component aw_snd_soc_codec_t; #else @@ -101,6 +127,7 @@ struct aw87xxx { char prof_off_name[AW_PROFILE_STR_MAX]; uint32_t off_bin_status; struct device *dev; + bool is_suspend; struct mutex reg_lock; struct aw_device aw_dev; @@ -114,9 +141,12 @@ struct aw87xxx { struct list_head list; struct aw_monitor monitor; +#ifdef AW_ALGO_AUTH_DSP + struct delayed_work auth_work; +#endif }; int aw87xxx_update_profile(struct aw87xxx *aw87xxx, char *profile); -int aw87xxx_esd_update_profile(struct aw87xxx *aw87xxx, char *profile); +int aw87xxx_update_profile_esd(struct aw87xxx *aw87xxx, char *profile); #endif diff --git a/sound/soc/codecs/aw87xxx/aw87xxx_pid_18_reg.h b/sound/soc/codecs/aw87xxx/aw87xxx_pid_18_reg.h index a63ae97eacb5..6794e2161d0a 100644 --- a/sound/soc/codecs/aw87xxx/aw87xxx_pid_18_reg.h +++ b/sound/soc/codecs/aw87xxx/aw87xxx_pid_18_reg.h @@ -1,4 +1,15 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ +/* SPDX-License-Identifier: GPL-2.0 + * aw87xxx_pid_18_reg.h + * + * Copyright (c) 2021 AWINIC Technology CO., LTD + * + * Author: Barry + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ #ifndef __AW87XXX_PID_18_REG_H__ #define __AW87XXX_PID_18_REG_H__ @@ -2314,4 +2325,5 @@ const unsigned char aw87xxx_pid_18_reg_access[AW87XXX_PID_18_REG_MAX] = { /* detail information of registers end */ -#endif /* #ifndef __AW87XXX_PID_18_REG_H__ */ \ No newline at end of file +#endif /* #ifndef __AW87XXX_PID_18_REG_H__ */ + diff --git a/sound/soc/codecs/aw87xxx/aw87xxx_pid_39_reg.h b/sound/soc/codecs/aw87xxx/aw87xxx_pid_39_reg.h index 9ba95c190ffb..771dc59ddcf7 100644 --- a/sound/soc/codecs/aw87xxx/aw87xxx_pid_39_reg.h +++ b/sound/soc/codecs/aw87xxx/aw87xxx_pid_39_reg.h @@ -1,4 +1,15 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ +/* SPDX-License-Identifier: GPL-2.0 + * aw87xxx_pid_39_reg.h + * + * Copyright (c) 2021 AWINIC Technology CO., LTD + * + * Author: Barry + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ #ifndef __AW87XXX_PID_39_REG_H__ #define __AW87XXX_PID_39_REG_H__ diff --git a/sound/soc/codecs/aw87xxx/aw87xxx_pid_59_3x9_reg.h b/sound/soc/codecs/aw87xxx/aw87xxx_pid_59_3x9_reg.h index 1a8c3eac781c..268324eb6f6d 100644 --- a/sound/soc/codecs/aw87xxx/aw87xxx_pid_59_3x9_reg.h +++ b/sound/soc/codecs/aw87xxx/aw87xxx_pid_59_3x9_reg.h @@ -1,12 +1,16 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * @Descripttion: Header file of AW87XXX_PID_59_3X9_REG - * @version: V1.33 - * @Author: zhaozhongbo - * @Date: 2021-03-10 - * @LastEditors: Please set LastEditors - * @LastEditTime: 2021-03-10 +/* SPDX-License-Identifier: GPL-2.0 + * aw87xxx_pid_59_3x9_reg.h + * + * Copyright (c) 2021 AWINIC Technology CO., LTD + * + * Author: Barry + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. */ + #ifndef __AW87XXX_PID_59_3X9_REG_H__ #define __AW87XXX_PID_59_3X9_REG_H__ diff --git a/sound/soc/codecs/aw87xxx/aw87xxx_pid_59_5x9_reg.h b/sound/soc/codecs/aw87xxx/aw87xxx_pid_59_5x9_reg.h index 8fb377ee9780..8cd15a4a4b0d 100644 --- a/sound/soc/codecs/aw87xxx/aw87xxx_pid_59_5x9_reg.h +++ b/sound/soc/codecs/aw87xxx/aw87xxx_pid_59_5x9_reg.h @@ -1,12 +1,16 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * @Descripttion: Header file of AW87XXX_PID_59_5X9_REG - * @version: V1.33 - * @Author: zhaozhongbo - * @Date: 2021-03-10 - * @LastEditors: Please set LastEditors - * @LastEditTime: 2021-03-10 +/* SPDX-License-Identifier: GPL-2.0 + * aw87xxx_pid_59_5x9_reg.h + * + * Copyright (c) 2021 AWINIC Technology CO., LTD + * + * Author: Barry + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. */ + #ifndef __AW87XXX_PID_59_5X9_REG_H__ #define __AW87XXX_PID_59_5X9_REG_H__ diff --git a/sound/soc/codecs/aw87xxx/aw87xxx_pid_5a_reg.h b/sound/soc/codecs/aw87xxx/aw87xxx_pid_5a_reg.h index ef2213b234d5..32a40cb01c4e 100644 --- a/sound/soc/codecs/aw87xxx/aw87xxx_pid_5a_reg.h +++ b/sound/soc/codecs/aw87xxx/aw87xxx_pid_5a_reg.h @@ -1,12 +1,16 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * @Descripttion: Header file of AW87XXX_PID_5A_REG - * @version: V1.4 - * @Author: zhaozhongbo - * @Date: 2021-03-10 - * @LastEditors: Please set LastEditors - * @LastEditTime: 2021-03-10 +/* SPDX-License-Identifier: GPL-2.0 + * aw87xxx_pid_5a_reg.h + * + * Copyright (c) 2021 AWINIC Technology CO., LTD + * + * Author: Barry + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. */ + #ifndef __AW87XXX_PID_5A_REG_H__ #define __AW87XXX_PID_5A_REG_H__ @@ -486,10 +490,10 @@ const unsigned char aw87xxx_pid_5a_reg_access[AW87XXX_PID_5A_REG_MAX] = { #define AW87XXX_PID_5A_REG_BURST_HYS_SELA_8P3MV_VALUE \ (AW87XXX_PID_5A_REG_BURST_HYS_SELA_8P3MV << AW87XXX_PID_5A_REG_BURST_HYS_SELA_START_BIT) /* -#define AW87XXX_PID_5A_REG_BURST_HYS_SELA_8P3MV (3) -#define AW87XXX_PID_5A_REG_BURST_HYS_SELA_8P3MV_VALUE \ + *#define AW87XXX_PID_5A_REG_BURST_HYS_SELA_8P3MV (3) + *#define AW87XXX_PID_5A_REG_BURST_HYS_SELA_8P3MV_VALUE \ (AW87XXX_PID_5A_REG_BURST_HYS_SELA_8P3MV << AW87XXX_PID_5A_REG_BURST_HYS_SELA_START_BIT) -*/ + */ #define AW87XXX_PID_5A_REG_BURST_HYS_SELA_DEFAULT_VALUE (0) #define AW87XXX_PID_5A_REG_BURST_HYS_SELA_DEFAULT \ (AW87XXX_PID_5A_REG_BURST_HYS_SELA_DEFAULT_VALUE << AW87XXX_PID_5A_REG_BURST_HYS_SELA_START_BIT) @@ -592,10 +596,10 @@ const unsigned char aw87xxx_pid_5a_reg_access[AW87XXX_PID_5A_REG_MAX] = { #define AW87XXX_PID_5A_REG_BURST_HYS_SEL_8P3MV_VALUE \ (AW87XXX_PID_5A_REG_BURST_HYS_SEL_8P3MV << AW87XXX_PID_5A_REG_BURST_HYS_SEL_START_BIT) /* -#define AW87XXX_PID_5A_REG_BURST_HYS_SEL_8P3MV (3) -#define AW87XXX_PID_5A_REG_BURST_HYS_SEL_8P3MV_VALUE \ + *#define AW87XXX_PID_5A_REG_BURST_HYS_SEL_8P3MV (3) + *#define AW87XXX_PID_5A_REG_BURST_HYS_SEL_8P3MV_VALUE \ (AW87XXX_PID_5A_REG_BURST_HYS_SEL_8P3MV << AW87XXX_PID_5A_REG_BURST_HYS_SEL_START_BIT) -*/ + */ #define AW87XXX_PID_5A_REG_BURST_HYS_SEL_DEFAULT_VALUE (0x0) #define AW87XXX_PID_5A_REG_BURST_HYS_SEL_DEFAULT \ (AW87XXX_PID_5A_REG_BURST_HYS_SEL_DEFAULT_VALUE << AW87XXX_PID_5A_REG_BURST_HYS_SEL_START_BIT) @@ -1290,10 +1294,10 @@ const unsigned char aw87xxx_pid_5a_reg_access[AW87XXX_PID_5A_REG_MAX] = { #define AW87XXX_PID_5A_REG_AGC1_ATT_TIME_0P005MSDB_VALUE \ (AW87XXX_PID_5A_REG_AGC1_ATT_TIME_0P005MSDB << AW87XXX_PID_5A_REG_AGC1_ATT_TIME_START_BIT) /* -#define AW87XXX_PID_5A_REG_AGC1_ATT_TIME_0P005MSDB (7) -#define AW87XXX_PID_5A_REG_AGC1_ATT_TIME_0P005MSDB_VALUE \ - (AW87XXX_PID_5A_REG_AGC1_ATT_TIME_0P005MSDB << AW87XXX_PID_5A_REG_AGC1_ATT_TIME_START_BIT) -*/ + *#define AW87XXX_PID_5A_REG_AGC1_ATT_TIME_0P005MSDB (7) + *#define AW87XXX_PID_5A_REG_AGC1_ATT_TIME_0P005MSDB_VALUE \ + * (AW87XXX_PID_5A_REG_AGC1_ATT_TIME_0P005MSDB << AW87XXX_PID_5A_REG_AGC1_ATT_TIME_START_BIT) + */ #define AW87XXX_PID_5A_REG_AGC1_ATT_TIME_DEFAULT_VALUE (0x1) #define AW87XXX_PID_5A_REG_AGC1_ATT_TIME_DEFAULT \ (AW87XXX_PID_5A_REG_AGC1_ATT_TIME_DEFAULT_VALUE << AW87XXX_PID_5A_REG_AGC1_ATT_TIME_START_BIT) @@ -1354,10 +1358,10 @@ const unsigned char aw87xxx_pid_5a_reg_access[AW87XXX_PID_5A_REG_MAX] = { #define AW87XXX_PID_5A_REG_AGC1_ATT_TIMEA_0P005MSDB_VALUE \ (AW87XXX_PID_5A_REG_AGC1_ATT_TIMEA_0P005MSDB << AW87XXX_PID_5A_REG_AGC1_ATT_TIMEA_START_BIT) /* -#define AW87XXX_PID_5A_REG_AGC1_ATT_TIMEA_0P005MSDB (7) -#define AW87XXX_PID_5A_REG_AGC1_ATT_TIMEA_0P005MSDB_VALUE \ - (AW87XXX_PID_5A_REG_AGC1_ATT_TIMEA_0P005MSDB << AW87XXX_PID_5A_REG_AGC1_ATT_TIMEA_START_BIT) -*/ + *#define AW87XXX_PID_5A_REG_AGC1_ATT_TIMEA_0P005MSDB (7) + *#define AW87XXX_PID_5A_REG_AGC1_ATT_TIMEA_0P005MSDB_VALUE \ + * (AW87XXX_PID_5A_REG_AGC1_ATT_TIMEA_0P005MSDB << AW87XXX_PID_5A_REG_AGC1_ATT_TIMEA_START_BIT) + */ #define AW87XXX_PID_5A_REG_AGC1_ATT_TIMEA_DEFAULT_VALUE (0) #define AW87XXX_PID_5A_REG_AGC1_ATT_TIMEA_DEFAULT \ (AW87XXX_PID_5A_REG_AGC1_ATT_TIMEA_DEFAULT_VALUE << AW87XXX_PID_5A_REG_AGC1_ATT_TIMEA_START_BIT) @@ -1396,10 +1400,10 @@ const unsigned char aw87xxx_pid_5a_reg_access[AW87XXX_PID_5A_REG_MAX] = { #define AW87XXX_PID_5A_REG_ADPBOOST_MODE_MD5_VALUE \ (AW87XXX_PID_5A_REG_ADPBOOST_MODE_MD5 << AW87XXX_PID_5A_REG_ADPBOOST_MODE_START_BIT) /* -#define AW87XXX_PID_5A_REG_ADPBOOST_MODE_MD2 (7) -#define AW87XXX_PID_5A_REG_ADPBOOST_MODE_MD2_VALUE \ - (AW87XXX_PID_5A_REG_ADPBOOST_MODE_MD2 << AW87XXX_PID_5A_REG_ADPBOOST_MODE_START_BIT) -*/ + *#define AW87XXX_PID_5A_REG_ADPBOOST_MODE_MD2 (7) + *#define AW87XXX_PID_5A_REG_ADPBOOST_MODE_MD2_VALUE \ + * (AW87XXX_PID_5A_REG_ADPBOOST_MODE_MD2 << AW87XXX_PID_5A_REG_ADPBOOST_MODE_START_BIT) + */ #define AW87XXX_PID_5A_REG_ADPBOOST_MODE_DEFAULT_VALUE (0x3) #define AW87XXX_PID_5A_REG_ADPBOOST_MODE_DEFAULT \ (AW87XXX_PID_5A_REG_ADPBOOST_MODE_DEFAULT_VALUE << AW87XXX_PID_5A_REG_ADPBOOST_MODE_START_BIT) @@ -1772,10 +1776,10 @@ const unsigned char aw87xxx_pid_5a_reg_access[AW87XXX_PID_5A_REG_MAX] = { #define AW87XXX_PID_5A_REG_SET_BOOST_VTH2_2P4W_VALUE \ (AW87XXX_PID_5A_REG_SET_BOOST_VTH2_2P4W << AW87XXX_PID_5A_REG_SET_BOOST_VTH2_START_BIT) /* -#define AW87XXX_PID_5A_REG_SET_BOOST_VTH2_2P4W (7) -#define AW87XXX_PID_5A_REG_SET_BOOST_VTH2_2P4W_VALUE \ - (AW87XXX_PID_5A_REG_SET_BOOST_VTH2_2P4W << AW87XXX_PID_5A_REG_SET_BOOST_VTH2_START_BIT) -*/ + *#define AW87XXX_PID_5A_REG_SET_BOOST_VTH2_2P4W (7) + *#define AW87XXX_PID_5A_REG_SET_BOOST_VTH2_2P4W_VALUE \ + * (AW87XXX_PID_5A_REG_SET_BOOST_VTH2_2P4W << AW87XXX_PID_5A_REG_SET_BOOST_VTH2_START_BIT) + */ #define AW87XXX_PID_5A_REG_SET_BOOST_VTH2_DEFAULT_VALUE (0x4) #define AW87XXX_PID_5A_REG_SET_BOOST_VTH2_DEFAULT \ (AW87XXX_PID_5A_REG_SET_BOOST_VTH2_DEFAULT_VALUE << AW87XXX_PID_5A_REG_SET_BOOST_VTH2_START_BIT) @@ -1810,14 +1814,14 @@ const unsigned char aw87xxx_pid_5a_reg_access[AW87XXX_PID_5A_REG_MAX] = { #define AW87XXX_PID_5A_REG_SET_BOOST_VTH1_0P6W_VALUE \ (AW87XXX_PID_5A_REG_SET_BOOST_VTH1_0P6W << AW87XXX_PID_5A_REG_SET_BOOST_VTH1_START_BIT) /* -#define AW87XXX_PID_5A_REG_SET_BOOST_VTH1_0P6W (6) -#define AW87XXX_PID_5A_REG_SET_BOOST_VTH1_0P6W_VALUE \ - (AW87XXX_PID_5A_REG_SET_BOOST_VTH1_0P6W << AW87XXX_PID_5A_REG_SET_BOOST_VTH1_START_BIT) + *#define AW87XXX_PID_5A_REG_SET_BOOST_VTH1_0P6W (6) + *#define AW87XXX_PID_5A_REG_SET_BOOST_VTH1_0P6W_VALUE \ + * (AW87XXX_PID_5A_REG_SET_BOOST_VTH1_0P6W << AW87XXX_PID_5A_REG_SET_BOOST_VTH1_START_BIT) -#define AW87XXX_PID_5A_REG_SET_BOOST_VTH1_0P6W (7) -#define AW87XXX_PID_5A_REG_SET_BOOST_VTH1_0P6W_VALUE \ - (AW87XXX_PID_5A_REG_SET_BOOST_VTH1_0P6W << AW87XXX_PID_5A_REG_SET_BOOST_VTH1_START_BIT) -*/ + *#define AW87XXX_PID_5A_REG_SET_BOOST_VTH1_0P6W (7) + *#define AW87XXX_PID_5A_REG_SET_BOOST_VTH1_0P6W_VALUE \ + * (AW87XXX_PID_5A_REG_SET_BOOST_VTH1_0P6W << AW87XXX_PID_5A_REG_SET_BOOST_VTH1_START_BIT) + */ #define AW87XXX_PID_5A_REG_SET_BOOST_VTH1_DEFAULT_VALUE (0x3) #define AW87XXX_PID_5A_REG_SET_BOOST_VTH1_DEFAULT \ (AW87XXX_PID_5A_REG_SET_BOOST_VTH1_DEFAULT_VALUE << AW87XXX_PID_5A_REG_SET_BOOST_VTH1_START_BIT) @@ -2726,10 +2730,10 @@ const unsigned char aw87xxx_pid_5a_reg_access[AW87XXX_PID_5A_REG_MAX] = { #define AW87XXX_PID_5A_REG_BST_LOOPR_480K_VALUE \ (AW87XXX_PID_5A_REG_BST_LOOPR_480K << AW87XXX_PID_5A_REG_BST_LOOPR_START_BIT) /* -#define AW87XXX_PID_5A_REG_BST_LOOPR_320K (3) -#define AW87XXX_PID_5A_REG_BST_LOOPR_320K_VALUE \ - (AW87XXX_PID_5A_REG_BST_LOOPR_320K << AW87XXX_PID_5A_REG_BST_LOOPR_START_BIT) -*/ + *#define AW87XXX_PID_5A_REG_BST_LOOPR_320K (3) + *#define AW87XXX_PID_5A_REG_BST_LOOPR_320K_VALUE \ + * (AW87XXX_PID_5A_REG_BST_LOOPR_320K << AW87XXX_PID_5A_REG_BST_LOOPR_START_BIT) + */ #define AW87XXX_PID_5A_REG_BST_LOOPR_DEFAULT_VALUE (0x2) #define AW87XXX_PID_5A_REG_BST_LOOPR_DEFAULT \ (AW87XXX_PID_5A_REG_BST_LOOPR_DEFAULT_VALUE << AW87XXX_PID_5A_REG_BST_LOOPR_START_BIT) @@ -2882,10 +2886,10 @@ const unsigned char aw87xxx_pid_5a_reg_access[AW87XXX_PID_5A_REG_MAX] = { #define AW87XXX_PID_5A_REG_AGC1_VTH_SEL_RAMP_GEN_AND_THGEN_VALUE \ (AW87XXX_PID_5A_REG_AGC1_VTH_SEL_RAMP_GEN_AND_THGEN << AW87XXX_PID_5A_REG_AGC1_VTH_SEL_START_BIT) /* -#define AW87XXX_PID_5A_REG_AGC1_VTH_SEL_RAMP_GEN_AND_THGEN (3) -#define AW87XXX_PID_5A_REG_AGC1_VTH_SEL_RAMP_GEN_AND_THGEN_VALUE \ - (AW87XXX_PID_5A_REG_AGC1_VTH_SEL_RAMP_GEN_AND_THGEN << AW87XXX_PID_5A_REG_AGC1_VTH_SEL_START_BIT) -*/ + *#define AW87XXX_PID_5A_REG_AGC1_VTH_SEL_RAMP_GEN_AND_THGEN (3) + *#define AW87XXX_PID_5A_REG_AGC1_VTH_SEL_RAMP_GEN_AND_THGEN_VALUE \ + * (AW87XXX_PID_5A_REG_AGC1_VTH_SEL_RAMP_GEN_AND_THGEN << AW87XXX_PID_5A_REG_AGC1_VTH_SEL_START_BIT) + */ #define AW87XXX_PID_5A_REG_AGC1_VTH_SEL_DEFAULT_VALUE (0x2) #define AW87XXX_PID_5A_REG_AGC1_VTH_SEL_DEFAULT \ (AW87XXX_PID_5A_REG_AGC1_VTH_SEL_DEFAULT_VALUE << AW87XXX_PID_5A_REG_AGC1_VTH_SEL_START_BIT) @@ -3815,18 +3819,18 @@ const unsigned char aw87xxx_pid_5a_reg_access[AW87XXX_PID_5A_REG_MAX] = { #define AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_1P25SLOPE_VALUE \ (AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_1P25SLOPE << AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_START_BIT) /* -#define AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_0P5SLOPE (4) -#define AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_0P5SLOPE_VALUE \ - (AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_0P5SLOPE << AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_START_BIT) -*/ + *#define AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_0P5SLOPE (4) + *#define AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_0P5SLOPE_VALUE \ + * (AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_0P5SLOPE << AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_START_BIT) + */ #define AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_0P75SLOPE (5) #define AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_0P75SLOPE_VALUE \ (AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_0P75SLOPE << AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_START_BIT) /* -#define AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_1P25SLOPE (6) -#define AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_1P25SLOPE_VALUE \ - (AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_1P25SLOPE << AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_START_BIT) -*/ + *#define AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_1P25SLOPE (6) + *#define AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_1P25SLOPE_VALUE \ + * (AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_1P25SLOPE << AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_START_BIT) + */ #define AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_1P75SLOPE (7) #define AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_1P75SLOPE_VALUE \ (AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_1P75SLOPE << AW87XXX_PID_5A_REG_BST_SLOPE_LIMIT_START_BIT) @@ -4047,10 +4051,10 @@ const unsigned char aw87xxx_pid_5a_reg_access[AW87XXX_PID_5A_REG_MAX] = { #define AW87XXX_PID_5A_REG_SS_CONTROL_SW20000_VALUE \ (AW87XXX_PID_5A_REG_SS_CONTROL_SW20000 << AW87XXX_PID_5A_REG_SS_CONTROL_START_BIT) /* -#define AW87XXX_PID_5A_REG_SS_CONTROL_SW20111 (3) -#define AW87XXX_PID_5A_REG_SS_CONTROL_SW20111_VALUE \ - (AW87XXX_PID_5A_REG_SS_CONTROL_SW20111 << AW87XXX_PID_5A_REG_SS_CONTROL_START_BIT) -*/ + *#define AW87XXX_PID_5A_REG_SS_CONTROL_SW20111 (3) + *#define AW87XXX_PID_5A_REG_SS_CONTROL_SW20111_VALUE \ + * (AW87XXX_PID_5A_REG_SS_CONTROL_SW20111 << AW87XXX_PID_5A_REG_SS_CONTROL_START_BIT) + */ #define AW87XXX_PID_5A_REG_SS_CONTROL_DEFAULT_VALUE (0x0) #define AW87XXX_PID_5A_REG_SS_CONTROL_DEFAULT \ (AW87XXX_PID_5A_REG_SS_CONTROL_DEFAULT_VALUE << AW87XXX_PID_5A_REG_SS_CONTROL_START_BIT) @@ -4122,4 +4126,4 @@ const unsigned char aw87xxx_pid_5a_reg_access[AW87XXX_PID_5A_REG_MAX] = { /* detail information of registers end */ -#endif /* #ifndef __AW87XXX_PID_5A_REG_H__ */ \ No newline at end of file +#endif /* #ifndef __AW87XXX_PID_5A_REG_H__ */ diff --git a/sound/soc/codecs/aw87xxx/aw87xxx_pid_60_reg.h b/sound/soc/codecs/aw87xxx/aw87xxx_pid_60_reg.h new file mode 100644 index 000000000000..b614d0604120 --- /dev/null +++ b/sound/soc/codecs/aw87xxx/aw87xxx_pid_60_reg.h @@ -0,0 +1,5259 @@ +/* SPDX-License-Identifier: GPL-2.0 + * aw87xxx_pid_60_reg.h + * + * Copyright (c) 2021 AWINIC Technology CO., LTD + * + * Author: Barry + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __AW87XXX_PID_60_REG_H__ +#define __AW87XXX_PID_60_REG_H__ + +/* registers list */ +#define AW87XXX_PID_60_ID_REG (0x00) +#define AW87XXX_PID_60_SYSCTRL_REG (0x01) +#define AW87XXX_PID_60_BSTOVR_REG (0x02) +#define AW87XXX_PID_60_PEAKLIMIT_REG (0x03) +#define AW87XXX_PID_60_ADPSET_REG (0x04) +#define AW87XXX_PID_60_PAG_REG (0x05) +#define AW87XXX_PID_60_AGC1PA_REG (0x06) +#define AW87XXX_PID_60_AGC2PA_REG (0x07) +#define AW87XXX_PID_60_AGC3PA_REG (0x08) +#define AW87XXX_PID_60_AGC3P_REG (0x09) +#define AW87XXX_PID_60_LOW_BAT_REG (0x0A) +#define AW87XXX_PID_60_BSTOUT_REG (0x0B) +#define AW87XXX_PID_60_SYSST_REG (0x59) +#define AW87XXX_PID_60_SYSINT_REG (0x60) +#define AW87XXX_PID_60_BURST_CON_REG (0x61) +#define AW87XXX_PID_60_BST_BIAS_REG (0x62) +#define AW87XXX_PID_60_BST_EA_REG (0x63) +#define AW87XXX_PID_60_BST_DE_SOFT_REG (0x64) +#define AW87XXX_PID_60_BST_BURST_KICK_REG (0x65) +#define AW87XXX_PID_60_BST_CON1_REG (0x66) +#define AW87XXX_PID_60_BST_OVP_REG (0x67) +#define AW87XXX_PID_60_LINE_MODE_REG (0x68) +#define AW87XXX_PID_60_BST_ISEN_REG (0x69) +#define AW87XXX_PID_60_BST_PEAK_REG (0x6A) +#define AW87XXX_PID_60_BST_PEAK2_REG (0x6B) +#define AW87XXX_PID_60_OFFTIME_REG (0x6C) +#define AW87XXX_PID_60_ADPBST_REG (0x6D) +#define AW87XXX_PID_60_OTA_REG (0x6E) +#define AW87XXX_PID_60_RAMPGEN_REG (0x6F) +#define AW87XXX_PID_60_CLASSD_SYSCTRL_REG (0x70) +#define AW87XXX_PID_60_GTDR_REG (0x71) +#define AW87XXX_PID_60_OC_REG (0x72) +#define AW87XXX_PID_60_AGC_CON_REG (0x73) +#define AW87XXX_PID_60_NG_REG (0x74) +#define AW87XXX_PID_60_NG2_REG (0x75) +#define AW87XXX_PID_60_NG3_REG (0x76) +#define AW87XXX_PID_60_CP_REG (0x77) +#define AW87XXX_PID_60_TEST_GTDR_REG (0x78) +#define AW87XXX_PID_60_TEST_BST_REG (0x79) +#define AW87XXX_PID_60_TEST_MODE_REG (0x7A) +#define AW87XXX_PID_60_TEST_CON_REG (0x7B) +#define AW87XXX_PID_60_ENCR_REG (0x7C) + +/******************************************** + * soft control info + * If you need to update this file, add this information manually + *******************************************/ +unsigned char aw87xxx_pid_60_softrst_access[2] = {0x00, 0xaa}; + +/******************************************** + * Register Access + *******************************************/ +#define AW87XXX_PID_60_REG_MAX (0x7D) + +#define REG_NONE_ACCESS (0) +#define REG_RD_ACCESS (1 << 0) +#define REG_WR_ACCESS (1 << 1) +#define AW87XXX_PID_60_ESD_REG_VAL (0x91) + +const unsigned char aw87xxx_pid_60_reg_access[AW87XXX_PID_60_REG_MAX] = { + [AW87XXX_PID_60_ID_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_60_SYSCTRL_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_BSTOVR_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_PEAKLIMIT_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_ADPSET_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_PAG_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_AGC1PA_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_AGC2PA_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_AGC3PA_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_AGC3P_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_LOW_BAT_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_BSTOUT_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_60_SYSST_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_60_SYSINT_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_60_BURST_CON_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_BST_BIAS_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_BST_EA_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_BST_DE_SOFT_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_BST_BURST_KICK_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_BST_CON1_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_BST_OVP_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_LINE_MODE_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_BST_ISEN_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_BST_PEAK_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_BST_PEAK2_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_OFFTIME_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_ADPBST_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_OTA_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_RAMPGEN_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_CLASSD_SYSCTRL_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_GTDR_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_OC_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_AGC_CON_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_NG_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_NG2_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_NG3_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_CP_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_TEST_GTDR_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_TEST_BST_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_TEST_MODE_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_TEST_CON_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_60_ENCR_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), +}; + +/* detail information of registers begin */ +/* ID (0x00) detail */ +/* IDCODE bit 7:0 (ID 0x00) */ +#define AW87XXX_PID_60_IDCODE_START_BIT (0) +#define AW87XXX_PID_60_IDCODE_BITS_LEN (8) +#define AW87XXX_PID_60_IDCODE_MASK \ + (~(((1< + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + #ifndef __AW87XXX_PID_76_REG_H__ #define __AW87XXX_PID_76_REG_H__ @@ -1203,4 +1215,4 @@ const unsigned char aw87xxx_pid_76_reg_access[AW87XXX_PID_76_REG_MAX] = { /* detail information of registers end */ -#endif /* #ifndef __AW87XXX_PID_76_REG_H__ */ \ No newline at end of file +#endif /* #ifndef __AW87XXX_PID_76_REG_H__ */ diff --git a/sound/soc/codecs/aw87xxx/aw87xxx_pid_9b_reg.h b/sound/soc/codecs/aw87xxx/aw87xxx_pid_9b_reg.h index 70105a697540..baebf515d1f9 100644 --- a/sound/soc/codecs/aw87xxx/aw87xxx_pid_9b_reg.h +++ b/sound/soc/codecs/aw87xxx/aw87xxx_pid_9b_reg.h @@ -1,4 +1,15 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ +/* SPDX-License-Identifier: GPL-2.0 + * aw87xxx_pid_9b_reg.h + * + * Copyright (c) 2021 AWINIC Technology CO., LTD + * + * Author: Barry + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ #ifndef __AW87XXX_PID_9B_REG_H__ #define __AW87XXX_PID_9B_REG_H__ diff --git a/sound/soc/codecs/aw87xxx/aw87xxx_pid_c1_reg.h b/sound/soc/codecs/aw87xxx/aw87xxx_pid_c1_reg.h new file mode 100644 index 000000000000..620aa4e84500 --- /dev/null +++ b/sound/soc/codecs/aw87xxx/aw87xxx_pid_c1_reg.h @@ -0,0 +1,698 @@ +/* SPDX-License-Identifier: GPL-2.0 + * aw87xxx_pid_c1_reg.h + * + * Copyright (c) 2021 AWINIC Technology CO., LTD + * + * Author: Barry + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __AW87XXX_PID_C1_REG_H__ +#define __AW87XXX_PID_C1_REG_H__ + +/* registers list */ +#define AW87XXX_PID_C1_ID_REG (0x00) +#define AW87XXX_PID_C1_SYSCTRL_REG (0x01) +#define AW87XXX_PID_C1_CP_REG (0x02) +#define AW87XXX_PID_C1_PAG_REG (0x03) +#define AW87XXX_PID_C1_AGCPO_REG (0x04) +#define AW87XXX_PID_C1_AGC2PA_REG (0x05) +#define AW87XXX_PID_C1_SYSST_REG (0x06) +#define AW87XXX_PID_C1_SYSINT_REG (0x07) +#define AW87XXX_PID_C1_DFT_SYSCTRL0_REG (0x5D) +#define AW87XXX_PID_C1_DFT_SYSCTRL1_REG (0x5E) +#define AW87XXX_PID_C1_DFT_CP_REG (0x5F) +#define AW87XXX_PID_C1_DFT_TRIM0_REG (0x60) +#define AW87XXX_PID_C1_DFT_TRIM1_REG (0x61) +#define AW87XXX_PID_C1_DFT_OC_REG (0x62) +#define AW87XXX_PID_C1_DFT_THGEN0_REG (0x63) +#define AW87XXX_PID_C1_DFT_THGEN1_REG (0x64) +#define AW87XXX_PID_C1_DFT_AGC_REG (0x65) +#define AW87XXX_PID_C1_DFT_LPMODE_REG (0x66) +#define AW87XXX_PID_C1_DFT_RAMPGEN_REG (0x67) +#define AW87XXX_PID_C1_DFT_BIAS_REG (0x68) +#define AW87XXX_PID_C1_OPTION_STATUS0_REG (0x69) +#define AW87XXX_PID_C1_OPTION_STATUS1_REG (0x6A) +#define AW87XXX_PID_C1_OPTION_STATUS2_REG (0x6B) +#define AW87XXX_PID_C1_OPTION_STATUS3_REG (0x6C) +#define AW87XXX_PID_C1_TESTCTRL0_REG (0x6E) +#define AW87XXX_PID_C1_TESTCTRL1_REG (0x6F) +#define AW87XXX_PID_C1_EFWH_REG (0x70) +#define AW87XXX_PID_C1_EFWL_REG (0x71) +#define AW87XXX_PID_C1_EFCTRL1_REG (0x72) +#define AW87XXX_PID_C1_EFCTRL2_REG (0x73) +#define AW87XXX_PID_C1_EFCTRL3_REG (0x74) +#define AW87XXX_PID_C1_EFCTRL4_REG (0x75) +#define AW87XXX_PID_C1_EFRH2_REG (0x76) +#define AW87XXX_PID_C1_EFRH1_REG (0x77) +#define AW87XXX_PID_C1_EFRL2_REG (0x78) +#define AW87XXX_PID_C1_EFRL1_REG (0x79) +#define AW87XXX_PID_C1_TM_REG (0x7A) +#define AW87XXX_PID_C1_TESTIN_REG (0x7B) +#define AW87XXX_PID_C1_TESTIN1_REG (0x7C) +#define AW87XXX_PID_C1_TESTIN2_REG (0x7D) +#define AW87XXX_PID_C1_TESTOUT1_REG (0x7E) +#define AW87XXX_PID_C1_TESTOUT2_REG (0x7F) + +#define AW87XXX_PID_C1_DFT_THGEN1_CHECK (0x0a) + +/******************************************** + * soft control info + * If you need to update this file, add this information manually + *******************************************/ +unsigned char aw87xxx_pid_c1_softrst_access[2] = {0x00, 0xaa}; + +/******************************************** + * Register Access + *******************************************/ +#define AW87XXX_PID_C1_REG_MAX (0x80) + +#define REG_NONE_ACCESS (0) +#define REG_RD_ACCESS (1 << 0) +#define REG_WR_ACCESS (1 << 1) + +const unsigned char aw87xxx_pid_c1_reg_access[AW87XXX_PID_C1_REG_MAX] = { + [AW87XXX_PID_C1_ID_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C1_SYSCTRL_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_CP_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_PAG_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_AGCPO_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_AGC2PA_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_SYSST_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C1_SYSINT_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C1_DFT_SYSCTRL0_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_DFT_SYSCTRL1_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_DFT_CP_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_DFT_TRIM0_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_DFT_TRIM1_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_DFT_OC_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_DFT_THGEN0_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_DFT_THGEN1_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_DFT_AGC_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_DFT_LPMODE_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_DFT_RAMPGEN_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_DFT_BIAS_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_OPTION_STATUS0_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C1_OPTION_STATUS1_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C1_OPTION_STATUS2_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C1_OPTION_STATUS3_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C1_TESTCTRL0_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_TESTCTRL1_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_EFWH_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_EFWL_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_EFCTRL1_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_EFCTRL2_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_EFCTRL3_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_EFCTRL4_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_EFRH2_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C1_EFRH1_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C1_EFRL2_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C1_EFRL1_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C1_TM_REG] = (REG_NONE_ACCESS), + [AW87XXX_PID_C1_TESTIN_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_TESTIN1_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_TESTIN2_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C1_TESTOUT1_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C1_TESTOUT2_REG] = (REG_RD_ACCESS), +}; + +/* detail information of registers begin */ +/* ID (0x00) detail */ +/* IDCODE bit 7:0 (ID 0x00) */ +#define AW87XXX_PID_C1_IDCODE_START_BIT (0) +#define AW87XXX_PID_C1_IDCODE_BITS_LEN (8) +#define AW87XXX_PID_C1_IDCODE_MASK \ + (~(((1< + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __AW87XXX_PID_C2_REG_H__ +#define __AW87XXX_PID_C2_REG_H__ + +/* registers list */ +#define AW87XXX_PID_C2_ID_REG (0x00) +#define AW87XXX_PID_C2_SYSCTRL_REG (0x01) +#define AW87XXX_PID_C2_BSTOVR_REG (0x02) +#define AW87XXX_PID_C2_PEAKLIMIT_REG (0x03) +#define AW87XXX_PID_C2_ADPSET_REG (0x04) +#define AW87XXX_PID_C2_PAG_REG (0x05) +#define AW87XXX_PID_C2_AGC1PA_REG (0x06) +#define AW87XXX_PID_C2_AGC2PA_REG (0x07) +#define AW87XXX_PID_C2_AGC3PA_REG (0x08) +#define AW87XXX_PID_C2_AGC3P_REG (0x09) +#define AW87XXX_PID_C2_BATT_DECT_REG (0x0A) +#define AW87XXX_PID_C2_BSTOUT_REG (0x0B) +#define AW87XXX_PID_C2_SYSST_REG (0x59) +#define AW87XXX_PID_C2_SYSINT_REG (0x60) +#define AW87XXX_PID_C2_BURST_CON_REG (0x0C) +#define AW87XXX_PID_C2_BST_BIAS_REG (0x0D) +#define AW87XXX_PID_C2_BST_EA_REG (0x0E) +#define AW87XXX_PID_C2_BST_DE_SOFT_REG (0x0F) +#define AW87XXX_PID_C2_BST_BURST_KICK_REG (0x10) +#define AW87XXX_PID_C2_BST_CON1_REG (0x11) +#define AW87XXX_PID_C2_BST_OVP_REG (0x12) +#define AW87XXX_PID_C2_LINE_MODE_REG (0x13) +#define AW87XXX_PID_C2_BST_ISEN_REG (0x14) +#define AW87XXX_PID_C2_BST_PEAK_REG (0x15) +#define AW87XXX_PID_C2_OFFTIME_MODE_REG (0x16) +#define AW87XXX_PID_C2_OFFTIME_REG (0x17) +#define AW87XXX_PID_C2_ADPBST_IRUSH_REG (0x18) +#define AW87XXX_PID_C2_RAMPGEN_REG (0x19) +#define AW87XXX_PID_C2_CLASSD_SYSCTRL_REG (0x1A) +#define AW87XXX_PID_C2_GTDR_REG (0x1B) +#define AW87XXX_PID_C2_OC_REG (0x1C) +#define AW87XXX_PID_C2_AGC_CON_REG (0x1D) +#define AW87XXX_PID_C2_LP_MODE_REG (0x1E) +#define AW87XXX_PID_C2_THGEN_UVLO_REG (0x1F) +#define AW87XXX_PID_C2_VOS_TRIM_REG (0x20) +#define AW87XXX_PID_C2_CP_REG (0x21) +#define AW87XXX_PID_C2_BOP_TIME_REG (0x22) +#define AW87XXX_PID_C2_BOP_TIME2_REG (0x23) +#define AW87XXX_PID_C2_OPTION_STATUS0_REG (0x24) +#define AW87XXX_PID_C2_OPTION_STATUS1_REG (0x25) +#define AW87XXX_PID_C2_OPTION_STATUS2_REG (0x26) +#define AW87XXX_PID_C2_OPTION_STATUS3_REG (0x27) +#define AW87XXX_PID_C2_TESTCTRL0_REG (0x28) +#define AW87XXX_PID_C2_TESTCTRL1_REG (0x29) +#define AW87XXX_PID_C2_EFWH_REG (0x2A) +#define AW87XXX_PID_C2_EFWM_REG (0x2B) +#define AW87XXX_PID_C2_EFWL_REG (0x2C) +#define AW87XXX_PID_C2_EFCTRL1_REG (0x2D) +#define AW87XXX_PID_C2_EFCTRL2_REG (0x2E) +#define AW87XXX_PID_C2_EFCTRL3_REG (0x2F) +#define AW87XXX_PID_C2_EFCTRL4_REG (0x30) +#define AW87XXX_PID_C2_EFRHH_REG (0x31) +#define AW87XXX_PID_C2_EFRHL_REG (0x32) +#define AW87XXX_PID_C2_EFRMH_REG (0x33) +#define AW87XXX_PID_C2_EFRML_REG (0x34) +#define AW87XXX_PID_C2_EFRLH_REG (0x35) +#define AW87XXX_PID_C2_EFRLL_REG (0x36) +#define AW87XXX_PID_C2_CRCOUT0_REG (0x37) +#define AW87XXX_PID_C2_CRCOUT1_REG (0x38) +#define AW87XXX_PID_C2_TESTOUT2_REG (0x39) +#define AW87XXX_PID_C2_TESTOUT3_REG (0x3A) +#define AW87XXX_PID_C2_TESTOUT4_REG (0x3B) +#define AW87XXX_PID_C2_TESTOUT5_REG (0x3C) +#define AW87XXX_PID_C2_TESTOUT6_REG (0x3D) +#define AW87XXX_PID_C2_TESTIN1_REG (0x3E) +#define AW87XXX_PID_C2_TESTIN2_REG (0x3F) +#define AW87XXX_PID_C2_RESERVED_REG1_REG (0x50) +#define AW87XXX_PID_C2_RESERVED_REG2_REG (0x51) +#define AW87XXX_PID_C2_TM_REG (0x7E) +#define AW87XXX_PID_C2_TESTIN_REG (0x7F) + +#define AW87XXX_PID_C2_CP_CHECK (0x77) + +/******************************************** + * soft control info + * If you need to update this file, add this information manually + *******************************************/ +unsigned char aw87xxx_pid_c2_softrst_access[2] = {0x00, 0xaa}; + +/******************************************** + * Register Access + *******************************************/ +#define AW87XXX_PID_C2_REG_MAX (0x80) + +#define REG_NONE_ACCESS (0) +#define REG_RD_ACCESS (1 << 0) +#define REG_WR_ACCESS (1 << 1) + +const unsigned char aw87xxx_pid_c2_reg_access[AW87XXX_PID_C2_REG_MAX] = { + [AW87XXX_PID_C2_ID_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C2_SYSCTRL_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_BSTOVR_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_PEAKLIMIT_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_ADPSET_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_PAG_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_AGC1PA_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_AGC2PA_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_AGC3PA_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_AGC3P_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_BATT_DECT_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_BSTOUT_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_SYSST_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C2_SYSINT_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C2_BURST_CON_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_BST_BIAS_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_BST_EA_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_BST_DE_SOFT_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_BST_BURST_KICK_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_BST_CON1_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_BST_OVP_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_LINE_MODE_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_BST_ISEN_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_BST_PEAK_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_OFFTIME_MODE_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_OFFTIME_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_ADPBST_IRUSH_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_RAMPGEN_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_CLASSD_SYSCTRL_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_GTDR_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_OC_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_AGC_CON_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_LP_MODE_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_THGEN_UVLO_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_VOS_TRIM_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_CP_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_BOP_TIME_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_BOP_TIME2_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_OPTION_STATUS0_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C2_OPTION_STATUS1_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C2_OPTION_STATUS2_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C2_OPTION_STATUS3_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C2_TESTCTRL0_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_TESTCTRL1_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_EFWH_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_EFWM_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_EFWL_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_EFCTRL1_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_EFCTRL2_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_EFCTRL3_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_EFCTRL4_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_EFRHH_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C2_EFRHL_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C2_EFRMH_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C2_EFRML_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C2_EFRLH_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C2_EFRLL_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C2_CRCOUT0_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C2_CRCOUT1_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C2_TESTOUT2_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C2_TESTOUT3_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C2_TESTOUT4_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C2_TESTOUT5_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C2_TESTOUT6_REG] = (REG_RD_ACCESS), + [AW87XXX_PID_C2_TESTIN1_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_TESTIN2_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_RESERVED_REG1_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_RESERVED_REG2_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), + [AW87XXX_PID_C2_TM_REG] = (REG_NONE_ACCESS), + [AW87XXX_PID_C2_TESTIN_REG] = (REG_RD_ACCESS | REG_WR_ACCESS), +}; + +/* detail information of registers begin */ +/* ID (0x00) detail */ +/* IDCODE bit 7:0 (ID 0x00) */ +#define AW87XXX_PID_C2_IDCODE_START_BIT (0) +#define AW87XXX_PID_C2_IDCODE_BITS_LEN (8) +#define AW87XXX_PID_C2_IDCODE_MASK \ + (~(((1< -#include +#include #include #include #include @@ -26,6 +26,52 @@ #include "aw_log.h" #include "aw_bin_parse.h" +/************************************************************************* + * + *Table corresponding to customized profile ids to profile names + * + *************************************************************************/ +enum aw_customers_profile_id { + AW_CTOS_PROFILE_OFF = 0, + AW_CTOS_PROFILE_MUSIC, + AW_CTOS_PROFILE_VOICE, + AW_CTOS_PROFILE_VOIP, + AW_CTOS_PROFILE_RINGTONE, + AW_CTOS_PROFILE_RINGTONE_HS, + AW_CTOS_PROFILE_LOWPOWER, + AW_CTOS_PROFILE_BYPASS, + AW_CTOS_PROFILE_MMI, + AW_CTOS_PROFILE_FM, + AW_CTOS_PROFILE_NOTIFICATION, + AW_CTOS_PROFILE_RECEIVER, + AW_CTOS_PROFILE_MAX, +}; + +static char *g_ctos_profile_name[AW_PROFILE_MAX] = { + [AW_CTOS_PROFILE_OFF] = "Off", + [AW_CTOS_PROFILE_MUSIC] = "Music", + [AW_CTOS_PROFILE_VOICE] = "Voice", + [AW_CTOS_PROFILE_VOIP] = "Voip", + [AW_CTOS_PROFILE_RINGTONE] = "Ringtone", + [AW_CTOS_PROFILE_RINGTONE_HS] = "Ringtone_hs", + [AW_CTOS_PROFILE_LOWPOWER] = "Lowpower", + [AW_CTOS_PROFILE_BYPASS] = "Bypass", + [AW_CTOS_PROFILE_MMI] = "Mmi", + [AW_CTOS_PROFILE_FM] = "Fm", + [AW_CTOS_PROFILE_NOTIFICATION] = "Notification", + [AW_CTOS_PROFILE_RECEIVER] = "Receiver", +}; + + +char *aw87xxx_ctos_get_prof_name(int profile_id) +{ + if (profile_id < 0 || profile_id >= AW_CTOS_PROFILE_MAX) + return NULL; + else + return g_ctos_profile_name[profile_id]; +} + + static char *g_profile_name[] = {"Music", "Voice", "Voip", "Ringtone", "Ringtone_hs", "Lowpower", "Bypass", "Mmi", "Fm", "Notification", "Receiver", "Off"}; @@ -132,7 +178,6 @@ static int aw_check_data_size_v_0_0_0_1(struct device *dev, AW_DEV_LOGE(dev, "acf dde[%d].data_size[%d],dev_name[%s],data_type[%d], data_size check failed", i, acf_dde[i].data_size, acf_dde[i].dev_name, acf_dde[i].data_type); - return -EINVAL; } data_size += acf_dde[i].data_size; } @@ -412,7 +457,7 @@ static int aw_parse_reg_with_hdr(struct device *dev, uint8_t *data, aw_bin->info.len = data_len; memcpy(aw_bin->info.data, data, data_len); - ret = aw_parsing_bin_file(aw_bin); + ret = aw87xxx_parsing_bin_file(aw_bin); if (ret < 0) { AW_DEV_LOGE(dev, "parse bin failed"); goto parse_bin_failed; @@ -440,6 +485,51 @@ parse_bin_failed: return ret; } +static int aw_dev_prof_parse_multi_bin(struct device *dev, + uint8_t *data, uint32_t data_len, struct aw_prof_desc *prof_desc) +{ + struct aw_bin *aw_bin = NULL; + int i; + int ret; + + aw_bin = devm_kzalloc(dev, + data_len + sizeof(struct aw_bin), GFP_KERNEL); + if (aw_bin == NULL) + return -ENOMEM; + + + aw_bin->info.len = data_len; + memcpy(aw_bin->info.data, data, data_len); + + ret = aw87xxx_parsing_bin_file(aw_bin); + if (ret < 0) { + AW_DEV_LOGE(dev, "parse bin failed"); + goto parse_bin_failed; + } + + for (i = 0; i < aw_bin->all_bin_parse_num; i++) { + if (aw_bin->header_info[i].bin_data_type == DATA_TYPE_REGISTER) { + prof_desc->data_container.len = aw_bin->header_info[i].valid_data_len; + prof_desc->data_container.data = data + aw_bin->header_info[i].valid_data_addr; + break; + } + } + if (i == aw_bin->all_bin_parse_num) { + AW_DEV_LOGE(dev, "the expected data type was not found,pls check"); + goto parse_bin_failed; + } + + devm_kfree(dev, aw_bin); + aw_bin = NULL; + prof_desc->prof_st = AW_PROFILE_OK; + return 0; + +parse_bin_failed: + devm_kfree(dev, aw_bin); + aw_bin = NULL; + return ret; +} + static int aw_parse_monitor_config(struct device *dev, char *monitor_data, uint32_t data_len) { @@ -450,7 +540,7 @@ static int aw_parse_monitor_config(struct device *dev, return -EBFONT; } - ret = aw_monitor_bin_parse(dev, monitor_data, data_len); + ret = aw87xxx_monitor_bin_parse(dev, monitor_data, data_len); if (ret < 0) { AW_DEV_LOGE(dev, "monitor_config parse failed"); return ret; @@ -484,7 +574,7 @@ static int aw_check_product_name_v_0_0_0_1(struct device *dev, int i = 0; for (i = 0; i < acf_info->product_cnt; i++) { - if (0 == strcmp(acf_info->product_tab[i], prof_hdr->dev_name)) { + if (strcmp(acf_info->product_tab[i], prof_hdr->dev_name) == 0) { AW_DEV_LOGD(dev, "bin_dev_name:%s", prof_hdr->dev_name); return 0; @@ -533,11 +623,15 @@ static int aw_parse_data_by_sec_type_v_0_0_0_1(struct device *dev, prof_hdr->data_size, profile_prof_desc); break; - case AW_MONITOR: - AW_DEV_LOGD(dev, "parse monitor type data enter"); - ret = aw_parse_monitor_config(dev, cfg_data, - prof_hdr->data_size); - break; + case AW_BIN_TYPE_MUTLBIN: + snprintf(profile_prof_desc->dev_name, sizeof(prof_hdr->dev_name), + "%s", prof_hdr->dev_name); + profile_prof_desc->prof_name = aw_get_prof_name(prof_hdr->dev_profile); + AW_DEV_LOGD(dev, "parse mutil type data enter,profile=%s", + aw_get_prof_name(prof_hdr->dev_profile)); + ret = aw_dev_prof_parse_multi_bin(dev, cfg_data, + prof_hdr->data_size, + profile_prof_desc); } return ret; @@ -549,7 +643,7 @@ static int aw_parse_dev_type_v_0_0_0_1(struct device *dev, int i = 0; int ret = -1; int sec_num = 0; - uint8_t soft_off_enable = acf_info->aw_dev->soft_off_enable; + char *cfg_data = NULL; struct aw_prof_desc *prof_desc = NULL; struct aw_acf_dde *acf_dde = (struct aw_acf_dde *)(acf_info->fw_data + acf_info->acf_hdr.ddt_offset); @@ -567,16 +661,14 @@ static int aw_parse_dev_type_v_0_0_0_1(struct device *dev, ret = aw_check_data_type_is_monitor_v_0_0_0_1(dev, &acf_dde[i]); if (ret == 0) { - prof_desc = NULL; - } else { - prof_desc = &all_prof_info->prof_desc[acf_dde[i].dev_profile]; - } - - if (acf_dde[i].dev_profile == AW_PROFILE_OFF && !soft_off_enable) { - AW_DEV_LOGE(dev, "profile off is not allowed"); - return -EINVAL; + cfg_data = acf_info->fw_data + acf_dde[i].data_offset; + ret = aw_parse_monitor_config(dev, cfg_data, acf_dde[i].data_size); + if (ret < 0) + return ret; + continue; } + prof_desc = &all_prof_info->prof_desc[acf_dde[i].dev_profile]; ret = aw_parse_data_by_sec_type_v_0_0_0_1(dev, acf_info, &acf_dde[i], prof_desc); if (ret < 0) { @@ -602,7 +694,7 @@ static int aw_parse_default_type_v_0_0_0_1(struct device *dev, int i = 0; int ret = -1; int sec_num = 0; - uint8_t soft_off_enable = acf_info->aw_dev->soft_off_enable; + char *cfg_data = NULL; struct aw_prof_desc *prof_desc = NULL; struct aw_acf_dde *acf_dde = (struct aw_acf_dde *)(acf_info->fw_data + acf_info->acf_hdr.ddt_offset); @@ -619,16 +711,14 @@ static int aw_parse_default_type_v_0_0_0_1(struct device *dev, ret = aw_check_data_type_is_monitor_v_0_0_0_1(dev, &acf_dde[i]); if (ret == 0) { - prof_desc = NULL; - } else { - prof_desc = &all_prof_info->prof_desc[acf_dde[i].dev_profile]; - } - - if (acf_dde[i].dev_profile == AW_PROFILE_OFF && !soft_off_enable) { - AW_DEV_LOGE(dev, "profile off is not allowed"); - return -EINVAL; + cfg_data = acf_info->fw_data + acf_dde[i].data_offset; + ret = aw_parse_monitor_config(dev, cfg_data, acf_dde[i].data_size); + if (ret < 0) + return ret; + continue; } + prof_desc = &all_prof_info->prof_desc[acf_dde[i].dev_profile]; ret = aw_parse_data_by_sec_type_v_0_0_0_1(dev, acf_info, &acf_dde[i], prof_desc); if (ret < 0) { @@ -654,23 +744,14 @@ static int aw_get_prof_count_v_0_0_0_1(struct device *dev, { int i = 0; int prof_count = 0; - uint8_t soft_off_enable = acf_info->aw_dev->soft_off_enable; struct aw_prof_desc *prof_desc = all_prof_info->prof_desc; for (i = 0; i < AW_PROFILE_MAX; i++) { - if (i == AW_PROFILE_OFF) { - if (!soft_off_enable && prof_desc[i].prof_st == AW_PROFILE_OK) { - AW_DEV_LOGE(dev, "profile_off is not allowed"); - return -EINVAL; - } else if (soft_off_enable && prof_desc[i].prof_st == AW_PROFILE_WAIT) { - AW_DEV_LOGE(dev, "profile [Off] is necessary,but not found"); - return -EINVAL; - } else { - prof_count++; - } - } else { - if (prof_desc[i].prof_st == AW_PROFILE_OK) - prof_count++; + if (prof_desc[i].prof_st == AW_PROFILE_OK) { + prof_count++; + } else if (i == AW_PROFILE_OFF) { + prof_count++; + AW_DEV_LOGI(dev, "not found profile [Off], set default"); } } @@ -683,7 +764,6 @@ static int aw_set_prof_off_info_v_0_0_0_1(struct device *dev, struct aw_all_prof_info *all_prof_info, int index) { - uint8_t soft_off_enable = acf_info->aw_dev->soft_off_enable; struct aw_prof_desc *prof_desc = all_prof_info->prof_desc; struct aw_prof_info *prof_info = &acf_info->prof_info; @@ -693,20 +773,17 @@ static int aw_set_prof_off_info_v_0_0_0_1(struct device *dev, return -EINVAL; } - if (soft_off_enable && prof_desc[AW_PROFILE_OFF].prof_st == AW_PROFILE_OK) { + if (prof_desc[AW_PROFILE_OFF].prof_st == AW_PROFILE_OK) { prof_info->prof_desc[index] = prof_desc[AW_PROFILE_OFF]; AW_DEV_LOGI(dev, "product=[%s]----profile=[%s]", prof_info->prof_desc[index].dev_name, aw_get_prof_name(AW_PROFILE_OFF)); - } else if (!soft_off_enable) { + } else { memset(&prof_info->prof_desc[index].data_container, 0, sizeof(struct aw_data_container)); prof_info->prof_desc[index].prof_st = AW_PROFILE_WAIT; prof_info->prof_desc[index].prof_name = aw_get_prof_name(AW_PROFILE_OFF); AW_DEV_LOGI(dev, "set default power_off with no data to profile"); - } else { - AW_DEV_LOGE(dev, "not init default power_off config"); - return -EINVAL; } return 0; @@ -807,7 +884,7 @@ static int aw_parse_acf_v_0_0_0_1(struct device *dev, ret = aw_get_vaild_prof_v_0_0_0_1(dev, acf_info, &all_prof_info); if (ret < 0) { - aw_acf_profile_free(dev, acf_info); + aw87xxx_acf_profile_free(dev, acf_info); AW_DEV_LOGE(dev, "hdr_cersion[0x%x] parse failed", acf_info->acf_hdr.hdr_version); return ret; @@ -815,7 +892,7 @@ static int aw_parse_acf_v_0_0_0_1(struct device *dev, ret = aw_set_prof_name_list_v_0_0_0_1(dev, acf_info); if (ret < 0) { - aw_acf_profile_free(dev, acf_info); + aw87xxx_acf_profile_free(dev, acf_info); AW_DEV_LOGE(dev, "creat prof_id_and_name_list failed"); return ret; } @@ -835,7 +912,7 @@ static int aw_check_product_name_v_1_0_0_0(struct device *dev, int i = 0; for (i = 0; i < acf_info->product_cnt; i++) { - if (0 == strcmp(acf_info->product_tab[i], prof_hdr->dev_name)) { + if (strcmp(acf_info->product_tab[i], prof_hdr->dev_name) == 0) { AW_DEV_LOGI(dev, "bin_dev_name:%s", prof_hdr->dev_name); return 0; } @@ -844,14 +921,6 @@ static int aw_check_product_name_v_1_0_0_0(struct device *dev, return -ENXIO; } -static void aw_print_prof_off_name_can_support_v_1_0_0_0(struct device *dev) -{ - int i = 0; - - for (i = 0; i < AW_POWER_OFF_NAME_SUPPORT_COUNT; i++) - AW_DEV_LOGI(dev, "support prof_off_name have string:[%s]", g_power_off_name[i]); -} - static int aw_get_dde_type_info_v_1_0_0_0(struct device *dev, struct acf_bin_info *acf_info) { @@ -888,7 +957,6 @@ static int aw_get_dde_type_info_v_1_0_0_0(struct device *dev, static int aw_parse_get_dev_type_prof_count_v_1_0_0_0(struct device *dev, struct acf_bin_info *acf_info) { - uint8_t soft_off_enable = acf_info->aw_dev->soft_off_enable; struct aw_acf_hdr *acf_hdr = (struct aw_acf_hdr *)acf_info->fw_data; struct aw_acf_dde_v_1_0_0_0 *acf_dde = (struct aw_acf_dde_v_1_0_0_0 *)(acf_info->fw_data + acf_hdr->ddt_offset); @@ -899,7 +967,8 @@ static int aw_parse_get_dev_type_prof_count_v_1_0_0_0(struct device *dev, for (i = 0; i < acf_hdr->dde_num; ++i) { if (((acf_dde[i].data_type == AW_BIN_TYPE_REG) || - (acf_dde[i].data_type == AW_BIN_TYPE_HDR_REG)) && + (acf_dde[i].data_type == AW_BIN_TYPE_HDR_REG) || + (acf_dde[i].data_type == AW_BIN_TYPE_MUTLBIN)) && ((acf_info->aw_dev->i2c_bus == acf_dde[i].dev_bus) && (acf_info->aw_dev->i2c_addr == acf_dde[i].dev_addr)) && (acf_info->aw_dev->chipid == acf_dde[i].chip_id)) { @@ -909,17 +978,10 @@ static int aw_parse_get_dev_type_prof_count_v_1_0_0_0(struct device *dev, continue; ret = aw_check_prof_str_is_off(acf_dde[i].dev_profile_str); - if (ret == 0) { + if (ret == 0) found_off_prof_flag = AW_PROFILE_OK; - if (soft_off_enable) { - count++; - } else { - AW_DEV_LOGE(dev, "profile_off is not allowed"); - return -EINVAL; - } - } else { - count++; - } + + count++; } } @@ -928,13 +990,7 @@ static int aw_parse_get_dev_type_prof_count_v_1_0_0_0(struct device *dev, return -EINVAL; } - if (!found_off_prof_flag && soft_off_enable) { - AW_DEV_LOGE(dev, "profile power off is necessary,but not found"); - aw_print_prof_off_name_can_support_v_1_0_0_0(dev); - return -EINVAL; - } - - if (!found_off_prof_flag && !soft_off_enable) { + if (!found_off_prof_flag) { count++; AW_DEV_LOGD(dev, "set no config power off profile in count"); } @@ -947,7 +1003,6 @@ static int aw_parse_get_dev_type_prof_count_v_1_0_0_0(struct device *dev, static int aw_parse_get_default_type_prof_count_v_1_0_0_0(struct device *dev, struct acf_bin_info *acf_info) { - uint8_t soft_off_enable = acf_info->aw_dev->soft_off_enable; struct aw_acf_hdr *acf_hdr = (struct aw_acf_hdr *)acf_info->fw_data; struct aw_acf_dde_v_1_0_0_0 *acf_dde = (struct aw_acf_dde_v_1_0_0_0 *)(acf_info->fw_data + acf_hdr->ddt_offset); @@ -958,7 +1013,8 @@ static int aw_parse_get_default_type_prof_count_v_1_0_0_0(struct device *dev, for (i = 0; i < acf_hdr->dde_num; ++i) { if (((acf_dde[i].data_type == AW_BIN_TYPE_REG) || - (acf_dde[i].data_type == AW_BIN_TYPE_HDR_REG)) && + (acf_dde[i].data_type == AW_BIN_TYPE_HDR_REG) || + (acf_dde[i].data_type == AW_BIN_TYPE_MUTLBIN)) && (acf_info->dev_index == acf_dde[i].dev_index) && (acf_info->aw_dev->chipid == acf_dde[i].chip_id)) { @@ -967,17 +1023,10 @@ static int aw_parse_get_default_type_prof_count_v_1_0_0_0(struct device *dev, continue; ret = aw_check_prof_str_is_off(acf_dde[i].dev_profile_str); - if (ret == 0) { + if (ret == 0) found_off_prof_flag = AW_PROFILE_OK; - if (soft_off_enable) { - count++; - } else { - AW_DEV_LOGE(dev, "profile_off is not allowed"); - return -EINVAL; - } - } else { - count++; - } + + count++; } } @@ -986,13 +1035,7 @@ static int aw_parse_get_default_type_prof_count_v_1_0_0_0(struct device *dev, return -EINVAL; } - if (!found_off_prof_flag && soft_off_enable) { - AW_DEV_LOGE(dev, "profile power off is necessary,but not found"); - aw_print_prof_off_name_can_support_v_1_0_0_0(dev); - return -EINVAL; - } - - if (!found_off_prof_flag && !soft_off_enable) { + if (!found_off_prof_flag) { count++; AW_DEV_LOGD(dev, "set no config power off profile in count"); } @@ -1044,7 +1087,8 @@ static int aw_parse_dev_type_prof_name_v_1_0_0_0(struct device *dev, for (i = 0; i < acf_hdr->dde_num; ++i) { if (((acf_dde[i].data_type == AW_BIN_TYPE_REG) || - (acf_dde[i].data_type == AW_BIN_TYPE_HDR_REG)) && + (acf_dde[i].data_type == AW_BIN_TYPE_HDR_REG) || + (acf_dde[i].data_type == AW_BIN_TYPE_MUTLBIN)) && (acf_info->aw_dev->i2c_bus == acf_dde[i].dev_bus) && (acf_info->aw_dev->i2c_addr == acf_dde[i].dev_addr) && (acf_info->aw_dev->chipid == acf_dde[i].chip_id)) { @@ -1081,7 +1125,8 @@ static int aw_parse_default_type_prof_name_v_1_0_0_0(struct device *dev, for (i = 0; i < acf_hdr->dde_num; ++i) { if (((acf_dde[i].data_type == AW_BIN_TYPE_REG) || - (acf_dde[i].data_type == AW_BIN_TYPE_HDR_REG)) && + (acf_dde[i].data_type == AW_BIN_TYPE_HDR_REG) || + (acf_dde[i].data_type == AW_BIN_TYPE_MUTLBIN)) && (acf_info->dev_index == acf_dde[i].dev_index) && (acf_info->aw_dev->chipid == acf_dde[i].chip_id)) { if (list_index > prof_info->count) { @@ -1152,6 +1197,11 @@ static int aw_search_prof_index_from_list_v_1_0_0_0(struct device *dev, int count = acf_info->prof_info.count; char (*prof_name_list)[AW_PROFILE_STR_MAX] = acf_info->prof_info.prof_name_list; + if (prof_name_list == NULL) { + AW_DEV_LOGE(dev, "the declared prof_name_list pointer is empty"); + return -ENOMEM; + } + for (i = 0; i < count; i++) { if (!strncmp(prof_name_list[i], prof_hdr->dev_profile_str, AW_PROFILE_STR_MAX)) { *prof_desc = &(acf_info->prof_info.prof_desc[i]); @@ -1198,6 +1248,16 @@ static int aw_parse_data_by_sec_type_v_1_0_0_0(struct device *dev, ret = aw_parse_reg_with_hdr(dev, cfg_data, prof_hdr->data_size, prof_desc); break; + case AW_BIN_TYPE_MUTLBIN: + snprintf(prof_desc->dev_name, sizeof(prof_hdr->dev_name), + "%s", prof_hdr->dev_name); + AW_DEV_LOGI(dev, "parse multi type data enter,product=[%s],prof_id=[%d],prof_name=[%s]", + prof_hdr->dev_name, prof_hdr->dev_profile, + prof_hdr->dev_profile_str); + prof_desc->prof_name = prof_hdr->dev_profile_str; + ret = aw_dev_prof_parse_multi_bin(dev, cfg_data, + prof_hdr->data_size, + prof_desc); } return ret; @@ -1313,13 +1373,12 @@ static int aw_parse_by_hdr_v_1_0_0_0(struct device *dev, static int aw_set_prof_off_info_v_1_0_0_0(struct device *dev, struct acf_bin_info *acf_info) { - uint8_t soft_off_enable = acf_info->aw_dev->soft_off_enable; struct aw_prof_info *prof_info = &acf_info->prof_info; int i = 0; int ret = 0; for (i = 0; i < prof_info->count; ++i) { - if (!(prof_info->prof_desc[i].prof_st) && !soft_off_enable) { + if (!(prof_info->prof_desc[i].prof_st)) { snprintf(prof_info->prof_name_list[i], AW_PROFILE_STR_MAX, "%s", g_power_off_name[0]); prof_info->prof_desc[i].prof_name = prof_info->prof_name_list[i]; @@ -1391,7 +1450,7 @@ static int aw_parse_acf_v_1_0_0_0(struct device *dev, *acf parse API * *************************************************************************/ -void aw_acf_profile_free(struct device *dev, struct acf_bin_info *acf_info) +void aw87xxx_acf_profile_free(struct device *dev, struct acf_bin_info *acf_info) { struct aw_prof_info *prof_info = &acf_info->prof_info; @@ -1415,7 +1474,7 @@ void aw_acf_profile_free(struct device *dev, struct acf_bin_info *acf_info) } } -int aw_acf_parse(struct device *dev, struct acf_bin_info *acf_info) +int aw87xxx_acf_parse(struct device *dev, struct acf_bin_info *acf_info) { int ret = 0; @@ -1445,7 +1504,7 @@ int aw_acf_parse(struct device *dev, struct acf_bin_info *acf_info) return ret; } -struct aw_prof_desc *aw_acf_get_prof_desc_form_name(struct device *dev, +struct aw_prof_desc *aw87xxx_acf_get_prof_desc_form_name(struct device *dev, struct acf_bin_info *acf_info, char *profile_name) { int i = 0; @@ -1476,7 +1535,7 @@ struct aw_prof_desc *aw_acf_get_prof_desc_form_name(struct device *dev, return prof_desc; } -int aw_acf_get_prof_index_form_name(struct device *dev, +int aw87xxx_acf_get_prof_index_form_name(struct device *dev, struct acf_bin_info *acf_info, char *profile_name) { int i = 0; @@ -1498,7 +1557,7 @@ int aw_acf_get_prof_index_form_name(struct device *dev, return -EINVAL; } -char *aw_acf_get_prof_name_form_index(struct device *dev, +char *aw87xxx_acf_get_prof_name_form_index(struct device *dev, struct acf_bin_info *acf_info, int index) { struct aw_prof_info *prof_info = &acf_info->prof_info; @@ -1517,7 +1576,7 @@ char *aw_acf_get_prof_name_form_index(struct device *dev, } -int aw_acf_get_profile_count(struct device *dev, +int aw87xxx_acf_get_profile_count(struct device *dev, struct acf_bin_info *acf_info) { struct aw_prof_info *prof_info = &acf_info->prof_info; @@ -1527,14 +1586,14 @@ int aw_acf_get_profile_count(struct device *dev, return -EINVAL; } - if (prof_info->count > 0) { + if (prof_info->count > 0) return prof_info->count; - } + return -EINVAL; } -char *aw_acf_get_prof_off_name(struct device *dev, +char *aw87xxx_acf_get_prof_off_name(struct device *dev, struct acf_bin_info *acf_info) { int i = 0; @@ -1555,7 +1614,7 @@ char *aw_acf_get_prof_off_name(struct device *dev, return NULL; } -void aw_acf_init(struct aw_device *aw_dev, struct acf_bin_info *acf_info, int index) +void aw87xxx_acf_init(struct aw_device *aw_dev, struct acf_bin_info *acf_info, int index) { acf_info->load_count = 0; diff --git a/sound/soc/codecs/aw87xxx/aw_acf_bin.h b/sound/soc/codecs/aw87xxx/aw_acf_bin.h index 0e4891830b15..a1fcfce1b4ff 100644 --- a/sound/soc/codecs/aw87xxx/aw_acf_bin.h +++ b/sound/soc/codecs/aw87xxx/aw_acf_bin.h @@ -1,7 +1,20 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ +/* SPDX-License-Identifier: GPL-2.0 + * + * aw87xxx_acf_bin.h aw87xxx pa module + * + * Copyright (c) 2021 AWINIC Technology CO., LTD + * + * Author: Barry + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ -#ifndef __AW_ACF_BIN_H__ -#define __AW_ACF_BIN_H__ +#ifndef __AW87XXX_ACF_BIN_H__ +#define __AW87XXX_ACF_BIN_H__ #include "aw_device.h" @@ -17,7 +30,7 @@ #define AW_REG_DATA_BYTE (1) #define AW_ACF_FILE_ID (0xa15f908) -#define AW_PROFILE_STR_MAX (32) +#define AW_PROFILE_STR_MAX (32) #define AW_POWER_OFF_NAME_SUPPORT_COUNT (5) enum aw_cfg_hdr_version { @@ -173,23 +186,21 @@ struct acf_bin_info { struct aw_prof_info prof_info; }; - -void aw_acf_profile_free(struct device *dev, +char *aw87xxx_ctos_get_prof_name(int profile_id); +void aw87xxx_acf_profile_free(struct device *dev, struct acf_bin_info *acf_info); -int aw_acf_parse(struct device *dev, struct acf_bin_info *acf_info); -struct aw_prof_desc *aw_acf_get_prof_desc_form_name(struct device *dev, +int aw87xxx_acf_parse(struct device *dev, struct acf_bin_info *acf_info); +struct aw_prof_desc *aw87xxx_acf_get_prof_desc_form_name(struct device *dev, struct acf_bin_info *acf_info, char *profile_name); -int aw_acf_get_prof_index_form_name(struct device *dev, +int aw87xxx_acf_get_prof_index_form_name(struct device *dev, struct acf_bin_info *acf_info, char *profile_name); -char *aw_acf_get_prof_name_form_index(struct device *dev, +char *aw87xxx_acf_get_prof_name_form_index(struct device *dev, struct acf_bin_info *acf_info, int index); -int aw_acf_get_profile_count(struct device *dev, +int aw87xxx_acf_get_profile_count(struct device *dev, struct acf_bin_info *acf_info); -int aw_acf_check_profile_is_off(struct device *dev, - struct acf_bin_info *acf_info, char *profile_name); -char *aw_acf_get_prof_off_name(struct device *dev, +char *aw87xxx_acf_get_prof_off_name(struct device *dev, struct acf_bin_info *acf_info); -void aw_acf_init(struct aw_device *aw_dev, struct acf_bin_info *acf_info, int index); +void aw87xxx_acf_init(struct aw_device *aw_dev, struct acf_bin_info *acf_info, int index); #endif diff --git a/sound/soc/codecs/aw87xxx/aw_bin_parse.c b/sound/soc/codecs/aw87xxx/aw_bin_parse.c index 84e1da024dab..bf66ab22ceaa 100644 --- a/sound/soc/codecs/aw87xxx/aw_bin_parse.c +++ b/sound/soc/codecs/aw87xxx/aw_bin_parse.c @@ -1,13 +1,15 @@ -/* -* aw_bin_parse.c -* -* Copyright (c) 2020 AWINIC Technology CO., LTD -* -* This program is free software; you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by the -* Free Software Foundation; either version 2 of the License, or (at your -* option) any later version. -*/ +// SPDX-License-Identifier: GPL-2.0 +/* aw87xxx_bin_parse.c + * + * Copyright (c) 2020 AWINIC Technology CO., LTD + * + * Author: Barry + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ #include #include @@ -22,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -37,58 +39,30 @@ #define DEBUG_LOG_LEVEL #ifdef DEBUG_LOG_LEVEL -#define DBG(fmt, arg...) do {\ -printk("AWINIC_BIN %s,line= %d,"fmt, __func__, __LINE__, ##arg);\ -} while (0) -#define DBG_ERR(fmt, arg...) do {\ -printk("AWINIC_BIN_ERR %s,line= %d,"fmt, __func__, __LINE__, ##arg);\ -} while (0) +#define DBG(fmt, arg...) \ + pr_debug("AWINIC_BIN %s,line= %d,"fmt, __func__, __LINE__, ##arg) + +#define DBG_ERR(fmt, arg...) \ + pr_err("AWINIC_BIN_ERR %s,line= %d,"fmt, __func__, __LINE__, ##arg) + #else #define DBG(fmt, arg...) do {} while (0) #define DBG_ERR(fmt, arg...) do {} while (0) #endif -#define printing_data_code - -typedef unsigned short int aw_uint16; -typedef unsigned long int aw_uint32; - -#define BigLittleSwap16(A) ((((aw_uint16)(A) & 0xff00) >> 8) | \ - (((aw_uint16)(A) & 0x00ff) << 8)) - -#define BigLittleSwap32(A) ((((aw_uint32)(A) & 0xff000000) >> 24) | \ - (((aw_uint32)(A) & 0x00ff0000) >> 8) | \ - (((aw_uint32)(A) & 0x0000ff00) << 8) | \ - (((aw_uint32)(A) & 0x000000ff) << 24)) - -/** -* -* Interface function -* -* return value: -* value = 0 :success; -* value = -1 :check bin header version -* value = -2 :check bin data type -* value = -3 :check sum or check bin data len error -* value = -4 :check data version -* value = -5 :check register num -* value = -6 :check dsp reg num -* value = -7 :check soc app num -* value = -8 :bin is NULL point -* -**/ +static int aw_parse_bin_header_1_0_0(struct aw_bin *bin); /******************************************************** -* -* check sum data -* -********************************************************/ -int aw_check_sum(struct aw_bin *bin, int bin_num) + * + * check sum data + * + ********************************************************/ +static int aw_check_sum(struct aw_bin *bin, int bin_num) { unsigned int i = 0; unsigned int sum_data = 0; unsigned int check_sum = 0; - char *p_check_sum = NULL; + unsigned char *p_check_sum = NULL; DBG("enter\n"); @@ -112,32 +86,33 @@ int aw_check_sum(struct aw_bin *bin, int bin_num) p_check_sum = NULL; DBG_ERR("aw_bin_parse check sum or check bin data len error\n"); DBG_ERR("aw_bin_parse bin_num=%d, check_sum = 0x%x, sum_data = 0x%x\n", bin_num, check_sum, sum_data); - return -3; + return -EINVAL; } p_check_sum = NULL; return 0; } -int aw_check_data_version(struct aw_bin *bin, int bin_num) +static int aw_check_data_version(struct aw_bin *bin, int bin_num) { int i = 0; + DBG("enter\n"); for (i = DATA_VERSION_V1; i < DATA_VERSION_MAX; i++) { - if (bin->header_info[bin_num].bin_data_ver == i) { + if (bin->header_info[bin_num].bin_data_ver == i) return 0; - } + } DBG_ERR("aw_bin_parse Unrecognized this bin data version\n"); - return -4; + return -EINVAL; } -int aw_check_register_num_v1(struct aw_bin *bin, int bin_num) +static int aw_check_register_num_v1(struct aw_bin *bin, int bin_num) { unsigned int check_register_num = 0; unsigned int parse_register_num = 0; - char *p_check_sum = NULL; + unsigned char *p_check_sum = NULL; DBG("enter\n"); @@ -157,7 +132,7 @@ int aw_check_register_num_v1(struct aw_bin *bin, int bin_num) p_check_sum = NULL; DBG_ERR("aw_bin_parse register num is error\n"); DBG_ERR("aw_bin_parse bin_num=%d, parse_register_num = 0x%x, check_register_num = 0x%x\n", bin_num, parse_register_num, check_register_num); - return -5; + return -EINVAL; } bin->header_info[bin_num].reg_num = parse_register_num; bin->header_info[bin_num].valid_data_len = @@ -168,11 +143,11 @@ int aw_check_register_num_v1(struct aw_bin *bin, int bin_num) return 0; } -int aw_check_dsp_reg_num_v1(struct aw_bin *bin, int bin_num) +static int aw_check_dsp_reg_num_v1(struct aw_bin *bin, int bin_num) { unsigned int check_dsp_reg_num = 0; unsigned int parse_dsp_reg_num = 0; - char *p_check_sum = NULL; + unsigned char *p_check_sum = NULL; DBG("enter\n"); @@ -195,7 +170,7 @@ int aw_check_dsp_reg_num_v1(struct aw_bin *bin, int bin_num) p_check_sum = NULL; DBG_ERR("aw_bin_parse dsp reg num is error\n"); DBG_ERR("aw_bin_parse bin_num=%d, parse_dsp_reg_num = 0x%x, check_dsp_reg_num = 0x%x\n", bin_num, parse_dsp_reg_num, check_dsp_reg_num); - return -6; + return -EINVAL; } bin->header_info[bin_num].download_addr = GET_32_DATA(*(p_check_sum + 3), *(p_check_sum + 2), @@ -209,11 +184,11 @@ int aw_check_dsp_reg_num_v1(struct aw_bin *bin, int bin_num) return 0; } -int aw_check_soc_app_num_v1(struct aw_bin *bin, int bin_num) +static int aw_check_soc_app_num_v1(struct aw_bin *bin, int bin_num) { unsigned int check_soc_app_num = 0; unsigned int parse_soc_app_num = 0; - char *p_check_sum = NULL; + unsigned char *p_check_sum = NULL; DBG("enter\n"); @@ -235,7 +210,7 @@ int aw_check_soc_app_num_v1(struct aw_bin *bin, int bin_num) p_check_sum = NULL; DBG_ERR("aw_bin_parse soc app num is error\n"); DBG_ERR("aw_bin_parse bin_num=%d, parse_soc_app_num = 0x%x, check_soc_app_num = 0x%x\n", bin_num, parse_soc_app_num, check_soc_app_num); - return -7; + return -EINVAL; } bin->header_info[bin_num].reg_num = parse_soc_app_num; bin->header_info[bin_num].download_addr = @@ -250,14 +225,15 @@ int aw_check_soc_app_num_v1(struct aw_bin *bin, int bin_num) } /************************ -*** -***bin header 1_0_0 -*** -************************/ -void aw_get_single_bin_header_1_0_0(struct aw_bin *bin) + *** + ***bin header 1_0_0 + *** + ************************/ +static void aw_get_single_bin_header_1_0_0(struct aw_bin *bin) { - int i; - DBG("enter %s\n", __func__); + int i = 0; + + DBG("enter\n"); bin->header_info[bin->all_bin_parse_num].header_len = 60; bin->header_info[bin->all_bin_parse_num].check_sum = GET_32_DATA(*(bin->p_addr + 3), *(bin->p_addr + 2), @@ -298,12 +274,13 @@ void aw_get_single_bin_header_1_0_0(struct aw_bin *bin) bin->all_bin_parse_num += 1; } -int aw_parse_each_of_multi_bins_1_0_0(unsigned int bin_num, int bin_serial_num, +static int aw_parse_each_of_multi_bins_1_0_0(unsigned int bin_num, int bin_serial_num, struct aw_bin *bin) { int ret = 0; unsigned int bin_start_addr = 0; unsigned int valid_data_len = 0; + DBG("aw_bin_parse enter multi bin branch -- %s\n", __func__); if (!bin_serial_num) { bin_start_addr = GET_32_DATA(*(bin->p_addr + 67), @@ -330,46 +307,48 @@ int aw_parse_each_of_multi_bins_1_0_0(unsigned int bin_num, int bin_serial_num, } /* Get the number of bins in multi bins, and set a for loop, loop processing each bin data */ -int aw_get_multi_bin_header_1_0_0(struct aw_bin *bin) +static int aw_get_multi_bin_header_1_0_0(struct aw_bin *bin) { int i = 0; int ret = 0; unsigned int bin_num = 0; + DBG("aw_bin_parse enter multi bin branch -- %s\n", __func__); bin_num = GET_32_DATA(*(bin->p_addr + 63), *(bin->p_addr + 62), *(bin->p_addr + 61), *(bin->p_addr + 60)); - if (bin->multi_bin_parse_num == 1) { + if (bin->multi_bin_parse_num == 1) bin->header_info[bin->all_bin_parse_num].valid_data_addr = 60; - } + aw_get_single_bin_header_1_0_0(bin); for (i = 0; i < bin_num; i++) { DBG("aw_bin_parse enter multi bin for is %d\n", i); ret = aw_parse_each_of_multi_bins_1_0_0(bin_num, i, bin); - if (ret < 0) { + if (ret < 0) return ret; - } + } return 0; } /******************************************************** -* -* If the bin framework header version is 1.0.0, + * + * If the bin framework header version is 1.0.0, determine the data type of bin, and then perform different processing according to the data type If it is a single bin data type, write the data directly into the structure array If it is a multi-bin data type, first obtain the number of bins, and then recursively call the bin frame header processing function according to the bin number to process the frame header information of each bin separately -* -********************************************************/ -int aw_parse_bin_header_1_0_0(struct aw_bin *bin) + * + ********************************************************/ +static int aw_parse_bin_header_1_0_0(struct aw_bin *bin) { int ret = 0; unsigned int bin_data_type; - DBG("enter %s\n", __func__); + + DBG("enter\n"); bin_data_type = GET_32_DATA(*(bin->p_addr + 11), *(bin->p_addr + 10), *(bin->p_addr + 9), *(bin->p_addr + 8)); @@ -379,17 +358,16 @@ int aw_parse_bin_header_1_0_0(struct aw_bin *bin) case DATA_TYPE_DSP_REG: case DATA_TYPE_SOC_APP: /* Divided into two processing methods, - one is single bin processing, - and the other is single bin processing in multi bin */ + * one is single bin processing, + * and the other is single bin processing in multi bin + */ DBG("aw_bin_parse enter single bin branch\n"); bin->single_bin_parse_num += 1; DBG("%s bin->single_bin_parse_num is %d\n", __func__, bin->single_bin_parse_num); - if (!bin->multi_bin_parse_num) { - bin->header_info[bin-> - all_bin_parse_num].valid_data_addr = - 60; - } + if (!bin->multi_bin_parse_num) + bin->header_info[bin->all_bin_parse_num].valid_data_addr = 60; + aw_get_single_bin_header_1_0_0(bin); break; case DATA_TYPE_MULTI_BINS: @@ -399,13 +377,14 @@ int aw_parse_bin_header_1_0_0(struct aw_bin *bin) DBG("%s bin->multi_bin_parse_num is %d\n", __func__, bin->multi_bin_parse_num); ret = aw_get_multi_bin_header_1_0_0(bin); - if (ret < 0) { + if (ret < 0) return ret; - } + break; default: - DBG_ERR("aw_bin_parse Unrecognized this bin data type\n"); - return -2; + DBG("aw_bin_parse Unrecognized this bin data type 0x%x\n", + bin_data_type); + break; } return 0; } @@ -423,18 +402,19 @@ static int aw_check_bin_header_version(struct aw_bin *bin) DBG("aw_bin_parse header_version 0x%x\n", header_version); /* Write data to the corresponding structure array - according to different formats of the bin frame header version */ + * according to different formats of the bin frame header version + */ switch (header_version) { case HEADER_VERSION_1_0_0: ret = aw_parse_bin_header_1_0_0(bin); return ret; default: - DBG_ERR("aw_bin_parse Unrecognized this bin header version \n"); - return -1; + DBG_ERR("aw_bin_parse Unrecognized this bin header version\n"); + return -EINVAL; } } -int aw_parsing_bin_file(struct aw_bin *bin) +int aw87xxx_parsing_bin_file(struct aw_bin *bin) { int i = 0; int ret = 0; @@ -442,7 +422,7 @@ int aw_parsing_bin_file(struct aw_bin *bin) DBG("aw_bin_parse code version:%s\n", AWINIC_CODE_VERSION); if (!bin) { DBG_ERR("aw_bin_parse bin is NULL\n"); - return -8; + return -EINVAL; } bin->p_addr = bin->info.data; bin->all_bin_parse_num = 0; diff --git a/sound/soc/codecs/aw87xxx/aw_bin_parse.h b/sound/soc/codecs/aw87xxx/aw_bin_parse.h index 632a1f47a9ed..17b032c0becd 100644 --- a/sound/soc/codecs/aw87xxx/aw_bin_parse.h +++ b/sound/soc/codecs/aw87xxx/aw_bin_parse.h @@ -1,7 +1,18 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ +/* SPDX-License-Identifier: GPL-2.0 + * aw87xxx_bin_parse.h + * + * Copyright (c) 2020 AWINIC Technology CO., LTD + * + * Author: Barry + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ -#ifndef __AW_BIN_PARSE_H__ -#define __AW_BIN_PARSE_H__ +#ifndef __AW87XXX_BIN_PARSE_H__ +#define __AW87XXX_BIN_PARSE_H__ #define NULL ((void *)0) #define GET_32_DATA(w, x, y, z) ((unsigned int)(((w) << 24) | ((x) << 16) | ((y) << 8) | (z))) @@ -53,17 +64,17 @@ struct bin_header_info { }; /************************************************************ -* -* function define -* -************************************************************/ + * + * function define + * + ************************************************************/ struct bin_container { unsigned int len; /* The size of the bin file obtained from the firmware */ unsigned char data[]; /* Store the bin file obtained from the firmware */ }; struct aw_bin { - char *p_addr; /* Offset pointer (backward offset pointer to obtain frame header information and important information) */ + unsigned char *p_addr; /* Offset pointer (backward offset pointer to obtain frame header information and important information) */ unsigned int all_bin_parse_num; /* The number of all bin files */ unsigned int multi_bin_parse_num; /* The number of single bin files */ unsigned int single_bin_parse_num; /* The number of multiple bin files */ @@ -71,6 +82,5 @@ struct aw_bin { struct bin_container info; /* Obtained bin file data that needs to be parsed */ }; -extern int aw_parsing_bin_file(struct aw_bin *bin); -int aw_parse_bin_header_1_0_0(struct aw_bin *bin); +extern int aw87xxx_parsing_bin_file(struct aw_bin *bin); #endif diff --git a/sound/soc/codecs/aw87xxx/aw_device.c b/sound/soc/codecs/aw87xxx/aw_device.c index 579c7e840b79..1009c1092210 100644 --- a/sound/soc/codecs/aw87xxx/aw_device.c +++ b/sound/soc/codecs/aw87xxx/aw_device.c @@ -1,5 +1,5 @@ -/* - * aw_device.c aw87xxx pa module +// SPDX-License-Identifier: GPL-2.0 +/* aw87xxx_device.c aw87xxx pa module * * Copyright (c) 2021 AWINIC Technology CO., LTD * @@ -25,6 +25,7 @@ #include #include "aw87xxx.h" #include "aw_device.h" +#include "aw_dsp.h" #include "aw_log.h" #include "aw87xxx_pid_9b_reg.h" #include "aw87xxx_pid_18_reg.h" @@ -33,54 +34,123 @@ #include "aw87xxx_pid_59_5x9_reg.h" #include "aw87xxx_pid_5a_reg.h" #include "aw87xxx_pid_76_reg.h" +#include "aw87xxx_pid_60_reg.h" +#include "aw87xxx_pid_c1_reg.h" +#include "aw87xxx_pid_c2_reg.h" + +#ifdef AW_ALGO_AUTH_DSP +static DEFINE_MUTEX(g_algo_auth_dsp_lock); +int g_algo_auth_st; +#endif /************************************************************************* * aw87xxx variable ************************************************************************/ const char *g_aw_pid_9b_product[] = { "aw87319", + "AW87319", +}; +const char *g_aw_pid_18_product[] = { + "aw87358", + "AW87358", }; const char *g_aw_pid_39_product[] = { "aw87329", + "AW87329", "aw87339", + "AW87339", "aw87349", + "AW87349", }; const char *g_aw_pid_59_3x9_product[] = { "aw87359", + "AW87359", "aw87389", + "AW87389", }; const char *g_aw_pid_59_5x9_product[] = { "aw87509", + "AW87509", "aw87519", + "AW87519", "aw87529", + "AW87529", "aw87539", + "AW87539", }; const char *g_aw_pid_5a_product[] = { "aw87549", + "AW87549", "aw87559", + "AW87559", "aw87569", + "AW87569", "aw87579", + "AW87579", "aw81509", + "AW81509", + "aw87579G", + "AW87579G", }; const char *g_aw_pid_76_product[] = { "aw87390", + "AW87390", "aw87320", + "AW87320", "aw87401", + "AW87401", + "aw87360", + "AW87360", + "aw87390G", + "AW87390G", }; -static int aw_dev_get_chipid(struct aw_device *aw_dev); +const char *g_aw_pid_60_product[] = { + "aw87560", + "AW87560", + "aw87561", + "AW87561", + "aw87562", + "AW87562", + "aw87501", + "AW87501", + "aw87550", + "AW87550", +}; + +const char *g_aw_pid_c1_product[] = { + "aw87391", + "AW87391", + "aw87392", + "AW87392", +}; + +const char *g_aw_pid_c2_product[] = { + "aw87565", + "AW87565", + "aw87566", + "AW87566", + "aw81564", + "AW81564", + "aw87567", + "AW87567", + "aw87568", + "AW87568", +}; + +static int aw87xxx_dev_get_chipid(struct aw_device *aw_dev); /*************************************************************************** * * reading and writing of I2C bus * ***************************************************************************/ -int aw_dev_i2c_write_byte(struct aw_device *aw_dev, +int aw87xxx_dev_i2c_write_byte(struct aw_device *aw_dev, uint8_t reg_addr, uint8_t reg_data) { int ret = -1; @@ -101,7 +171,7 @@ int aw_dev_i2c_write_byte(struct aw_device *aw_dev, return ret; } -int aw_dev_i2c_read_byte(struct aw_device *aw_dev, +int aw87xxx_dev_i2c_read_byte(struct aw_device *aw_dev, uint8_t reg_addr, uint8_t *reg_data) { int ret = -1; @@ -123,7 +193,7 @@ int aw_dev_i2c_read_byte(struct aw_device *aw_dev, return ret; } -int aw_dev_i2c_read_msg(struct aw_device *aw_dev, +int aw87xxx_dev_i2c_read_msg(struct aw_device *aw_dev, uint8_t reg_addr, uint8_t *data_buf, uint32_t data_len) { int ret = -1; @@ -155,20 +225,20 @@ int aw_dev_i2c_read_msg(struct aw_device *aw_dev, return 0; } -int aw_dev_i2c_write_bits(struct aw_device *aw_dev, +int aw87xxx_dev_i2c_write_bits(struct aw_device *aw_dev, uint8_t reg_addr, uint8_t mask, uint8_t reg_data) { int ret = -1; unsigned char reg_val = 0; - ret = aw_dev_i2c_read_byte(aw_dev, reg_addr, ®_val); + ret = aw87xxx_dev_i2c_read_byte(aw_dev, reg_addr, ®_val); if (ret < 0) { AW_DEV_LOGE(aw_dev->dev, "i2c read error, ret=%d", ret); return ret; } reg_val &= mask; - reg_val |= reg_data; - ret = aw_dev_i2c_write_byte(aw_dev, reg_addr, reg_val); + reg_val |= (reg_data & (~mask)); + ret = aw87xxx_dev_i2c_write_byte(aw_dev, reg_addr, reg_val); if (ret < 0) { AW_DEV_LOGE(aw_dev->dev, "i2c write error, ret=%d", ret); return ret; @@ -182,7 +252,7 @@ int aw_dev_i2c_write_bits(struct aw_device *aw_dev, * aw87xxx device update profile data to registers * ************************************************************************/ -static int aw_dev_reg_update(struct aw_device *aw_dev, +static int aw87xxx_dev_reg_update(struct aw_device *aw_dev, struct aw_data_container *profile_data) { int i = 0; @@ -200,7 +270,15 @@ static int aw_dev_reg_update(struct aw_device *aw_dev, //AW_DEV_LOGI(aw_dev->dev, "reg=0x%02x, val = 0x%02x", // profile_data->data[i], profile_data->data[i + 1]); - ret = aw_dev_i2c_write_byte(aw_dev, profile_data->data[i], + /*delay ms*/ + if (profile_data->data[i] == AW87XXX_DELAY_REG_ADDR) { + AW_DEV_LOGI(aw_dev->dev, "delay %d ms", profile_data->data[i + 1]); + usleep_range(profile_data->data[i + 1] * AW87XXX_REG_DELAY_TIME, + profile_data->data[i + 1] * AW87XXX_REG_DELAY_TIME + 10); + continue; + } + + ret = aw87xxx_dev_i2c_write_byte(aw_dev, profile_data->data[i], profile_data->data[i + 1]); if (ret < 0) return ret; @@ -209,7 +287,7 @@ static int aw_dev_reg_update(struct aw_device *aw_dev, return 0; } -static void aw_dev_reg_mute_bits_set(struct aw_device *aw_dev, +static void aw87xxx_dev_reg_mute_bits_set(struct aw_device *aw_dev, uint8_t *reg_val, bool enable) { if (enable) { @@ -221,12 +299,58 @@ static void aw_dev_reg_mute_bits_set(struct aw_device *aw_dev, } } +static int aw87xxx_dev_reg_update_mute(struct aw_device *aw_dev, + struct aw_data_container *profile_data) +{ + int i = 0; + int ret = -1; + uint8_t reg_val = 0; + + if (profile_data == NULL) + return -EINVAL; + + if (aw_dev->hwen_status == AW_DEV_HWEN_OFF) { + AW_DEV_LOGE(aw_dev->dev, "hwen is off,can not update reg"); + return -EINVAL; + } + + if (aw_dev->mute_desc.mask == AW_DEV_REG_INVALID_MASK) { + AW_DEV_LOGE(aw_dev->dev, "mute ctrl mask invalid"); + return -EINVAL; + } + + for (i = 0; i < profile_data->len; i = i + 2) { + AW_DEV_LOGI(aw_dev->dev, "reg=0x%02x, val = 0x%02x", + profile_data->data[i], profile_data->data[i + 1]); + /*delay ms*/ + if (profile_data->data[i] == AW87XXX_DELAY_REG_ADDR) { + AW_DEV_LOGI(aw_dev->dev, "delay %d ms", profile_data->data[i + 1]); + usleep_range(profile_data->data[i + 1] * AW87XXX_REG_DELAY_TIME, + profile_data->data[i + 1] * AW87XXX_REG_DELAY_TIME + 10); + continue; + } + + reg_val = profile_data->data[i + 1]; + if (profile_data->data[i] == aw_dev->mute_desc.addr) { + aw87xxx_dev_reg_mute_bits_set(aw_dev, ®_val, true); + AW_DEV_LOGD(aw_dev->dev, "change mute_mask, val = 0x%02x", + reg_val); + } + + ret = aw87xxx_dev_i2c_write_byte(aw_dev, profile_data->data[i], reg_val); + if (ret < 0) + return ret; + } + + return 0; +} + /************************************************************************ * * aw87xxx device hadware and soft contols * ************************************************************************/ -static bool aw_dev_gpio_is_valid(struct aw_device *aw_dev) +static bool aw87xxx_dev_gpio_is_valid(struct aw_device *aw_dev) { if (gpio_is_valid(aw_dev->rst_gpio)) return true; @@ -234,14 +358,14 @@ static bool aw_dev_gpio_is_valid(struct aw_device *aw_dev) return false; } -void aw_dev_hw_pwr_ctrl(struct aw_device *aw_dev, bool enable) +void aw87xxx_dev_hw_pwr_ctrl(struct aw_device *aw_dev, bool enable) { if (aw_dev->hwen_status == AW_DEV_HWEN_INVALID) { AW_DEV_LOGD(aw_dev->dev, "product not have reset-pin,hardware pwd control invalid"); return; } if (enable) { - if (aw_dev_gpio_is_valid(aw_dev)) { + if (aw87xxx_dev_gpio_is_valid(aw_dev)) { gpio_set_value_cansleep(aw_dev->rst_gpio, AW_GPIO_LOW_LEVEL); mdelay(2); gpio_set_value_cansleep(aw_dev->rst_gpio, AW_GPIO_HIGHT_LEVEL); @@ -252,7 +376,7 @@ void aw_dev_hw_pwr_ctrl(struct aw_device *aw_dev, bool enable) AW_DEV_LOGI(aw_dev->dev, "hw already power on"); } } else { - if (aw_dev_gpio_is_valid(aw_dev)) { + if (aw87xxx_dev_gpio_is_valid(aw_dev)) { gpio_set_value_cansleep(aw_dev->rst_gpio, AW_GPIO_LOW_LEVEL); mdelay(2); aw_dev->hwen_status = AW_DEV_HWEN_OFF; @@ -263,18 +387,18 @@ void aw_dev_hw_pwr_ctrl(struct aw_device *aw_dev, bool enable) } } -int aw_dev_mute_ctrl(struct aw_device *aw_dev, bool enable) +static int aw87xxx_dev_mute_ctrl(struct aw_device *aw_dev, bool enable) { int ret = 0; if (enable) { - ret = aw_dev_i2c_write_bits(aw_dev, aw_dev->mute_desc.addr, + ret = aw87xxx_dev_i2c_write_bits(aw_dev, aw_dev->mute_desc.addr, aw_dev->mute_desc.mask, aw_dev->mute_desc.enable); if (ret < 0) return ret; AW_DEV_LOGI(aw_dev->dev, "set mute down"); } else { - ret = aw_dev_i2c_write_bits(aw_dev, aw_dev->mute_desc.addr, + ret = aw87xxx_dev_i2c_write_bits(aw_dev, aw_dev->mute_desc.addr, aw_dev->mute_desc.mask, aw_dev->mute_desc.disable); if (ret < 0) return ret; @@ -284,7 +408,7 @@ int aw_dev_mute_ctrl(struct aw_device *aw_dev, bool enable) return 0; } -void aw_dev_soft_reset(struct aw_device *aw_dev) +void aw87xxx_dev_soft_reset(struct aw_device *aw_dev) { int i = 0; int ret = -1; @@ -313,11 +437,11 @@ void aw_dev_soft_reset(struct aw_device *aw_dev) return; } - for (i = 0; i < soft_rst->len / sizeof(uint8_t); i += 2) { + for (i = 0; i < soft_rst->len; i += 2) { AW_DEV_LOGD(aw_dev->dev, "softrst_reg=0x%02x, val = 0x%02x", soft_rst->access[i], soft_rst->access[i + 1]); - ret = aw_dev_i2c_write_byte(aw_dev, soft_rst->access[i], + ret = aw87xxx_dev_i2c_write_byte(aw_dev, soft_rst->access[i], soft_rst->access[i + 1]); if (ret < 0) { AW_DEV_LOGE(aw_dev->dev, "write failed,ret = %d,cnt=%d", @@ -329,7 +453,7 @@ void aw_dev_soft_reset(struct aw_device *aw_dev) } -int aw_dev_default_pwr_off(struct aw_device *aw_dev, +int aw87xxx_dev_default_pwr_off(struct aw_device *aw_dev, struct aw_data_container *profile_data) { int ret = 0; @@ -341,19 +465,22 @@ int aw_dev_default_pwr_off(struct aw_device *aw_dev, } if (aw_dev->soft_off_enable && profile_data) { - ret = aw_dev_reg_update(aw_dev, profile_data); + ret = aw87xxx_dev_reg_update(aw_dev, profile_data); if (ret < 0) { AW_DEV_LOGE(aw_dev->dev, "update profile[Off] fw config failed"); goto reg_off_update_failed; } } - aw_dev_hw_pwr_ctrl(aw_dev, false); + if (aw_dev->chipid == AW_DEV_CHIPID_C2) + mdelay(5); + + aw87xxx_dev_hw_pwr_ctrl(aw_dev, false); AW_DEV_LOGD(aw_dev->dev, "down"); return 0; reg_off_update_failed: - aw_dev_hw_pwr_ctrl(aw_dev, false); + aw87xxx_dev_hw_pwr_ctrl(aw_dev, false); return ret; } @@ -364,15 +491,18 @@ reg_off_update_failed: * ************************************************************************/ -int aw_dev_default_pwr_on(struct aw_device *aw_dev, +int aw87xxx_dev_default_pwr_on(struct aw_device *aw_dev, struct aw_data_container *profile_data) { int ret = 0; /*hw power on*/ - aw_dev_hw_pwr_ctrl(aw_dev, true); + aw87xxx_dev_hw_pwr_ctrl(aw_dev, true); - ret = aw_dev_reg_update(aw_dev, profile_data); + if (aw_dev->chipid == AW_DEV_CHIPID_C2) + mdelay(3); + + ret = aw87xxx_dev_reg_update(aw_dev, profile_data); if (ret < 0) return ret; @@ -384,7 +514,7 @@ int aw_dev_default_pwr_on(struct aw_device *aw_dev, * aw87xxx chip esd status check * ****************************************************************************/ -int aw_dev_esd_reg_status_check(struct aw_device *aw_dev) +int aw87xxx_dev_esd_reg_status_check(struct aw_device *aw_dev) { int ret; unsigned char reg_val = 0; @@ -397,7 +527,7 @@ int aw_dev_esd_reg_status_check(struct aw_device *aw_dev) return -EINVAL; } - ret = aw_dev_i2c_read_byte(aw_dev, esd_desc->first_update_reg_addr, + ret = aw87xxx_dev_i2c_read_byte(aw_dev, esd_desc->first_update_reg_addr, ®_val); if (ret < 0) { AW_DEV_LOGE(aw_dev->dev, "read reg 0x%02x failed", @@ -416,7 +546,7 @@ int aw_dev_esd_reg_status_check(struct aw_device *aw_dev) return 0; } -int aw_dev_check_reg_is_rec_mode(struct aw_device *aw_dev) +int aw87xxx_dev_check_reg_is_rec_mode(struct aw_device *aw_dev) { int ret; unsigned char reg_val = 0; @@ -427,7 +557,7 @@ int aw_dev_check_reg_is_rec_mode(struct aw_device *aw_dev) return -EINVAL; } - ret = aw_dev_i2c_read_byte(aw_dev, rec_desc->addr, ®_val); + ret = aw87xxx_dev_i2c_read_byte(aw_dev, rec_desc->addr, ®_val); if (ret < 0) { AW_DEV_LOGE(aw_dev->dev, "read reg 0x%02x failed", rec_desc->addr); @@ -452,6 +582,140 @@ int aw_dev_check_reg_is_rec_mode(struct aw_device *aw_dev) return 0; } +/**************************************************************************** + * + * aw87xxx algo_encryption + * + ****************************************************************************/ +int aw87xxx_dev_get_encrypted_value(struct aw_device *aw_dev, + unsigned int in, unsigned int *out) +{ + int ret = 0; + struct aw_auth_desc *desc = &aw_dev->auth_desc; + uint8_t out_l = 0; + uint8_t out_h = 0; + + if ((desc->reg_in_l == AW_REG_NONE) || (desc->reg_in_h == AW_REG_NONE) || + (desc->reg_out_l == AW_REG_NONE) || (desc->reg_out_h == AW_REG_NONE)) { + AW_DEV_LOGD(aw_dev->dev, "Missing encryption register"); + return -EINVAL; + } + + ret = aw87xxx_dev_i2c_write_byte(aw_dev, desc->reg_in_l, (in & 0xFF)); + if (ret < 0) + return ret; + + ret = aw87xxx_dev_i2c_write_byte(aw_dev, desc->reg_in_h, ((in >> 8) & 0xFF)); + if (ret < 0) + return ret; + + ret = aw87xxx_dev_i2c_read_byte(aw_dev, desc->reg_out_l, &out_l); + if (ret < 0) + return ret; + + ret = aw87xxx_dev_i2c_read_byte(aw_dev, desc->reg_out_h, &out_h); + + *out = out_l | (out_h << 8); + + return ret; +} + +int aw87xxx_dev_algo_auth_mode(struct aw_device *aw_dev, struct algo_auth_data *algo_data) +{ + int ret = 0; + unsigned int encrypted_out = 0; + + AW_DEV_LOGD(aw_dev->dev, "algo auth mode: %d", algo_data->auth_mode); + + aw_dev->auth_desc.auth_mode = algo_data->auth_mode; + aw_dev->auth_desc.random = algo_data->random; + aw_dev->auth_desc.chip_id = AW_ALGO_AUTH_MAGIC_ID; + aw_dev->auth_desc.check_result = algo_data->check_result; + + switch (algo_data->auth_mode) { + case AW_ALGO_AUTH_MODE_MAGIC_ID: + aw_dev->auth_desc.reg_crc = algo_data->reg_crc; + break; + case AW_ALGO_AUTH_MODE_REG_CRC: + ret = aw87xxx_dev_get_encrypted_value(aw_dev, algo_data->random, &encrypted_out); + if (ret < 0) + AW_DEV_LOGE(aw_dev->dev, "get encrypted value failed"); + aw_dev->auth_desc.reg_crc = encrypted_out; + break; + default: + AW_DEV_LOGE(aw_dev->dev, "unsupport auth mode[%d]", algo_data->auth_mode); + ret = -EINVAL; + } + return ret; +} + +#ifdef AW_ALGO_AUTH_DSP +int aw87xxx_dev_algo_auth_dsp_mode(struct aw_device *aw_dev, struct algo_auth_data *algo_data) +{ + int ret = 0; + unsigned int encrypted_out = 0; + + AW_DEV_LOGD(aw_dev->dev, "algo auth mode: %d", algo_data->auth_mode); + + algo_data->chip_id = AW_ALGO_AUTH_MAGIC_ID; + + if (algo_data->auth_mode == AW_ALGO_AUTH_MODE_REG_CRC) { + ret = aw87xxx_dev_get_encrypted_value(aw_dev, algo_data->random, &encrypted_out); + if (ret < 0) + AW_DEV_LOGE(aw_dev->dev, "get encrypted value failed"); + algo_data->reg_crc = encrypted_out; + } + + return ret; +} + +void aw87xxx_dev_algo_authentication(struct aw_device *aw_dev) +{ + int ret = 0; + struct algo_auth_data algo_data; + + mutex_lock(&g_algo_auth_dsp_lock); + + AW_DEV_LOGD(aw_dev->dev, "g_algo_auth_st=%d", g_algo_auth_st); + + if (g_algo_auth_st == AW_ALGO_AUTH_OK) { + AW_DEV_LOGD(aw_dev->dev, "algo auth complete"); + goto exit; + } + + ret = aw87xxx_dsp_get_algo_auth_data(aw_dev, (char *)&algo_data, sizeof(struct algo_auth_data)); + if (ret < 0) + goto exit; + + ret = aw87xxx_dev_algo_auth_dsp_mode(aw_dev, &algo_data); + if (ret < 0) + goto exit; + + ret = aw87xxx_dsp_set_algo_auth_data(aw_dev, (char *)&algo_data, sizeof(struct algo_auth_data)); + if (ret < 0) + goto exit; + + g_algo_auth_st = AW_ALGO_AUTH_OK; + + AW_DEV_LOGI(aw_dev->dev, "g_algo_auth_st=%d", g_algo_auth_st); + + AW_DEV_LOGD(aw_dev->dev, "mode=%d,reg_crc=0x%x,random=0x%x,id=0x%x,res=%d", + algo_data.auth_mode, algo_data.reg_crc, algo_data.random, + algo_data.chip_id, algo_data.check_result); + +exit: + mutex_unlock(&g_algo_auth_dsp_lock); +} +#endif + +static void aw_dev_auth_reg_none(struct aw_device *aw_dev) +{ + /*encryption info*/ + aw_dev->auth_desc.reg_in_l = AW_REG_NONE; + aw_dev->auth_desc.reg_in_h = AW_REG_NONE; + aw_dev->auth_desc.reg_out_l = AW_REG_NONE; + aw_dev->auth_desc.reg_out_h = AW_REG_NONE; +} /**************************************************************************** * @@ -480,7 +744,7 @@ static int aw_dev_pid_9b_reg_update(struct aw_device *aw_dev, AW_DEV_LOGE(aw_dev->dev, "reg_config count of bin is error,can not update reg"); return -EINVAL; } - ret = aw_dev_i2c_write_byte(aw_dev, AW87XXX_PID_9B_ENCRYPTION_REG, + ret = aw87xxx_dev_i2c_write_byte(aw_dev, AW87XXX_PID_9B_ENCRYPTION_REG, AW87XXX_PID_9B_ENCRYPTION_BOOST_OUTPUT_SET); if (ret < 0) return ret; @@ -488,14 +752,22 @@ static int aw_dev_pid_9b_reg_update(struct aw_device *aw_dev, for (i = 1; i < AW_PID_9B_BIN_REG_CFG_COUNT; i++) { AW_DEV_LOGI(aw_dev->dev, "reg=0x%02x, val = 0x%02x", i, profile_data->data[i]); + /*delay ms*/ + if (profile_data->data[i] == AW87XXX_DELAY_REG_ADDR) { + AW_DEV_LOGI(aw_dev->dev, "delay %d ms", profile_data->data[i + 1]); + usleep_range(profile_data->data[i + 1] * AW87XXX_REG_DELAY_TIME, + profile_data->data[i + 1] * AW87XXX_REG_DELAY_TIME + 10); + continue; + } + reg_val = profile_data->data[i]; if (i == AW87XXX_PID_9B_SYSCTRL_REG) { - aw_dev_reg_mute_bits_set(aw_dev, ®_val, true); + aw87xxx_dev_reg_mute_bits_set(aw_dev, ®_val, true); AW_DEV_LOGD(aw_dev->dev, "change mute_mask, val = 0x%02x", reg_val); } - ret = aw_dev_i2c_write_byte(aw_dev, i, reg_val); + ret = aw87xxx_dev_i2c_write_byte(aw_dev, i, reg_val); if (ret < 0) return ret; } @@ -503,15 +775,15 @@ static int aw_dev_pid_9b_reg_update(struct aw_device *aw_dev, return 0; } -int aw_dev_pid_9b_pwr_on(struct aw_device *aw_dev, struct aw_data_container *data) +static int aw_dev_pid_9b_pwr_on(struct aw_device *aw_dev, struct aw_data_container *data) { int ret = 0; /*hw power on*/ - aw_dev_hw_pwr_ctrl(aw_dev, true); + aw87xxx_dev_hw_pwr_ctrl(aw_dev, true); /* open the mute */ - ret = aw_dev_mute_ctrl(aw_dev, true); + ret = aw87xxx_dev_mute_ctrl(aw_dev, true); if (ret < 0) return ret; @@ -521,7 +793,7 @@ int aw_dev_pid_9b_pwr_on(struct aw_device *aw_dev, struct aw_data_container *dat return ret; /* close the mute */ - aw_dev_mute_ctrl(aw_dev, false); + ret = aw87xxx_dev_mute_ctrl(aw_dev, false); if (ret < 0) return ret; @@ -559,20 +831,24 @@ static void aw_dev_pid_9b_init(struct aw_device *aw_dev) /* esd reg info */ aw_dev->esd_desc.first_update_reg_addr = AW87XXX_PID_9B_SYSCTRL_REG; aw_dev->esd_desc.first_update_reg_val = AW87XXX_PID_9B_SYSCTRL_DEFAULT; + + aw_dev->vol_desc.addr = AW_REG_NONE; + + aw_dev_auth_reg_none(aw_dev); } static int aw_dev_pid_9a_init(struct aw_device *aw_dev) { int ret = 0; - ret = aw_dev_i2c_write_byte(aw_dev, AW87XXX_PID_9B_ENCRYPTION_REG, + ret = aw87xxx_dev_i2c_write_byte(aw_dev, AW87XXX_PID_9B_ENCRYPTION_REG, AW87XXX_PID_9B_ENCRYPTION_BOOST_OUTPUT_SET); if (ret < 0) { AW_DEV_LOGE(aw_dev->dev, "write 0x64=0x2C error"); return -EINVAL; } - ret = aw_dev_get_chipid(aw_dev); + ret = aw87xxx_dev_get_chipid(aw_dev); if (ret < 0) { AW_DEV_LOGE(aw_dev->dev, "read chipid is failed,ret=%d", ret); return ret; @@ -582,7 +858,7 @@ static int aw_dev_pid_9a_init(struct aw_device *aw_dev) AW_DEV_LOGI(aw_dev->dev, "product is pid_9B class"); aw_dev_pid_9b_init(aw_dev); } else { - AW_DEV_LOGE(aw_dev->dev, "product is not pid_9B class, not support"); + AW_DEV_LOGE(aw_dev->dev, "product is not pid_9B class,not support"); return -EINVAL; } @@ -591,6 +867,71 @@ static int aw_dev_pid_9a_init(struct aw_device *aw_dev) /********************** aw87xxx_pid_9b attributes end ***********************/ +/********************** aw87xxx_pid_18 attributes ***************************/ +static int aw_dev_pid_18_pwr_on(struct aw_device *aw_dev, struct aw_data_container *data) +{ + int ret = 0; + + /*hw power on*/ + aw87xxx_dev_hw_pwr_ctrl(aw_dev, true); + + /* open the mute */ + ret = aw87xxx_dev_mute_ctrl(aw_dev, true); + if (ret < 0) + return ret; + + /* Update scene parameters in mute mode */ + ret = aw87xxx_dev_reg_update_mute(aw_dev, data); + if (ret < 0) + return ret; + + /* close the mute */ + ret = aw87xxx_dev_mute_ctrl(aw_dev, false); + if (ret < 0) + return ret; + + return 0; +} + +static void aw_dev_chipid_18_init(struct aw_device *aw_dev) +{ + /* Product register permission info */ + aw_dev->reg_max_addr = AW87XXX_PID_18_REG_MAX; + aw_dev->reg_access = aw87xxx_pid_18_reg_access; + + aw_dev->mute_desc.addr = AW87XXX_PID_18_SYSCTRL_REG; + aw_dev->mute_desc.mask = AW87XXX_PID_18_REG_EN_SW_MASK; + aw_dev->mute_desc.enable = AW87XXX_PID_18_REG_EN_SW_DISABLE_VALUE; + aw_dev->mute_desc.disable = AW87XXX_PID_18_REG_EN_SW_ENABLE_VALUE; + aw_dev->ops.pwr_on_func = aw_dev_pid_18_pwr_on; + + /* software reset control info */ + aw_dev->soft_rst_desc.len = sizeof(aw87xxx_pid_18_softrst_access); + aw_dev->soft_rst_desc.access = aw87xxx_pid_18_softrst_access; + aw_dev->soft_rst_enable = AW_DEV_SOFT_RST_ENABLE; + + /* Whether to allow register operation to power off */ + aw_dev->soft_off_enable = AW_DEV_SOFT_OFF_ENABLE; + + aw_dev->product_tab = g_aw_pid_18_product; + aw_dev->product_cnt = AW87XXX_PID_18_PRODUCT_MAX; + + aw_dev->rec_desc.addr = AW87XXX_PID_18_SYSCTRL_REG; + aw_dev->rec_desc.disable = AW87XXX_PID_18_REG_REC_MODE_DISABLE; + aw_dev->rec_desc.enable = AW87XXX_PID_18_REG_REC_MODE_ENABLE; + aw_dev->rec_desc.mask = AW87XXX_PID_18_REG_REC_MODE_MASK; + + /* esd reg info */ + aw_dev->esd_desc.first_update_reg_addr = AW87XXX_PID_18_CLASSD_REG; + aw_dev->esd_desc.first_update_reg_val = AW87XXX_PID_18_CLASSD_DEFAULT; + aw_dev->ipeak_desc.reg = AW_REG_NONE; + + aw_dev->vol_desc.addr = AW87XXX_PID_18_CPOC_REG; + + aw_dev_auth_reg_none(aw_dev); +} +/********************** aw87xxx_pid_18 attributes end ***********************/ + /********************** aw87xxx_pid_39 attributes ***************************/ static void aw_dev_chipid_39_init(struct aw_device *aw_dev) { @@ -617,6 +958,11 @@ static void aw_dev_chipid_39_init(struct aw_device *aw_dev) /* esd reg info */ aw_dev->esd_desc.first_update_reg_addr = AW87XXX_PID_39_REG_MODECTRL; aw_dev->esd_desc.first_update_reg_val = AW87XXX_PID_39_MODECTRL_DEFAULT; + aw_dev->ipeak_desc.reg = AW_REG_NONE; + + aw_dev->vol_desc.addr = AW87XXX_PID_39_REG_CPOVP; + + aw_dev_auth_reg_none(aw_dev); } /********************* aw87xxx_pid_39 attributes end *************************/ @@ -647,6 +993,11 @@ static void aw_dev_chipid_59_5x9_init(struct aw_device *aw_dev) /* esd reg info */ aw_dev->esd_desc.first_update_reg_addr = AW87XXX_PID_59_5X9_REG_ENCR; aw_dev->esd_desc.first_update_reg_val = AW87XXX_PID_59_5X9_ENCRY_DEFAULT; + aw_dev->ipeak_desc.reg = AW_REG_NONE; + + aw_dev->vol_desc.addr = AW_REG_NONE; + + aw_dev_auth_reg_none(aw_dev); } /******************* aw87xxx_pid_59_5x9 attributes end ***********************/ @@ -676,6 +1027,11 @@ static void aw_dev_chipid_59_3x9_init(struct aw_device *aw_dev) /* esd reg info */ aw_dev->esd_desc.first_update_reg_addr = AW87XXX_PID_59_3X9_REG_ENCR; aw_dev->esd_desc.first_update_reg_val = AW87XXX_PID_59_3X9_ENCR_DEFAULT; + aw_dev->ipeak_desc.reg = AW_REG_NONE; + + aw_dev->vol_desc.addr = AW87XXX_PID_59_3X9_REG_CPOVP; + + aw_dev_auth_reg_none(aw_dev); } /******************* aw87xxx_pid_59_3x9 attributes end ***********************/ @@ -705,8 +1061,16 @@ static void aw_dev_chipid_5a_init(struct aw_device *aw_dev) /* esd reg info */ aw_dev->esd_desc.first_update_reg_addr = AW87XXX_PID_5A_REG_DFT3R_REG; aw_dev->esd_desc.first_update_reg_val = AW87XXX_PID_5A_DFT3R_DEFAULT; -} + aw_dev->ipeak_desc.reg = AW87XXX_PID_5A_REG_BSTCPR2_REG; + aw_dev->ipeak_desc.mask = AW87XXX_PID_5A_REG_BST_IPEAK_MASK; + aw_dev->vol_desc.addr = AW_REG_NONE; + + aw_dev_auth_reg_none(aw_dev); +} +/********************** aw87xxx_pid_5a attributes end ************************/ + +/********************** aw87xxx_pid_76 attributes ****************************/ static void aw_dev_chipid_76_init(struct aw_device *aw_dev) { /* Product register permission info */ @@ -732,11 +1096,128 @@ static void aw_dev_chipid_76_init(struct aw_device *aw_dev) /* esd reg info */ aw_dev->esd_desc.first_update_reg_addr = AW87XXX_PID_76_DFT_ADP1_REG; aw_dev->esd_desc.first_update_reg_val = AW87XXX_PID_76_DFT_ADP1_CHECK; + aw_dev->ipeak_desc.reg = AW_REG_NONE; + + aw_dev->vol_desc.addr = AW87XXX_PID_76_CPOVP_REG; + + aw_dev_auth_reg_none(aw_dev); } +/********************** aw87xxx_pid_76 attributes end ************************/ -/********************** aw87xxx_pid_5a attributes end ************************/ +/********************** aw87xxx_pid_60 attributes ****************************/ +static void aw_dev_chipid_60_init(struct aw_device *aw_dev) +{ + /* Product register permission info */ + aw_dev->reg_max_addr = AW87XXX_PID_60_REG_MAX; + aw_dev->reg_access = aw87xxx_pid_60_reg_access; -static void aw_dev_chip_init(struct aw_device *aw_dev) + /* software reset control info */ + aw_dev->soft_rst_desc.len = sizeof(aw87xxx_pid_60_softrst_access); + aw_dev->soft_rst_desc.access = aw87xxx_pid_60_softrst_access; + aw_dev->soft_rst_enable = AW_DEV_SOFT_RST_ENABLE; + + /* software power off control info */ + aw_dev->soft_off_enable = AW_DEV_SOFT_OFF_ENABLE; + + aw_dev->product_tab = g_aw_pid_60_product; + aw_dev->product_cnt = AW87XXX_PID_60_PROFUCT_MAX; + + aw_dev->rec_desc.addr = AW87XXX_PID_60_SYSCTRL_REG; + aw_dev->rec_desc.disable = AW87XXX_PID_60_RCV_MODE_DISABLE; + aw_dev->rec_desc.enable = AW87XXX_PID_60_RCV_MODE_ENABLE; + aw_dev->rec_desc.mask = AW87XXX_PID_60_RCV_MODE_MASK; + + /* esd reg info */ + aw_dev->esd_desc.first_update_reg_addr = AW87XXX_PID_60_NG3_REG; + aw_dev->esd_desc.first_update_reg_val = AW87XXX_PID_60_ESD_REG_VAL; + + aw_dev->ipeak_desc.reg = AW_REG_NONE; + aw_dev->vol_desc.addr = AW_REG_NONE; + + aw_dev_auth_reg_none(aw_dev); +} +/********************** aw87xxx_pid_60 attributes end ************************/ + +/********************** aw87xxx_pid_c1 attributes ****************************/ +static void aw_dev_chipid_c1_init(struct aw_device *aw_dev) +{ + /* Product register permission info */ + aw_dev->reg_max_addr = AW87XXX_PID_C1_REG_MAX; + aw_dev->reg_access = aw87xxx_pid_c1_reg_access; + + /* software reset control info */ + aw_dev->soft_rst_desc.len = sizeof(aw87xxx_pid_c1_softrst_access); + aw_dev->soft_rst_desc.access = aw87xxx_pid_c1_softrst_access; + aw_dev->soft_rst_enable = AW_DEV_SOFT_RST_ENABLE; + + /* software power off control info */ + aw_dev->soft_off_enable = AW_DEV_SOFT_OFF_ENABLE; + + aw_dev->product_tab = g_aw_pid_c1_product; + aw_dev->product_cnt = AW87XXX_PID_C1_PROFUCT_MAX; + + aw_dev->rec_desc.addr = AW87XXX_PID_C1_SYSCTRL_REG; + aw_dev->rec_desc.disable = AW87XXX_PID_C1_EN_SPK_SPK_MODE_ENABLE; + aw_dev->rec_desc.enable = AW87XXX_PID_C1_EN_SPK_SPK_MODE_DISABLE; + aw_dev->rec_desc.mask = AW87XXX_PID_C1_EN_SPK_MASK; + + /* esd reg info */ + aw_dev->esd_desc.first_update_reg_addr = AW87XXX_PID_C1_DFT_THGEN1_REG; + aw_dev->esd_desc.first_update_reg_val = AW87XXX_PID_C1_DFT_THGEN1_CHECK; + + aw_dev->vol_desc.addr = AW_REG_NONE; + + aw_dev->ipeak_desc.reg = AW_REG_NONE; + + /*encryption info*/ + aw_dev->auth_desc.reg_in_l = AW87XXX_PID_C1_TESTIN1_REG; + aw_dev->auth_desc.reg_in_h = AW87XXX_PID_C1_TESTIN2_REG; + aw_dev->auth_desc.reg_out_l = AW87XXX_PID_C1_TESTOUT1_REG; + aw_dev->auth_desc.reg_out_h = AW87XXX_PID_C1_TESTOUT2_REG; +} +/********************** aw87xxx_pid_c1 attributes end ************************/ + +/********************** aw87xxx_pid_c2 attributes ****************************/ +static void aw_dev_chipid_c2_init(struct aw_device *aw_dev) +{ + /* Product register permission info */ + aw_dev->reg_max_addr = AW87XXX_PID_C2_REG_MAX; + aw_dev->reg_access = aw87xxx_pid_c2_reg_access; + + /* software reset control info */ + aw_dev->soft_rst_desc.len = sizeof(aw87xxx_pid_c2_softrst_access); + aw_dev->soft_rst_desc.access = aw87xxx_pid_c2_softrst_access; + aw_dev->soft_rst_enable = AW_DEV_SOFT_RST_ENABLE; + + /* software power off control info */ + aw_dev->soft_off_enable = AW_DEV_SOFT_OFF_ENABLE; + + aw_dev->product_tab = g_aw_pid_c2_product; + aw_dev->product_cnt = AW87XXX_PID_C2_PROFUCT_MAX; + + aw_dev->rec_desc.addr = AW87XXX_PID_C2_SYSCTRL_REG; + aw_dev->rec_desc.disable = AW87XXX_PID_C2_RCV_MODE_DISABLE; + aw_dev->rec_desc.enable = AW87XXX_PID_C2_RCV_MODE_ENABLE; + aw_dev->rec_desc.mask = AW87XXX_PID_C2_RCV_MODE_MASK; + + /* esd reg info */ + aw_dev->esd_desc.first_update_reg_addr = AW87XXX_PID_C2_CP_REG; + aw_dev->esd_desc.first_update_reg_val = AW87XXX_PID_C2_CP_CHECK; + + aw_dev->ipeak_desc.reg = AW87XXX_PID_C2_PEAKLIMIT_REG; + aw_dev->ipeak_desc.mask = AW87XXX_PID_C2_BST_IPEAK_MASK; + + aw_dev->vol_desc.addr = AW_REG_NONE; + + /*encryption info*/ + aw_dev->auth_desc.reg_in_l = AW87XXX_PID_C2_TESTIN1_REG; + aw_dev->auth_desc.reg_in_h = AW87XXX_PID_C2_TESTIN2_REG; + aw_dev->auth_desc.reg_out_l = AW87XXX_PID_C2_CRCOUT0_REG; + aw_dev->auth_desc.reg_out_h = AW87XXX_PID_C2_CRCOUT1_REG; +} +/********************** aw87xxx_pid_c2 attributes end ************************/ + +static int aw_dev_chip_init(struct aw_device *aw_dev) { int ret = 0; @@ -751,12 +1232,16 @@ static void aw_dev_chip_init(struct aw_device *aw_dev) aw_dev_pid_9b_init(aw_dev); AW_DEV_LOGI(aw_dev->dev, "product is pid_9B class"); break; + case AW_DEV_CHIPID_18: + aw_dev_chipid_18_init(aw_dev); + AW_DEV_LOGI(aw_dev->dev, "product is pid_18 class"); + break; case AW_DEV_CHIPID_39: aw_dev_chipid_39_init(aw_dev); AW_DEV_LOGI(aw_dev->dev, "product is pid_39 class"); break; case AW_DEV_CHIPID_59: - if (aw_dev_gpio_is_valid(aw_dev)) { + if (aw87xxx_dev_gpio_is_valid(aw_dev)) { aw_dev_chipid_59_5x9_init(aw_dev); AW_DEV_LOGI(aw_dev->dev, "product is pid_59_5x9 class"); } else { @@ -772,21 +1257,35 @@ static void aw_dev_chip_init(struct aw_device *aw_dev) aw_dev_chipid_76_init(aw_dev); AW_DEV_LOGI(aw_dev->dev, "product is pid_76 class"); break; + case AW_DEV_CHIPID_60: + aw_dev_chipid_60_init(aw_dev); + AW_DEV_LOGI(aw_dev->dev, "product is pid_60 class"); + break; + case AW_DEV_CHIPID_C1: + aw_dev_chipid_c1_init(aw_dev); + AW_DEV_LOGI(aw_dev->dev, "product is pid_c1 class"); + break; + case AW_DEV_CHIPID_C2: + aw_dev_chipid_c2_init(aw_dev); + AW_DEV_LOGI(aw_dev->dev, "product is pid_c2 class"); + break; default: AW_DEV_LOGE(aw_dev->dev, "unsupported device revision [0x%x]", aw_dev->chipid); - return; + return -EINVAL; } + + return 0; } -static int aw_dev_get_chipid(struct aw_device *aw_dev) +static int aw87xxx_dev_get_chipid(struct aw_device *aw_dev) { int ret = -1; unsigned int cnt = 0; unsigned char reg_val = 0; for (cnt = 0; cnt < AW_READ_CHIPID_RETRIES; cnt++) { - ret = aw_dev_i2c_read_byte(aw_dev, AW_DEV_REG_CHIPID, ®_val); + ret = aw87xxx_dev_i2c_read_byte(aw_dev, AW_DEV_REG_CHIPID, ®_val); if (ret < 0) { AW_DEV_LOGE(aw_dev->dev, "[%d] read chip is failed, ret=%d", cnt, ret); @@ -807,19 +1306,19 @@ static int aw_dev_get_chipid(struct aw_device *aw_dev) return 0; } -int aw_dev_init(struct aw_device *aw_dev) +int aw87xxx_dev_init(struct aw_device *aw_dev) { int ret = -1; - ret = aw_dev_get_chipid(aw_dev); + ret = aw87xxx_dev_get_chipid(aw_dev); if (ret < 0) { AW_DEV_LOGE(aw_dev->dev, "read chipid is failed,ret=%d", ret); return ret; } - aw_dev_chip_init(aw_dev); + ret = aw_dev_chip_init(aw_dev); - return 0; + return ret; } diff --git a/sound/soc/codecs/aw87xxx/aw_device.h b/sound/soc/codecs/aw87xxx/aw_device.h index aec7f21c6453..9eab755c8ab5 100644 --- a/sound/soc/codecs/aw87xxx/aw_device.h +++ b/sound/soc/codecs/aw87xxx/aw_device.h @@ -1,19 +1,37 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ +/* SPDX-License-Identifier: GPL-2.0 + * + * aw87xxx_device.h aw87xxx pa module + * + * Copyright (c) 2021 AWINIC Technology CO., LTD + * + * Author: Barry + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ -#ifndef __AW_DEVICE_H__ -#define __AW_DEVICE_H__ +#ifndef __AW87XXX_DEVICE_H__ +#define __AW87XXX_DEVICE_H__ #include #include #include #include #include "aw_acf_bin.h" -#define AW87XXX_PID_9B_PRODUCT_MAX (1) -#define AW87XXX_PID_39_PRODUCT_MAX (3) -#define AW87XXX_PID_59_3X9_PRODUCT_MAX (2) -#define AW87XXX_PID_59_5X9_PRODUCT_MAX (4) -#define AW87XXX_PID_5A_PRODUCT_MAX (5) -#define AW87XXX_PID_76_PROFUCT_MAX (3) +#define AW87XXX_PID_9B_PRODUCT_MAX (2) +#define AW87XXX_PID_18_PRODUCT_MAX (2) +#define AW87XXX_PID_39_PRODUCT_MAX (6) +#define AW87XXX_PID_59_3X9_PRODUCT_MAX (4) +#define AW87XXX_PID_59_5X9_PRODUCT_MAX (8) +#define AW87XXX_PID_5A_PRODUCT_MAX (12) +#define AW87XXX_PID_76_PROFUCT_MAX (10) +#define AW87XXX_PID_60_PROFUCT_MAX (10) +#define AW87XXX_PID_C1_PROFUCT_MAX (4) +#define AW87XXX_PID_C2_PROFUCT_MAX (10) + #define AW_PRODUCT_NAME_LEN (8) #define AW_GPIO_HIGHT_LEVEL (1) @@ -33,6 +51,12 @@ #define AW_PID_9B_BIN_REG_CFG_COUNT (10) +#define AW87XXX_DELAY_REG_ADDR (0xFE) +#define AW87XXX_REG_DELAY_TIME (1000) + +#define AW_BOOST_VOLTAGE_MIN (0x00) + +#define AW_REG_NONE (0xFF) /******************************************** * * aw87xxx devices attributes @@ -40,6 +64,36 @@ *******************************************/ struct aw_device; +/*#define AW_ALGO_AUTH_DSP*/ +extern int g_algo_auth_st; + +enum AW_ALGO_AUTH_MODE { + AW_ALGO_AUTH_DISABLE = 0, + AW_ALGO_AUTH_MODE_MAGIC_ID, + AW_ALGO_AUTH_MODE_REG_CRC, +}; + +enum AW_ALGO_AUTH_ID { + AW_ALGO_AUTH_MAGIC_ID = 0x4157, +}; + +enum AW_ALGO_AUTH_STATUS { + AW_ALGO_AUTH_WAIT = 0, + AW_ALGO_AUTH_OK = 1, +}; + +#define AW_IOCTL_MAGIC_S 'w' +#define AW_IOCTL_GET_ALGO_AUTH _IOWR(AW_IOCTL_MAGIC_S, 1, struct algo_auth_data) +#define AW_IOCTL_SET_ALGO_AUTH _IOWR(AW_IOCTL_MAGIC_S, 2, struct algo_auth_data) + +struct algo_auth_data { + int32_t auth_mode; /* 0: disable 1 : chip ID 2 : reg crc */ + int32_t reg_crc; + int32_t random; + int32_t chip_id; + int32_t check_result; /* 0 failed 1 success */ +}; + struct aw_device_ops { int (*pwr_on_func)(struct aw_device *aw_dev, struct aw_data_container *data); int (*pwr_off_func)(struct aw_device *aw_dev, struct aw_data_container *data); @@ -54,6 +108,9 @@ enum aw_dev_chipid { AW_DEV_CHIPID_9A = 0x9A, AW_DEV_CHIPID_9B = 0x9B, AW_DEV_CHIPID_76 = 0x76, + AW_DEV_CHIPID_60 = 0x60, + AW_DEV_CHIPID_C1 = 0xC1, + AW_DEV_CHIPID_C2 = 0xC2, }; enum aw_dev_hw_status { @@ -78,6 +135,11 @@ enum aw_reg_receiver_mode { AW_IS_REC_MODE = 1, }; +enum aw_reg_voltage_status { + AW_VOLTAGE_LOW = 0, + AW_VOLTAGE_HIGH, +}; + struct aw_mute_desc { uint8_t addr; uint8_t enable; @@ -102,6 +164,29 @@ struct aw_rec_mode_desc { uint8_t mask; }; +struct aw_voltage_desc { + uint8_t addr; + uint8_t vol_max; + uint8_t vol_min; +}; + +struct aw_auth_desc { + uint8_t reg_in_l; + uint8_t reg_in_h; + uint8_t reg_out_l; + uint8_t reg_out_h; + int32_t auth_mode; + int32_t reg_crc; + int32_t random; + int32_t chip_id; + int32_t check_result; +}; + +struct aw_ipeak_desc { + unsigned int reg; + unsigned int mask; +}; + struct aw_device { uint8_t i2c_addr; uint8_t chipid; @@ -111,7 +196,6 @@ struct aw_device { int hwen_status; int i2c_bus; int rst_gpio; - int rst_shared_gpio; int reg_max_addr; int product_cnt; const char **product_tab; @@ -123,29 +207,34 @@ struct aw_device { struct aw_soft_rst_desc soft_rst_desc; struct aw_esd_check_desc esd_desc; struct aw_rec_mode_desc rec_desc; + struct aw_voltage_desc vol_desc; + struct aw_auth_desc auth_desc; + struct aw_ipeak_desc ipeak_desc; struct aw_device_ops ops; }; -int aw_dev_i2c_write_byte(struct aw_device *aw_dev, +int aw87xxx_dev_i2c_write_byte(struct aw_device *aw_dev, uint8_t reg_addr, uint8_t reg_data); -int aw_dev_i2c_read_byte(struct aw_device *aw_dev, +int aw87xxx_dev_i2c_read_byte(struct aw_device *aw_dev, uint8_t reg_addr, uint8_t *reg_data); -int aw_dev_i2c_read_msg(struct aw_device *aw_dev, +int aw87xxx_dev_i2c_read_msg(struct aw_device *aw_dev, uint8_t reg_addr, uint8_t *data_buf, uint32_t data_len); -int aw_dev_i2c_write_bits(struct aw_device *aw_dev, +int aw87xxx_dev_i2c_write_bits(struct aw_device *aw_dev, uint8_t reg_addr, uint8_t mask, uint8_t reg_data); -void aw_dev_soft_reset(struct aw_device *aw_dev); -void aw_dev_hw_pwr_ctrl(struct aw_device *aw_dev, bool enable); -int aw_dev_default_profile_check(struct aw_device *aw_dev, - int profile, struct aw_data_container *profile_data); -int aw_dev_default_pwr_on(struct aw_device *aw_dev, +void aw87xxx_dev_soft_reset(struct aw_device *aw_dev); +void aw87xxx_dev_hw_pwr_ctrl(struct aw_device *aw_dev, bool enable); +int aw87xxx_dev_default_pwr_on(struct aw_device *aw_dev, struct aw_data_container *profile_data); -int aw_dev_default_pwr_off(struct aw_device *aw_dev, +int aw87xxx_dev_default_pwr_off(struct aw_device *aw_dev, struct aw_data_container *profile_data); -int aw_dev_esd_reg_status_check(struct aw_device *aw_dev); -int aw_dev_check_reg_is_rec_mode(struct aw_device *aw_dev); -int aw_dev_init(struct aw_device *aw_dev); +int aw87xxx_dev_esd_reg_status_check(struct aw_device *aw_dev); +int aw87xxx_dev_check_reg_is_rec_mode(struct aw_device *aw_dev); +int aw87xxx_dev_init(struct aw_device *aw_dev); +int aw87xxx_dev_algo_auth_mode(struct aw_device *aw_dev, struct algo_auth_data *algo_data); +#ifdef AW_ALGO_AUTH_DSP +void aw87xxx_dev_algo_authentication(struct aw_device *aw_dev); +#endif #endif diff --git a/sound/soc/codecs/aw87xxx/aw_dsp.c b/sound/soc/codecs/aw87xxx/aw_dsp.c index 83104d4f4348..fbb0474505ff 100644 --- a/sound/soc/codecs/aw87xxx/aw_dsp.c +++ b/sound/soc/codecs/aw87xxx/aw_dsp.c @@ -1,5 +1,5 @@ -/* - * aw87xxx_dsp.c +// SPDX-License-Identifier: GPL-2.0 +/* aw87xxx_dsp.c * * Copyright (c) 2021 AWINIC Technology CO., LTD * @@ -24,47 +24,34 @@ #include "aw_dsp.h" static DEFINE_MUTEX(g_dsp_lock); +static unsigned int g_spin_value; + +static int g_rx_topo_id = AW_RX_DEFAULT_TOPO_ID; +static int g_rx_port_id = AW_RX_DEFAULT_PORT_ID; #ifdef AW_MTK_OPEN_DSP_PLATFORM extern int mtk_spk_send_ipi_buf_to_dsp(void *data_buffer, uint32_t data_size); extern int mtk_spk_recv_ipi_buf_from_dsp(int8_t *buffer, int16_t size, uint32_t *buf_len); -/* -static int mtk_spk_send_ipi_buf_to_dsp(void *data_buffer, - uint32_t data_size) -{ - AW_LOGI("enter"); - return 0; -} -static int mtk_spk_recv_ipi_buf_from_dsp(int8_t *buffer, - int16_t size, uint32_t *buf_len) -{ - AW_LOGI("enter"); - return 0; -} -*/ #elif defined AW_QCOM_OPEN_DSP_PLATFORM extern int afe_get_topology(int port_id); extern int aw_send_afe_cal_apr(uint32_t param_id, void *buf, int cmd_size, bool write); -/* -static int afe_get_topology(int port_id) -{ - return -EPERM; -} -static int aw_send_afe_cal_apr(uint32_t param_id, - void *buf, int cmd_size, bool write) -{ - AW_LOGI("enter, no define AWINIC_ADSP_ENABLE", __func__); - return 0; -} -*/ #endif -uint8_t aw_dsp_isEnable(void) +#ifdef AW_QCOM_OPEN_DSP_PLATFORM +extern void aw_set_port_id(int rx_port_id); +#else +static void aw_set_port_id(int rx_port_id) +{ + +} +#endif + +uint8_t aw87xxx_dsp_isEnable(void) { #if (defined AW_QCOM_OPEN_DSP_PLATFORM) || (defined AW_MTK_OPEN_DSP_PLATFORM) return true; @@ -142,97 +129,87 @@ failed: /******************qcom dsp communication function start**********************/ #ifdef AW_QCOM_OPEN_DSP_PLATFORM -static int aw_check_dsp_ready(void) +static void aw_check_dsp_ready(void) { int ret; - ret = afe_get_topology(AFE_PORT_ID_AWDSP_RX); + ret = afe_get_topology(g_rx_port_id); AW_LOGD("topo_id 0x%x", ret); - if (ret <= 0) - return 0; - else - return 1; + if (ret != g_rx_topo_id) + AW_LOGE("topo id 0x%x", ret); + } static int aw_qcom_write_data_to_dsp(int32_t param_id, void *data, int data_size) { int ret = 0; - int try = 0; AW_LOGI("enter"); mutex_lock(&g_dsp_lock); - while (try < AW_DSP_TRY_TIME) { - if (aw_check_dsp_ready()) { - ret = aw_send_afe_cal_apr(param_id, data, - data_size, true); - mutex_unlock(&g_dsp_lock); - return ret; - } else { - try++; - msleep(AW_DSP_SLEEP_TIME); - AW_LOGD("afe not ready try again"); - } - } + aw_check_dsp_ready(); + ret = aw_send_afe_cal_apr(param_id, data, + data_size, true); mutex_unlock(&g_dsp_lock); - - return -EINVAL; + return ret; } static int aw_qcom_read_data_from_dsp(int32_t param_id, void *data, int data_size) { int ret = 0; - int try = 0; AW_LOGI("enter"); - mutex_lock(&g_dsp_lock); - while (try < AW_DSP_TRY_TIME) { - if (aw_check_dsp_ready()) { - ret = aw_send_afe_cal_apr(param_id, data, - data_size, false); - mutex_unlock(&g_dsp_lock); - return ret; - } else { - try++; - msleep(AW_DSP_SLEEP_TIME); - AW_LOGD("afe not ready try again"); - } - } + aw_check_dsp_ready(); + ret = aw_send_afe_cal_apr(param_id, data, + data_size, false); mutex_unlock(&g_dsp_lock); - - return -EINVAL; + return ret; } #endif /*****************qcom dsp communication function end*********************/ -int aw_dsp_get_rx_module_enable(int *enable) +/*****************read/write msg communication function*********************/ +static int aw_write_data_to_dsp(int32_t param_id, void *data, int data_size) { - int ret = 0; +#if defined AW_QCOM_OPEN_DSP_PLATFORM + return aw_qcom_write_data_to_dsp(param_id, data, data_size); +#elif defined AW_MTK_OPEN_DSP_PLATFORM + return aw_mtk_write_data_to_dsp(param_id, data, data_size); +#else + return -EINVAL; +#endif +} +static int aw_read_data_from_dsp(int32_t param_id, void *data, int data_size) +{ +#if defined AW_QCOM_OPEN_DSP_PLATFORM + return aw_qcom_read_data_from_dsp(param_id, data, data_size); +#elif defined AW_MTK_OPEN_DSP_PLATFORM + return aw_mtk_read_data_from_dsp(param_id, data, data_size); +#else + return -EINVAL; +#endif +} + +/***************read/write msg communication function end*******************/ + +int aw87xxx_dsp_get_rx_module_enable(int *enable) +{ if (!enable) { AW_LOGE("enable is NULL"); return -EINVAL; } -#ifdef AW_QCOM_OPEN_DSP_PLATFORM - ret = aw_qcom_read_data_from_dsp(AWDSP_RX_SET_ENABLE, + return aw_read_data_from_dsp(AWDSP_RX_SET_ENABLE, (void *)enable, sizeof(uint32_t)); -#elif defined AW_MTK_OPEN_DSP_PLATFORM - ret = aw_mtk_read_data_from_dsp(AWDSP_RX_SET_ENABLE, - (void *)enable, sizeof(uint32_t)); -#endif - - return ret; } -int aw_dsp_set_rx_module_enable(int enable) +int aw87xxx_dsp_set_rx_module_enable(int enable) { - int ret = 0; - switch (enable) { case AW_RX_MODULE_DISENABLE: AW_LOGD("set enable=%d", enable); @@ -245,21 +222,13 @@ int aw_dsp_set_rx_module_enable(int enable) return -EINVAL; } -#ifdef AW_QCOM_OPEN_DSP_PLATFORM - ret = aw_qcom_write_data_to_dsp(AWDSP_RX_SET_ENABLE, + return aw_write_data_to_dsp(AWDSP_RX_SET_ENABLE, &enable, sizeof(uint32_t)); -#elif defined AW_MTK_OPEN_DSP_PLATFORM - ret = aw_mtk_write_data_to_dsp(AWDSP_RX_SET_ENABLE, - &enable, sizeof(uint32_t)); -#endif - - return ret; } -int aw_dsp_get_vmax(uint32_t *vmax, int dev_index) +int aw87xxx_dsp_get_vmax(uint32_t *vmax, int dev_index) { - int ret = 0; int32_t param_id = 0; switch (dev_index % AW_DSP_CHANNEL_MAX) { @@ -274,40 +243,120 @@ int aw_dsp_get_vmax(uint32_t *vmax, int dev_index) dev_index); return -EINVAL; } -#ifdef AW_QCOM_OPEN_DSP_PLATFORM - ret = aw_qcom_read_data_from_dsp(param_id, - (void *)vmax, sizeof(uint32_t)); -#elif defined AW_MTK_OPEN_DSP_PLATFORM - ret = aw_mtk_read_data_from_dsp(param_id, - (void *)vmax, sizeof(uint32_t)); -#endif - return ret; + return aw_read_data_from_dsp(param_id, + (void *)vmax, sizeof(uint32_t)); } -int aw_dsp_set_vmax(uint32_t vmax, int dev_index) +int aw87xxx_dsp_set_vmax(uint32_t vmax, int dev_index) +{ + int32_t param_id = 0; + + switch (dev_index % AW_DSP_CHANNEL_MAX) { + case AW_DSP_CHANNEL_0: + param_id = AWDSP_RX_VMAX_0; + break; + case AW_DSP_CHANNEL_1: + param_id = AWDSP_RX_VMAX_1; + break; + default: + AW_LOGE("algo only support double PA channel:%d unsupport", + dev_index); + return -EINVAL; + } + + return aw_write_data_to_dsp(param_id, &vmax, sizeof(uint32_t)); +} + +int aw87xxx_dsp_set_spin(uint32_t ctrl_value) { int ret = 0; - int32_t param_id = 0; - switch (dev_index % AW_DSP_CHANNEL_MAX) { - case AW_DSP_CHANNEL_0: - param_id = AWDSP_RX_VMAX_0; - break; - case AW_DSP_CHANNEL_1: - param_id = AWDSP_RX_VMAX_1; - break; - default: - AW_LOGE("algo only support double PA channel:%d unsupport", - dev_index); + if (ctrl_value >= AW_SPIN_MAX) { + AW_LOGE("spin [%d] unsupported ", ctrl_value); return -EINVAL; } -#ifdef AW_QCOM_OPEN_DSP_PLATFORM - ret = aw_qcom_write_data_to_dsp(param_id, &vmax, sizeof(uint32_t)); -#elif defined AW_MTK_OPEN_DSP_PLATFORM - ret = aw_mtk_write_data_to_dsp(param_id, &vmax, sizeof(uint32_t)); -#endif + ret = aw_write_data_to_dsp(AW_MSG_ID_SPIN, &ctrl_value, + sizeof(uint32_t)); + if (ret) { + AW_LOGE("spin [%d] set failed ", ctrl_value); + return ret; + } + + g_spin_value = ctrl_value; + return 0; +} + +int aw87xxx_dsp_get_spin(void) +{ + return g_spin_value; +} + +int aw87xxx_spin_set_record_val(void) +{ + AW_LOGD("record write spin enter"); + + return aw87xxx_dsp_set_spin(g_spin_value); +} +EXPORT_SYMBOL(aw87xxx_spin_set_record_val); + +#ifdef AW_ALGO_AUTH_DSP +int aw87xxx_dsp_get_algo_auth_data(struct aw_device *aw_dev, + char *data, unsigned int data_len) +{ + int ret = 0; + + ret = aw_read_data_from_dsp(AW_MSG_ID_ALGO_AUTHENTICATION, data, data_len); + if (ret) { + AW_DEV_LOGE(aw_dev->dev, "read algo auth failed"); + return ret; + } + + AW_DEV_LOGD(aw_dev->dev, "get algo auth data done"); return ret; } +int aw87xxx_dsp_set_algo_auth_data(struct aw_device *aw_dev, + char *data, unsigned int data_len) +{ + int ret = 0; + + ret = aw_write_data_to_dsp(AW_MSG_ID_ALGO_AUTHENTICATION, data, data_len); + if (ret) { + AW_DEV_LOGE(aw_dev->dev, "write algo auth failed "); + return ret; + } + AW_DEV_LOGD(aw_dev->dev, "set algo auth done"); + + return ret; +} +#endif + +void aw87xxx_device_parse_topo_id_dt(struct aw_device *aw_dev) +{ + int ret; + + ret = of_property_read_u32(aw_dev->dev->of_node, "aw-rx-topo-id", &g_rx_topo_id); + if (ret < 0) { + g_rx_topo_id = AW_RX_DEFAULT_TOPO_ID; + AW_DEV_LOGI(aw_dev->dev, "read aw-rx-topo-id failed,use default"); + } + + AW_DEV_LOGI(aw_dev->dev, "rx-topo-id: 0x%x", g_rx_topo_id); +} + +void aw87xxx_device_parse_port_id_dt(struct aw_device *aw_dev) +{ + int ret; + + ret = of_property_read_u32(aw_dev->dev->of_node, "aw-rx-port-id", &g_rx_port_id); + if (ret < 0) { + g_rx_port_id = AW_RX_DEFAULT_PORT_ID; + AW_DEV_LOGI(aw_dev->dev, "read aw-rx-port-id failed,use default"); + } + + aw_set_port_id(g_rx_port_id); + AW_DEV_LOGI(aw_dev->dev, "rx-port-id: 0x%x", g_rx_port_id); +} + diff --git a/sound/soc/codecs/aw87xxx/aw_dsp.h b/sound/soc/codecs/aw87xxx/aw_dsp.h index 823a77f9bfc2..bfcdb0a59846 100644 --- a/sound/soc/codecs/aw87xxx/aw_dsp.h +++ b/sound/soc/codecs/aw87xxx/aw_dsp.h @@ -1,22 +1,47 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ +/* SPDX-License-Identifier: GPL-2.0 + * aw87xxx_dsp.h + * + * Copyright (c) 2021 AWINIC Technology CO., LTD + * + * Author: Barry + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ -#ifndef __AW_DSP_H__ -#define __AW_DSP_H__ +#ifndef __AW87XXX_DSP_H__ +#define __AW87XXX_DSP_H__ + +#include "aw_device.h" /*#define AW_MTK_OPEN_DSP_PLATFORM*/ /*#define AW_QCOM_OPEN_DSP_PLATFORM*/ /*Note: The pord_ID is configured according to different platforms*/ -#define AFE_PORT_ID_AWDSP_RX (0x4000) -#define AW_DSP_TRY_TIME (3) #define AW_DSP_SLEEP_TIME (10) #define AW_DSP_MSG_HDR_VER (1) +#define AW_RX_DEFAULT_TOPO_ID (0x1000FF01) +#define AW_RX_DEFAULT_PORT_ID (0x4000) + #define AWDSP_RX_SET_ENABLE (0x10013D11) #define AWDSP_RX_PARAMS (0x10013D12) #define AWDSP_RX_VMAX_0 (0X10013D17) #define AWDSP_RX_VMAX_1 (0X10013D18) +#define AW_MSG_ID_SPIN (0x10013D2E) +#define AW_MSG_ID_ALGO_AUTHENTICATION (0x10013D46) + + +enum { + AW_SPIN_0 = 0, + AW_SPIN_90, + AW_SPIN_180, + AW_SPIN_270, + AW_SPIN_MAX, +}; typedef struct mtk_dsp_msg_header { int32_t type; @@ -41,10 +66,19 @@ enum aw_dsp_channel { AW_DSP_CHANNEL_MAX, }; -uint8_t aw_dsp_isEnable(void); -int aw_dsp_get_rx_module_enable(int *enable); -int aw_dsp_set_rx_module_enable(int enable); -int aw_dsp_get_vmax(uint32_t *vmax, int channel); -int aw_dsp_set_vmax(uint32_t vmax, int channel); +uint8_t aw87xxx_dsp_isEnable(void); +int aw87xxx_dsp_get_rx_module_enable(int *enable); +int aw87xxx_dsp_set_rx_module_enable(int enable); +int aw87xxx_dsp_get_vmax(uint32_t *vmax, int channel); +int aw87xxx_dsp_set_vmax(uint32_t vmax, int channel); +int aw87xxx_dsp_set_spin(uint32_t ctrl_value); +int aw87xxx_dsp_get_spin(void); +int aw87xxx_spin_set_record_val(void); +void aw87xxx_device_parse_port_id_dt(struct aw_device *aw_dev); +void aw87xxx_device_parse_topo_id_dt(struct aw_device *aw_dev); +#ifdef AW_ALGO_AUTH_DSP +int aw87xxx_dsp_get_algo_auth_data(struct aw_device *aw_dev, char *data, unsigned int data_len); +int aw87xxx_dsp_set_algo_auth_data(struct aw_device *aw_dev, char *data, unsigned int data_len); +#endif #endif diff --git a/sound/soc/codecs/aw87xxx/aw_log.h b/sound/soc/codecs/aw87xxx/aw_log.h index f8dd9a174594..ac9f53e58dcd 100644 --- a/sound/soc/codecs/aw87xxx/aw_log.h +++ b/sound/soc/codecs/aw87xxx/aw_log.h @@ -1,7 +1,18 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ +/* SPDX-License-Identifier: GPL-2.0 + * aw87xxx_log.h + * + * Copyright (c) 2021 AWINIC Technology CO., LTD + * + * Author: Barry + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ -#ifndef __AW_LOG_H__ -#define __AW_LOG_H__ +#ifndef __AW87XXX_LOG_H__ +#define __AW87XXX_LOG_H__ #include diff --git a/sound/soc/codecs/aw87xxx/aw_monitor.c b/sound/soc/codecs/aw87xxx/aw_monitor.c index 80f4cab80750..61fbb40fa9ae 100644 --- a/sound/soc/codecs/aw87xxx/aw_monitor.c +++ b/sound/soc/codecs/aw87xxx/aw_monitor.c @@ -1,5 +1,5 @@ -/* - * aw_monitor.c +// SPDX-License-Identifier: GPL-2.0 +/* aw87xxx_monitor.c * * Copyright (c) 2021 AWINIC Technology CO., LTD * @@ -46,6 +46,8 @@ #define AW_MONITOT_BIN_PARSE_VERSION "V0.1.0" +#define AW87XXX_MONITOR_NAME "awinic_monitor.bin" + #define AW_GET_32_DATA(w, x, y, z) \ ((uint32_t)((((uint8_t)w) << 24) | (((uint8_t)x) << 16) | \ (((uint8_t)y) << 8) | ((uint8_t)z))) @@ -55,8 +57,33 @@ * aw87xxx monitor bin check * ****************************************************************************/ + +static int aw_monitor_get_ctrl_info(struct device *dev, uint32_t *switch_ctrl, uint32_t *count, + uint32_t *time) +{ + struct aw87xxx *aw87xxx = dev_get_drvdata(dev); + struct aw_monitor *monitor = &aw87xxx->monitor; + + switch (monitor->version) { + case DATA_VERSION_V1: + *time = monitor->monitor_hdr.monitor_time; + *count = monitor->monitor_hdr.monitor_count; + *switch_ctrl = monitor->monitor_hdr.monitor_switch; + break; + case AW_MONITOR_HDR_VER_0_1_2: + *time = monitor->monitor_cfg.monitor_time; + *count = monitor->monitor_cfg.monitor_count; + *switch_ctrl = monitor->monitor_cfg.monitor_switch; + break; + default: + return -EINVAL; + } + + return 0; +} + static int aw_monitor_check_header_v_1_0_0(struct device *dev, - char *data, uint32_t data_len) + const char *data, uint32_t data_len) { int i = 0; struct aw_bin_header *header = (struct aw_bin_header *)data; @@ -89,7 +116,7 @@ static int aw_monitor_check_header_v_1_0_0(struct device *dev, } static int aw_monitor_check_data_v1_size(struct device *dev, - char *data, int32_t data_len) + const char *data, int32_t data_len) { int32_t bin_header_len = sizeof(struct aw_bin_header); int32_t monitor_header_len = sizeof(struct aw_monitor_header); @@ -117,7 +144,7 @@ static int aw_monitor_check_data_v1_size(struct device *dev, } static int aw_monitor_check_data_size(struct device *dev, - char *data, int32_t data_len) + const char *data, int32_t data_len) { int ret = -1; struct aw_bin_header *header = (struct aw_bin_header *)data; @@ -139,7 +166,7 @@ static int aw_monitor_check_data_size(struct device *dev, static int aw_monitor_check_bin_header(struct device *dev, - char *data, int32_t data_len) + const char *data, int32_t data_len) { int ret = -1; struct aw_bin_header *header = NULL; @@ -168,7 +195,7 @@ static int aw_monitor_check_bin_header(struct device *dev, } static int aw_monitor_bin_check_sum(struct device *dev, - char *data, int32_t data_len) + const char *data, int32_t data_len) { int i, data_sum = 0; uint32_t *check_sum = (uint32_t *)data; @@ -188,7 +215,7 @@ static int aw_monitor_bin_check_sum(struct device *dev, } static int aw_monitor_bin_check(struct device *dev, - char *monitor_data, uint32_t data_len) + const char *monitor_data, uint32_t data_len) { int ret = -1; @@ -225,7 +252,7 @@ static int aw_monitor_bin_check(struct device *dev, *****************************************************************************/ static void aw_monitor_write_to_table_v1(struct device *dev, struct vmax_step_config *vmax_step, - char *vmax_data, uint32_t step_count) + const char *vmax_data, uint32_t step_count) { int i = 0; int index = 0; @@ -258,10 +285,10 @@ static void aw_monitor_write_to_table_v1(struct device *dev, } static int aw_monitor_parse_vol_data_v1(struct device *dev, - struct aw_monitor *monitor, char *monitor_data) + struct aw_monitor *monitor, const char *monitor_data) { uint32_t step_count = 0; - char *vmax_data = NULL; + const char *vmax_data = NULL; struct vmax_step_config *vmax_step = NULL; AW_DEV_LOGD(dev, "enter"); @@ -289,7 +316,7 @@ static int aw_monitor_parse_vol_data_v1(struct device *dev, } static int aw_monitor_parse_data_v1(struct device *dev, - struct aw_monitor *monitor, char *monitor_data) + struct aw_monitor *monitor, const char *monitor_data) { int ret = -1; int header_len = 0; @@ -315,8 +342,8 @@ static int aw_monitor_parse_data_v1(struct device *dev, } -static int aw_monitor_parse_v_1_0_0(struct device *dev, - struct aw_monitor *monitor, char *monitor_data) +static int aw_monitor_parse_v_0_0_1(struct device *dev, + struct aw_monitor *monitor, const char *monitor_data) { int ret = -1; struct aw_bin_header *header = (struct aw_bin_header *)monitor_data; @@ -334,7 +361,7 @@ static int aw_monitor_parse_v_1_0_0(struct device *dev, return 0; } -void aw_monitor_cfg_free(struct aw_monitor *monitor) +static void aw_monitor_cfg_v_0_0_1_free(struct aw_monitor *monitor) { struct aw87xxx *aw87xxx = container_of(monitor, struct aw87xxx, monitor); @@ -348,13 +375,279 @@ void aw_monitor_cfg_free(struct aw_monitor *monitor) } } -int aw_monitor_bin_parse(struct device *dev, - char *monitor_data, uint32_t data_len) +static void aw_monitor_write_data_to_table(struct device *dev, + struct aw_table_info *table_info, const char *offset_ptr) +{ + int i = 0; + int table_size = AW_TABLE_SIZE; + + for (i = 0; i < (int)(table_info->table_num * table_size); i += table_size) { + table_info->aw_table[i / AW_TABLE_SIZE].min_val = + AW_GET_16_DATA(offset_ptr[1 + i], offset_ptr[i]); + table_info->aw_table[i / AW_TABLE_SIZE].max_val = + AW_GET_16_DATA(offset_ptr[3 + i], offset_ptr[2 + i]); + table_info->aw_table[i / AW_TABLE_SIZE].ipeak = + AW_GET_16_DATA(offset_ptr[5 + i], offset_ptr[4 + i]); + table_info->aw_table[i / AW_TABLE_SIZE].gain = + AW_GET_16_DATA(offset_ptr[7 + i], offset_ptr[6 + i]); + table_info->aw_table[i / AW_TABLE_SIZE].vmax = + AW_GET_32_DATA(offset_ptr[11 + i], offset_ptr[10 + i], + offset_ptr[9 + i], offset_ptr[8 + i]); + } + + for (i = 0; i < table_info->table_num; i++) + AW_DEV_LOGI(dev, + "min_val:%d, max_val:%d, ipeak:0x%x, gain:0x%x, vmax:0x%x", + table_info->aw_table[i].min_val, + table_info->aw_table[i].max_val, + table_info->aw_table[i].ipeak, + table_info->aw_table[i].gain, + table_info->aw_table[i].vmax); + +} + +static int aw_monitor_parse_vol_data_v_0_1_2(struct device *dev, const uint8_t *data) +{ + struct aw_monitor_hdr *monitor_hdr = + (struct aw_monitor_hdr *)data; + struct aw87xxx *aw87xxx = dev_get_drvdata(dev); + struct aw_monitor_cfg *monitor_cfg = &aw87xxx->monitor.monitor_cfg; + struct aw_table_info *vol_info = &monitor_cfg->vol_info; + + AW_DEV_LOGI(dev, "===parse vol start ==="); + if (vol_info->aw_table != NULL) { + devm_kfree(dev, vol_info->aw_table); + vol_info->aw_table = NULL; + } + + vol_info->aw_table = devm_kzalloc(dev, + (monitor_hdr->vol_num * AW_TABLE_SIZE), + GFP_KERNEL); + if (vol_info->aw_table == NULL) + return -ENOMEM; + + vol_info->table_num = monitor_hdr->vol_num; + aw_monitor_write_data_to_table(dev, vol_info, + &data[monitor_hdr->vol_offset]); + AW_DEV_LOGI(dev, "===parse vol end ==="); + return 0; +} + +static int aw_monitor_parse_temp_data_v_0_1_2(struct device *dev, const uint8_t *data) +{ + struct aw_monitor_hdr *monitor_hdr = + (struct aw_monitor_hdr *)data; + struct aw87xxx *aw87xxx = dev_get_drvdata(dev); + struct aw_monitor_cfg *monitor_cfg = &aw87xxx->monitor.monitor_cfg; + struct aw_table_info *temp_info = &monitor_cfg->temp_info; + + AW_DEV_LOGI(dev, "===parse temp start ==="); + + if (temp_info->aw_table != NULL) { + devm_kfree(dev, temp_info->aw_table); + temp_info->aw_table = NULL; + } + + temp_info->aw_table = devm_kzalloc(dev, + (monitor_hdr->temp_num * AW_TABLE_SIZE), + GFP_KERNEL); + if (temp_info->aw_table == NULL) + return -ENOMEM; + + temp_info->table_num = monitor_hdr->temp_num; + aw_monitor_write_data_to_table(dev, temp_info, + &data[monitor_hdr->temp_offset]); + AW_DEV_LOGI(dev, "===parse temp end ==="); + return 0; +} + +static void aw_monitor_parse_hdr_v_0_1_2(struct device *dev, const uint8_t *data) +{ + struct aw_monitor_hdr *monitor_hdr = + (struct aw_monitor_hdr *)data; + struct aw87xxx *aw87xxx = dev_get_drvdata(dev); + struct aw_monitor_cfg *monitor_cfg = &aw87xxx->monitor.monitor_cfg; + + monitor_cfg->monitor_switch = + (monitor_hdr->enable_flag >> MONITOR_EN_BIT) & MONITOR_EN_MASK; + monitor_cfg->monitor_time = monitor_hdr->monitor_time; + monitor_cfg->monitor_count = monitor_hdr->monitor_count; + monitor_cfg->ipeak_switch = + (monitor_hdr->enable_flag >> MONITOR_IPEAK_EN_BIT) & MONITOR_EN_MASK; + monitor_cfg->logic_switch = + (monitor_hdr->enable_flag >> MONITOR_LOGIC_BIT) & MONITOR_EN_MASK; + monitor_cfg->gain_switch = + (monitor_hdr->enable_flag >> MONITOR_GAIN_EN_BIT) & MONITOR_EN_MASK; + monitor_cfg->vmax_switch = + (monitor_hdr->enable_flag >> MONITOR_VMAX_EN_BIT) & MONITOR_EN_MASK; + monitor_cfg->temp_switch = + (monitor_hdr->enable_flag >> MONITOR_TEMP_EN_BIT) & MONITOR_EN_MASK; + monitor_cfg->temp_aplha = monitor_hdr->temp_aplha; + monitor_cfg->vol_switch = + (monitor_hdr->enable_flag >> MONITOR_VOL_EN_BIT) & MONITOR_EN_MASK; + monitor_cfg->vol_aplha = monitor_hdr->vol_aplha; + monitor_cfg->temp_source = + (monitor_hdr->enable_flag >> MONITOR_TEMPERATURE_SOURCE_BIT) & MONITOR_EN_MASK; + monitor_cfg->vol_source = + (monitor_hdr->enable_flag >> MONITOR_VOLTAGE_SOURCE_BIT) & MONITOR_EN_MASK; + monitor_cfg->vol_mode = + (monitor_hdr->enable_flag >> MONITOR_VOLTAGE_MODE_BIT) & MONITOR_EN_MASK; + + AW_DEV_LOGI(dev, "chip name:%s", monitor_hdr->chip_type); + AW_DEV_LOGI(dev, "ui ver:0x%x", monitor_hdr->ui_ver); + + AW_DEV_LOGI(dev, + "voltage mode:%d, voltage source:%d , temperature source:%d", + monitor_cfg->vol_mode, monitor_cfg->vol_source, + monitor_cfg->temp_source); + + AW_DEV_LOGI(dev, + "monitor_switch:%d, monitor_time:%d (ms), monitor_count:%d", + monitor_cfg->monitor_switch, monitor_cfg->monitor_time, + monitor_cfg->monitor_count); + + AW_DEV_LOGI(dev, + "logic_switch:%d, ipeak_switch:%d, gain_switch:%d, vmax_switch:%d", + monitor_cfg->logic_switch, monitor_cfg->ipeak_switch, + monitor_cfg->gain_switch, monitor_cfg->vmax_switch); + + AW_DEV_LOGI(dev, + "temp_switch:%d, temp_aplha:%d, vol_switch:%d, vol_aplha:%d", + monitor_cfg->temp_switch, monitor_cfg->temp_aplha, + monitor_cfg->vol_switch, monitor_cfg->vol_aplha); +} + +static int aw_monitor_check_fw_v_0_1_2(struct device *dev, + const uint8_t *data, uint32_t data_len) +{ + struct aw_monitor_hdr *monitor_hdr = + (struct aw_monitor_hdr *)data; + uint32_t temp_size = 0; + uint32_t vol_size = 0; + + if (data_len < sizeof(struct aw_monitor_hdr)) { + AW_DEV_LOGE(dev, + "params size[%d] < struct aw_monitor_hdr size[%d]!", + data_len, (int)sizeof(struct aw_monitor_hdr)); + return -ENOMEM; + } + + if (monitor_hdr->temp_offset > data_len) { + AW_DEV_LOGE(dev, "temp_offset[%d] overflow file size[%d]!", + monitor_hdr->temp_offset, data_len); + return -ENOMEM; + } + + if (monitor_hdr->vol_offset > data_len) { + AW_DEV_LOGE(dev, "vol_offset[%d] overflow file size[%d]!", + monitor_hdr->vol_offset, data_len); + return -ENOMEM; + } + + temp_size = (uint32_t)(monitor_hdr->temp_num * monitor_hdr->single_temp_size); + if (temp_size > data_len) { + AW_DEV_LOGE(dev, "temp_size:[%d] overflow file size[%d]!", + temp_size, data_len); + return -ENOMEM; + } + + vol_size = (uint32_t)(monitor_hdr->vol_num * monitor_hdr->single_vol_size); + if (vol_size > data_len) { + AW_DEV_LOGE(dev, "vol_size:[%d] overflow file size[%d]!", + vol_size, data_len); + return -ENOMEM; + } + + return 0; +} + +static int aw_monitor_parse_data_v_0_1_2(struct device *dev, + const uint8_t *data, uint32_t data_len) +{ + int ret = -1; + struct aw87xxx *aw87xxx = dev_get_drvdata(dev); + struct aw_monitor *monitor = &aw87xxx->monitor; + + ret = aw_monitor_check_fw_v_0_1_2(dev, data, data_len); + if (ret < 0) { + AW_DEV_LOGE(dev, "check monitor failed"); + return ret; + } + + aw_monitor_parse_hdr_v_0_1_2(dev, data); + + ret = aw_monitor_parse_temp_data_v_0_1_2(dev, data); + if (ret < 0) + return ret; + + ret = aw_monitor_parse_vol_data_v_0_1_2(dev, data); + if (ret < 0) + return ret; + + monitor->bin_status = AW_MONITOR_CFG_OK; + + return 0; +} + +static int aw_monitor_param_check_sum(struct device *dev, + const uint8_t *data, uint32_t data_len) +{ + int i = 0, check_sum = 0; + struct aw_monitor_hdr *monitor_hdr = + (struct aw_monitor_hdr *)data; + + if (data_len < sizeof(struct aw_monitor_hdr)) { + AW_DEV_LOGE(dev, + "data size smaller than hdr , please check monitor bin"); + return -ENOMEM; + } + + for (i = 4 ; i < data_len; i++) + check_sum += (uint8_t)data[i]; + + if (monitor_hdr->check_sum != check_sum) { + AW_DEV_LOGE(dev, + "check_sum[%d] is not equal to actual check_sum[%d]", + monitor_hdr->check_sum, check_sum); + return -ENOMEM; + } + + return 0; +} + +static int aw87xxx_monitor_bin_version_parse(struct device *dev, const char *monitor_data) +{ + struct aw_bin_header *bin_header = NULL; + struct aw_monitor_hdr *monitor_hdr = NULL; + + bin_header = (struct aw_bin_header *)monitor_data; + switch (bin_header->bin_data_ver) { + case DATA_VERSION_V1: + return DATA_VERSION_V1; + default: + AW_DEV_LOGE(dev, "DATA_VERSION_V1 version Mismatched"); + } + + monitor_hdr = (struct aw_monitor_hdr *)monitor_data; + switch (monitor_hdr->monitor_ver) { + case AW_MONITOR_HDR_VER_0_1_2: + return AW_MONITOR_HDR_VER_0_1_2; + default: + AW_DEV_LOGE(dev, "HDR_VER_0_1_2 version Mismatched"); + } + + AW_DEV_LOGE(dev, "unsupported monitor_hdr"); + + return -EINVAL; +} + +int aw87xxx_monitor_bin_parse(struct device *dev, + const char *monitor_data, uint32_t data_len) { int ret = -1; struct aw87xxx *aw87xxx = dev_get_drvdata(dev); struct aw_monitor *monitor = NULL; - struct aw_bin_header *bin_header = NULL; + struct aw_container *monitor_container = NULL; if (aw87xxx == NULL) { AW_DEV_LOGE(dev, "get struct aw87xxx failed"); @@ -364,28 +657,60 @@ int aw_monitor_bin_parse(struct device *dev, monitor = &aw87xxx->monitor; monitor->bin_status = AW_MONITOR_CFG_WAIT; - AW_DEV_LOGI(dev, "monitor bin parse version: %s", - AW_MONITOT_BIN_PARSE_VERSION); - + ret = aw87xxx_monitor_bin_version_parse(dev, monitor_data); + switch (ret) { + case DATA_VERSION_V1: + AW_DEV_LOGD(dev, "DATA_VERSION_V1 enter"); ret = aw_monitor_bin_check(dev, monitor_data, data_len); if (ret < 0) { AW_DEV_LOGE(dev, "monitor bin check failed"); return ret; } - bin_header = (struct aw_bin_header *)monitor_data; - switch (bin_header->bin_data_ver) { - case DATA_VERSION_V1: - ret = aw_monitor_parse_v_1_0_0(dev, monitor, + ret = aw_monitor_parse_v_0_0_1(dev, monitor, monitor_data); if (ret < 0) { - aw_monitor_cfg_free(monitor); + aw_monitor_cfg_v_0_0_1_free(monitor); return ret; } + monitor->version = DATA_VERSION_V1; + break; + case AW_MONITOR_HDR_VER_0_1_2: + AW_DEV_LOGD(dev, "AW_MONITOR_HDR_VER_0_1_2 enter"); + + monitor_container = devm_kzalloc(dev, + data_len + sizeof(uint32_t), GFP_KERNEL); + if (monitor_container == NULL) + return -ENOMEM; + + if (monitor->monitor_container) { + devm_kfree(dev, monitor->monitor_container); + monitor->monitor_container = NULL; + } + + monitor->monitor_container = monitor_container; + monitor_container->len = data_len; + memcpy(monitor_container->data, monitor_data, data_len); + + if (monitor_container == NULL) + AW_DEV_LOGE(dev, "monitor_container not null"); + else + AW_DEV_LOGE(dev, "len %d ", monitor_container->len); + + ret = aw_monitor_param_check_sum(dev, monitor_data, data_len); + if (ret < 0) { + AW_DEV_LOGE(dev, "monitor bin check failed"); + return ret; + } + + ret = aw_monitor_parse_data_v_0_1_2(dev, monitor_data, data_len); + if (ret < 0) + return ret; + monitor->version = AW_MONITOR_HDR_VER_0_1_2; break; default: AW_DEV_LOGE(dev, "Unrecognized this bin data version[0x%x]", - bin_header->bin_data_ver); + ret); } return 0; @@ -396,9 +721,8 @@ int aw_monitor_bin_parse(struct device *dev, * aw87xxx monitor get adjustment vmax of power * ***************************************************************************/ -static int aw_monitor_get_battery_capacity(struct device *dev, - struct aw_monitor *monitor, - uint32_t *vbat_capacity) +static int aw_monitor_get_battery_status(struct device *dev, + int type, int *value) { char name[] = "battery"; int ret = -1; @@ -407,18 +731,133 @@ static int aw_monitor_get_battery_capacity(struct device *dev, psy = power_supply_get_by_name(name); if (psy == NULL) { - //AW_DEV_LOGE(dev, "no struct power supply name:%s", name); + AW_DEV_LOGE(dev, "no struct power supply name:%s", name); return -EINVAL; } - ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_CAPACITY, &prop); + ret = power_supply_get_property(psy, type, &prop); if (ret < 0) { - //AW_DEV_LOGE(dev, "get vbat capacity failed"); + AW_DEV_LOGE(dev, "get type:%d failed", type); + return -EINVAL; + } + + *value = prop.intval; + AW_DEV_LOGI(dev, "get type:%d value %d", + type, *value); + + return 0; +} + +static int aw_monitor_get_chip_temperature(struct device *dev, int *value) +{ + return 0; +} + +static int aw_monitor_get_chip_voltage(struct device *dev, int *value) +{ + return 0; +} + +static int aw_monitor_get_sys_temperature(struct device *dev, int *value) +{ + int ret = -1; + int temperature = 0; + + ret = aw_monitor_get_battery_status(dev, POWER_SUPPLY_PROP_TEMP, &temperature); + if (ret < 0) + return ret; + + *value = temperature / 10; + + AW_DEV_LOGI(dev, "sys temperature: %d", *value); + + return ret; +} + +static int aw_monitor_get_sys_voltage(struct device *dev, int *value) +{ + int ret = 0; + int voltage = 0; + + ret = aw_monitor_get_battery_status(dev, POWER_SUPPLY_PROP_VOLTAGE_NOW, &voltage); + if (ret < 0) + return ret; + + *value = voltage / 1000; + + AW_DEV_LOGI(dev, "sys voltage: %d", *value); + + return ret; +} + +static int aw_monitor_get_sys_capacity(struct device *dev, int *value) +{ + int ret = 0; + + ret = aw_monitor_get_battery_status(dev, POWER_SUPPLY_PROP_CAPACITY, value); + if (ret < 0) + return ret; + + AW_DEV_LOGI(dev, "sys capacity: %d", *value); + + return ret; +} + +static int aw_monitor_get_chip_runtime_info(struct device *dev, uint8_t info_type, int *value) +{ + switch (info_type) { + case AW_VOLTAGE_INFO: + aw_monitor_get_chip_voltage(dev, value); + break; + case AW_TEMPERATURE_INFO: + aw_monitor_get_chip_temperature(dev, value); + break; + default: + AW_DEV_LOGE(dev, "unsupported type: %d", info_type); + return -EINVAL; + } + + return 0; +} + +static int aw_monitor_get_sys_runtime_info(struct device *dev, uint8_t info_type, int *value) +{ + AW_DEV_LOGI(dev, "info_type: %s", (info_type == AW_TEMPERATURE_INFO) ? "temperature info" : + ((info_type == AW_VOLTAGE_INFO) ? "voltage info" : "capacity info")); + + switch (info_type) { + case AW_VOLTAGE_INFO: + aw_monitor_get_sys_voltage(dev, value); + break; + case AW_TEMPERATURE_INFO: + aw_monitor_get_sys_temperature(dev, value); + break; + case AW_CAPACITY_INFO: + aw_monitor_get_sys_capacity(dev, value); + break; + default: + AW_DEV_LOGE(dev, "unsupported type: %d", info_type); + return -EINVAL; + } + + return 0; +} + +static int aw_monitor_get_runtime_info(struct device *dev, uint8_t src_type, uint8_t info_type, int *value) +{ + AW_DEV_LOGI(dev, "source type: %s", src_type ? "platform info" : "chip info"); + + switch (src_type) { + case AW_CHIP_INFO: + aw_monitor_get_chip_runtime_info(dev, info_type, value); + break; + case AW_PLATFORM_INFO: + aw_monitor_get_sys_runtime_info(dev, info_type, value); + break; + default: + AW_DEV_LOGE(dev, "unsupported type: %d", info_type); return -EINVAL; } - *vbat_capacity = prop.intval; - //AW_DEV_LOGI(dev, "The percentage is %d", - // *vbat_capacity); return 0; } @@ -482,7 +921,7 @@ static int aw_chip_status_recover(struct aw87xxx *aw87xxx) AW_DEV_LOGD(aw87xxx->dev, "enter"); - ret = aw87xxx_esd_update_profile(aw87xxx, profile); + ret = aw87xxx_update_profile_esd(aw87xxx, profile); if (ret < 0) { AW_DEV_LOGE(aw87xxx->dev, "load profile[%s] failed ", profile); @@ -508,9 +947,10 @@ static int aw_monitor_chip_esd_check_work(struct aw87xxx *aw87xxx) for (i = 0; i < REG_STATUS_CHECK_MAX; i++) { AW_DEV_LOGD(aw87xxx->dev, "reg_status_check[%d]", i); - ret = aw_dev_esd_reg_status_check(&aw87xxx->aw_dev); + ret = aw87xxx_dev_esd_reg_status_check(&aw87xxx->aw_dev); if (ret < 0) { - aw_chip_status_recover(aw87xxx); + if (ret == -EINVAL) + aw_chip_status_recover(aw87xxx); } else { AW_DEV_LOGD(aw87xxx->dev, "chip status check succeed"); break; @@ -518,13 +958,7 @@ static int aw_monitor_chip_esd_check_work(struct aw87xxx *aw87xxx) msleep(AW_ESD_CHECK_DELAY); } - if (ret < 0) { - AW_DEV_LOGE(aw87xxx->dev, "chip status recover failed,chip off"); - aw87xxx_esd_update_profile(aw87xxx, aw87xxx->prof_off_name); - return ret; - } - - return 0; + return ret; } @@ -540,14 +974,14 @@ static int aw_monitor_update_vmax_to_dsp(struct device *dev, uint32_t enable = 0; if (monitor->pre_vmax != vmax_set) { - ret = aw_dsp_get_rx_module_enable(&enable); + ret = aw87xxx_dsp_get_rx_module_enable(&enable); if (!enable || ret < 0) { AW_DEV_LOGE(dev, "get rx failed or rx disable, ret=%d, enable=%d", ret, enable); return -EPERM; } - ret = aw_dsp_set_vmax(vmax_set, monitor->dev_index); + ret = aw87xxx_dsp_set_vmax(vmax_set, monitor->dev_index); if (ret) { AW_DEV_LOGE(dev, "set dsp msg fail, ret=%d", ret); return ret; @@ -567,13 +1001,13 @@ static void aw_monitor_with_dsp_vmax_work(struct device *dev, { int ret = -1; int vmax_set = 0; - uint32_t vbat_capacity = 0; - uint32_t ave_capacity = 0; + int vbat_capacity = 0; + int ave_capacity = 0; struct aw_monitor_header *monitor_hdr = &monitor->monitor_hdr; AW_DEV_LOGD(dev, "enter with dsp monitor"); - ret = aw_monitor_get_battery_capacity(dev, monitor, &vbat_capacity); + ret = aw_monitor_get_sys_capacity(dev, &vbat_capacity); if (ret < 0) return; @@ -606,6 +1040,307 @@ static void aw_monitor_with_dsp_vmax_work(struct device *dev, } } +static int aw_monitor_get_temp_and_vol(struct device *dev) +{ + struct aw87xxx *aw87xxx = dev_get_drvdata(dev); + struct aw_monitor *monitor = &aw87xxx->monitor; + unsigned int voltage = 0; + int current_temp = 0; + int ret = -1; + +#ifdef AW_DEBUG + if (monitor->test_vol == 0) { + ret = aw_monitor_get_runtime_info(dev, monitor->monitor_cfg.temp_source, + AW_VOLTAGE_INFO, &voltage); + if (ret < 0) + return ret; + } else { + voltage = monitor->test_vol; + } + + if (monitor->test_temp == 0) { + ret = aw_monitor_get_runtime_info(dev, monitor->monitor_cfg.temp_source, + AW_TEMPERATURE_INFO, ¤t_temp); + if (ret < 0) + return ret; + } else { + current_temp = monitor->test_temp; + } +#else + + ret = aw_monitor_get_runtime_info(dev, monitor->monitor_cfg.vol_source, + monitor->monitor_cfg.vol_mode, &voltage); + if (ret < 0) + return ret; + + ret = aw_monitor_get_runtime_info(dev, monitor->monitor_cfg.temp_source, + AW_TEMPERATURE_INFO, ¤t_temp); + if (ret < 0) + return ret; + +#endif + + monitor->vol_trace.sum_val += voltage; + monitor->temp_trace.sum_val += current_temp; + monitor->samp_count++; + + return 0; +} + +static int aw_monitor_first_get_data_form_table(struct device *dev, + struct aw_table_info table_info, + struct aw_monitor_trace *data_trace) +{ + int i = 0; + + if (table_info.aw_table == NULL) { + AW_DEV_LOGE(dev, "table_info.aw_table is null"); + return -EINVAL; + } + + for (i = 0; i < table_info.table_num; i++) { + if (data_trace->sum_val >= table_info.aw_table[i].min_val) { + memcpy(&data_trace->aw_table, &table_info.aw_table[i], + sizeof(struct aw_table)); + break; + } + } + return 0; +} + +static int aw_monitor_trace_data_from_table(struct device *dev, + struct aw_table_info table_info, + struct aw_monitor_trace *data_trace) +{ + int i = 0; + + if (table_info.aw_table == NULL) { + AW_DEV_LOGE(dev, "table_info.aw_table is null"); + return -EINVAL; + } + + for (i = 0; i < table_info.table_num; i++) { + if (data_trace->sum_val >= table_info.aw_table[i].min_val && + data_trace->sum_val <= table_info.aw_table[i].max_val) { + memcpy(&data_trace->aw_table, &table_info.aw_table[i], + sizeof(struct aw_table)); + break; + } + } + + return 0; +} + +static int aw_monitor_get_data_from_table(struct device *dev, + struct aw_table_info table_info, + struct aw_monitor_trace *data_trace, + uint32_t aplha) +{ + struct aw87xxx *aw87xxx = dev_get_drvdata(dev); + struct aw_monitor *monitor = &aw87xxx->monitor; + + if (monitor->first_entry == AW_FIRST_ENTRY) { + return aw_monitor_first_get_data_form_table(dev, + table_info, data_trace); + } else { + if (monitor->samp_count == 0) { + AW_DEV_LOGE(dev, "monitor->samp_count:%d unsupported", monitor->samp_count); + return -EINVAL; + } + + data_trace->sum_val = data_trace->sum_val / monitor->samp_count; + data_trace->sum_val = ((int32_t)aplha * data_trace->sum_val + + (1000 - (int32_t)aplha) * data_trace->pre_val) / 1000; + return aw_monitor_trace_data_from_table(dev, + table_info, data_trace); + } + + return 0; +} + +static int aw_monitor_get_data(struct device *dev) +{ + struct aw87xxx *aw87xxx = dev_get_drvdata(dev); + struct aw_monitor *monitor = &aw87xxx->monitor; + struct aw_monitor_cfg *monitor_cfg = &monitor->monitor_cfg; + struct aw_monitor_trace *vol_trace = &monitor->vol_trace; + struct aw_monitor_trace *temp_trace = &monitor->temp_trace; + int ret = -1; + + if (monitor_cfg->vol_switch) { + ret = aw_monitor_get_data_from_table(dev, + monitor_cfg->vol_info, vol_trace, + monitor_cfg->vol_aplha); + if (ret < 0) + return ret; + } else { + vol_trace->aw_table.ipeak = IPEAK_NONE; + vol_trace->aw_table.gain = GAIN_NONE; + vol_trace->aw_table.vmax = VMAX_NONE; + } + + if (monitor_cfg->temp_switch) { + ret = aw_monitor_get_data_from_table(dev, + monitor_cfg->temp_info, temp_trace, + monitor_cfg->temp_aplha); + if (ret < 0) + return ret; + } else { + temp_trace->aw_table.ipeak = IPEAK_NONE; + temp_trace->aw_table.gain = GAIN_NONE; + temp_trace->aw_table.vmax = VMAX_NONE; + } + + AW_DEV_LOGD(dev, + "filter_vol:%d, vol: ipeak = 0x%x, gain = 0x%x, vmax = 0x%x", + monitor->vol_trace.sum_val, vol_trace->aw_table.ipeak, + vol_trace->aw_table.gain, vol_trace->aw_table.vmax); + + AW_DEV_LOGD(dev, + "filter_temp:%d, temp: ipeak = 0x%x, gain = 0x%x, vmax = 0x%x", + monitor->temp_trace.sum_val, temp_trace->aw_table.ipeak, + temp_trace->aw_table.gain, temp_trace->aw_table.vmax); + return 0; +} + +static void aw_monitor_get_cfg(struct device *dev, + struct aw_table *set_table) +{ + struct aw87xxx *aw87xxx = dev_get_drvdata(dev); + struct aw_monitor *monitor = &aw87xxx->monitor; + struct aw_table *temp_data = &monitor->temp_trace.aw_table; + struct aw_table *vol_data = &monitor->vol_trace.aw_table; + + if (temp_data->ipeak == IPEAK_NONE && vol_data->ipeak == IPEAK_NONE) { + memcpy(set_table, temp_data, sizeof(struct aw_table)); + } else if (temp_data->ipeak == IPEAK_NONE) { + memcpy(set_table, vol_data, sizeof(struct aw_table)); + } else if (vol_data->ipeak == IPEAK_NONE) { + memcpy(set_table, temp_data, sizeof(struct aw_table)); + } else { + if (monitor->monitor_cfg.logic_switch == AW_MON_LOGIC_OR) { + set_table->ipeak = (temp_data->ipeak < vol_data->ipeak ? + temp_data->ipeak : vol_data->ipeak); + set_table->gain = (temp_data->gain < vol_data->gain ? + vol_data->gain : temp_data->gain); + set_table->vmax = (temp_data->vmax < vol_data->vmax ? + vol_data->vmax : temp_data->vmax); + } else { + set_table->ipeak = (temp_data->ipeak < vol_data->ipeak ? + vol_data->ipeak : temp_data->ipeak); + set_table->gain = (temp_data->gain < vol_data->gain ? + temp_data->gain : vol_data->gain); + set_table->vmax = (temp_data->vmax < vol_data->vmax ? + temp_data->vmax : vol_data->vmax); + } + } +} + +static void aw_monitor_set_ipeak(struct device *dev, + uint16_t ipeak) +{ + struct aw87xxx *aw87xxx = dev_get_drvdata(dev); + struct aw_monitor *monitor = &aw87xxx->monitor; + struct aw_monitor_cfg *monitor_cfg = &monitor->monitor_cfg; + uint8_t reg_val = 0; + uint8_t read_reg_val = 0; + int ret = -1; + struct aw_ipeak_desc *desc = &aw87xxx->aw_dev.ipeak_desc; + + if (desc->reg == AW_REG_NONE) + return; + + if (ipeak == IPEAK_NONE || (!monitor_cfg->ipeak_switch)) + return; + + ret = aw87xxx_dev_i2c_read_byte(&aw87xxx->aw_dev, desc->reg, ®_val); + if (ret < 0) { + AW_DEV_LOGE(dev, "read ipeak failed"); + return; + } + + read_reg_val = reg_val; + read_reg_val &= (~desc->mask); + + if (read_reg_val == ipeak) { + AW_DEV_LOGD(dev, "ipeak = 0x%x, no change", + read_reg_val); + return; + } + reg_val &= desc->mask; + read_reg_val = ipeak; + reg_val |= read_reg_val; + + ret = aw87xxx_dev_i2c_write_byte(&aw87xxx->aw_dev, desc->reg, reg_val); + if (ret < 0) { + AW_DEV_LOGE(dev, "write ipeak failed"); + return; + } + AW_DEV_LOGI(dev, "set reg val = 0x%x, ipeak = 0x%x", + reg_val, ipeak); + +} + +static void aw_monitor_set_gain(struct device *dev, uint16_t gain) +{ +} + +static void aw_monitor_set_vmax(struct device *dev, + uint32_t vmax) +{ + struct aw87xxx *aw87xxx = dev_get_drvdata(dev); + struct aw_monitor *monitor = &aw87xxx->monitor; + struct aw_monitor_cfg *monitor_cfg = &monitor->monitor_cfg; + + if (vmax == VMAX_NONE || (!monitor_cfg->vmax_switch)) + return; + + aw_monitor_update_vmax_to_dsp(dev, monitor, vmax); +} + +static void aw_monitor_with_dsp_work(struct device *dev) +{ + int ret = -1; + struct aw87xxx *aw87xxx = dev_get_drvdata(dev); + struct aw_monitor *monitor = &aw87xxx->monitor; + struct aw_table set_table; + + ret = aw_monitor_get_temp_and_vol(dev); + if (ret < 0) + return; + + if (monitor->samp_count < monitor->monitor_cfg.monitor_count && + (monitor->first_entry == AW_NOT_FIRST_ENTRY)) + return; + + ret = aw_monitor_get_data(dev); + if (ret < 0) + return; + + aw_monitor_get_cfg(dev, &set_table); + + AW_DEV_LOGD(dev, + "set_ipeak = 0x%x, set_gain = 0x%x, set_vmax = 0x%x", + set_table.ipeak, set_table.gain, set_table.vmax); + + aw_monitor_set_ipeak(dev, set_table.ipeak); + + aw_monitor_set_gain(dev, set_table.gain); + + aw_monitor_set_vmax(dev, set_table.vmax); + + monitor->samp_count = 0; + monitor->temp_trace.pre_val = monitor->temp_trace.sum_val; + monitor->temp_trace.sum_val = 0; + + monitor->vol_trace.pre_val = monitor->vol_trace.sum_val; + monitor->vol_trace.sum_val = 0; + + if (monitor->first_entry == AW_FIRST_ENTRY) + monitor->first_entry = AW_NOT_FIRST_ENTRY; + +} + static void aw_monitor_work_func(struct work_struct *work) { int ret = 0; @@ -613,31 +1348,55 @@ static void aw_monitor_work_func(struct work_struct *work) struct aw87xxx, monitor.with_dsp_work.work); struct device *dev = aw87xxx->dev; struct aw_monitor *monitor = &aw87xxx->monitor; - struct aw_monitor_header *monitor_hdr = &monitor->monitor_hdr; + uint32_t monitor_switch = 0; + uint32_t monitor_time = 0; + uint32_t monitor_count = 0; AW_DEV_LOGD(dev, "enter"); - if (monitor->esd_enable) { - ret = aw_monitor_chip_esd_check_work(aw87xxx); - if (ret < 0) - return; + pm_stay_awake(dev); + + if (!aw87xxx->is_suspend) { + if (monitor->esd_enable && + monitor->esd_err_cnt < AW_MONOTOR_ESD_ERR_CNT_MAX) { + ret = aw_monitor_chip_esd_check_work(aw87xxx); + if (ret < 0) { + aw87xxx->monitor.esd_err_cnt++; + AW_DEV_LOGI(dev, "esd check failed"); + } + } + + aw_monitor_get_ctrl_info(dev, &monitor_switch, + &monitor_count, &monitor_time); + + if (monitor_switch && !(aw87xxx->aw_dev.is_rec_mode) && + monitor->open_dsp_en && monitor->bin_status == AW_MONITOR_CFG_OK) { + AW_DEV_LOGD(dev, "monitor version 0x%x", monitor->version); + switch (monitor->version) { + case DATA_VERSION_V1: + aw_monitor_with_dsp_vmax_work(dev, monitor); + break; + case AW_MONITOR_HDR_VER_0_1_2: + aw_monitor_with_dsp_work(dev); + break; + default: + AW_DEV_LOGE(dev, "INVALID version:%d", monitor->version); + return; + } + } } - if (monitor_hdr->monitor_switch && !(aw87xxx->aw_dev.is_rec_mode) && - monitor->open_dsp_en && monitor->bin_status == AW_ACF_UPDATE) { - AW_DEV_LOGD(dev, "start low power protection"); - aw_monitor_with_dsp_vmax_work(dev, monitor); - } + pm_relax(dev); - if (monitor->esd_enable || (monitor_hdr->monitor_switch && + if (monitor->esd_enable || (monitor_switch && !(aw87xxx->aw_dev.is_rec_mode) && monitor->open_dsp_en && - monitor->bin_status == AW_ACF_UPDATE)) { + monitor->bin_status == AW_MONITOR_CFG_OK)) { schedule_delayed_work(&monitor->with_dsp_work, - msecs_to_jiffies(monitor_hdr->monitor_time)); + msecs_to_jiffies(monitor_time)); } } -void aw_monitor_stop(struct aw_monitor *monitor) +void aw87xxx_monitor_stop(struct aw_monitor *monitor) { struct aw87xxx *aw87xxx = container_of(monitor, struct aw87xxx, monitor); @@ -646,30 +1405,44 @@ void aw_monitor_stop(struct aw_monitor *monitor) cancel_delayed_work_sync(&monitor->with_dsp_work); } -void aw_monitor_start(struct aw_monitor *monitor) +void aw87xxx_monitor_start(struct aw_monitor *monitor) { struct aw87xxx *aw87xxx = container_of(monitor, struct aw87xxx, monitor); + uint32_t monitor_switch = 0; + uint32_t monitor_time = 0; + uint32_t monitor_count = 0; int ret = 0; - ret = aw_dev_check_reg_is_rec_mode(&aw87xxx->aw_dev); + ret = aw87xxx_dev_check_reg_is_rec_mode(&aw87xxx->aw_dev); if (ret < 0) { AW_DEV_LOGE(aw87xxx->dev, "get reg current mode failed"); return; } - if (monitor->esd_enable || (monitor->monitor_hdr.monitor_switch && + aw_monitor_get_ctrl_info(aw87xxx->dev, &monitor_switch, + &monitor_count, &monitor_time); + + AW_DEV_LOGI(aw87xxx->dev, + "esd_enable:%d, monitor_open_dsp_en:%d, is_rec_mode:%d", + monitor->esd_enable, monitor->open_dsp_en, aw87xxx->aw_dev.is_rec_mode); + AW_DEV_LOGI(aw87xxx->dev, + "monitor_switch:%d, monitor_count:%d, monitor_time:%d", + monitor_switch, monitor_count, monitor_time); + + if (monitor->esd_enable || (monitor_switch && !(aw87xxx->aw_dev.is_rec_mode) && monitor->open_dsp_en - && monitor->bin_status == AW_ACF_UPDATE)) { + && monitor->bin_status == AW_MONITOR_CFG_OK)) { AW_DEV_LOGD(aw87xxx->dev, "enter"); monitor->pre_vmax = AW_VMAX_INIT_VAL; monitor->first_entry = AW_FIRST_ENTRY; monitor->timer_cnt = 0; monitor->vbat_sum = 0; + monitor->esd_err_cnt = 0; schedule_delayed_work(&monitor->with_dsp_work, - msecs_to_jiffies(monitor->monitor_hdr.monitor_time)); + msecs_to_jiffies(monitor_time)); } } /*************************************************************************** @@ -677,7 +1450,36 @@ void aw_monitor_start(struct aw_monitor *monitor) * aw87xxx no dsp monitor func * ***************************************************************************/ -int aw_monitor_no_dsp_get_vmax(struct aw_monitor *monitor, int32_t *vmax) +static int aw87xxx_hal_get_vmax(struct device *dev, int32_t *vmax) +{ + int ret = -1; + struct aw87xxx *aw87xxx = dev_get_drvdata(dev); + struct aw_monitor *monitor = &aw87xxx->monitor; + struct aw_table set_table; + + monitor->first_entry = AW_FIRST_ENTRY; + monitor->samp_count = 0; + monitor->temp_trace.sum_val = 0; + monitor->temp_trace.pre_val = 0; + monitor->vol_trace.sum_val = 0; + monitor->vol_trace.pre_val = 0; + + ret = aw_monitor_get_temp_and_vol(dev); + if (ret < 0) + return ret; + + ret = aw_monitor_get_data(dev); + if (ret < 0) + return ret; + + aw_monitor_get_cfg(dev, &set_table); + + *vmax = set_table.vmax; + + return 0; +} + +int aw87xxx_monitor_no_dsp_get_vmax(struct aw_monitor *monitor, int32_t *vmax) { int vbat_capacity = 0; int ret = -1; @@ -686,7 +1488,10 @@ int aw_monitor_no_dsp_get_vmax(struct aw_monitor *monitor, int32_t *vmax) container_of(monitor, struct aw87xxx, monitor); struct device *dev = aw87xxx->dev; - ret = aw_monitor_get_battery_capacity(dev, monitor, &vbat_capacity); + if (monitor->version == AW_MONITOR_HDR_VER_0_1_2) + return aw87xxx_hal_get_vmax(dev, vmax); + + ret = aw_monitor_get_sys_capacity(dev, &vbat_capacity); if (ret < 0) return ret; @@ -711,7 +1516,85 @@ int aw_monitor_no_dsp_get_vmax(struct aw_monitor *monitor, int32_t *vmax) * aw87xxx monitor sysfs nodes * ***************************************************************************/ -static ssize_t aw_attr_get_esd_enable(struct device *dev, +#ifdef AW_DEBUG +static ssize_t vol_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int ret = -1; + struct aw87xxx *aw87xxx = dev_get_drvdata(dev); + struct aw_monitor *monitor = &aw87xxx->monitor; + uint32_t vol = 0; + + if (count == 0) + return 0; + + ret = kstrtouint(buf, 0, &vol); + if (ret < 0) + return ret; + + AW_DEV_LOGI(aw87xxx->dev, "vol set =%d", vol); + monitor->test_vol = vol; + + return count; +} + +static ssize_t vol_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw87xxx *aw87xxx = dev_get_drvdata(dev); + struct aw_monitor *monitor = &aw87xxx->monitor; + + ssize_t len = 0; + + len += snprintf(buf+len, PAGE_SIZE-len, + "vol: %d\n", + monitor->test_vol); + return len; +} + +static ssize_t temp_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int ret = -1; + struct aw87xxx *aw87xxx = dev_get_drvdata(dev); + struct aw_monitor *monitor = &aw87xxx->monitor; + int32_t temp = 0; + + if (count == 0) + return 0; + + ret = kstrtoint(buf, 0, &temp); + if (ret < 0) + return ret; + + AW_DEV_LOGI(aw87xxx->dev, "temp set =%d", temp); + + monitor->test_temp = temp; + + return count; +} + +static ssize_t temp_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw87xxx *aw87xxx = dev_get_drvdata(dev); + struct aw_monitor *monitor = &aw87xxx->monitor; + + ssize_t len = 0; + + len += snprintf(buf+len, PAGE_SIZE-len, + "temp: %d\n", + monitor->test_temp); + + return len; +} + +static DEVICE_ATTR_RW(vol); +static DEVICE_ATTR_RW(temp); +#endif + + +static ssize_t esd_enable_show(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t len = 0; @@ -731,14 +1614,20 @@ static ssize_t aw_attr_get_esd_enable(struct device *dev, return len; } -static ssize_t aw_attr_set_esd_enable(struct device *dev, +static ssize_t esd_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - char esd_enable[16] = {0}; + char esd_enable[AW_ESD_ENABLE_STRLEN] = {0}; struct aw87xxx *aw87xxx = dev_get_drvdata(dev); struct aw_monitor *monitor = &aw87xxx->monitor; - if (sscanf(buf, "%s", esd_enable) == 1) { + if (strlen(buf) > AW_ESD_ENABLE_STRLEN) { + AW_DEV_LOGE(aw87xxx->dev, "input esd_enable_str_len is out of max[%d]", + AW_ESD_ENABLE_STRLEN); + return -EINVAL; + } + + if (sscanf(buf, "%15s", esd_enable) == 1) { AW_DEV_LOGD(aw87xxx->dev, "input esd-enable=[%s]", esd_enable); if (!strcmp(esd_enable, "true")) monitor->esd_enable = AW_ESD_ENABLE; @@ -754,7 +1643,7 @@ static ssize_t aw_attr_set_esd_enable(struct device *dev, return len; } -static ssize_t aw_attr_get_vbat(struct device *dev, +static ssize_t vbat_show(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t len = 0; @@ -764,8 +1653,7 @@ static ssize_t aw_attr_get_vbat(struct device *dev, struct aw_monitor *monitor = &aw87xxx->monitor; if (monitor->custom_capacity == 0) { - ret = aw_monitor_get_battery_capacity(dev, monitor, - &vbat_capacity); + ret = aw_monitor_get_sys_capacity(dev, &vbat_capacity); if (ret < 0) { AW_DEV_LOGE(aw87xxx->dev, "get battery_capacity failed"); return ret; @@ -781,11 +1669,11 @@ static ssize_t aw_attr_get_vbat(struct device *dev, return len; } -static ssize_t aw_attr_set_vbat(struct device *dev, +static ssize_t vbat_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { int ret = -1; - uint32_t capacity = 0; + int capacity = 0; struct aw87xxx *aw87xxx = dev_get_drvdata(dev); struct aw_monitor *monitor = &aw87xxx->monitor; @@ -805,28 +1693,27 @@ static ssize_t aw_attr_set_vbat(struct device *dev, return len; } -static ssize_t aw_attr_get_vmax(struct device *dev, +static ssize_t vmax_show(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t len = 0; int ret = -1; - uint32_t vbat_capacity = 0; + int vbat_capacity = 0; int vmax_get = 0; struct aw87xxx *aw87xxx = dev_get_drvdata(dev); struct aw_monitor *monitor = &aw87xxx->monitor; if (monitor->open_dsp_en) { - ret = aw_dsp_get_vmax(&vmax_get, aw87xxx->dev_index); + ret = aw87xxx_dsp_get_vmax(&vmax_get, aw87xxx->dev_index); if (ret < 0) { AW_DEV_LOGE(aw87xxx->dev, "get dsp vmax fail, ret=%d", ret); return ret; } len += snprintf(buf + len, PAGE_SIZE - len, - "get_vmax=0x%x\n", vmax_get); + "get_vmax=%d\n", vmax_get); } else { - ret = aw_monitor_get_battery_capacity(dev, monitor, - &vbat_capacity); + ret = aw_monitor_get_sys_capacity(dev, &vbat_capacity); if (ret < 0) return ret; AW_DEV_LOGI(aw87xxx->dev, "get_battery_capacity is [%d]", @@ -854,7 +1741,7 @@ static ssize_t aw_attr_get_vmax(struct device *dev, return len; } -static ssize_t aw_attr_set_vmax(struct device *dev, +static ssize_t vmax_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { uint32_t vmax_set = 0; @@ -869,13 +1756,13 @@ static ssize_t aw_attr_set_vmax(struct device *dev, AW_DEV_LOGI(aw87xxx->dev, "vmax_set=0x%x", vmax_set); if (monitor->open_dsp_en) { - ret = aw_dsp_set_vmax(vmax_set, aw87xxx->dev_index); + ret = aw87xxx_dsp_set_vmax(vmax_set, aw87xxx->dev_index); if (ret < 0) { AW_DEV_LOGE(aw87xxx->dev, "send dsp_msg error, ret = %d", ret); return ret; } - msleep(2); + usleep_range(2000, 2010); } else { AW_DEV_LOGE(aw87xxx->dev, "no_dsp system,vmax_set invalid"); return -EINVAL; @@ -884,71 +1771,92 @@ static ssize_t aw_attr_set_vmax(struct device *dev, return count; } -static ssize_t aw_attr_get_monitor_switch(struct device *dev, +static ssize_t monitor_show(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t len = 0; - struct aw87xxx *aw87xxx = dev_get_drvdata(dev); - struct aw_monitor *monitor = &aw87xxx->monitor; - struct aw_monitor_header *monitor_hdr = &monitor->monitor_hdr; + uint32_t monitor_count = 0; + uint32_t monitor_time = 0; + uint32_t monitor_switch = 0; + + aw_monitor_get_ctrl_info(dev, &monitor_switch, + &monitor_count, &monitor_time); len += snprintf(buf + len, PAGE_SIZE - len, - "aw87xxx monitor switch: %d\n", - monitor_hdr->monitor_switch); + "aw87xxx monitor switch: %u\n", + monitor_switch); return len; } -static ssize_t aw_attr_set_monitor_switch(struct device *dev, + +int aw87xxx_dev_monitor_switch_set(struct aw_monitor *monitor, uint32_t enable) +{ + struct aw87xxx *aw87xxx = + container_of(monitor, struct aw87xxx, monitor); + struct aw_monitor_header *monitor_hdr = &monitor->monitor_hdr; + struct aw_monitor_cfg *monitor_cfg = &monitor->monitor_cfg; + + AW_DEV_LOGI(aw87xxx->dev, "monitor switch set =%d", enable); + + if (monitor->bin_status == AW_MONITOR_CFG_WAIT) { + AW_DEV_LOGE(aw87xxx->dev, "bin parse faile or not loaded,set invalid"); + return -EINVAL; + } + + if (enable) { + monitor_hdr->monitor_switch = 1; + monitor_cfg->monitor_switch = 1; + if (monitor->open_dsp_en) { + monitor->pre_vmax = AW_VMAX_INIT_VAL; + monitor->first_entry = AW_FIRST_ENTRY; + monitor->timer_cnt = 0; + monitor->vbat_sum = 0; + } + } else { + monitor_hdr->monitor_switch = 0; + monitor_cfg->monitor_switch = 0; + } + + return 0; +} + +static ssize_t monitor_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { uint32_t enable = 0; int ret = -1; struct aw87xxx *aw87xxx = dev_get_drvdata(dev); struct aw_monitor *monitor = &aw87xxx->monitor; - struct aw_monitor_header *monitor_hdr = &monitor->monitor_hdr; ret = kstrtouint(buf, 0, &enable); if (ret < 0) return ret; - AW_DEV_LOGI(aw87xxx->dev, "monitor switch set =%d", enable); - if (!monitor->bin_status) { - AW_DEV_LOGE(aw87xxx->dev, "bin parse faile or not loaded,set invalid"); - return -EINVAL; - } + ret = aw87xxx_dev_monitor_switch_set(monitor, enable); + if (ret) + return ret; - if (enable > 0) - monitor_hdr->monitor_switch = 1; - else - monitor_hdr->monitor_switch = 0; - - if (monitor->open_dsp_en && enable) { - monitor_hdr->monitor_switch = 1; - monitor->pre_vmax = AW_VMAX_INIT_VAL; - monitor->first_entry = AW_FIRST_ENTRY; - monitor->timer_cnt = 0; - monitor->vbat_sum = 0; - } else if (monitor->open_dsp_en && !enable) { - monitor_hdr->monitor_switch = 0; - } return count; } -static ssize_t aw_attr_get_monitor_time(struct device *dev, +static ssize_t monitor_time_show(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t len = 0; - struct aw87xxx *aw87xxx = dev_get_drvdata(dev); - struct aw_monitor *monitor = &aw87xxx->monitor; - struct aw_monitor_header *monitor_hdr = &monitor->monitor_hdr; + uint32_t monitor_count = 0; + uint32_t monitor_time = 0; + uint32_t monitor_switch = 0; + + aw_monitor_get_ctrl_info(dev, &monitor_switch, + &monitor_count, &monitor_time); len += snprintf(buf + len, PAGE_SIZE - len, - "aw_monitor_timer = %d(ms)\n", - monitor_hdr->monitor_time); + "aw_monitor_timer = %u(ms)\n", + monitor_time); return len; } -static ssize_t aw_attr_set_monitor_time(struct device *dev, +static ssize_t monitor_time_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned int timer_val = 0; @@ -956,6 +1864,7 @@ static ssize_t aw_attr_set_monitor_time(struct device *dev, struct aw87xxx *aw87xxx = dev_get_drvdata(dev); struct aw_monitor *monitor = &aw87xxx->monitor; struct aw_monitor_header *monitor_hdr = &monitor->monitor_hdr; + struct aw_monitor_cfg *monitor_cfg = &monitor->monitor_cfg; ret = kstrtouint(buf, 0, &timer_val); if (ret < 0) @@ -963,34 +1872,36 @@ static ssize_t aw_attr_set_monitor_time(struct device *dev, AW_DEV_LOGI(aw87xxx->dev, "input monitor timer=%d(ms)", timer_val); - if (!monitor->bin_status) { + if (monitor->bin_status == AW_MONITOR_CFG_WAIT) { AW_DEV_LOGE(aw87xxx->dev, "bin parse faile or not loaded,set invalid"); return -EINVAL; } - if (timer_val != monitor_hdr->monitor_time) - monitor_hdr->monitor_time = timer_val; - else - AW_DEV_LOGI(aw87xxx->dev, "no_change monitor_time"); + + monitor_hdr->monitor_time = timer_val; + monitor_cfg->monitor_time = timer_val; return count; } -static ssize_t aw_attr_get_monitor_count(struct device *dev, +static ssize_t monitor_count_show(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t len = 0; - struct aw87xxx *aw87xxx = dev_get_drvdata(dev); - struct aw_monitor *monitor = &aw87xxx->monitor; - struct aw_monitor_header *monitor_hdr = &monitor->monitor_hdr; + uint32_t monitor_count = 0; + uint32_t monitor_time = 0; + uint32_t monitor_switch = 0; + + aw_monitor_get_ctrl_info(dev, &monitor_switch, + &monitor_count, &monitor_time); len += snprintf(buf + len, PAGE_SIZE - len, - "aw_monitor_count = %d\n", - monitor_hdr->monitor_count); + "aw_monitor_count = %u\n", + monitor_count); return len; } -static ssize_t aw_attr_set_monitor_count(struct device *dev, +static ssize_t monitor_count_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned int monitor_count = 0; @@ -998,27 +1909,26 @@ static ssize_t aw_attr_set_monitor_count(struct device *dev, struct aw87xxx *aw87xxx = dev_get_drvdata(dev); struct aw_monitor *monitor = &aw87xxx->monitor; struct aw_monitor_header *monitor_hdr = &monitor->monitor_hdr; + struct aw_monitor_cfg *monitor_cfg = &monitor->monitor_cfg; ret = kstrtouint(buf, 0, &monitor_count); if (ret < 0) return ret; AW_DEV_LOGI(aw87xxx->dev, "input monitor count=%d", monitor_count); - if (!monitor->bin_status) { + if (monitor->bin_status == AW_MONITOR_CFG_WAIT) { AW_DEV_LOGE(aw87xxx->dev, "bin parse faile or not loaded,set invalid"); return -EINVAL; } - if (monitor_count != monitor_hdr->monitor_count) - monitor_hdr->monitor_count = monitor_count; - else - AW_DEV_LOGI(aw87xxx->dev, "no_change monitor_count"); + monitor_hdr->monitor_count = monitor_count; + monitor_cfg->monitor_count = monitor_count; return count; } -static ssize_t aw_attr_get_rx(struct device *dev, +static ssize_t rx_show(struct device *dev, struct device_attribute *attr, char *buf) { struct aw87xxx *aw87xxx = dev_get_drvdata(dev); @@ -1028,13 +1938,13 @@ static ssize_t aw_attr_get_rx(struct device *dev, uint32_t enable = 0; if (monitor->open_dsp_en) { - ret = aw_dsp_get_rx_module_enable(&enable); + ret = aw87xxx_dsp_get_rx_module_enable(&enable); if (ret) { AW_DEV_LOGE(aw87xxx->dev, "dsp_msg error, ret=%d", ret); return ret; } len += snprintf(buf + len, PAGE_SIZE - len, - "aw87xxx rx: %d\n", enable); + "aw87xxx rx: %u\n", enable); } else { len += snprintf(buf + len, PAGE_SIZE - len, "command is invalid\n"); @@ -1043,7 +1953,7 @@ static ssize_t aw_attr_get_rx(struct device *dev, return len; } -static ssize_t aw_attr_set_rx(struct device *dev, +static ssize_t rx_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct aw87xxx *aw87xxx = dev_get_drvdata(dev); @@ -1058,7 +1968,7 @@ static ssize_t aw_attr_set_rx(struct device *dev, if (monitor->open_dsp_en) { AW_DEV_LOGI(aw87xxx->dev, "set rx enable=%d", enable); - ret = aw_dsp_set_rx_module_enable(enable); + ret = aw87xxx_dsp_set_rx_module_enable(enable); if (ret < 0) { AW_DEV_LOGE(aw87xxx->dev, "dsp_msg error, ret=%d", ret); @@ -1072,27 +1982,146 @@ static ssize_t aw_attr_set_rx(struct device *dev, return count; } +static ssize_t monitor_params_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw87xxx *aw87xxx = dev_get_drvdata(dev); + struct aw_monitor *monitor = &aw87xxx->monitor; + struct aw_container *monitor_container = monitor->monitor_container; + ssize_t len = 0; + int i = 0; -static DEVICE_ATTR(esd_enable, S_IWUSR | S_IRUGO, - aw_attr_get_esd_enable, aw_attr_set_esd_enable); -static DEVICE_ATTR(vbat, S_IWUSR | S_IRUGO, - aw_attr_get_vbat, aw_attr_set_vbat); -static DEVICE_ATTR(vmax, S_IWUSR | S_IRUGO, - aw_attr_get_vmax, aw_attr_set_vmax); + if ((monitor_container == NULL) || (monitor->bin_status == AW_MONITOR_CFG_WAIT)) { + len += snprintf((char *)(buf + len), PAGE_SIZE - len, + "0\n"); + return len; + } -static DEVICE_ATTR(monitor_switch, S_IWUSR | S_IRUGO, - aw_attr_get_monitor_switch, aw_attr_set_monitor_switch); -static DEVICE_ATTR(monitor_time, S_IWUSR | S_IRUGO, - aw_attr_get_monitor_time, aw_attr_set_monitor_time); -static DEVICE_ATTR(monitor_count, S_IWUSR | S_IRUGO, - aw_attr_get_monitor_count, aw_attr_set_monitor_count); -static DEVICE_ATTR(rx, S_IWUSR | S_IRUGO, - aw_attr_get_rx, aw_attr_set_rx); + len += snprintf((char *)(buf + len), PAGE_SIZE - len, "1 "); + for (i = 0; i < monitor_container->len; i++) { + len += snprintf((char *)(buf + len), PAGE_SIZE - len, + "%02x,", monitor_container->data[i]); + } + + len += snprintf((char *)(buf + len), PAGE_SIZE - len, "\n"); + + return len; +} + +static int aw_monitor_real_time_update_monitor(struct device *dev) +{ + const struct firmware *cont = NULL; + int ret = 0; + + ret = request_firmware(&cont, AW87XXX_MONITOR_NAME, dev); + if (ret < 0) { + AW_DEV_LOGE(dev, "failed to read %s", AW87XXX_MONITOR_NAME); + release_firmware(cont); + return ret; + } + + ret = aw87xxx_monitor_bin_parse(dev, cont->data, (uint32_t)cont->size); + if (ret < 0) + AW_DEV_LOGE(dev, "parse monitor firmware failed!"); + + release_firmware(cont); + + return ret; +} + +void aw87xxx_monitor_cfg_free(struct aw_monitor *monitor) +{ + struct aw_monitor_cfg *monitor_cfg = &monitor->monitor_cfg; + struct aw87xxx *aw87xxx = + container_of(monitor, struct aw87xxx, monitor); + + aw_monitor_cfg_v_0_0_1_free(monitor); + + if (monitor_cfg->temp_info.aw_table != NULL) { + devm_kfree(aw87xxx->dev, monitor_cfg->temp_info.aw_table); + monitor_cfg->temp_info.aw_table = NULL; + } + + if (monitor_cfg->vol_info.aw_table != NULL) { + devm_kfree(aw87xxx->dev, monitor_cfg->vol_info.aw_table); + monitor_cfg->vol_info.aw_table = NULL; + } + + memset(monitor_cfg, 0, sizeof(struct aw_monitor_cfg)); +} + +static ssize_t monitor_update_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct aw87xxx *aw87xxx = dev_get_drvdata(dev); + struct aw_monitor *aw_monitor = &aw87xxx->monitor; + ssize_t len = 0; + + if (aw_monitor->version == AW_MONITOR_DATA_VER) { + len += snprintf((char *)(buf + len), PAGE_SIZE - len, + "0\n"); + AW_DEV_LOGE(dev, "unsupported monitor version"); + return len; + } + + if (aw_monitor->bin_status == AW_MONITOR_CFG_WAIT) { + len += snprintf((char *)(buf + len), PAGE_SIZE - len, + "0\n"); + } else if (aw_monitor->bin_status == AW_MONITOR_CFG_OK) { + len += snprintf((char *)(buf + len), PAGE_SIZE - len, + "1\n"); + } else { + AW_DEV_LOGE(dev, "unsupported bin_status"); + } + + return len; +} + +static ssize_t monitor_update_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct aw87xxx *aw87xxx = dev_get_drvdata(dev); + struct aw_monitor *aw_monitor = &aw87xxx->monitor; + uint32_t update = 0; + int ret = -1; + + ret = kstrtouint(buf, 0, &update); + if (ret < 0) + return ret; + + AW_DEV_LOGI(dev, "monitor update = %d", update); + + if (update) { + aw87xxx_monitor_stop(aw_monitor); + aw87xxx_monitor_cfg_free(aw_monitor); + ret = aw_monitor_real_time_update_monitor(dev); + if (ret < 0) + return ret; + aw87xxx_monitor_start(aw_monitor); + } + + return count; +} + +static DEVICE_ATTR_RW(esd_enable); +static DEVICE_ATTR_RW(vbat); +static DEVICE_ATTR_RW(vmax); + +static DEVICE_ATTR_RW(monitor); +static DEVICE_ATTR_RW(monitor_time); +static DEVICE_ATTR_RW(monitor_count); +static DEVICE_ATTR_RW(rx); +static DEVICE_ATTR_RW(monitor_update); +static DEVICE_ATTR_RO(monitor_params); static struct attribute *aw_monitor_vol_adjust[] = { &dev_attr_esd_enable.attr, &dev_attr_vbat.attr, &dev_attr_vmax.attr, +#ifdef AW_DEBUG + &dev_attr_vol.attr, + &dev_attr_temp.attr, +#endif NULL }; @@ -1101,10 +2130,12 @@ static struct attribute_group aw_monitor_vol_adjust_group = { }; static struct attribute *aw_monitor_control[] = { - &dev_attr_monitor_switch.attr, + &dev_attr_monitor.attr, &dev_attr_monitor_time.attr, &dev_attr_monitor_count.attr, &dev_attr_rx.attr, + &dev_attr_monitor_update.attr, + &dev_attr_monitor_params.attr, NULL }; @@ -1129,17 +2160,17 @@ static void aw_monitor_dtsi_parse(struct device *dev, AW_DEV_LOGI(dev, "esd_enable parse failed, user default[disable]"); monitor->esd_enable = AW_ESD_DISABLE; } else { - if (!strcmp(esd_enable, "true")) - monitor->esd_enable = AW_ESD_ENABLE; - else + if (!strcmp(esd_enable, "false")) monitor->esd_enable = AW_ESD_DISABLE; + else + monitor->esd_enable = AW_ESD_ENABLE; AW_DEV_LOGI(dev, "parse esd-enable=[%s]", monitor->esd_enable ? "true" : "false"); } } -void aw_monitor_init(struct device *dev, struct aw_monitor *monitor, +void aw87xxx_monitor_init(struct device *dev, struct aw_monitor *monitor, struct device_node *dev_node) { int ret = -1; @@ -1152,7 +2183,7 @@ void aw_monitor_init(struct device *dev, struct aw_monitor *monitor, aw_monitor_dtsi_parse(dev, monitor, dev_node); /* get platform open dsp type */ - monitor->open_dsp_en = aw_dsp_isEnable(); + monitor->open_dsp_en = aw87xxx_dsp_isEnable(); ret = sysfs_create_group(&dev->kobj, &aw_monitor_vol_adjust_group); if (ret < 0) @@ -1170,7 +2201,7 @@ void aw_monitor_init(struct device *dev, struct aw_monitor *monitor, AW_DEV_LOGI(dev, "monitor init succeed"); } -void aw_monitor_exit(struct aw_monitor *monitor) +void aw87xxx_monitor_exit(struct aw_monitor *monitor) { struct aw87xxx *aw87xxx = container_of(monitor, struct aw87xxx, monitor); @@ -1178,7 +2209,7 @@ void aw_monitor_exit(struct aw_monitor *monitor) sysfs_remove_group(&aw87xxx->dev->kobj, &aw_monitor_vol_adjust_group); - aw_monitor_stop(monitor); + aw87xxx_monitor_stop(monitor); if (monitor->open_dsp_en) { sysfs_remove_group(&aw87xxx->dev->kobj, diff --git a/sound/soc/codecs/aw87xxx/aw_monitor.h b/sound/soc/codecs/aw87xxx/aw_monitor.h index ca59e9d7430a..c42a9653ba7d 100644 --- a/sound/soc/codecs/aw87xxx/aw_monitor.h +++ b/sound/soc/codecs/aw87xxx/aw_monitor.h @@ -1,7 +1,20 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ +/* SPDX-License-Identifier: GPL-2.0 + * aw87xxx_monitor.h + * + * Copyright (c) 2021 AWINIC Technology CO., LTD + * + * Author: Barry + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ -#ifndef __AW_MONITOR_H__ -#define __AW_MONITOR_H__ +#ifndef __AW87XXX_MONITOR_H__ +#define __AW87XXX_MONITOR_H__ + +/*#define AW_DEBUG*/ #define AW_WAIT_DSP_OPEN_TIME (3000) #define AW_VBAT_CAPACITY_MIN (0) @@ -11,11 +24,64 @@ #define AW_VMAX_MAX (0) #define AW_DEFAULT_MONITOR_TIME (3000) #define AW_WAIT_TIME (3000) -#define REG_STATUS_CHECK_MAX (10) +#define REG_STATUS_CHECK_MAX (5) #define AW_ESD_CHECK_DELAY (1) +#define AW_MONOTOR_ESD_ERR_CNT_MAX (3) + + +#define AW_MONITOR_TIME_MIN (0) +#define AW_MONITOR_TIME_MAX (50000) + #define AW_ESD_ENABLE (true) #define AW_ESD_DISABLE (false) +#define AW_ESD_ENABLE_STRLEN (16) +#define MONITOR_EN_MASK 0x01 + +#define AW_TABLE_SIZE sizeof(struct aw_table) + +#define AW_GET_32_DATA(w, x, y, z) \ + ((uint32_t)((((uint8_t)w) << 24) | (((uint8_t)x) << 16) | (((uint8_t)y) << 8) | ((uint8_t)z))) +#define AW_GET_16_DATA(x, y) \ + ((uint16_t)((((uint8_t)x) << 8) | (uint8_t)y)) + +#define IPEAK_NONE (0xFF) +#define GAIN_NONE (0xFF) +#define VMAX_NONE (0xFFFFFFFF) + +enum { + AW_MON_LOGIC_OR = 0, + AW_MON_LOGIC_AND = 1, +}; + +enum { + MONITOR_EN_BIT = 0, + MONITOR_LOGIC_BIT = 1, + MONITOR_IPEAK_EN_BIT = 2, + MONITOR_GAIN_EN_BIT = 3, + MONITOR_VMAX_EN_BIT = 4, + MONITOR_TEMP_EN_BIT = 5, + MONITOR_VOL_EN_BIT = 6, + MONITOR_TEMPERATURE_SOURCE_BIT = 7, + MONITOR_VOLTAGE_SOURCE_BIT = 8, + MONITOR_VOLTAGE_MODE_BIT = 9, +}; + +enum { + AW_SYS_VOLTAGE_NOW = 0, + AW_SYS_CAPACITY = 1, +}; + +enum { + AW_VOLTAGE_INFO = 0, + AW_CAPACITY_INFO = 1, + AW_TEMPERATURE_INFO = 2, +}; + +enum { + AW_CHIP_INFO = 0, + AW_PLATFORM_INFO = 1, +}; enum aw_monitor_init { AW_MONITOR_CFG_WAIT = 0, @@ -32,11 +98,30 @@ enum aw_monitor_data_ver { AW_MONITOR_DATA_VER_MAX, }; +enum aw_monitor_hdr_ver { + AW_MONITOR_HDR_VER_0_1_0 = 0x00010000, + AW_MONITOR_HDR_VER_0_1_1 = 0x00010100, + AW_MONITOR_HDR_VER_0_1_2 = 0x00010200, +}; + enum aw_monitor_first_enter { AW_FIRST_ENTRY = 0, AW_NOT_FIRST_ENTRY = 1, }; +struct aw_container { + int len; + uint8_t data[]; +}; + +struct aw_table { + int16_t min_val; + int16_t max_val; + uint16_t ipeak; + uint16_t gain; + uint32_t vmax; +}; + struct aw_bin_header { uint32_t check_sum; uint32_t header_ver; @@ -59,12 +144,75 @@ struct aw_monitor_header { uint32_t reserve[4]; }; + +/* v0.1.2 */ +struct aw_monitor_hdr { + uint32_t check_sum; + uint32_t monitor_ver; + char chip_type[16]; + uint32_t ui_ver; + uint32_t monitor_time; + uint32_t monitor_count; + uint32_t enable_flag; + /* [bit 31:7]*/ + /* [bit 9: voltage mode]*/ + /* [bit 8: voltage source]*/ + /* [bit 7: temperature source]*/ + /* [bit 6: vol en]*/ + /* [bit 5: temp en]*/ + /* [bit 4: vmax en]*/ + /* [bit 3: gain en]*/ + /* [bit 2: ipeak en]*/ + /* [bit 1: & or | flag]*/ + /* [bit 0: monitor en]*/ + uint32_t temp_aplha; + uint32_t temp_num; + uint32_t single_temp_size; + uint32_t temp_offset; + uint32_t vol_aplha; + uint32_t vol_num; + uint32_t single_vol_size; + uint32_t vol_offset; + uint32_t reserver[3]; +}; + struct vmax_step_config { uint32_t vbat_min; uint32_t vbat_max; int vmax_vol; }; +struct aw_table_info { + uint8_t table_num; + struct aw_table *aw_table; +}; + +struct aw_monitor_cfg { + uint8_t monitor_status; + uint32_t monitor_switch; + uint32_t monitor_time; + uint32_t monitor_count; + uint32_t logic_switch; + uint32_t temp_switch; + uint32_t temp_aplha; + uint32_t vol_switch; + uint32_t vol_aplha; + uint32_t ipeak_switch; + uint32_t gain_switch; + uint32_t vmax_switch; + uint32_t temp_source; + uint32_t vol_source; + uint32_t vol_mode; + struct aw_table_info temp_info; + struct aw_table_info vol_info; +}; + +struct aw_monitor_trace { + int32_t pre_val; + int32_t sum_val; + struct aw_table aw_table; +}; + struct aw_monitor { bool open_dsp_en; bool esd_enable; @@ -72,24 +220,39 @@ struct aw_monitor { uint8_t first_entry; uint8_t timer_cnt; uint32_t vbat_sum; - uint32_t custom_capacity; + int32_t custom_capacity; uint32_t pre_vmax; + uint32_t esd_err_cnt; + uint8_t samp_count; + uint32_t version; + +#ifdef AW_DEBUG + uint16_t test_vol; + int16_t test_temp; +#endif int bin_status; struct aw_monitor_header monitor_hdr; struct vmax_step_config *vmax_cfg; + struct aw_monitor_cfg monitor_cfg; + + struct aw_monitor_trace temp_trace; + struct aw_monitor_trace vol_trace; + struct aw_container *monitor_container; struct delayed_work with_dsp_work; }; -void aw_monitor_cfg_free(struct aw_monitor *monitor); -int aw_monitor_bin_parse(struct device *dev, - char *monitor_data, uint32_t data_len); -void aw_monitor_stop(struct aw_monitor *monitor); -void aw_monitor_start(struct aw_monitor *monitor); -int aw_monitor_no_dsp_get_vmax(struct aw_monitor *monitor, +void aw87xxx_monitor_cfg_free(struct aw_monitor *monitor); +int aw87xxx_monitor_bin_parse(struct device *dev, + const char *monitor_data, uint32_t data_len); +void aw87xxx_monitor_stop(struct aw_monitor *monitor); +void aw87xxx_monitor_start(struct aw_monitor *monitor); +int aw87xxx_monitor_no_dsp_get_vmax(struct aw_monitor *monitor, int32_t *vmax); -void aw_monitor_init(struct device *dev, struct aw_monitor *monitor, +void aw87xxx_monitor_init(struct device *dev, struct aw_monitor *monitor, struct device_node *dev_node); -void aw_monitor_exit(struct aw_monitor *monitor); +void aw87xxx_monitor_exit(struct aw_monitor *monitor); +int aw87xxx_dev_monitor_switch_set(struct aw_monitor *monitor, uint32_t enable); + #endif diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c index f11175dc0fa2..3e2de70340cc 100644 --- a/sound/soc/codecs/es8328.c +++ b/sound/soc/codecs/es8328.c @@ -893,13 +893,6 @@ int es8328_probe(struct device *dev, struct regmap *regmap) dev_set_drvdata(dev, es8328); -#ifdef CONFIG_SND_SOC_AW87XXX - ret = aw87xxx_add_codec_controls((void *)component); - if (ret < 0) { - pr_err("%s: add_codec_controls failed, ret %d\n", __func__, ret); - } -#endif - return devm_snd_soc_register_component(dev, &es8328_component_driver, &es8328_dai, 1); }