From nobody Sat Dec 28 06:38:00 2024 Received: from out198-14.us.a.mail.aliyun.com (out198-14.us.a.mail.aliyun.com [47.90.198.14]) (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 E8D1128EB; Tue, 24 Dec 2024 03:19:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=47.90.198.14 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735010376; cv=none; b=OLm/k1Yq5bzsnHm61jdIlihfPC2/Wx4PciEb+EjxBEYM98ueowfGVc9phWBwMzofBjBVeJXqyEedO6muK7+1XdnHZhs8bAJ0TRBAzTPvYBL2f0No6vdUvovGXB792HXKdCLXpRTZklnfUppGs5b/oY9Qg2o9WnKnJdWdx4C3qUw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735010376; c=relaxed/simple; bh=AiwyJH3F7xFqdpOh3+7secJHibxrjCi4Mo557SWasw8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kxlMbXa9AqKxgRkHf6Kxo/mb4HLmdE1beHafkPoXCkIROPjMlQ9aZ3DFpq5r2UFkuL0wqUaIH6HHBR52oS9EQI7jq9F/T2bPEAwZRnFNAbNhMqljzCzbiUCJOue0LSnqfyZn586bLPeoMKyNNmc0y9S+hcJi7CKMFMbx5IFnlwo= 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; arc=none smtp.client-ip=47.90.198.14 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 Received: from ubuntu-VirtualBox..(mailfrom:wangweidong.a@awinic.com fp:SMTPD_---.alWruKJ_1735010345 cluster:ay29) by smtp.aliyun-inc.com; Tue, 24 Dec 2024 11:19:11 +0800 From: wangweidong.a@awinic.com To: lgirdwood@gmail.com, broonie@kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, perex@perex.cz, tiwai@suse.com, ivprusov@salutedevices.com, neil.armstrong@linaro.org, jack.yu@realtek.com, rf@opensource.cirrus.com, luca.ceresoli@bootlin.com, quic_pkumpatl@quicinc.com, herve.codina@bootlin.com, masahiroy@kernel.org, nuno.sa@analog.com, wangweidong.a@awinic.com, yesanishhere@gmail.com, linux-sound@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Cc: yijiangtao@awinic.com, Krzysztof Kozlowski Subject: [PATCH V3 1/2] ASoC: dt-bindings: Add schema for "awinic,aw88083" Date: Tue, 24 Dec 2024 11:18:22 +0800 Message-ID: <20241224031823.363777-2-wangweidong.a@awinic.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241224031823.363777-1-wangweidong.a@awinic.com> References: <20241224031823.363777-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 Add the awinic,aw88083 property to support the aw88083 chip. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Weidong Wang --- Documentation/devicetree/bindings/sound/awinic,aw88395.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/awinic,aw88395.yaml b/= Documentation/devicetree/bindings/sound/awinic,aw88395.yaml index 3b0b743e49c4..6676406bf2de 100644 --- a/Documentation/devicetree/bindings/sound/awinic,aw88395.yaml +++ b/Documentation/devicetree/bindings/sound/awinic,aw88395.yaml @@ -18,6 +18,7 @@ properties: compatible: enum: - awinic,aw88081 + - awinic,aw88083 - awinic,aw88261 - awinic,aw88395 - awinic,aw88399 @@ -58,6 +59,7 @@ allOf: contains: enum: - awinic,aw88081 + - awinic,aw88083 - awinic,aw88261 then: properties: --=20 2.47.0 From nobody Sat Dec 28 06:38:00 2024 Received: from out28-193.mail.aliyun.com (out28-193.mail.aliyun.com [115.124.28.193]) (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 E80F6149DF0; Tue, 24 Dec 2024 03:19:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.28.193 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735010372; cv=none; b=XEhXldUBrexG5xdLqj7jOBh7DR4y1/QjXmKuCKwhJNwgqfKwXTAkyYNxzBGjg8ApwGkEeOjstK5+susBn0dWXGNdbE4q7llzraeH4HJbO7PVnuIZS1dMeEVIXRp+evAo6PUP2J9Ykr16o5pMXxolHGlgHCs3kiu1Ec+5gUoMzWc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735010372; c=relaxed/simple; bh=3khdGhmio7CGGJ9BQhIndDohD7okGabrAKlkiFBUwbA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uYUGNzCPaOxzXs5liNR0X2Kp4jtTn7CEdwijtMC7wiZiZaZao7WJVMACM6+3Io2L0p0ypmKAol1NPc+wAtd8redTK0mm22/Rw+rXuVFGuh3Rb3VN/oYle9kQXGgCHLTqEO7vUL1k6DsNON9qg2kSRx1PCv+jM37+y3XNUrdCa6s= 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; arc=none smtp.client-ip=115.124.28.193 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 Received: from ubuntu-VirtualBox..(mailfrom:wangweidong.a@awinic.com fp:SMTPD_---.alWruUh_1735010351 cluster:ay29) by smtp.aliyun-inc.com; Tue, 24 Dec 2024 11:19:17 +0800 From: wangweidong.a@awinic.com To: lgirdwood@gmail.com, broonie@kernel.org, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, perex@perex.cz, tiwai@suse.com, ivprusov@salutedevices.com, neil.armstrong@linaro.org, jack.yu@realtek.com, rf@opensource.cirrus.com, luca.ceresoli@bootlin.com, quic_pkumpatl@quicinc.com, herve.codina@bootlin.com, masahiroy@kernel.org, nuno.sa@analog.com, wangweidong.a@awinic.com, yesanishhere@gmail.com, linux-sound@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Cc: yijiangtao@awinic.com, kernel test robot Subject: [PATCH V3 2/2] ASoC: codecs: Add aw88083 amplifier driver Date: Tue, 24 Dec 2024 11:18:23 +0800 Message-ID: <20241224031823.363777-3-wangweidong.a@awinic.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241224031823.363777-1-wangweidong.a@awinic.com> References: <20241224031823.363777-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 The driver is for amplifiers aw88083 of Awinic Technology Corporation. The AW88083 is an intelligent digital audio amplifier with low noise. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202412201745.fBpf3Ui5-lkp@int= el.com/ Signed-off-by: Weidong Wang --- sound/soc/codecs/Kconfig | 2 +- sound/soc/codecs/aw88081.c | 333 ++++++++++++++++++++++++++++++------- sound/soc/codecs/aw88081.h | 43 +++++ 3 files changed, 321 insertions(+), 57 deletions(-) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 0f2df7c91e18..0ba319683b6b 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -692,7 +692,7 @@ config SND_SOC_AW88261 the input amplitude. =20 config SND_SOC_AW88081 - tristate "Soc Audio for awinic aw88081" + tristate "Soc Audio for awinic aw88081/aw88083" depends on I2C select REGMAP_I2C select SND_SOC_AW88395_LIB diff --git a/sound/soc/codecs/aw88081.c b/sound/soc/codecs/aw88081.c index 58b8e002d76f..ad16ab6812cd 100644 --- a/sound/soc/codecs/aw88081.c +++ b/sound/soc/codecs/aw88081.c @@ -14,13 +14,18 @@ #include "aw88081.h" #include "aw88395/aw88395_device.h" =20 +enum aw8808x_type { + AW88081, + AW88083, +}; + struct aw88081 { struct aw_device *aw_pa; struct mutex lock; struct delayed_work start_work; struct regmap *regmap; struct aw_container *aw_cfg; - + enum aw8808x_type devtype; bool phase_sync; }; =20 @@ -32,6 +37,14 @@ static const struct regmap_config aw88081_regmap_config = =3D { .val_format_endian =3D REGMAP_ENDIAN_BIG, }; =20 +static const struct regmap_config aw88083_regmap_config =3D { + .val_bits =3D 16, + .reg_bits =3D 8, + .max_register =3D AW88083_REG_MAX, + .reg_format_endian =3D REGMAP_ENDIAN_LITTLE, + .val_format_endian =3D REGMAP_ENDIAN_BIG, +}; + static int aw88081_dev_get_iis_status(struct aw_device *aw_dev) { unsigned int reg_val; @@ -196,6 +209,41 @@ static void aw88081_dev_amppd(struct aw_device *aw_dev= , bool amppd) ~AW88081_EN_PA_MASK, AW88081_EN_PA_WORKING_VALUE); } =20 +static void aw88083_i2c_wen(struct aw88081 *aw88081, bool flag) +{ + struct aw_device *aw_dev =3D aw88081->aw_pa; + + if (aw88081->devtype !=3D AW88083) + return; + + if (flag) + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, + ~AW88083_I2C_WEN_MASK, AW88083_I2C_WEN_ENABLE_VALUE); + else + regmap_update_bits(aw_dev->regmap, AW88081_SYSCTRL_REG, + ~AW88083_I2C_WEN_MASK, AW88083_I2C_WEN_DISABLE_VALUE); +} + +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; @@ -284,12 +332,90 @@ static void aw88081_dev_uls_hmute(struct aw_device *a= w_dev, bool uls_hmute) AW88081_ULS_HMUTE_DISABLE_VALUE); } =20 +static int aw88081_dev_reg_value_check(struct aw_device *aw_dev, + unsigned char reg_addr, unsigned short *reg_val) +{ + unsigned int read_vol; + + if (reg_addr =3D=3D AW88081_SYSCTRL_REG) { + *reg_val &=3D ~(~AW88081_EN_PA_MASK | + ~AW88081_PWDN_MASK | + ~AW88081_HMUTE_MASK | + ~AW88081_ULS_HMUTE_MASK); + + *reg_val |=3D AW88081_EN_PA_POWER_DOWN_VALUE | + AW88081_PWDN_POWER_DOWN_VALUE | + AW88081_HMUTE_ENABLE_VALUE | + AW88081_ULS_HMUTE_ENABLE_VALUE; + } + + if (reg_addr =3D=3D AW88081_SYSCTRL2_REG) { + read_vol =3D (*reg_val & (~AW88081_VOL_MASK)) >> AW88081_VOL_START_BIT; + aw_dev->volume_desc.init_volume =3D read_vol; + } + + /* i2stxen */ + if (reg_addr =3D=3D AW88081_I2SCTRL3_REG) { + /* close tx */ + *reg_val &=3D AW88081_I2STXEN_MASK; + *reg_val |=3D AW88081_I2STXEN_DISABLE_VALUE; + } + + return 0; +} + +static int aw88083_dev_reg_value_check(struct aw_device *aw_dev, + unsigned char reg_addr, unsigned short *reg_val) +{ + unsigned int read_vol; + + if (reg_addr =3D=3D AW88081_SYSCTRL_REG) { + *reg_val &=3D ~(~AW88083_AMPPD_MASK | + ~AW88081_PWDN_MASK | + ~AW88081_HMUTE_MASK | + ~AW88083_I2C_WEN_MASK); + + *reg_val |=3D AW88083_AMPPD_POWER_DOWN_VALUE | + AW88081_PWDN_POWER_DOWN_VALUE | + AW88081_HMUTE_ENABLE_VALUE | + AW88083_I2C_WEN_ENABLE_VALUE; + } + + if (reg_addr =3D=3D AW88081_SYSCTRL2_REG) { + read_vol =3D (*reg_val & (~AW88081_VOL_MASK)) >> AW88081_VOL_START_BIT; + aw_dev->volume_desc.init_volume =3D read_vol; + } + + return 0; +} + +static int aw88081_reg_value_check(struct aw88081 *aw88081, + unsigned char reg_addr, unsigned short *reg_val) +{ + struct aw_device *aw_dev =3D aw88081->aw_pa; + int ret; + + switch (aw88081->devtype) { + case AW88081: + ret =3D aw88081_dev_reg_value_check(aw_dev, reg_addr, reg_val); + break; + case AW88083: + ret =3D aw88083_dev_reg_value_check(aw_dev, reg_addr, reg_val); + break; + default: + dev_err(aw_dev->dev, "unsupported device\n"); + ret =3D -EINVAL; + break; + } + + return ret; +} + static int aw88081_dev_reg_update(struct aw88081 *aw88081, unsigned char *data, unsigned int len) { struct aw_device *aw_dev =3D aw88081->aw_pa; struct aw_volume_desc *vol_desc =3D &aw_dev->volume_desc; - unsigned int read_vol; int data_len, i, ret; int16_t *reg_data; u16 reg_val; @@ -312,30 +438,9 @@ static int aw88081_dev_reg_update(struct aw88081 *aw88= 081, reg_addr =3D reg_data[i]; reg_val =3D reg_data[i + 1]; =20 - if (reg_addr =3D=3D AW88081_SYSCTRL_REG) { - reg_val &=3D ~(~AW88081_EN_PA_MASK | - ~AW88081_PWDN_MASK | - ~AW88081_HMUTE_MASK | - ~AW88081_ULS_HMUTE_MASK); - - reg_val |=3D AW88081_EN_PA_POWER_DOWN_VALUE | - AW88081_PWDN_POWER_DOWN_VALUE | - AW88081_HMUTE_ENABLE_VALUE | - AW88081_ULS_HMUTE_ENABLE_VALUE; - } - - if (reg_addr =3D=3D AW88081_SYSCTRL2_REG) { - read_vol =3D (reg_val & (~AW88081_VOL_MASK)) >> - AW88081_VOL_START_BIT; - aw_dev->volume_desc.init_volume =3D read_vol; - } - - /* i2stxen */ - if (reg_addr =3D=3D AW88081_I2SCTRL3_REG) { - /* close tx */ - reg_val &=3D AW88081_I2STXEN_MASK; - reg_val |=3D AW88081_I2STXEN_DISABLE_VALUE; - } + ret =3D aw88081_reg_value_check(aw88081, reg_addr, ®_val); + if (ret) + return ret; =20 ret =3D regmap_write(aw_dev->regmap, reg_addr, reg_val); if (ret) @@ -474,8 +579,60 @@ static int aw88081_dev_start(struct aw88081 *aw88081) return ret; } =20 -static int aw88081_dev_stop(struct aw_device *aw_dev) +static int aw88083_dev_start(struct aw88081 *aw88081) +{ + struct aw_device *aw_dev =3D aw88081->aw_pa; + + if (aw_dev->status =3D=3D AW88081_DEV_PW_ON) { + dev_dbg(aw_dev->dev, "already power on"); + return 0; + } + + aw88083_i2c_wen(aw88081, true); + + /* power on */ + aw88081_dev_pwd(aw_dev, false); + usleep_range(AW88081_2000_US, AW88081_2000_US + 10); + + aw88083_dev_pllpd(aw_dev, true); + /* amppd on */ + aw88083_dev_amppd(aw_dev, false); + usleep_range(AW88081_2000_US, AW88081_2000_US + 50); + + /* close mute */ + aw88081_dev_mute(aw_dev, false); + + aw88083_i2c_wen(aw88081, false); + + aw_dev->status =3D AW88081_DEV_PW_ON; + + return 0; +} + +static int aw88081_device_start(struct aw88081 *aw88081) +{ + int ret; + + switch (aw88081->devtype) { + case AW88081: + ret =3D aw88081_dev_start(aw88081); + break; + case AW88083: + ret =3D aw88083_dev_start(aw88081); + break; + default: + ret =3D -EINVAL; + dev_err(aw88081->aw_pa->dev, "unsupported device\n"); + break; + } + + return ret; +} + +static int aw88081_dev_stop(struct aw88081 *aw88081) { + struct aw_device *aw_dev =3D aw88081->aw_pa; + if (aw_dev->status =3D=3D AW88081_DEV_PW_OFF) { dev_dbg(aw_dev->dev, "already power off"); return 0; @@ -503,6 +660,56 @@ static int aw88081_dev_stop(struct aw_device *aw_dev) return 0; } =20 +static int aw88083_dev_stop(struct aw88081 *aw88081) +{ + struct aw_device *aw_dev =3D aw88081->aw_pa; + + if (aw_dev->status =3D=3D AW88081_DEV_PW_OFF) { + dev_dbg(aw_dev->dev, "already power off"); + return 0; + } + + aw_dev->status =3D AW88081_DEV_PW_OFF; + + aw88083_i2c_wen(aw88081, true); + /* set mute */ + aw88081_dev_mute(aw_dev, true); + + usleep_range(AW88081_2000_US, AW88081_2000_US + 100); + + /* enable amppd */ + aw88083_dev_amppd(aw_dev, true); + + aw88083_dev_pllpd(aw_dev, false); + + /* set power down */ + aw88081_dev_pwd(aw_dev, true); + + aw88083_i2c_wen(aw88081, false); + + return 0; +} + +static int aw88081_stop(struct aw88081 *aw88081) +{ + int ret; + + switch (aw88081->devtype) { + case AW88081: + ret =3D aw88081_dev_stop(aw88081); + break; + case AW88083: + ret =3D aw88083_dev_stop(aw88081); + break; + default: + dev_err(aw88081->aw_pa->dev, "unsupported device\n"); + ret =3D -EINVAL; + break; + } + + return ret; +} + static int aw88081_reg_update(struct aw88081 *aw88081, bool force) { struct aw_device *aw_dev =3D aw88081->aw_pa; @@ -540,7 +747,7 @@ static void aw88081_start_pa(struct aw88081 *aw88081) dev_err(aw88081->aw_pa->dev, "fw update failed, cnt:%d\n", i); continue; } - ret =3D aw88081_dev_start(aw88081); + ret =3D aw88081_device_start(aw88081); if (ret) { dev_err(aw88081->aw_pa->dev, "aw88081 device start failed. retry =3D %d= ", i); continue; @@ -745,7 +952,7 @@ static int aw88081_profile_set(struct snd_kcontrol *kco= ntrol, } =20 if (aw88081->aw_pa->status) { - aw88081_dev_stop(aw88081->aw_pa); + aw88081_stop(aw88081); aw88081_start(aw88081, AW88081_SYNC_START); } =20 @@ -781,12 +988,16 @@ static int aw88081_volume_set(struct snd_kcontrol *kc= ontrol, if (value < mc->min || value > mc->max) return -EINVAL; =20 + aw88083_i2c_wen(aw88081, true); + if (vol_desc->ctl_volume !=3D value) { vol_desc->ctl_volume =3D value; aw88081_dev_set_volume(aw88081->aw_pa, vol_desc->ctl_volume); return 1; } =20 + aw88083_i2c_wen(aw88081, false); + return 0; } =20 @@ -860,13 +1071,19 @@ static int aw88081_init(struct aw88081 *aw88081, str= uct i2c_client *i2c, struct dev_err(&i2c->dev, "%s read chipid error. ret =3D %d", __func__, ret); return ret; } - if (chip_id !=3D AW88081_CHIP_ID) { + + switch (chip_id) { + case AW88081_CHIP_ID: + dev_dbg(&i2c->dev, "chip id =3D 0x%x\n", chip_id); + break; + case AW88083_CHIP_ID: + dev_dbg(&i2c->dev, "chip id =3D 0x%x\n", chip_id); + break; + default: dev_err(&i2c->dev, "unsupported device"); return -ENXIO; } =20 - 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; @@ -875,7 +1092,7 @@ static int aw88081_init(struct aw88081 *aw88081, struc= t i2c_client *i2c, struct aw_dev->i2c =3D i2c; aw_dev->regmap =3D regmap; aw_dev->dev =3D &i2c->dev; - aw_dev->chip_id =3D AW88081_CHIP_ID; + 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; @@ -912,21 +1129,8 @@ static int aw88081_dev_init(struct aw88081 *aw88081, = struct aw_container *aw_cfg return ret; } =20 - aw88081_dev_clear_int_status(aw_dev); - - aw88081_dev_uls_hmute(aw_dev, true); - - aw88081_dev_mute(aw_dev, true); - - usleep_range(AW88081_5000_US, AW88081_5000_US + 10); - - aw88081_dev_i2s_tx_enable(aw_dev, false); - - usleep_range(AW88081_1000_US, AW88081_1000_US + 100); - - aw88081_dev_amppd(aw_dev, true); - - aw88081_dev_pwd(aw_dev, true); + aw_dev->status =3D AW88081_DEV_PW_ON; + aw88081_stop(aw88081); =20 return 0; } @@ -977,7 +1181,7 @@ static int aw88081_playback_event(struct snd_soc_dapm_= widget *w, aw88081_start(aw88081, AW88081_ASYNC_START); break; case SND_SOC_DAPM_POST_PMD: - aw88081_dev_stop(aw88081->aw_pa); + aw88081_stop(aw88081); break; default: break; @@ -1036,8 +1240,17 @@ static const struct snd_soc_component_driver soc_cod= ec_dev_aw88081 =3D { .num_controls =3D ARRAY_SIZE(aw88081_controls), }; =20 +static const struct i2c_device_id aw88081_i2c_id[] =3D { + { AW88081_I2C_NAME, AW88081}, + { AW88083_I2C_NAME, AW88083}, + { } +}; +MODULE_DEVICE_TABLE(i2c, aw88081_i2c_id); + static int aw88081_i2c_probe(struct i2c_client *i2c) { + const struct regmap_config *regmap_config; + const struct i2c_device_id *id; struct aw88081 *aw88081; int ret; =20 @@ -1049,11 +1262,25 @@ static int aw88081_i2c_probe(struct i2c_client *i2c) if (!aw88081) return -ENOMEM; =20 + id =3D i2c_match_id(aw88081_i2c_id, i2c); + aw88081->devtype =3D id->driver_data; + mutex_init(&aw88081->lock); =20 i2c_set_clientdata(i2c, aw88081); =20 - aw88081->regmap =3D devm_regmap_init_i2c(i2c, &aw88081_regmap_config); + switch (aw88081->devtype) { + case AW88081: + regmap_config =3D &aw88081_regmap_config; + break; + case AW88083: + regmap_config =3D &aw88083_regmap_config; + break; + default: + return -EINVAL; + } + + aw88081->regmap =3D devm_regmap_init_i2c(i2c, regmap_config); if (IS_ERR(aw88081->regmap)) return dev_err_probe(&i2c->dev, PTR_ERR(aw88081->regmap), "failed to init regmap\n"); @@ -1068,12 +1295,6 @@ static int aw88081_i2c_probe(struct i2c_client *i2c) aw88081_dai, ARRAY_SIZE(aw88081_dai)); } =20 -static const struct i2c_device_id aw88081_i2c_id[] =3D { - { AW88081_I2C_NAME }, - { } -}; -MODULE_DEVICE_TABLE(i2c, aw88081_i2c_id); - static struct i2c_driver aw88081_i2c_driver =3D { .driver =3D { .name =3D AW88081_I2C_NAME, diff --git a/sound/soc/codecs/aw88081.h b/sound/soc/codecs/aw88081.h index b4bf7288021a..c4679476f524 100644 --- a/sound/soc/codecs/aw88081.h +++ b/sound/soc/codecs/aw88081.h @@ -231,6 +231,49 @@ #define AW88081_CCO_MUX_BYPASS_VALUE \ (AW88081_CCO_MUX_BYPASS << AW88081_CCO_MUX_START_BIT) =20 +#define AW88083_I2C_WEN_START_BIT (14) +#define AW88083_I2C_WEN_BITS_LEN (2) +#define AW88083_I2C_WEN_MASK \ + (~(((1<