From nobody Wed Oct 1 22:31:21 2025 Received: from out28-217.mail.aliyun.com (out28-217.mail.aliyun.com [115.124.28.217]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 867E62EB87B; Fri, 26 Sep 2025 10:26:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.28.217 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758882373; cv=none; b=QkrVj0ilIpmQNtM0nbsH2ix56Pabac/tE6Yqhmqc3ctqGp/7tmQBIHrim5HngBOzOoLfRwBhJ2e9U/Jjh3cD/hQaOiBa5x9T5QvO3uXAOt1d+jkdzWSt29ptlbvswnmUIruMae7L2IhTKmfYhrbTgNnkK2No4kDJcCNc993X7mM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758882373; c=relaxed/simple; bh=u0dMHGgjZUhbMy43C7nqTUZVq3367hhW7y9G/fJ+fOc=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bkfUwnlkdmoNDtv8Lf09HLvFl3v4eQ2h8Aa8ux/8Z249poLtxJIfhogGOmpb8LfgMGavirL5El4MX4L6elFw6DeUsBPvEdzUadid/eg+lsCb5uVI2DH2VcecKWf7ZrZx2BZGRsTM/PviWFKBNwsVhYgEnXe3+/L+1dpRkV/5GZg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=awinic.com; spf=pass smtp.mailfrom=awinic.com; dkim=pass (2048-bit key) header.d=awinic.com header.i=@awinic.com header.b=C1wL2RWP; arc=none smtp.client-ip=115.124.28.217 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=awinic.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=awinic.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=awinic.com header.i=@awinic.com header.b="C1wL2RWP" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=awinic.com; s=default; t=1758882364; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=TY2rxFHrYKS4StlXKyojeXzvnUVe4yFv+sqjqOytCbo=; b=C1wL2RWPYMwA0ibY7Whyeo/0ULlmcILwDmVGnr3iaUygeqab0D2dM1Z4nXXK8clHM+bOrOU3EpNptNSb2+dt+GhxNU/kSJmpUslIL9VltByud6Yb+3qR0pzTzBFSJuANeMPrjQ0yhHSK9OnxA4+K6Yih8pwOWzowdY+CwF+jpVSNLU19GT7MU2Wu3G1l8//yJYvlVlNqe25acIt4ESeeFlnjrbXnIUtXSaHjfD1UdFb7f12YdiUa8aCRIJLi9M7BnJyxIZLml3wOBKyWPMF5xGhFrMSkfK1KM7qc6FVzRXfVe0GFoEbAHm6cF7S15i4wKamV1Xyad6WdokFqx7WaFQ== Received: from ubuntu-VirtualBox..(mailfrom:wangweidong.a@awinic.com fp:SMTPD_---.ensjOvI_1758882042 cluster:ay29) by smtp.aliyun-inc.com; Fri, 26 Sep 2025 18:20:43 +0800 From: wangweidong.a@awinic.com To: lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, wangweidong.a@awinic.com, cy_huang@richtek.com, ivprusov@salutedevices.com, zhoubinbin@loongson.cn, zhangyi@everest-semi.com, jack.yu@realtek.com, shenghao-ding@ti.com, rf@opensource.cirrus.com, git@apitzsch.eu, nuno.sa@analog.com, colin.i.king@gmail.com, thorsten.blum@linux.dev, yesanishhere@gmail.com, ebiggers@google.com, ardb@kernel.org, zhujun2@cmss.chinamobile.com, linux-kernel@vger.kernel.org, linux-sound@vger.kernel.org Subject: [PATCH V1 1/7] ASoC: codecs:Rework the awinic driver lib Date: Fri, 26 Sep 2025 18:20:31 +0800 Message-ID: <20250926102037.27697-2-wangweidong.a@awinic.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20250926102037.27697-1-wangweidong.a@awinic.com> References: <20250926102037.27697-1-wangweidong.a@awinic.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Weidong Wang Extract the awxxxx driver common interfaces into aw-common-firmware and aw-common-device to facilitate subsequent driver usage. Signed-off-by: Weidong Wang --- sound/soc/codecs/aw-common-device.c | 509 +++++ sound/soc/codecs/aw-common-device.h | 206 ++ .../aw88395_lib.c =3D> aw-common-firmware.c} | 150 +- sound/soc/codecs/aw-common-firmware.h | 211 ++ sound/soc/codecs/aw88395/aw88395_data_type.h | 142 -- sound/soc/codecs/aw88395/aw88395_device.c | 1720 ----------------- sound/soc/codecs/aw88395/aw88395_device.h | 214 -- sound/soc/codecs/aw88395/aw88395_lib.h | 92 - 8 files changed, 1002 insertions(+), 2242 deletions(-) create mode 100644 sound/soc/codecs/aw-common-device.c create mode 100644 sound/soc/codecs/aw-common-device.h rename sound/soc/codecs/{aw88395/aw88395_lib.c =3D> aw-common-firmware.c} = (89%) create mode 100644 sound/soc/codecs/aw-common-firmware.h delete mode 100644 sound/soc/codecs/aw88395/aw88395_data_type.h delete mode 100644 sound/soc/codecs/aw88395/aw88395_device.c delete mode 100644 sound/soc/codecs/aw88395/aw88395_device.h delete mode 100644 sound/soc/codecs/aw88395/aw88395_lib.h diff --git a/sound/soc/codecs/aw-common-device.c b/sound/soc/codecs/aw-comm= on-device.c new file mode 100644 index 000000000000..a001633b43bc --- /dev/null +++ b/sound/soc/codecs/aw-common-device.c @@ -0,0 +1,509 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// aw-dev-common.h -- awinic amp common driver interface +// +// Copyright (c) 2025 AWINIC Technology CO., LTD +// +// Author: Weidong Wang +// + +#include +#include +#include +#include +#include +#include "aw-common-device.h" +#include "aw-common-firmware.h" + +static int aw_dev_dsp_write_16bit(struct aw_device *aw_dev, + unsigned short dsp_addr, unsigned int dsp_data) +{ + int ret; + + ret =3D regmap_write(aw_dev->regmap, AW_DSPMADD_REG, dsp_addr); + if (ret) { + dev_err(aw_dev->dev, "%s write addr error, ret=3D%d", __func__, ret); + return ret; + } + + ret =3D regmap_write(aw_dev->regmap, AW_DSPMDAT_REG, (u16)dsp_data); + if (ret) { + dev_err(aw_dev->dev, "%s write data error, ret=3D%d", __func__, ret); + return ret; + } + + return 0; +} + +static int aw_dev_dsp_write_32bit(struct aw_device *aw_dev, + unsigned short dsp_addr, unsigned int dsp_data) +{ + u16 temp_data; + int ret; + + ret =3D regmap_write(aw_dev->regmap, AW_DSPMADD_REG, dsp_addr); + if (ret) { + dev_err(aw_dev->dev, "%s write addr error, ret=3D%d", __func__, ret); + return ret; + } + + temp_data =3D dsp_data & AW_DSP_16_DATA_MASK; + ret =3D regmap_write(aw_dev->regmap, AW_DSPMDAT_REG, (u16)temp_data); + if (ret) { + dev_err(aw_dev->dev, "%s write datal error, ret=3D%d", __func__, ret); + return ret; + } + + temp_data =3D dsp_data >> 16; + ret =3D regmap_write(aw_dev->regmap, AW_DSPMDAT_REG, (u16)temp_data); + if (ret) { + dev_err(aw_dev->dev, "%s write datah error, ret=3D%d", __func__, ret); + return ret; + } + + return 0; +} + +int aw_dev_dsp_write(struct aw_device *aw_dev, + unsigned short dsp_addr, unsigned int dsp_data, unsigned char data_type) +{ + u32 reg_value; + int ret; + + mutex_lock(&aw_dev->dsp_lock); + switch (data_type) { + case AW_DSP_16_DATA: + ret =3D aw_dev_dsp_write_16bit(aw_dev, dsp_addr, dsp_data); + if (ret) + dev_err(aw_dev->dev, "write dsp_addr[0x%x] 16-bit dsp_data[0x%x] failed= ", + dsp_addr, dsp_data); + break; + case AW_DSP_32_DATA: + ret =3D aw_dev_dsp_write_32bit(aw_dev, dsp_addr, dsp_data); + if (ret) + dev_err(aw_dev->dev, "write dsp_addr[0x%x] 32-bit dsp_data[0x%x] failed= ", + dsp_addr, dsp_data); + break; + default: + dev_err(aw_dev->dev, "data type[%d] unsupported", data_type); + ret =3D -EINVAL; + break; + } + + /* clear dsp chip select state*/ + if (regmap_read(aw_dev->regmap, AW_ID_REG, ®_value)) + dev_err(aw_dev->dev, "%s fail to clear chip state. Err=3D%d\n", __func__= , ret); + mutex_unlock(&aw_dev->dsp_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(aw_dev_dsp_write); + +int aw_dev_dsp_read_16bit(struct aw_device *aw_dev, + unsigned short dsp_addr, unsigned int *dsp_data) +{ + unsigned int temp_data; + int ret; + + ret =3D regmap_write(aw_dev->regmap, AW_DSPMADD_REG, dsp_addr); + if (ret) { + dev_err(aw_dev->dev, "%s write error, ret=3D%d", __func__, ret); + return ret; + } + + ret =3D regmap_read(aw_dev->regmap, AW_DSPMDAT_REG, &temp_data); + if (ret) { + dev_err(aw_dev->dev, "%s read error, ret=3D%d", __func__, ret); + return ret; + } + *dsp_data =3D temp_data; + + return 0; +} +EXPORT_SYMBOL_GPL(aw_dev_dsp_read_16bit); + +static int aw_dev_dsp_read_32bit(struct aw_device *aw_dev, + unsigned short dsp_addr, unsigned int *dsp_data) +{ + unsigned int temp_data; + int ret; + + ret =3D regmap_write(aw_dev->regmap, AW_DSPMADD_REG, dsp_addr); + if (ret) { + dev_err(aw_dev->dev, "%s write error, ret=3D%d", __func__, ret); + return ret; + } + + ret =3D regmap_read(aw_dev->regmap, AW_DSPMDAT_REG, &temp_data); + if (ret) { + dev_err(aw_dev->dev, "%s read error, ret=3D%d", __func__, ret); + return ret; + } + *dsp_data =3D temp_data; + + ret =3D regmap_read(aw_dev->regmap, AW_DSPMDAT_REG, &temp_data); + if (ret) { + dev_err(aw_dev->dev, "%s read error, ret=3D%d", __func__, ret); + return ret; + } + *dsp_data |=3D (temp_data << 16); + + return 0; +} + +int aw_dev_dsp_read(struct aw_device *aw_dev, + unsigned short dsp_addr, unsigned int *dsp_data, unsigned char data_type) +{ + u32 reg_value; + int ret; + + mutex_lock(&aw_dev->dsp_lock); + switch (data_type) { + case AW_DSP_16_DATA: + ret =3D aw_dev_dsp_read_16bit(aw_dev, dsp_addr, dsp_data); + if (ret) + dev_err(aw_dev->dev, "read dsp_addr[0x%x] 16-bit dsp_data[0x%x] failed", + dsp_addr, *dsp_data); + break; + case AW_DSP_32_DATA: + ret =3D aw_dev_dsp_read_32bit(aw_dev, dsp_addr, dsp_data); + if (ret) + dev_err(aw_dev->dev, "read dsp_addr[0x%x] 32r-bit dsp_data[0x%x] failed= ", + dsp_addr, *dsp_data); + break; + default: + dev_err(aw_dev->dev, "data type[%d] unsupported", data_type); + ret =3D -EINVAL; + break; + } + + /* clear dsp chip select state*/ + if (regmap_read(aw_dev->regmap, AW_ID_REG, ®_value)) + dev_err(aw_dev->dev, "%s fail to clear chip state. Err=3D%d\n", __func__= , ret); + mutex_unlock(&aw_dev->dsp_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(aw_dev_dsp_read); + +int aw_dev_get_dsp_status(struct aw_device *aw_dev) +{ + unsigned int reg_val; + int ret; + + ret =3D regmap_read(aw_dev->regmap, AW_WDT_REG, ®_val); + if (ret) + return ret; + if (!(reg_val & (~AW_WDT_CNT_MASK))) + ret =3D -EPERM; + + return ret; +} +EXPORT_SYMBOL_GPL(aw_dev_get_dsp_status); + +void aw_dev_get_int_status(struct aw_device *aw_dev, unsigned short *int_s= tatus) +{ + unsigned int reg_val; + int ret; + + ret =3D regmap_read(aw_dev->regmap, AW_SYSINT_REG, ®_val); + if (ret) + dev_err(aw_dev->dev, "read interrupt reg fail, ret=3D%d", ret); + else + *int_status =3D reg_val; + + dev_dbg(aw_dev->dev, "read interrupt reg =3D 0x%04x", *int_status); +} +EXPORT_SYMBOL_GPL(aw_dev_get_int_status); + +void aw_dev_clear_int_status(struct aw_device *aw_dev) +{ + u16 int_status; + + /* read int status and clear */ + aw_dev_get_int_status(aw_dev, &int_status); + /* make sure int status is clear */ + aw_dev_get_int_status(aw_dev, &int_status); + if (int_status) + dev_info(aw_dev->dev, "int status(%d) is not cleaned.\n", int_status); +} +EXPORT_SYMBOL_GPL(aw_dev_clear_int_status); + +static int aw_dev_dsp_update_container(struct aw_device *aw_dev, + unsigned char *data, unsigned int len, unsigned short base) +{ + int i, ret; + u32 tmp_len; + + mutex_lock(&aw_dev->dsp_lock); + ret =3D regmap_write(aw_dev->regmap, AW_DSPMADD_REG, base); + if (ret) + goto error_operation; + + for (i =3D 0; i < len; i +=3D AW_MAX_RAM_WRITE_BYTE_SIZE) { + tmp_len =3D min(len - i, AW_MAX_RAM_WRITE_BYTE_SIZE); + ret =3D regmap_raw_write(aw_dev->regmap, AW_DSPMDAT_REG, + &data[i], tmp_len); + if (ret) + goto error_operation; + } + mutex_unlock(&aw_dev->dsp_lock); + + return 0; + +error_operation: + mutex_unlock(&aw_dev->dsp_lock); + return ret; +} + +int aw_dev_dsp_update_fw(struct aw_device *aw_dev, + unsigned char *data, unsigned int len, unsigned int addr) +{ + dev_dbg(aw_dev->dev, "dsp firmware len:%d", len); + + if (!len || !data) { + dev_err(aw_dev->dev, "dsp firmware data is null or len is 0"); + return -EINVAL; + } + aw_dev_dsp_update_container(aw_dev, data, len, addr); + aw_dev->dsp_fw_len =3D len; + + return 0; +} +EXPORT_SYMBOL_GPL(aw_dev_dsp_update_fw); + +int aw_dev_dsp_update_cfg(struct aw_device *aw_dev, + unsigned char *data, unsigned int len, unsigned int addr) +{ + dev_dbg(aw_dev->dev, "dsp config len:%d", len); + + if (!len || !data) { + dev_err(aw_dev->dev, "dsp config data is null or len is 0"); + return -EINVAL; + } + + aw_dev_dsp_update_container(aw_dev, data, len, addr); + aw_dev->dsp_cfg_len =3D len; + + return 0; +} +EXPORT_SYMBOL_GPL(aw_dev_dsp_update_cfg); + +int aw_dev_set_profile_index(struct aw_device *aw_dev, int index) +{ + /* check the index whether is valid */ + if ((index >=3D aw_dev->prof_info.count) || (index < 0)) + return -EINVAL; + /* check the index whether change */ + if (aw_dev->prof_index =3D=3D index) + return -EINVAL; + + aw_dev->prof_index =3D index; + dev_dbg(aw_dev->dev, "set prof[%s]", + aw_dev->prof_info.prof_name_list[aw_dev->prof_info.prof_desc[index].id]); + + return 0; +} +EXPORT_SYMBOL_GPL(aw_dev_set_profile_index); + +int aw_dev_get_prof_name(struct aw_device *aw_dev, int index, char **prof_= name) +{ + struct aw_prof_info *prof_info =3D &aw_dev->prof_info; + struct aw_prof_desc *prof_desc; + + if ((index >=3D aw_dev->prof_info.count) || (index < 0)) { + dev_err(aw_dev->dev, "index[%d] overflow count[%d]", + index, aw_dev->prof_info.count); + return -EINVAL; + } + + prof_desc =3D &aw_dev->prof_info.prof_desc[index]; + + *prof_name =3D prof_info->prof_name_list[prof_desc->id]; + + return 0; +} +EXPORT_SYMBOL_GPL(aw_dev_get_prof_name); + +int aw_dev_get_prof_data(struct aw_device *aw_dev, int index, + struct aw_prof_desc **prof_desc) +{ + if ((index >=3D aw_dev->prof_info.count) || (index < 0)) { + dev_err(aw_dev->dev, "%s: index[%d] overflow count[%d]\n", + __func__, index, aw_dev->prof_info.count); + return -EINVAL; + } + + *prof_desc =3D &aw_dev->prof_info.prof_desc[index]; + + return 0; +} +EXPORT_SYMBOL_GPL(aw_dev_get_prof_data); + +static int aw_dev_read_chipid(struct aw_device *aw_dev, u16 *chip_id) +{ + int reg_val; + int ret; + + ret =3D regmap_read(aw_dev->regmap, AW_ID_REG, ®_val); + if (ret) { + dev_err(aw_dev->dev, "%s read chipid error. ret =3D %d", __func__, ret); + return ret; + } + + dev_info(aw_dev->dev, "chip id =3D %x\n", reg_val); + *chip_id =3D reg_val; + + return 0; +} + +static void aw_parse_channel_dt(struct aw_device *aw_dev) +{ + struct device_node *np =3D aw_dev->dev->of_node; + u32 channel_value; + + of_property_read_u32(np, "awinic,audio-channel", &channel_value); + aw_dev->channel =3D channel_value; + aw_dev->phase_sync =3D of_property_read_bool(np, "awinic,sync-flag"); +} + + +int aw_dev_init(struct aw_device *aw_dev, struct i2c_client *i2c, struct r= egmap *regmap) +{ + u16 chip_id; + int ret; + + aw_dev->i2c =3D i2c; + aw_dev->dev =3D &i2c->dev; + aw_dev->regmap =3D regmap; + mutex_init(&aw_dev->dsp_lock); + + /* read chip id */ + ret =3D aw_dev_read_chipid(aw_dev, &chip_id); + if (ret) { + dev_err(&i2c->dev, "dev_read_chipid failed ret=3D%d", ret); + return ret; + } + + aw_dev->chip_id =3D chip_id; + aw_dev->acf =3D NULL; + aw_dev->prof_info.prof_desc =3D NULL; + aw_dev->prof_info.count =3D 0; + aw_dev->prof_info.prof_type =3D AW_DEV_NONE_TYPE_ID; + aw_dev->channel =3D 0; + aw_dev->fw_status =3D AW_DEV_FW_FAILED; + + aw_dev->fade_step =3D AW_VOLUME_STEP_DB; + aw_dev->volume_desc.ctl_volume =3D AW_VOL_DEFAULT_VALUE; + + aw_dev->fade_in_time =3D AW_1000_US / 10; + aw_dev->fade_out_time =3D AW_1000_US >> 1; + + aw_parse_channel_dt(aw_dev); + + return 0; +} +EXPORT_SYMBOL_GPL(aw_dev_init); + +int aw_dev_request_firmware_file(struct aw_device *aw_dev, char *acf_name) +{ + const struct firmware *cont =3D NULL; + int ret; + + aw_dev->fw_status =3D AW_DEV_FW_FAILED; + + ret =3D request_firmware(&cont, acf_name, aw_dev->dev); + if ((ret < 0) || (!cont)) { + dev_err(aw_dev->dev, "load [%s] failed!", acf_name); + return ret; + } + + dev_dbg(aw_dev->dev, "loaded %s - size: %zu\n", acf_name, cont ? cont->si= ze : 0); + + aw_dev->aw_cfg =3D devm_kzalloc(aw_dev->dev, cont->size + sizeof(int), GF= P_KERNEL); + if (!aw_dev->aw_cfg) { + release_firmware(cont); + return -ENOMEM; + } + + aw_dev->aw_cfg->len =3D (int)cont->size; + memcpy(aw_dev->aw_cfg->data, cont->data, cont->size); + release_firmware(cont); + + ret =3D aw_dev_load_acf_check(aw_dev, aw_dev->aw_cfg); + if (ret < 0) { + dev_err(aw_dev->dev, "Load [%s] failed ....!", acf_name); + return ret; + } + + ret =3D aw_dev_cfg_load(aw_dev, aw_dev->aw_cfg); + if (ret) { + dev_err(aw_dev->dev, "aw_dev acf parse failed"); + return -EINVAL; + } + + aw_dev->prof_cur =3D aw_dev->prof_info.prof_desc[0].id; + aw_dev->prof_index =3D aw_dev->prof_info.prof_desc[0].id; + + return ret; +} +EXPORT_SYMBOL_GPL(aw_dev_request_firmware_file); + +void aw_dev_fade_in(struct aw_device *aw_dev, + void (*set_volume)(struct aw_device *aw_dev, unsigned int value)) +{ + struct aw_volume_desc *desc =3D &aw_dev->volume_desc; + u16 fade_in_vol =3D desc->ctl_volume; + int fade_step =3D aw_dev->fade_step; + int i; + + if (fade_step =3D=3D 0 || aw_dev->fade_in_time =3D=3D 0) { + set_volume(aw_dev, fade_in_vol); + return; + } + + for (i =3D desc->mute_volume; i >=3D fade_in_vol; i -=3D fade_step) { + set_volume(aw_dev, i); + usleep_range(aw_dev->fade_in_time, aw_dev->fade_in_time + 10); + } + + if (i !=3D fade_in_vol) + set_volume(aw_dev, fade_in_vol); +} +EXPORT_SYMBOL_GPL(aw_dev_fade_in); + +void aw_dev_fade_out(struct aw_device *aw_dev, + void (*set_volume)(struct aw_device *aw_dev, unsigned int value)) +{ + struct aw_volume_desc *desc =3D &aw_dev->volume_desc; + int fade_step =3D aw_dev->fade_step; + int i; + + if (fade_step =3D=3D 0 || aw_dev->fade_out_time =3D=3D 0) { + set_volume(aw_dev, desc->mute_volume); + return; + } + + for (i =3D desc->ctl_volume; i <=3D desc->mute_volume; i +=3D fade_step) { + set_volume(aw_dev, i); + usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10); + } + + if (i !=3D desc->mute_volume) { + set_volume(aw_dev, desc->mute_volume); + usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10); + } +} +EXPORT_SYMBOL_GPL(aw_dev_fade_out); + +void aw_hw_reset(struct aw_device *aw_dev) +{ + gpiod_set_value_cansleep(aw_dev->reset_gpio, 1); + usleep_range(AW_1000_US, AW_1000_US + 10); + gpiod_set_value_cansleep(aw_dev->reset_gpio, 0); + usleep_range(AW_1000_US, AW_1000_US + 10); +} +EXPORT_SYMBOL_GPL(aw_hw_reset); + +MODULE_DESCRIPTION("awinic device lib"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/aw-common-device.h b/sound/soc/codecs/aw-comm= on-device.h new file mode 100644 index 000000000000..32d21c428455 --- /dev/null +++ b/sound/soc/codecs/aw-common-device.h @@ -0,0 +1,206 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// aw-dev-common.h -- awinic amp common driver interface +// +// Copyright (c) 2025 AWINIC Technology CO., LTD +// +// Author: Weidong Wang +// + +#ifndef __AW_COMMON_DEVICE_H__ +#define __AW_COMMON_DEVICE_H__ + +#define AW_ID_REG (0x00) +#define AW_SYSINT_REG (0x02) +#define AW_DSPMADD_REG (0x40) +#define AW_DSPMDAT_REG (0x41) +#define AW_WDT_REG (0x42) +#define AW_DSP_16_DATA_MASK (0x0000ffff) +#define AW_WDT_CNT_START_BIT (0) +#define AW_WDT_CNT_BITS_LEN (8) +#define AW_WDT_CNT_MASK \ + (~(((1< +// Author: Weidong Wang // =20 #include #include #include -#include "aw88395_lib.h" -#include "aw88395_device.h" +#include "aw-common-firmware.h" =20 -#define AW88395_CRC8_POLYNOMIAL 0x8C +#define AW_CRC8_POLYNOMIAL 0x8C DECLARE_CRC8_TABLE(aw_crc8_table); =20 -static char *profile_name[AW88395_PROFILE_MAX] =3D { +static char *profile_name[AW_PROFILE_MAX] =3D { "Music", "Voice", "Voip", "Ringtone", "Ringtone_hs", "Lowpower", "Bypass", "Mmi", "Fm", "Notification", "Receiver" @@ -319,10 +318,10 @@ static int aw_parsing_bin_file(struct aw_device *aw_d= ev, struct aw_bin *bin) static int aw_dev_parse_raw_reg(unsigned char *data, unsigned int data_len, struct aw_prof_desc *prof_desc) { - prof_desc->sec_desc[AW88395_DATA_TYPE_REG].data =3D data; - prof_desc->sec_desc[AW88395_DATA_TYPE_REG].len =3D data_len; + prof_desc->sec_desc[AW_DATA_TYPE_REG].data =3D data; + prof_desc->sec_desc[AW_DATA_TYPE_REG].len =3D data_len; =20 - prof_desc->prof_st =3D AW88395_PROFILE_OK; + prof_desc->prof_st =3D AW_PROFILE_OK; =20 return 0; } @@ -335,10 +334,10 @@ static int aw_dev_parse_raw_dsp_cfg(unsigned char *da= ta, unsigned int data_len, =20 swab16_array((u16 *)data, data_len >> 1); =20 - prof_desc->sec_desc[AW88395_DATA_TYPE_DSP_CFG].data =3D data; - prof_desc->sec_desc[AW88395_DATA_TYPE_DSP_CFG].len =3D data_len; + prof_desc->sec_desc[AW_DATA_TYPE_DSP_CFG].data =3D data; + prof_desc->sec_desc[AW_DATA_TYPE_DSP_CFG].len =3D data_len; =20 - prof_desc->prof_st =3D AW88395_PROFILE_OK; + prof_desc->prof_st =3D AW_PROFILE_OK; =20 return 0; } @@ -351,10 +350,10 @@ static int aw_dev_parse_raw_dsp_fw(unsigned char *dat= a, unsigned int data_len, =20 swab16_array((u16 *)data, data_len >> 1); =20 - prof_desc->sec_desc[AW88395_DATA_TYPE_DSP_FW].data =3D data; - prof_desc->sec_desc[AW88395_DATA_TYPE_DSP_FW].len =3D data_len; + prof_desc->sec_desc[AW_DATA_TYPE_DSP_FW].data =3D data; + prof_desc->sec_desc[AW_DATA_TYPE_DSP_FW].len =3D data_len; =20 - prof_desc->prof_st =3D AW88395_PROFILE_OK; + prof_desc->prof_st =3D AW_PROFILE_OK; =20 return 0; } @@ -362,8 +361,7 @@ static int aw_dev_parse_raw_dsp_fw(unsigned char *data,= unsigned int data_len, static int aw_dev_prof_parse_multi_bin(struct aw_device *aw_dev, unsigned = char *data, unsigned int data_len, struct aw_prof_desc *prof_desc) { - int ret; - int i; + int ret, i; =20 struct aw_bin *aw_bin __free(kfree) =3D kzalloc(data_len + sizeof(struct = aw_bin), GFP_KERNEL); @@ -382,9 +380,9 @@ static int aw_dev_prof_parse_multi_bin(struct aw_device= *aw_dev, unsigned char * for (i =3D 0; i < aw_bin->all_bin_parse_num; i++) { switch (aw_bin->header_info[i].bin_data_type) { case DATA_TYPE_REGISTER: - prof_desc->sec_desc[AW88395_DATA_TYPE_REG].len =3D + prof_desc->sec_desc[AW_DATA_TYPE_REG].len =3D aw_bin->header_info[i].valid_data_len; - prof_desc->sec_desc[AW88395_DATA_TYPE_REG].data =3D + prof_desc->sec_desc[AW_DATA_TYPE_REG].data =3D data + aw_bin->header_info[i].valid_data_addr; break; case DATA_TYPE_DSP_REG: @@ -394,10 +392,12 @@ static int aw_dev_prof_parse_multi_bin(struct aw_devi= ce *aw_dev, unsigned char * swab16_array((u16 *)(data + aw_bin->header_info[i].valid_data_addr), aw_bin->header_info[i].valid_data_len >> 1); =20 - prof_desc->sec_desc[AW88395_DATA_TYPE_DSP_CFG].len =3D + prof_desc->sec_desc[AW_DATA_TYPE_DSP_CFG].len =3D aw_bin->header_info[i].valid_data_len; - prof_desc->sec_desc[AW88395_DATA_TYPE_DSP_CFG].data =3D + prof_desc->sec_desc[AW_DATA_TYPE_DSP_CFG].data =3D data + aw_bin->header_info[i].valid_data_addr; + prof_desc->sec_desc[AW_DATA_TYPE_DSP_CFG].addr =3D + aw_bin->header_info[i].download_addr; break; case DATA_TYPE_DSP_FW: case DATA_TYPE_SOC_APP: @@ -408,17 +408,19 @@ static int aw_dev_prof_parse_multi_bin(struct aw_devi= ce *aw_dev, unsigned char * aw_bin->header_info[i].valid_data_len >> 1); =20 prof_desc->fw_ver =3D aw_bin->header_info[i].app_version; - prof_desc->sec_desc[AW88395_DATA_TYPE_DSP_FW].len =3D + prof_desc->sec_desc[AW_DATA_TYPE_DSP_FW].len =3D aw_bin->header_info[i].valid_data_len; - prof_desc->sec_desc[AW88395_DATA_TYPE_DSP_FW].data =3D + prof_desc->sec_desc[AW_DATA_TYPE_DSP_FW].data =3D data + aw_bin->header_info[i].valid_data_addr; + prof_desc->sec_desc[AW_DATA_TYPE_DSP_FW].addr =3D + aw_bin->header_info[i].download_addr; break; default: dev_dbg(aw_dev->dev, "bin_data_type not found"); break; } } - prof_desc->prof_st =3D AW88395_PROFILE_OK; + prof_desc->prof_st =3D AW_PROFILE_OK; =20 return 0; } @@ -448,11 +450,11 @@ static int aw_dev_parse_reg_bin_with_hdr(struct aw_de= vice *aw_dev, return -EINVAL; } =20 - prof_desc->sec_desc[AW88395_DATA_TYPE_REG].data =3D + prof_desc->sec_desc[AW_DATA_TYPE_REG].data =3D data + aw_bin->header_info[0].valid_data_addr; - prof_desc->sec_desc[AW88395_DATA_TYPE_REG].len =3D + prof_desc->sec_desc[AW_DATA_TYPE_REG].len =3D aw_bin->header_info[0].valid_data_len; - prof_desc->prof_st =3D AW88395_PROFILE_OK; + prof_desc->prof_st =3D AW_PROFILE_OK; =20 return 0; } @@ -497,9 +499,9 @@ static int aw_dev_parse_dev_type(struct aw_device *aw_d= ev, for (i =3D 0; i < prof_hdr->ddt_num; i++) { if ((aw_dev->i2c->adapter->nr =3D=3D cfg_dde[i].dev_bus) && (aw_dev->i2c->addr =3D=3D cfg_dde[i].dev_addr) && - (cfg_dde[i].type =3D=3D AW88395_DEV_TYPE_ID) && + (cfg_dde[i].type =3D=3D AW_DEV_TYPE_ID) && (cfg_dde[i].data_type !=3D ACF_SEC_TYPE_MONITOR)) { - if (cfg_dde[i].dev_profile >=3D AW88395_PROFILE_MAX) { + if (cfg_dde[i].dev_profile >=3D AW_PROFILE_MAX) { dev_err(aw_dev->dev, "dev_profile [%d] overflow", cfg_dde[i].dev_profile); return -EINVAL; @@ -517,10 +519,10 @@ static int aw_dev_parse_dev_type(struct aw_device *aw= _dev, =20 if (sec_num =3D=3D 0) { dev_dbg(aw_dev->dev, "get dev type num is %d, please use default", sec_n= um); - return AW88395_DEV_TYPE_NONE; + return AW_DEV_TYPE_NONE; } =20 - return AW88395_DEV_TYPE_OK; + return AW_DEV_TYPE_OK; } =20 static int aw_dev_parse_dev_default_type(struct aw_device *aw_dev, @@ -533,9 +535,9 @@ static int aw_dev_parse_dev_default_type(struct aw_devi= ce *aw_dev, =20 for (i =3D 0; i < prof_hdr->ddt_num; i++) { if ((aw_dev->channel =3D=3D cfg_dde[i].dev_index) && - (cfg_dde[i].type =3D=3D AW88395_DEV_DEFAULT_TYPE_ID) && + (cfg_dde[i].type =3D=3D AW_DEV_DEFAULT_TYPE_ID) && (cfg_dde[i].data_type !=3D ACF_SEC_TYPE_MONITOR)) { - if (cfg_dde[i].dev_profile >=3D AW88395_PROFILE_MAX) { + if (cfg_dde[i].dev_profile >=3D AW_PROFILE_MAX) { dev_err(aw_dev->dev, "dev_profile [%d] overflow", cfg_dde[i].dev_profile); return -EINVAL; @@ -567,8 +569,8 @@ static int aw_dev_cfg_get_reg_valid_prof(struct aw_devi= ce *aw_dev, int num =3D 0; int i; =20 - for (i =3D 0; i < AW88395_PROFILE_MAX; i++) { - if (prof_desc[i].prof_st =3D=3D AW88395_PROFILE_OK) + for (i =3D 0; i < AW_PROFILE_MAX; i++) { + if (prof_desc[i].prof_st =3D=3D AW_PROFILE_OK) prof_info->count++; } =20 @@ -585,8 +587,8 @@ static int aw_dev_cfg_get_reg_valid_prof(struct aw_devi= ce *aw_dev, if (!prof_info->prof_desc) return -ENOMEM; =20 - for (i =3D 0; i < AW88395_PROFILE_MAX; i++) { - if (prof_desc[i].prof_st =3D=3D AW88395_PROFILE_OK) { + for (i =3D 0; i < AW_PROFILE_MAX; i++) { + if (prof_desc[i].prof_st =3D=3D AW_PROFILE_OK) { if (num >=3D prof_info->count) { dev_err(aw_dev->dev, "overflow count[%d]", prof_info->count); @@ -610,15 +612,15 @@ static int aw_dev_cfg_get_multiple_valid_prof(struct = aw_device *aw_dev, int num =3D 0; int i; =20 - for (i =3D 0; i < AW88395_PROFILE_MAX; i++) { - if (prof_desc[i].prof_st =3D=3D AW88395_PROFILE_OK) { + for (i =3D 0; i < AW_PROFILE_MAX; i++) { + if (prof_desc[i].prof_st =3D=3D AW_PROFILE_OK) { sec_desc =3D prof_desc[i].sec_desc; - if ((sec_desc[AW88395_DATA_TYPE_REG].data !=3D NULL) && - (sec_desc[AW88395_DATA_TYPE_REG].len !=3D 0) && - (sec_desc[AW88395_DATA_TYPE_DSP_CFG].data !=3D NULL) && - (sec_desc[AW88395_DATA_TYPE_DSP_CFG].len !=3D 0) && - (sec_desc[AW88395_DATA_TYPE_DSP_FW].data !=3D NULL) && - (sec_desc[AW88395_DATA_TYPE_DSP_FW].len !=3D 0)) + if ((sec_desc[AW_DATA_TYPE_REG].data !=3D NULL) && + (sec_desc[AW_DATA_TYPE_REG].len !=3D 0) && + (sec_desc[AW_DATA_TYPE_DSP_CFG].data !=3D NULL) && + (sec_desc[AW_DATA_TYPE_DSP_CFG].len !=3D 0) && + (sec_desc[AW_DATA_TYPE_DSP_FW].data !=3D NULL) && + (sec_desc[AW_DATA_TYPE_DSP_FW].len !=3D 0)) prof_info->count++; } } @@ -636,15 +638,15 @@ static int aw_dev_cfg_get_multiple_valid_prof(struct = aw_device *aw_dev, if (!prof_info->prof_desc) return -ENOMEM; =20 - for (i =3D 0; i < AW88395_PROFILE_MAX; i++) { - if (prof_desc[i].prof_st =3D=3D AW88395_PROFILE_OK) { + for (i =3D 0; i < AW_PROFILE_MAX; i++) { + if (prof_desc[i].prof_st =3D=3D AW_PROFILE_OK) { sec_desc =3D prof_desc[i].sec_desc; - if ((sec_desc[AW88395_DATA_TYPE_REG].data !=3D NULL) && - (sec_desc[AW88395_DATA_TYPE_REG].len !=3D 0) && - (sec_desc[AW88395_DATA_TYPE_DSP_CFG].data !=3D NULL) && - (sec_desc[AW88395_DATA_TYPE_DSP_CFG].len !=3D 0) && - (sec_desc[AW88395_DATA_TYPE_DSP_FW].data !=3D NULL) && - (sec_desc[AW88395_DATA_TYPE_DSP_FW].len !=3D 0)) { + if ((sec_desc[AW_DATA_TYPE_REG].data !=3D NULL) && + (sec_desc[AW_DATA_TYPE_REG].len !=3D 0) && + (sec_desc[AW_DATA_TYPE_DSP_CFG].data !=3D NULL) && + (sec_desc[AW_DATA_TYPE_DSP_CFG].len !=3D 0) && + (sec_desc[AW_DATA_TYPE_DSP_FW].data !=3D NULL) && + (sec_desc[AW_DATA_TYPE_DSP_FW].len !=3D 0)) { if (num >=3D prof_info->count) { dev_err(aw_dev->dev, "overflow count[%d]", prof_info->count); @@ -673,7 +675,7 @@ static int aw_dev_load_cfg_by_hdr(struct aw_device *aw_= dev, ret =3D aw_dev_parse_dev_type(aw_dev, prof_hdr, all_prof_info); if (ret < 0) { return ret; - } else if (ret =3D=3D AW88395_DEV_TYPE_NONE) { + } else if (ret =3D=3D AW_DEV_TYPE_NONE) { dev_dbg(aw_dev->dev, "get dev type num is 0, parse default dev"); ret =3D aw_dev_parse_dev_default_type(aw_dev, prof_hdr, all_prof_info); if (ret < 0) @@ -734,17 +736,17 @@ static int aw_get_dde_type_info(struct aw_device *aw_= dev, struct aw_container *a unsigned int i; =20 for (i =3D 0; i < cfg_hdr->ddt_num; i++) { - if (cfg_dde[i].type =3D=3D AW88395_DEV_TYPE_ID) + if (cfg_dde[i].type =3D=3D AW_DEV_TYPE_ID) dev_num++; =20 - if (cfg_dde[i].type =3D=3D AW88395_DEV_DEFAULT_TYPE_ID) + if (cfg_dde[i].type =3D=3D AW_DEV_DEFAULT_TYPE_ID) default_num++; } =20 if (dev_num !=3D 0) { - aw_dev->prof_info.prof_type =3D AW88395_DEV_TYPE_ID; + aw_dev->prof_info.prof_type =3D AW_DEV_TYPE_ID; } else if (default_num !=3D 0) { - aw_dev->prof_info.prof_type =3D AW88395_DEV_DEFAULT_TYPE_ID; + aw_dev->prof_info.prof_type =3D AW_DEV_DEFAULT_TYPE_ID; } else { dev_err(aw_dev->dev, "can't find scene"); return -EINVAL; @@ -817,10 +819,10 @@ static int aw_dev_parse_scene_count_v1(struct aw_devi= ce *aw_dev, return ret; =20 switch (aw_dev->prof_info.prof_type) { - case AW88395_DEV_TYPE_ID: + case AW_DEV_TYPE_ID: ret =3D aw_get_dev_scene_count_v1(aw_dev, aw_cfg, count); break; - case AW88395_DEV_DEFAULT_TYPE_ID: + case AW_DEV_DEFAULT_TYPE_ID: ret =3D aw_get_default_scene_count_v1(aw_dev, aw_cfg, count); break; default: @@ -937,10 +939,10 @@ static int aw_dev_parse_by_hdr_v1(struct aw_device *a= w_dev, int ret; =20 switch (aw_dev->prof_info.prof_type) { - case AW88395_DEV_TYPE_ID: + case AW_DEV_TYPE_ID: ret =3D aw_dev_parse_dev_type_v1(aw_dev, cfg_hdr); break; - case AW88395_DEV_DEFAULT_TYPE_ID: + case AW_DEV_DEFAULT_TYPE_ID: ret =3D aw_dev_parse_default_type_v1(aw_dev, cfg_hdr); break; default: @@ -987,7 +989,7 @@ static int aw_dev_load_cfg_by_hdr_v1(struct aw_device *= aw_dev, return 0; } =20 -int aw88395_dev_cfg_load(struct aw_device *aw_dev, struct aw_container *aw= _cfg) +int aw_dev_cfg_load(struct aw_device *aw_dev, struct aw_container *aw_cfg) { struct aw_cfg_hdr *cfg_hdr; int ret; @@ -995,7 +997,7 @@ int aw88395_dev_cfg_load(struct aw_device *aw_dev, stru= ct aw_container *aw_cfg) cfg_hdr =3D (struct aw_cfg_hdr *)aw_cfg->data; =20 switch (cfg_hdr->hdr_version) { - case AW88395_CFG_HDR_VER: + case AW_CFG_HDR_VER: ret =3D aw_dev_load_cfg_by_hdr(aw_dev, cfg_hdr); if (ret < 0) { dev_err(aw_dev->dev, "hdr_version[0x%x] parse failed", @@ -1003,7 +1005,7 @@ int aw88395_dev_cfg_load(struct aw_device *aw_dev, st= ruct aw_container *aw_cfg) return ret; } break; - case AW88395_CFG_HDR_VER_V1: + case AW_CFG_HDR_VER_V1: ret =3D aw_dev_load_cfg_by_hdr_v1(aw_dev, aw_cfg); if (ret < 0) { dev_err(aw_dev->dev, "hdr_version[0x%x] parse failed", @@ -1015,11 +1017,11 @@ int aw88395_dev_cfg_load(struct aw_device *aw_dev, = struct aw_container *aw_cfg) dev_err(aw_dev->dev, "unsupported hdr_version [0x%x]", cfg_hdr->hdr_vers= ion); return -EINVAL; } - aw_dev->fw_status =3D AW88395_DEV_FW_OK; + aw_dev->fw_status =3D AW_DEV_FW_OK; =20 return 0; } -EXPORT_SYMBOL_GPL(aw88395_dev_cfg_load); +EXPORT_SYMBOL_GPL(aw_dev_cfg_load); =20 static int aw_dev_check_cfg_by_hdr(struct aw_device *aw_dev, struct aw_con= tainer *aw_cfg) { @@ -1138,7 +1140,7 @@ static int aw_dev_check_acf_by_hdr_v1(struct aw_devic= e *aw_dev, struct aw_contai return 0; } =20 -int aw88395_dev_load_acf_check(struct aw_device *aw_dev, struct aw_contain= er *aw_cfg) +int aw_dev_load_acf_check(struct aw_device *aw_dev, struct aw_container *a= w_cfg) { struct aw_cfg_hdr *cfg_hdr; =20 @@ -1153,13 +1155,13 @@ int aw88395_dev_load_acf_check(struct aw_device *aw= _dev, struct aw_container *aw return -EINVAL; } =20 - crc8_populate_lsb(aw_crc8_table, AW88395_CRC8_POLYNOMIAL); + crc8_populate_lsb(aw_crc8_table, AW_CRC8_POLYNOMIAL); =20 cfg_hdr =3D (struct aw_cfg_hdr *)aw_cfg->data; switch (cfg_hdr->hdr_version) { - case AW88395_CFG_HDR_VER: + case AW_CFG_HDR_VER: return aw_dev_check_cfg_by_hdr(aw_dev, aw_cfg); - case AW88395_CFG_HDR_VER_V1: + case AW_CFG_HDR_VER_V1: return aw_dev_check_acf_by_hdr_v1(aw_dev, aw_cfg); default: dev_err(aw_dev->dev, "unsupported hdr_version [0x%x]", cfg_hdr->hdr_vers= ion); @@ -1168,7 +1170,7 @@ int aw88395_dev_load_acf_check(struct aw_device *aw_d= ev, struct aw_container *aw =20 return 0; } -EXPORT_SYMBOL_GPL(aw88395_dev_load_acf_check); +EXPORT_SYMBOL_GPL(aw_dev_load_acf_check); =20 -MODULE_DESCRIPTION("AW88395 ACF File Parsing Lib"); +MODULE_DESCRIPTION("awinic firmware lib"); MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/aw-common-firmware.h b/sound/soc/codecs/aw-co= mmon-firmware.h new file mode 100644 index 000000000000..e6722a4448a2 --- /dev/null +++ b/sound/soc/codecs/aw-common-firmware.h @@ -0,0 +1,211 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// aw-common-firmware.h -- awinic amp common firmware interface +// +// Copyright (c) 2025 AWINIC Technology CO., LTD +// +// Author: Weidong Wang +// + +#ifndef __AW_COMMON_FIRMWARE_H__ +#define __AW_COMMON_FIRMWARE_H__ + +#include "aw-common-device.h" + +#define CHECK_REGISTER_NUM_OFFSET (4) +#define VALID_DATA_LEN (4) +#define VALID_DATA_ADDR (4) +#define PARSE_DSP_REG_NUM (4) +#define REG_DATA_BYTP_LEN (8) +#define CHECK_DSP_REG_NUM (12) +#define DSP_VALID_DATA_LEN (12) +#define DSP_VALID_DATA_ADDR (12) +#define PARSE_SOC_APP_NUM (8) +#define CHECK_SOC_APP_NUM (12) +#define APP_DOWNLOAD_ADDR (4) +#define APP_VALID_DATA_LEN (12) +#define APP_VALID_DATA_ADDR (12) +#define BIN_NUM_MAX (100) +#define HEADER_LEN (60) +#define BIN_DATA_TYPE_OFFSET (8) +#define DATA_LEN (44) +#define VALID_DATA_ADDR_OFFSET (60) +#define START_ADDR_OFFSET (64) + +#define HDADER_LEN (60) + +#define HEADER_VERSION_OFFSET (4) + +#define PROJECT_NAME_MAX (24) +#define CUSTOMER_NAME_MAX (16) +#define CFG_VERSION_MAX (4) +#define DEV_NAME_MAX (16) +#define PROFILE_STR_MAX (32) + +#define ACF_FILE_ID (0xa15f908) + +enum bin_header_version_enum { + HEADER_VERSION_V1 =3D 0x01000000, +}; + +enum data_type_enum { + DATA_TYPE_REGISTER =3D 0x00000000, + DATA_TYPE_DSP_REG =3D 0x00000010, + DATA_TYPE_DSP_CFG =3D 0x00000011, + DATA_TYPE_SOC_REG =3D 0x00000020, + DATA_TYPE_SOC_APP =3D 0x00000021, + DATA_TYPE_DSP_FW =3D 0x00000022, + DATA_TYPE_MULTI_BINS =3D 0x00002000, +}; + +enum data_version_enum { + DATA_VERSION_V1 =3D 0x00000001, + DATA_VERSION_MAX, +}; + +enum aw_sec_type { + ACF_SEC_TYPE_REG =3D 0, + ACF_SEC_TYPE_DSP, + ACF_SEC_TYPE_DSP_CFG, + ACF_SEC_TYPE_DSP_FW, + ACF_SEC_TYPE_HDR_REG, + ACF_SEC_TYPE_HDR_DSP_CFG, + ACF_SEC_TYPE_HDR_DSP_FW, + ACF_SEC_TYPE_MULTIPLE_BIN, + ACF_SEC_TYPE_SKT_PROJECT, + ACF_SEC_TYPE_DSP_PROJECT, + ACF_SEC_TYPE_MONITOR, + ACF_SEC_TYPE_MAX, +}; + +enum aw_prof_type { + AW_PROFILE_MUSIC =3D 0, + AW_PROFILE_VOICE, + AW_PROFILE_VOIP, + AW_PROFILE_RINGTONE, + AW_PROFILE_RINGTONE_HS, + AW_PROFILE_LOWPOWER, + AW_PROFILE_BYPASS, + AW_PROFILE_MMI, + AW_PROFILE_FM, + AW_PROFILE_NOTIFICATION, + AW_PROFILE_RECEIVER, + AW_PROFILE_MAX, +}; + +enum profile_data_type { + AW_DATA_TYPE_REG =3D 0, + AW_DATA_TYPE_DSP_CFG, + AW_DATA_TYPE_DSP_FW, + AW_DATA_TYPE_MAX, +}; + +enum { + AW_DEV_TYPE_OK =3D 0, + AW_DEV_TYPE_NONE =3D 1, +}; + +enum aw_cfg_dde_type { + AW_DEV_NONE_TYPE_ID =3D 0xFFFFFFFF, + AW_DEV_TYPE_ID =3D 0x00000000, + AW_SKT_TYPE_ID =3D 0x00000001, + AW_DEV_DEFAULT_TYPE_ID =3D 0x00000002, +}; + +enum aw_profile_status { + AW_PROFILE_WAIT =3D 0, + AW_PROFILE_OK, +}; + +enum aw_cfg_hdr_version { + AW_CFG_HDR_VER =3D 0x00000001, + AW_CFG_HDR_VER_V1 =3D 0x01000000, +}; + +struct aw_cfg_hdr { + u32 id; + char project[PROJECT_NAME_MAX]; + char custom[CUSTOMER_NAME_MAX]; + char version[CFG_VERSION_MAX]; + u32 author_id; + u32 ddt_size; + u32 ddt_num; + u32 hdr_offset; + u32 hdr_version; + u32 reserved[3]; +}; + +struct aw_cfg_dde { + u32 type; + char dev_name[DEV_NAME_MAX]; + u16 dev_index; + u16 dev_bus; + u16 dev_addr; + u16 dev_profile; + u32 data_type; + u32 data_size; + u32 data_offset; + u32 data_crc; + u32 reserved[5]; +}; + +struct aw_cfg_dde_v1 { + u32 type; + char dev_name[DEV_NAME_MAX]; + u16 dev_index; + u16 dev_bus; + u16 dev_addr; + u16 dev_profile; + u32 data_type; + u32 data_size; + u32 data_offset; + u32 data_crc; + char dev_profile_str[PROFILE_STR_MAX]; + u32 chip_id; + u32 reserved[4]; +}; + +struct bin_header_info { + unsigned int check_sum; + unsigned int header_ver; + unsigned int bin_data_type; + unsigned int bin_data_ver; + unsigned int bin_data_len; + unsigned int ui_ver; + unsigned char chip_type[8]; + unsigned int reg_byte_len; + unsigned int data_byte_len; + unsigned int device_addr; + unsigned int valid_data_len; + unsigned int valid_data_addr; + + unsigned int reg_num; + unsigned int reg_data_byte_len; + unsigned int download_addr; + unsigned int app_version; + unsigned int header_len; +}; + +struct aw_container { + int len; + u8 data[]; +}; + +struct bin_container { + unsigned int len; + unsigned char data[]; +}; + +struct aw_bin { + unsigned char *p_addr; + unsigned int all_bin_parse_num; + unsigned int multi_bin_parse_num; + unsigned int single_bin_parse_num; + struct bin_header_info header_info[BIN_NUM_MAX]; + struct bin_container info; +}; + +int aw_dev_load_acf_check(struct aw_device *aw_dev, struct aw_container *a= w_cfg); +int aw_dev_cfg_load(struct aw_device *aw_dev, struct aw_container *aw_cfg); + +#endif diff --git a/sound/soc/codecs/aw88395/aw88395_data_type.h b/sound/soc/codec= s/aw88395/aw88395_data_type.h deleted file mode 100644 index e7aa56178b36..000000000000 --- a/sound/soc/codecs/aw88395/aw88395_data_type.h +++ /dev/null @@ -1,142 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// -// aw883_data_type.h -- The data type of the AW88395 chip -// -// Copyright (c) 2022-2023 AWINIC Technology CO., LTD -// -// Author: Bruce zhao -// - -#ifndef __AW88395_DATA_TYPE_H__ -#define __AW88395_DATA_TYPE_H__ - -#define PROJECT_NAME_MAX (24) -#define CUSTOMER_NAME_MAX (16) -#define CFG_VERSION_MAX (4) -#define DEV_NAME_MAX (16) -#define PROFILE_STR_MAX (32) - -#define ACF_FILE_ID (0xa15f908) - -enum aw_cfg_hdr_version { - AW88395_CFG_HDR_VER =3D 0x00000001, - AW88395_CFG_HDR_VER_V1 =3D 0x01000000, -}; - -enum aw_cfg_dde_type { - AW88395_DEV_NONE_TYPE_ID =3D 0xFFFFFFFF, - AW88395_DEV_TYPE_ID =3D 0x00000000, - AW88395_SKT_TYPE_ID =3D 0x00000001, - AW88395_DEV_DEFAULT_TYPE_ID =3D 0x00000002, -}; - -enum aw_sec_type { - ACF_SEC_TYPE_REG =3D 0, - ACF_SEC_TYPE_DSP, - ACF_SEC_TYPE_DSP_CFG, - ACF_SEC_TYPE_DSP_FW, - ACF_SEC_TYPE_HDR_REG, - ACF_SEC_TYPE_HDR_DSP_CFG, - ACF_SEC_TYPE_HDR_DSP_FW, - ACF_SEC_TYPE_MULTIPLE_BIN, - ACF_SEC_TYPE_SKT_PROJECT, - ACF_SEC_TYPE_DSP_PROJECT, - ACF_SEC_TYPE_MONITOR, - ACF_SEC_TYPE_MAX, -}; - -enum profile_data_type { - AW88395_DATA_TYPE_REG =3D 0, - AW88395_DATA_TYPE_DSP_CFG, - AW88395_DATA_TYPE_DSP_FW, - AW88395_DATA_TYPE_MAX, -}; - -enum aw_prof_type { - AW88395_PROFILE_MUSIC =3D 0, - AW88395_PROFILE_VOICE, - AW88395_PROFILE_VOIP, - AW88395_PROFILE_RINGTONE, - AW88395_PROFILE_RINGTONE_HS, - AW88395_PROFILE_LOWPOWER, - AW88395_PROFILE_BYPASS, - AW88395_PROFILE_MMI, - AW88395_PROFILE_FM, - AW88395_PROFILE_NOTIFICATION, - AW88395_PROFILE_RECEIVER, - AW88395_PROFILE_MAX, -}; - -enum aw_profile_status { - AW88395_PROFILE_WAIT =3D 0, - AW88395_PROFILE_OK, -}; - -struct aw_cfg_hdr { - u32 id; - char project[PROJECT_NAME_MAX]; - char custom[CUSTOMER_NAME_MAX]; - char version[CFG_VERSION_MAX]; - u32 author_id; - u32 ddt_size; - u32 ddt_num; - u32 hdr_offset; - u32 hdr_version; - u32 reserved[3]; -}; - -struct aw_cfg_dde { - u32 type; - char dev_name[DEV_NAME_MAX]; - u16 dev_index; - u16 dev_bus; - u16 dev_addr; - u16 dev_profile; - u32 data_type; - u32 data_size; - u32 data_offset; - u32 data_crc; - u32 reserved[5]; -}; - -struct aw_cfg_dde_v1 { - u32 type; - char dev_name[DEV_NAME_MAX]; - u16 dev_index; - u16 dev_bus; - u16 dev_addr; - u16 dev_profile; - u32 data_type; - u32 data_size; - u32 data_offset; - u32 data_crc; - char dev_profile_str[PROFILE_STR_MAX]; - u32 chip_id; - u32 reserved[4]; -}; - -struct aw_sec_data_desc { - u32 len; - u8 *data; -}; - -struct aw_prof_desc { - u32 id; - u32 prof_st; - char *prf_str; - u32 fw_ver; - struct aw_sec_data_desc sec_desc[AW88395_DATA_TYPE_MAX]; -}; - -struct aw_all_prof_info { - struct aw_prof_desc prof_desc[AW88395_PROFILE_MAX]; -}; - -struct aw_prof_info { - int count; - int prof_type; - char **prof_name_list; - struct aw_prof_desc *prof_desc; -}; - -#endif diff --git a/sound/soc/codecs/aw88395/aw88395_device.c b/sound/soc/codecs/a= w88395/aw88395_device.c deleted file mode 100644 index e1430940015d..000000000000 --- a/sound/soc/codecs/aw88395/aw88395_device.c +++ /dev/null @@ -1,1720 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// -// aw88395_device.c -- AW88395 function for ALSA Audio Driver -// -// Copyright (c) 2022-2023 AWINIC Technology CO., LTD -// -// Author: Bruce zhao -// Author: Ben Yi -// - -#include -#include -#include -#include -#include "aw88395_device.h" -#include "aw88395_reg.h" - -static int aw_dev_dsp_write_16bit(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int dsp_data) -{ - int ret; - - ret =3D regmap_write(aw_dev->regmap, AW88395_DSPMADD_REG, dsp_addr); - if (ret) { - dev_err(aw_dev->dev, "%s write addr error, ret=3D%d", __func__, ret); - return ret; - } - - ret =3D regmap_write(aw_dev->regmap, AW88395_DSPMDAT_REG, (u16)dsp_data); - if (ret) { - dev_err(aw_dev->dev, "%s write data error, ret=3D%d", __func__, ret); - return ret; - } - - return 0; -} - -static int aw_dev_dsp_write_32bit(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int dsp_data) -{ - u16 temp_data; - int ret; - - ret =3D regmap_write(aw_dev->regmap, AW88395_DSPMADD_REG, dsp_addr); - if (ret) { - dev_err(aw_dev->dev, "%s write addr error, ret=3D%d", __func__, ret); - return ret; - } - - temp_data =3D dsp_data & AW88395_DSP_16_DATA_MASK; - ret =3D regmap_write(aw_dev->regmap, AW88395_DSPMDAT_REG, (u16)temp_data); - if (ret) { - dev_err(aw_dev->dev, "%s write datal error, ret=3D%d", __func__, ret); - return ret; - } - - temp_data =3D dsp_data >> 16; - ret =3D regmap_write(aw_dev->regmap, AW88395_DSPMDAT_REG, (u16)temp_data); - if (ret) { - dev_err(aw_dev->dev, "%s write datah error, ret=3D%d", __func__, ret); - return ret; - } - - return 0; -} - -static int aw_dev_dsp_write(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int dsp_data, unsigned char data_type) -{ - u32 reg_value; - int ret; - - mutex_lock(&aw_dev->dsp_lock); - switch (data_type) { - case AW88395_DSP_16_DATA: - ret =3D aw_dev_dsp_write_16bit(aw_dev, dsp_addr, dsp_data); - if (ret) - dev_err(aw_dev->dev, "write dsp_addr[0x%x] 16-bit dsp_data[0x%x] failed= ", - (u32)dsp_addr, dsp_data); - break; - case AW88395_DSP_32_DATA: - ret =3D aw_dev_dsp_write_32bit(aw_dev, dsp_addr, dsp_data); - if (ret) - dev_err(aw_dev->dev, "write dsp_addr[0x%x] 32-bit dsp_data[0x%x] failed= ", - (u32)dsp_addr, dsp_data); - break; - default: - dev_err(aw_dev->dev, "data type[%d] unsupported", data_type); - ret =3D -EINVAL; - break; - } - - /* clear dsp chip select state*/ - if (regmap_read(aw_dev->regmap, AW88395_ID_REG, ®_value)) - dev_err(aw_dev->dev, "%s fail to clear chip state. Err=3D%d\n", __func__= , ret); - mutex_unlock(&aw_dev->dsp_lock); - - return ret; -} - -static int aw_dev_dsp_read_16bit(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int *dsp_data) -{ - unsigned int temp_data; - int ret; - - ret =3D regmap_write(aw_dev->regmap, AW88395_DSPMADD_REG, dsp_addr); - if (ret) { - dev_err(aw_dev->dev, "%s write error, ret=3D%d", __func__, ret); - return ret; - } - - ret =3D regmap_read(aw_dev->regmap, AW88395_DSPMDAT_REG, &temp_data); - if (ret) { - dev_err(aw_dev->dev, "%s read error, ret=3D%d", __func__, ret); - return ret; - } - *dsp_data =3D temp_data; - - return 0; -} - -static int aw_dev_dsp_read_32bit(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int *dsp_data) -{ - unsigned int temp_data; - int ret; - - ret =3D regmap_write(aw_dev->regmap, AW88395_DSPMADD_REG, dsp_addr); - if (ret) { - dev_err(aw_dev->dev, "%s write error, ret=3D%d", __func__, ret); - return ret; - } - - ret =3D regmap_read(aw_dev->regmap, AW88395_DSPMDAT_REG, &temp_data); - if (ret) { - dev_err(aw_dev->dev, "%s read error, ret=3D%d", __func__, ret); - return ret; - } - *dsp_data =3D temp_data; - - ret =3D regmap_read(aw_dev->regmap, AW88395_DSPMDAT_REG, &temp_data); - if (ret) { - dev_err(aw_dev->dev, "%s read error, ret=3D%d", __func__, ret); - return ret; - } - *dsp_data |=3D (temp_data << 16); - - return 0; -} - -static int aw_dev_dsp_read(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int *dsp_data, unsigned char data_type) -{ - u32 reg_value; - int ret; - - mutex_lock(&aw_dev->dsp_lock); - switch (data_type) { - case AW88395_DSP_16_DATA: - ret =3D aw_dev_dsp_read_16bit(aw_dev, dsp_addr, dsp_data); - if (ret) - dev_err(aw_dev->dev, "read dsp_addr[0x%x] 16-bit dsp_data[0x%x] failed", - (u32)dsp_addr, *dsp_data); - break; - case AW88395_DSP_32_DATA: - ret =3D aw_dev_dsp_read_32bit(aw_dev, dsp_addr, dsp_data); - if (ret) - dev_err(aw_dev->dev, "read dsp_addr[0x%x] 32r-bit dsp_data[0x%x] failed= ", - (u32)dsp_addr, *dsp_data); - break; - default: - dev_err(aw_dev->dev, "data type[%d] unsupported", data_type); - ret =3D -EINVAL; - break; - } - - /* clear dsp chip select state*/ - if (regmap_read(aw_dev->regmap, AW88395_ID_REG, ®_value)) - dev_err(aw_dev->dev, "%s fail to clear chip state. Err=3D%d\n", __func__= , ret); - mutex_unlock(&aw_dev->dsp_lock); - - return ret; -} - - -static int aw_dev_read_chipid(struct aw_device *aw_dev, u16 *chip_id) -{ - int reg_val; - int ret; - - ret =3D regmap_read(aw_dev->regmap, AW88395_CHIP_ID_REG, ®_val); - if (ret) { - dev_err(aw_dev->dev, "%s read chipid error. ret =3D %d", __func__, ret); - return ret; - } - - dev_info(aw_dev->dev, "chip id =3D %x\n", reg_val); - *chip_id =3D reg_val; - - return 0; -} - -static unsigned int reg_val_to_db(unsigned int value) -{ - return (((value >> AW88395_VOL_6DB_START) * AW88395_VOLUME_STEP_DB) + - ((value & 0x3f) % AW88395_VOLUME_STEP_DB)); -} - -static unsigned short db_to_reg_val(unsigned short value) -{ - return (((value / AW88395_VOLUME_STEP_DB) << AW88395_VOL_6DB_START) + - (value % AW88395_VOLUME_STEP_DB)); -} - -static int aw_dev_dsp_fw_check(struct aw_device *aw_dev) -{ - struct aw_sec_data_desc *dsp_fw_desc; - struct aw_prof_desc *set_prof_desc; - u16 base_addr =3D AW88395_DSP_FW_ADDR; - u16 addr =3D base_addr; - u32 dsp_val; - u16 bin_val; - int ret, i; - - ret =3D aw88395_dev_get_prof_data(aw_dev, aw_dev->prof_cur, &set_prof_des= c); - if (ret) - return ret; - - /* update reg */ - dsp_fw_desc =3D &set_prof_desc->sec_desc[AW88395_DATA_TYPE_DSP_FW]; - - for (i =3D 0; i < AW88395_FW_CHECK_PART; i++) { - ret =3D aw_dev_dsp_read(aw_dev, addr, &dsp_val, AW88395_DSP_16_DATA); - if (ret) { - dev_err(aw_dev->dev, "dsp read failed"); - return ret; - } - - bin_val =3D be16_to_cpup((void *)&dsp_fw_desc->data[2 * (addr - base_add= r)]); - - if (dsp_val !=3D bin_val) { - dev_err(aw_dev->dev, "fw check failed, addr[0x%x], read[0x%x] !=3D bind= ata[0x%x]", - addr, dsp_val, bin_val); - return -EINVAL; - } - - addr +=3D (dsp_fw_desc->len / 2) / AW88395_FW_CHECK_PART; - if ((addr - base_addr) > dsp_fw_desc->len) { - dev_err(aw_dev->dev, "fw check failed, addr[0x%x] too large", addr); - return -EINVAL; - } - } - - return 0; -} - -static int aw_dev_set_volume(struct aw_device *aw_dev, unsigned int value) -{ - struct aw_volume_desc *vol_desc =3D &aw_dev->volume_desc; - unsigned int reg_value; - u16 real_value, volume; - int ret; - - volume =3D min((value + vol_desc->init_volume), (unsigned int)AW88395_MUT= E_VOL); - real_value =3D db_to_reg_val(volume); - - /* cal real value */ - ret =3D regmap_read(aw_dev->regmap, AW88395_SYSCTRL2_REG, ®_value); - if (ret) - return ret; - - dev_dbg(aw_dev->dev, "value 0x%x , reg:0x%x", value, real_value); - - /* [15 : 6] volume */ - real_value =3D (real_value << AW88395_VOL_START_BIT) | (reg_value & AW883= 95_VOL_MASK); - - /* write value */ - ret =3D regmap_write(aw_dev->regmap, AW88395_SYSCTRL2_REG, real_value); - - return ret; -} - -void aw88395_dev_set_volume(struct aw_device *aw_dev, unsigned short set_v= ol) -{ - int ret; - - ret =3D aw_dev_set_volume(aw_dev, set_vol); - if (ret) - dev_dbg(aw_dev->dev, "set volume failed"); -} -EXPORT_SYMBOL_GPL(aw88395_dev_set_volume); - -static void aw_dev_fade_in(struct aw_device *aw_dev) -{ - struct aw_volume_desc *desc =3D &aw_dev->volume_desc; - u16 fade_in_vol =3D desc->ctl_volume; - int fade_step =3D aw_dev->fade_step; - int i; - - if (fade_step =3D=3D 0 || aw_dev->fade_in_time =3D=3D 0) { - aw_dev_set_volume(aw_dev, fade_in_vol); - return; - } - - for (i =3D AW88395_MUTE_VOL; i >=3D fade_in_vol; i -=3D fade_step) { - aw_dev_set_volume(aw_dev, i); - usleep_range(aw_dev->fade_in_time, aw_dev->fade_in_time + 10); - } - - if (i !=3D fade_in_vol) - aw_dev_set_volume(aw_dev, fade_in_vol); -} - -static void aw_dev_fade_out(struct aw_device *aw_dev) -{ - struct aw_volume_desc *desc =3D &aw_dev->volume_desc; - int fade_step =3D aw_dev->fade_step; - int i; - - if (fade_step =3D=3D 0 || aw_dev->fade_out_time =3D=3D 0) { - aw_dev_set_volume(aw_dev, AW88395_MUTE_VOL); - return; - } - - for (i =3D desc->ctl_volume; i <=3D AW88395_MUTE_VOL; i +=3D fade_step) { - aw_dev_set_volume(aw_dev, i); - usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10); - } - - if (i !=3D AW88395_MUTE_VOL) { - aw_dev_set_volume(aw_dev, AW88395_MUTE_VOL); - usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10); - } -} - -static int aw_dev_modify_dsp_cfg(struct aw_device *aw_dev, - unsigned int addr, unsigned int dsp_data, unsigned char data_type) -{ - struct aw_sec_data_desc *crc_dsp_cfg =3D &aw_dev->crc_dsp_cfg; - unsigned int addr_offset; - __le16 data1; - __le32 data2; - - dev_dbg(aw_dev->dev, "addr:0x%x, dsp_data:0x%x", addr, dsp_data); - - addr_offset =3D (addr - AW88395_DSP_CFG_ADDR) * 2; - if (addr_offset > crc_dsp_cfg->len) { - dev_err(aw_dev->dev, "addr_offset[%d] > crc_dsp_cfg->len[%d]", - addr_offset, crc_dsp_cfg->len); - return -EINVAL; - } - switch (data_type) { - case AW88395_DSP_16_DATA: - data1 =3D cpu_to_le16((u16)dsp_data); - memcpy(crc_dsp_cfg->data + addr_offset, (u8 *)&data1, 2); - break; - case AW88395_DSP_32_DATA: - data2 =3D cpu_to_le32(dsp_data); - memcpy(crc_dsp_cfg->data + addr_offset, (u8 *)&data2, 4); - break; - default: - dev_err(aw_dev->dev, "data type[%d] unsupported", data_type); - return -EINVAL; - } - - return 0; -} - -static int aw_dev_dsp_set_cali_re(struct aw_device *aw_dev) -{ - u32 cali_re; - int ret; - - cali_re =3D AW88395_SHOW_RE_TO_DSP_RE((aw_dev->cali_desc.cali_re + - aw_dev->cali_desc.ra), AW88395_DSP_RE_SHIFT); - - /* set cali re to device */ - ret =3D aw_dev_dsp_write(aw_dev, - AW88395_DSP_REG_CFG_ADPZ_RE, cali_re, AW88395_DSP_32_DATA); - if (ret) { - dev_err(aw_dev->dev, "set cali re error"); - return ret; - } - - ret =3D aw_dev_modify_dsp_cfg(aw_dev, AW88395_DSP_REG_CFG_ADPZ_RE, - cali_re, AW88395_DSP_32_DATA); - if (ret) - dev_err(aw_dev->dev, "modify dsp cfg failed"); - - return ret; -} - -static void aw_dev_i2s_tx_enable(struct aw_device *aw_dev, bool flag) -{ - int ret; - - if (flag) { - ret =3D regmap_update_bits(aw_dev->regmap, AW88395_I2SCFG1_REG, - ~AW88395_I2STXEN_MASK, AW88395_I2STXEN_ENABLE_VALUE); - } else { - ret =3D regmap_update_bits(aw_dev->regmap, AW88395_I2SCFG1_REG, - ~AW88395_I2STXEN_MASK, AW88395_I2STXEN_DISABLE_VALUE); - } - - if (ret) - dev_dbg(aw_dev->dev, "%s failed", __func__); -} - -static int aw_dev_dsp_set_crc32(struct aw_device *aw_dev) -{ - struct aw_sec_data_desc *crc_dsp_cfg =3D &aw_dev->crc_dsp_cfg; - u32 crc_value, crc_data_len; - - /* get crc data len */ - crc_data_len =3D (AW88395_DSP_REG_CRC_ADDR - AW88395_DSP_CFG_ADDR) * 2; - if (crc_data_len > crc_dsp_cfg->len) { - dev_err(aw_dev->dev, "crc data len :%d > cfg_data len:%d", - crc_data_len, crc_dsp_cfg->len); - return -EINVAL; - } - - if (crc_data_len & 0x11) { - dev_err(aw_dev->dev, "The crc data len :%d unsupport", crc_data_len); - return -EINVAL; - } - - crc_value =3D crc32c(0xFFFFFFFF, crc_dsp_cfg->data, crc_data_len) ^ 0xFFF= FFFFF; - - return aw_dev_dsp_write(aw_dev, AW88395_DSP_REG_CRC_ADDR, crc_value, - AW88395_DSP_32_DATA); -} - -static void aw_dev_dsp_check_crc_enable(struct aw_device *aw_dev, bool fla= g) -{ - int ret; - - if (flag) { - ret =3D regmap_update_bits(aw_dev->regmap, AW88395_HAGCCFG7_REG, - ~AW88395_AGC_DSP_CTL_MASK, AW88395_AGC_DSP_CTL_ENABLE_VALUE); - } else { - ret =3D regmap_update_bits(aw_dev->regmap, AW88395_HAGCCFG7_REG, - ~AW88395_AGC_DSP_CTL_MASK, AW88395_AGC_DSP_CTL_DISABLE_VALUE); - } - if (ret) - dev_dbg(aw_dev->dev, "%s failed", __func__); -} - -static int aw_dev_dsp_check_st(struct aw_device *aw_dev) -{ - unsigned int reg_val; - int ret; - int i; - - for (i =3D 0; i < AW88395_DSP_ST_CHECK_MAX; i++) { - ret =3D regmap_read(aw_dev->regmap, AW88395_SYSST_REG, ®_val); - if (ret) { - dev_err(aw_dev->dev, "read reg0x%x failed", AW88395_SYSST_REG); - continue; - } - - if ((reg_val & (~AW88395_DSPS_MASK)) !=3D AW88395_DSPS_NORMAL_VALUE) { - dev_err(aw_dev->dev, "check dsp st fail,reg_val:0x%04x", reg_val); - ret =3D -EPERM; - continue; - } else { - dev_dbg(aw_dev->dev, "dsp st check ok, reg_val:0x%04x", reg_val); - return 0; - } - } - - return ret; -} - -static void aw_dev_dsp_enable(struct aw_device *aw_dev, bool is_enable) -{ - int ret; - - if (is_enable) { - ret =3D regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, - ~AW88395_DSPBY_MASK, AW88395_DSPBY_WORKING_VALUE); - if (ret) - dev_dbg(aw_dev->dev, "enable dsp failed"); - } else { - ret =3D regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, - ~AW88395_DSPBY_MASK, AW88395_DSPBY_BYPASS_VALUE); - if (ret) - dev_dbg(aw_dev->dev, "disable dsp failed"); - } -} - -static int aw_dev_dsp_check_crc32(struct aw_device *aw_dev) -{ - int ret; - - if (aw_dev->dsp_cfg =3D=3D AW88395_DEV_DSP_BYPASS) { - dev_info(aw_dev->dev, "dsp bypass"); - return 0; - } - - ret =3D aw_dev_dsp_set_crc32(aw_dev); - if (ret) { - dev_err(aw_dev->dev, "set dsp crc32 failed"); - return ret; - } - - aw_dev_dsp_check_crc_enable(aw_dev, true); - - /* dsp enable */ - aw_dev_dsp_enable(aw_dev, true); - usleep_range(AW88395_5000_US, AW88395_5000_US + 100); - - ret =3D aw_dev_dsp_check_st(aw_dev); - if (ret) { - dev_err(aw_dev->dev, "check crc32 fail"); - } else { - aw_dev_dsp_check_crc_enable(aw_dev, false); - aw_dev->dsp_crc_st =3D AW88395_DSP_CRC_OK; - } - - return ret; -} - -static void aw_dev_pwd(struct aw_device *aw_dev, bool pwd) -{ - int ret; - - if (pwd) { - ret =3D regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, - ~AW88395_PWDN_MASK, AW88395_PWDN_POWER_DOWN_VALUE); - } else { - ret =3D regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, - ~AW88395_PWDN_MASK, AW88395_PWDN_WORKING_VALUE); - } - if (ret) - dev_dbg(aw_dev->dev, "%s failed", __func__); -} - -static void aw_dev_amppd(struct aw_device *aw_dev, bool amppd) -{ - int ret; - - if (amppd) { - ret =3D regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, - ~AW88395_AMPPD_MASK, AW88395_AMPPD_POWER_DOWN_VALUE); - } else { - ret =3D regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, - ~AW88395_AMPPD_MASK, AW88395_AMPPD_WORKING_VALUE); - } - if (ret) - dev_dbg(aw_dev->dev, "%s failed", __func__); -} - -void aw88395_dev_mute(struct aw_device *aw_dev, bool is_mute) -{ - int ret; - - if (is_mute) { - aw_dev_fade_out(aw_dev); - ret =3D regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, - ~AW88395_HMUTE_MASK, AW88395_HMUTE_ENABLE_VALUE); - } else { - ret =3D regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, - ~AW88395_HMUTE_MASK, AW88395_HMUTE_DISABLE_VALUE); - aw_dev_fade_in(aw_dev); - } - - if (ret) - dev_dbg(aw_dev->dev, "%s failed", __func__); -} -EXPORT_SYMBOL_GPL(aw88395_dev_mute); - -static int aw_dev_get_icalk(struct aw_device *aw_dev, int16_t *icalk) -{ - unsigned int reg_val; - u16 reg_icalk; - int ret; - - ret =3D regmap_read(aw_dev->regmap, AW88395_EFRM2_REG, ®_val); - if (ret) - return ret; - - reg_icalk =3D reg_val & (~AW88395_EF_ISN_GESLP_MASK); - - if (reg_icalk & (~AW88395_EF_ISN_GESLP_SIGN_MASK)) - reg_icalk =3D reg_icalk | AW88395_EF_ISN_GESLP_SIGN_NEG; - - *icalk =3D (int16_t)reg_icalk; - - return ret; -} - -static int aw_dev_get_vcalk(struct aw_device *aw_dev, int16_t *vcalk) -{ - unsigned int reg_val; - u16 reg_vcalk; - int ret; - - ret =3D regmap_read(aw_dev->regmap, AW88395_EFRH_REG, ®_val); - if (ret) - return ret; - - reg_val =3D reg_val >> AW88395_EF_VSENSE_GAIN_SHIFT; - - reg_vcalk =3D (u16)reg_val & (~AW88395_EF_VSN_GESLP_MASK); - - if (reg_vcalk & (~AW88395_EF_VSN_GESLP_SIGN_MASK)) - reg_vcalk =3D reg_vcalk | AW88395_EF_VSN_GESLP_SIGN_NEG; - - *vcalk =3D (int16_t)reg_vcalk; - - return ret; -} - -static int aw_dev_get_vcalk_dac(struct aw_device *aw_dev, int16_t *vcalk) -{ - unsigned int reg_val; - u16 reg_vcalk; - int ret; - - ret =3D regmap_read(aw_dev->regmap, AW88395_EFRM2_REG, ®_val); - if (ret) - return ret; - - reg_vcalk =3D reg_val >> AW88395_EF_DAC_GESLP_SHIFT; - - if (reg_vcalk & AW88395_EF_DAC_GESLP_SIGN_MASK) - reg_vcalk =3D reg_vcalk | AW88395_EF_DAC_GESLP_SIGN_NEG; - - *vcalk =3D (int16_t)reg_vcalk; - - return ret; -} - -static int aw_dev_vsense_select(struct aw_device *aw_dev, int *vsense_sele= ct) -{ - unsigned int vsense_reg_val; - int ret; - - ret =3D regmap_read(aw_dev->regmap, AW88395_I2SCFG3_REG, &vsense_reg_val); - if (ret) { - dev_err(aw_dev->dev, "read vsense_reg_val failed"); - return ret; - } - dev_dbg(aw_dev->dev, "vsense_reg =3D 0x%x", vsense_reg_val); - - if (vsense_reg_val & (~AW88395_VDSEL_MASK)) { - *vsense_select =3D AW88395_DEV_VDSEL_VSENSE; - dev_dbg(aw_dev->dev, "vsense outside"); - } else { - *vsense_select =3D AW88395_DEV_VDSEL_DAC; - dev_dbg(aw_dev->dev, "vsense inside"); - } - - return 0; -} - -static int aw_dev_set_vcalb(struct aw_device *aw_dev) -{ - int16_t icalk_val, vcalk_val; - int icalk, vsense_select; - u32 vcalb_adj, reg_val; - int vcalb, vcalk; - int ret; - - ret =3D aw_dev_dsp_read(aw_dev, AW88395_DSP_REG_VCALB, &vcalb_adj, AW8839= 5_DSP_16_DATA); - if (ret) { - dev_err(aw_dev->dev, "read vcalb_adj failed"); - return ret; - } - - ret =3D aw_dev_vsense_select(aw_dev, &vsense_select); - if (ret) - return ret; - dev_dbg(aw_dev->dev, "vsense_select =3D %d", vsense_select); - - ret =3D aw_dev_get_icalk(aw_dev, &icalk_val); - if (ret) - return ret; - icalk =3D AW88395_CABL_BASE_VALUE + AW88395_ICABLK_FACTOR * icalk_val; - - switch (vsense_select) { - case AW88395_DEV_VDSEL_VSENSE: - ret =3D aw_dev_get_vcalk(aw_dev, &vcalk_val); - if (ret) - return ret; - vcalk =3D AW88395_CABL_BASE_VALUE + AW88395_VCABLK_FACTOR * vcalk_val; - vcalb =3D AW88395_VCAL_FACTOR * AW88395_VSCAL_FACTOR / - AW88395_ISCAL_FACTOR * icalk / vcalk * vcalb_adj; - - dev_dbg(aw_dev->dev, "vcalk_factor=3D%d, vscal_factor=3D%d, icalk=3D%d, = vcalk=3D%d", - AW88395_VCABLK_FACTOR, AW88395_VSCAL_FACTOR, icalk, vcalk); - break; - case AW88395_DEV_VDSEL_DAC: - ret =3D aw_dev_get_vcalk_dac(aw_dev, &vcalk_val); - if (ret) - return ret; - vcalk =3D AW88395_CABL_BASE_VALUE + AW88395_VCABLK_FACTOR_DAC * vcalk_va= l; - vcalb =3D AW88395_VCAL_FACTOR * AW88395_VSCAL_FACTOR_DAC / - AW88395_ISCAL_FACTOR * icalk / vcalk * vcalb_adj; - - dev_dbg(aw_dev->dev, "vcalk_dac_factor=3D%d, vscal_dac_factor=3D%d, ical= k=3D%d, vcalk=3D%d", - AW88395_VCABLK_FACTOR_DAC, - AW88395_VSCAL_FACTOR_DAC, icalk, vcalk); - break; - default: - dev_err(aw_dev->dev, "unsupported vsense status"); - return -EINVAL; - } - - if ((vcalk =3D=3D 0) || (AW88395_ISCAL_FACTOR =3D=3D 0)) { - dev_err(aw_dev->dev, "vcalk:%d or desc->iscal_factor:%d unsupported", - vcalk, AW88395_ISCAL_FACTOR); - return -EINVAL; - } - - vcalb =3D vcalb >> AW88395_VCALB_ADJ_FACTOR; - reg_val =3D (u32)vcalb; - - dev_dbg(aw_dev->dev, "vcalb=3D%d, reg_val=3D0x%x, vcalb_adj =3D0x%x", - vcalb, reg_val, vcalb_adj); - - ret =3D aw_dev_dsp_write(aw_dev, AW88395_DSP_REG_VCALB, reg_val, AW88395_= DSP_16_DATA); - if (ret) { - dev_err(aw_dev->dev, "write vcalb failed"); - return ret; - } - - ret =3D aw_dev_modify_dsp_cfg(aw_dev, AW88395_DSP_REG_VCALB, - (u32)reg_val, AW88395_DSP_16_DATA); - if (ret) - dev_err(aw_dev->dev, "modify dsp cfg failed"); - - return ret; -} - -static int aw_dev_get_cali_f0_delay(struct aw_device *aw_dev) -{ - struct aw_cali_delay_desc *desc =3D &aw_dev->cali_delay_desc; - u32 cali_delay; - int ret; - - ret =3D aw_dev_dsp_read(aw_dev, - AW88395_DSP_CALI_F0_DELAY, &cali_delay, AW88395_DSP_16_DATA); - if (ret) - dev_err(aw_dev->dev, "read cali delay failed, ret=3D%d", ret); - else - desc->delay =3D AW88395_CALI_DELAY_CACL(cali_delay); - - dev_dbg(aw_dev->dev, "read cali delay: %d ms", desc->delay); - - return ret; -} - -static void aw_dev_get_int_status(struct aw_device *aw_dev, unsigned short= *int_status) -{ - unsigned int reg_val; - int ret; - - ret =3D regmap_read(aw_dev->regmap, AW88395_SYSINT_REG, ®_val); - if (ret) - dev_err(aw_dev->dev, "read interrupt reg fail, ret=3D%d", ret); - else - *int_status =3D reg_val; - - dev_dbg(aw_dev->dev, "read interrupt reg =3D 0x%04x", *int_status); -} - -static void aw_dev_clear_int_status(struct aw_device *aw_dev) -{ - u16 int_status; - - /* read int status and clear */ - aw_dev_get_int_status(aw_dev, &int_status); - /* make sure int status is clear */ - aw_dev_get_int_status(aw_dev, &int_status); - if (int_status) - dev_info(aw_dev->dev, "int status(%d) is not cleaned.\n", int_status); -} - -static int aw_dev_get_iis_status(struct aw_device *aw_dev) -{ - unsigned int reg_val; - int ret; - - ret =3D regmap_read(aw_dev->regmap, AW88395_SYSST_REG, ®_val); - if (ret) - return -EIO; - if ((reg_val & AW88395_BIT_PLL_CHECK) !=3D AW88395_BIT_PLL_CHECK) { - dev_err(aw_dev->dev, "check pll lock fail,reg_val:0x%04x", reg_val); - return -EINVAL; - } - - return 0; -} - -static int aw_dev_check_mode1_pll(struct aw_device *aw_dev) -{ - int ret, i; - - for (i =3D 0; i < AW88395_DEV_SYSST_CHECK_MAX; i++) { - ret =3D aw_dev_get_iis_status(aw_dev); - if (ret < 0) { - dev_err(aw_dev->dev, "mode1 iis signal check error"); - usleep_range(AW88395_2000_US, AW88395_2000_US + 10); - } else { - return 0; - } - } - - return -EPERM; -} - -static int aw_dev_check_mode2_pll(struct aw_device *aw_dev) -{ - unsigned int reg_val; - int ret, i; - - ret =3D regmap_read(aw_dev->regmap, AW88395_PLLCTRL1_REG, ®_val); - if (ret) - return ret; - - reg_val &=3D (~AW88395_CCO_MUX_MASK); - if (reg_val =3D=3D AW88395_CCO_MUX_DIVIDED_VALUE) { - dev_dbg(aw_dev->dev, "CCO_MUX is already divider"); - return -EPERM; - } - - /* change mode2 */ - ret =3D regmap_update_bits(aw_dev->regmap, AW88395_PLLCTRL1_REG, - ~AW88395_CCO_MUX_MASK, AW88395_CCO_MUX_DIVIDED_VALUE); - if (ret) - return ret; - - for (i =3D 0; i < AW88395_DEV_SYSST_CHECK_MAX; i++) { - ret =3D aw_dev_get_iis_status(aw_dev); - if (ret) { - dev_err(aw_dev->dev, "mode2 iis signal check error"); - usleep_range(AW88395_2000_US, AW88395_2000_US + 10); - } else { - break; - } - } - - /* change mode1 */ - ret =3D regmap_update_bits(aw_dev->regmap, AW88395_PLLCTRL1_REG, - ~AW88395_CCO_MUX_MASK, AW88395_CCO_MUX_BYPASS_VALUE); - if (ret =3D=3D 0) { - usleep_range(AW88395_2000_US, AW88395_2000_US + 10); - for (i =3D 0; i < AW88395_DEV_SYSST_CHECK_MAX; i++) { - ret =3D aw_dev_check_mode1_pll(aw_dev); - if (ret < 0) { - dev_err(aw_dev->dev, "mode2 switch to mode1, iis signal check error"); - usleep_range(AW88395_2000_US, AW88395_2000_US + 10); - } else { - break; - } - } - } - - return ret; -} - -static int aw_dev_check_syspll(struct aw_device *aw_dev) -{ - int ret; - - ret =3D aw_dev_check_mode1_pll(aw_dev); - if (ret) { - dev_dbg(aw_dev->dev, "mode1 check iis failed try switch to mode2 check"); - ret =3D aw_dev_check_mode2_pll(aw_dev); - if (ret) { - dev_err(aw_dev->dev, "mode2 check iis failed"); - return ret; - } - } - - return ret; -} - -static int aw_dev_check_sysst(struct aw_device *aw_dev) -{ - unsigned int check_val; - unsigned int reg_val; - int ret, i; - - for (i =3D 0; i < AW88395_DEV_SYSST_CHECK_MAX; i++) { - ret =3D regmap_read(aw_dev->regmap, AW88395_SYSST_REG, ®_val); - if (ret) - return ret; - - check_val =3D reg_val & (~AW88395_BIT_SYSST_CHECK_MASK) - & AW88395_BIT_SYSST_CHECK; - if (check_val !=3D AW88395_BIT_SYSST_CHECK) { - dev_err(aw_dev->dev, "check sysst fail, cnt=3D%d, reg_val=3D0x%04x, che= ck:0x%x", - i, reg_val, AW88395_BIT_SYSST_CHECK); - usleep_range(AW88395_2000_US, AW88395_2000_US + 10); - } else { - return 0; - } - } - - return -EPERM; -} - -static int aw_dev_check_sysint(struct aw_device *aw_dev) -{ - u16 reg_val; - - aw_dev_get_int_status(aw_dev, ®_val); - - if (reg_val & AW88395_BIT_SYSINT_CHECK) { - dev_err(aw_dev->dev, "pa stop check fail:0x%04x", reg_val); - return -EINVAL; - } - - return 0; -} - -static void aw_dev_get_cur_mode_st(struct aw_device *aw_dev) -{ - struct aw_profctrl_desc *profctrl_desc =3D &aw_dev->profctrl_desc; - unsigned int reg_val; - int ret; - - ret =3D regmap_read(aw_dev->regmap, AW88395_SYSCTRL_REG, ®_val); - if (ret) { - dev_dbg(aw_dev->dev, "%s failed", __func__); - return; - } - if ((reg_val & (~AW88395_RCV_MODE_MASK)) =3D=3D AW88395_RCV_MODE_RECEIVER= _VALUE) - profctrl_desc->cur_mode =3D AW88395_RCV_MODE; - else - profctrl_desc->cur_mode =3D AW88395_NOT_RCV_MODE; -} - -static void aw_dev_get_dsp_config(struct aw_device *aw_dev, unsigned char = *dsp_cfg) -{ - unsigned int reg_val =3D 0; - int ret; - - ret =3D regmap_read(aw_dev->regmap, AW88395_SYSCTRL_REG, ®_val); - if (ret) { - dev_dbg(aw_dev->dev, "%s failed", __func__); - return; - } - if (reg_val & (~AW88395_DSPBY_MASK)) - *dsp_cfg =3D AW88395_DEV_DSP_BYPASS; - else - *dsp_cfg =3D AW88395_DEV_DSP_WORK; -} - -static void aw_dev_select_memclk(struct aw_device *aw_dev, unsigned char f= lag) -{ - int ret; - - switch (flag) { - case AW88395_DEV_MEMCLK_PLL: - ret =3D regmap_update_bits(aw_dev->regmap, AW88395_DBGCTRL_REG, - ~AW88395_MEM_CLKSEL_MASK, - AW88395_MEM_CLKSEL_DAP_HCLK_VALUE); - if (ret) - dev_err(aw_dev->dev, "memclk select pll failed"); - break; - case AW88395_DEV_MEMCLK_OSC: - ret =3D regmap_update_bits(aw_dev->regmap, AW88395_DBGCTRL_REG, - ~AW88395_MEM_CLKSEL_MASK, - AW88395_MEM_CLKSEL_OSC_CLK_VALUE); - if (ret) - dev_err(aw_dev->dev, "memclk select OSC failed"); - break; - default: - dev_err(aw_dev->dev, "unknown memclk config, flag=3D0x%x", flag); - break; - } -} - -static int aw_dev_get_dsp_status(struct aw_device *aw_dev) -{ - unsigned int reg_val; - int ret; - - ret =3D regmap_read(aw_dev->regmap, AW88395_WDT_REG, ®_val); - if (ret) - return ret; - if (!(reg_val & (~AW88395_WDT_CNT_MASK))) - ret =3D -EPERM; - - return ret; -} - -static int aw_dev_get_vmax(struct aw_device *aw_dev, unsigned int *vmax) -{ - return aw_dev_dsp_read(aw_dev, AW88395_DSP_REG_VMAX, vmax, AW88395_DSP_16= _DATA); -} - -static int aw_dev_update_reg_container(struct aw_device *aw_dev, - unsigned char *data, unsigned int len) -{ - struct aw_volume_desc *vol_desc =3D &aw_dev->volume_desc; - unsigned int read_val; - int16_t *reg_data; - int data_len; - u16 read_vol; - u16 reg_val; - u8 reg_addr; - int i, ret; - - reg_data =3D (int16_t *)data; - data_len =3D len >> 1; - - if (data_len & 0x1) { - dev_err(aw_dev->dev, "data len:%d unsupported", data_len); - return -EINVAL; - } - - for (i =3D 0; i < data_len; i +=3D 2) { - reg_addr =3D reg_data[i]; - reg_val =3D reg_data[i + 1]; - - if (reg_addr =3D=3D AW88395_SYSCTRL_REG) { - ret =3D regmap_read(aw_dev->regmap, reg_addr, &read_val); - if (ret) - break; - read_val &=3D (~AW88395_HMUTE_MASK); - reg_val &=3D AW88395_HMUTE_MASK; - reg_val |=3D read_val; - } - if (reg_addr =3D=3D AW88395_HAGCCFG7_REG) - reg_val &=3D AW88395_AGC_DSP_CTL_MASK; - - if (reg_addr =3D=3D AW88395_I2SCFG1_REG) { - /* close tx */ - reg_val &=3D AW88395_I2STXEN_MASK; - reg_val |=3D AW88395_I2STXEN_DISABLE_VALUE; - } - - if (reg_addr =3D=3D AW88395_SYSCTRL2_REG) { - read_vol =3D (reg_val & (~AW88395_VOL_MASK)) >> - AW88395_VOL_START_BIT; - aw_dev->volume_desc.init_volume =3D - reg_val_to_db(read_vol); - } - ret =3D regmap_write(aw_dev->regmap, reg_addr, reg_val); - if (ret) - break; - - } - - aw_dev_get_cur_mode_st(aw_dev); - - if (aw_dev->prof_cur !=3D aw_dev->prof_index) { - /* clear control volume when PA change profile */ - vol_desc->ctl_volume =3D 0; - } else { - /* keep control volume when PA start with sync mode */ - aw_dev_set_volume(aw_dev, vol_desc->ctl_volume); - } - - aw_dev_get_dsp_config(aw_dev, &aw_dev->dsp_cfg); - - return ret; -} - -static int aw_dev_reg_update(struct aw_device *aw_dev, - unsigned char *data, unsigned int len) -{ - int ret; - - if (!len || !data) { - dev_err(aw_dev->dev, "reg data is null or len is 0"); - return -EINVAL; - } - - ret =3D aw_dev_update_reg_container(aw_dev, data, len); - if (ret) { - dev_err(aw_dev->dev, "reg update failed"); - return ret; - } - - return 0; -} - -static int aw_dev_get_ra(struct aw_cali_desc *cali_desc) -{ - struct aw_device *aw_dev =3D - container_of(cali_desc, struct aw_device, cali_desc); - u32 dsp_ra; - int ret; - - ret =3D aw_dev_dsp_read(aw_dev, AW88395_DSP_REG_CFG_ADPZ_RA, - &dsp_ra, AW88395_DSP_32_DATA); - if (ret) { - dev_err(aw_dev->dev, "read ra error"); - return ret; - } - - cali_desc->ra =3D AW88395_DSP_RE_TO_SHOW_RE(dsp_ra, - AW88395_DSP_RE_SHIFT); - - return ret; -} - -static int aw_dev_dsp_update_container(struct aw_device *aw_dev, - unsigned char *data, unsigned int len, unsigned short base) -{ - int i, ret; - -#ifdef AW88395_DSP_I2C_WRITES - u32 tmp_len; - - mutex_lock(&aw_dev->dsp_lock); - ret =3D regmap_write(aw_dev->regmap, AW88395_DSPMADD_REG, base); - if (ret) - goto error_operation; - - for (i =3D 0; i < len; i +=3D AW88395_MAX_RAM_WRITE_BYTE_SIZE) { - tmp_len =3D min(len - i, AW88395_MAX_RAM_WRITE_BYTE_SIZE); - ret =3D regmap_raw_write(aw_dev->regmap, AW88395_DSPMDAT_REG, - &data[i], tmp_len); - if (ret) - goto error_operation; - } - mutex_unlock(&aw_dev->dsp_lock); -#else - __be16 reg_val; - - mutex_lock(&aw_dev->dsp_lock); - /* i2c write */ - ret =3D regmap_write(aw_dev->regmap, AW88395_DSPMADD_REG, base); - if (ret) - goto error_operation; - for (i =3D 0; i < len; i +=3D 2) { - reg_val =3D cpu_to_be16p((u16 *)(data + i)); - ret =3D regmap_write(aw_dev->regmap, AW88395_DSPMDAT_REG, - (u16)reg_val); - if (ret) - goto error_operation; - } - mutex_unlock(&aw_dev->dsp_lock); -#endif - - return 0; - -error_operation: - mutex_unlock(&aw_dev->dsp_lock); - return ret; -} - -static int aw_dev_dsp_update_fw(struct aw_device *aw_dev, - unsigned char *data, unsigned int len) -{ - - dev_dbg(aw_dev->dev, "dsp firmware len:%d", len); - - if (!len || !data) { - dev_err(aw_dev->dev, "dsp firmware data is null or len is 0"); - return -EINVAL; - } - aw_dev_dsp_update_container(aw_dev, data, len, AW88395_DSP_FW_ADDR); - aw_dev->dsp_fw_len =3D len; - - return 0; -} - -static int aw_dev_copy_to_crc_dsp_cfg(struct aw_device *aw_dev, - unsigned char *data, unsigned int size) -{ - struct aw_sec_data_desc *crc_dsp_cfg =3D &aw_dev->crc_dsp_cfg; - - if (!crc_dsp_cfg->data) { - crc_dsp_cfg->data =3D devm_kzalloc(aw_dev->dev, size, GFP_KERNEL); - if (!crc_dsp_cfg->data) - return -ENOMEM; - crc_dsp_cfg->len =3D size; - } else if (crc_dsp_cfg->len < size) { - devm_kfree(aw_dev->dev, crc_dsp_cfg->data); - crc_dsp_cfg->data =3D devm_kzalloc(aw_dev->dev, size, GFP_KERNEL); - if (!crc_dsp_cfg->data) - return -ENOMEM; - crc_dsp_cfg->len =3D size; - } - memcpy(crc_dsp_cfg->data, data, size); - swab16_array((u16 *)crc_dsp_cfg->data, size >> 1); - - return 0; -} - -static int aw_dev_dsp_update_cfg(struct aw_device *aw_dev, - unsigned char *data, unsigned int len) -{ - int ret; - - dev_dbg(aw_dev->dev, "dsp config len:%d", len); - - if (!len || !data) { - dev_err(aw_dev->dev, "dsp config data is null or len is 0"); - return -EINVAL; - } - - aw_dev_dsp_update_container(aw_dev, data, len, AW88395_DSP_CFG_ADDR); - aw_dev->dsp_cfg_len =3D len; - - ret =3D aw_dev_copy_to_crc_dsp_cfg(aw_dev, data, len); - if (ret) - return ret; - - ret =3D aw_dev_set_vcalb(aw_dev); - if (ret) - return ret; - ret =3D aw_dev_get_ra(&aw_dev->cali_desc); - if (ret) - return ret; - ret =3D aw_dev_get_cali_f0_delay(aw_dev); - if (ret) - return ret; - - ret =3D aw_dev_get_vmax(aw_dev, &aw_dev->vmax_desc.init_vmax); - if (ret) { - dev_err(aw_dev->dev, "get vmax failed"); - return ret; - } - dev_dbg(aw_dev->dev, "get init vmax:0x%x", aw_dev->vmax_desc.init_vmax); - aw_dev->dsp_crc_st =3D AW88395_DSP_CRC_NA; - - return 0; -} - -static int aw_dev_check_sram(struct aw_device *aw_dev) -{ - unsigned int reg_val; - - mutex_lock(&aw_dev->dsp_lock); - /* check the odd bits of reg 0x40 */ - regmap_write(aw_dev->regmap, AW88395_DSPMADD_REG, AW88395_DSP_ODD_NUM_BIT= _TEST); - regmap_read(aw_dev->regmap, AW88395_DSPMADD_REG, ®_val); - if (reg_val !=3D AW88395_DSP_ODD_NUM_BIT_TEST) { - dev_err(aw_dev->dev, "check reg 0x40 odd bit failed, read[0x%x] !=3D wri= te[0x%x]", - reg_val, AW88395_DSP_ODD_NUM_BIT_TEST); - goto error; - } - - /* check the even bits of reg 0x40 */ - regmap_write(aw_dev->regmap, AW88395_DSPMADD_REG, AW88395_DSP_EVEN_NUM_BI= T_TEST); - regmap_read(aw_dev->regmap, AW88395_DSPMADD_REG, ®_val); - if (reg_val !=3D AW88395_DSP_EVEN_NUM_BIT_TEST) { - dev_err(aw_dev->dev, "check reg 0x40 even bit failed, read[0x%x] !=3D wr= ite[0x%x]", - reg_val, AW88395_DSP_EVEN_NUM_BIT_TEST); - goto error; - } - - /* check dsp_fw_base_addr */ - aw_dev_dsp_write_16bit(aw_dev, AW88395_DSP_FW_ADDR, AW88395_DSP_EVEN_NUM_= BIT_TEST); - aw_dev_dsp_read_16bit(aw_dev, AW88395_DSP_FW_ADDR, ®_val); - if (reg_val !=3D AW88395_DSP_EVEN_NUM_BIT_TEST) { - dev_err(aw_dev->dev, "check dsp fw addr failed, read[0x%x] !=3D write[0x= %x]", - reg_val, AW88395_DSP_EVEN_NUM_BIT_TEST); - goto error; - } - - /* check dsp_cfg_base_addr */ - aw_dev_dsp_write_16bit(aw_dev, AW88395_DSP_CFG_ADDR, AW88395_DSP_ODD_NUM_= BIT_TEST); - aw_dev_dsp_read_16bit(aw_dev, AW88395_DSP_CFG_ADDR, ®_val); - if (reg_val !=3D AW88395_DSP_ODD_NUM_BIT_TEST) { - dev_err(aw_dev->dev, "check dsp cfg failed, read[0x%x] !=3D write[0x%x]", - reg_val, AW88395_DSP_ODD_NUM_BIT_TEST); - goto error; - } - mutex_unlock(&aw_dev->dsp_lock); - - return 0; - -error: - mutex_unlock(&aw_dev->dsp_lock); - return -EPERM; -} - -int aw88395_dev_fw_update(struct aw_device *aw_dev, bool up_dsp_fw_en, boo= l force_up_en) -{ - struct aw_prof_desc *prof_index_desc; - struct aw_sec_data_desc *sec_desc; - char *prof_name; - int ret; - - if ((aw_dev->prof_cur =3D=3D aw_dev->prof_index) && - (force_up_en =3D=3D AW88395_FORCE_UPDATE_OFF)) { - dev_dbg(aw_dev->dev, "scene no change, not update"); - return 0; - } - - if (aw_dev->fw_status =3D=3D AW88395_DEV_FW_FAILED) { - dev_err(aw_dev->dev, "fw status[%d] error", aw_dev->fw_status); - return -EPERM; - } - - ret =3D aw88395_dev_get_prof_name(aw_dev, aw_dev->prof_index, &prof_name); - if (ret) - return ret; - - dev_dbg(aw_dev->dev, "start update %s", prof_name); - - ret =3D aw88395_dev_get_prof_data(aw_dev, aw_dev->prof_index, &prof_index= _desc); - if (ret) - return ret; - - /* update reg */ - sec_desc =3D prof_index_desc->sec_desc; - ret =3D aw_dev_reg_update(aw_dev, sec_desc[AW88395_DATA_TYPE_REG].data, - sec_desc[AW88395_DATA_TYPE_REG].len); - if (ret) { - dev_err(aw_dev->dev, "update reg failed"); - return ret; - } - - aw88395_dev_mute(aw_dev, true); - - if (aw_dev->dsp_cfg =3D=3D AW88395_DEV_DSP_WORK) - aw_dev_dsp_enable(aw_dev, false); - - aw_dev_select_memclk(aw_dev, AW88395_DEV_MEMCLK_OSC); - - if (up_dsp_fw_en) { - ret =3D aw_dev_check_sram(aw_dev); - if (ret) { - dev_err(aw_dev->dev, "check sram failed"); - goto error; - } - - /* update dsp firmware */ - dev_dbg(aw_dev->dev, "fw_ver: [%x]", prof_index_desc->fw_ver); - ret =3D aw_dev_dsp_update_fw(aw_dev, sec_desc[AW88395_DATA_TYPE_DSP_FW].= data, - sec_desc[AW88395_DATA_TYPE_DSP_FW].len); - if (ret) { - dev_err(aw_dev->dev, "update dsp fw failed"); - goto error; - } - } - - /* update dsp config */ - ret =3D aw_dev_dsp_update_cfg(aw_dev, sec_desc[AW88395_DATA_TYPE_DSP_CFG]= .data, - sec_desc[AW88395_DATA_TYPE_DSP_CFG].len); - if (ret) { - dev_err(aw_dev->dev, "update dsp cfg failed"); - goto error; - } - - aw_dev_select_memclk(aw_dev, AW88395_DEV_MEMCLK_PLL); - - aw_dev->prof_cur =3D aw_dev->prof_index; - - return 0; - -error: - aw_dev_select_memclk(aw_dev, AW88395_DEV_MEMCLK_PLL); - return ret; -} -EXPORT_SYMBOL_GPL(aw88395_dev_fw_update); - -static int aw_dev_dsp_check(struct aw_device *aw_dev) -{ - int ret, i; - - switch (aw_dev->dsp_cfg) { - case AW88395_DEV_DSP_BYPASS: - dev_dbg(aw_dev->dev, "dsp bypass"); - ret =3D 0; - break; - case AW88395_DEV_DSP_WORK: - aw_dev_dsp_enable(aw_dev, false); - aw_dev_dsp_enable(aw_dev, true); - usleep_range(AW88395_1000_US, AW88395_1000_US + 10); - for (i =3D 0; i < AW88395_DEV_DSP_CHECK_MAX; i++) { - ret =3D aw_dev_get_dsp_status(aw_dev); - if (ret) { - dev_err(aw_dev->dev, "dsp wdt status error=3D%d", ret); - usleep_range(AW88395_2000_US, AW88395_2000_US + 10); - } - } - break; - default: - dev_err(aw_dev->dev, "unknown dsp cfg=3D%d", aw_dev->dsp_cfg); - ret =3D -EINVAL; - break; - } - - return ret; -} - -static void aw_dev_update_cali_re(struct aw_cali_desc *cali_desc) -{ - struct aw_device *aw_dev =3D - container_of(cali_desc, struct aw_device, cali_desc); - int ret; - - if ((aw_dev->cali_desc.cali_re < AW88395_CALI_RE_MAX) && - (aw_dev->cali_desc.cali_re > AW88395_CALI_RE_MIN)) { - - ret =3D aw_dev_dsp_set_cali_re(aw_dev); - if (ret) - dev_err(aw_dev->dev, "set cali re failed"); - } -} - -int aw88395_dev_start(struct aw_device *aw_dev) -{ - int ret; - - if (aw_dev->status =3D=3D AW88395_DEV_PW_ON) { - dev_info(aw_dev->dev, "already power on"); - return 0; - } - /* power on */ - aw_dev_pwd(aw_dev, false); - usleep_range(AW88395_2000_US, AW88395_2000_US + 10); - - ret =3D aw_dev_check_syspll(aw_dev); - if (ret) { - dev_err(aw_dev->dev, "pll check failed cannot start"); - goto pll_check_fail; - } - - /* amppd on */ - aw_dev_amppd(aw_dev, false); - usleep_range(AW88395_1000_US, AW88395_1000_US + 50); - - /* check i2s status */ - ret =3D aw_dev_check_sysst(aw_dev); - if (ret) { - dev_err(aw_dev->dev, "sysst check failed"); - goto sysst_check_fail; - } - - if (aw_dev->dsp_cfg =3D=3D AW88395_DEV_DSP_WORK) { - /* dsp bypass */ - aw_dev_dsp_enable(aw_dev, false); - ret =3D aw_dev_dsp_fw_check(aw_dev); - if (ret) - goto dev_dsp_fw_check_fail; - - aw_dev_update_cali_re(&aw_dev->cali_desc); - - if (aw_dev->dsp_crc_st !=3D AW88395_DSP_CRC_OK) { - ret =3D aw_dev_dsp_check_crc32(aw_dev); - if (ret) { - dev_err(aw_dev->dev, "dsp crc check failed"); - goto crc_check_fail; - } - } - - ret =3D aw_dev_dsp_check(aw_dev); - if (ret) { - dev_err(aw_dev->dev, "dsp status check failed"); - goto dsp_check_fail; - } - } else { - dev_dbg(aw_dev->dev, "start pa with dsp bypass"); - } - - /* enable tx feedback */ - aw_dev_i2s_tx_enable(aw_dev, true); - - /* close mute */ - aw88395_dev_mute(aw_dev, false); - /* clear inturrupt */ - aw_dev_clear_int_status(aw_dev); - aw_dev->status =3D AW88395_DEV_PW_ON; - - return 0; - -dsp_check_fail: -crc_check_fail: - aw_dev_dsp_enable(aw_dev, false); -dev_dsp_fw_check_fail: -sysst_check_fail: - aw_dev_clear_int_status(aw_dev); - aw_dev_amppd(aw_dev, true); -pll_check_fail: - aw_dev_pwd(aw_dev, true); - aw_dev->status =3D AW88395_DEV_PW_OFF; - - return ret; -} -EXPORT_SYMBOL_GPL(aw88395_dev_start); - -int aw88395_dev_stop(struct aw_device *aw_dev) -{ - struct aw_sec_data_desc *dsp_cfg =3D - &aw_dev->prof_info.prof_desc[aw_dev->prof_cur].sec_desc[AW88395_DATA_TYP= E_DSP_CFG]; - struct aw_sec_data_desc *dsp_fw =3D - &aw_dev->prof_info.prof_desc[aw_dev->prof_cur].sec_desc[AW88395_DATA_TYP= E_DSP_FW]; - int int_st =3D 0; - int ret; - - if (aw_dev->status =3D=3D AW88395_DEV_PW_OFF) { - dev_info(aw_dev->dev, "already power off"); - return 0; - } - - aw_dev->status =3D AW88395_DEV_PW_OFF; - - /* set mute */ - aw88395_dev_mute(aw_dev, true); - usleep_range(AW88395_4000_US, AW88395_4000_US + 100); - - /* close tx feedback */ - aw_dev_i2s_tx_enable(aw_dev, false); - usleep_range(AW88395_1000_US, AW88395_1000_US + 100); - - /* check sysint state */ - int_st =3D aw_dev_check_sysint(aw_dev); - - /* close dsp */ - aw_dev_dsp_enable(aw_dev, false); - - /* enable amppd */ - aw_dev_amppd(aw_dev, true); - - if (int_st < 0) { - /* system status anomaly */ - aw_dev_select_memclk(aw_dev, AW88395_DEV_MEMCLK_OSC); - ret =3D aw_dev_dsp_update_fw(aw_dev, dsp_fw->data, dsp_fw->len); - if (ret) - dev_err(aw_dev->dev, "update dsp fw failed"); - ret =3D aw_dev_dsp_update_cfg(aw_dev, dsp_cfg->data, dsp_cfg->len); - if (ret) - dev_err(aw_dev->dev, "update dsp cfg failed"); - aw_dev_select_memclk(aw_dev, AW88395_DEV_MEMCLK_PLL); - } - - /* set power down */ - aw_dev_pwd(aw_dev, true); - - return 0; -} -EXPORT_SYMBOL_GPL(aw88395_dev_stop); - -int aw88395_dev_init(struct aw_device *aw_dev, struct aw_container *aw_cfg) -{ - int ret; - - if ((!aw_dev) || (!aw_cfg)) { - pr_err("aw_dev is NULL or aw_cfg is NULL"); - return -ENOMEM; - } - ret =3D aw88395_dev_cfg_load(aw_dev, aw_cfg); - if (ret) { - dev_err(aw_dev->dev, "aw_dev acf parse failed"); - return -EINVAL; - } - aw_dev->fade_in_time =3D AW88395_1000_US / 10; - aw_dev->fade_out_time =3D AW88395_1000_US >> 1; - aw_dev->prof_cur =3D aw_dev->prof_info.prof_desc[0].id; - aw_dev->prof_index =3D aw_dev->prof_info.prof_desc[0].id; - - ret =3D aw88395_dev_fw_update(aw_dev, AW88395_FORCE_UPDATE_ON, AW88395_DS= P_FW_UPDATE_ON); - if (ret) { - dev_err(aw_dev->dev, "fw update failed ret =3D %d\n", ret); - return ret; - } - - /* set mute */ - aw88395_dev_mute(aw_dev, true); - usleep_range(AW88395_4000_US, AW88395_4000_US + 100); - - /* close tx feedback */ - aw_dev_i2s_tx_enable(aw_dev, false); - usleep_range(AW88395_1000_US, AW88395_1000_US + 100); - - /* close dsp */ - aw_dev_dsp_enable(aw_dev, false); - /* enable amppd */ - aw_dev_amppd(aw_dev, true); - /* set power down */ - aw_dev_pwd(aw_dev, true); - - return 0; -} -EXPORT_SYMBOL_GPL(aw88395_dev_init); - -static void aw88395_parse_channel_dt(struct aw_device *aw_dev) -{ - struct device_node *np =3D aw_dev->dev->of_node; - u32 channel_value; - int ret; - - ret =3D of_property_read_u32(np, "awinic,audio-channel", &channel_value); - if (ret) { - dev_dbg(aw_dev->dev, - "read audio-channel failed,use default 0"); - aw_dev->channel =3D AW88395_DEV_DEFAULT_CH; - return; - } - - dev_dbg(aw_dev->dev, "read audio-channel value is: %d", - channel_value); - aw_dev->channel =3D channel_value; -} - -static int aw_dev_init(struct aw_device *aw_dev) -{ - aw_dev->chip_id =3D AW88395_CHIP_ID; - /* call aw device init func */ - aw_dev->acf =3D NULL; - aw_dev->prof_info.prof_desc =3D NULL; - aw_dev->prof_info.count =3D 0; - aw_dev->prof_info.prof_type =3D AW88395_DEV_NONE_TYPE_ID; - aw_dev->channel =3D 0; - aw_dev->fw_status =3D AW88395_DEV_FW_FAILED; - - aw_dev->fade_step =3D AW88395_VOLUME_STEP_DB; - aw_dev->volume_desc.ctl_volume =3D AW88395_VOL_DEFAULT_VALUE; - aw88395_parse_channel_dt(aw_dev); - - return 0; -} - -int aw88395_dev_get_profile_count(struct aw_device *aw_dev) -{ - return aw_dev->prof_info.count; -} -EXPORT_SYMBOL_GPL(aw88395_dev_get_profile_count); - -int aw88395_dev_get_profile_index(struct aw_device *aw_dev) -{ - return aw_dev->prof_index; -} -EXPORT_SYMBOL_GPL(aw88395_dev_get_profile_index); - -int aw88395_dev_set_profile_index(struct aw_device *aw_dev, int index) -{ - /* check the index whether is valid */ - if ((index >=3D aw_dev->prof_info.count) || (index < 0)) - return -EINVAL; - /* check the index whether change */ - if (aw_dev->prof_index =3D=3D index) - return -EINVAL; - - aw_dev->prof_index =3D index; - dev_dbg(aw_dev->dev, "set prof[%s]", - aw_dev->prof_info.prof_name_list[aw_dev->prof_info.prof_desc[index].id]); - - return 0; -} -EXPORT_SYMBOL_GPL(aw88395_dev_set_profile_index); - -int aw88395_dev_get_prof_name(struct aw_device *aw_dev, int index, char **= prof_name) -{ - struct aw_prof_info *prof_info =3D &aw_dev->prof_info; - struct aw_prof_desc *prof_desc; - - if ((index >=3D aw_dev->prof_info.count) || (index < 0)) { - dev_err(aw_dev->dev, "index[%d] overflow count[%d]", - index, aw_dev->prof_info.count); - return -EINVAL; - } - - prof_desc =3D &aw_dev->prof_info.prof_desc[index]; - - *prof_name =3D prof_info->prof_name_list[prof_desc->id]; - - return 0; -} -EXPORT_SYMBOL_GPL(aw88395_dev_get_prof_name); - -int aw88395_dev_get_prof_data(struct aw_device *aw_dev, int index, - struct aw_prof_desc **prof_desc) -{ - if ((index >=3D aw_dev->prof_info.count) || (index < 0)) { - dev_err(aw_dev->dev, "%s: index[%d] overflow count[%d]\n", - __func__, index, aw_dev->prof_info.count); - return -EINVAL; - } - - *prof_desc =3D &aw_dev->prof_info.prof_desc[index]; - - return 0; -} -EXPORT_SYMBOL_GPL(aw88395_dev_get_prof_data); - -int aw88395_init(struct aw_device **aw_dev, struct i2c_client *i2c, struct= regmap *regmap) -{ - u16 chip_id; - int ret; - - if (*aw_dev) { - dev_info(&i2c->dev, "it should be initialized here.\n"); - } else { - *aw_dev =3D devm_kzalloc(&i2c->dev, sizeof(struct aw_device), GFP_KERNEL= ); - if (!(*aw_dev)) - return -ENOMEM; - } - - (*aw_dev)->i2c =3D i2c; - (*aw_dev)->dev =3D &i2c->dev; - (*aw_dev)->regmap =3D regmap; - mutex_init(&(*aw_dev)->dsp_lock); - - /* read chip id */ - ret =3D aw_dev_read_chipid((*aw_dev), &chip_id); - if (ret) { - dev_err(&i2c->dev, "dev_read_chipid failed ret=3D%d", ret); - return ret; - } - - switch (chip_id) { - case AW88395_CHIP_ID: - ret =3D aw_dev_init((*aw_dev)); - break; - default: - ret =3D -EINVAL; - dev_err((*aw_dev)->dev, "unsupported device"); - break; - } - - return ret; -} -EXPORT_SYMBOL_GPL(aw88395_init); - -MODULE_DESCRIPTION("AW88395 device lib"); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/aw88395/aw88395_device.h b/sound/soc/codecs/a= w88395/aw88395_device.h deleted file mode 100644 index 6f8b30b475da..000000000000 --- a/sound/soc/codecs/aw88395/aw88395_device.h +++ /dev/null @@ -1,214 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// -// aw88395_device.h -- AW88395 function for ALSA Audio Driver -// -// Copyright (c) 2022-2023 AWINIC Technology CO., LTD -// -// Author: Bruce zhao -// - -#ifndef __AW88395_DEVICE_FILE_H__ -#define __AW88395_DEVICE_FILE_H__ - -#include "aw88395.h" -#include "aw88395_data_type.h" -#include "aw88395_lib.h" - -#define AW88395_DEV_DEFAULT_CH (0) -#define AW88395_DEV_DSP_CHECK_MAX (5) -#define AW88395_DSP_I2C_WRITES -#define AW88395_MAX_RAM_WRITE_BYTE_SIZE (128) -#define AW88395_DSP_ODD_NUM_BIT_TEST (0x5555) -#define AW88395_DSP_EVEN_NUM_BIT_TEST (0xAAAA) -#define AW88395_DSP_ST_CHECK_MAX (2) -#define AW88395_FADE_IN_OUT_DEFAULT (0) -#define AW88395_CALI_RE_MAX (15000) -#define AW88395_CALI_RE_MIN (4000) -#define AW88395_CALI_DELAY_CACL(value) ((value * 32) / 48) - -#define AW88395_DSP_RE_TO_SHOW_RE(re, shift) (((re) * (1000)) >> (shift)) -#define AW88395_SHOW_RE_TO_DSP_RE(re, shift) (((re) << shift) / (1000)) - -#define AW88395_ACF_FILE "aw88395_acf.bin" -#define AW88395_DEV_SYSST_CHECK_MAX (10) - -enum { - AW88395_DEV_VDSEL_DAC =3D 0, - AW88395_DEV_VDSEL_VSENSE =3D 1, -}; - -enum { - AW88395_DSP_CRC_NA =3D 0, - AW88395_DSP_CRC_OK =3D 1, -}; - -enum { - AW88395_DSP_FW_UPDATE_OFF =3D 0, - AW88395_DSP_FW_UPDATE_ON =3D 1, -}; - -enum { - AW88395_FORCE_UPDATE_OFF =3D 0, - AW88395_FORCE_UPDATE_ON =3D 1, -}; - -enum { - AW88395_1000_US =3D 1000, - AW88395_2000_US =3D 2000, - AW88395_3000_US =3D 3000, - AW88395_4000_US =3D 4000, - AW88395_5000_US =3D 5000, - AW88395_10000_US =3D 10000, - AW88395_100000_US =3D 100000, -}; - -enum { - AW88395_DEV_TYPE_OK =3D 0, - AW88395_DEV_TYPE_NONE =3D 1, -}; - - -enum AW88395_DEV_STATUS { - AW88395_DEV_PW_OFF =3D 0, - AW88395_DEV_PW_ON, -}; - -enum AW88395_DEV_FW_STATUS { - AW88395_DEV_FW_FAILED =3D 0, - AW88395_DEV_FW_OK, -}; - -enum AW88395_DEV_MEMCLK { - AW88395_DEV_MEMCLK_OSC =3D 0, - AW88395_DEV_MEMCLK_PLL =3D 1, -}; - -enum AW88395_DEV_DSP_CFG { - AW88395_DEV_DSP_WORK =3D 0, - AW88395_DEV_DSP_BYPASS =3D 1, -}; - -enum { - AW88395_DSP_16_DATA =3D 0, - AW88395_DSP_32_DATA =3D 1, -}; - -enum { - AW88395_NOT_RCV_MODE =3D 0, - AW88395_RCV_MODE =3D 1, -}; - -struct aw_profctrl_desc { - unsigned int cur_mode; -}; - -enum { - CALI_RESULT_NORMAL, - CALI_RESULT_ERROR, -}; - -struct aw_volume_desc { - unsigned int init_volume; - unsigned int mute_volume; - unsigned int ctl_volume; - unsigned int max_volume; -}; - -struct aw_dsp_mem_desc { - unsigned int dsp_madd_reg; - unsigned int dsp_mdat_reg; - unsigned int dsp_fw_base_addr; - unsigned int dsp_cfg_base_addr; -}; - -struct aw_vmax_desc { - unsigned int init_vmax; -}; - -struct aw_cali_delay_desc { - unsigned int delay; -}; - -#define AW_CALI_CFG_NUM (4) -struct cali_cfg { - uint32_t data[AW_CALI_CFG_NUM]; -}; - -struct aw_cali_backup_desc { - unsigned int dsp_ng_cfg; - unsigned int dsp_lp_cfg; -}; - -struct aw_cali_desc { - u32 cali_re; - u32 ra; - bool cali_switch; - bool cali_running; - uint16_t cali_result; - uint16_t store_vol; - struct cali_cfg cali_cfg; - struct aw_cali_backup_desc backup_info; -}; - -struct aw_container { - int len; - u8 data[]; -}; - -struct aw_device { - int status; - struct mutex dsp_lock; - - unsigned char prof_cur; - unsigned char prof_index; - unsigned char dsp_crc_st; - unsigned char dsp_cfg; - u16 chip_id; - - unsigned int channel; - unsigned int fade_step; - unsigned int prof_data_type; - - struct i2c_client *i2c; - struct device *dev; - struct regmap *regmap; - char *acf; - - u32 dsp_fw_len; - u32 dsp_cfg_len; - u8 platform; - u8 fw_status; - - unsigned int fade_in_time; - unsigned int fade_out_time; - - struct aw_prof_info prof_info; - struct aw_sec_data_desc crc_dsp_cfg; - struct aw_profctrl_desc profctrl_desc; - struct aw_volume_desc volume_desc; - struct aw_dsp_mem_desc dsp_mem_desc; - struct aw_vmax_desc vmax_desc; - - struct aw_cali_delay_desc cali_delay_desc; - struct aw_cali_desc cali_desc; - -}; - -int aw88395_init(struct aw_device **aw_dev, struct i2c_client *i2c, struct= regmap *regmap); -int aw88395_dev_init(struct aw_device *aw_dev, struct aw_container *aw_cfg= ); -int aw88395_dev_start(struct aw_device *aw_dev); -int aw88395_dev_stop(struct aw_device *aw_dev); -int aw88395_dev_fw_update(struct aw_device *aw_dev, bool up_dsp_fw_en, boo= l force_up_en); - -void aw88395_dev_set_volume(struct aw_device *aw_dev, unsigned short set_v= ol); -int aw88395_dev_get_prof_data(struct aw_device *aw_dev, int index, - struct aw_prof_desc **prof_desc); -int aw88395_dev_get_prof_name(struct aw_device *aw_dev, int index, char **= prof_name); -int aw88395_dev_set_profile_index(struct aw_device *aw_dev, int index); -int aw88395_dev_get_profile_index(struct aw_device *aw_dev); -int aw88395_dev_get_profile_count(struct aw_device *aw_dev); -int aw88395_dev_load_acf_check(struct aw_device *aw_dev, struct aw_contain= er *aw_cfg); -int aw88395_dev_cfg_load(struct aw_device *aw_dev, struct aw_container *aw= _cfg); -void aw88395_dev_mute(struct aw_device *aw_dev, bool is_mute); - -#endif diff --git a/sound/soc/codecs/aw88395/aw88395_lib.h b/sound/soc/codecs/aw88= 395/aw88395_lib.h deleted file mode 100644 index 8a620920d8bd..000000000000 --- a/sound/soc/codecs/aw88395/aw88395_lib.h +++ /dev/null @@ -1,92 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// -// aw88395_lib.h -- ACF bin parsing and check library file for aw88395 -// -// Copyright (c) 2022-2023 AWINIC Technology CO., LTD -// -// Author: Bruce zhao -// - -#ifndef __AW88395_LIB_H__ -#define __AW88395_LIB_H__ - -#define CHECK_REGISTER_NUM_OFFSET (4) -#define VALID_DATA_LEN (4) -#define VALID_DATA_ADDR (4) -#define PARSE_DSP_REG_NUM (4) -#define REG_DATA_BYTP_LEN (8) -#define CHECK_DSP_REG_NUM (12) -#define DSP_VALID_DATA_LEN (12) -#define DSP_VALID_DATA_ADDR (12) -#define PARSE_SOC_APP_NUM (8) -#define CHECK_SOC_APP_NUM (12) -#define APP_DOWNLOAD_ADDR (4) -#define APP_VALID_DATA_LEN (12) -#define APP_VALID_DATA_ADDR (12) -#define BIN_NUM_MAX (100) -#define HEADER_LEN (60) -#define BIN_DATA_TYPE_OFFSET (8) -#define DATA_LEN (44) -#define VALID_DATA_ADDR_OFFSET (60) -#define START_ADDR_OFFSET (64) - -#define AW88395_FW_CHECK_PART (10) -#define HDADER_LEN (60) - -#define HEADER_VERSION_OFFSET (4) - -enum bin_header_version_enum { - HEADER_VERSION_V1 =3D 0x01000000, -}; - -enum data_type_enum { - DATA_TYPE_REGISTER =3D 0x00000000, - DATA_TYPE_DSP_REG =3D 0x00000010, - DATA_TYPE_DSP_CFG =3D 0x00000011, - DATA_TYPE_SOC_REG =3D 0x00000020, - DATA_TYPE_SOC_APP =3D 0x00000021, - DATA_TYPE_DSP_FW =3D 0x00000022, - DATA_TYPE_MULTI_BINS =3D 0x00002000, -}; - -enum data_version_enum { - DATA_VERSION_V1 =3D 0x00000001, - DATA_VERSION_MAX, -}; - -struct bin_header_info { - unsigned int check_sum; - unsigned int header_ver; - unsigned int bin_data_type; - unsigned int bin_data_ver; - unsigned int bin_data_len; - unsigned int ui_ver; - unsigned char chip_type[8]; - unsigned int reg_byte_len; - unsigned int data_byte_len; - unsigned int device_addr; - unsigned int valid_data_len; - unsigned int valid_data_addr; - - unsigned int reg_num; - unsigned int reg_data_byte_len; - unsigned int download_addr; - unsigned int app_version; - unsigned int header_len; -}; - -struct bin_container { - unsigned int len; - unsigned char data[]; -}; - -struct aw_bin { - unsigned char *p_addr; - unsigned int all_bin_parse_num; - unsigned int multi_bin_parse_num; - unsigned int single_bin_parse_num; - struct bin_header_info header_info[BIN_NUM_MAX]; - struct bin_container info; -}; - -#endif --=20 2.47.0 From nobody Wed Oct 1 22:31:21 2025 Received: from out28-3.mail.aliyun.com (out28-3.mail.aliyun.com [115.124.28.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2C9781A58D; Fri, 26 Sep 2025 10:36:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.28.3 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758882995; cv=none; b=QwlmtexqmcXdgi29mgqGOIdO9ld+HxKlh2XWZKCNH2PuMRXq3V4HNL0jmHnRwsa5xCtxE+sU2I7Ko5bGPrAeWCtQnU9JXZg6+yzrVx1zUdAXkfYMQiWJFss8HDxydckIXKWFJrviH8cj/RFrRZfsqOYQuiAQk4gU6WyMq/7nwng= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758882995; c=relaxed/simple; bh=KWH0BqsCaHGYrNL8ZEOgTY93SQThzGUSbtzaQPdu4Nw=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kPxLeIB5/yWLAg+dPuIV8kvFk1kXR8R3c5mVJUdmsEtOxrpeZqjGs1HxBwLKaiGMD2twbTs156yCQtNTEfOnXR6mhU1tvGH3OqDk0T+Ew1EqY79Dt+LZPXy0UyJm2nj4dTUXC3y4ujvSEAveKMI2cNIqie0tlaTBD2v9r4Fa53g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=awinic.com; spf=pass smtp.mailfrom=awinic.com; dkim=pass (2048-bit key) header.d=awinic.com header.i=@awinic.com header.b=bEbqj8+O; arc=none smtp.client-ip=115.124.28.3 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=awinic.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=awinic.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=awinic.com header.i=@awinic.com header.b="bEbqj8+O" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=awinic.com; s=default; t=1758882984; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=eOocW7XO87KQGoWcWy6jZGqpK2EvZcfN7Tih9Jvg6zE=; b=bEbqj8+OEWNHkwWMqYGR+GQVkb8biy4BT3E6kdBsGfuaJhz+bHhiQRYHcgC8geZ1pm87//prridwaBzXLfolfsajHDu2skT2OS+buAYjzMBI5GZEkHDkIVX618/Z1H/R9nSLoj07HxQp4H0qAB3m3MPoPdQBbLLaM0uqXvlJOfiBG0ZDgwNssktnjIcxX+0kndPo90C/EJO1Ap4FsSm7DMbPdM0K7tRS3jW0O1TQ+Z85acm35IcOodBk86kjut0GwEabgLADckO3n+/S2sQq2Zekz7JUvgAdTYIqNAvRgEBVsMrT/1ySyu1sthZ53duezJ++ULtzXJqPpUp6vdxFjQ== Received: from ubuntu-VirtualBox..(mailfrom:wangweidong.a@awinic.com fp:SMTPD_---.ensjOxn_1758882044 cluster:ay29) by smtp.aliyun-inc.com; Fri, 26 Sep 2025 18:20:45 +0800 From: wangweidong.a@awinic.com To: lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, wangweidong.a@awinic.com, cy_huang@richtek.com, ivprusov@salutedevices.com, zhoubinbin@loongson.cn, zhangyi@everest-semi.com, jack.yu@realtek.com, shenghao-ding@ti.com, rf@opensource.cirrus.com, git@apitzsch.eu, nuno.sa@analog.com, colin.i.king@gmail.com, thorsten.blum@linux.dev, yesanishhere@gmail.com, ebiggers@google.com, ardb@kernel.org, zhujun2@cmss.chinamobile.com, linux-kernel@vger.kernel.org, linux-sound@vger.kernel.org Subject: [PATCH V1 2/7] ASoC: codecs: Rework the aw88395 driver Date: Fri, 26 Sep 2025 18:20:32 +0800 Message-ID: <20250926102037.27697-3-wangweidong.a@awinic.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20250926102037.27697-1-wangweidong.a@awinic.com> References: <20250926102037.27697-1-wangweidong.a@awinic.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Weidong Wang Modify the interface for calling the aw88395 driver to adapt it for aw-common-device.c and aw-common-firmware.c Signed-off-by: Weidong Wang --- sound/soc/codecs/Kconfig | 14 +- sound/soc/codecs/Makefile | 8 +- sound/soc/codecs/aw88395.c | 1337 +++++++++++++++++ .../{aw88395/aw88395_reg.h =3D> aw88395.h} | 58 +- sound/soc/codecs/aw88395/aw88395.c | 576 ------- sound/soc/codecs/aw88395/aw88395.h | 58 - 6 files changed, 1383 insertions(+), 668 deletions(-) create mode 100644 sound/soc/codecs/aw88395.c rename sound/soc/codecs/{aw88395/aw88395_reg.h =3D> aw88395.h} (91%) delete mode 100644 sound/soc/codecs/aw88395/aw88395.c delete mode 100644 sound/soc/codecs/aw88395/aw88395.h diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 6d7e4725d89c..a46665802b4f 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -667,7 +667,7 @@ config SND_SOC_AW8738 SND_SOC_SIMPLE_AMPLIFIER, but additionally allows setting the operation mode using the Awinic-specific one-wire pulse control. =20 -config SND_SOC_AW88395_LIB +config SND_SOC_AWCOMMON_LIB select CRC8 tristate =20 @@ -677,7 +677,7 @@ config SND_SOC_AW88395 select CRC32 select REGMAP_I2C select GPIOLIB - select SND_SOC_AW88395_LIB + select SND_SOC_AWCOMMON_LIB help this option enables support for aw88395 Smart PA. The Awinic AW88395 is an I2S/TDM input, high efficiency @@ -689,7 +689,7 @@ config SND_SOC_AW88166 depends on I2C select REGMAP_I2C select GPIOLIB - select SND_SOC_AW88395_LIB + select SND_SOC_AWCOMMON_LIB help This option enables support for aw88166 Smart PA. The awinic AW88166 is an I2S/TDM input, high efficiency @@ -701,7 +701,7 @@ config SND_SOC_AW88261 depends on I2C select REGMAP_I2C select GPIOLIB - select SND_SOC_AW88395_LIB + select SND_SOC_AWCOMMON_LIB help This option enables support for aw88261 Smart PA. The awinic AW88261 is an I2S/TDM input, high efficiency @@ -713,7 +713,7 @@ config SND_SOC_AW88081 tristate "Soc Audio for awinic aw88081/aw88083" depends on I2C select REGMAP_I2C - select SND_SOC_AW88395_LIB + select SND_SOC_AWCOMMON_LIB help This option enables support for aw88081 Smart PA. The awinic AW88081 is an I2S/TDM input, high efficiency @@ -724,7 +724,7 @@ config SND_SOC_AW87390 tristate "Soc Audio for awinic aw87390" depends on I2C select REGMAP_I2C - select SND_SOC_AW88395_LIB + select SND_SOC_AWCOMMON_LIB help The awinic aw87390 is specifically designed to improve the musical output dynamic range, enhance the overall @@ -737,7 +737,7 @@ config SND_SOC_AW88399 select CRC8 select REGMAP_I2C select GPIOLIB - select SND_SOC_AW88395_LIB + select SND_SOC_AWCOMMON_LIB help This option enables support for aw88399 Smart PA. The awinic AW88399 is an I2S/TDM input, high efficiency diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index a68c3d192a1b..de775563def9 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -50,9 +50,9 @@ snd-soc-audio-iio-aux-y :=3D audio-iio-aux.o snd-soc-aw8738-y :=3D aw8738.o snd-soc-aw87390-y :=3D aw87390.o snd-soc-aw88081-y :=3D aw88081.o -snd-soc-aw88395-lib-y :=3D aw88395/aw88395_lib.o -snd-soc-aw88395-y :=3D aw88395/aw88395.o \ - aw88395/aw88395_device.o +snd-soc-awcommon-lib-y :=3D aw-common-device.o \ + aw-common-firmware.o +snd-soc-aw88395-y :=3D aw88395.o snd-soc-aw88166-y :=3D aw88166.o snd-soc-aw88261-y :=3D aw88261.o snd-soc-aw88399-y :=3D aw88399.o @@ -476,7 +476,7 @@ obj-$(CONFIG_SND_SOC_AUDIO_IIO_AUX) +=3D snd-soc-audio-= iio-aux.o obj-$(CONFIG_SND_SOC_AW8738) +=3D snd-soc-aw8738.o obj-$(CONFIG_SND_SOC_AW87390) +=3D snd-soc-aw87390.o obj-$(CONFIG_SND_SOC_AW88081) +=3D snd-soc-aw88081.o -obj-$(CONFIG_SND_SOC_AW88395_LIB) +=3D snd-soc-aw88395-lib.o +obj-$(CONFIG_SND_SOC_AWCOMMON_LIB) +=3D snd-soc-awcommon-lib.o obj-$(CONFIG_SND_SOC_AW88395) +=3Dsnd-soc-aw88395.o obj-$(CONFIG_SND_SOC_AW88166) +=3Dsnd-soc-aw88166.o obj-$(CONFIG_SND_SOC_AW88261) +=3Dsnd-soc-aw88261.o diff --git a/sound/soc/codecs/aw88395.c b/sound/soc/codecs/aw88395.c new file mode 100644 index 000000000000..3ed77e0f0df2 --- /dev/null +++ b/sound/soc/codecs/aw88395.c @@ -0,0 +1,1337 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// aw88395.c -- ALSA SoC AW88395 codec support +// +// Copyright (c) 2022-2023 AWINIC Technology CO., LTD +// +// Author: Weidong Wang +// + +#include +#include +#include +#include +#include +#include +#include "aw88395.h" +#include "aw-common-device.h" +#include "aw-common-firmware.h" + +struct aw88395 { + struct aw_device *aw_pa; + struct mutex lock; + struct delayed_work start_work; + struct regmap *regmap; +}; + +static const struct regmap_config aw88395_remap_config =3D { + .val_bits =3D 16, + .reg_bits =3D 8, + .max_register =3D AW88395_REG_MAX - 1, + .reg_format_endian =3D REGMAP_ENDIAN_LITTLE, + .val_format_endian =3D REGMAP_ENDIAN_BIG, +}; + +static unsigned int reg_val_to_db(unsigned int value) +{ + return (((value >> AW88395_VOL_6DB_START) * AW_VOLUME_STEP_DB) + + ((value & 0x3f) % AW_VOLUME_STEP_DB)); +} + +static unsigned short db_to_reg_val(unsigned short value) +{ + return (((value / AW_VOLUME_STEP_DB) << AW88395_VOL_6DB_START) + + (value % AW_VOLUME_STEP_DB)); +} + +static void aw88395_set_volume(struct aw_device *aw_dev, unsigned int valu= e) +{ + struct aw_volume_desc *vol_desc =3D &aw_dev->volume_desc; + unsigned int reg_value; + u16 real_value, volume; + + volume =3D min((value + vol_desc->init_volume), (unsigned int)AW88395_MUT= E_VOL); + real_value =3D db_to_reg_val(volume); + + /* cal real value */ + regmap_read(aw_dev->regmap, AW88395_SYSCTRL2_REG, ®_value); + + dev_dbg(aw_dev->dev, "value 0x%x , reg:0x%x", value, real_value); + + /* [15 : 6] volume */ + real_value =3D (real_value << AW88395_VOL_START_BIT) | (reg_value & AW883= 95_VOL_MASK); + + /* write value */ + regmap_write(aw_dev->regmap, AW88395_SYSCTRL2_REG, real_value); +} + +static int aw88395_check_sram(struct aw_device *aw_dev) +{ + unsigned int reg_val; + + /* read dsp_rom_check_reg */ + aw_dev_dsp_read(aw_dev, AW88395_DSP_ROM_CHECK_ADDR, ®_val, AW_DSP_16_D= ATA); + if (reg_val !=3D AW88395_DSP_ROM_CHECK_DATA) { + dev_err(aw_dev->dev, "check dsp rom failed "); + goto error; + } + + /* check dsp_fw_base_addr */ + aw_dev_dsp_write(aw_dev, AW88395_DSP_FW_ADDR, AW88395_DSP_ODD_NUM_BIT_TES= T, AW_DSP_16_DATA); + aw_dev_dsp_read(aw_dev, AW88395_DSP_FW_ADDR, ®_val, AW_DSP_16_DATA); + if (reg_val !=3D AW88395_DSP_ODD_NUM_BIT_TEST) { + dev_err(aw_dev->dev, "check dsp fw addr failed"); + goto error; + } + + return 0; + +error: + return -EPERM; +} + +static int aw88395_get_iis_status(struct aw_device *aw_dev) +{ + unsigned int reg_val; + int ret; + + ret =3D regmap_read(aw_dev->regmap, AW88395_SYSST_REG, ®_val); + if (ret) + return -EIO; + if ((reg_val & AW88395_BIT_PLL_CHECK) !=3D AW88395_BIT_PLL_CHECK) { + dev_err(aw_dev->dev, "check pll lock fail,reg_val:0x%04x", reg_val); + return -EINVAL; + } + + return 0; +} + +static int aw88395_check_mode1_pll(struct aw_device *aw_dev) +{ + int ret, i; + + for (i =3D 0; i < AW88395_DEV_SYSST_CHECK_MAX; i++) { + ret =3D aw88395_get_iis_status(aw_dev); + if (ret < 0) { + dev_err(aw_dev->dev, "mode1 iis signal check error"); + usleep_range(AW_2000_US, AW_2000_US + 10); + } else { + return 0; + } + } + + return -EPERM; +} + +static int aw88395_check_mode2_pll(struct aw_device *aw_dev) +{ + unsigned int reg_val; + int ret, i; + + ret =3D regmap_read(aw_dev->regmap, AW88395_PLLCTRL1_REG, ®_val); + if (ret) + return ret; + + reg_val &=3D (~AW88395_CCO_MUX_MASK); + if (reg_val =3D=3D AW88395_CCO_MUX_DIVIDED_VALUE) { + dev_dbg(aw_dev->dev, "CCO_MUX is already divider"); + return -EPERM; + } + + /* change mode2 */ + ret =3D regmap_update_bits(aw_dev->regmap, AW88395_PLLCTRL1_REG, + ~AW88395_CCO_MUX_MASK, AW88395_CCO_MUX_DIVIDED_VALUE); + if (ret) + return ret; + + for (i =3D 0; i < AW88395_DEV_SYSST_CHECK_MAX; i++) { + ret =3D aw88395_get_iis_status(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "mode2 iis signal check error"); + usleep_range(AW_2000_US, AW_2000_US + 10); + } else { + break; + } + } + + /* change mode1 */ + ret =3D regmap_update_bits(aw_dev->regmap, AW88395_PLLCTRL1_REG, + ~AW88395_CCO_MUX_MASK, AW88395_CCO_MUX_BYPASS_VALUE); + if (ret =3D=3D 0) { + usleep_range(AW_2000_US, AW_2000_US + 10); + for (i =3D 0; i < AW88395_DEV_SYSST_CHECK_MAX; i++) { + ret =3D aw88395_check_mode1_pll(aw_dev); + if (ret < 0) { + dev_err(aw_dev->dev, "mode2 switch to mode1, iis signal check error"); + usleep_range(AW_2000_US, AW_2000_US + 10); + } else { + break; + } + } + } + + return ret; +} + +static int aw88395_check_syspll(struct aw_device *aw_dev) +{ + int ret; + + ret =3D aw88395_check_mode1_pll(aw_dev); + if (ret) { + dev_dbg(aw_dev->dev, "mode1 check iis failed try switch to mode2 check"); + ret =3D aw88395_check_mode2_pll(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "mode2 check iis failed"); + return ret; + } + } + + return ret; +} + +static int aw88395_check_sysst(struct aw_device *aw_dev) +{ + unsigned int check_val; + unsigned int reg_val; + int ret, i; + + for (i =3D 0; i < AW88395_DEV_SYSST_CHECK_MAX; i++) { + ret =3D regmap_read(aw_dev->regmap, AW88395_SYSST_REG, ®_val); + if (ret) + return ret; + + check_val =3D reg_val & (~AW88395_BIT_SYSST_CHECK_MASK) & AW88395_BIT_SY= SST_CHECK; + if (check_val !=3D AW88395_BIT_SYSST_CHECK) { + dev_err(aw_dev->dev, "check sysst fail, cnt=3D%d, reg_val=3D0x%04x, che= ck:0x%x", + i, reg_val, AW88395_BIT_SYSST_CHECK); + usleep_range(AW_2000_US, AW_2000_US + 10); + } else { + return 0; + } + } + + return -EPERM; +} + +static int aw88395_check_sysint(struct aw_device *aw_dev) +{ + u16 reg_val; + + aw_dev_get_int_status(aw_dev, ®_val); + + if (reg_val & AW88395_BIT_SYSINT_CHECK) { + dev_err(aw_dev->dev, "pa stop check fail:0x%04x", reg_val); + return -EINVAL; + } + + return 0; +} + +static void aw88395_dev_mute(struct aw_device *aw_dev, bool is_mute) +{ + int ret; + + if (is_mute) { + aw_dev_fade_out(aw_dev, aw88395_set_volume); + ret =3D regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, + ~AW88395_HMUTE_MASK, AW88395_HMUTE_ENABLE_VALUE); + } else { + ret =3D regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, + ~AW88395_HMUTE_MASK, AW88395_HMUTE_DISABLE_VALUE); + aw_dev_fade_in(aw_dev, aw88395_set_volume); + } + + if (ret) + dev_dbg(aw_dev->dev, "%s failed", __func__); +} + +static int aw888395_cali_get_ra(struct aw_device *aw_dev) +{ + struct aw_cali_desc *cali_desc =3D &aw_dev->cali_desc; + uint32_t dsp_ra; + int ret; + + ret =3D aw_dev_dsp_read(aw_dev, AW88395_DSP_REG_CFG_ADPZ_RA, + &dsp_ra, AW_DSP_32_DATA); + if (ret < 0) { + dev_err(aw_dev->dev, "read ra error"); + return ret; + } + + cali_desc->ra =3D AW88395_DSP_RE_TO_SHOW_RE(dsp_ra, AW88395_DSP_RE_SHIFT); + + return 0; +} + +static int aw88395_dsp_set_cali_re(struct aw_device *aw_dev) +{ + u32 cali_re; + int ret; + + cali_re =3D AW88395_SHOW_RE_TO_DSP_RE((aw_dev->cali_desc.cali_re + + aw_dev->cali_desc.ra), AW88395_DSP_RE_SHIFT); + + /* set cali re to device */ + ret =3D aw_dev_dsp_write(aw_dev, + AW88395_DSP_REG_CFG_ADPZ_RE, cali_re, AW_DSP_32_DATA); + if (ret) + dev_err(aw_dev->dev, "set cali re error"); + + return ret; +} + +static int aw88395_update_cali_re(struct aw_cali_desc *cali_desc) +{ + struct aw_device *aw_dev =3D + container_of(cali_desc, struct aw_device, cali_desc); + int ret; + + if ((aw_dev->cali_desc.cali_re >=3D AW88395_CALI_RE_MAX) || + (aw_dev->cali_desc.cali_re <=3D AW88395_CALI_RE_MIN)) { + return -EINVAL; + } + + ret =3D aw88395_dsp_set_cali_re(aw_dev); + if (ret) + dev_err(aw_dev->dev, "set cali re failed"); + + return ret; +} + +static int aw88395_dsp_check_st(struct aw_device *aw_dev) +{ + unsigned int reg_val; + int ret; + int i; + + for (i =3D 0; i < AW88395_DSP_ST_CHECK_MAX; i++) { + ret =3D regmap_read(aw_dev->regmap, AW88395_SYSST_REG, ®_val); + if (ret) { + dev_err(aw_dev->dev, "read reg0x%x failed", AW88395_SYSST_REG); + continue; + } + + if ((reg_val & (~AW88395_DSPS_MASK)) !=3D AW88395_DSPS_NORMAL_VALUE) { + dev_err(aw_dev->dev, "check dsp st fail,reg_val:0x%04x", reg_val); + ret =3D -EPERM; + continue; + } else { + dev_dbg(aw_dev->dev, "dsp st check ok, reg_val:0x%04x", reg_val); + return 0; + } + } + + return ret; +} + +static int aw88395_copy_to_crc_dsp_cfg(struct aw_device *aw_dev, + unsigned char *data, unsigned int size) +{ + struct aw_sec_data_desc *crc_dsp_cfg =3D &aw_dev->crc_dsp_cfg; + + if (!crc_dsp_cfg->data) { + crc_dsp_cfg->data =3D devm_kzalloc(aw_dev->dev, size, GFP_KERNEL); + if (!crc_dsp_cfg->data) + return -ENOMEM; + crc_dsp_cfg->len =3D size; + } else if (crc_dsp_cfg->len < size) { + devm_kfree(aw_dev->dev, crc_dsp_cfg->data); + crc_dsp_cfg->data =3D devm_kzalloc(aw_dev->dev, size, GFP_KERNEL); + if (!crc_dsp_cfg->data) + return -ENOMEM; + crc_dsp_cfg->len =3D size; + } + memcpy(crc_dsp_cfg->data, data, size); + swab16_array((u16 *)crc_dsp_cfg->data, size >> 1); + + return 0; +} + +static int aw88395_dsp_set_crc32(struct aw_device *aw_dev) +{ + struct aw_sec_data_desc *crc_dsp_cfg =3D &aw_dev->crc_dsp_cfg; + struct aw_prof_desc *set_prof_desc =3D NULL; + u32 crc_value, crc_data_len; + int ret; + + ret =3D aw_dev_get_prof_data(aw_dev, aw_dev->prof_cur, &set_prof_desc); + if (ret) + return ret; + + ret =3D aw88395_copy_to_crc_dsp_cfg(aw_dev, + set_prof_desc->sec_desc[AW_DATA_TYPE_DSP_CFG].data, + set_prof_desc->sec_desc[AW_DATA_TYPE_DSP_CFG].len); + if (ret) + return ret; + + /* get crc data len */ + crc_data_len =3D (AW88395_DSP_REG_CRC_ADDR - AW88395_DSP_CFG_ADDR) * 2; + if (crc_data_len > crc_dsp_cfg->len) { + dev_err(aw_dev->dev, "crc data len :%d > cfg_data len:%d", + crc_data_len, crc_dsp_cfg->len); + return -EINVAL; + } + + if (crc_data_len & 0x11) { + dev_err(aw_dev->dev, "The crc data len :%d unsupport", crc_data_len); + return -EINVAL; + } + + crc_value =3D crc32c(0xFFFFFFFF, crc_dsp_cfg->data, crc_data_len) ^ 0xFFF= FFFFF; + + return aw_dev_dsp_write(aw_dev, AW88395_DSP_REG_CRC_ADDR, crc_value, AW_D= SP_32_DATA); +} + +static int aw88395_dsp_crc_check(struct aw_device *aw_dev) +{ + int ret; + + if (aw_dev->fw_ver < AW88395_FIRMWARE_VERSION) { + ret =3D aw88395_dsp_set_crc32(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "set dsp crc32 failed"); + return ret; + } + } + + regmap_update_bits(aw_dev->regmap, AW88395_HAGCCFG7_REG, + ~AW88395_AGC_DSP_CTL_MASK, AW88395_AGC_DSP_CTL_ENABLE_VALUE); + + /* dsp enable */ + regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, + ~AW88395_DSPBY_MASK, AW88395_DSPBY_WORKING_VALUE); + usleep_range(AW_5000_US, AW_5000_US + 100); + + ret =3D aw88395_dsp_check_st(aw_dev); + if (ret) + dev_err(aw_dev->dev, "check crc32 fail"); + + regmap_update_bits(aw_dev->regmap, AW88395_HAGCCFG7_REG, + ~AW88395_AGC_DSP_CTL_MASK, AW88395_AGC_DSP_CTL_DISABLE_VALUE); + + return ret; +} + +static int aw88395_dsp_check(struct aw_device *aw_dev) +{ + int ret, i; + + regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, + ~AW88395_DSPBY_MASK, AW88395_DSPBY_BYPASS_VALUE); + regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, + ~AW88395_DSPBY_MASK, AW88395_DSPBY_WORKING_VALUE); + usleep_range(AW_1000_US, AW_1000_US + 10); + + for (i =3D 0; i < AW88395_DEV_DSP_CHECK_MAX; i++) { + ret =3D aw_dev_get_dsp_status(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "dsp wdt status error=3D%d", ret); + usleep_range(AW_2000_US, AW_2000_US + 10); + } else { + break; + } + } + + return ret; +} + +static int aw88395_get_icalk(struct aw_device *aw_dev, int16_t *icalk) +{ + unsigned int reg_val; + u16 reg_icalk; + int ret; + + ret =3D regmap_read(aw_dev->regmap, AW88395_EFRM2_REG, ®_val); + if (ret) + return ret; + + reg_icalk =3D reg_val & (~AW88395_EF_ISN_GESLP_MASK); + + if (reg_icalk & (~AW88395_EF_ISN_GESLP_SIGN_MASK)) + reg_icalk =3D reg_icalk | AW88395_EF_ISN_GESLP_SIGN_NEG; + + *icalk =3D (int16_t)reg_icalk; + + return ret; +} + +static int aw88395_get_vcalk(struct aw_device *aw_dev, int16_t *vcalk) +{ + unsigned int reg_val; + u16 reg_vcalk; + int ret; + + ret =3D regmap_read(aw_dev->regmap, AW88395_EFRH_REG, ®_val); + if (ret) + return ret; + + reg_val =3D reg_val >> AW88395_EF_VSENSE_GAIN_SHIFT; + + reg_vcalk =3D (u16)reg_val & (~AW88395_EF_VSN_GESLP_MASK); + + if (reg_vcalk & (~AW88395_EF_VSN_GESLP_SIGN_MASK)) + reg_vcalk =3D reg_vcalk | AW88395_EF_VSN_GESLP_SIGN_NEG; + + *vcalk =3D (int16_t)reg_vcalk; + + return ret; +} + +static int aw88395_get_vcalk_dac(struct aw_device *aw_dev, int16_t *vcalk) +{ + unsigned int reg_val; + u16 reg_vcalk; + int ret; + + ret =3D regmap_read(aw_dev->regmap, AW88395_EFRM2_REG, ®_val); + if (ret) + return ret; + + reg_vcalk =3D reg_val >> AW88395_EF_DAC_GESLP_SHIFT; + + if (reg_vcalk & AW88395_EF_DAC_GESLP_SIGN_MASK) + reg_vcalk =3D reg_vcalk | AW88395_EF_DAC_GESLP_SIGN_NEG; + + *vcalk =3D (int16_t)reg_vcalk; + + return ret; +} + +static int aw88395_set_vcalb(struct aw_device *aw_dev) +{ + int16_t icalk_val, vcalk_val; + int icalk, vsense_select; + u32 vcalb_adj, reg_val; + int vcalb, vcalk; + int ret; + + ret =3D aw_dev_dsp_read(aw_dev, AW88395_DSP_REG_VCALB, &vcalb_adj, AW_DSP= _16_DATA); + if (ret) { + dev_err(aw_dev->dev, "read vcalb_adj failed"); + return ret; + } + + ret =3D aw88395_get_icalk(aw_dev, &icalk_val); + if (ret) + return ret; + icalk =3D AW88395_CABL_BASE_VALUE + AW88395_ICABLK_FACTOR * icalk_val; + + ret =3D regmap_read(aw_dev->regmap, AW88395_I2SCFG3_REG, &vsense_select); + if (ret) { + dev_err(aw_dev->dev, "read vsense_reg_val failed"); + return ret; + } + vsense_select =3D vsense_select & (~AW88395_VDSEL_MASK); + + dev_dbg(aw_dev->dev, "vsense_select =3D %d", vsense_select); + + switch (vsense_select) { + case AW88395_DEV_VDSEL_VSENSE: + ret =3D aw88395_get_vcalk(aw_dev, &vcalk_val); + if (ret) + return ret; + vcalk =3D AW88395_CABL_BASE_VALUE + AW88395_VCABLK_FACTOR * vcalk_val; + vcalb =3D AW88395_VCAL_FACTOR * AW88395_VSCAL_FACTOR / + AW88395_ISCAL_FACTOR * icalk / vcalk * vcalb_adj; + + dev_dbg(aw_dev->dev, "vcalk_factor=3D%d, vscal_factor=3D%d, icalk=3D%d, = vcalk=3D%d", + AW88395_VCABLK_FACTOR, AW88395_VSCAL_FACTOR, icalk, vcalk); + break; + case AW88395_DEV_VDSEL_DAC: + ret =3D aw88395_get_vcalk_dac(aw_dev, &vcalk_val); + if (ret) + return ret; + vcalk =3D AW88395_CABL_BASE_VALUE + AW88395_VCABLK_FACTOR_DAC * vcalk_va= l; + vcalb =3D AW88395_VCAL_FACTOR * AW88395_VSCAL_FACTOR_DAC / + AW88395_ISCAL_FACTOR * icalk / vcalk * vcalb_adj; + + dev_dbg(aw_dev->dev, "vcalk_dac_factor=3D%d, vscal_dac_factor=3D%d, ical= k=3D%d, vcalk=3D%d", + AW88395_VCABLK_FACTOR_DAC, + AW88395_VSCAL_FACTOR_DAC, icalk, vcalk); + break; + default: + dev_err(aw_dev->dev, "unsupported vsense status"); + return -EINVAL; + } + + if ((vcalk =3D=3D 0) || (AW88395_ISCAL_FACTOR =3D=3D 0)) { + dev_err(aw_dev->dev, "vcalk:%d or desc->iscal_factor:%d unsupported", + vcalk, AW88395_ISCAL_FACTOR); + return -EINVAL; + } + + vcalb =3D vcalb >> AW88395_VCALB_ADJ_FACTOR; + reg_val =3D (u32)vcalb; + + dev_dbg(aw_dev->dev, "vcalb=3D%d, reg_val=3D0x%x, vcalb_adj =3D0x%x", + vcalb, reg_val, vcalb_adj); + + ret =3D aw_dev_dsp_write(aw_dev, AW88395_DSP_REG_VCALB, reg_val, AW_DSP_1= 6_DATA); + if (ret) + dev_err(aw_dev->dev, "write vcalb failed"); + + return ret; +} + +static int aw88395_reg_update(struct aw_device *aw_dev, + unsigned char *data, unsigned int len) +{ + struct aw_volume_desc *vol_desc =3D &aw_dev->volume_desc; + int16_t *reg_data; + int data_len; + u16 read_vol; + u16 reg_val; + u8 reg_addr; + int i, ret; + + reg_data =3D (int16_t *)data; + data_len =3D len >> 1; + + if (data_len & 0x1) { + dev_err(aw_dev->dev, "data len:%d unsupported", data_len); + return -EINVAL; + } + + for (i =3D 0; i < data_len; i +=3D 2) { + reg_addr =3D reg_data[i]; + reg_val =3D reg_data[i + 1]; + + if (reg_addr =3D=3D AW88395_SYSCTRL_REG) { + if (reg_val & (~AW88395_DSPBY_MASK)) + aw_dev->dsp_cfg =3D AW_DEV_DSP_BYPASS; + else + aw_dev->dsp_cfg =3D AW_DEV_DSP_WORK; + + reg_val &=3D (AW88395_HMUTE_MASK | AW88395_PWDN_MASK | AW88395_AMPPD_MA= SK | + AW88395_DSPBY_MASK); + reg_val |=3D (AW88395_HMUTE_DISABLE_VALUE | AW88395_PWDN_POWER_DOWN_VAL= UE | + AW88395_AMPPD_POWER_DOWN_VALUE | AW88395_DSPBY_BYPASS_VALUE); + } + + if (reg_addr =3D=3D AW88395_I2SCFG1_REG) { + reg_val &=3D AW88395_I2STXEN_MASK; + reg_val |=3D AW88395_I2STXEN_DISABLE_VALUE; + } + + if (reg_addr =3D=3D AW88395_SYSCTRL2_REG) { + read_vol =3D (reg_val & (~AW88395_VOL_MASK)) >> AW88395_VOL_START_BIT; + aw_dev->volume_desc.init_volume =3D reg_val_to_db(read_vol); + } + + if (reg_addr =3D=3D AW88395_HAGCCFG7_REG) + reg_val &=3D AW88395_AGC_DSP_CTL_MASK; + + ret =3D regmap_write(aw_dev->regmap, reg_addr, reg_val); + if (ret) + break; + + } + + if (aw_dev->prof_cur !=3D aw_dev->prof_index) { + /* clear control volume when PA change profile */ + vol_desc->ctl_volume =3D 0; + } else { + /* keep control volume when PA start with sync mode */ + aw88395_set_volume(aw_dev, vol_desc->ctl_volume); + } + + return ret; +} + +static int aw88395_fw_update(struct aw_device *aw_dev, bool up_dsp_fw_en, = bool force_up_en) +{ + struct aw_prof_desc *prof_index_desc; + struct aw_sec_data_desc *sec_desc; + char *prof_name; + int ret; + + if ((aw_dev->prof_cur =3D=3D aw_dev->prof_index) && + (force_up_en =3D=3D AW_FORCE_UPDATE_OFF)) { + dev_info(aw_dev->dev, "scene no change, not update"); + return 0; + } + + if (aw_dev->fw_status =3D=3D AW_DEV_FW_FAILED) { + dev_err(aw_dev->dev, "fw status[%d] error", aw_dev->fw_status); + return -EPERM; + } + + ret =3D aw_dev_get_prof_name(aw_dev, aw_dev->prof_index, &prof_name); + if (ret) + return ret; + + dev_dbg(aw_dev->dev, "start update %s", prof_name); + + ret =3D aw_dev_get_prof_data(aw_dev, aw_dev->prof_index, &prof_index_desc= ); + if (ret) + return ret; + + /* update reg */ + sec_desc =3D prof_index_desc->sec_desc; + ret =3D aw88395_reg_update(aw_dev, sec_desc[AW_DATA_TYPE_REG].data, + sec_desc[AW_DATA_TYPE_REG].len); + if (ret) { + dev_err(aw_dev->dev, "update reg failed"); + return ret; + } + + regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, ~AW88395_PWDN_MAS= K, + AW88395_PWDN_WORKING_VALUE); + + regmap_update_bits(aw_dev->regmap, AW88395_DBGCTRL_REG, ~AW88395_MEM_CLKS= EL_MASK, + AW88395_MEM_CLKSEL_OSC_CLK_VALUE); + + if (up_dsp_fw_en) { + ret =3D aw88395_check_sram(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "check sram failed"); + goto error; + } + + /* update dsp firmware */ + dev_dbg(aw_dev->dev, "fw_ver: [%x]", prof_index_desc->fw_ver); + ret =3D aw_dev_dsp_update_fw(aw_dev, sec_desc[AW_DATA_TYPE_DSP_FW].data, + sec_desc[AW_DATA_TYPE_DSP_FW].len, + sec_desc[AW_DATA_TYPE_DSP_FW].addr); + if (ret) { + dev_err(aw_dev->dev, "update dsp fw failed"); + goto error; + } + } + + /* update dsp config */ + ret =3D aw_dev_dsp_update_cfg(aw_dev, sec_desc[AW_DATA_TYPE_DSP_CFG].data, + sec_desc[AW_DATA_TYPE_DSP_CFG].len, + sec_desc[AW_DATA_TYPE_DSP_CFG].addr); + if (ret) { + dev_err(aw_dev->dev, "update dsp cfg failed"); + goto error; + } + + aw_dev_dsp_read(aw_dev, AW88395_FIRMWARE_VERSION_ADDR, + &aw_dev->fw_ver, AW_DSP_16_DATA); + aw888395_cali_get_ra(aw_dev); + + regmap_update_bits(aw_dev->regmap, AW88395_DBGCTRL_REG, ~AW88395_MEM_CLKS= EL_MASK, + AW88395_MEM_CLKSEL_DAP_HCLK_VALUE); + regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, ~AW88395_PWDN_MAS= K, + AW88395_PWDN_POWER_DOWN_VALUE); + + aw_dev->prof_cur =3D aw_dev->prof_index; + + return 0; + +error: + regmap_update_bits(aw_dev->regmap, AW88395_DBGCTRL_REG, ~AW88395_MEM_CLKS= EL_MASK, + AW88395_MEM_CLKSEL_DAP_HCLK_VALUE); + regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, ~AW88395_PWDN_MAS= K, + AW88395_PWDN_POWER_DOWN_VALUE); + return ret; +} + +static int aw88395_dev_start(struct aw_device *aw_dev) +{ + int ret; + + if (aw_dev->status =3D=3D AW_DEV_PW_ON) { + dev_info(aw_dev->dev, "already power on"); + return 0; + } + + /* power on */ + regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, + ~AW88395_PWDN_MASK, AW88395_PWDN_WORKING_VALUE); + usleep_range(AW_2000_US, AW_2000_US + 10); + + ret =3D aw88395_check_syspll(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "pll check failed cannot start"); + goto pll_check_fail; + } + + /* amppd on */ + regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, + ~AW88395_AMPPD_MASK, AW88395_AMPPD_WORKING_VALUE); + usleep_range(AW_1000_US, AW_1000_US + 50); + + /* check i2s status */ + ret =3D aw88395_check_sysst(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "sysst check failed"); + goto sysst_check_fail; + } + + if (aw_dev->dsp_cfg =3D=3D AW_DEV_DSP_WORK) { + ret =3D aw88395_dsp_crc_check(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "dsp crc check failed"); + goto crc_check_fail; + } + /* dsp bypass */ + regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, + ~AW88395_DSPBY_MASK, AW88395_DSPBY_BYPASS_VALUE); + aw88395_set_vcalb(aw_dev); + aw88395_update_cali_re(&aw_dev->cali_desc); + ret =3D aw88395_dsp_check(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "dsp status check failed"); + goto dsp_check_fail; + } + } + + /* enable tx feedback */ + regmap_update_bits(aw_dev->regmap, AW88395_I2SCFG1_REG, + ~AW88395_I2STXEN_MASK, AW88395_I2STXEN_ENABLE_VALUE); + + /* close mute */ + aw88395_dev_mute(aw_dev, false); + /* clear inturrupt */ + aw_dev_clear_int_status(aw_dev); + aw_dev->status =3D AW_DEV_PW_ON; + + return 0; + +dsp_check_fail: +crc_check_fail: + regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, + ~AW88395_DSPBY_MASK, AW88395_DSPBY_BYPASS_VALUE); +sysst_check_fail: + aw_dev_clear_int_status(aw_dev); + regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, + ~AW88395_AMPPD_MASK, AW88395_AMPPD_POWER_DOWN_VALUE); +pll_check_fail: + regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, + ~AW88395_PWDN_MASK, AW88395_PWDN_POWER_DOWN_VALUE); + aw_dev->status =3D AW_DEV_PW_OFF; + + return ret; +} + +static int aw88395_dev_stop(struct aw_device *aw_dev) +{ + struct aw_sec_data_desc *dsp_cfg =3D + &aw_dev->prof_info.prof_desc[aw_dev->prof_cur].sec_desc[AW_DATA_TYPE_DSP= _CFG]; + struct aw_sec_data_desc *dsp_fw =3D + &aw_dev->prof_info.prof_desc[aw_dev->prof_cur].sec_desc[AW_DATA_TYPE_DSP= _FW]; + int int_st =3D 0; + int ret; + + if (aw_dev->status =3D=3D AW_DEV_PW_OFF) { + dev_info(aw_dev->dev, "already power off"); + return 0; + } + + aw_dev->status =3D AW_DEV_PW_OFF; + + /* set mute */ + aw88395_dev_mute(aw_dev, true); + usleep_range(AW_4000_US, AW_4000_US + 100); + + /* close tx feedback */ + regmap_update_bits(aw_dev->regmap, AW88395_I2SCFG1_REG, + ~AW88395_I2STXEN_MASK, AW88395_I2STXEN_ENABLE_VALUE); + usleep_range(AW_1000_US, AW_1000_US + 100); + + /* check sysint state */ + int_st =3D aw88395_check_sysint(aw_dev); + + /* close dsp */ + regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, + ~AW88395_DSPBY_MASK, AW88395_DSPBY_BYPASS_VALUE); + + /* enable amppd */ + regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, + ~AW88395_AMPPD_MASK, AW88395_AMPPD_POWER_DOWN_VALUE); + + if (int_st < 0) { + /* system status anomaly */ + regmap_update_bits(aw_dev->regmap, AW88395_DBGCTRL_REG, + ~AW88395_MEM_CLKSEL_MASK, + AW88395_MEM_CLKSEL_OSC_CLK_VALUE); + ret =3D aw_dev_dsp_update_fw(aw_dev, dsp_fw->data, dsp_fw->len, dsp_fw->= addr); + if (ret) + dev_err(aw_dev->dev, "update dsp fw failed"); + ret =3D aw_dev_dsp_update_cfg(aw_dev, dsp_cfg->data, dsp_cfg->len, dsp_c= fg->addr); + if (ret) + dev_err(aw_dev->dev, "update dsp cfg failed"); + regmap_update_bits(aw_dev->regmap, AW88395_DBGCTRL_REG, + ~AW88395_MEM_CLKSEL_MASK, + AW88395_MEM_CLKSEL_DAP_HCLK_VALUE); + } + + /* set power down */ + regmap_update_bits(aw_dev->regmap, AW88395_SYSCTRL_REG, + ~AW88395_PWDN_MASK, AW88395_PWDN_POWER_DOWN_VALUE); + + return 0; +} + +static void aw88395_start_pa(struct aw88395 *aw88395) +{ + int ret, i; + + for (i =3D 0; i < AW88395_START_RETRIES; i++) { + ret =3D aw88395_dev_start(aw88395->aw_pa); + if (ret) { + dev_err(aw88395->aw_pa->dev, "aw88395 device start failed. retry =3D %d= ", i); + ret =3D aw88395_fw_update(aw88395->aw_pa, AW_DSP_FW_UPDATE_ON, true); + if (ret < 0) { + dev_err(aw88395->aw_pa->dev, "fw update failed"); + continue; + } + } else { + dev_info(aw88395->aw_pa->dev, "start success\n"); + break; + } + } +} + +static void aw88395_startup_work(struct work_struct *work) +{ + struct aw88395 *aw88395 =3D + container_of(work, struct aw88395, start_work.work); + + mutex_lock(&aw88395->lock); + aw88395_start_pa(aw88395); + mutex_unlock(&aw88395->lock); +} + +static void aw88395_start(struct aw88395 *aw88395, bool sync_start) +{ + int ret; + + if (aw88395->aw_pa->fw_status !=3D AW_DEV_FW_OK) + return; + + if (aw88395->aw_pa->status =3D=3D AW_DEV_PW_ON) + return; + + ret =3D aw88395_fw_update(aw88395->aw_pa, AW_DSP_FW_UPDATE_OFF, + aw88395->aw_pa->phase_sync); + if (ret < 0) { + dev_err(aw88395->aw_pa->dev, "fw update failed."); + return; + } + + if (sync_start =3D=3D AW_SYNC_START) + aw88395_start_pa(aw88395); + else + queue_delayed_work(system_wq, + &aw88395->start_work, + AW88395_START_WORK_DELAY_MS); +} + +static struct snd_soc_dai_driver aw88395_dai[] =3D { + { + .name =3D "aw88395-aif", + .id =3D 1, + .playback =3D { + .stream_name =3D "Speaker_Playback", + .channels_min =3D 1, + .channels_max =3D 2, + .rates =3D AW88395_RATES, + .formats =3D AW88395_FORMATS, + }, + .capture =3D { + .stream_name =3D "Speaker_Capture", + .channels_min =3D 1, + .channels_max =3D 2, + .rates =3D AW88395_RATES, + .formats =3D AW88395_FORMATS, + }, + }, +}; + +static int aw88395_get_fade_in_time(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component =3D snd_soc_kcontrol_component(kcontr= ol); + struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(component); + struct aw_device *aw_dev =3D aw88395->aw_pa; + + ucontrol->value.integer.value[0] =3D aw_dev->fade_in_time; + + return 0; +} + +static int aw88395_set_fade_in_time(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component =3D snd_soc_kcontrol_component(kcontr= ol); + struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(component); + struct soc_mixer_control *mc =3D + (struct soc_mixer_control *)kcontrol->private_value; + struct aw_device *aw_dev =3D aw88395->aw_pa; + int time; + + time =3D ucontrol->value.integer.value[0]; + + if (time < mc->min || time > mc->max) + return -EINVAL; + + if (time !=3D aw_dev->fade_in_time) { + aw_dev->fade_in_time =3D time; + return 1; + } + + return 0; +} + +static int aw88395_get_fade_out_time(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component =3D snd_soc_kcontrol_component(kcontr= ol); + struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(component); + struct aw_device *aw_dev =3D aw88395->aw_pa; + + ucontrol->value.integer.value[0] =3D aw_dev->fade_out_time; + + return 0; +} + +static int aw88395_set_fade_out_time(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component =3D snd_soc_kcontrol_component(kcontr= ol); + struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(component); + struct soc_mixer_control *mc =3D + (struct soc_mixer_control *)kcontrol->private_value; + struct aw_device *aw_dev =3D aw88395->aw_pa; + int time; + + time =3D ucontrol->value.integer.value[0]; + if (time < mc->min || time > mc->max) + return -EINVAL; + + if (time !=3D aw_dev->fade_out_time) { + aw_dev->fade_out_time =3D time; + return 1; + } + + return 0; +} + +static int aw88395_profile_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct snd_soc_component *codec =3D snd_soc_kcontrol_component(kcontrol); + struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(codec); + char *prof_name; + int count, ret; + + uinfo->type =3D SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count =3D 1; + + count =3D aw88395->aw_pa->prof_info.count; + if (count <=3D 0) { + uinfo->value.enumerated.items =3D 0; + return 0; + } + + uinfo->value.enumerated.items =3D count; + + if (uinfo->value.enumerated.item >=3D count) + uinfo->value.enumerated.item =3D count - 1; + + count =3D uinfo->value.enumerated.item; + + ret =3D aw_dev_get_prof_name(aw88395->aw_pa, count, &prof_name); + if (ret) { + strscpy(uinfo->value.enumerated.name, "null"); + return 0; + } + + strscpy(uinfo->value.enumerated.name, prof_name); + + return 0; +} + +static int aw88395_profile_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *codec =3D snd_soc_kcontrol_component(kcontrol); + struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(codec); + + ucontrol->value.integer.value[0] =3D aw88395->aw_pa->prof_index; + + return 0; +} + +static int aw88395_profile_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *codec =3D snd_soc_kcontrol_component(kcontrol); + struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(codec); + int ret; + + /* pa stop or stopping just set profile */ + mutex_lock(&aw88395->lock); + ret =3D aw_dev_set_profile_index(aw88395->aw_pa, ucontrol->value.integer.= value[0]); + if (ret < 0) { + dev_dbg(codec->dev, "profile index does not change"); + mutex_unlock(&aw88395->lock); + return 0; + } + + if (aw88395->aw_pa->status) { + aw88395_dev_stop(aw88395->aw_pa); + aw88395_start(aw88395, AW_SYNC_START); + } + + mutex_unlock(&aw88395->lock); + + return 1; +} + +static int aw88395_volume_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *codec =3D snd_soc_kcontrol_component(kcontrol); + struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(codec); + struct aw_volume_desc *vol_desc =3D &aw88395->aw_pa->volume_desc; + + ucontrol->value.integer.value[0] =3D vol_desc->ctl_volume; + + return 0; +} + +static int aw88395_volume_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *codec =3D snd_soc_kcontrol_component(kcontrol); + struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(codec); + struct aw_volume_desc *vol_desc =3D &aw88395->aw_pa->volume_desc; + struct soc_mixer_control *mc =3D + (struct soc_mixer_control *)kcontrol->private_value; + int value; + + value =3D ucontrol->value.integer.value[0]; + if (value < mc->min || value > mc->max) + return -EINVAL; + + if (vol_desc->ctl_volume !=3D value) { + vol_desc->ctl_volume =3D value; + aw88395_set_volume(aw88395->aw_pa, vol_desc->ctl_volume); + + return 1; + } + + return 0; +} + +static int aw88395_get_fade_step(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *codec =3D snd_soc_kcontrol_component(kcontrol); + struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(codec); + + ucontrol->value.integer.value[0] =3D aw88395->aw_pa->fade_step; + + return 0; +} + +static int aw88395_set_fade_step(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *codec =3D snd_soc_kcontrol_component(kcontrol); + struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(codec); + struct soc_mixer_control *mc =3D + (struct soc_mixer_control *)kcontrol->private_value; + int value; + + value =3D ucontrol->value.integer.value[0]; + if (value < mc->min || value > mc->max) + return -EINVAL; + + if (aw88395->aw_pa->fade_step !=3D value) { + aw88395->aw_pa->fade_step =3D value; + return 1; + } + + return 0; +} + +static int aw88395_re_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *codec =3D snd_soc_kcontrol_component(kcontrol); + struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(codec); + struct aw_device *aw_dev =3D aw88395->aw_pa; + + ucontrol->value.integer.value[0] =3D aw_dev->cali_desc.cali_re; + + return 0; +} + +static int aw88395_re_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *codec =3D snd_soc_kcontrol_component(kcontrol); + struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(codec); + struct soc_mixer_control *mc =3D + (struct soc_mixer_control *)kcontrol->private_value; + struct aw_device *aw_dev =3D aw88395->aw_pa; + int value; + + value =3D ucontrol->value.integer.value[0]; + if (value < mc->min || value > mc->max) + return -EINVAL; + + if (aw_dev->cali_desc.cali_re !=3D value) { + aw_dev->cali_desc.cali_re =3D value; + return 1; + } + + return 0; +} + +static const struct snd_kcontrol_new aw88395_controls[] =3D { + SOC_SINGLE_EXT("PCM Playback Volume", AW88395_SYSCTRL2_REG, + 6, AW88395_MUTE_VOL, 0, aw88395_volume_get, + aw88395_volume_set), + SOC_SINGLE_EXT("Fade Step", 0, 0, AW88395_MUTE_VOL, 0, + aw88395_get_fade_step, aw88395_set_fade_step), + SOC_SINGLE_EXT("Volume Ramp Up Step", 0, 0, FADE_TIME_MAX, FADE_TIME_MIN, + aw88395_get_fade_in_time, aw88395_set_fade_in_time), + SOC_SINGLE_EXT("Volume Ramp Down Step", 0, 0, FADE_TIME_MAX, FADE_TIME_MI= N, + aw88395_get_fade_out_time, aw88395_set_fade_out_time), + SOC_SINGLE_EXT("Calib", 0, 0, AW88395_CALI_RE_MAX, 0, + aw88395_re_get, aw88395_re_set), + AW_PROFILE_EXT("Profile Set", aw88395_profile_info, + aw88395_profile_get, aw88395_profile_set), +}; + +static int aw88395_playback_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_component *component =3D snd_soc_dapm_to_component(w->dapm= ); + struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(component); + + mutex_lock(&aw88395->lock); + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + aw88395_start(aw88395, AW_ASYNC_START); + break; + case SND_SOC_DAPM_POST_PMD: + aw88395_dev_stop(aw88395->aw_pa); + break; + default: + break; + } + mutex_unlock(&aw88395->lock); + + return 0; +} + +static const struct snd_soc_dapm_widget aw88395_dapm_widgets[] =3D { + /* playback */ + SND_SOC_DAPM_AIF_IN_E("AIF_RX", "Speaker_Playback", 0, SND_SOC_NOPM, 0, 0, + aw88395_playback_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_OUTPUT("DAC Output"), + + /* capture */ + SND_SOC_DAPM_AIF_OUT("AIF_TX", "Speaker_Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_INPUT("ADC Input"), +}; + +static const struct snd_soc_dapm_route aw88395_audio_map[] =3D { + {"DAC Output", NULL, "AIF_RX"}, + {"AIF_TX", NULL, "ADC Input"}, +}; + +static int aw88395_codec_probe(struct snd_soc_component *component) +{ + struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(component); + int ret; + + INIT_DELAYED_WORK(&aw88395->start_work, aw88395_startup_work); + + ret =3D aw_dev_request_firmware_file(aw88395->aw_pa, AW88395_ACF_FILE); + if (ret) { + dev_err(aw88395->aw_pa->dev, "%s failed\n", __func__); + return ret; + } + + ret =3D aw88395_fw_update(aw88395->aw_pa, AW_FORCE_UPDATE_ON, AW_DSP_FW_U= PDATE_ON); + if (ret) + dev_err(aw88395->aw_pa->dev, "fw update failed ret =3D %d\n", ret); + + return ret; +} + +static void aw88395_codec_remove(struct snd_soc_component *aw_codec) +{ + struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(aw_codec); + + cancel_delayed_work_sync(&aw88395->start_work); +} + +static const struct snd_soc_component_driver soc_codec_dev_aw88395 =3D { + .probe =3D aw88395_codec_probe, + .remove =3D aw88395_codec_remove, + .dapm_widgets =3D aw88395_dapm_widgets, + .num_dapm_widgets =3D ARRAY_SIZE(aw88395_dapm_widgets), + .dapm_routes =3D aw88395_audio_map, + .num_dapm_routes =3D ARRAY_SIZE(aw88395_audio_map), + .controls =3D aw88395_controls, + .num_controls =3D ARRAY_SIZE(aw88395_controls), +}; + +static int aw88395_i2c_probe(struct i2c_client *i2c) +{ + struct aw88395 *aw88395; + int ret; + + if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) + return dev_err_probe(&i2c->dev, -ENXIO, "check_functionality failed"); + + aw88395 =3D devm_kzalloc(&i2c->dev, sizeof(*aw88395), GFP_KERNEL); + if (!aw88395) + return -ENOMEM; + + mutex_init(&aw88395->lock); + i2c_set_clientdata(i2c, aw88395); + + aw88395->aw_pa =3D devm_kzalloc(&i2c->dev, sizeof(*aw88395->aw_pa), GFP_K= ERNEL); + if (!aw88395->aw_pa) + return -ENOMEM; + + aw88395->aw_pa->reset_gpio =3D devm_gpiod_get_optional(&i2c->dev, "reset"= , GPIOD_OUT_LOW); + if (IS_ERR(aw88395->aw_pa->reset_gpio)) + dev_info(&i2c->dev, "reset gpio not defined\n"); + else + aw_hw_reset(aw88395->aw_pa); + + aw88395->regmap =3D devm_regmap_init_i2c(i2c, &aw88395_remap_config); + if (IS_ERR(aw88395->regmap)) + return dev_err_probe(&i2c->dev, PTR_ERR(aw88395->regmap), + "failed to init regmap\n"); + + /* aw pa init */ + ret =3D aw_dev_init(aw88395->aw_pa, i2c, aw88395->regmap); + if (ret) + return ret; + + return devm_snd_soc_register_component(&i2c->dev, &soc_codec_dev_aw88395, + aw88395_dai, ARRAY_SIZE(aw88395_dai)); +} + +static const struct i2c_device_id aw88395_i2c_id[] =3D { + { AW88395_I2C_NAME }, + { } +}; +MODULE_DEVICE_TABLE(i2c, aw88395_i2c_id); + +static struct i2c_driver aw88395_i2c_driver =3D { + .driver =3D { + .name =3D AW88395_I2C_NAME, + }, + .probe =3D aw88395_i2c_probe, + .id_table =3D aw88395_i2c_id, +}; +module_i2c_driver(aw88395_i2c_driver); + +MODULE_DESCRIPTION("ASoC AW88395 Smart PA Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/aw88395/aw88395_reg.h b/sound/soc/codecs/aw88= 395.h similarity index 91% rename from sound/soc/codecs/aw88395/aw88395_reg.h rename to sound/soc/codecs/aw88395.h index e64f24e97150..436d314e8df7 100644 --- a/sound/soc/codecs/aw88395/aw88395_reg.h +++ b/sound/soc/codecs/aw88395.h @@ -1,14 +1,14 @@ // SPDX-License-Identifier: GPL-2.0-only // -// aw88395_reg.h -- AW88395 chip register file +// aw88395.h -- ALSA SoC AW88395 codec support // // Copyright (c) 2022-2023 AWINIC Technology CO., LTD // -// Author: Bruce zhao +// Author: Weidong Wang // =20 -#ifndef __AW88395_REG_H__ -#define __AW88395_REG_H__ +#ifndef __AW88395_H__ +#define __AW88395_H___ =20 #define AW88395_ID_REG (0x00) #define AW88395_SYSST_REG (0x01) @@ -94,14 +94,8 @@ #define AW88395_EFRL_REG (0x7B) #define AW88395_TM_REG (0x7C) =20 -enum aw88395_id { - AW88395_CHIP_ID =3D 0x2049, -}; - #define AW88395_REG_MAX (0x7D) =20 -#define AW88395_VOLUME_STEP_DB (6 * 8) - #define AW88395_UVLS_START_BIT (14) #define AW88395_UVLS_NORMAL (0) #define AW88395_UVLS_NORMAL_VALUE \ @@ -216,15 +210,6 @@ enum aw88395_id { #define AW88395_HMUTE_ENABLE_VALUE \ (AW88395_HMUTE_ENABLE << AW88395_HMUTE_START_BIT) =20 -#define AW88395_RCV_MODE_START_BIT (7) -#define AW88395_RCV_MODE_BITS_LEN (1) -#define AW88395_RCV_MODE_MASK \ - (~(((1<> (shift)) +#define AW88395_SHOW_RE_TO_DSP_RE(re, shift) (((re) << shift) / (1000)) +#define AW88395_DEV_SYSST_CHECK_MAX (10) + +#define AW88395_FIRMWARE_VERSION (0x0002) +#define AW88395_I2C_NAME "aw88395" +#define AW88395_ACF_FILE "aw88395_acf.bin" + +#define AW88395_RATES (SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_96000) + +#define AW88395_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +enum { + AW88395_DEV_VDSEL_DAC =3D 0, + AW88395_DEV_VDSEL_VSENSE =3D 1, +}; =20 #endif diff --git a/sound/soc/codecs/aw88395/aw88395.c b/sound/soc/codecs/aw88395/= aw88395.c deleted file mode 100644 index fb563b4c6971..000000000000 --- a/sound/soc/codecs/aw88395/aw88395.c +++ /dev/null @@ -1,576 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// -// aw88395.c -- ALSA SoC AW88395 codec support -// -// Copyright (c) 2022-2023 AWINIC Technology CO., LTD -// -// Author: Bruce zhao -// Author: Weidong Wang -// - -#include -#include -#include -#include -#include -#include "aw88395.h" -#include "aw88395_device.h" -#include "aw88395_lib.h" -#include "aw88395_reg.h" - -static const struct regmap_config aw88395_remap_config =3D { - .val_bits =3D 16, - .reg_bits =3D 8, - .max_register =3D AW88395_REG_MAX - 1, - .reg_format_endian =3D REGMAP_ENDIAN_LITTLE, - .val_format_endian =3D REGMAP_ENDIAN_BIG, -}; - -static void aw88395_start_pa(struct aw88395 *aw88395) -{ - int ret, i; - - for (i =3D 0; i < AW88395_START_RETRIES; i++) { - ret =3D aw88395_dev_start(aw88395->aw_pa); - if (ret) { - dev_err(aw88395->aw_pa->dev, "aw88395 device start failed. retry =3D %d= ", i); - ret =3D aw88395_dev_fw_update(aw88395->aw_pa, AW88395_DSP_FW_UPDATE_ON,= true); - if (ret < 0) { - dev_err(aw88395->aw_pa->dev, "fw update failed"); - continue; - } - } else { - dev_info(aw88395->aw_pa->dev, "start success\n"); - break; - } - } -} - -static void aw88395_startup_work(struct work_struct *work) -{ - struct aw88395 *aw88395 =3D - container_of(work, struct aw88395, start_work.work); - - mutex_lock(&aw88395->lock); - aw88395_start_pa(aw88395); - mutex_unlock(&aw88395->lock); -} - -static void aw88395_start(struct aw88395 *aw88395, bool sync_start) -{ - int ret; - - if (aw88395->aw_pa->fw_status !=3D AW88395_DEV_FW_OK) - return; - - if (aw88395->aw_pa->status =3D=3D AW88395_DEV_PW_ON) - return; - - ret =3D aw88395_dev_fw_update(aw88395->aw_pa, AW88395_DSP_FW_UPDATE_OFF, = true); - if (ret < 0) { - dev_err(aw88395->aw_pa->dev, "fw update failed."); - return; - } - - if (sync_start =3D=3D AW88395_SYNC_START) - aw88395_start_pa(aw88395); - else - queue_delayed_work(system_wq, - &aw88395->start_work, - AW88395_START_WORK_DELAY_MS); -} - -static struct snd_soc_dai_driver aw88395_dai[] =3D { - { - .name =3D "aw88395-aif", - .id =3D 1, - .playback =3D { - .stream_name =3D "Speaker_Playback", - .channels_min =3D 1, - .channels_max =3D 2, - .rates =3D AW88395_RATES, - .formats =3D AW88395_FORMATS, - }, - .capture =3D { - .stream_name =3D "Speaker_Capture", - .channels_min =3D 1, - .channels_max =3D 2, - .rates =3D AW88395_RATES, - .formats =3D AW88395_FORMATS, - }, - }, -}; - -static int aw88395_get_fade_in_time(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component =3D snd_soc_kcontrol_component(kcontr= ol); - struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(component); - struct aw_device *aw_dev =3D aw88395->aw_pa; - - ucontrol->value.integer.value[0] =3D aw_dev->fade_in_time; - - return 0; -} - -static int aw88395_set_fade_in_time(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component =3D snd_soc_kcontrol_component(kcontr= ol); - struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(component); - struct soc_mixer_control *mc =3D - (struct soc_mixer_control *)kcontrol->private_value; - struct aw_device *aw_dev =3D aw88395->aw_pa; - int time; - - time =3D ucontrol->value.integer.value[0]; - - if (time < mc->min || time > mc->max) - return -EINVAL; - - if (time !=3D aw_dev->fade_in_time) { - aw_dev->fade_in_time =3D time; - return 1; - } - - return 0; -} - -static int aw88395_get_fade_out_time(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component =3D snd_soc_kcontrol_component(kcontr= ol); - struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(component); - struct aw_device *aw_dev =3D aw88395->aw_pa; - - ucontrol->value.integer.value[0] =3D aw_dev->fade_out_time; - - return 0; -} - -static int aw88395_set_fade_out_time(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component =3D snd_soc_kcontrol_component(kcontr= ol); - struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(component); - struct soc_mixer_control *mc =3D - (struct soc_mixer_control *)kcontrol->private_value; - struct aw_device *aw_dev =3D aw88395->aw_pa; - int time; - - time =3D ucontrol->value.integer.value[0]; - if (time < mc->min || time > mc->max) - return -EINVAL; - - if (time !=3D aw_dev->fade_out_time) { - aw_dev->fade_out_time =3D time; - return 1; - } - - return 0; -} - -static int aw88395_profile_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct snd_soc_component *codec =3D snd_soc_kcontrol_component(kcontrol); - struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(codec); - char *prof_name; - int count, ret; - - uinfo->type =3D SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count =3D 1; - - count =3D aw88395_dev_get_profile_count(aw88395->aw_pa); - if (count <=3D 0) { - uinfo->value.enumerated.items =3D 0; - return 0; - } - - uinfo->value.enumerated.items =3D count; - - if (uinfo->value.enumerated.item >=3D count) - uinfo->value.enumerated.item =3D count - 1; - - count =3D uinfo->value.enumerated.item; - - ret =3D aw88395_dev_get_prof_name(aw88395->aw_pa, count, &prof_name); - if (ret) { - strscpy(uinfo->value.enumerated.name, "null"); - return 0; - } - - strscpy(uinfo->value.enumerated.name, prof_name); - - return 0; -} - -static int aw88395_profile_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *codec =3D snd_soc_kcontrol_component(kcontrol); - struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(codec); - - ucontrol->value.integer.value[0] =3D aw88395_dev_get_profile_index(aw8839= 5->aw_pa); - - return 0; -} - -static int aw88395_profile_set(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *codec =3D snd_soc_kcontrol_component(kcontrol); - struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(codec); - int ret; - - /* pa stop or stopping just set profile */ - mutex_lock(&aw88395->lock); - ret =3D aw88395_dev_set_profile_index(aw88395->aw_pa, ucontrol->value.int= eger.value[0]); - if (ret < 0) { - dev_dbg(codec->dev, "profile index does not change"); - mutex_unlock(&aw88395->lock); - return 0; - } - - if (aw88395->aw_pa->status) { - aw88395_dev_stop(aw88395->aw_pa); - aw88395_start(aw88395, AW88395_SYNC_START); - } - - mutex_unlock(&aw88395->lock); - - return 1; -} - -static int aw88395_volume_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *codec =3D snd_soc_kcontrol_component(kcontrol); - struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(codec); - struct aw_volume_desc *vol_desc =3D &aw88395->aw_pa->volume_desc; - - ucontrol->value.integer.value[0] =3D vol_desc->ctl_volume; - - return 0; -} - -static int aw88395_volume_set(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *codec =3D snd_soc_kcontrol_component(kcontrol); - struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(codec); - struct aw_volume_desc *vol_desc =3D &aw88395->aw_pa->volume_desc; - struct soc_mixer_control *mc =3D - (struct soc_mixer_control *)kcontrol->private_value; - int value; - - value =3D ucontrol->value.integer.value[0]; - if (value < mc->min || value > mc->max) - return -EINVAL; - - if (vol_desc->ctl_volume !=3D value) { - vol_desc->ctl_volume =3D value; - aw88395_dev_set_volume(aw88395->aw_pa, vol_desc->ctl_volume); - - return 1; - } - - return 0; -} - -static int aw88395_get_fade_step(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *codec =3D snd_soc_kcontrol_component(kcontrol); - struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(codec); - - ucontrol->value.integer.value[0] =3D aw88395->aw_pa->fade_step; - - return 0; -} - -static int aw88395_set_fade_step(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *codec =3D snd_soc_kcontrol_component(kcontrol); - struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(codec); - struct soc_mixer_control *mc =3D - (struct soc_mixer_control *)kcontrol->private_value; - int value; - - value =3D ucontrol->value.integer.value[0]; - if (value < mc->min || value > mc->max) - return -EINVAL; - - if (aw88395->aw_pa->fade_step !=3D value) { - aw88395->aw_pa->fade_step =3D value; - return 1; - } - - return 0; -} - -static int aw88395_re_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *codec =3D snd_soc_kcontrol_component(kcontrol); - struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(codec); - struct aw_device *aw_dev =3D aw88395->aw_pa; - - ucontrol->value.integer.value[0] =3D aw_dev->cali_desc.cali_re; - - return 0; -} - -static int aw88395_re_set(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *codec =3D snd_soc_kcontrol_component(kcontrol); - struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(codec); - struct soc_mixer_control *mc =3D - (struct soc_mixer_control *)kcontrol->private_value; - struct aw_device *aw_dev =3D aw88395->aw_pa; - int value; - - value =3D ucontrol->value.integer.value[0]; - if (value < mc->min || value > mc->max) - return -EINVAL; - - if (aw_dev->cali_desc.cali_re !=3D value) { - aw_dev->cali_desc.cali_re =3D value; - return 1; - } - - return 0; -} - -static const struct snd_kcontrol_new aw88395_controls[] =3D { - SOC_SINGLE_EXT("PCM Playback Volume", AW88395_SYSCTRL2_REG, - 6, AW88395_MUTE_VOL, 0, aw88395_volume_get, - aw88395_volume_set), - SOC_SINGLE_EXT("Fade Step", 0, 0, AW88395_MUTE_VOL, 0, - aw88395_get_fade_step, aw88395_set_fade_step), - SOC_SINGLE_EXT("Volume Ramp Up Step", 0, 0, FADE_TIME_MAX, FADE_TIME_MIN, - aw88395_get_fade_in_time, aw88395_set_fade_in_time), - SOC_SINGLE_EXT("Volume Ramp Down Step", 0, 0, FADE_TIME_MAX, FADE_TIME_MI= N, - aw88395_get_fade_out_time, aw88395_set_fade_out_time), - SOC_SINGLE_EXT("Calib", 0, 0, AW88395_CALI_RE_MAX, 0, - aw88395_re_get, aw88395_re_set), - AW88395_PROFILE_EXT("Profile Set", aw88395_profile_info, - aw88395_profile_get, aw88395_profile_set), -}; - -static int aw88395_playback_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - struct snd_soc_component *component =3D snd_soc_dapm_to_component(w->dapm= ); - struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(component); - - mutex_lock(&aw88395->lock); - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - aw88395_start(aw88395, AW88395_ASYNC_START); - break; - case SND_SOC_DAPM_POST_PMD: - aw88395_dev_stop(aw88395->aw_pa); - break; - default: - break; - } - mutex_unlock(&aw88395->lock); - - return 0; -} - -static const struct snd_soc_dapm_widget aw88395_dapm_widgets[] =3D { - /* playback */ - SND_SOC_DAPM_AIF_IN_E("AIF_RX", "Speaker_Playback", 0, 0, 0, 0, - aw88395_playback_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_OUTPUT("DAC Output"), - - /* capture */ - SND_SOC_DAPM_AIF_OUT("AIF_TX", "Speaker_Capture", 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_INPUT("ADC Input"), -}; - -static const struct snd_soc_dapm_route aw88395_audio_map[] =3D { - {"DAC Output", NULL, "AIF_RX"}, - {"AIF_TX", NULL, "ADC Input"}, -}; - -static int aw88395_codec_probe(struct snd_soc_component *component) -{ - struct snd_soc_dapm_context *dapm =3D snd_soc_component_get_dapm(componen= t); - struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(component); - int ret; - - INIT_DELAYED_WORK(&aw88395->start_work, aw88395_startup_work); - - /* add widgets */ - ret =3D snd_soc_dapm_new_controls(dapm, aw88395_dapm_widgets, - ARRAY_SIZE(aw88395_dapm_widgets)); - if (ret < 0) - return ret; - - /* add route */ - ret =3D snd_soc_dapm_add_routes(dapm, aw88395_audio_map, - ARRAY_SIZE(aw88395_audio_map)); - if (ret < 0) - return ret; - - ret =3D snd_soc_add_component_controls(component, aw88395_controls, - ARRAY_SIZE(aw88395_controls)); - - return ret; -} - -static void aw88395_codec_remove(struct snd_soc_component *aw_codec) -{ - struct aw88395 *aw88395 =3D snd_soc_component_get_drvdata(aw_codec); - - cancel_delayed_work_sync(&aw88395->start_work); -} - -static const struct snd_soc_component_driver soc_codec_dev_aw88395 =3D { - .probe =3D aw88395_codec_probe, - .remove =3D aw88395_codec_remove, -}; - -static struct aw88395 *aw88395_malloc_init(struct i2c_client *i2c) -{ - struct aw88395 *aw88395 =3D devm_kzalloc(&i2c->dev, - sizeof(struct aw88395), GFP_KERNEL); - if (!aw88395) - return NULL; - - mutex_init(&aw88395->lock); - - return aw88395; -} - -static void aw88395_hw_reset(struct aw88395 *aw88395) -{ - if (aw88395->reset_gpio) { - gpiod_set_value_cansleep(aw88395->reset_gpio, 0); - usleep_range(AW88395_1000_US, AW88395_1000_US + 10); - gpiod_set_value_cansleep(aw88395->reset_gpio, 1); - usleep_range(AW88395_1000_US, AW88395_1000_US + 10); - } else { - dev_err(aw88395->aw_pa->dev, "%s failed", __func__); - } -} - -static int aw88395_request_firmware_file(struct aw88395 *aw88395) -{ - const struct firmware *cont =3D NULL; - int ret; - - aw88395->aw_pa->fw_status =3D AW88395_DEV_FW_FAILED; - - ret =3D request_firmware(&cont, AW88395_ACF_FILE, aw88395->aw_pa->dev); - if ((ret < 0) || (!cont)) { - dev_err(aw88395->aw_pa->dev, "load [%s] failed!", AW88395_ACF_FILE); - return ret; - } - - dev_info(aw88395->aw_pa->dev, "loaded %s - size: %zu\n", - AW88395_ACF_FILE, cont ? cont->size : 0); - - aw88395->aw_cfg =3D devm_kzalloc(aw88395->aw_pa->dev, cont->size + sizeof= (int), GFP_KERNEL); - if (!aw88395->aw_cfg) { - release_firmware(cont); - return -ENOMEM; - } - aw88395->aw_cfg->len =3D (int)cont->size; - memcpy(aw88395->aw_cfg->data, cont->data, cont->size); - release_firmware(cont); - - ret =3D aw88395_dev_load_acf_check(aw88395->aw_pa, aw88395->aw_cfg); - if (ret < 0) { - dev_err(aw88395->aw_pa->dev, "Load [%s] failed ....!", AW88395_ACF_FILE); - return ret; - } - - dev_dbg(aw88395->aw_pa->dev, "%s : bin load success\n", __func__); - - mutex_lock(&aw88395->lock); - /* aw device init */ - ret =3D aw88395_dev_init(aw88395->aw_pa, aw88395->aw_cfg); - if (ret < 0) - dev_err(aw88395->aw_pa->dev, "dev init failed"); - mutex_unlock(&aw88395->lock); - - return ret; -} - -static int aw88395_i2c_probe(struct i2c_client *i2c) -{ - struct aw88395 *aw88395; - int ret; - - if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) { - dev_err(&i2c->dev, "check_functionality failed"); - return -EIO; - } - - aw88395 =3D aw88395_malloc_init(i2c); - if (!aw88395) { - dev_err(&i2c->dev, "malloc aw88395 failed"); - return -ENOMEM; - } - i2c_set_clientdata(i2c, aw88395); - - aw88395->reset_gpio =3D devm_gpiod_get_optional(&i2c->dev, "reset", GPIOD= _OUT_LOW); - if (IS_ERR(aw88395->reset_gpio)) - dev_info(&i2c->dev, "reset gpio not defined\n"); - - /* hardware reset */ - aw88395_hw_reset(aw88395); - - aw88395->regmap =3D devm_regmap_init_i2c(i2c, &aw88395_remap_config); - if (IS_ERR(aw88395->regmap)) { - ret =3D PTR_ERR(aw88395->regmap); - dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret); - return ret; - } - - /* aw pa init */ - ret =3D aw88395_init(&aw88395->aw_pa, i2c, aw88395->regmap); - if (ret < 0) - return ret; - - ret =3D aw88395_request_firmware_file(aw88395); - if (ret < 0) { - dev_err(&i2c->dev, "%s failed\n", __func__); - return ret; - } - - ret =3D devm_snd_soc_register_component(&i2c->dev, - &soc_codec_dev_aw88395, - aw88395_dai, ARRAY_SIZE(aw88395_dai)); - if (ret < 0) { - dev_err(&i2c->dev, "failed to register aw88395: %d", ret); - return ret; - } - - return 0; -} - -static const struct i2c_device_id aw88395_i2c_id[] =3D { - { AW88395_I2C_NAME }, - { } -}; -MODULE_DEVICE_TABLE(i2c, aw88395_i2c_id); - -static struct i2c_driver aw88395_i2c_driver =3D { - .driver =3D { - .name =3D AW88395_I2C_NAME, - }, - .probe =3D aw88395_i2c_probe, - .id_table =3D aw88395_i2c_id, -}; -module_i2c_driver(aw88395_i2c_driver); - -MODULE_DESCRIPTION("ASoC AW88395 Smart PA Driver"); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/aw88395/aw88395.h b/sound/soc/codecs/aw88395/= aw88395.h deleted file mode 100644 index c2a4f0cb8cd5..000000000000 --- a/sound/soc/codecs/aw88395/aw88395.h +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -// -// aw88395.h -- ALSA SoC AW88395 codec support -// -// Copyright (c) 2022-2023 AWINIC Technology CO., LTD -// -// Author: Bruce zhao -// - -#ifndef __AW88395_H__ -#define __AW88395_H__ - -#define AW88395_CHIP_ID_REG (0x00) -#define AW88395_START_RETRIES (5) -#define AW88395_START_WORK_DELAY_MS (0) - -#define AW88395_DSP_16_DATA_MASK (0x0000ffff) - -#define AW88395_I2C_NAME "aw88395" - -#define AW88395_RATES (SNDRV_PCM_RATE_8000_48000 | \ - SNDRV_PCM_RATE_96000) -#define AW88395_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ - SNDRV_PCM_FMTBIT_S24_LE | \ - SNDRV_PCM_FMTBIT_S32_LE) - -#define FADE_TIME_MAX 100000 -#define FADE_TIME_MIN 0 - -#define AW88395_PROFILE_EXT(xname, profile_info, profile_get, profile_set)= \ -{ \ - .iface =3D SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name =3D xname, \ - .info =3D profile_info, \ - .get =3D profile_get, \ - .put =3D profile_set, \ -} - -enum { - AW88395_SYNC_START =3D 0, - AW88395_ASYNC_START, -}; - -enum { - AW88395_STREAM_CLOSE =3D 0, - AW88395_STREAM_OPEN, -}; - -struct aw88395 { - struct aw_device *aw_pa; - struct mutex lock; - struct gpio_desc *reset_gpio; - struct delayed_work start_work; - struct regmap *regmap; - struct aw_container *aw_cfg; -}; - -#endif --=20 2.47.0 From nobody Wed Oct 1 22:31:21 2025 Received: from out198-15.us.a.mail.aliyun.com (out198-15.us.a.mail.aliyun.com [47.90.198.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 59F2038DEC; Fri, 26 Sep 2025 10:21:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=47.90.198.15 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758882065; cv=none; b=NjkEfGbAPVYI9UV5m5YWvBK4cb9d9aNXD0H3sW2W8bAzPT4B8B/Spp9ScGyeEDpdz6Ht0EIePcw/zCYN7Y3ThWR3/3kMOUNAfbGG8goLXCQ8D6Po0eLLI5oD+9SsGxowz7n3myYW/MRKy2WRsysC5Wwnj6oQsidlRBRyNgfIJ+I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758882065; c=relaxed/simple; bh=ycdqKx049ec96ztt5legE1xGnQlokmuCPb4oXnPK5kc=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cKSs3GPbw7dcB1C/W21F91MDPjiLrFWa3yAoaQzP/YmMjCG/Jwy+nCeGWvX4yNmHH50bTA1Yh5BmKOZQdqkUJXBP9vepSPNdajssa6+xk5Z8z/QyyyLlEJhZ9OFP4kTHUlXYAKGXzvoafTHfqZP7KT5qK7hdJTlD8OHGG7Ry+EQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=awinic.com; spf=pass smtp.mailfrom=awinic.com; dkim=pass (2048-bit key) header.d=awinic.com header.i=@awinic.com header.b=DBzefck1; arc=none smtp.client-ip=47.90.198.15 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=awinic.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=awinic.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=awinic.com header.i=@awinic.com header.b="DBzefck1" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=awinic.com; s=default; t=1758882049; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=N3NMHu79bWTQmAi1Ox9IMsWEADEFAdTNFM0K+1AfHXg=; b=DBzefck14B0vxV0FiCBMC6jm5lDgoVD9JXe+eg7wyYNH+FTc8IvqbewdJhyyBPLQfQPz3VYn8xlpSlv1mghw5G48/ffq3UPkbeZx2hJQcsKn0KG6SabSqXockdvAfQ3TVOYfSTBXonLzoUWpDNHu5s8M+CXyhV1ZU5Z9/hoPrkpoGx6O0+eOi5y/iP/rddjpWOn4bT439ekabBrVh5Kt472+hQEWcNGimSirDytmarzPHOyyI7qdd4hn/OP+uf7dQUOjmzAY5m35q4dx1pwXWEoqMkHo0WdIcIWxQ5JnZMnFn9pO1bkog0e1qQUXYG301hmmvCItIzrvu2EdS0DXNw== Received: from ubuntu-VirtualBox..(mailfrom:wangweidong.a@awinic.com fp:SMTPD_---.ensjOzf_1758882046 cluster:ay29) by smtp.aliyun-inc.com; Fri, 26 Sep 2025 18:20:47 +0800 From: wangweidong.a@awinic.com To: lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, wangweidong.a@awinic.com, cy_huang@richtek.com, ivprusov@salutedevices.com, zhoubinbin@loongson.cn, zhangyi@everest-semi.com, jack.yu@realtek.com, shenghao-ding@ti.com, rf@opensource.cirrus.com, git@apitzsch.eu, nuno.sa@analog.com, colin.i.king@gmail.com, thorsten.blum@linux.dev, yesanishhere@gmail.com, ebiggers@google.com, ardb@kernel.org, zhujun2@cmss.chinamobile.com, linux-kernel@vger.kernel.org, linux-sound@vger.kernel.org Subject: [PATCH V1 3/7] ASoC: codecs: Rework the aw87390 driver Date: Fri, 26 Sep 2025 18:20:33 +0800 Message-ID: <20250926102037.27697-4-wangweidong.a@awinic.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20250926102037.27697-1-wangweidong.a@awinic.com> References: <20250926102037.27697-1-wangweidong.a@awinic.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Weidong Wang Modify the interface for calling the aw87380 driver to adapt it for aw-common-device.c and aw-common-firmware.c Signed-off-by: Weidong Wang --- sound/soc/codecs/aw87390.c | 118 ++++++------------------------------- sound/soc/codecs/aw87390.h | 16 ----- 2 files changed, 18 insertions(+), 116 deletions(-) diff --git a/sound/soc/codecs/aw87390.c b/sound/soc/codecs/aw87390.c index ef6f64856988..4ed7045a3844 100644 --- a/sound/soc/codecs/aw87390.c +++ b/sound/soc/codecs/aw87390.c @@ -12,8 +12,14 @@ #include #include #include "aw87390.h" -#include "aw88395/aw88395_data_type.h" -#include "aw88395/aw88395_device.h" +#include "aw-common-device.h" +#include "aw-common-firmware.h" + +struct aw87390 { + struct aw_device *aw_pa; + struct mutex lock; + struct regmap *regmap; +}; =20 static const struct regmap_config aw87390_remap_config =3D { .val_bits =3D 8, @@ -47,38 +53,6 @@ static int aw87390_dev_reg_update(struct aw_device *aw_d= ev, return 0; } =20 -static int aw87390_dev_get_prof_name(struct aw_device *aw_dev, int index, = char **prof_name) -{ - struct aw_prof_info *prof_info =3D &aw_dev->prof_info; - struct aw_prof_desc *prof_desc; - - if ((index >=3D aw_dev->prof_info.count) || (index < 0)) { - dev_err(aw_dev->dev, "index[%d] overflow count[%d]\n", - index, aw_dev->prof_info.count); - return -EINVAL; - } - - prof_desc =3D &aw_dev->prof_info.prof_desc[index]; - - *prof_name =3D prof_info->prof_name_list[prof_desc->id]; - - return 0; -} - -static int aw87390_dev_get_prof_data(struct aw_device *aw_dev, int index, - struct aw_prof_desc **prof_desc) -{ - if ((index >=3D aw_dev->prof_info.count) || (index < 0)) { - dev_err(aw_dev->dev, "%s: index[%d] overflow count[%d]\n", - __func__, index, aw_dev->prof_info.count); - return -EINVAL; - } - - *prof_desc =3D &aw_dev->prof_info.prof_desc[index]; - - return 0; -} - static int aw87390_dev_fw_update(struct aw_device *aw_dev) { struct aw_prof_desc *prof_index_desc; @@ -86,7 +60,7 @@ static int aw87390_dev_fw_update(struct aw_device *aw_dev) char *prof_name; int ret; =20 - ret =3D aw87390_dev_get_prof_name(aw_dev, aw_dev->prof_index, &prof_name); + ret =3D aw_dev_get_prof_name(aw_dev, aw_dev->prof_index, &prof_name); if (ret) { dev_err(aw_dev->dev, "get prof name failed\n"); return -EINVAL; @@ -94,7 +68,7 @@ static int aw87390_dev_fw_update(struct aw_device *aw_dev) =20 dev_dbg(aw_dev->dev, "start update %s", prof_name); =20 - ret =3D aw87390_dev_get_prof_data(aw_dev, aw_dev->prof_index, &prof_index= _desc); + ret =3D aw_dev_get_prof_data(aw_dev, aw_dev->prof_index, &prof_index_desc= ); if (ret) { dev_err(aw_dev->dev, "aw87390_dev_get_prof_data failed\n"); return ret; @@ -102,8 +76,8 @@ static int aw87390_dev_fw_update(struct aw_device *aw_de= v) =20 /* update reg */ sec_desc =3D prof_index_desc->sec_desc; - ret =3D aw87390_dev_reg_update(aw_dev, sec_desc[AW88395_DATA_TYPE_REG].da= ta, - sec_desc[AW88395_DATA_TYPE_REG].len); + ret =3D aw87390_dev_reg_update(aw_dev, sec_desc[AW_DATA_TYPE_REG].data, + sec_desc[AW_DATA_TYPE_REG].len); if (ret) { dev_err(aw_dev->dev, "update reg failed\n"); return ret; @@ -159,19 +133,6 @@ static int aw87390_power_on(struct aw_device *aw_dev) return 0; } =20 -static int aw87390_dev_set_profile_index(struct aw_device *aw_dev, int ind= ex) -{ - if ((index >=3D aw_dev->prof_info.count) || (index < 0)) - return -EINVAL; - - if (aw_dev->prof_index =3D=3D index) - return -EPERM; - - aw_dev->prof_index =3D index; - - return 0; -} - static int aw87390_profile_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -196,7 +157,7 @@ static int aw87390_profile_info(struct snd_kcontrol *kc= ontrol, =20 count =3D uinfo->value.enumerated.item; =20 - ret =3D aw87390_dev_get_prof_name(aw87390->aw_pa, count, &prof_name); + ret =3D aw_dev_get_prof_name(aw87390->aw_pa, count, &prof_name); if (ret) { strscpy(uinfo->value.enumerated.name, "null"); return 0; @@ -226,7 +187,7 @@ static int aw87390_profile_set(struct snd_kcontrol *kco= ntrol, int ret; =20 mutex_lock(&aw87390->lock); - ret =3D aw87390_dev_set_profile_index(aw87390->aw_pa, ucontrol->value.int= eger.value[0]); + ret =3D aw_dev_set_profile_index(aw87390->aw_pa, ucontrol->value.integer.= value[0]); if (ret) { dev_dbg(codec->dev, "profile index does not change\n"); mutex_unlock(&aw87390->lock); @@ -244,53 +205,10 @@ static int aw87390_profile_set(struct snd_kcontrol *k= control, } =20 static const struct snd_kcontrol_new aw87390_controls[] =3D { - AW87390_PROFILE_EXT("AW87390 Profile Set", aw87390_profile_info, + AW_PROFILE_EXT("AW87390 Profile Set", aw87390_profile_info, aw87390_profile_get, aw87390_profile_set), }; =20 -static int aw87390_request_firmware_file(struct aw87390 *aw87390) -{ - const struct firmware *cont =3D NULL; - int ret; - - aw87390->aw_pa->fw_status =3D AW87390_DEV_FW_FAILED; - - ret =3D request_firmware(&cont, AW87390_ACF_FILE, aw87390->aw_pa->dev); - if (ret) - return dev_err_probe(aw87390->aw_pa->dev, ret, - "load [%s] failed!\n", AW87390_ACF_FILE); - - dev_dbg(aw87390->aw_pa->dev, "loaded %s - size: %zu\n", - AW87390_ACF_FILE, cont ? cont->size : 0); - - aw87390->aw_cfg =3D devm_kzalloc(aw87390->aw_pa->dev, - struct_size(aw87390->aw_cfg, data, cont->size), GFP_KERNEL); - if (!aw87390->aw_cfg) { - release_firmware(cont); - return -ENOMEM; - } - - aw87390->aw_cfg->len =3D cont->size; - memcpy(aw87390->aw_cfg->data, cont->data, cont->size); - release_firmware(cont); - - ret =3D aw88395_dev_load_acf_check(aw87390->aw_pa, aw87390->aw_cfg); - if (ret) { - dev_err(aw87390->aw_pa->dev, "load [%s] failed!\n", AW87390_ACF_FILE); - return ret; - } - - mutex_lock(&aw87390->lock); - - ret =3D aw88395_dev_cfg_load(aw87390->aw_pa, aw87390->aw_cfg); - if (ret) - dev_err(aw87390->aw_pa->dev, "aw_dev acf parse failed\n"); - - mutex_unlock(&aw87390->lock); - - return ret; -} - static int aw87390_drv_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -331,10 +249,10 @@ static int aw87390_codec_probe(struct snd_soc_compone= nt *component) struct aw87390 *aw87390 =3D snd_soc_component_get_drvdata(component); int ret; =20 - ret =3D aw87390_request_firmware_file(aw87390); + ret =3D aw_dev_request_firmware_file(aw87390->aw_pa, AW87390_ACF_FILE); if (ret) return dev_err_probe(aw87390->aw_pa->dev, ret, - "aw87390_request_firmware_file failed\n"); + "aw_request_firmware_file failed\n"); =20 return 0; } @@ -392,7 +310,7 @@ static int aw87390_init(struct aw87390 **aw87390, struc= t i2c_client *i2c, struct aw_dev->acf =3D NULL; aw_dev->prof_info.prof_desc =3D NULL; aw_dev->prof_info.count =3D 0; - aw_dev->prof_info.prof_type =3D AW88395_DEV_NONE_TYPE_ID; + aw_dev->prof_info.prof_type =3D AW_DEV_NONE_TYPE_ID; aw_dev->channel =3D AW87390_DEV_DEFAULT_CH; aw_dev->fw_status =3D AW87390_DEV_FW_FAILED; aw_dev->prof_index =3D AW87390_INIT_PROFILE; diff --git a/sound/soc/codecs/aw87390.h b/sound/soc/codecs/aw87390.h index d0d049e65991..6023d4d5a0f9 100644 --- a/sound/soc/codecs/aw87390.h +++ b/sound/soc/codecs/aw87390.h @@ -52,15 +52,6 @@ #define AW87390_I2C_NAME "aw87390" #define AW87390_ACF_FILE "aw87390_acf.bin" =20 -#define AW87390_PROFILE_EXT(xname, profile_info, profile_get, profile_set)= \ -{ \ - .iface =3D SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name =3D xname, \ - .info =3D profile_info, \ - .get =3D profile_get, \ - .put =3D profile_set, \ -} - enum aw87390_id { AW87390_CHIP_ID =3D 0x76, }; @@ -75,11 +66,4 @@ enum { AW87390_DEV_PW_ON, }; =20 -struct aw87390 { - struct aw_device *aw_pa; - struct mutex lock; - struct regmap *regmap; - struct aw_container *aw_cfg; -}; - #endif --=20 2.47.0 From nobody Wed Oct 1 22:31:21 2025 Received: from out28-197.mail.aliyun.com (out28-197.mail.aliyun.com [115.124.28.197]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4D68872639; Fri, 26 Sep 2025 10:26:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.28.197 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758882374; cv=none; b=AHEHfghEmUZrrU54dVVSk/2Ctr4L/RFQF676CCplTyAOBwdzpU8h5e0VPVGhTRymZNTDzCN0xyCjwC//KDpp9xab31SBzw8V+f1jZebnPnVr1T6igzlT+2FVfLtqftOZSe5SQnPB82leviT1gM9qRCwNjB3XA+fERE6Oq0hErfE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758882374; c=relaxed/simple; bh=Kdw9N2mC9FBIXB1eAlIV54BBXiut0NmHaIda1DY7u8k=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jGz/IkVIVWsru1TsanvcXc+SoABQBtccpi15QcOsFy7VmwDrlqLbMaEMqDBNUJczOqze0HZWcy82yNOIWfrnyfw2tTgMqmjXYGKJUwGBxfWzOAmmcx7W+rvHjJ31GO8q9lN5c0AmkpVg54oABfatezR6CmqfwwDAA862zgIyGXE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=awinic.com; spf=pass smtp.mailfrom=awinic.com; dkim=pass (2048-bit key) header.d=awinic.com header.i=@awinic.com header.b=FadIhz/v; arc=none smtp.client-ip=115.124.28.197 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=awinic.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=awinic.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=awinic.com header.i=@awinic.com header.b="FadIhz/v" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=awinic.com; s=default; t=1758882369; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=2buohluJi10528nwyNdVqz59xQRiIfWb/fClHYIZeQE=; b=FadIhz/vm4gX7FU5MFpHYQPW1gqju56lWBzK8ge5kJxsmfUHT7jU1k+g1hBjTv0MRGPboCvw/gtEa/kTsjUmu2B0fw8Uli6ASC+of1chPye8pc7bUJ6amu2SHQkThPtQM0Ji9JtD9WEo1IMro4B3PBLccn5t20C5wKHtOXYJEZF1fSDC/MKOWj9qmrEKmhrzoyE+yuk4C6iJ9XSHs95X6dc1gKZa4fHhh2RJBhWTZoR+sX3TBVEC6AP+iE8rAb/eMdJPBz8hBBYT35Q9H0fxqOxr0F5ShRhSoH1aHVlFF/U3mcUb8elt1mIp12khpiCT87iWToJ91z2SlZX7Gl2OgA== Received: from ubuntu-VirtualBox..(mailfrom:wangweidong.a@awinic.com fp:SMTPD_---.ensjP.e_1758882048 cluster:ay29) by smtp.aliyun-inc.com; Fri, 26 Sep 2025 18:20:49 +0800 From: wangweidong.a@awinic.com To: lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, wangweidong.a@awinic.com, cy_huang@richtek.com, ivprusov@salutedevices.com, zhoubinbin@loongson.cn, zhangyi@everest-semi.com, jack.yu@realtek.com, shenghao-ding@ti.com, rf@opensource.cirrus.com, git@apitzsch.eu, nuno.sa@analog.com, colin.i.king@gmail.com, thorsten.blum@linux.dev, yesanishhere@gmail.com, ebiggers@google.com, ardb@kernel.org, zhujun2@cmss.chinamobile.com, linux-kernel@vger.kernel.org, linux-sound@vger.kernel.org Subject: [PATCH V1 4/7] ASoC: codecs: Rework the aw88081 driver Date: Fri, 26 Sep 2025 18:20:34 +0800 Message-ID: <20250926102037.27697-5-wangweidong.a@awinic.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20250926102037.27697-1-wangweidong.a@awinic.com> References: <20250926102037.27697-1-wangweidong.a@awinic.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Weidong Wang Modify the interface for calling the aw88081 driver to adapt it for aw-common-device.c and aw-common-firmware.c Signed-off-by: Weidong Wang --- sound/soc/codecs/aw88081.c | 357 +++++++++---------------------------- sound/soc/codecs/aw88081.h | 33 ---- 2 files changed, 83 insertions(+), 307 deletions(-) diff --git a/sound/soc/codecs/aw88081.c b/sound/soc/codecs/aw88081.c index d61a7b8c5470..edba6db117d5 100644 --- a/sound/soc/codecs/aw88081.c +++ b/sound/soc/codecs/aw88081.c @@ -12,7 +12,8 @@ #include #include #include "aw88081.h" -#include "aw88395/aw88395_device.h" +#include "aw-common-device.h" +#include "aw-common-firmware.h" =20 enum aw8808x_type { AW88081, @@ -69,7 +70,7 @@ static int aw88081_dev_check_mode1_pll(struct aw_device *= aw_dev) ret =3D aw88081_dev_get_iis_status(aw_dev); if (ret) { dev_err(aw_dev->dev, "mode1 iis signal check error"); - usleep_range(AW88081_2000_US, AW88081_2000_US + 10); + usleep_range(AW_2000_US, AW_2000_US + 10); } else { return 0; } @@ -103,7 +104,7 @@ static int aw88081_dev_check_mode2_pll(struct aw_device= *aw_dev) ret =3D aw88081_dev_get_iis_status(aw_dev); if (ret) { dev_err(aw_dev->dev, "mode2 iis check error"); - usleep_range(AW88081_2000_US, AW88081_2000_US + 10); + usleep_range(AW_2000_US, AW_2000_US + 10); } else { break; } @@ -113,12 +114,12 @@ static int aw88081_dev_check_mode2_pll(struct aw_devi= ce *aw_dev) ret =3D regmap_update_bits(aw_dev->regmap, AW88081_PLLCTRL1_REG, ~AW88081_CCO_MUX_MASK, AW88081_CCO_MUX_BYPASS_VALUE); if (ret =3D=3D 0) { - usleep_range(AW88081_2000_US, AW88081_2000_US + 10); + usleep_range(AW_2000_US, AW_2000_US + 10); for (i =3D 0; i < AW88081_DEV_SYSST_CHECK_MAX; i++) { ret =3D aw88081_dev_check_mode1_pll(aw_dev); if (ret) { dev_err(aw_dev->dev, "mode2 switch to mode1, iis check error"); - usleep_range(AW88081_2000_US, AW88081_2000_US + 10); + usleep_range(AW_2000_US, AW_2000_US + 10); } else { break; } @@ -170,7 +171,7 @@ static int aw88081_dev_check_sysst(struct aw_device *aw= _dev) if (value !=3D check_val) { dev_err(aw_dev->dev, "check sysst fail, reg_val=3D0x%04x, check:0x%x", reg_val, check_val); - usleep_range(AW88081_2000_US, AW88081_2000_US + 10); + usleep_range(AW_2000_US, AW_2000_US + 10); } else { return 0; } @@ -179,36 +180,6 @@ static int aw88081_dev_check_sysst(struct aw_device *a= w_dev) return -EPERM; } =20 -static void aw88081_dev_i2s_tx_enable(struct aw_device *aw_dev, bool flag) -{ - if (flag) - regmap_update_bits(aw_dev->regmap, AW88081_I2SCTRL3_REG, - ~AW88081_I2STXEN_MASK, AW88081_I2STXEN_ENABLE_VALUE); - else - regmap_update_bits(aw_dev->regmap, AW88081_I2SCTRL3_REG, - ~AW88081_I2STXEN_MASK, AW88081_I2STXEN_DISABLE_VALUE); -} - -static void aw88081_dev_pwd(struct aw_device *aw_dev, bool pwd) -{ - if (pwd) - regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, - ~AW88081_PWDN_MASK, AW88081_PWDN_POWER_DOWN_VALUE); - else - regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, - ~AW88081_PWDN_MASK, AW88081_PWDN_WORKING_VALUE); -} - -static void aw88081_dev_amppd(struct aw_device *aw_dev, bool amppd) -{ - if (amppd) - regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, - ~AW88081_EN_PA_MASK, AW88081_EN_PA_POWER_DOWN_VALUE); - else - regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, - ~AW88081_EN_PA_MASK, AW88081_EN_PA_WORKING_VALUE); -} - static void aw88083_i2c_wen(struct aw88081 *aw88081, bool flag) { struct aw_device *aw_dev =3D aw88081->aw_pa; @@ -224,39 +195,7 @@ static void aw88083_i2c_wen(struct aw88081 *aw88081, b= ool flag) ~AW88083_I2C_WEN_MASK, AW88083_I2C_WEN_DISABLE_VALUE); } =20 -static void aw88083_dev_amppd(struct aw_device *aw_dev, bool amppd) -{ - if (amppd) - regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, - ~AW88083_AMPPD_MASK, AW88083_AMPPD_POWER_DOWN_VALUE); - else - regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, - ~AW88083_AMPPD_MASK, AW88083_AMPPD_WORKING_VALUE); -} - -static void aw88083_dev_pllpd(struct aw_device *aw_dev, bool pllpd) -{ - if (pllpd) - regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, - ~AW88083_PLL_PD_MASK, AW88083_PLL_PD_WORKING_VALUE); - else - regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, - ~AW88083_PLL_PD_MASK, AW88083_PLL_PD_POWER_DOWN_VALUE); -} - -static void aw88081_dev_clear_int_status(struct aw_device *aw_dev) -{ - unsigned int int_status; - - /* read int status and clear */ - regmap_read(aw_dev->regmap, AW88081_SYSINT_REG, &int_status); - /* make sure int status is clear */ - regmap_read(aw_dev->regmap, AW88081_SYSINT_REG, &int_status); - - dev_dbg(aw_dev->dev, "read interrupt reg =3D 0x%04x", int_status); -} - -static void aw88081_dev_set_volume(struct aw_device *aw_dev, unsigned int = value) +static void aw88081_set_volume(struct aw_device *aw_dev, unsigned int valu= e) { struct aw_volume_desc *vol_desc =3D &aw_dev->volume_desc; unsigned int volume; @@ -266,72 +205,19 @@ static void aw88081_dev_set_volume(struct aw_device *= aw_dev, unsigned int value) regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL2_REG, ~AW88081_VOL_MAS= K, volume); } =20 -static void aw88081_dev_fade_in(struct aw_device *aw_dev) -{ - struct aw_volume_desc *desc =3D &aw_dev->volume_desc; - int fade_in_vol =3D desc->ctl_volume; - int fade_step =3D aw_dev->fade_step; - int i; - - if (fade_step =3D=3D 0 || aw_dev->fade_in_time =3D=3D 0) { - aw88081_dev_set_volume(aw_dev, fade_in_vol); - return; - } - - for (i =3D AW88081_MUTE_VOL; i >=3D fade_in_vol; i -=3D fade_step) { - aw88081_dev_set_volume(aw_dev, i); - usleep_range(aw_dev->fade_in_time, aw_dev->fade_in_time + 10); - } - - if (i !=3D fade_in_vol) - aw88081_dev_set_volume(aw_dev, fade_in_vol); -} - -static void aw88081_dev_fade_out(struct aw_device *aw_dev) -{ - struct aw_volume_desc *desc =3D &aw_dev->volume_desc; - int fade_step =3D aw_dev->fade_step; - int i; - - if (fade_step =3D=3D 0 || aw_dev->fade_out_time =3D=3D 0) { - aw88081_dev_set_volume(aw_dev, AW88081_MUTE_VOL); - return; - } - - for (i =3D desc->ctl_volume; i <=3D AW88081_MUTE_VOL; i +=3D fade_step) { - aw88081_dev_set_volume(aw_dev, i); - usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10); - } - - if (i !=3D AW88081_MUTE_VOL) - aw88081_dev_set_volume(aw_dev, AW88081_MUTE_VOL); -} - static void aw88081_dev_mute(struct aw_device *aw_dev, bool is_mute) { if (is_mute) { - aw88081_dev_fade_out(aw_dev); + aw_dev_fade_out(aw_dev, aw88081_set_volume); regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, ~AW88081_HMUTE_MASK, AW88081_HMUTE_ENABLE_VALUE); } else { regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, ~AW88081_HMUTE_MASK, AW88081_HMUTE_DISABLE_VALUE); - aw88081_dev_fade_in(aw_dev); + aw_dev_fade_in(aw_dev, aw88081_set_volume); } } =20 -static void aw88081_dev_uls_hmute(struct aw_device *aw_dev, bool uls_hmute) -{ - if (uls_hmute) - regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, - ~AW88081_ULS_HMUTE_MASK, - AW88081_ULS_HMUTE_ENABLE_VALUE); - else - regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, - ~AW88081_ULS_HMUTE_MASK, - AW88081_ULS_HMUTE_DISABLE_VALUE); -} - static int aw88081_dev_reg_value_check(struct aw_device *aw_dev, unsigned char reg_addr, unsigned short *reg_val) { @@ -451,39 +337,7 @@ static int aw88081_dev_reg_update(struct aw88081 *aw88= 081, vol_desc->ctl_volume =3D 0; =20 /* keep min volume */ - aw88081_dev_set_volume(aw_dev, vol_desc->mute_volume); - - return 0; -} - -static int aw88081_dev_get_prof_name(struct aw_device *aw_dev, int index, = char **prof_name) -{ - struct aw_prof_info *prof_info =3D &aw_dev->prof_info; - struct aw_prof_desc *prof_desc; - - if ((index >=3D aw_dev->prof_info.count) || (index < 0)) { - dev_err(aw_dev->dev, "index[%d] overflow count[%d]", - index, aw_dev->prof_info.count); - return -EINVAL; - } - - prof_desc =3D &aw_dev->prof_info.prof_desc[index]; - - *prof_name =3D prof_info->prof_name_list[prof_desc->id]; - - return 0; -} - -static int aw88081_dev_get_prof_data(struct aw_device *aw_dev, int index, - struct aw_prof_desc **prof_desc) -{ - if ((index >=3D aw_dev->prof_info.count) || (index < 0)) { - dev_err(aw_dev->dev, "%s: index[%d] overflow count[%d]\n", - __func__, index, aw_dev->prof_info.count); - return -EINVAL; - } - - *prof_desc =3D &aw_dev->prof_info.prof_desc[index]; + aw88081_set_volume(aw_dev, vol_desc->mute_volume); =20 return 0; } @@ -496,7 +350,7 @@ static int aw88081_dev_fw_update(struct aw88081 *aw8808= 1) char *prof_name; int ret; =20 - ret =3D aw88081_dev_get_prof_name(aw_dev, aw_dev->prof_index, &prof_name); + ret =3D aw_dev_get_prof_name(aw_dev, aw_dev->prof_index, &prof_name); if (ret) { dev_err(aw_dev->dev, "get prof name failed"); return -EINVAL; @@ -504,14 +358,14 @@ static int aw88081_dev_fw_update(struct aw88081 *aw88= 081) =20 dev_dbg(aw_dev->dev, "start update %s", prof_name); =20 - ret =3D aw88081_dev_get_prof_data(aw_dev, aw_dev->prof_index, &prof_index= _desc); + ret =3D aw_dev_get_prof_data(aw_dev, aw_dev->prof_index, &prof_index_desc= ); if (ret) return ret; =20 /* update reg */ sec_desc =3D prof_index_desc->sec_desc; - ret =3D aw88081_dev_reg_update(aw88081, sec_desc[AW88395_DATA_TYPE_REG].d= ata, - sec_desc[AW88395_DATA_TYPE_REG].len); + ret =3D aw88081_dev_reg_update(aw88081, sec_desc[AW_DATA_TYPE_REG].data, + sec_desc[AW_DATA_TYPE_REG].len); if (ret) { dev_err(aw_dev->dev, "update reg failed"); return ret; @@ -527,14 +381,15 @@ static int aw88081_dev_start(struct aw88081 *aw88081) struct aw_device *aw_dev =3D aw88081->aw_pa; int ret; =20 - if (aw_dev->status =3D=3D AW88081_DEV_PW_ON) { + if (aw_dev->status =3D=3D AW_DEV_PW_ON) { dev_dbg(aw_dev->dev, "already power on"); return 0; } =20 /* power on */ - aw88081_dev_pwd(aw_dev, false); - usleep_range(AW88081_2000_US, AW88081_2000_US + 10); + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, + ~AW88081_PWDN_MASK, AW88081_PWDN_WORKING_VALUE); + usleep_range(AW_2000_US, AW_2000_US + 10); =20 ret =3D aw88081_dev_check_syspll(aw_dev); if (ret) { @@ -543,8 +398,9 @@ static int aw88081_dev_start(struct aw88081 *aw88081) } =20 /* amppd on */ - aw88081_dev_amppd(aw_dev, false); - usleep_range(AW88081_1000_US, AW88081_1000_US + 50); + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, + ~AW88081_EN_PA_MASK, AW88081_EN_PA_WORKING_VALUE); + usleep_range(AW_1000_US, AW_1000_US + 50); =20 /* check i2s status */ ret =3D aw88081_dev_check_sysst(aw_dev); @@ -554,27 +410,32 @@ static int aw88081_dev_start(struct aw88081 *aw88081) } =20 /* enable tx feedback */ - aw88081_dev_i2s_tx_enable(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88081_I2SCTRL3_REG, + ~AW88081_I2STXEN_MASK, AW88081_I2STXEN_ENABLE_VALUE); =20 /* close uls mute */ - aw88081_dev_uls_hmute(aw_dev, false); + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, + ~AW88081_ULS_HMUTE_MASK, AW88081_ULS_HMUTE_DISABLE_VALUE); =20 /* close mute */ aw88081_dev_mute(aw_dev, false); =20 /* clear inturrupt */ - aw88081_dev_clear_int_status(aw_dev); - aw_dev->status =3D AW88081_DEV_PW_ON; + aw_dev_clear_int_status(aw_dev); + aw_dev->status =3D AW_DEV_PW_ON; =20 return 0; =20 sysst_check_fail: - aw88081_dev_i2s_tx_enable(aw_dev, false); - aw88081_dev_clear_int_status(aw_dev); - aw88081_dev_amppd(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88081_I2SCTRL3_REG, + ~AW88081_I2STXEN_MASK, AW88081_I2STXEN_DISABLE_VALUE); + aw_dev_clear_int_status(aw_dev); + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, + ~AW88081_EN_PA_MASK, AW88081_EN_PA_POWER_DOWN_VALUE); pll_check_fail: - aw88081_dev_pwd(aw_dev, true); - aw_dev->status =3D AW88081_DEV_PW_OFF; + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, + ~AW88081_PWDN_MASK, AW88081_PWDN_POWER_DOWN_VALUE); + aw_dev->status =3D AW_DEV_PW_OFF; =20 return ret; } @@ -583,7 +444,7 @@ static int aw88083_dev_start(struct aw88081 *aw88081) { struct aw_device *aw_dev =3D aw88081->aw_pa; =20 - if (aw_dev->status =3D=3D AW88081_DEV_PW_ON) { + if (aw_dev->status =3D=3D AW_DEV_PW_ON) { dev_dbg(aw_dev->dev, "already power on"); return 0; } @@ -591,20 +452,23 @@ static int aw88083_dev_start(struct aw88081 *aw88081) aw88083_i2c_wen(aw88081, true); =20 /* power on */ - aw88081_dev_pwd(aw_dev, false); - usleep_range(AW88081_2000_US, AW88081_2000_US + 10); + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, + ~AW88081_PWDN_MASK, AW88081_PWDN_WORKING_VALUE); + usleep_range(AW_2000_US, AW_2000_US + 10); =20 - aw88083_dev_pllpd(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, + ~AW88083_PLL_PD_MASK, AW88083_PLL_PD_WORKING_VALUE); /* amppd on */ - aw88083_dev_amppd(aw_dev, false); - usleep_range(AW88081_2000_US, AW88081_2000_US + 50); + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, + ~AW88083_AMPPD_MASK, AW88083_AMPPD_WORKING_VALUE); + usleep_range(AW_2000_US, AW_2000_US + 50); =20 /* close mute */ aw88081_dev_mute(aw_dev, false); =20 aw88083_i2c_wen(aw88081, false); =20 - aw_dev->status =3D AW88081_DEV_PW_ON; + aw_dev->status =3D AW_DEV_PW_ON; =20 return 0; } @@ -633,29 +497,33 @@ static int aw88081_dev_stop(struct aw88081 *aw88081) { struct aw_device *aw_dev =3D aw88081->aw_pa; =20 - if (aw_dev->status =3D=3D AW88081_DEV_PW_OFF) { + if (aw_dev->status =3D=3D AW_DEV_PW_OFF) { dev_dbg(aw_dev->dev, "already power off"); return 0; } =20 - aw_dev->status =3D AW88081_DEV_PW_OFF; + aw_dev->status =3D AW_DEV_PW_OFF; =20 /* clear inturrupt */ - aw88081_dev_clear_int_status(aw_dev); + aw_dev_clear_int_status(aw_dev); =20 - aw88081_dev_uls_hmute(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, + ~AW88081_ULS_HMUTE_MASK, AW88081_ULS_HMUTE_ENABLE_VALUE); /* set mute */ aw88081_dev_mute(aw_dev, true); =20 /* close tx feedback */ - aw88081_dev_i2s_tx_enable(aw_dev, false); - usleep_range(AW88081_1000_US, AW88081_1000_US + 100); + regmap_update_bits(aw_dev->regmap, AW88081_I2SCTRL3_REG, + ~AW88081_I2STXEN_MASK, AW88081_I2STXEN_DISABLE_VALUE); + usleep_range(AW_1000_US, AW_1000_US + 100); =20 /* enable amppd */ - aw88081_dev_amppd(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, + ~AW88081_EN_PA_MASK, AW88081_EN_PA_POWER_DOWN_VALUE); =20 /* set power down */ - aw88081_dev_pwd(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, + ~AW88081_PWDN_MASK, AW88081_PWDN_POWER_DOWN_VALUE); =20 return 0; } @@ -664,26 +532,29 @@ static int aw88083_dev_stop(struct aw88081 *aw88081) { struct aw_device *aw_dev =3D aw88081->aw_pa; =20 - if (aw_dev->status =3D=3D AW88081_DEV_PW_OFF) { + if (aw_dev->status =3D=3D AW_DEV_PW_OFF) { dev_dbg(aw_dev->dev, "already power off"); return 0; } =20 - aw_dev->status =3D AW88081_DEV_PW_OFF; + aw_dev->status =3D AW_DEV_PW_OFF; =20 aw88083_i2c_wen(aw88081, true); /* set mute */ aw88081_dev_mute(aw_dev, true); =20 - usleep_range(AW88081_2000_US, AW88081_2000_US + 100); + usleep_range(AW_2000_US, AW_2000_US + 100); =20 /* enable amppd */ - aw88083_dev_amppd(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, + ~AW88083_AMPPD_MASK, AW88083_AMPPD_POWER_DOWN_VALUE); =20 - aw88083_dev_pllpd(aw_dev, false); + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, + ~AW88083_PLL_PD_MASK, AW88083_PLL_PD_POWER_DOWN_VALUE); =20 /* set power down */ - aw88081_dev_pwd(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, + ~AW88081_PWDN_MASK, AW88081_PWDN_POWER_DOWN_VALUE); =20 aw88083_i2c_wen(aw88081, false); =20 @@ -770,13 +641,13 @@ static void aw88081_startup_work(struct work_struct *= work) =20 static void aw88081_start(struct aw88081 *aw88081, bool sync_start) { - if (aw88081->aw_pa->fw_status !=3D AW88081_DEV_FW_OK) + if (aw88081->aw_pa->fw_status !=3D AW_DEV_FW_OK) return; =20 - if (aw88081->aw_pa->status =3D=3D AW88081_DEV_PW_ON) + if (aw88081->aw_pa->status =3D=3D AW_DEV_PW_ON) return; =20 - if (sync_start =3D=3D AW88081_SYNC_START) + if (sync_start =3D=3D AW_SYNC_START) aw88081_start_pa(aw88081); else queue_delayed_work(system_wq, @@ -912,7 +783,7 @@ static int aw88081_profile_info(struct snd_kcontrol *kc= ontrol, =20 count =3D uinfo->value.enumerated.item; =20 - ret =3D aw88081_dev_get_prof_name(aw88081->aw_pa, count, &prof_name); + ret =3D aw_dev_get_prof_name(aw88081->aw_pa, count, &prof_name); if (ret) { strscpy(uinfo->value.enumerated.name, "null"); return 0; @@ -952,7 +823,7 @@ static int aw88081_profile_set(struct snd_kcontrol *kco= ntrol, =20 if (aw88081->aw_pa->status) { aw88081_stop(aw88081); - aw88081_start(aw88081, AW88081_SYNC_START); + aw88081_start(aw88081, AW_SYNC_START); } =20 mutex_unlock(&aw88081->lock); @@ -991,7 +862,7 @@ static int aw88081_volume_set(struct snd_kcontrol *kcon= trol, =20 if (vol_desc->ctl_volume !=3D value) { vol_desc->ctl_volume =3D value; - aw88081_dev_set_volume(aw88081->aw_pa, vol_desc->ctl_volume); + aw88081_set_volume(aw88081->aw_pa, vol_desc->ctl_volume); return 1; } =20 @@ -1042,7 +913,7 @@ static const struct snd_kcontrol_new aw88081_controls[= ] =3D { aw88081_get_fade_in_time, aw88081_set_fade_in_time), SOC_SINGLE_EXT("Volume Ramp Down Step", 0, 0, FADE_TIME_MAX, 0, aw88081_get_fade_out_time, aw88081_set_fade_out_time), - AW88081_PROFILE_EXT("Profile Set", aw88081_profile_info, + AW_PROFILE_EXT("Profile Set", aw88081_profile_info, aw88081_profile_get, aw88081_profile_set), }; =20 @@ -1094,7 +965,7 @@ static int aw88081_init(struct aw88081 *aw88081, struc= t i2c_client *i2c, struct aw_dev->chip_id =3D chip_id; aw_dev->acf =3D NULL; aw_dev->prof_info.prof_desc =3D NULL; - aw_dev->prof_info.prof_type =3D AW88395_DEV_NONE_TYPE_ID; + aw_dev->prof_info.prof_type =3D AW_DEV_NONE_TYPE_ID; aw_dev->fade_step =3D AW88081_VOLUME_STEP_DB; aw_dev->volume_desc.mute_volume =3D AW88081_MUTE_VOL; aw88081_parse_channel_dt(aw88081); @@ -1102,72 +973,6 @@ static int aw88081_init(struct aw88081 *aw88081, stru= ct i2c_client *i2c, struct return 0; } =20 -static int aw88081_dev_init(struct aw88081 *aw88081, struct aw_container *= aw_cfg) -{ - struct aw_device *aw_dev =3D aw88081->aw_pa; - int ret; - - ret =3D aw88395_dev_cfg_load(aw_dev, aw_cfg); - if (ret) { - dev_err(aw_dev->dev, "aw_dev acf parse failed"); - return -EINVAL; - } - - ret =3D regmap_write(aw_dev->regmap, AW88081_ID_REG, AW88081_SOFT_RESET_V= ALUE); - if (ret) - return ret; - - aw_dev->fade_in_time =3D AW88081_500_US; - aw_dev->fade_out_time =3D AW88081_500_US; - aw_dev->prof_cur =3D AW88081_INIT_PROFILE; - aw_dev->prof_index =3D AW88081_INIT_PROFILE; - - ret =3D aw88081_dev_fw_update(aw88081); - if (ret) { - dev_err(aw_dev->dev, "fw update failed ret =3D %d\n", ret); - return ret; - } - - aw_dev->status =3D AW88081_DEV_PW_ON; - aw88081_stop(aw88081); - - return 0; -} - -static int aw88081_request_firmware_file(struct aw88081 *aw88081) -{ - const struct firmware *cont =3D NULL; - int ret; - - aw88081->aw_pa->fw_status =3D AW88081_DEV_FW_FAILED; - - ret =3D request_firmware(&cont, AW88081_ACF_FILE, aw88081->aw_pa->dev); - if (ret) - return ret; - - dev_dbg(aw88081->aw_pa->dev, "loaded %s - size: %zu\n", - AW88081_ACF_FILE, cont ? cont->size : 0); - - aw88081->aw_cfg =3D devm_kzalloc(aw88081->aw_pa->dev, cont->size + sizeof= (int), GFP_KERNEL); - if (!aw88081->aw_cfg) { - release_firmware(cont); - return -ENOMEM; - } - aw88081->aw_cfg->len =3D (int)cont->size; - memcpy(aw88081->aw_cfg->data, cont->data, cont->size); - release_firmware(cont); - - ret =3D aw88395_dev_load_acf_check(aw88081->aw_pa, aw88081->aw_cfg); - if (ret) - return ret; - - mutex_lock(&aw88081->lock); - ret =3D aw88081_dev_init(aw88081, aw88081->aw_cfg); - mutex_unlock(&aw88081->lock); - - return ret; -} - static int aw88081_playback_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { @@ -1177,7 +982,7 @@ static int aw88081_playback_event(struct snd_soc_dapm_= widget *w, mutex_lock(&aw88081->lock); switch (event) { case SND_SOC_DAPM_PRE_PMU: - aw88081_start(aw88081, AW88081_ASYNC_START); + aw88081_start(aw88081, AW_ASYNC_START); break; case SND_SOC_DAPM_POST_PMD: aw88081_stop(aw88081); @@ -1214,9 +1019,13 @@ static int aw88081_codec_probe(struct snd_soc_compon= ent *component) =20 INIT_DELAYED_WORK(&aw88081->start_work, aw88081_startup_work); =20 - ret =3D aw88081_request_firmware_file(aw88081); - if (ret) - dev_err(aw88081->aw_pa->dev, "%s: request firmware failed\n", __func__); + ret =3D aw_dev_request_firmware_file(aw88081->aw_pa, AW88081_ACF_FILE); + if (ret) { + dev_err(aw88081->aw_pa->dev, "%s failed\n", __func__); + return ret; + } + + ret =3D aw88081_dev_fw_update(aw88081); =20 return ret; } diff --git a/sound/soc/codecs/aw88081.h b/sound/soc/codecs/aw88081.h index 7a4564270ab3..4e356bf0e010 100644 --- a/sound/soc/codecs/aw88081.h +++ b/sound/soc/codecs/aw88081.h @@ -286,8 +286,6 @@ SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S32_LE) =20 -#define FADE_TIME_MAX 100000 - #define AW88081_DEV_DEFAULT_CH (0) #define AW88081_ACF_FILE "aw88081_acf.bin" #define AW88081_DEV_SYSST_CHECK_MAX (10) @@ -295,35 +293,4 @@ =20 #define AW88081_INIT_PROFILE (0) =20 -#define AW88081_PROFILE_EXT(xname, profile_info, profile_get, profile_set)= \ -{ \ - .iface =3D SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name =3D xname, \ - .info =3D profile_info, \ - .get =3D profile_get, \ - .put =3D profile_set, \ -} - -enum { - AW88081_SYNC_START =3D 0, - AW88081_ASYNC_START, -}; - -enum { - AW88081_500_US =3D 500, - AW88081_1000_US =3D 1000, - AW88081_2000_US =3D 2000, - AW88081_5000_US =3D 5000, -}; - -enum { - AW88081_DEV_PW_OFF =3D 0, - AW88081_DEV_PW_ON, -}; - -enum { - AW88081_DEV_FW_FAILED =3D 0, - AW88081_DEV_FW_OK, -}; - #endif --=20 2.47.0 From nobody Wed Oct 1 22:31:21 2025 Received: from out198-13.us.a.mail.aliyun.com (out198-13.us.a.mail.aliyun.com [47.90.198.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2F4372EF67A; Fri, 26 Sep 2025 10:21:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=47.90.198.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758882071; cv=none; b=EXnHcOlEinsFY0X0s8TaWna2YotdDlXMPem+GttyvjAfCDtJf157dItxg7xQI8+Ze6v6plnqyRxatFOaxpE+F6LTQa0WPYa92bX1/riAgojA7kzaLqFrxZx3G/xl2xk3hnyqhtrx2L8OsI02VFzWPJc5s6dksQZDAfKXDDcG5Es= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758882071; c=relaxed/simple; bh=QiSbJfURIf+Lu04dsvrIgofWufpqWBOww8czbBwfnEk=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tpVvufyFuPAYqw+sV1CwaBAajMIoJZ6InIJVik/r9CbD/8r5jcBIMDoKlpZTegdiy5muhaRy67VjOmQs4BR+2DJy5tHFNRHlrAr7iKwgffaYdPb9biPbQ3ZRwm4lhuIM9mbnTWiGk609SUzcP19spQ0nG0sk2Cp9M4hqAqPLrGs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=awinic.com; spf=pass smtp.mailfrom=awinic.com; dkim=pass (2048-bit key) header.d=awinic.com header.i=@awinic.com header.b=ZypvEhGE; arc=none smtp.client-ip=47.90.198.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=awinic.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=awinic.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=awinic.com header.i=@awinic.com header.b="ZypvEhGE" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=awinic.com; s=default; t=1758882054; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=foMJuuIU9iM9ucLIhSZvo4bGpJiocPgRr44s1b5iQQU=; b=ZypvEhGEOik7Xcp2FAOkmtBVgURiBauiI8LBZi+MMzlPWm6mCpfAmd5hfUbfeIdTYyjqGM1fbjsYnA1mUze8xy+7SL89ndlpVh3esv/tcmOH7QGyyl2rccMtVioZYrZpWOG0hvgzKFBt1JCbcBtXecK2L3jzfebpDxG/2JuPUSZ2O1ZoolQuydMMn1a99OE932/eiSOmLLnD9p9/JiXfijkSD0XRarnegQPmWzzrFFr6tvU/7FG7xBCGkvqsz5mzvjHVu8sB4UNmI1R5wS5VpsgppRnFUUZKqfzmpqshzG594IRYESzTrUnL18Qq70IzSZmqgaZq8lTSOlM9b9Bh9A== Received: from ubuntu-VirtualBox..(mailfrom:wangweidong.a@awinic.com fp:SMTPD_---.ensjP1n_1758882050 cluster:ay29) by smtp.aliyun-inc.com; Fri, 26 Sep 2025 18:20:51 +0800 From: wangweidong.a@awinic.com To: lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, wangweidong.a@awinic.com, cy_huang@richtek.com, ivprusov@salutedevices.com, zhoubinbin@loongson.cn, zhangyi@everest-semi.com, jack.yu@realtek.com, shenghao-ding@ti.com, rf@opensource.cirrus.com, git@apitzsch.eu, nuno.sa@analog.com, colin.i.king@gmail.com, thorsten.blum@linux.dev, yesanishhere@gmail.com, ebiggers@google.com, ardb@kernel.org, zhujun2@cmss.chinamobile.com, linux-kernel@vger.kernel.org, linux-sound@vger.kernel.org Subject: [PATCH V1 5/7] ASoC: codecs: Rework the aw88166 driver Date: Fri, 26 Sep 2025 18:20:35 +0800 Message-ID: <20250926102037.27697-6-wangweidong.a@awinic.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20250926102037.27697-1-wangweidong.a@awinic.com> References: <20250926102037.27697-1-wangweidong.a@awinic.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Weidong Wang Modify the interface for calling the aw88166 driver to adapt it for aw-common-device.c and aw-common-firmware.c Signed-off-by: Weidong Wang --- sound/soc/codecs/aw88166.c | 819 +++++++------------------------------ sound/soc/codecs/aw88166.h | 58 --- 2 files changed, 137 insertions(+), 740 deletions(-) diff --git a/sound/soc/codecs/aw88166.c b/sound/soc/codecs/aw88166.c index 28f62b991ef2..3538675b0d68 100644 --- a/sound/soc/codecs/aw88166.c +++ b/sound/soc/codecs/aw88166.c @@ -11,11 +11,11 @@ #include #include #include -#include #include #include #include "aw88166.h" -#include "aw88395/aw88395_device.h" +#include "aw-common-device.h" +#include "aw-common-firmware.h" =20 struct aw88166 { struct aw_device *aw_pa; @@ -41,150 +41,6 @@ static const struct regmap_config aw88166_remap_config = =3D { .val_format_endian =3D REGMAP_ENDIAN_BIG, }; =20 -static int aw_dev_dsp_write_16bit(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int dsp_data) -{ - int ret; - - ret =3D regmap_write(aw_dev->regmap, AW88166_DSPMADD_REG, dsp_addr); - if (ret) { - dev_err(aw_dev->dev, "%s write addr error, ret=3D%d", __func__, ret); - return ret; - } - - ret =3D regmap_write(aw_dev->regmap, AW88166_DSPMDAT_REG, (u16)dsp_data); - if (ret) { - dev_err(aw_dev->dev, "%s write data error, ret=3D%d", __func__, ret); - return ret; - } - - return 0; -} - -static int aw_dev_dsp_read_16bit(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int *dsp_data) -{ - unsigned int temp_data; - int ret; - - ret =3D regmap_write(aw_dev->regmap, AW88166_DSPMADD_REG, dsp_addr); - if (ret) { - dev_err(aw_dev->dev, "%s write error, ret=3D%d", __func__, ret); - return ret; - } - - ret =3D regmap_read(aw_dev->regmap, AW88166_DSPMDAT_REG, &temp_data); - if (ret) { - dev_err(aw_dev->dev, "%s read error, ret=3D%d", __func__, ret); - return ret; - } - *dsp_data =3D temp_data; - - return 0; -} - -static int aw_dev_dsp_read_32bit(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int *dsp_data) -{ - unsigned int temp_data; - int ret; - - ret =3D regmap_write(aw_dev->regmap, AW88166_DSPMADD_REG, dsp_addr); - if (ret) { - dev_err(aw_dev->dev, "%s write error, ret=3D%d", __func__, ret); - return ret; - } - - ret =3D regmap_read(aw_dev->regmap, AW88166_DSPMDAT_REG, &temp_data); - if (ret) { - dev_err(aw_dev->dev, "%s read error, ret=3D%d", __func__, ret); - return ret; - } - *dsp_data =3D temp_data; - - ret =3D regmap_read(aw_dev->regmap, AW88166_DSPMDAT_REG, &temp_data); - if (ret) { - dev_err(aw_dev->dev, "%s read error, ret=3D%d", __func__, ret); - return ret; - } - *dsp_data |=3D (temp_data << 16); - - return 0; -} - -static int aw_dev_dsp_read(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int *dsp_data, unsigned char data_type) -{ - u32 reg_value; - int ret; - - mutex_lock(&aw_dev->dsp_lock); - switch (data_type) { - case AW88166_DSP_16_DATA: - ret =3D aw_dev_dsp_read_16bit(aw_dev, dsp_addr, dsp_data); - if (ret) - dev_err(aw_dev->dev, "read dsp_addr[0x%x] 16-bit failed", (u32)dsp_addr= ); - break; - case AW88166_DSP_32_DATA: - ret =3D aw_dev_dsp_read_32bit(aw_dev, dsp_addr, dsp_data); - if (ret) - dev_err(aw_dev->dev, "read dsp_addr[0x%x] 32-bit failed", (u32)dsp_addr= ); - break; - default: - dev_err(aw_dev->dev, "data type[%d] unsupported", data_type); - ret =3D -EINVAL; - break; - } - - /* clear dsp chip select state */ - if (regmap_read(aw_dev->regmap, AW88166_ID_REG, ®_value)) - dev_err(aw_dev->dev, "%s fail to clear chip state. ret=3D%d\n", __func__= , ret); - mutex_unlock(&aw_dev->dsp_lock); - - return ret; -} - -static void aw_dev_pwd(struct aw_device *aw_dev, bool pwd) -{ - int ret; - - if (pwd) - ret =3D regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, - ~AW88166_PWDN_MASK, AW88166_PWDN_POWER_DOWN_VALUE); - else - ret =3D regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, - ~AW88166_PWDN_MASK, AW88166_PWDN_WORKING_VALUE); - - if (ret) - dev_dbg(aw_dev->dev, "%s failed", __func__); -} - -static void aw_dev_get_int_status(struct aw_device *aw_dev, unsigned short= *int_status) -{ - unsigned int reg_val; - int ret; - - ret =3D regmap_read(aw_dev->regmap, AW88166_SYSINT_REG, ®_val); - if (ret) - dev_err(aw_dev->dev, "read interrupt reg fail, ret=3D%d", ret); - else - *int_status =3D reg_val; - - dev_dbg(aw_dev->dev, "read interrupt reg=3D0x%04x", *int_status); -} - -static void aw_dev_clear_int_status(struct aw_device *aw_dev) -{ - u16 int_status; - - /* read int status and clear */ - aw_dev_get_int_status(aw_dev, &int_status); - /* make sure int status is clear */ - aw_dev_get_int_status(aw_dev, &int_status); - if (int_status) - dev_dbg(aw_dev->dev, "int status(%d) is not cleaned.\n", int_status); -} - static int aw_dev_get_iis_status(struct aw_device *aw_dev) { unsigned int reg_val; @@ -209,7 +65,7 @@ static int aw_dev_check_mode1_pll(struct aw_device *aw_d= ev) ret =3D aw_dev_get_iis_status(aw_dev); if (ret) { dev_err(aw_dev->dev, "mode1 iis signal check error"); - usleep_range(AW88166_2000_US, AW88166_2000_US + 10); + usleep_range(AW_2000_US, AW_2000_US + 10); } else { return 0; } @@ -243,7 +99,7 @@ static int aw_dev_check_mode2_pll(struct aw_device *aw_d= ev) ret =3D aw_dev_get_iis_status(aw_dev); if (ret) { dev_err(aw_dev->dev, "mode2 iis signal check error"); - usleep_range(AW88166_2000_US, AW88166_2000_US + 10); + usleep_range(AW_2000_US, AW_2000_US + 10); } else { break; } @@ -253,12 +109,12 @@ static int aw_dev_check_mode2_pll(struct aw_device *a= w_dev) regmap_update_bits(aw_dev->regmap, AW88166_PLLCTRL2_REG, ~AW88166_CCO_MUX_MASK, AW88166_CCO_MUX_BYPASS_VALUE); if (ret =3D=3D 0) { - usleep_range(AW88166_2000_US, AW88166_2000_US + 10); + usleep_range(AW_2000_US, AW_2000_US + 10); for (i =3D 0; i < AW88166_DEV_SYSST_CHECK_MAX; i++) { ret =3D aw_dev_get_iis_status(aw_dev); if (ret) { dev_err(aw_dev->dev, "mode2 switch to mode1, iis signal check error"); - usleep_range(AW88166_2000_US, AW88166_2000_US + 10); + usleep_range(AW_2000_US, AW_2000_US + 10); } else { break; } @@ -308,7 +164,7 @@ static int aw_dev_check_sysst(struct aw_device *aw_dev) if ((reg_val & (~AW88166_BIT_SYSST_CHECK_MASK) & check_val) !=3D check_v= al) { dev_err(aw_dev->dev, "check sysst fail, cnt=3D%d, reg_val=3D0x%04x, che= ck:0x%x", i, reg_val, AW88166_BIT_SYSST_NOSWS_CHECK); - usleep_range(AW88166_2000_US, AW88166_2000_US + 10); + usleep_range(AW_2000_US, AW_2000_US + 10); } else { return 0; } @@ -317,36 +173,6 @@ static int aw_dev_check_sysst(struct aw_device *aw_dev) return -EPERM; } =20 -static void aw_dev_amppd(struct aw_device *aw_dev, bool amppd) -{ - int ret; - - if (amppd) - ret =3D regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, - ~AW88166_AMPPD_MASK, AW88166_AMPPD_POWER_DOWN_VALUE); - else - ret =3D regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, - ~AW88166_AMPPD_MASK, AW88166_AMPPD_WORKING_VALUE); - - if (ret) - dev_dbg(aw_dev->dev, "%s failed", __func__); -} - -static void aw_dev_dsp_enable(struct aw_device *aw_dev, bool is_enable) -{ - int ret; - - if (is_enable) - ret =3D regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, - ~AW88166_DSPBY_MASK, AW88166_DSPBY_WORKING_VALUE); - else - ret =3D regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, - ~AW88166_DSPBY_MASK, AW88166_DSPBY_BYPASS_VALUE); - - if (ret) - dev_dbg(aw_dev->dev, "%s failed\n", __func__); -} - static int aw88166_dev_get_icalk(struct aw88166 *aw88166, int16_t *icalk) { struct aw_device *aw_dev =3D aw88166->aw_pa; @@ -564,7 +390,7 @@ static int aw_dev_fw_crc_check(struct aw_device *aw_dev) ret =3D regmap_update_bits(aw_dev->regmap, AW88166_CRCCTRL_REG, ~AW88166_CRC_CODE_EN_MASK, AW88166_CRC_CODE_EN_ENABLE_VALUE); =20 - usleep_range(AW88166_2000_US, AW88166_2000_US + 10); + usleep_range(AW_2000_US, AW_2000_US + 10); =20 /* read crc check result */ regmap_read(aw_dev->regmap, AW88166_HAGCST_REG, ®_val); @@ -609,7 +435,7 @@ static int aw_dev_cfg_crc_check(struct aw_device *aw_de= v) if (ret) return ret; =20 - usleep_range(AW88166_1000_US, AW88166_1000_US + 10); + usleep_range(AW_1000_US, AW_1000_US + 10); =20 /* read crc check result */ ret =3D regmap_read(aw_dev->regmap, AW88166_HAGCST_REG, ®_val); @@ -670,170 +496,74 @@ static int aw_dev_hw_crc_check(struct aw88166 *aw881= 66) return ret; } =20 -static void aw_dev_i2s_tx_enable(struct aw_device *aw_dev, bool flag) -{ - int ret; - - if (flag) - ret =3D regmap_update_bits(aw_dev->regmap, AW88166_I2SCTRL3_REG, - ~AW88166_I2STXEN_MASK, AW88166_I2STXEN_ENABLE_VALUE); - else - ret =3D regmap_update_bits(aw_dev->regmap, AW88166_I2SCTRL3_REG, - ~AW88166_I2STXEN_MASK, AW88166_I2STXEN_DISABLE_VALUE); - - if (ret) - dev_dbg(aw_dev->dev, "%s failed", __func__); -} - -static int aw_dev_get_dsp_status(struct aw_device *aw_dev) -{ - unsigned int reg_val; - int ret; - - ret =3D regmap_read(aw_dev->regmap, AW88166_WDT_REG, ®_val); - if (ret) - return ret; - if (!(reg_val & (~AW88166_WDT_CNT_MASK))) - return -EPERM; - - return 0; -} - static int aw_dev_dsp_check(struct aw_device *aw_dev) { int ret, i; =20 - switch (aw_dev->dsp_cfg) { - case AW88166_DEV_DSP_BYPASS: - dev_dbg(aw_dev->dev, "dsp bypass"); - ret =3D 0; - break; - case AW88166_DEV_DSP_WORK: - aw_dev_dsp_enable(aw_dev, false); - aw_dev_dsp_enable(aw_dev, true); - usleep_range(AW88166_1000_US, AW88166_1000_US + 10); - for (i =3D 0; i < AW88166_DEV_DSP_CHECK_MAX; i++) { - ret =3D aw_dev_get_dsp_status(aw_dev); - if (ret) { - dev_err(aw_dev->dev, "dsp wdt status error=3D%d", ret); - usleep_range(AW88166_2000_US, AW88166_2000_US + 10); - } + + regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, + ~AW88166_DSPBY_MASK, AW88166_DSPBY_BYPASS_VALUE); + regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, + ~AW88166_DSPBY_MASK, AW88166_DSPBY_WORKING_VALUE); + usleep_range(AW_1000_US, AW_1000_US + 10); + for (i =3D 0; i < AW88166_DEV_DSP_CHECK_MAX; i++) { + ret =3D aw_dev_get_dsp_status(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "dsp wdt status error=3D%d", ret); + usleep_range(AW_2000_US, AW_2000_US + 10); } - break; - default: - dev_err(aw_dev->dev, "unknown dsp cfg=3D%d", aw_dev->dsp_cfg); - ret =3D -EINVAL; - break; } =20 return ret; } =20 -static int aw_dev_set_volume(struct aw_device *aw_dev, unsigned int value) +static void aw88166_set_volume(struct aw_device *aw_dev, unsigned int valu= e) { struct aw_volume_desc *vol_desc =3D &aw_dev->volume_desc; unsigned int reg_value; u16 real_value; - int ret; =20 real_value =3D min((value + vol_desc->init_volume), (unsigned int)AW88166= _MUTE_VOL); =20 - ret =3D regmap_read(aw_dev->regmap, AW88166_SYSCTRL2_REG, ®_value); - if (ret) - return ret; + regmap_read(aw_dev->regmap, AW88166_SYSCTRL2_REG, ®_value); =20 dev_dbg(aw_dev->dev, "value 0x%x , reg:0x%x", value, real_value); =20 real_value =3D (real_value << AW88166_VOL_START_BIT) | (reg_value & AW881= 66_VOL_MASK); =20 - ret =3D regmap_write(aw_dev->regmap, AW88166_SYSCTRL2_REG, real_value); - - return ret; -} - -static void aw_dev_fade_in(struct aw_device *aw_dev) -{ - struct aw_volume_desc *desc =3D &aw_dev->volume_desc; - u16 fade_in_vol =3D desc->ctl_volume; - int fade_step =3D aw_dev->fade_step; - int i; - - if (fade_step =3D=3D 0 || aw_dev->fade_in_time =3D=3D 0) { - aw_dev_set_volume(aw_dev, fade_in_vol); - return; - } - - for (i =3D AW88166_MUTE_VOL; i >=3D fade_in_vol; i -=3D fade_step) { - aw_dev_set_volume(aw_dev, i); - usleep_range(aw_dev->fade_in_time, aw_dev->fade_in_time + 10); - } - - if (i !=3D fade_in_vol) - aw_dev_set_volume(aw_dev, fade_in_vol); -} - -static void aw_dev_fade_out(struct aw_device *aw_dev) -{ - struct aw_volume_desc *desc =3D &aw_dev->volume_desc; - int fade_step =3D aw_dev->fade_step; - int i; - - if (fade_step =3D=3D 0 || aw_dev->fade_out_time =3D=3D 0) { - aw_dev_set_volume(aw_dev, AW88166_MUTE_VOL); - return; - } - - for (i =3D desc->ctl_volume; i <=3D AW88166_MUTE_VOL; i +=3D fade_step) { - aw_dev_set_volume(aw_dev, i); - usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10); - } - - if (i !=3D AW88166_MUTE_VOL) { - aw_dev_set_volume(aw_dev, AW88166_MUTE_VOL); - usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10); - } + regmap_write(aw_dev->regmap, AW88166_SYSCTRL2_REG, real_value); } =20 static void aw88166_dev_mute(struct aw_device *aw_dev, bool is_mute) { if (is_mute) { - aw_dev_fade_out(aw_dev); + aw_dev_fade_out(aw_dev, aw88166_set_volume); regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, ~AW88166_HMUTE_MASK, AW88166_HMUTE_ENABLE_VALUE); } else { regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, ~AW88166_HMUTE_MASK, AW88166_HMUTE_DISABLE_VALUE); - aw_dev_fade_in(aw_dev); + aw_dev_fade_in(aw_dev, aw88166_set_volume); } } =20 -static void aw88166_dev_set_dither(struct aw88166 *aw88166, bool dither) -{ - struct aw_device *aw_dev =3D aw88166->aw_pa; - - if (dither) - regmap_update_bits(aw_dev->regmap, AW88166_DBGCTRL_REG, - ~AW88166_DITHER_EN_MASK, AW88166_DITHER_EN_ENABLE_VALUE); - else - regmap_update_bits(aw_dev->regmap, AW88166_DBGCTRL_REG, - ~AW88166_DITHER_EN_MASK, AW88166_DITHER_EN_DISABLE_VALUE); -} - static int aw88166_dev_start(struct aw88166 *aw88166) { struct aw_device *aw_dev =3D aw88166->aw_pa; int ret; =20 - if (aw_dev->status =3D=3D AW88166_DEV_PW_ON) { + if (aw_dev->status =3D=3D AW_DEV_PW_ON) { dev_dbg(aw_dev->dev, "already power on"); return 0; } =20 - aw88166_dev_set_dither(aw88166, false); + regmap_update_bits(aw_dev->regmap, AW88166_DBGCTRL_REG, + ~AW88166_DITHER_EN_MASK, AW88166_DITHER_EN_DISABLE_VALUE); =20 /* power on */ - aw_dev_pwd(aw_dev, false); - usleep_range(AW88166_2000_US, AW88166_2000_US + 10); + regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, + ~AW88166_PWDN_MASK, AW88166_PWDN_WORKING_VALUE); + usleep_range(AW_2000_US, AW_2000_US + 10); =20 ret =3D aw_dev_check_syspll(aw_dev); if (ret) { @@ -842,8 +572,9 @@ static int aw88166_dev_start(struct aw88166 *aw88166) } =20 /* amppd on */ - aw_dev_amppd(aw_dev, false); - usleep_range(AW88166_1000_US, AW88166_1000_US + 50); + regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, + ~AW88166_AMPPD_MASK, AW88166_AMPPD_WORKING_VALUE); + usleep_range(AW_1000_US, AW_1000_US + 50); =20 /* check i2s status */ ret =3D aw_dev_check_sysst(aw_dev); @@ -852,14 +583,15 @@ static int aw88166_dev_start(struct aw88166 *aw88166) goto sysst_check_fail; } =20 - if (aw_dev->dsp_cfg =3D=3D AW88166_DEV_DSP_WORK) { + if (aw_dev->dsp_cfg =3D=3D AW_DEV_DSP_WORK) { aw_dev_backup_sec_recovery(aw88166); ret =3D aw_dev_hw_crc_check(aw88166); if (ret) { dev_err(aw_dev->dev, "dsp crc check failed\n"); goto crc_check_fail; } - aw_dev_dsp_enable(aw_dev, false); + regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, + ~AW88166_DSPBY_MASK, AW88166_DSPBY_BYPASS_VALUE); aw88166_dev_set_vcalb(aw88166); aw_dev_update_cali_re(&aw_dev->cali_desc); ret =3D aw_dev_dsp_check(aw_dev); @@ -872,68 +604,45 @@ static int aw88166_dev_start(struct aw88166 *aw88166) } =20 /* enable tx feedback */ - aw_dev_i2s_tx_enable(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88166_I2SCTRL3_REG, + ~AW88166_I2STXEN_MASK, AW88166_I2STXEN_ENABLE_VALUE); =20 if (aw88166->dither_st =3D=3D AW88166_DITHER_EN_ENABLE_VALUE) - aw88166_dev_set_dither(aw88166, true); + regmap_update_bits(aw_dev->regmap, AW88166_DBGCTRL_REG, + ~AW88166_DITHER_EN_MASK, AW88166_DITHER_EN_ENABLE_VALUE); =20 /* close mute */ aw88166_dev_mute(aw_dev, false); /* clear inturrupt */ aw_dev_clear_int_status(aw_dev); - aw_dev->status =3D AW88166_DEV_PW_ON; + aw_dev->status =3D AW_DEV_PW_ON; =20 return 0; =20 dsp_check_fail: crc_check_fail: - aw_dev_dsp_enable(aw_dev, false); + regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, + ~AW88166_DSPBY_MASK, AW88166_DSPBY_BYPASS_VALUE); sysst_check_fail: aw_dev_clear_int_status(aw_dev); - aw_dev_amppd(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, + ~AW88166_AMPPD_MASK, AW88166_AMPPD_POWER_DOWN_VALUE); pll_check_fail: - aw_dev_pwd(aw_dev, true); - aw_dev->status =3D AW88166_DEV_PW_OFF; - - return ret; -} - -static int aw_dev_dsp_update_container(struct aw_device *aw_dev, - unsigned char *data, unsigned int len, unsigned short base) -{ - u32 tmp_len; - int i, ret; - - mutex_lock(&aw_dev->dsp_lock); - ret =3D regmap_write(aw_dev->regmap, AW88166_DSPMADD_REG, base); - if (ret) - goto error_operation; - - for (i =3D 0; i < len; i +=3D AW88166_MAX_RAM_WRITE_BYTE_SIZE) { - tmp_len =3D min(len - i, AW88166_MAX_RAM_WRITE_BYTE_SIZE); - ret =3D regmap_raw_write(aw_dev->regmap, AW88166_DSPMDAT_REG, - &data[i], tmp_len); - if (ret) - goto error_operation; - } - mutex_unlock(&aw_dev->dsp_lock); - - return 0; + regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, + ~AW88166_PWDN_MASK, AW88166_PWDN_POWER_DOWN_VALUE); + aw_dev->status =3D AW_DEV_PW_OFF; =20 -error_operation: - mutex_unlock(&aw_dev->dsp_lock); return ret; } =20 -static int aw_dev_get_ra(struct aw_cali_desc *cali_desc) +static int aw_dev_get_ra(struct aw_device *aw_dev) { - struct aw_device *aw_dev =3D - container_of(cali_desc, struct aw_device, cali_desc); + struct aw_cali_desc *cali_desc =3D &aw_dev->cali_desc; u32 dsp_ra; int ret; =20 ret =3D aw_dev_dsp_read(aw_dev, AW88166_DSP_REG_CFG_ADPZ_RA, - &dsp_ra, AW88166_DSP_32_DATA); + &dsp_ra, AW_DSP_32_DATA); if (ret) { dev_err(aw_dev->dev, "read ra error\n"); return ret; @@ -945,54 +654,12 @@ static int aw_dev_get_ra(struct aw_cali_desc *cali_de= sc) return 0; } =20 -static int aw_dev_dsp_update_cfg(struct aw_device *aw_dev, - unsigned char *data, unsigned int len) -{ - int ret; - - dev_dbg(aw_dev->dev, "dsp config len:%d", len); - - if (!len || !data) { - dev_err(aw_dev->dev, "dsp config data is null or len is 0\n"); - return -EINVAL; - } - - ret =3D aw_dev_dsp_update_container(aw_dev, data, len, AW88166_DSP_CFG_AD= DR); - if (ret) - return ret; - - aw_dev->dsp_cfg_len =3D len; - - ret =3D aw_dev_get_ra(&aw_dev->cali_desc); - - return ret; -} - -static int aw_dev_dsp_update_fw(struct aw_device *aw_dev, - unsigned char *data, unsigned int len) -{ - int ret; - - dev_dbg(aw_dev->dev, "dsp firmware len:%d", len); - - if (!len || !data) { - dev_err(aw_dev->dev, "dsp firmware data is null or len is 0\n"); - return -EINVAL; - } - - aw_dev->dsp_fw_len =3D len; - ret =3D aw_dev_dsp_update_container(aw_dev, data, len, AW88166_DSP_FW_ADD= R); - - return ret; -} - -static int aw_dev_check_sram(struct aw_device *aw_dev) +static int aw88166_check_sram(struct aw_device *aw_dev) { unsigned int reg_val; =20 - mutex_lock(&aw_dev->dsp_lock); /* read dsp_rom_check_reg */ - aw_dev_dsp_read_16bit(aw_dev, AW88166_DSP_ROM_CHECK_ADDR, ®_val); + aw_dev_dsp_read(aw_dev, AW88166_DSP_ROM_CHECK_ADDR, ®_val, AW_DSP_16_D= ATA); if (reg_val !=3D AW88166_DSP_ROM_CHECK_DATA) { dev_err(aw_dev->dev, "check dsp rom failed, read[0x%x] !=3D check[0x%x]\= n", reg_val, AW88166_DSP_ROM_CHECK_DATA); @@ -1000,47 +667,21 @@ static int aw_dev_check_sram(struct aw_device *aw_de= v) } =20 /* check dsp_cfg_base_addr */ - aw_dev_dsp_write_16bit(aw_dev, AW88166_DSP_CFG_ADDR, AW88166_DSP_ODD_NUM_= BIT_TEST); - aw_dev_dsp_read_16bit(aw_dev, AW88166_DSP_CFG_ADDR, ®_val); + aw_dev_dsp_write(aw_dev, AW88166_DSP_CFG_ADDR, + AW88166_DSP_ODD_NUM_BIT_TEST, AW_DSP_16_DATA); + aw_dev_dsp_read(aw_dev, AW88166_DSP_CFG_ADDR, ®_val, AW_DSP_16_DATA); if (reg_val !=3D AW88166_DSP_ODD_NUM_BIT_TEST) { dev_err(aw_dev->dev, "check dsp cfg failed, read[0x%x] !=3D write[0x%x]\= n", reg_val, AW88166_DSP_ODD_NUM_BIT_TEST); goto error; } - mutex_unlock(&aw_dev->dsp_lock); =20 return 0; error: - mutex_unlock(&aw_dev->dsp_lock); return -EPERM; } =20 -static void aw_dev_select_memclk(struct aw_device *aw_dev, unsigned char f= lag) -{ - int ret; - - switch (flag) { - case AW88166_DEV_MEMCLK_PLL: - ret =3D regmap_update_bits(aw_dev->regmap, AW88166_DBGCTRL_REG, - ~AW88166_MEM_CLKSEL_MASK, - AW88166_MEM_CLKSEL_DAPHCLK_VALUE); - if (ret) - dev_err(aw_dev->dev, "memclk select pll failed\n"); - break; - case AW88166_DEV_MEMCLK_OSC: - ret =3D regmap_update_bits(aw_dev->regmap, AW88166_DBGCTRL_REG, - ~AW88166_MEM_CLKSEL_MASK, - AW88166_MEM_CLKSEL_OSCCLK_VALUE); - if (ret) - dev_err(aw_dev->dev, "memclk select OSC failed\n"); - break; - default: - dev_err(aw_dev->dev, "unknown memclk config, flag=3D0x%x\n", flag); - break; - } -} - -static int aw_dev_update_reg_container(struct aw88166 *aw88166, +static int aw88166_reg_update(struct aw88166 *aw88166, unsigned char *data, unsigned int len) { struct aw_device *aw_dev =3D aw88166->aw_pa; @@ -1054,7 +695,7 @@ static int aw_dev_update_reg_container(struct aw88166 = *aw88166, data_len =3D len >> 1; =20 if (data_len & 0x1) { - dev_err(aw_dev->dev, "data len:%d unsupported\n", data_len); + dev_err(aw_dev->dev, "data len:%d unsupported\n", data_len); return -EINVAL; } =20 @@ -1069,9 +710,9 @@ static int aw_dev_update_reg_container(struct aw88166 = *aw88166, =20 if (reg_addr =3D=3D AW88166_SYSCTRL_REG) { if (reg_val & (~AW88166_DSPBY_MASK)) - aw_dev->dsp_cfg =3D AW88166_DEV_DSP_BYPASS; + aw_dev->dsp_cfg =3D AW_DEV_DSP_BYPASS; else - aw_dev->dsp_cfg =3D AW88166_DEV_DSP_WORK; + aw_dev->dsp_cfg =3D AW_DEV_DSP_WORK; =20 reg_val &=3D (AW88166_HMUTE_MASK | AW88166_PWDN_MASK | AW88166_DSPBY_MASK); @@ -1117,62 +758,14 @@ static int aw_dev_update_reg_container(struct aw8816= 6 *aw88166, return ret; } =20 - aw_dev_pwd(aw_dev, false); - usleep_range(AW88166_1000_US, AW88166_1000_US + 10); + regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, + ~AW88166_PWDN_MASK, AW88166_PWDN_WORKING_VALUE); + usleep_range(AW_1000_US, AW_1000_US + 10); =20 if (aw_dev->prof_cur !=3D aw_dev->prof_index) vol_desc->ctl_volume =3D 0; else - aw_dev_set_volume(aw_dev, vol_desc->ctl_volume); - - return 0; -} - -static int aw_dev_reg_update(struct aw88166 *aw88166, - unsigned char *data, unsigned int len) -{ - int ret; - - if (!len || !data) { - dev_err(aw88166->aw_pa->dev, "reg data is null or len is 0\n"); - return -EINVAL; - } - - ret =3D aw_dev_update_reg_container(aw88166, data, len); - if (ret) - dev_err(aw88166->aw_pa->dev, "reg update failed\n"); - - return ret; -} - -static int aw88166_dev_get_prof_name(struct aw_device *aw_dev, int index, = char **prof_name) -{ - struct aw_prof_info *prof_info =3D &aw_dev->prof_info; - struct aw_prof_desc *prof_desc; - - if ((index >=3D aw_dev->prof_info.count) || (index < 0)) { - dev_err(aw_dev->dev, "index[%d] overflow count[%d]\n", - index, aw_dev->prof_info.count); - return -EINVAL; - } - - prof_desc =3D &aw_dev->prof_info.prof_desc[index]; - - *prof_name =3D prof_info->prof_name_list[prof_desc->id]; - - return 0; -} - -static int aw88166_dev_get_prof_data(struct aw_device *aw_dev, int index, - struct aw_prof_desc **prof_desc) -{ - if ((index >=3D aw_dev->prof_info.count) || (index < 0)) { - dev_err(aw_dev->dev, "%s: index[%d] overflow count[%d]\n", - __func__, index, aw_dev->prof_info.count); - return -EINVAL; - } - - *prof_desc =3D &aw_dev->prof_info.prof_desc[index]; + aw88166_set_volume(aw_dev, vol_desc->ctl_volume); =20 return 0; } @@ -1186,54 +779,51 @@ static int aw88166_dev_fw_update(struct aw88166 *aw8= 8166, bool up_dsp_fw_en, boo int ret; =20 if ((aw_dev->prof_cur =3D=3D aw_dev->prof_index) && - (force_up_en =3D=3D AW88166_FORCE_UPDATE_OFF)) { + (force_up_en =3D=3D AW_FORCE_UPDATE_OFF)) { dev_dbg(aw_dev->dev, "scene no change, not update"); return 0; } =20 - if (aw_dev->fw_status =3D=3D AW88166_DEV_FW_FAILED) { + if (aw_dev->fw_status =3D=3D AW_DEV_FW_FAILED) { dev_err(aw_dev->dev, "fw status[%d] error\n", aw_dev->fw_status); return -EPERM; } =20 - ret =3D aw88166_dev_get_prof_name(aw_dev, aw_dev->prof_index, &prof_name); + ret =3D aw_dev_get_prof_name(aw_dev, aw_dev->prof_index, &prof_name); if (ret) return ret; =20 dev_dbg(aw_dev->dev, "start update %s", prof_name); =20 - ret =3D aw88166_dev_get_prof_data(aw_dev, aw_dev->prof_index, &prof_index= _desc); + ret =3D aw_dev_get_prof_data(aw_dev, aw_dev->prof_index, &prof_index_desc= ); if (ret) return ret; =20 /* update reg */ sec_desc =3D prof_index_desc->sec_desc; - ret =3D aw_dev_reg_update(aw88166, sec_desc[AW88395_DATA_TYPE_REG].data, - sec_desc[AW88395_DATA_TYPE_REG].len); + ret =3D aw88166_reg_update(aw88166, sec_desc[AW_DATA_TYPE_REG].data, + sec_desc[AW_DATA_TYPE_REG].len); if (ret) { dev_err(aw_dev->dev, "update reg failed\n"); return ret; } =20 - aw88166_dev_mute(aw_dev, true); - - if (aw_dev->dsp_cfg =3D=3D AW88166_DEV_DSP_WORK) - aw_dev_dsp_enable(aw_dev, false); - - aw_dev_select_memclk(aw_dev, AW88166_DEV_MEMCLK_OSC); - - ret =3D aw_dev_check_sram(aw_dev); - if (ret) { - dev_err(aw_dev->dev, "check sram failed\n"); - goto error; - } + regmap_update_bits(aw_dev->regmap, AW88166_DBGCTRL_REG, ~AW88166_MEM_CLKS= EL_MASK, + AW88166_MEM_CLKSEL_OSCCLK_VALUE); =20 aw_dev_backup_sec_recovery(aw88166); =20 if (up_dsp_fw_en) { + ret =3D aw88166_check_sram(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "check sram failed\n"); + goto error; + } + dev_dbg(aw_dev->dev, "fw_ver: [%x]", prof_index_desc->fw_ver); - ret =3D aw_dev_dsp_update_fw(aw_dev, sec_desc[AW88395_DATA_TYPE_DSP_FW].= data, - sec_desc[AW88395_DATA_TYPE_DSP_FW].len); + ret =3D aw_dev_dsp_update_fw(aw_dev, sec_desc[AW_DATA_TYPE_DSP_FW].data, + sec_desc[AW_DATA_TYPE_DSP_FW].len, + sec_desc[AW_DATA_TYPE_DSP_FW].addr); if (ret) { dev_err(aw_dev->dev, "update dsp fw failed\n"); goto error; @@ -1241,23 +831,27 @@ static int aw88166_dev_fw_update(struct aw88166 *aw8= 8166, bool up_dsp_fw_en, boo } =20 /* update dsp config */ - ret =3D aw_dev_dsp_update_cfg(aw_dev, sec_desc[AW88395_DATA_TYPE_DSP_CFG]= .data, - sec_desc[AW88395_DATA_TYPE_DSP_CFG].len); + ret =3D aw_dev_dsp_update_cfg(aw_dev, sec_desc[AW_DATA_TYPE_DSP_CFG].data, + sec_desc[AW_DATA_TYPE_DSP_CFG].len, + sec_desc[AW_DATA_TYPE_DSP_CFG].addr); if (ret) { dev_err(aw_dev->dev, "update dsp cfg failed\n"); goto error; } =20 + aw_dev_get_ra(aw_dev); aw_dev_backup_sec_record(aw88166); =20 - aw_dev_select_memclk(aw_dev, AW88166_DEV_MEMCLK_PLL); + regmap_update_bits(aw_dev->regmap, AW88166_DBGCTRL_REG, ~AW88166_MEM_CLKS= EL_MASK, + AW88166_MEM_CLKSEL_DAPHCLK_VALUE); =20 aw_dev->prof_cur =3D aw_dev->prof_index; =20 return 0; =20 error: - aw_dev_select_memclk(aw_dev, AW88166_DEV_MEMCLK_PLL); + regmap_update_bits(aw_dev->regmap, AW88166_DBGCTRL_REG, ~AW88166_MEM_CLKS= EL_MASK, + AW88166_MEM_CLKSEL_DAPHCLK_VALUE); return ret; } =20 @@ -1269,7 +863,7 @@ static void aw88166_start_pa(struct aw88166 *aw88166) ret =3D aw88166_dev_start(aw88166); if (ret) { dev_err(aw88166->aw_pa->dev, "aw88166 device start failed. retry =3D %d= ", i); - ret =3D aw88166_dev_fw_update(aw88166, AW88166_DSP_FW_UPDATE_ON, true); + ret =3D aw88166_dev_fw_update(aw88166, AW_DSP_FW_UPDATE_ON, true); if (ret) { dev_err(aw88166->aw_pa->dev, "fw update failed"); continue; @@ -1295,19 +889,19 @@ static void aw88166_start(struct aw88166 *aw88166, b= ool sync_start) { int ret; =20 - if (aw88166->aw_pa->fw_status !=3D AW88166_DEV_FW_OK) + if (aw88166->aw_pa->fw_status !=3D AW_DEV_FW_OK) return; =20 - if (aw88166->aw_pa->status =3D=3D AW88166_DEV_PW_ON) + if (aw88166->aw_pa->status =3D=3D AW_DEV_PW_ON) return; =20 - ret =3D aw88166_dev_fw_update(aw88166, AW88166_DSP_FW_UPDATE_OFF, aw88166= ->phase_sync); + ret =3D aw88166_dev_fw_update(aw88166, AW_DSP_FW_UPDATE_OFF, aw88166->pha= se_sync); if (ret) { dev_err(aw88166->aw_pa->dev, "fw update failed\n"); return; } =20 - if (sync_start =3D=3D AW88166_SYNC_START) + if (sync_start =3D=3D AW_SYNC_START) aw88166_start_pa(aw88166); else queue_delayed_work(system_wq, @@ -1331,38 +925,44 @@ static int aw_dev_check_sysint(struct aw_device *aw_= dev) static int aw88166_stop(struct aw_device *aw_dev) { struct aw_sec_data_desc *dsp_cfg =3D - &aw_dev->prof_info.prof_desc[aw_dev->prof_cur].sec_desc[AW88395_DATA_TYP= E_DSP_CFG]; + &aw_dev->prof_info.prof_desc[aw_dev->prof_cur].sec_desc[AW_DATA_TYPE_DSP= _CFG]; struct aw_sec_data_desc *dsp_fw =3D - &aw_dev->prof_info.prof_desc[aw_dev->prof_cur].sec_desc[AW88395_DATA_TYP= E_DSP_FW]; + &aw_dev->prof_info.prof_desc[aw_dev->prof_cur].sec_desc[AW_DATA_TYPE_DSP= _FW]; int int_st; =20 - if (aw_dev->status =3D=3D AW88166_DEV_PW_OFF) { + if (aw_dev->status =3D=3D AW_DEV_PW_OFF) { dev_dbg(aw_dev->dev, "already power off"); return 0; } =20 - aw_dev->status =3D AW88166_DEV_PW_OFF; + aw_dev->status =3D AW_DEV_PW_OFF; =20 aw88166_dev_mute(aw_dev, true); - usleep_range(AW88166_4000_US, AW88166_4000_US + 100); + usleep_range(AW_4000_US, AW_4000_US + 100); =20 - aw_dev_i2s_tx_enable(aw_dev, false); - usleep_range(AW88166_1000_US, AW88166_1000_US + 100); + regmap_update_bits(aw_dev->regmap, AW88166_I2SCTRL3_REG, + ~AW88166_I2STXEN_MASK, AW88166_I2STXEN_DISABLE_VALUE); + usleep_range(AW_1000_US, AW_1000_US + 100); =20 int_st =3D aw_dev_check_sysint(aw_dev); =20 - aw_dev_dsp_enable(aw_dev, false); + regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, + ~AW88166_DSPBY_MASK, AW88166_DSPBY_BYPASS_VALUE); =20 - aw_dev_amppd(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, + ~AW88166_AMPPD_MASK, AW88166_AMPPD_POWER_DOWN_VALUE); =20 if (int_st) { - aw_dev_select_memclk(aw_dev, AW88166_DEV_MEMCLK_OSC); - aw_dev_dsp_update_fw(aw_dev, dsp_fw->data, dsp_fw->len); - aw_dev_dsp_update_cfg(aw_dev, dsp_cfg->data, dsp_cfg->len); - aw_dev_select_memclk(aw_dev, AW88166_DEV_MEMCLK_PLL); + regmap_update_bits(aw_dev->regmap, AW88166_DBGCTRL_REG, ~AW88166_MEM_CLK= SEL_MASK, + AW88166_MEM_CLKSEL_OSCCLK_VALUE); + aw_dev_dsp_update_fw(aw_dev, dsp_fw->data, dsp_fw->len, dsp_fw->addr); + aw_dev_dsp_update_cfg(aw_dev, dsp_cfg->data, dsp_cfg->len, dsp_cfg->addr= ); + regmap_update_bits(aw_dev->regmap, AW88166_DBGCTRL_REG, ~AW88166_MEM_CLK= SEL_MASK, + AW88166_MEM_CLKSEL_DAPHCLK_VALUE); } =20 - aw_dev_pwd(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88166_SYSCTRL_REG, + ~AW88166_PWDN_MASK, AW88166_PWDN_POWER_DOWN_VALUE); =20 return 0; } @@ -1457,22 +1057,6 @@ static int aw88166_set_fade_out_time(struct snd_kcon= trol *kcontrol, return 0; } =20 -static int aw88166_dev_set_profile_index(struct aw_device *aw_dev, int ind= ex) -{ - /* check the index whether is valid */ - if ((index >=3D aw_dev->prof_info.count) || (index < 0)) - return -EINVAL; - /* check the index whether change */ - if (aw_dev->prof_index =3D=3D index) - return -EINVAL; - - aw_dev->prof_index =3D index; - dev_dbg(aw_dev->dev, "set prof[%s]", - aw_dev->prof_info.prof_name_list[aw_dev->prof_info.prof_desc[index].id]); - - return 0; -} - static int aw88166_profile_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -1497,7 +1081,7 @@ static int aw88166_profile_info(struct snd_kcontrol *= kcontrol, =20 count =3D uinfo->value.enumerated.item; =20 - ret =3D aw88166_dev_get_prof_name(aw88166->aw_pa, count, &prof_name); + ret =3D aw_dev_get_prof_name(aw88166->aw_pa, count, &prof_name); if (ret) { strscpy(uinfo->value.enumerated.name, "null"); return 0; @@ -1527,7 +1111,7 @@ static int aw88166_profile_set(struct snd_kcontrol *k= control, int ret; =20 mutex_lock(&aw88166->lock); - ret =3D aw88166_dev_set_profile_index(aw88166->aw_pa, ucontrol->value.int= eger.value[0]); + ret =3D aw_dev_set_profile_index(aw88166->aw_pa, ucontrol->value.integer.= value[0]); if (ret) { dev_dbg(codec->dev, "profile index does not change"); mutex_unlock(&aw88166->lock); @@ -1536,7 +1120,7 @@ static int aw88166_profile_set(struct snd_kcontrol *k= control, =20 if (aw88166->aw_pa->status) { aw88166_stop(aw88166->aw_pa); - aw88166_start(aw88166, AW88166_SYNC_START); + aw88166_start(aw88166, AW_SYNC_START); } =20 mutex_unlock(&aw88166->lock); @@ -1572,7 +1156,7 @@ static int aw88166_volume_set(struct snd_kcontrol *kc= ontrol, =20 if (vol_desc->ctl_volume !=3D value) { vol_desc->ctl_volume =3D value; - aw_dev_set_volume(aw88166->aw_pa, vol_desc->ctl_volume); + aw88166_set_volume(aw88166->aw_pa, vol_desc->ctl_volume); =20 return 1; } @@ -1646,86 +1230,6 @@ static int aw88166_re_set(struct snd_kcontrol *kcont= rol, return 0; } =20 -static int aw88166_dev_init(struct aw88166 *aw88166, struct aw_container *= aw_cfg) -{ - struct aw_device *aw_dev =3D aw88166->aw_pa; - int ret; - - ret =3D aw88395_dev_cfg_load(aw_dev, aw_cfg); - if (ret) { - dev_err(aw_dev->dev, "aw_dev acf parse failed\n"); - return -EINVAL; - } - aw_dev->fade_in_time =3D AW88166_1000_US / 10; - aw_dev->fade_out_time =3D AW88166_1000_US >> 1; - aw_dev->prof_cur =3D aw_dev->prof_info.prof_desc[0].id; - aw_dev->prof_index =3D aw_dev->prof_info.prof_desc[0].id; - - ret =3D aw88166_dev_fw_update(aw88166, AW88166_FORCE_UPDATE_ON, AW88166_D= SP_FW_UPDATE_ON); - if (ret) { - dev_err(aw_dev->dev, "fw update failed ret =3D %d\n", ret); - return ret; - } - - aw88166_dev_mute(aw_dev, true); - - /* close tx feedback */ - aw_dev_i2s_tx_enable(aw_dev, false); - usleep_range(AW88166_1000_US, AW88166_1000_US + 100); - - /* enable amppd */ - aw_dev_amppd(aw_dev, true); - - /* close dsp */ - aw_dev_dsp_enable(aw_dev, false); - /* set power down */ - aw_dev_pwd(aw_dev, true); - - return 0; -} - -static int aw88166_request_firmware_file(struct aw88166 *aw88166) -{ - const struct firmware *cont =3D NULL; - int ret; - - aw88166->aw_pa->fw_status =3D AW88166_DEV_FW_FAILED; - - ret =3D request_firmware(&cont, AW88166_ACF_FILE, aw88166->aw_pa->dev); - if (ret) { - dev_err(aw88166->aw_pa->dev, "request [%s] failed!\n", AW88166_ACF_FILE); - return ret; - } - - dev_dbg(aw88166->aw_pa->dev, "loaded %s - size: %zu\n", - AW88166_ACF_FILE, cont ? cont->size : 0); - - aw88166->aw_cfg =3D devm_kzalloc(aw88166->aw_pa->dev, - struct_size(aw88166->aw_cfg, data, cont->size), GFP_KERNEL); - if (!aw88166->aw_cfg) { - release_firmware(cont); - return -ENOMEM; - } - aw88166->aw_cfg->len =3D (int)cont->size; - memcpy(aw88166->aw_cfg->data, cont->data, cont->size); - release_firmware(cont); - - ret =3D aw88395_dev_load_acf_check(aw88166->aw_pa, aw88166->aw_cfg); - if (ret) { - dev_err(aw88166->aw_pa->dev, "load [%s] failed!\n", AW88166_ACF_FILE); - return ret; - } - - mutex_lock(&aw88166->lock); - /* aw device init */ - ret =3D aw88166_dev_init(aw88166, aw88166->aw_cfg); - if (ret) - dev_err(aw88166->aw_pa->dev, "dev init failed\n"); - mutex_unlock(&aw88166->lock); - - return ret; -} - static const struct snd_kcontrol_new aw88166_controls[] =3D { SOC_SINGLE_EXT("PCM Playback Volume", AW88166_SYSCTRL2_REG, 6, AW88166_MUTE_VOL, 0, aw88166_volume_get, @@ -1738,7 +1242,7 @@ static const struct snd_kcontrol_new aw88166_controls= [] =3D { aw88166_get_fade_out_time, aw88166_set_fade_out_time), SOC_SINGLE_EXT("Calib", 0, 0, AW88166_CALI_RE_MAX, 0, aw88166_re_get, aw88166_re_set), - AW88166_PROFILE_EXT("AW88166 Profile Set", aw88166_profile_info, + AW_PROFILE_EXT("AW88166 Profile Set", aw88166_profile_info, aw88166_profile_get, aw88166_profile_set), }; =20 @@ -1751,7 +1255,7 @@ static int aw88166_playback_event(struct snd_soc_dapm= _widget *w, mutex_lock(&aw88166->lock); switch (event) { case SND_SOC_DAPM_PRE_PMU: - aw88166_start(aw88166, AW88166_ASYNC_START); + aw88166_start(aw88166, AW_ASYNC_START); break; case SND_SOC_DAPM_POST_PMD: aw88166_stop(aw88166->aw_pa); @@ -1788,9 +1292,15 @@ static int aw88166_codec_probe(struct snd_soc_compon= ent *component) =20 INIT_DELAYED_WORK(&aw88166->start_work, aw88166_startup_work); =20 - ret =3D aw88166_request_firmware_file(aw88166); - if (ret) + ret =3D aw_dev_request_firmware_file(aw88166->aw_pa, AW88166_ACF_FILE); + if (ret) { dev_err(aw88166->aw_pa->dev, "%s failed\n", __func__); + return ret; + } + + ret =3D aw88166_dev_fw_update(aw88166, AW_FORCE_UPDATE_ON, AW_DSP_FW_UPDA= TE_ON); + if (ret) + dev_err(aw88166->aw_pa->dev, "fw update failed ret =3D %d\n", ret); =20 return ret; } @@ -1813,65 +1323,6 @@ static const struct snd_soc_component_driver soc_cod= ec_dev_aw88166 =3D { .num_controls =3D ARRAY_SIZE(aw88166_controls), }; =20 -static void aw88166_hw_reset(struct aw88166 *aw88166) -{ - if (aw88166->reset_gpio) { - gpiod_set_value_cansleep(aw88166->reset_gpio, 1); - usleep_range(AW88166_1000_US, AW88166_1000_US + 10); - gpiod_set_value_cansleep(aw88166->reset_gpio, 0); - usleep_range(AW88166_1000_US, AW88166_1000_US + 10); - } -} - -static void aw88166_parse_channel_dt(struct aw88166 *aw88166) -{ - struct aw_device *aw_dev =3D aw88166->aw_pa; - struct device_node *np =3D aw_dev->dev->of_node; - u32 channel_value; - - of_property_read_u32(np, "awinic,audio-channel", &channel_value); - aw_dev->channel =3D channel_value; - aw88166->phase_sync =3D of_property_read_bool(np, "awinic,sync-flag"); -} - -static int aw88166_init(struct aw88166 *aw88166, struct i2c_client *i2c, s= truct regmap *regmap) -{ - struct aw_device *aw_dev; - unsigned int chip_id; - int ret; - - ret =3D regmap_read(regmap, AW88166_ID_REG, &chip_id); - if (ret) { - dev_err(&i2c->dev, "%s read chipid error. ret =3D %d\n", __func__, ret); - return ret; - } - - aw_dev =3D devm_kzalloc(&i2c->dev, sizeof(*aw_dev), GFP_KERNEL); - if (!aw_dev) - return -ENOMEM; - aw88166->aw_pa =3D aw_dev; - - aw_dev->i2c =3D i2c; - aw_dev->dev =3D &i2c->dev; - aw_dev->regmap =3D regmap; - mutex_init(&aw_dev->dsp_lock); - - aw_dev->chip_id =3D chip_id; - aw_dev->acf =3D NULL; - aw_dev->prof_info.prof_desc =3D NULL; - aw_dev->prof_info.count =3D 0; - aw_dev->prof_info.prof_type =3D AW88395_DEV_NONE_TYPE_ID; - aw_dev->channel =3D AW88166_DEV_DEFAULT_CH; - aw_dev->fw_status =3D AW88166_DEV_FW_FAILED; - - aw_dev->fade_step =3D AW88166_VOLUME_STEP_DB; - aw_dev->volume_desc.ctl_volume =3D AW88166_VOL_DEFAULT_VALUE; - - aw88166_parse_channel_dt(aw88166); - - return 0; -} - static int aw88166_i2c_probe(struct i2c_client *i2c) { struct aw88166 *aw88166; @@ -1888,11 +1339,15 @@ static int aw88166_i2c_probe(struct i2c_client *i2c) =20 i2c_set_clientdata(i2c, aw88166); =20 - aw88166->reset_gpio =3D devm_gpiod_get_optional(&i2c->dev, "reset", GPIOD= _OUT_LOW); - if (IS_ERR(aw88166->reset_gpio)) + aw88166->aw_pa =3D devm_kzalloc(&i2c->dev, sizeof(struct aw_device), GFP_= KERNEL); + if (!aw88166->aw_pa) + return -ENOMEM; + + aw88166->aw_pa->reset_gpio =3D devm_gpiod_get_optional(&i2c->dev, "reset"= , GPIOD_OUT_LOW); + if (IS_ERR(aw88166->aw_pa->reset_gpio)) return dev_err_probe(&i2c->dev, PTR_ERR(aw88166->reset_gpio), "reset gpio not defined\n"); - aw88166_hw_reset(aw88166); + aw_hw_reset(aw88166->aw_pa); =20 aw88166->regmap =3D devm_regmap_init_i2c(i2c, &aw88166_remap_config); if (IS_ERR(aw88166->regmap)) @@ -1900,7 +1355,7 @@ static int aw88166_i2c_probe(struct i2c_client *i2c) "failed to init regmap\n"); =20 /* aw pa init */ - ret =3D aw88166_init(aw88166, i2c, aw88166->regmap); + ret =3D aw_dev_init(aw88166->aw_pa, i2c, aw88166->regmap); if (ret) return ret; =20 diff --git a/sound/soc/codecs/aw88166.h b/sound/soc/codecs/aw88166.h index 3a53ba0ac625..3b90fdaf76b7 100644 --- a/sound/soc/codecs/aw88166.h +++ b/sound/soc/codecs/aw88166.h @@ -453,8 +453,6 @@ #define AW88166_DEV_SYSST_CHECK_MAX (10) #define AW88166_START_RETRIES (5) #define AW88166_START_WORK_DELAY_MS (0) -#define FADE_TIME_MAX 100000 -#define FADE_TIME_MIN 0 #define AW88166_CHIP_ID (0x2066) #define AW88166_I2C_NAME "aw88166" #define AW88166_ACF_FILE "aw88166_acf.bin" @@ -465,67 +463,11 @@ SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S32_LE) =20 -#define AW88166_PROFILE_EXT(xname, profile_info, profile_get, profile_set)= \ -{ \ - .iface =3D SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name =3D xname, \ - .info =3D profile_info, \ - .get =3D profile_get, \ - .put =3D profile_set, \ -} - enum { AW_EF_AND_CHECK =3D 0, AW_EF_OR_CHECK, }; =20 -enum { - AW88166_DSP_FW_UPDATE_OFF =3D 0, - AW88166_DSP_FW_UPDATE_ON =3D 1, -}; - -enum { - AW88166_FORCE_UPDATE_OFF =3D 0, - AW88166_FORCE_UPDATE_ON =3D 1, -}; - -enum { - AW88166_1000_US =3D 1000, - AW88166_2000_US =3D 2000, - AW88166_3000_US =3D 3000, - AW88166_4000_US =3D 4000, -}; - -enum AW88166_DEV_STATUS { - AW88166_DEV_PW_OFF =3D 0, - AW88166_DEV_PW_ON, -}; - -enum AW88166_DEV_FW_STATUS { - AW88166_DEV_FW_FAILED =3D 0, - AW88166_DEV_FW_OK, -}; - -enum AW88166_DEV_MEMCLK { - AW88166_DEV_MEMCLK_OSC =3D 0, - AW88166_DEV_MEMCLK_PLL =3D 1, -}; - -enum AW88166_DEV_DSP_CFG { - AW88166_DEV_DSP_WORK =3D 0, - AW88166_DEV_DSP_BYPASS =3D 1, -}; - -enum { - AW88166_DSP_16_DATA =3D 0, - AW88166_DSP_32_DATA =3D 1, -}; - -enum { - AW88166_SYNC_START =3D 0, - AW88166_ASYNC_START, -}; - enum { AW88166_RECORD_SEC_DATA =3D 0, AW88166_RECOVERY_SEC_DATA =3D 1, --=20 2.47.0 From nobody Wed Oct 1 22:31:21 2025 Received: from out198-7.us.a.mail.aliyun.com (out198-7.us.a.mail.aliyun.com [47.90.198.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4AD612EFD93; Fri, 26 Sep 2025 10:21:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=47.90.198.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758882071; cv=none; b=kr8gcSV6rF546kuLlnwIsChxtif1ZxSHIAmpZBeDhOtdQVsM+OG36GOP3RlmEtHFbTw17qMB2ffcbeTBAdzHE3PWcPodRPkDUOe1JkuwVPLL+2vh7BI5ESNLj2aev735Pi8qzXa6WbNzPvyDsoZ/BnkWqHTWtMP6YZLFEFMXOxA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758882071; c=relaxed/simple; bh=/lqU8p1Kqbv85cHsipPyuFnqWhOF8j4KHe/KhVhwa+4=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=T+qkRU7yLgtG/C21pTb8OeBPsv96mKP7gnpnPxEuQUMytP2AkMJVMojNMfVghKBxheNPFkIdqiuFVqDXStWuEoilsAQf0KWVMrHwuTy3HU/vp4SMrZxERXAQTiBfEJKDLEsbBL+mooX9/hpOo2UOAusbHmaU9B5X2xeq+8fqWhs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=awinic.com; spf=pass smtp.mailfrom=awinic.com; dkim=pass (2048-bit key) header.d=awinic.com header.i=@awinic.com header.b=lLwq9r3M; arc=none smtp.client-ip=47.90.198.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=awinic.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=awinic.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=awinic.com header.i=@awinic.com header.b="lLwq9r3M" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=awinic.com; s=default; t=1758882055; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=8T5et6u9khsy7lcDi/wk+p4Nfv5cWPBYYQbejNK+v/0=; b=lLwq9r3M73tJBxcUJqymL1zY1++BpLgmOfqdJFvKTae8MFkv3bd7VBvkh2SWisWyMstuMYFAIzMjG44XDoxO5ZP4pvMFy6gbp5SCtQTgeavYX5EqAsVWknEvRHGAwPgnDEorB7yz3rLNDzUppJlZOp1B8Qys1I/N8XAoWnGmkT0vuK/tHpyyJqqN6l89i0nhI9YZCB7pmpxGT7JxydCL6z859kGdlGBQuSZZA7/q6oNCEf+nRDD/bpbAx3okq+KMZz+RCzzpCLAfD8AZWCMfZsOSBxAgEss2pVDoWLT5it4HiuOvD4nqgt0fo6tzwJZMCs1GUGFreO2pouNQEHcueQ== Received: from ubuntu-VirtualBox..(mailfrom:wangweidong.a@awinic.com fp:SMTPD_---.ensjP48_1758882052 cluster:ay29) by smtp.aliyun-inc.com; Fri, 26 Sep 2025 18:20:53 +0800 From: wangweidong.a@awinic.com To: lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, wangweidong.a@awinic.com, cy_huang@richtek.com, ivprusov@salutedevices.com, zhoubinbin@loongson.cn, zhangyi@everest-semi.com, jack.yu@realtek.com, shenghao-ding@ti.com, rf@opensource.cirrus.com, git@apitzsch.eu, nuno.sa@analog.com, colin.i.king@gmail.com, thorsten.blum@linux.dev, yesanishhere@gmail.com, ebiggers@google.com, ardb@kernel.org, zhujun2@cmss.chinamobile.com, linux-kernel@vger.kernel.org, linux-sound@vger.kernel.org Subject: [PATCH V1 6/7] ASoC: codecs: Rework the aw88261 driver Date: Fri, 26 Sep 2025 18:20:36 +0800 Message-ID: <20250926102037.27697-7-wangweidong.a@awinic.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20250926102037.27697-1-wangweidong.a@awinic.com> References: <20250926102037.27697-1-wangweidong.a@awinic.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Weidong Wang Modify the interface for calling the aw88261 driver to adapt it for aw-common-device.c and aw-common-firmware.c Signed-off-by: Weidong Wang --- sound/soc/codecs/aw88261.c | 427 ++++++++----------------------------- sound/soc/codecs/aw88261.h | 52 ----- 2 files changed, 93 insertions(+), 386 deletions(-) diff --git a/sound/soc/codecs/aw88261.c b/sound/soc/codecs/aw88261.c index de11ae8dd9d9..4f11d1b27a44 100644 --- a/sound/soc/codecs/aw88261.c +++ b/sound/soc/codecs/aw88261.c @@ -13,8 +13,22 @@ #include #include #include "aw88261.h" -#include "aw88395/aw88395_data_type.h" -#include "aw88395/aw88395_device.h" +#include "aw-common-device.h" +#include "aw-common-firmware.h" + +struct aw88261 { + struct aw_device *aw_pa; + struct mutex lock; + struct delayed_work start_work; + struct regmap *regmap; + + int efuse_check; + int frcset_en; + unsigned int mute_st; + unsigned int amppd_st; + + bool phase_sync; +}; =20 static const struct regmap_config aw88261_remap_config =3D { .val_bits =3D 16, @@ -24,7 +38,7 @@ static const struct regmap_config aw88261_remap_config = =3D { .val_format_endian =3D REGMAP_ENDIAN_BIG, }; =20 -static void aw88261_dev_set_volume(struct aw_device *aw_dev, unsigned int = value) +static void aw88261_set_volume(struct aw_device *aw_dev, unsigned int valu= e) { struct aw_volume_desc *vol_desc =3D &aw_dev->volume_desc; unsigned int real_value, volume; @@ -42,105 +56,19 @@ static void aw88261_dev_set_volume(struct aw_device *a= w_dev, unsigned int value) regmap_write(aw_dev->regmap, AW88261_SYSCTRL2_REG, real_value); } =20 -static void aw88261_dev_fade_in(struct aw_device *aw_dev) -{ - struct aw_volume_desc *desc =3D &aw_dev->volume_desc; - int fade_in_vol =3D desc->ctl_volume; - int fade_step =3D aw_dev->fade_step; - int i; - - if (fade_step =3D=3D 0 || aw_dev->fade_in_time =3D=3D 0) { - aw88261_dev_set_volume(aw_dev, fade_in_vol); - return; - } - - for (i =3D AW88261_MUTE_VOL; i >=3D fade_in_vol; i -=3D fade_step) { - aw88261_dev_set_volume(aw_dev, i); - usleep_range(aw_dev->fade_in_time, - aw_dev->fade_in_time + 10); - } - - if (i !=3D fade_in_vol) - aw88261_dev_set_volume(aw_dev, fade_in_vol); -} - -static void aw88261_dev_fade_out(struct aw_device *aw_dev) -{ - struct aw_volume_desc *desc =3D &aw_dev->volume_desc; - int fade_step =3D aw_dev->fade_step; - int i; - - if (fade_step =3D=3D 0 || aw_dev->fade_out_time =3D=3D 0) { - aw88261_dev_set_volume(aw_dev, AW88261_MUTE_VOL); - return; - } - - for (i =3D desc->ctl_volume; i <=3D AW88261_MUTE_VOL; i +=3D fade_step) { - aw88261_dev_set_volume(aw_dev, i); - usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10); - } - - if (i !=3D AW88261_MUTE_VOL) { - aw88261_dev_set_volume(aw_dev, AW88261_MUTE_VOL); - usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10); - } -} - -static void aw88261_dev_i2s_tx_enable(struct aw_device *aw_dev, bool flag) -{ - if (flag) - regmap_update_bits(aw_dev->regmap, AW88261_I2SCFG1_REG, - ~AW88261_I2STXEN_MASK, AW88261_I2STXEN_ENABLE_VALUE); - else - regmap_update_bits(aw_dev->regmap, AW88261_I2SCFG1_REG, - ~AW88261_I2STXEN_MASK, AW88261_I2STXEN_DISABLE_VALUE); -} - -static void aw88261_dev_pwd(struct aw_device *aw_dev, bool pwd) -{ - if (pwd) - regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG, - ~AW88261_PWDN_MASK, AW88261_PWDN_POWER_DOWN_VALUE); - else - regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG, - ~AW88261_PWDN_MASK, AW88261_PWDN_WORKING_VALUE); -} - -static void aw88261_dev_amppd(struct aw_device *aw_dev, bool amppd) -{ - if (amppd) - regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG, - ~AW88261_AMPPD_MASK, AW88261_AMPPD_POWER_DOWN_VALUE); - else - regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG, - ~AW88261_AMPPD_MASK, AW88261_AMPPD_WORKING_VALUE); -} - static void aw88261_dev_mute(struct aw_device *aw_dev, bool is_mute) { if (is_mute) { - aw88261_dev_fade_out(aw_dev); + aw_dev_fade_out(aw_dev, aw88261_set_volume); regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG, ~AW88261_HMUTE_MASK, AW88261_HMUTE_ENABLE_VALUE); } else { regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG, ~AW88261_HMUTE_MASK, AW88261_HMUTE_DISABLE_VALUE); - aw88261_dev_fade_in(aw_dev); + aw_dev_fade_in(aw_dev, aw88261_set_volume); } } =20 -static void aw88261_dev_clear_int_status(struct aw_device *aw_dev) -{ - unsigned int int_status; - - /* read int status and clear */ - regmap_read(aw_dev->regmap, AW88261_SYSINT_REG, &int_status); - /* make sure int status is clear */ - regmap_read(aw_dev->regmap, AW88261_SYSINT_REG, &int_status); - - dev_dbg(aw_dev->dev, "read interrupt reg =3D 0x%04x", int_status); -} - static int aw88261_dev_get_iis_status(struct aw_device *aw_dev) { unsigned int reg_val; @@ -165,7 +93,7 @@ static int aw88261_dev_check_mode1_pll(struct aw_device = *aw_dev) ret =3D aw88261_dev_get_iis_status(aw_dev); if (ret) { dev_err(aw_dev->dev, "mode1 iis signal check error"); - usleep_range(AW88261_2000_US, AW88261_2000_US + 10); + usleep_range(AW_2000_US, AW_2000_US + 10); } else { return ret; } @@ -199,7 +127,7 @@ static int aw88261_dev_check_mode2_pll(struct aw_device= *aw_dev) ret =3D aw88261_dev_get_iis_status(aw_dev); if (ret) { dev_err(aw_dev->dev, "mode2 iis signal check error"); - usleep_range(AW88261_2000_US, AW88261_2000_US + 10); + usleep_range(AW_2000_US, AW_2000_US + 10); } else { break; } @@ -209,12 +137,12 @@ static int aw88261_dev_check_mode2_pll(struct aw_devi= ce *aw_dev) ret =3D regmap_update_bits(aw_dev->regmap, AW88261_PLLCTRL1_REG, ~AW88261_CCO_MUX_MASK, AW88261_CCO_MUX_BYPASS_VALUE); if (ret =3D=3D 0) { - usleep_range(AW88261_2000_US, AW88261_2000_US + 10); + usleep_range(AW_2000_US, AW_2000_US + 10); for (i =3D 0; i < AW88261_DEV_SYSST_CHECK_MAX; i++) { ret =3D aw88261_dev_check_mode1_pll(aw_dev); if (ret) { dev_err(aw_dev->dev, "mode2 switch to mode1, iis signal check error"); - usleep_range(AW88261_2000_US, AW88261_2000_US + 10); + usleep_range(AW_2000_US, AW_2000_US + 10); } else { break; } @@ -257,7 +185,7 @@ static int aw88261_dev_check_sysst(struct aw_device *aw= _dev) if (check_val !=3D AW88261_BIT_SYSST_CHECK) { dev_err(aw_dev->dev, "check sysst fail, reg_val=3D0x%04x, check:0x%x", reg_val, AW88261_BIT_SYSST_CHECK); - usleep_range(AW88261_2000_US, AW88261_2000_US + 10); + usleep_range(AW_2000_US, AW_2000_US + 10); } else { return 0; } @@ -266,18 +194,6 @@ static int aw88261_dev_check_sysst(struct aw_device *a= w_dev) return -EPERM; } =20 -static void aw88261_dev_uls_hmute(struct aw_device *aw_dev, bool uls_hmute) -{ - if (uls_hmute) - regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG, - ~AW88261_ULS_HMUTE_MASK, - AW88261_ULS_HMUTE_ENABLE_VALUE); - else - regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG, - ~AW88261_ULS_HMUTE_MASK, - AW88261_ULS_HMUTE_DISABLE_VALUE); -} - static void aw88261_reg_force_set(struct aw88261 *aw88261) { if (aw88261->frcset_en =3D=3D AW88261_FRCSET_ENABLE) { @@ -471,43 +387,11 @@ static int aw88261_dev_reg_update(struct aw88261 *aw8= 8261, vol_desc->ctl_volume =3D 0; =20 /* keep min volume */ - aw88261_dev_set_volume(aw_dev, vol_desc->mute_volume); + aw88261_set_volume(aw_dev, vol_desc->mute_volume); =20 return ret; } =20 -static int aw88261_dev_get_prof_name(struct aw_device *aw_dev, int index, = char **prof_name) -{ - struct aw_prof_info *prof_info =3D &aw_dev->prof_info; - struct aw_prof_desc *prof_desc; - - if ((index >=3D aw_dev->prof_info.count) || (index < 0)) { - dev_err(aw_dev->dev, "index[%d] overflow count[%d]", - index, aw_dev->prof_info.count); - return -EINVAL; - } - - prof_desc =3D &aw_dev->prof_info.prof_desc[index]; - - *prof_name =3D prof_info->prof_name_list[prof_desc->id]; - - return 0; -} - -static int aw88261_dev_get_prof_data(struct aw_device *aw_dev, int index, - struct aw_prof_desc **prof_desc) -{ - if ((index >=3D aw_dev->prof_info.count) || (index < 0)) { - dev_err(aw_dev->dev, "%s: index[%d] overflow count[%d]\n", - __func__, index, aw_dev->prof_info.count); - return -EINVAL; - } - - *prof_desc =3D &aw_dev->prof_info.prof_desc[index]; - - return 0; -} - static int aw88261_dev_fw_update(struct aw88261 *aw88261) { struct aw_device *aw_dev =3D aw88261->aw_pa; @@ -516,7 +400,7 @@ static int aw88261_dev_fw_update(struct aw88261 *aw8826= 1) char *prof_name; int ret; =20 - ret =3D aw88261_dev_get_prof_name(aw_dev, aw_dev->prof_index, &prof_name); + ret =3D aw_dev_get_prof_name(aw_dev, aw_dev->prof_index, &prof_name); if (ret) { dev_err(aw_dev->dev, "get prof name failed"); return -EINVAL; @@ -524,14 +408,14 @@ static int aw88261_dev_fw_update(struct aw88261 *aw88= 261) =20 dev_dbg(aw_dev->dev, "start update %s", prof_name); =20 - ret =3D aw88261_dev_get_prof_data(aw_dev, aw_dev->prof_index, &prof_index= _desc); + ret =3D aw_dev_get_prof_data(aw_dev, aw_dev->prof_index, &prof_index_desc= ); if (ret) return ret; =20 /* update reg */ sec_desc =3D prof_index_desc->sec_desc; - ret =3D aw88261_dev_reg_update(aw88261, sec_desc[AW88395_DATA_TYPE_REG].d= ata, - sec_desc[AW88395_DATA_TYPE_REG].len); + ret =3D aw88261_dev_reg_update(aw88261, sec_desc[AW_DATA_TYPE_REG].data, + sec_desc[AW_DATA_TYPE_REG].len); if (ret) { dev_err(aw_dev->dev, "update reg failed"); return ret; @@ -547,14 +431,15 @@ static int aw88261_dev_start(struct aw88261 *aw88261) struct aw_device *aw_dev =3D aw88261->aw_pa; int ret; =20 - if (aw_dev->status =3D=3D AW88261_DEV_PW_ON) { + if (aw_dev->status =3D=3D AW_DEV_PW_ON) { dev_info(aw_dev->dev, "already power on"); return 0; } =20 /* power on */ - aw88261_dev_pwd(aw_dev, false); - usleep_range(AW88261_2000_US, AW88261_2000_US + 10); + regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG, + ~AW88261_PWDN_MASK, AW88261_PWDN_WORKING_VALUE); + usleep_range(AW_2000_US, AW_2000_US + 10); =20 ret =3D aw88261_dev_check_syspll(aw_dev); if (ret) { @@ -563,8 +448,9 @@ static int aw88261_dev_start(struct aw88261 *aw88261) } =20 /* amppd on */ - aw88261_dev_amppd(aw_dev, false); - usleep_range(AW88261_1000_US, AW88261_1000_US + 50); + regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG, + ~AW88261_AMPPD_MASK, AW88261_AMPPD_WORKING_VALUE); + usleep_range(AW_1000_US, AW_1000_US + 50); =20 /* check i2s status */ ret =3D aw88261_dev_check_sysst(aw_dev); @@ -574,62 +460,72 @@ static int aw88261_dev_start(struct aw88261 *aw88261) } =20 /* enable tx feedback */ - aw88261_dev_i2s_tx_enable(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88261_I2SCFG1_REG, + ~AW88261_I2STXEN_MASK, AW88261_I2STXEN_ENABLE_VALUE); =20 if (aw88261->amppd_st) - aw88261_dev_amppd(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG, + ~AW88261_AMPPD_MASK, AW88261_AMPPD_POWER_DOWN_VALUE); =20 aw88261_reg_force_set(aw88261); =20 /* close uls mute */ - aw88261_dev_uls_hmute(aw_dev, false); + regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG, + ~AW88261_ULS_HMUTE_MASK, AW88261_ULS_HMUTE_DISABLE_VALUE); =20 /* close mute */ if (!aw88261->mute_st) aw88261_dev_mute(aw_dev, false); =20 /* clear inturrupt */ - aw88261_dev_clear_int_status(aw_dev); - aw_dev->status =3D AW88261_DEV_PW_ON; + aw_dev_clear_int_status(aw_dev); + aw_dev->status =3D AW_DEV_PW_ON; =20 return 0; =20 sysst_check_fail: - aw88261_dev_i2s_tx_enable(aw_dev, false); - aw88261_dev_clear_int_status(aw_dev); - aw88261_dev_amppd(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88261_I2SCFG1_REG, + ~AW88261_I2STXEN_MASK, AW88261_I2STXEN_DISABLE_VALUE); + aw_dev_clear_int_status(aw_dev); + regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG, + ~AW88261_AMPPD_MASK, AW88261_AMPPD_POWER_DOWN_VALUE); pll_check_fail: - aw88261_dev_pwd(aw_dev, true); - aw_dev->status =3D AW88261_DEV_PW_OFF; + regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG, + ~AW88261_PWDN_MASK, AW88261_PWDN_POWER_DOWN_VALUE); + aw_dev->status =3D AW_DEV_PW_OFF; =20 return ret; } =20 static int aw88261_dev_stop(struct aw_device *aw_dev) { - if (aw_dev->status =3D=3D AW88261_DEV_PW_OFF) { + if (aw_dev->status =3D=3D AW_DEV_PW_OFF) { dev_info(aw_dev->dev, "already power off"); return 0; } =20 - aw_dev->status =3D AW88261_DEV_PW_OFF; + aw_dev->status =3D AW_DEV_PW_OFF; =20 /* clear inturrupt */ - aw88261_dev_clear_int_status(aw_dev); + aw_dev_clear_int_status(aw_dev); =20 - aw88261_dev_uls_hmute(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG, + ~AW88261_ULS_HMUTE_MASK, AW88261_ULS_HMUTE_ENABLE_VALUE); /* set mute */ aw88261_dev_mute(aw_dev, true); =20 /* close tx feedback */ - aw88261_dev_i2s_tx_enable(aw_dev, false); - usleep_range(AW88261_1000_US, AW88261_1000_US + 100); + regmap_update_bits(aw_dev->regmap, AW88261_I2SCFG1_REG, + ~AW88261_I2STXEN_MASK, AW88261_I2STXEN_DISABLE_VALUE); + usleep_range(AW_1000_US, AW_1000_US + 100); =20 /* enable amppd */ - aw88261_dev_amppd(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG, + ~AW88261_AMPPD_MASK, AW88261_AMPPD_POWER_DOWN_VALUE); =20 /* set power down */ - aw88261_dev_pwd(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88261_SYSCTRL_REG, + ~AW88261_PWDN_MASK, AW88261_PWDN_POWER_DOWN_VALUE); =20 return 0; } @@ -696,18 +592,17 @@ static void aw88261_startup_work(struct work_struct *= work) =20 static void aw88261_start(struct aw88261 *aw88261, bool sync_start) { - if (aw88261->aw_pa->fw_status !=3D AW88261_DEV_FW_OK) + if (aw88261->aw_pa->fw_status !=3D AW_DEV_FW_OK) return; =20 - if (aw88261->aw_pa->status =3D=3D AW88261_DEV_PW_ON) + if (aw88261->aw_pa->status =3D=3D AW_DEV_PW_ON) return; =20 - if (sync_start =3D=3D AW88261_SYNC_START) + if (sync_start =3D=3D AW_SYNC_START) aw88261_start_pa(aw88261); else queue_delayed_work(system_wq, - &aw88261->start_work, - AW88261_START_WORK_DELAY_MS); + &aw88261->start_work, AW88261_START_WORK_DELAY_MS); } =20 static struct snd_soc_dai_driver aw88261_dai[] =3D { @@ -838,7 +733,7 @@ static int aw88261_profile_info(struct snd_kcontrol *kc= ontrol, =20 count =3D uinfo->value.enumerated.item; =20 - ret =3D aw88261_dev_get_prof_name(aw88261->aw_pa, count, &prof_name); + ret =3D aw_dev_get_prof_name(aw88261->aw_pa, count, &prof_name); if (ret) { strscpy(uinfo->value.enumerated.name, "null"); return 0; @@ -878,7 +773,7 @@ static int aw88261_profile_set(struct snd_kcontrol *kco= ntrol, =20 if (aw88261->aw_pa->status) { aw88261_dev_stop(aw88261->aw_pa); - aw88261_start(aw88261, AW88261_SYNC_START); + aw88261_start(aw88261, AW_SYNC_START); } =20 mutex_unlock(&aw88261->lock); @@ -915,7 +810,7 @@ static int aw88261_volume_set(struct snd_kcontrol *kcon= trol, =20 if (vol_desc->ctl_volume !=3D value) { vol_desc->ctl_volume =3D value; - aw88261_dev_set_volume(aw88261->aw_pa, vol_desc->ctl_volume); + aw88261_set_volume(aw88261->aw_pa, vol_desc->ctl_volume); =20 return 1; } @@ -965,7 +860,7 @@ static const struct snd_kcontrol_new aw88261_controls[]= =3D { aw88261_get_fade_in_time, aw88261_set_fade_in_time), SOC_SINGLE_EXT("Volume Ramp Down Step", 0, 0, FADE_TIME_MAX, FADE_TIME_MI= N, aw88261_get_fade_out_time, aw88261_set_fade_out_time), - AW88261_PROFILE_EXT("Profile Set", aw88261_profile_info, + AW_PROFILE_EXT("Profile Set", aw88261_profile_info, aw88261_profile_get, aw88261_profile_set), }; =20 @@ -978,7 +873,7 @@ static int aw88261_playback_event(struct snd_soc_dapm_w= idget *w, mutex_lock(&aw88261->lock); switch (event) { case SND_SOC_DAPM_PRE_PMU: - aw88261_start(aw88261, AW88261_ASYNC_START); + aw88261_start(aw88261, AW_ASYNC_START); break; case SND_SOC_DAPM_POST_PMD: aw88261_dev_stop(aw88261->aw_pa); @@ -993,7 +888,7 @@ static int aw88261_playback_event(struct snd_soc_dapm_w= idget *w, =20 static const struct snd_soc_dapm_widget aw88261_dapm_widgets[] =3D { /* playback */ - SND_SOC_DAPM_AIF_IN_E("AIF_RX", "Speaker_Playback", 0, 0, 0, 0, + SND_SOC_DAPM_AIF_IN_E("AIF_RX", "Speaker_Playback", 0, SND_SOC_NOPM, 0, 0, aw88261_playback_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_OUTPUT("DAC Output"), @@ -1040,123 +935,31 @@ static int aw88261_frcset_check(struct aw88261 *aw8= 8261) return ret; } =20 -static int aw88261_dev_init(struct aw88261 *aw88261, struct aw_container *= aw_cfg) +static int aw88261_codec_probe(struct snd_soc_component *component) { - struct aw_device *aw_dev =3D aw88261->aw_pa; + struct aw88261 *aw88261 =3D snd_soc_component_get_drvdata(component); int ret; =20 - ret =3D aw88395_dev_cfg_load(aw_dev, aw_cfg); - if (ret) { - dev_err(aw_dev->dev, "aw_dev acf parse failed"); - return -EINVAL; - } + INIT_DELAYED_WORK(&aw88261->start_work, aw88261_startup_work); =20 - ret =3D regmap_write(aw_dev->regmap, AW88261_ID_REG, AW88261_SOFT_RESET_V= ALUE); + ret =3D aw_dev_request_firmware_file(aw88261->aw_pa, AW88261_ACF_FILE); if (ret) - return ret; + return dev_err_probe(aw88261->aw_pa->dev, ret, + "aw88261_request_firmware_file failed\n"); =20 - aw_dev->fade_in_time =3D AW88261_500_US; - aw_dev->fade_out_time =3D AW88261_500_US; - aw_dev->prof_cur =3D AW88261_INIT_PROFILE; - aw_dev->prof_index =3D AW88261_INIT_PROFILE; =20 ret =3D aw88261_dev_fw_update(aw88261); if (ret) { - dev_err(aw_dev->dev, "fw update failed ret =3D %d\n", ret); + dev_err(aw88261->aw_pa->dev, "fw update failed ret =3D %d\n", ret); return ret; } =20 ret =3D aw88261_frcset_check(aw88261); if (ret) { - dev_err(aw_dev->dev, "aw88261_frcset_check ret =3D %d\n", ret); - return ret; - } - - aw88261_dev_clear_int_status(aw_dev); - - aw88261_dev_uls_hmute(aw_dev, true); - - aw88261_dev_mute(aw_dev, true); - - aw88261_dev_i2s_tx_enable(aw_dev, false); - - usleep_range(AW88261_1000_US, AW88261_1000_US + 100); - - aw88261_dev_amppd(aw_dev, true); - - aw88261_dev_pwd(aw_dev, true); - - return 0; -} - -static int aw88261_request_firmware_file(struct aw88261 *aw88261) -{ - const struct firmware *cont =3D NULL; - int ret; - - aw88261->aw_pa->fw_status =3D AW88261_DEV_FW_FAILED; - - ret =3D request_firmware(&cont, AW88261_ACF_FILE, aw88261->aw_pa->dev); - if (ret) - return dev_err_probe(aw88261->aw_pa->dev, ret, - "load [%s] failed!", AW88261_ACF_FILE); - - dev_info(aw88261->aw_pa->dev, "loaded %s - size: %zu\n", - AW88261_ACF_FILE, cont ? cont->size : 0); - - aw88261->aw_cfg =3D devm_kzalloc(aw88261->aw_pa->dev, cont->size + sizeof= (int), GFP_KERNEL); - if (!aw88261->aw_cfg) { - release_firmware(cont); - return -ENOMEM; - } - aw88261->aw_cfg->len =3D (int)cont->size; - memcpy(aw88261->aw_cfg->data, cont->data, cont->size); - release_firmware(cont); - - ret =3D aw88395_dev_load_acf_check(aw88261->aw_pa, aw88261->aw_cfg); - if (ret) { - dev_err(aw88261->aw_pa->dev, "load [%s] failed !", AW88261_ACF_FILE); + dev_err(aw88261->aw_pa->dev, "aw88261_frcset_check ret =3D %d\n", ret); return ret; } =20 - mutex_lock(&aw88261->lock); - /* aw device init */ - ret =3D aw88261_dev_init(aw88261, aw88261->aw_cfg); - if (ret) - dev_err(aw88261->aw_pa->dev, "dev init failed"); - mutex_unlock(&aw88261->lock); - - return ret; -} - -static int aw88261_codec_probe(struct snd_soc_component *component) -{ - struct snd_soc_dapm_context *dapm =3D snd_soc_component_get_dapm(componen= t); - struct aw88261 *aw88261 =3D snd_soc_component_get_drvdata(component); - int ret; - - INIT_DELAYED_WORK(&aw88261->start_work, aw88261_startup_work); - - ret =3D aw88261_request_firmware_file(aw88261); - if (ret) - return dev_err_probe(aw88261->aw_pa->dev, ret, - "aw88261_request_firmware_file failed\n"); - - /* add widgets */ - ret =3D snd_soc_dapm_new_controls(dapm, aw88261_dapm_widgets, - ARRAY_SIZE(aw88261_dapm_widgets)); - if (ret) - return ret; - - /* add route */ - ret =3D snd_soc_dapm_add_routes(dapm, aw88261_audio_map, - ARRAY_SIZE(aw88261_audio_map)); - if (ret) - return ret; - - ret =3D snd_soc_add_component_controls(component, aw88261_controls, - ARRAY_SIZE(aw88261_controls)); - return ret; } =20 @@ -1170,62 +973,14 @@ static void aw88261_codec_remove(struct snd_soc_comp= onent *aw_codec) static const struct snd_soc_component_driver soc_codec_dev_aw88261 =3D { .probe =3D aw88261_codec_probe, .remove =3D aw88261_codec_remove, + .dapm_widgets =3D aw88261_dapm_widgets, + .num_dapm_widgets =3D ARRAY_SIZE(aw88261_dapm_widgets), + .dapm_routes =3D aw88261_audio_map, + .num_dapm_routes =3D ARRAY_SIZE(aw88261_audio_map), + .controls =3D aw88261_controls, + .num_controls =3D ARRAY_SIZE(aw88261_controls), }; =20 -static void aw88261_parse_channel_dt(struct aw88261 *aw88261) -{ - struct aw_device *aw_dev =3D aw88261->aw_pa; - struct device_node *np =3D aw_dev->dev->of_node; - u32 channel_value =3D AW88261_DEV_DEFAULT_CH; - - of_property_read_u32(np, "awinic,audio-channel", &channel_value); - aw88261->phase_sync =3D of_property_read_bool(np, "awinic,sync-flag"); - - aw_dev->channel =3D channel_value; -} - -static int aw88261_init(struct aw88261 **aw88261, struct i2c_client *i2c, = struct regmap *regmap) -{ - struct aw_device *aw_dev; - unsigned int chip_id; - int ret; - - /* read chip id */ - ret =3D regmap_read(regmap, AW88261_ID_REG, &chip_id); - if (ret) { - dev_err(&i2c->dev, "%s read chipid error. ret =3D %d", __func__, ret); - return ret; - } - if (chip_id !=3D AW88261_CHIP_ID) { - dev_err(&i2c->dev, "unsupported device"); - return -ENXIO; - } - - dev_info(&i2c->dev, "chip id =3D %x\n", chip_id); - - aw_dev =3D devm_kzalloc(&i2c->dev, sizeof(*aw_dev), GFP_KERNEL); - if (!aw_dev) - return -ENOMEM; - - (*aw88261)->aw_pa =3D aw_dev; - aw_dev->i2c =3D i2c; - aw_dev->regmap =3D regmap; - aw_dev->dev =3D &i2c->dev; - aw_dev->chip_id =3D AW88261_CHIP_ID; - aw_dev->acf =3D NULL; - aw_dev->prof_info.prof_desc =3D NULL; - aw_dev->prof_info.count =3D 0; - aw_dev->prof_info.prof_type =3D AW88395_DEV_NONE_TYPE_ID; - aw_dev->channel =3D 0; - aw_dev->fw_status =3D AW88261_DEV_FW_FAILED; - aw_dev->fade_step =3D AW88261_VOLUME_STEP_DB; - aw_dev->volume_desc.ctl_volume =3D AW88261_VOL_DEFAULT_VALUE; - aw_dev->volume_desc.mute_volume =3D AW88261_MUTE_VOL; - aw88261_parse_channel_dt(*aw88261); - - return ret; -} - static int aw88261_i2c_probe(struct i2c_client *i2c) { struct aw88261 *aw88261; @@ -1249,8 +1004,12 @@ static int aw88261_i2c_probe(struct i2c_client *i2c) return dev_err_probe(&i2c->dev, ret, "failed to init regmap: %d\n", ret); } =20 + aw88261->aw_pa =3D devm_kzalloc(&i2c->dev, sizeof(*aw88261->aw_pa), GFP_K= ERNEL); + if (!aw88261->aw_pa) + return -ENOMEM; + /* aw pa init */ - ret =3D aw88261_init(&aw88261, i2c, aw88261->regmap); + ret =3D aw_dev_init(aw88261->aw_pa, i2c, aw88261->regmap); if (ret) return ret; =20 diff --git a/sound/soc/codecs/aw88261.h b/sound/soc/codecs/aw88261.h index 734d0f93ced9..4ec0fe3ad033 100644 --- a/sound/soc/codecs/aw88261.h +++ b/sound/soc/codecs/aw88261.h @@ -378,8 +378,6 @@ SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S32_LE) =20 -#define FADE_TIME_MAX 100000 -#define FADE_TIME_MIN 0 =20 #define AW88261_DEV_DEFAULT_CH (0) #define AW88261_ACF_FILE "aw88261_acf.bin" @@ -396,40 +394,6 @@ AW88261_VOL_6DB_START) + \ ((value) % AW88261_VOLUME_STEP_DB)) =20 -#define AW88261_PROFILE_EXT(xname, profile_info, profile_get, profile_set)= \ -{ \ - .iface =3D SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name =3D xname, \ - .info =3D profile_info, \ - .get =3D profile_get, \ - .put =3D profile_set, \ -} - -enum { - AW88261_SYNC_START =3D 0, - AW88261_ASYNC_START, -}; - -enum aw88261_id { - AW88261_CHIP_ID =3D 0x2113, -}; - -enum { - AW88261_500_US =3D 500, - AW88261_1000_US =3D 1000, - AW88261_2000_US =3D 2000, -}; - -enum { - AW88261_DEV_PW_OFF =3D 0, - AW88261_DEV_PW_ON, -}; - -enum { - AW88261_DEV_FW_FAILED =3D 0, - AW88261_DEV_FW_OK, -}; - enum { AW88261_EF_AND_CHECK =3D 0, AW88261_EF_OR_CHECK, @@ -440,20 +404,4 @@ enum { AW88261_FRCSET_ENABLE, }; =20 -struct aw88261 { - struct aw_device *aw_pa; - struct mutex lock; - struct gpio_desc *reset_gpio; - struct delayed_work start_work; - struct regmap *regmap; - struct aw_container *aw_cfg; - - int efuse_check; - int frcset_en; - unsigned int mute_st; - unsigned int amppd_st; - - bool phase_sync; -}; - #endif --=20 2.47.0 From nobody Wed Oct 1 22:31:21 2025 Received: from out198-21.us.a.mail.aliyun.com (out198-21.us.a.mail.aliyun.com [47.90.198.21]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 550B22EFDAB; Fri, 26 Sep 2025 10:26:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=47.90.198.21 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758882392; cv=none; b=ePb269Pww4sR7JRPn1y+Sxz1wL+AdkeWJpkXie96+JPseq8T/qPqnGK+Kq8c28IGBXqWlzQHtnr5hvVQxEQ3kNoNzNgxNN1os20BCEcFXQe/7niKhz1+4WOI9lrx6vQ9wP8y3O1le4wjd2QixcUFwrgchH4HWubyCJEwecVbSj4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758882392; c=relaxed/simple; bh=I1OucDUHrSBgrZ1xvnZ8rP+Btk4sdbt+W0GcWLi+a4o=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=INveFinrKS4VN3mYAWAb+1bWa5AxcVBuWHPbLYeKx/1HEWCbfImrM2bwTOT4MF+wE5jlXkyQLa/uiz1S7d3wFhfBJETEzv1kN/SXh7ssHKOhQWHQZZ8V5zMjATgZUpC/k0GfksZGKIBZtqFoj/uAs4MnIfb+ZZZPnD4EMlruxoU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=awinic.com; spf=pass smtp.mailfrom=awinic.com; dkim=pass (2048-bit key) header.d=awinic.com header.i=@awinic.com header.b=jxI/KCow; arc=none smtp.client-ip=47.90.198.21 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=awinic.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=awinic.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=awinic.com header.i=@awinic.com header.b="jxI/KCow" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=awinic.com; s=default; t=1758882375; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=gTK9I+5C+gXVIJ8cNIVMFSjeFqQcgwWj7Bg5gOLOieE=; b=jxI/KCowrTwCEdGJRLsze/I8KKGIaSOljQfz3xuyteCeTPElxq08R3iDiy4H99jYnuDiT/umq3E33XHCBBdV8gHA60Rmdp+1QDe7tlxLJPFknJcflPVP4MZ+rMbOG1HlX8N4zW9/wBNFxgxb4Ter6YflhAwvwoM8an90HJxiVZB/yFmwuHEKp9HQSLhH+CZPPN4sPboGrY+zZNA53HKAXN1x97u6KbckSPs44UzS3IFMR/I99KKoGKIi1NCWZ0T9ZGlkBTF3mIlfZCSjy/NxTsQNuJ/X+devnLt1HRumErzqNnUFS4oI74QQ6FrZoz2CdbRCgenM2ag+UkBWCMy7Eg== Received: from ubuntu-VirtualBox..(mailfrom:wangweidong.a@awinic.com fp:SMTPD_---.ensjP6d_1758882054 cluster:ay29) by smtp.aliyun-inc.com; Fri, 26 Sep 2025 18:20:55 +0800 From: wangweidong.a@awinic.com To: lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com, wangweidong.a@awinic.com, cy_huang@richtek.com, ivprusov@salutedevices.com, zhoubinbin@loongson.cn, zhangyi@everest-semi.com, jack.yu@realtek.com, shenghao-ding@ti.com, rf@opensource.cirrus.com, git@apitzsch.eu, nuno.sa@analog.com, colin.i.king@gmail.com, thorsten.blum@linux.dev, yesanishhere@gmail.com, ebiggers@google.com, ardb@kernel.org, zhujun2@cmss.chinamobile.com, linux-kernel@vger.kernel.org, linux-sound@vger.kernel.org Subject: [PATCH V1 7/7] ASoC: codecs: Rework the aw88399 driver Date: Fri, 26 Sep 2025 18:20:37 +0800 Message-ID: <20250926102037.27697-8-wangweidong.a@awinic.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20250926102037.27697-1-wangweidong.a@awinic.com> References: <20250926102037.27697-1-wangweidong.a@awinic.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Weidong Wang Modify the interface for calling the aw88399 driver to adapt it for aw-common-device.c and aw-common-firmware.c Signed-off-by: Weidong Wang --- sound/soc/codecs/aw88399.c | 1025 ++++++++---------------------------- sound/soc/codecs/aw88399.h | 93 +--- 2 files changed, 217 insertions(+), 901 deletions(-) diff --git a/sound/soc/codecs/aw88399.c b/sound/soc/codecs/aw88399.c index 58846feb013d..0be105ff48a7 100644 --- a/sound/soc/codecs/aw88399.c +++ b/sound/soc/codecs/aw88399.c @@ -11,12 +11,23 @@ #include #include #include -#include #include -#include #include +#include #include "aw88399.h" -#include "aw88395/aw88395_device.h" +#include "aw-common-device.h" +#include "aw-common-firmware.h" + +struct aw88399 { + struct aw_device *aw_pa; + struct mutex lock; + struct delayed_work start_work; + struct regmap *regmap; + unsigned int check_val; + unsigned int crc_init_val; + unsigned int vcalb_init_val; + unsigned int dither_st; +}; =20 static const struct regmap_config aw88399_remap_config =3D { .val_bits =3D 16, @@ -26,214 +37,7 @@ static const struct regmap_config aw88399_remap_config = =3D { .val_format_endian =3D REGMAP_ENDIAN_BIG, }; =20 -static int aw_dev_dsp_write_16bit(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int dsp_data) -{ - int ret; - - ret =3D regmap_write(aw_dev->regmap, AW88399_DSPMADD_REG, dsp_addr); - if (ret) { - dev_err(aw_dev->dev, "%s write addr error, ret=3D%d", __func__, ret); - return ret; - } - - ret =3D regmap_write(aw_dev->regmap, AW88399_DSPMDAT_REG, (u16)dsp_data); - if (ret) { - dev_err(aw_dev->dev, "%s write data error, ret=3D%d", __func__, ret); - return ret; - } - - return 0; -} - -static int aw_dev_dsp_write_32bit(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int dsp_data) -{ - unsigned int temp_data; - int ret; - - ret =3D regmap_write(aw_dev->regmap, AW88399_DSPMADD_REG, dsp_addr); - if (ret) { - dev_err(aw_dev->dev, "%s write addr error, ret=3D%d", __func__, ret); - return ret; - } - - temp_data =3D dsp_data & AW88395_DSP_16_DATA_MASK; - ret =3D regmap_write(aw_dev->regmap, AW88399_DSPMDAT_REG, temp_data); - if (ret) { - dev_err(aw_dev->dev, "%s write datal error, ret=3D%d", __func__, ret); - return ret; - } - - temp_data =3D dsp_data >> 16; - ret =3D regmap_write(aw_dev->regmap, AW88399_DSPMDAT_REG, temp_data); - if (ret) - dev_err(aw_dev->dev, "%s write datah error, ret=3D%d", __func__, ret); - - return ret; -} - -static int aw_dev_dsp_write(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int dsp_data, unsigned char data_type) -{ - unsigned int reg_value; - int ret; - - mutex_lock(&aw_dev->dsp_lock); - switch (data_type) { - case AW88395_DSP_16_DATA: - ret =3D aw_dev_dsp_write_16bit(aw_dev, dsp_addr, dsp_data); - if (ret) - dev_err(aw_dev->dev, "write dsp_addr[0x%x] 16-bit dsp_data[0x%x] failed= ", - dsp_addr, dsp_data); - break; - case AW88395_DSP_32_DATA: - ret =3D aw_dev_dsp_write_32bit(aw_dev, dsp_addr, dsp_data); - if (ret) - dev_err(aw_dev->dev, "write dsp_addr[0x%x] 32-bit dsp_data[0x%x] failed= ", - dsp_addr, dsp_data); - break; - default: - dev_err(aw_dev->dev, "data type[%d] unsupported", data_type); - ret =3D -EINVAL; - break; - } - - /* clear dsp chip select state */ - if (regmap_read(aw_dev->regmap, 0x00, ®_value)) - dev_err(aw_dev->dev, "%s fail to clear chip state. Err=3D%d\n", __func__= , ret); - mutex_unlock(&aw_dev->dsp_lock); - - return ret; -} - -static int aw_dev_dsp_read_16bit(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int *dsp_data) -{ - unsigned int temp_data; - int ret; - - ret =3D regmap_write(aw_dev->regmap, AW88399_DSPMADD_REG, dsp_addr); - if (ret) { - dev_err(aw_dev->dev, "%s write error, ret=3D%d", __func__, ret); - return ret; - } - - ret =3D regmap_read(aw_dev->regmap, AW88399_DSPMDAT_REG, &temp_data); - if (ret) { - dev_err(aw_dev->dev, "%s read error, ret=3D%d", __func__, ret); - return ret; - } - *dsp_data =3D temp_data; - - return 0; -} - -static int aw_dev_dsp_read_32bit(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int *dsp_data) -{ - unsigned int temp_data; - int ret; - - ret =3D regmap_write(aw_dev->regmap, AW88399_DSPMADD_REG, dsp_addr); - if (ret) { - dev_err(aw_dev->dev, "%s write error, ret=3D%d", __func__, ret); - return ret; - } - - ret =3D regmap_read(aw_dev->regmap, AW88399_DSPMDAT_REG, &temp_data); - if (ret) { - dev_err(aw_dev->dev, "%s read error, ret=3D%d", __func__, ret); - return ret; - } - *dsp_data =3D temp_data; - - ret =3D regmap_read(aw_dev->regmap, AW88399_DSPMDAT_REG, &temp_data); - if (ret) { - dev_err(aw_dev->dev, "%s read error, ret=3D%d", __func__, ret); - return ret; - } - *dsp_data |=3D (temp_data << 16); - - return 0; -} - -static int aw_dev_dsp_read(struct aw_device *aw_dev, - unsigned short dsp_addr, unsigned int *dsp_data, unsigned char data_type) -{ - u32 reg_value; - int ret; - - mutex_lock(&aw_dev->dsp_lock); - switch (data_type) { - case AW88399_DSP_16_DATA: - ret =3D aw_dev_dsp_read_16bit(aw_dev, dsp_addr, dsp_data); - if (ret) - dev_err(aw_dev->dev, "read dsp_addr[0x%x] 16-bit dsp_data[0x%x] failed", - (u32)dsp_addr, *dsp_data); - break; - case AW88399_DSP_32_DATA: - ret =3D aw_dev_dsp_read_32bit(aw_dev, dsp_addr, dsp_data); - if (ret) - dev_err(aw_dev->dev, "read dsp_addr[0x%x] 32r-bit dsp_data[0x%x] failed= ", - (u32)dsp_addr, *dsp_data); - break; - default: - dev_err(aw_dev->dev, "data type[%d] unsupported", data_type); - ret =3D -EINVAL; - break; - } - - /* clear dsp chip select state */ - if (regmap_read(aw_dev->regmap, AW88399_ID_REG, ®_value)) - dev_err(aw_dev->dev, "%s fail to clear chip state. ret=3D%d\n", __func__= , ret); - mutex_unlock(&aw_dev->dsp_lock); - - return ret; -} - -static void aw_dev_pwd(struct aw_device *aw_dev, bool pwd) -{ - int ret; - - if (pwd) - ret =3D regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, - ~AW88399_PWDN_MASK, AW88399_PWDN_POWER_DOWN_VALUE); - else - ret =3D regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, - ~AW88399_PWDN_MASK, AW88399_PWDN_WORKING_VALUE); - - if (ret) - dev_dbg(aw_dev->dev, "%s failed", __func__); -} - -static void aw_dev_get_int_status(struct aw_device *aw_dev, unsigned short= *int_status) -{ - unsigned int reg_val; - int ret; - - ret =3D regmap_read(aw_dev->regmap, AW88399_SYSINT_REG, ®_val); - if (ret) - dev_err(aw_dev->dev, "read interrupt reg fail, ret=3D%d", ret); - else - *int_status =3D reg_val; - - dev_dbg(aw_dev->dev, "read interrupt reg=3D0x%04x", *int_status); -} - -static void aw_dev_clear_int_status(struct aw_device *aw_dev) -{ - u16 int_status; - - /* read int status and clear */ - aw_dev_get_int_status(aw_dev, &int_status); - /* make sure int status is clear */ - aw_dev_get_int_status(aw_dev, &int_status); - if (int_status) - dev_dbg(aw_dev->dev, "int status(%d) is not cleaned.\n", int_status); -} - -static int aw_dev_get_iis_status(struct aw_device *aw_dev) +static int aw88399_get_iis_status(struct aw_device *aw_dev) { unsigned int reg_val; int ret; @@ -249,15 +53,15 @@ static int aw_dev_get_iis_status(struct aw_device *aw_= dev) return 0; } =20 -static int aw_dev_check_mode1_pll(struct aw_device *aw_dev) +static int aw88399_check_mode1_pll(struct aw_device *aw_dev) { int ret, i; =20 for (i =3D 0; i < AW88399_DEV_SYSST_CHECK_MAX; i++) { - ret =3D aw_dev_get_iis_status(aw_dev); + ret =3D aw88399_get_iis_status(aw_dev); if (ret) { dev_err(aw_dev->dev, "mode1 iis signal check error"); - usleep_range(AW88399_2000_US, AW88399_2000_US + 10); + usleep_range(AW_2000_US, AW_2000_US + 10); } else { return 0; } @@ -266,7 +70,7 @@ static int aw_dev_check_mode1_pll(struct aw_device *aw_d= ev) return -EPERM; } =20 -static int aw_dev_check_mode2_pll(struct aw_device *aw_dev) +static int aw88399_check_mode2_pll(struct aw_device *aw_dev) { unsigned int reg_val; int ret, i; @@ -288,10 +92,10 @@ static int aw_dev_check_mode2_pll(struct aw_device *aw= _dev) return ret; =20 for (i =3D 0; i < AW88399_DEV_SYSST_CHECK_MAX; i++) { - ret =3D aw_dev_get_iis_status(aw_dev); + ret =3D aw88399_get_iis_status(aw_dev); if (ret) { dev_err(aw_dev->dev, "mode2 iis signal check error"); - usleep_range(AW88399_2000_US, AW88399_2000_US + 10); + usleep_range(AW_2000_US, AW_2000_US + 10); } else { break; } @@ -301,12 +105,12 @@ static int aw_dev_check_mode2_pll(struct aw_device *a= w_dev) regmap_update_bits(aw_dev->regmap, AW88399_PLLCTRL2_REG, ~AW88399_CCO_MUX_MASK, AW88399_CCO_MUX_BYPASS_VALUE); if (ret =3D=3D 0) { - usleep_range(AW88399_2000_US, AW88399_2000_US + 10); + usleep_range(AW_2000_US, AW_2000_US + 10); for (i =3D 0; i < AW88399_DEV_SYSST_CHECK_MAX; i++) { - ret =3D aw_dev_get_iis_status(aw_dev); + ret =3D aw88399_get_iis_status(aw_dev); if (ret) { dev_err(aw_dev->dev, "mode2 switch to mode1, iis signal check error"); - usleep_range(AW88399_2000_US, AW88399_2000_US + 10); + usleep_range(AW_2000_US, AW_2000_US + 10); } else { break; } @@ -316,14 +120,14 @@ static int aw_dev_check_mode2_pll(struct aw_device *a= w_dev) return ret; } =20 -static int aw_dev_check_syspll(struct aw_device *aw_dev) +static int aw88399_check_syspll(struct aw_device *aw_dev) { int ret; =20 - ret =3D aw_dev_check_mode1_pll(aw_dev); + ret =3D aw88399_check_mode1_pll(aw_dev); if (ret) { dev_dbg(aw_dev->dev, "mode1 check iis failed try switch to mode2 check"); - ret =3D aw_dev_check_mode2_pll(aw_dev); + ret =3D aw88399_check_mode2_pll(aw_dev); if (ret) { dev_err(aw_dev->dev, "mode2 check iis failed"); return ret; @@ -333,7 +137,7 @@ static int aw_dev_check_syspll(struct aw_device *aw_dev) return 0; } =20 -static int aw_dev_check_sysst(struct aw_device *aw_dev) +static int aw88399_check_sysst(struct aw_device *aw_dev) { unsigned int check_val; unsigned int reg_val; @@ -356,7 +160,7 @@ static int aw_dev_check_sysst(struct aw_device *aw_dev) if ((reg_val & (~AW88399_BIT_SYSST_CHECK_MASK) & check_val) !=3D check_v= al) { dev_err(aw_dev->dev, "check sysst fail, cnt=3D%d, reg_val=3D0x%04x, che= ck:0x%x", i, reg_val, AW88399_BIT_SYSST_NOSWS_CHECK); - usleep_range(AW88399_2000_US, AW88399_2000_US + 10); + usleep_range(AW_2000_US, AW_2000_US + 10); } else { return 0; } @@ -365,36 +169,6 @@ static int aw_dev_check_sysst(struct aw_device *aw_dev) return -EPERM; } =20 -static void aw_dev_amppd(struct aw_device *aw_dev, bool amppd) -{ - int ret; - - if (amppd) - ret =3D regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, - ~AW88399_AMPPD_MASK, AW88399_AMPPD_POWER_DOWN_VALUE); - else - ret =3D regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, - ~AW88399_AMPPD_MASK, AW88399_AMPPD_WORKING_VALUE); - - if (ret) - dev_dbg(aw_dev->dev, "%s failed", __func__); -} - -static void aw_dev_dsp_enable(struct aw_device *aw_dev, bool is_enable) -{ - int ret; - - if (is_enable) - ret =3D regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, - ~AW88399_DSPBY_MASK, AW88399_DSPBY_WORKING_VALUE); - else - ret =3D regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, - ~AW88399_DSPBY_MASK, AW88399_DSPBY_BYPASS_VALUE); - - if (ret) - dev_dbg(aw_dev->dev, "%s failed\n", __func__); -} - static int aw88399_dev_get_icalk(struct aw88399 *aw88399, int16_t *icalk) { uint16_t icalkh_val, icalkl_val, icalk_val; @@ -487,7 +261,7 @@ static int aw88399_dev_get_internal_vcalk(struct aw8839= 9 *aw88399, int16_t *vcal return 0; } =20 -static int aw_dev_set_vcalb(struct aw88399 *aw88399) +static int aw88399_set_vcalb(struct aw88399 *aw88399) { struct aw_device *aw_dev =3D aw88399->aw_pa; unsigned int vsense_select, vsense_value; @@ -540,7 +314,7 @@ static int aw_dev_set_vcalb(struct aw88399 *aw88399) return 0; } =20 -static int aw_dev_update_cali_re(struct aw_cali_desc *cali_desc) +static int aw88399_update_cali_re(struct aw_cali_desc *cali_desc) { struct aw_device *aw_dev =3D container_of(cali_desc, struct aw_device, cali_desc); @@ -571,7 +345,7 @@ static int aw_dev_update_cali_re(struct aw_cali_desc *c= ali_desc) return ret; } =20 -static int aw_dev_fw_crc_check(struct aw_device *aw_dev) +static int aw88399_fw_crc_check(struct aw_device *aw_dev) { uint16_t check_val, fw_len_val; unsigned int reg_val; @@ -589,7 +363,7 @@ static int aw_dev_fw_crc_check(struct aw_device *aw_dev) ret =3D regmap_update_bits(aw_dev->regmap, AW88399_CRCCTRL_REG, ~AW88399_CRC_CODE_EN_MASK, AW88399_CRC_CODE_EN_ENABLE_VALUE); =20 - usleep_range(AW88399_2000_US, AW88399_2000_US + 10); + usleep_range(AW_2000_US, AW_2000_US + 10); =20 /* read crc check result */ regmap_read(aw_dev->regmap, AW88399_HAGCST_REG, ®_val); @@ -613,7 +387,7 @@ static int aw_dev_fw_crc_check(struct aw_device *aw_dev) return ret; } =20 -static int aw_dev_cfg_crc_check(struct aw_device *aw_dev) +static int aw88399_cfg_crc_check(struct aw_device *aw_dev) { uint16_t check_val, cfg_len_val; unsigned int reg_val; @@ -634,7 +408,7 @@ static int aw_dev_cfg_crc_check(struct aw_device *aw_de= v) if (ret) return ret; =20 - usleep_range(AW88399_1000_US, AW88399_1000_US + 10); + usleep_range(AW_1000_US, AW_1000_US + 10); =20 /* read crc check result */ ret =3D regmap_read(aw_dev->regmap, AW88399_HAGCST_REG, ®_val); @@ -658,7 +432,7 @@ static int aw_dev_cfg_crc_check(struct aw_device *aw_de= v) return ret; } =20 -static int aw_dev_hw_crc_check(struct aw88399 *aw88399) +static int aw88399_hw_crc_check(struct aw88399 *aw88399) { struct aw_device *aw_dev =3D aw88399->aw_pa; int ret; @@ -668,13 +442,13 @@ static int aw_dev_hw_crc_check(struct aw88399 *aw8839= 9) if (ret) return ret; =20 - ret =3D aw_dev_fw_crc_check(aw_dev); + ret =3D aw88399_fw_crc_check(aw_dev); if (ret) { dev_err(aw_dev->dev, "fw_crc_check failed\n"); goto crc_check_failed; } =20 - ret =3D aw_dev_cfg_crc_check(aw_dev); + ret =3D aw88399_cfg_crc_check(aw_dev); if (ret) { dev_err(aw_dev->dev, "cfg_crc_check failed\n"); goto crc_check_failed; @@ -695,199 +469,104 @@ static int aw_dev_hw_crc_check(struct aw88399 *aw88= 399) return ret; } =20 -static void aw_dev_i2s_tx_enable(struct aw_device *aw_dev, bool flag) -{ - int ret; - - if (flag) - ret =3D regmap_update_bits(aw_dev->regmap, AW88399_I2SCTRL3_REG, - ~AW88399_I2STXEN_MASK, AW88399_I2STXEN_ENABLE_VALUE); - else - ret =3D regmap_update_bits(aw_dev->regmap, AW88399_I2SCFG1_REG, - ~AW88399_I2STXEN_MASK, AW88399_I2STXEN_DISABLE_VALUE); - - if (ret) - dev_dbg(aw_dev->dev, "%s failed", __func__); -} - -static int aw_dev_get_dsp_status(struct aw_device *aw_dev) -{ - unsigned int reg_val; - int ret; - - ret =3D regmap_read(aw_dev->regmap, AW88399_WDT_REG, ®_val); - if (ret) - return ret; - if (!(reg_val & (~AW88399_WDT_CNT_MASK))) - return -EPERM; - - return 0; -} - -static int aw_dev_dsp_check(struct aw_device *aw_dev) +static int aw88399_dsp_check(struct aw_device *aw_dev) { int ret, i; =20 - switch (aw_dev->dsp_cfg) { - case AW88399_DEV_DSP_BYPASS: - dev_dbg(aw_dev->dev, "dsp bypass"); - ret =3D 0; - break; - case AW88399_DEV_DSP_WORK: - aw_dev_dsp_enable(aw_dev, false); - aw_dev_dsp_enable(aw_dev, true); - usleep_range(AW88399_1000_US, AW88399_1000_US + 10); - for (i =3D 0; i < AW88399_DEV_DSP_CHECK_MAX; i++) { - ret =3D aw_dev_get_dsp_status(aw_dev); - if (ret) { - dev_err(aw_dev->dev, "dsp wdt status error=3D%d", ret); - usleep_range(AW88399_2000_US, AW88399_2000_US + 10); - } + regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, + ~AW88399_DSPBY_MASK, AW88399_DSPBY_BYPASS_VALUE); + regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, + ~AW88399_DSPBY_MASK, AW88399_DSPBY_WORKING_VALUE); + usleep_range(AW_1000_US, AW_1000_US + 10); + for (i =3D 0; i < AW88399_DEV_DSP_CHECK_MAX; i++) { + ret =3D aw_dev_get_dsp_status(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "dsp wdt status error=3D%d", ret); + usleep_range(AW_2000_US, AW_2000_US + 10); } - break; - default: - dev_err(aw_dev->dev, "unknown dsp cfg=3D%d", aw_dev->dsp_cfg); - ret =3D -EINVAL; - break; } =20 return ret; } =20 -static int aw_dev_set_volume(struct aw_device *aw_dev, unsigned int value) +static void aw88399_set_volume(struct aw_device *aw_dev, unsigned int valu= e) { struct aw_volume_desc *vol_desc =3D &aw_dev->volume_desc; unsigned int reg_value; u16 real_value; - int ret; =20 real_value =3D min((value + vol_desc->init_volume), (unsigned int)AW88399= _MUTE_VOL); =20 - ret =3D regmap_read(aw_dev->regmap, AW88399_SYSCTRL2_REG, ®_value); - if (ret) - return ret; + regmap_read(aw_dev->regmap, AW88399_SYSCTRL2_REG, ®_value); =20 dev_dbg(aw_dev->dev, "value 0x%x , reg:0x%x", value, real_value); =20 real_value =3D (real_value << AW88399_VOL_START_BIT) | (reg_value & AW883= 99_VOL_MASK); =20 - ret =3D regmap_write(aw_dev->regmap, AW88399_SYSCTRL2_REG, real_value); - - return ret; -} - -static void aw_dev_fade_in(struct aw_device *aw_dev) -{ - struct aw_volume_desc *desc =3D &aw_dev->volume_desc; - u16 fade_in_vol =3D desc->ctl_volume; - int fade_step =3D aw_dev->fade_step; - int i; - - if (fade_step =3D=3D 0 || aw_dev->fade_in_time =3D=3D 0) { - aw_dev_set_volume(aw_dev, fade_in_vol); - return; - } - - for (i =3D AW88399_MUTE_VOL; i >=3D fade_in_vol; i -=3D fade_step) { - aw_dev_set_volume(aw_dev, i); - usleep_range(aw_dev->fade_in_time, aw_dev->fade_in_time + 10); - } - - if (i !=3D fade_in_vol) - aw_dev_set_volume(aw_dev, fade_in_vol); -} - -static void aw_dev_fade_out(struct aw_device *aw_dev) -{ - struct aw_volume_desc *desc =3D &aw_dev->volume_desc; - int fade_step =3D aw_dev->fade_step; - int i; - - if (fade_step =3D=3D 0 || aw_dev->fade_out_time =3D=3D 0) { - aw_dev_set_volume(aw_dev, AW88399_MUTE_VOL); - return; - } - - for (i =3D desc->ctl_volume; i <=3D AW88399_MUTE_VOL; i +=3D fade_step) { - aw_dev_set_volume(aw_dev, i); - usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10); - } - - if (i !=3D AW88399_MUTE_VOL) { - aw_dev_set_volume(aw_dev, AW88399_MUTE_VOL); - usleep_range(aw_dev->fade_out_time, aw_dev->fade_out_time + 10); - } + regmap_write(aw_dev->regmap, AW88399_SYSCTRL2_REG, real_value); } =20 static void aw88399_dev_mute(struct aw_device *aw_dev, bool is_mute) { if (is_mute) { - aw_dev_fade_out(aw_dev); + aw_dev_fade_out(aw_dev, aw88399_set_volume); regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, ~AW88399_HMUTE_MASK, AW88399_HMUTE_ENABLE_VALUE); } else { regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, ~AW88399_HMUTE_MASK, AW88399_HMUTE_DISABLE_VALUE); - aw_dev_fade_in(aw_dev); + aw_dev_fade_in(aw_dev, aw88399_set_volume); } } =20 -static void aw88399_dev_set_dither(struct aw88399 *aw88399, bool dither) -{ - struct aw_device *aw_dev =3D aw88399->aw_pa; - - if (dither) - regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG, - ~AW88399_DITHER_EN_MASK, AW88399_DITHER_EN_ENABLE_VALUE); - else - regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG, - ~AW88399_DITHER_EN_MASK, AW88399_DITHER_EN_DISABLE_VALUE); -} - static int aw88399_dev_start(struct aw88399 *aw88399) { struct aw_device *aw_dev =3D aw88399->aw_pa; int ret; =20 - if (aw_dev->status =3D=3D AW88399_DEV_PW_ON) { + if (aw_dev->status =3D=3D AW_DEV_PW_ON) { dev_dbg(aw_dev->dev, "already power on"); return 0; } =20 - aw88399_dev_set_dither(aw88399, false); + regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG, + ~AW88399_DITHER_EN_MASK, AW88399_DITHER_EN_DISABLE_VALUE); =20 /* power on */ - aw_dev_pwd(aw_dev, false); - usleep_range(AW88399_2000_US, AW88399_2000_US + 10); + regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, + ~AW88399_PWDN_MASK, AW88399_PWDN_WORKING_VALUE); + usleep_range(AW_2000_US, AW_2000_US + 10); =20 - ret =3D aw_dev_check_syspll(aw_dev); + ret =3D aw88399_check_syspll(aw_dev); if (ret) { dev_err(aw_dev->dev, "pll check failed cannot start"); goto pll_check_fail; } =20 /* amppd on */ - aw_dev_amppd(aw_dev, false); - usleep_range(AW88399_1000_US, AW88399_1000_US + 50); + regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, + ~AW88399_PWDN_MASK, AW88399_PWDN_WORKING_VALUE); + usleep_range(AW_1000_US, AW_1000_US + 50); =20 /* check i2s status */ - ret =3D aw_dev_check_sysst(aw_dev); + ret =3D aw88399_check_sysst(aw_dev); if (ret) { dev_err(aw_dev->dev, "sysst check failed"); goto sysst_check_fail; } =20 - if (aw_dev->dsp_cfg =3D=3D AW88399_DEV_DSP_WORK) { - ret =3D aw_dev_hw_crc_check(aw88399); + if (aw_dev->dsp_cfg =3D=3D AW_DEV_DSP_WORK) { + ret =3D aw88399_hw_crc_check(aw88399); if (ret) { dev_err(aw_dev->dev, "dsp crc check failed"); goto crc_check_fail; } - aw_dev_dsp_enable(aw_dev, false); - aw_dev_set_vcalb(aw88399); - aw_dev_update_cali_re(&aw_dev->cali_desc); + regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, + ~AW88399_DSPBY_MASK, AW88399_DSPBY_BYPASS_VALUE); + aw88399_set_vcalb(aw88399); + aw88399_update_cali_re(&aw_dev->cali_desc); =20 - ret =3D aw_dev_dsp_check(aw_dev); + ret =3D aw88399_dsp_check(aw_dev); if (ret) { dev_err(aw_dev->dev, "dsp status check failed"); goto dsp_check_fail; @@ -897,68 +576,45 @@ static int aw88399_dev_start(struct aw88399 *aw88399) } =20 /* enable tx feedback */ - aw_dev_i2s_tx_enable(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88399_I2SCTRL3_REG, + ~AW88399_I2STXEN_MASK, AW88399_I2STXEN_ENABLE_VALUE); =20 if (aw88399->dither_st =3D=3D AW88399_DITHER_EN_ENABLE_VALUE) - aw88399_dev_set_dither(aw88399, true); + regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG, + ~AW88399_DITHER_EN_MASK, AW88399_DITHER_EN_ENABLE_VALUE); =20 /* close mute */ aw88399_dev_mute(aw_dev, false); /* clear inturrupt */ aw_dev_clear_int_status(aw_dev); - aw_dev->status =3D AW88399_DEV_PW_ON; + aw_dev->status =3D AW_DEV_PW_ON; =20 return 0; =20 dsp_check_fail: crc_check_fail: - aw_dev_dsp_enable(aw_dev, false); + regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, + ~AW88399_DSPBY_MASK, AW88399_DSPBY_BYPASS_VALUE); sysst_check_fail: aw_dev_clear_int_status(aw_dev); - aw_dev_amppd(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, + ~AW88399_AMPPD_MASK, AW88399_AMPPD_POWER_DOWN_VALUE); pll_check_fail: - aw_dev_pwd(aw_dev, true); - aw_dev->status =3D AW88399_DEV_PW_OFF; - - return ret; -} - -static int aw_dev_dsp_update_container(struct aw_device *aw_dev, - unsigned char *data, unsigned int len, unsigned short base) -{ - u32 tmp_len; - int i, ret; - - mutex_lock(&aw_dev->dsp_lock); - ret =3D regmap_write(aw_dev->regmap, AW88399_DSPMADD_REG, base); - if (ret) - goto error_operation; - - for (i =3D 0; i < len; i +=3D AW88399_MAX_RAM_WRITE_BYTE_SIZE) { - tmp_len =3D min(len - i, AW88399_MAX_RAM_WRITE_BYTE_SIZE); - ret =3D regmap_raw_write(aw_dev->regmap, AW88399_DSPMDAT_REG, - &data[i], tmp_len); - if (ret) - goto error_operation; - } - mutex_unlock(&aw_dev->dsp_lock); - - return 0; + regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, + ~AW88399_PWDN_MASK, AW88399_PWDN_POWER_DOWN_VALUE); + aw_dev->status =3D AW_DEV_PW_OFF; =20 -error_operation: - mutex_unlock(&aw_dev->dsp_lock); return ret; } =20 -static int aw_dev_get_ra(struct aw_cali_desc *cali_desc) +static int aw88399_get_ra(struct aw_device *aw_dev) { - struct aw_device *aw_dev =3D - container_of(cali_desc, struct aw_device, cali_desc); + struct aw_cali_desc *cali_desc =3D &aw_dev->cali_desc; u32 dsp_ra; int ret; =20 ret =3D aw_dev_dsp_read(aw_dev, AW88399_DSP_REG_CFG_ADPZ_RA, - &dsp_ra, AW88399_DSP_32_DATA); + &dsp_ra, AW_DSP_32_DATA); if (ret) { dev_err(aw_dev->dev, "read ra error"); return ret; @@ -970,54 +626,12 @@ static int aw_dev_get_ra(struct aw_cali_desc *cali_de= sc) return 0; } =20 -static int aw_dev_dsp_update_cfg(struct aw_device *aw_dev, - unsigned char *data, unsigned int len) -{ - int ret; - - dev_dbg(aw_dev->dev, "dsp config len:%d", len); - - if (!len || !data) { - dev_err(aw_dev->dev, "dsp config data is null or len is 0"); - return -EINVAL; - } - - ret =3D aw_dev_dsp_update_container(aw_dev, data, len, AW88399_DSP_CFG_AD= DR); - if (ret) - return ret; - - aw_dev->dsp_cfg_len =3D len; - - ret =3D aw_dev_get_ra(&aw_dev->cali_desc); - - return ret; -} - -static int aw_dev_dsp_update_fw(struct aw_device *aw_dev, - unsigned char *data, unsigned int len) -{ - int ret; - - dev_dbg(aw_dev->dev, "dsp firmware len:%d", len); - - if (!len || !data) { - dev_err(aw_dev->dev, "dsp firmware data is null or len is 0"); - return -EINVAL; - } - - aw_dev->dsp_fw_len =3D len; - ret =3D aw_dev_dsp_update_container(aw_dev, data, len, AW88399_DSP_FW_ADD= R); - - return ret; -} - -static int aw_dev_check_sram(struct aw_device *aw_dev) +static int aw88399_check_sram(struct aw_device *aw_dev) { unsigned int reg_val; =20 - mutex_lock(&aw_dev->dsp_lock); /* read dsp_rom_check_reg */ - aw_dev_dsp_read_16bit(aw_dev, AW88399_DSP_ROM_CHECK_ADDR, ®_val); + aw_dev_dsp_read(aw_dev, AW88399_DSP_ROM_CHECK_ADDR, ®_val, AW_DSP_16_D= ATA); if (reg_val !=3D AW88399_DSP_ROM_CHECK_DATA) { dev_err(aw_dev->dev, "check dsp rom failed, read[0x%x] !=3D check[0x%x]", reg_val, AW88399_DSP_ROM_CHECK_DATA); @@ -1025,64 +639,22 @@ static int aw_dev_check_sram(struct aw_device *aw_de= v) } =20 /* check dsp_cfg_base_addr */ - aw_dev_dsp_write_16bit(aw_dev, AW88399_DSP_CFG_ADDR, AW88399_DSP_ODD_NUM_= BIT_TEST); - aw_dev_dsp_read_16bit(aw_dev, AW88399_DSP_CFG_ADDR, ®_val); + aw_dev_dsp_write(aw_dev, AW88399_DSP_CFG_ADDR, + AW88399_DSP_ODD_NUM_BIT_TEST, AW_DSP_16_DATA); + aw_dev_dsp_read(aw_dev, AW88399_DSP_CFG_ADDR, ®_val, AW_DSP_16_DATA); if (reg_val !=3D AW88399_DSP_ODD_NUM_BIT_TEST) { dev_err(aw_dev->dev, "check dsp cfg failed, read[0x%x] !=3D write[0x%x]", reg_val, AW88399_DSP_ODD_NUM_BIT_TEST); goto error; } - mutex_unlock(&aw_dev->dsp_lock); =20 return 0; + error: - mutex_unlock(&aw_dev->dsp_lock); return -EPERM; } =20 -static void aw_dev_select_memclk(struct aw_device *aw_dev, unsigned char f= lag) -{ - int ret; - - switch (flag) { - case AW88399_DEV_MEMCLK_PLL: - ret =3D regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG, - ~AW88399_MEM_CLKSEL_MASK, - AW88399_MEM_CLKSEL_DAPHCLK_VALUE); - if (ret) - dev_err(aw_dev->dev, "memclk select pll failed"); - break; - case AW88399_DEV_MEMCLK_OSC: - ret =3D regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG, - ~AW88399_MEM_CLKSEL_MASK, - AW88399_MEM_CLKSEL_OSCCLK_VALUE); - if (ret) - dev_err(aw_dev->dev, "memclk select OSC failed"); - break; - default: - dev_err(aw_dev->dev, "unknown memclk config, flag=3D0x%x", flag); - break; - } -} - -static void aw_dev_get_cur_mode_st(struct aw_device *aw_dev) -{ - struct aw_profctrl_desc *profctrl_desc =3D &aw_dev->profctrl_desc; - unsigned int reg_val; - int ret; - - ret =3D regmap_read(aw_dev->regmap, AW88399_SYSCTRL_REG, ®_val); - if (ret) { - dev_dbg(aw_dev->dev, "%s failed", __func__); - return; - } - if ((reg_val & (~AW88399_RCV_MODE_MASK)) =3D=3D AW88399_RCV_MODE_RECEIVER= _VALUE) - profctrl_desc->cur_mode =3D AW88399_RCV_MODE; - else - profctrl_desc->cur_mode =3D AW88399_NOT_RCV_MODE; -} - -static int aw_dev_update_reg_container(struct aw88399 *aw88399, +static int aw88399_reg_update(struct aw88399 *aw88399, unsigned char *data, unsigned int len) { struct aw_device *aw_dev =3D aw88399->aw_pa; @@ -1111,9 +683,9 @@ static int aw_dev_update_reg_container(struct aw88399 = *aw88399, =20 if (reg_addr =3D=3D AW88399_SYSCTRL_REG) { if (reg_val & (~AW88399_DSPBY_MASK)) - aw_dev->dsp_cfg =3D AW88399_DEV_DSP_BYPASS; + aw_dev->dsp_cfg =3D AW_DEV_DSP_BYPASS; else - aw_dev->dsp_cfg =3D AW88399_DEV_DSP_WORK; + aw_dev->dsp_cfg =3D AW_DEV_DSP_WORK; =20 reg_val &=3D (AW88399_HMUTE_MASK | AW88399_PWDN_MASK | AW88399_DSPBY_MASK); @@ -1136,7 +708,7 @@ static int aw_dev_update_reg_container(struct aw88399 = *aw88399, if ((reg_val & (~AW88399_EF_DBMD_MASK)) =3D=3D AW88399_EF_DBMD_OR_VALUE) aw88399->check_val =3D AW_EF_OR_CHECK; else - aw88399->check_val =3D AW_EF_AND_CHECK; + aw88399->check_val =3D AW_EF_AND_CHECK; =20 aw88399->dither_st =3D reg_val & (~AW88399_DITHER_EN_MASK); } @@ -1149,69 +721,17 @@ static int aw_dev_update_reg_container(struct aw8839= 9 *aw88399, return ret; } =20 - aw_dev_pwd(aw_dev, false); - usleep_range(AW88399_1000_US, AW88399_1000_US + 10); - - aw_dev_get_cur_mode_st(aw_dev); + usleep_range(AW_1000_US, AW_1000_US + 10); =20 if (aw_dev->prof_cur !=3D aw_dev->prof_index) vol_desc->ctl_volume =3D 0; else - aw_dev_set_volume(aw_dev, vol_desc->ctl_volume); - - return 0; -} - -static int aw_dev_reg_update(struct aw88399 *aw88399, - unsigned char *data, unsigned int len) -{ - int ret; - - if (!len || !data) { - dev_err(aw88399->aw_pa->dev, "reg data is null or len is 0"); - return -EINVAL; - } - - ret =3D aw_dev_update_reg_container(aw88399, data, len); - if (ret) - dev_err(aw88399->aw_pa->dev, "reg update failed"); - - return ret; -} - -static int aw88399_dev_get_prof_name(struct aw_device *aw_dev, int index, = char **prof_name) -{ - struct aw_prof_info *prof_info =3D &aw_dev->prof_info; - struct aw_prof_desc *prof_desc; - - if ((index >=3D aw_dev->prof_info.count) || (index < 0)) { - dev_err(aw_dev->dev, "index[%d] overflow count[%d]", - index, aw_dev->prof_info.count); - return -EINVAL; - } - - prof_desc =3D &aw_dev->prof_info.prof_desc[index]; - - *prof_name =3D prof_info->prof_name_list[prof_desc->id]; - - return 0; -} - -static int aw88399_dev_get_prof_data(struct aw_device *aw_dev, int index, - struct aw_prof_desc **prof_desc) -{ - if ((index >=3D aw_dev->prof_info.count) || (index < 0)) { - dev_err(aw_dev->dev, "%s: index[%d] overflow count[%d]\n", - __func__, index, aw_dev->prof_info.count); - return -EINVAL; - } - - *prof_desc =3D &aw_dev->prof_info.prof_desc[index]; + aw88399_set_volume(aw_dev, vol_desc->ctl_volume); =20 return 0; } =20 -static int aw88399_dev_fw_update(struct aw88399 *aw88399, bool up_dsp_fw_e= n, bool force_up_en) +static int aw88399_fw_update(struct aw88399 *aw88399, bool up_dsp_fw_en, b= ool force_up_en) { struct aw_device *aw_dev =3D aw88399->aw_pa; struct aw_prof_desc *prof_index_desc; @@ -1220,52 +740,52 @@ static int aw88399_dev_fw_update(struct aw88399 *aw8= 8399, bool up_dsp_fw_en, boo int ret; =20 if ((aw_dev->prof_cur =3D=3D aw_dev->prof_index) && - (force_up_en =3D=3D AW88399_FORCE_UPDATE_OFF)) { + (force_up_en =3D=3D AW_FORCE_UPDATE_OFF)) { dev_dbg(aw_dev->dev, "scene no change, not update"); return 0; } =20 - if (aw_dev->fw_status =3D=3D AW88399_DEV_FW_FAILED) { + if (aw_dev->fw_status =3D=3D AW_DEV_FW_FAILED) { dev_err(aw_dev->dev, "fw status[%d] error", aw_dev->fw_status); return -EPERM; } =20 - ret =3D aw88399_dev_get_prof_name(aw_dev, aw_dev->prof_index, &prof_name); + ret =3D aw_dev_get_prof_name(aw_dev, aw_dev->prof_index, &prof_name); if (ret) return ret; =20 dev_dbg(aw_dev->dev, "start update %s", prof_name); =20 - ret =3D aw88399_dev_get_prof_data(aw_dev, aw_dev->prof_index, &prof_index= _desc); + ret =3D aw_dev_get_prof_data(aw_dev, aw_dev->prof_index, &prof_index_desc= ); if (ret) return ret; =20 /* update reg */ sec_desc =3D prof_index_desc->sec_desc; - ret =3D aw_dev_reg_update(aw88399, sec_desc[AW88395_DATA_TYPE_REG].data, - sec_desc[AW88395_DATA_TYPE_REG].len); + ret =3D aw88399_reg_update(aw88399, sec_desc[AW_DATA_TYPE_REG].data, + sec_desc[AW_DATA_TYPE_REG].len); if (ret) { dev_err(aw_dev->dev, "update reg failed"); return ret; } =20 - aw88399_dev_mute(aw_dev, true); - - if (aw_dev->dsp_cfg =3D=3D AW88399_DEV_DSP_WORK) - aw_dev_dsp_enable(aw_dev, false); + regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, + ~AW88399_PWDN_MASK, AW88399_PWDN_WORKING_VALUE); =20 - aw_dev_select_memclk(aw_dev, AW88399_DEV_MEMCLK_OSC); - - ret =3D aw_dev_check_sram(aw_dev); - if (ret) { - dev_err(aw_dev->dev, "check sram failed"); - goto error; - } + regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG, + ~AW88399_MEM_CLKSEL_MASK, AW88399_MEM_CLKSEL_OSCCLK_VALUE); =20 if (up_dsp_fw_en) { + ret =3D aw88399_check_sram(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "check sram failed"); + goto error; + } + dev_dbg(aw_dev->dev, "fw_ver: [%x]", prof_index_desc->fw_ver); - ret =3D aw_dev_dsp_update_fw(aw_dev, sec_desc[AW88395_DATA_TYPE_DSP_FW].= data, - sec_desc[AW88395_DATA_TYPE_DSP_FW].len); + ret =3D aw_dev_dsp_update_fw(aw_dev, sec_desc[AW_DATA_TYPE_DSP_FW].data, + sec_desc[AW_DATA_TYPE_DSP_FW].len, + sec_desc[AW_DATA_TYPE_DSP_FW].addr); if (ret) { dev_err(aw_dev->dev, "update dsp fw failed"); goto error; @@ -1273,21 +793,25 @@ static int aw88399_dev_fw_update(struct aw88399 *aw8= 8399, bool up_dsp_fw_en, boo } =20 /* update dsp config */ - ret =3D aw_dev_dsp_update_cfg(aw_dev, sec_desc[AW88395_DATA_TYPE_DSP_CFG]= .data, - sec_desc[AW88395_DATA_TYPE_DSP_CFG].len); + ret =3D aw_dev_dsp_update_cfg(aw_dev, sec_desc[AW_DATA_TYPE_DSP_CFG].data, + sec_desc[AW_DATA_TYPE_DSP_CFG].len, + sec_desc[AW_DATA_TYPE_DSP_CFG].addr); if (ret) { dev_err(aw_dev->dev, "update dsp cfg failed"); goto error; } =20 - aw_dev_select_memclk(aw_dev, AW88399_DEV_MEMCLK_PLL); + aw88399_get_ra(aw_dev); + regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG, + ~AW88399_MEM_CLKSEL_MASK, AW88399_MEM_CLKSEL_DAPHCLK_VALUE); =20 aw_dev->prof_cur =3D aw_dev->prof_index; =20 return 0; =20 error: - aw_dev_select_memclk(aw_dev, AW88399_DEV_MEMCLK_PLL); + regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG, + ~AW88399_MEM_CLKSEL_MASK, AW88399_MEM_CLKSEL_DAPHCLK_VALUE); return ret; } =20 @@ -1299,7 +823,7 @@ static void aw88399_start_pa(struct aw88399 *aw88399) ret =3D aw88399_dev_start(aw88399); if (ret) { dev_err(aw88399->aw_pa->dev, "aw88399 device start failed. retry =3D %d= ", i); - ret =3D aw88399_dev_fw_update(aw88399, AW88399_DSP_FW_UPDATE_ON, true); + ret =3D aw88399_fw_update(aw88399, AW_DSP_FW_UPDATE_ON, true); if (ret) { dev_err(aw88399->aw_pa->dev, "fw update failed"); continue; @@ -1325,27 +849,27 @@ static void aw88399_start(struct aw88399 *aw88399, b= ool sync_start) { int ret; =20 - if (aw88399->aw_pa->fw_status !=3D AW88399_DEV_FW_OK) + if (aw88399->aw_pa->fw_status !=3D AW_DEV_FW_OK) return; =20 - if (aw88399->aw_pa->status =3D=3D AW88399_DEV_PW_ON) + if (aw88399->aw_pa->status =3D=3D AW_DEV_PW_ON) return; =20 - ret =3D aw88399_dev_fw_update(aw88399, AW88399_DSP_FW_UPDATE_OFF, true); + ret =3D aw88399_fw_update(aw88399, AW_DSP_FW_UPDATE_OFF, + aw88399->aw_pa->phase_sync); if (ret) { dev_err(aw88399->aw_pa->dev, "fw update failed."); return; } =20 - if (sync_start =3D=3D AW88399_SYNC_START) + if (sync_start =3D=3D AW_SYNC_START) aw88399_start_pa(aw88399); else queue_delayed_work(system_wq, - &aw88399->start_work, - AW88399_START_WORK_DELAY_MS); + &aw88399->start_work, AW88399_START_WORK_DELAY_MS); } =20 -static int aw_dev_check_sysint(struct aw_device *aw_dev) +static int aw88399_check_sysint(struct aw_device *aw_dev) { u16 reg_val; =20 @@ -1361,38 +885,44 @@ static int aw_dev_check_sysint(struct aw_device *aw_= dev) static int aw88399_stop(struct aw_device *aw_dev) { struct aw_sec_data_desc *dsp_cfg =3D - &aw_dev->prof_info.prof_desc[aw_dev->prof_cur].sec_desc[AW88395_DATA_TYP= E_DSP_CFG]; + &aw_dev->prof_info.prof_desc[aw_dev->prof_cur].sec_desc[AW_DATA_TYPE_DSP= _CFG]; struct aw_sec_data_desc *dsp_fw =3D - &aw_dev->prof_info.prof_desc[aw_dev->prof_cur].sec_desc[AW88395_DATA_TYP= E_DSP_FW]; + &aw_dev->prof_info.prof_desc[aw_dev->prof_cur].sec_desc[AW_DATA_TYPE_DSP= _FW]; int int_st; =20 - if (aw_dev->status =3D=3D AW88399_DEV_PW_OFF) { + if (aw_dev->status =3D=3D AW_DEV_PW_OFF) { dev_dbg(aw_dev->dev, "already power off"); return 0; } =20 - aw_dev->status =3D AW88399_DEV_PW_OFF; + aw_dev->status =3D AW_DEV_PW_OFF; =20 aw88399_dev_mute(aw_dev, true); - usleep_range(AW88399_4000_US, AW88399_4000_US + 100); + usleep_range(AW_4000_US, AW_4000_US + 100); =20 - aw_dev_i2s_tx_enable(aw_dev, false); - usleep_range(AW88399_1000_US, AW88399_1000_US + 100); + regmap_update_bits(aw_dev->regmap, AW88399_I2SCFG1_REG, + ~AW88399_I2STXEN_MASK, AW88399_I2STXEN_DISABLE_VALUE); + usleep_range(AW_1000_US, AW_1000_US + 100); =20 - int_st =3D aw_dev_check_sysint(aw_dev); + int_st =3D aw88399_check_sysint(aw_dev); =20 - aw_dev_dsp_enable(aw_dev, false); + regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, + ~AW88399_DSPBY_MASK, AW88399_DSPBY_BYPASS_VALUE); =20 - aw_dev_amppd(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, + ~AW88399_AMPPD_MASK, AW88399_AMPPD_POWER_DOWN_VALUE); =20 if (int_st) { - aw_dev_select_memclk(aw_dev, AW88399_DEV_MEMCLK_OSC); - aw_dev_dsp_update_fw(aw_dev, dsp_fw->data, dsp_fw->len); - aw_dev_dsp_update_cfg(aw_dev, dsp_cfg->data, dsp_cfg->len); - aw_dev_select_memclk(aw_dev, AW88399_DEV_MEMCLK_PLL); + regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG, + ~AW88399_MEM_CLKSEL_MASK, AW88399_MEM_CLKSEL_OSCCLK_VALUE); + aw_dev_dsp_update_fw(aw_dev, dsp_fw->data, dsp_fw->len, dsp_fw->addr); + aw_dev_dsp_update_cfg(aw_dev, dsp_cfg->data, dsp_cfg->len, dsp_cfg->addr= ); + regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG, + ~AW88399_MEM_CLKSEL_MASK, AW88399_MEM_CLKSEL_DAPHCLK_VALUE); } =20 - aw_dev_pwd(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, + ~AW88399_PWDN_MASK, AW88399_PWDN_POWER_DOWN_VALUE); =20 return 0; } @@ -1432,22 +962,22 @@ static int aw_cali_svc_get_cali_cfg(struct aw_device= *aw_dev) int ret; =20 ret =3D aw_dev_dsp_read(aw_dev, AW88399_DSP_REG_CFG_MBMEC_ACTAMPTH, - &cali_cfg->data[0], AW88399_DSP_32_DATA); + &cali_cfg->data[0], AW_DSP_32_DATA); if (ret) return ret; =20 ret =3D aw_dev_dsp_read(aw_dev, AW88399_DSP_REG_CFG_MBMEC_NOISEAMPTH, - &cali_cfg->data[1], AW88399_DSP_32_DATA); + &cali_cfg->data[1], AW_DSP_32_DATA); if (ret) return ret; =20 ret =3D aw_dev_dsp_read(aw_dev, AW88399_DSP_REG_CFG_ADPZ_USTEPN, - &cali_cfg->data[2], AW88399_DSP_16_DATA); + &cali_cfg->data[2], AW_DSP_16_DATA); if (ret) return ret; =20 ret =3D aw_dev_dsp_read(aw_dev, AW88399_DSP_REG_CFG_RE_ALPHA, - &cali_cfg->data[3], AW88399_DSP_16_DATA); + &cali_cfg->data[3], AW_DSP_16_DATA); =20 return ret; } @@ -1458,22 +988,22 @@ static int aw_cali_svc_set_cali_cfg(struct aw_device= *aw_dev, int ret; =20 ret =3D aw_dev_dsp_write(aw_dev, AW88399_DSP_REG_CFG_MBMEC_ACTAMPTH, - cali_cfg.data[0], AW88399_DSP_32_DATA); + cali_cfg.data[0], AW_DSP_32_DATA); if (ret) return ret; =20 ret =3D aw_dev_dsp_write(aw_dev, AW88399_DSP_REG_CFG_MBMEC_NOISEAMPTH, - cali_cfg.data[1], AW88399_DSP_32_DATA); + cali_cfg.data[1], AW_DSP_32_DATA); if (ret) return ret; =20 ret =3D aw_dev_dsp_write(aw_dev, AW88399_DSP_REG_CFG_ADPZ_USTEPN, - cali_cfg.data[2], AW88399_DSP_16_DATA); + cali_cfg.data[2], AW_DSP_16_DATA); if (ret) return ret; =20 ret =3D aw_dev_dsp_write(aw_dev, AW88399_DSP_REG_CFG_RE_ALPHA, - cali_cfg.data[3], AW88399_DSP_16_DATA); + cali_cfg.data[3], AW_DSP_16_DATA); =20 return ret; } @@ -1483,17 +1013,19 @@ static int aw_cali_svc_cali_en(struct aw_device *aw= _dev, bool cali_en) struct cali_cfg set_cfg; int ret; =20 - aw_dev_dsp_enable(aw_dev, false); + regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, + ~AW88399_DSPBY_MASK, AW88399_DSPBY_BYPASS_VALUE); if (cali_en) { regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG, - ~AW883XX_DSP_NG_EN_MASK, AW883XX_DSP_NG_EN_DISABLE_VALUE); + ~AW88399_DSP_NG_EN_MASK, AW88399_DSP_NG_EN_DISABLE_VALUE); aw_dev_dsp_write(aw_dev, AW88399_DSP_LOW_POWER_SWITCH_CFG_ADDR, - AW88399_DSP_LOW_POWER_SWITCH_DISABLE, AW88399_DSP_16_DATA); + AW88399_DSP_LOW_POWER_SWITCH_DISABLE, AW_DSP_16_DATA); =20 ret =3D aw_cali_svc_get_cali_cfg(aw_dev); if (ret) { dev_err(aw_dev->dev, "get cali cfg failed\n"); - aw_dev_dsp_enable(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, + ~AW88399_DSPBY_MASK, AW88399_DSPBY_WORKING_VALUE); return ret; } set_cfg.data[0] =3D 0; @@ -1505,14 +1037,16 @@ static int aw_cali_svc_cali_en(struct aw_device *aw= _dev, bool cali_en) if (ret) { dev_err(aw_dev->dev, "set cali cfg failed\n"); aw_cali_svc_set_cali_cfg(aw_dev, aw_dev->cali_desc.cali_cfg); - aw_dev_dsp_enable(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, + ~AW88399_DSPBY_MASK, AW88399_DSPBY_WORKING_VALUE); return ret; } } else { aw_cali_svc_set_cali_cfg(aw_dev, aw_dev->cali_desc.cali_cfg); } =20 - aw_dev_dsp_enable(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, + ~AW88399_DSPBY_MASK, AW88399_DSPBY_WORKING_VALUE); =20 return 0; } @@ -1546,10 +1080,10 @@ static void aw_cali_svc_backup_info(struct aw_devic= e *aw_dev) unsigned int reg_val, dsp_val; =20 regmap_read(aw_dev->regmap, AW88399_DBGCTRL_REG, ®_val); - backup_desc->dsp_ng_cfg =3D reg_val & (~AW883XX_DSP_NG_EN_MASK); + backup_desc->dsp_ng_cfg =3D reg_val & (~AW88399_DSP_NG_EN_MASK); =20 aw_dev_dsp_read(aw_dev, AW88399_DSP_LOW_POWER_SWITCH_CFG_ADDR, - &dsp_val, AW88399_DSP_16_DATA); + &dsp_val, AW_DSP_16_DATA); =20 backup_desc->dsp_lp_cfg =3D dsp_val; } @@ -1559,10 +1093,10 @@ static void aw_cali_svc_recover_info(struct aw_devi= ce *aw_dev) struct aw_cali_backup_desc *backup_desc =3D &aw_dev->cali_desc.backup_inf= o; =20 regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG, - ~AW883XX_DSP_NG_EN_MASK, backup_desc->dsp_ng_cfg); + ~AW88399_DSP_NG_EN_MASK, backup_desc->dsp_ng_cfg); =20 aw_dev_dsp_write(aw_dev, AW88399_DSP_LOW_POWER_SWITCH_CFG_ADDR, - backup_desc->dsp_lp_cfg, AW88399_DSP_16_DATA); + backup_desc->dsp_lp_cfg, AW_DSP_16_DATA); } =20 static int aw_cali_svc_cali_re_mode_enable(struct aw_device *aw_dev, bool = is_enable) @@ -1570,7 +1104,7 @@ static int aw_cali_svc_cali_re_mode_enable(struct aw_= device *aw_dev, bool is_ena int ret; =20 if (is_enable) { - ret =3D aw_dev_check_syspll(aw_dev); + ret =3D aw88399_check_syspll(aw_dev); if (ret) { dev_err(aw_dev->dev, "pll check failed cannot start\n"); return ret; @@ -1609,7 +1143,7 @@ static int aw_cali_svc_get_dev_re(struct aw_device *a= w_dev, uint32_t *re) uint32_t dsp_re, show_re; int ret; =20 - ret =3D aw_dev_dsp_read(aw_dev, AW88399_DSP_REG_CALRE, &dsp_re, AW88399_D= SP_16_DATA); + ret =3D aw_dev_dsp_read(aw_dev, AW88399_DSP_REG_CALRE, &dsp_re, AW_DSP_16= _DATA); if (ret) return ret; =20 @@ -1695,9 +1229,11 @@ static int aw_cali_svc_get_smooth_cali_re(struct aw_= device *aw_dev) aw_dev->cali_desc.cali_re =3D dsp_re; dev_dbg(aw_dev->dev, "re[%d]mohm\n", aw_dev->cali_desc.cali_re); =20 - aw_dev_dsp_enable(aw_dev, false); - aw_dev_update_cali_re(&aw_dev->cali_desc); - aw_dev_dsp_enable(aw_dev, true); + regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, + ~AW88399_DSPBY_MASK, AW88399_DSPBY_BYPASS_VALUE); + aw88399_update_cali_re(&aw_dev->cali_desc); + regmap_update_bits(aw_dev->regmap, AW88399_SYSCTRL_REG, + ~AW88399_DSPBY_MASK, AW88399_DSPBY_WORKING_VALUE); =20 return 0; =20 @@ -1850,7 +1386,7 @@ static int aw88399_profile_info(struct snd_kcontrol *= kcontrol, =20 count =3D uinfo->value.enumerated.item; =20 - ret =3D aw88399_dev_get_prof_name(aw88399->aw_pa, count, &prof_name); + ret =3D aw_dev_get_prof_name(aw88399->aw_pa, count, &prof_name); if (ret) { strscpy(uinfo->value.enumerated.name, "null"); return 0; @@ -1889,7 +1425,7 @@ static int aw88399_profile_set(struct snd_kcontrol *k= control, =20 if (aw88399->aw_pa->status) { aw88399_stop(aw88399->aw_pa); - aw88399_start(aw88399, AW88399_SYNC_START); + aw88399_start(aw88399, AW_SYNC_START); } =20 mutex_unlock(&aw88399->lock); @@ -1925,7 +1461,7 @@ static int aw88399_volume_set(struct snd_kcontrol *kc= ontrol, =20 if (vol_desc->ctl_volume !=3D value) { vol_desc->ctl_volume =3D value; - aw_dev_set_volume(aw88399->aw_pa, vol_desc->ctl_volume); + aw88399_set_volume(aw88399->aw_pa, vol_desc->ctl_volume); =20 return 1; } @@ -2046,86 +1582,6 @@ static int aw88399_calib_set(struct snd_kcontrol *kc= ontrol, return 0; } =20 -static int aw88399_dev_init(struct aw88399 *aw88399, struct aw_container *= aw_cfg) -{ - struct aw_device *aw_dev =3D aw88399->aw_pa; - int ret; - - ret =3D aw88395_dev_cfg_load(aw_dev, aw_cfg); - if (ret) { - dev_err(aw_dev->dev, "aw_dev acf parse failed"); - return -EINVAL; - } - aw_dev->fade_in_time =3D AW88399_1000_US / 10; - aw_dev->fade_out_time =3D AW88399_1000_US >> 1; - aw_dev->prof_cur =3D aw_dev->prof_info.prof_desc[0].id; - aw_dev->prof_index =3D aw_dev->prof_info.prof_desc[0].id; - - ret =3D aw88399_dev_fw_update(aw88399, AW88399_FORCE_UPDATE_ON, AW88399_D= SP_FW_UPDATE_ON); - if (ret) { - dev_err(aw_dev->dev, "fw update failed ret =3D %d\n", ret); - return ret; - } - - aw88399_dev_mute(aw_dev, true); - - /* close tx feedback */ - aw_dev_i2s_tx_enable(aw_dev, false); - usleep_range(AW88399_1000_US, AW88399_1000_US + 100); - - /* enable amppd */ - aw_dev_amppd(aw_dev, true); - - /* close dsp */ - aw_dev_dsp_enable(aw_dev, false); - /* set power down */ - aw_dev_pwd(aw_dev, true); - - return 0; -} - -static int aw88399_request_firmware_file(struct aw88399 *aw88399) -{ - const struct firmware *cont =3D NULL; - int ret; - - aw88399->aw_pa->fw_status =3D AW88399_DEV_FW_FAILED; - - ret =3D request_firmware(&cont, AW88399_ACF_FILE, aw88399->aw_pa->dev); - if (ret) { - dev_err(aw88399->aw_pa->dev, "request [%s] failed!", AW88399_ACF_FILE); - return ret; - } - - dev_dbg(aw88399->aw_pa->dev, "loaded %s - size: %zu\n", - AW88399_ACF_FILE, cont ? cont->size : 0); - - aw88399->aw_cfg =3D devm_kzalloc(aw88399->aw_pa->dev, - struct_size(aw88399->aw_cfg, data, cont->size), GFP_KERNEL); - if (!aw88399->aw_cfg) { - release_firmware(cont); - return -ENOMEM; - } - aw88399->aw_cfg->len =3D (int)cont->size; - memcpy(aw88399->aw_cfg->data, cont->data, cont->size); - release_firmware(cont); - - ret =3D aw88395_dev_load_acf_check(aw88399->aw_pa, aw88399->aw_cfg); - if (ret) { - dev_err(aw88399->aw_pa->dev, "load [%s] failed!", AW88399_ACF_FILE); - return ret; - } - - mutex_lock(&aw88399->lock); - /* aw device init */ - ret =3D aw88399_dev_init(aw88399, aw88399->aw_cfg); - if (ret) - dev_err(aw88399->aw_pa->dev, "dev init failed"); - mutex_unlock(&aw88399->lock); - - return ret; -} - static const struct snd_kcontrol_new aw88399_controls[] =3D { SOC_SINGLE_EXT("PCM Playback Volume", AW88399_SYSCTRL2_REG, 6, AW88399_MUTE_VOL, 0, aw88399_volume_get, @@ -2142,7 +1598,7 @@ static const struct snd_kcontrol_new aw88399_controls= [] =3D { aw88399_calib_switch_get, aw88399_calib_switch_set), SOC_SINGLE_EXT("Trigger Calib", SND_SOC_NOPM, 0, 1, 0, aw88399_calib_get, aw88399_calib_set), - AW88399_PROFILE_EXT("AW88399 Profile Set", aw88399_profile_info, + AW_PROFILE_EXT("AW88399 Profile Set", aw88399_profile_info, aw88399_profile_get, aw88399_profile_set), }; =20 @@ -2155,7 +1611,7 @@ static int aw88399_playback_event(struct snd_soc_dapm= _widget *w, mutex_lock(&aw88399->lock); switch (event) { case SND_SOC_DAPM_PRE_PMU: - aw88399_start(aw88399, AW88399_ASYNC_START); + aw88399_start(aw88399, AW_ASYNC_START); break; case SND_SOC_DAPM_POST_PMD: aw88399_stop(aw88399->aw_pa); @@ -2170,7 +1626,7 @@ static int aw88399_playback_event(struct snd_soc_dapm= _widget *w, =20 static const struct snd_soc_dapm_widget aw88399_dapm_widgets[] =3D { /* playback */ - SND_SOC_DAPM_AIF_IN_E("AIF_RX", "Speaker_Playback", 0, 0, 0, 0, + SND_SOC_DAPM_AIF_IN_E("AIF_RX", "Speaker_Playback", 0, SND_SOC_NOPM, 0, 0, aw88399_playback_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_OUTPUT("DAC Output"), @@ -2192,9 +1648,15 @@ static int aw88399_codec_probe(struct snd_soc_compon= ent *component) =20 INIT_DELAYED_WORK(&aw88399->start_work, aw88399_startup_work); =20 - ret =3D aw88399_request_firmware_file(aw88399); - if (ret) + ret =3D aw_dev_request_firmware_file(aw88399->aw_pa, AW88399_ACF_FILE); + if (ret) { dev_err(aw88399->aw_pa->dev, "%s failed\n", __func__); + return ret; + } + + ret =3D aw88399_fw_update(aw88399, AW_FORCE_UPDATE_ON, AW_DSP_FW_UPDATE_O= N); + if (ret) + dev_err(aw88399->aw_pa->dev, "fw update failed ret =3D %d\n", ret); =20 return ret; } @@ -2217,70 +1679,6 @@ static const struct snd_soc_component_driver soc_cod= ec_dev_aw88399 =3D { .num_controls =3D ARRAY_SIZE(aw88399_controls), }; =20 -static void aw88399_hw_reset(struct aw88399 *aw88399) -{ - if (aw88399->reset_gpio) { - gpiod_set_value_cansleep(aw88399->reset_gpio, 1); - usleep_range(AW88399_1000_US, AW88399_1000_US + 10); - gpiod_set_value_cansleep(aw88399->reset_gpio, 0); - usleep_range(AW88399_1000_US, AW88399_1000_US + 10); - gpiod_set_value_cansleep(aw88399->reset_gpio, 1); - usleep_range(AW88399_1000_US, AW88399_1000_US + 10); - } -} - -static void aw88399_parse_channel_dt(struct aw_device *aw_dev) -{ - struct device_node *np =3D aw_dev->dev->of_node; - u32 channel_value; - - of_property_read_u32(np, "awinic,audio-channel", &channel_value); - aw_dev->channel =3D channel_value; -} - -static int aw88399_init(struct aw88399 *aw88399, struct i2c_client *i2c, s= truct regmap *regmap) -{ - struct aw_device *aw_dev; - unsigned int chip_id; - int ret; - - ret =3D regmap_read(regmap, AW88399_ID_REG, &chip_id); - if (ret) { - dev_err(&i2c->dev, "%s read chipid error. ret =3D %d", __func__, ret); - return ret; - } - if (chip_id !=3D AW88399_CHIP_ID) { - dev_err(&i2c->dev, "unsupported device"); - return -ENXIO; - } - dev_dbg(&i2c->dev, "chip id =3D %x\n", chip_id); - - aw_dev =3D devm_kzalloc(&i2c->dev, sizeof(*aw_dev), GFP_KERNEL); - if (!aw_dev) - return -ENOMEM; - aw88399->aw_pa =3D aw_dev; - - aw_dev->i2c =3D i2c; - aw_dev->dev =3D &i2c->dev; - aw_dev->regmap =3D regmap; - mutex_init(&aw_dev->dsp_lock); - - aw_dev->chip_id =3D chip_id; - aw_dev->acf =3D NULL; - aw_dev->prof_info.prof_desc =3D NULL; - aw_dev->prof_info.count =3D 0; - aw_dev->prof_info.prof_type =3D AW88395_DEV_NONE_TYPE_ID; - aw_dev->channel =3D AW88399_DEV_DEFAULT_CH; - aw_dev->fw_status =3D AW88399_DEV_FW_FAILED; - - aw_dev->fade_step =3D AW88399_VOLUME_STEP_DB; - aw_dev->volume_desc.ctl_volume =3D AW88399_VOL_DEFAULT_VALUE; - - aw88399_parse_channel_dt(aw_dev); - - return 0; -} - static int aw88399_i2c_probe(struct i2c_client *i2c) { struct aw88399 *aw88399; @@ -2294,14 +1692,17 @@ static int aw88399_i2c_probe(struct i2c_client *i2c) return -ENOMEM; =20 mutex_init(&aw88399->lock); - i2c_set_clientdata(i2c, aw88399); =20 - aw88399->reset_gpio =3D devm_gpiod_get_optional(&i2c->dev, "reset", GPIOD= _OUT_LOW); - if (IS_ERR(aw88399->reset_gpio)) - return dev_err_probe(&i2c->dev, PTR_ERR(aw88399->reset_gpio), + aw88399->aw_pa =3D devm_kzalloc(&i2c->dev, sizeof(struct aw_device), GFP_= KERNEL); + if (!aw88399->aw_pa) + return -ENOMEM; + + aw88399->aw_pa->reset_gpio =3D devm_gpiod_get_optional(&i2c->dev, "reset"= , GPIOD_OUT_LOW); + if (IS_ERR(aw88399->aw_pa->reset_gpio)) + return dev_err_probe(&i2c->dev, PTR_ERR(aw88399->aw_pa->reset_gpio), "reset gpio not defined\n"); - aw88399_hw_reset(aw88399); + aw_hw_reset(aw88399->aw_pa); =20 aw88399->regmap =3D devm_regmap_init_i2c(i2c, &aw88399_remap_config); if (IS_ERR(aw88399->regmap)) @@ -2309,17 +1710,12 @@ static int aw88399_i2c_probe(struct i2c_client *i2c) "failed to init regmap\n"); =20 /* aw pa init */ - ret =3D aw88399_init(aw88399, i2c, aw88399->regmap); + ret =3D aw_dev_init(aw88399->aw_pa, i2c, aw88399->regmap); if (ret) return ret; =20 - ret =3D devm_snd_soc_register_component(&i2c->dev, - &soc_codec_dev_aw88399, - aw88399_dai, ARRAY_SIZE(aw88399_dai)); - if (ret) - dev_err(&i2c->dev, "failed to register aw88399: %d", ret); - - return ret; + return devm_snd_soc_register_component(&i2c->dev, &soc_codec_dev_aw88399, + aw88399_dai, ARRAY_SIZE(aw88399_dai)); } =20 static const struct i2c_device_id aw88399_i2c_id[] =3D { @@ -2339,7 +1735,6 @@ MODULE_DEVICE_TABLE(acpi, aw88399_acpi_match); static struct i2c_driver aw88399_i2c_driver =3D { .driver =3D { .name =3D AW88399_I2C_NAME, - .acpi_match_table =3D ACPI_PTR(aw88399_acpi_match), }, .probe =3D aw88399_i2c_probe, .id_table =3D aw88399_i2c_id, diff --git a/sound/soc/codecs/aw88399.h b/sound/soc/codecs/aw88399.h index cacc03b1eefa..45684513dbab 100644 --- a/sound/soc/codecs/aw88399.h +++ b/sound/soc/codecs/aw88399.h @@ -461,13 +461,13 @@ #define AW88399_DSP_VOL_MASK \ (~(((1<