* [PATCH V2 0/2] ASoC: codecs: Add aw88083 amplifier driver
@ 2024-12-19 12:30 wangweidong.a
2024-12-19 12:30 ` [PATCH V2 1/2] ASoC: dt-bindings: Add schema for "awinic,aw88083" wangweidong.a
2024-12-19 12:30 ` [PATCH V2 2/2] ASoC: codecs: Add aw88083 amplifier driver wangweidong.a
0 siblings, 2 replies; 5+ messages in thread
From: wangweidong.a @ 2024-12-19 12:30 UTC (permalink / raw)
To: lgirdwood, broonie, robh, krzk+dt, conor+dt, perex, tiwai,
ivprusov, neil.armstrong, jack.yu, rf, zhoubinbin, quic_pkumpatl,
herve.codina, masahiroy, nuno.sa, wangweidong.a, yesanishhere,
linux-sound, devicetree, linux-kernel
Cc: yijiangtao
From: Weidong Wang <wangweidong.a@awinic.com>
Add the awinic,aw88083 property to support the aw88083 chip.
The driver is for amplifiers aw88083 of Awinic Technology
Corporation. The AW88083 is an intelligent digital audio
amplifier with low noise.
v1 -> v2: Use "switch" instead of "if else" to distinguish devices
Weidong Wang (2):
ASoC: dt-bindings: Add schema for "awinic,aw88083"
ASoC: codecs: Add aw88083 amplifier driver
.../bindings/sound/awinic,aw88395.yaml | 2 +
sound/soc/codecs/Kconfig | 2 +-
sound/soc/codecs/aw88081.c | 344 ++++++++++++++----
sound/soc/codecs/aw88081.h | 43 +++
4 files changed, 328 insertions(+), 63 deletions(-)
base-commit: eabcdba3ad4098460a376538df2ae36500223c1e
--
2.47.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH V2 1/2] ASoC: dt-bindings: Add schema for "awinic,aw88083"
2024-12-19 12:30 [PATCH V2 0/2] ASoC: codecs: Add aw88083 amplifier driver wangweidong.a
@ 2024-12-19 12:30 ` wangweidong.a
2024-12-19 12:30 ` [PATCH V2 2/2] ASoC: codecs: Add aw88083 amplifier driver wangweidong.a
1 sibling, 0 replies; 5+ messages in thread
From: wangweidong.a @ 2024-12-19 12:30 UTC (permalink / raw)
To: lgirdwood, broonie, robh, krzk+dt, conor+dt, perex, tiwai,
ivprusov, neil.armstrong, jack.yu, rf, zhoubinbin, quic_pkumpatl,
herve.codina, masahiroy, nuno.sa, wangweidong.a, yesanishhere,
linux-sound, devicetree, linux-kernel
Cc: yijiangtao, Krzysztof Kozlowski
From: Weidong Wang <wangweidong.a@awinic.com>
Add the awinic,aw88083 property to support the aw88083 chip.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Weidong Wang <wangweidong.a@awinic.com>
---
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:
--
2.47.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH V2 2/2] ASoC: codecs: Add aw88083 amplifier driver
2024-12-19 12:30 [PATCH V2 0/2] ASoC: codecs: Add aw88083 amplifier driver wangweidong.a
2024-12-19 12:30 ` [PATCH V2 1/2] ASoC: dt-bindings: Add schema for "awinic,aw88083" wangweidong.a
@ 2024-12-19 12:30 ` wangweidong.a
2024-12-20 10:17 ` kernel test robot
2024-12-20 13:42 ` kernel test robot
1 sibling, 2 replies; 5+ messages in thread
From: wangweidong.a @ 2024-12-19 12:30 UTC (permalink / raw)
To: lgirdwood, broonie, robh, krzk+dt, conor+dt, perex, tiwai,
ivprusov, neil.armstrong, jack.yu, rf, zhoubinbin, quic_pkumpatl,
herve.codina, masahiroy, nuno.sa, wangweidong.a, yesanishhere,
linux-sound, devicetree, linux-kernel
Cc: yijiangtao
From: Weidong Wang <wangweidong.a@awinic.com>
The driver is for amplifiers aw88083 of Awinic Technology
Corporation. The AW88083 is an intelligent digital audio
amplifier with low noise.
Signed-off-by: Weidong Wang <wangweidong.a@awinic.com>
---
sound/soc/codecs/Kconfig | 2 +-
sound/soc/codecs/aw88081.c | 344 ++++++++++++++++++++++++++++++-------
sound/soc/codecs/aw88081.h | 43 +++++
3 files changed, 326 insertions(+), 63 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.
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..dc8359074f4b 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"
+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;
};
@@ -32,6 +37,14 @@ static const struct regmap_config aw88081_regmap_config = {
.val_format_endian = REGMAP_ENDIAN_BIG,
};
+static const struct regmap_config aw88083_regmap_config = {
+ .val_bits = 16,
+ .reg_bits = 8,
+ .max_register = AW88083_REG_MAX,
+ .reg_format_endian = REGMAP_ENDIAN_LITTLE,
+ .val_format_endian = REGMAP_ENDIAN_BIG,
+};
+
static int aw88081_dev_get_iis_status(struct aw_device *aw_dev)
{
unsigned int reg_val;
@@ -176,6 +189,21 @@ static void aw88081_dev_i2s_tx_enable(struct aw_device *aw_dev, bool flag)
~AW88081_I2STXEN_MASK, AW88081_I2STXEN_DISABLE_VALUE);
}
+static void aw88083_i2c_wen(struct aw88081 *aw88081, bool flag)
+{
+ struct aw_device *aw_dev = aw88081->aw_pa;
+
+ if (aw88081->devtype != 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 aw88081_dev_pwd(struct aw_device *aw_dev, bool pwd)
{
if (pwd)
@@ -196,6 +224,26 @@ static void aw88081_dev_amppd(struct aw_device *aw_dev, bool amppd)
~AW88081_EN_PA_MASK, AW88081_EN_PA_WORKING_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,91 @@ static void aw88081_dev_uls_hmute(struct aw_device *aw_dev, bool uls_hmute)
AW88081_ULS_HMUTE_DISABLE_VALUE);
}
+static int aw88081_dev_reg_value_check(struct aw_device *aw_dev,
+ unsigned int reg_addr, unsigned int *reg_val)
+{
+ unsigned int read_vol;
+
+ if (reg_addr == AW88081_SYSCTRL_REG) {
+ *reg_val &= ~(~AW88081_EN_PA_MASK |
+ ~AW88081_PWDN_MASK |
+ ~AW88081_HMUTE_MASK |
+ ~AW88081_ULS_HMUTE_MASK);
+
+ *reg_val |= AW88081_EN_PA_POWER_DOWN_VALUE |
+ AW88081_PWDN_POWER_DOWN_VALUE |
+ AW88081_HMUTE_ENABLE_VALUE |
+ AW88081_ULS_HMUTE_ENABLE_VALUE;
+ }
+
+ if (reg_addr == AW88081_SYSCTRL2_REG) {
+ read_vol = (*reg_val & (~AW88081_VOL_MASK)) >>
+ AW88081_VOL_START_BIT;
+ aw_dev->volume_desc.init_volume = read_vol;
+ }
+
+ /* i2stxen */
+ if (reg_addr == AW88081_I2SCTRL3_REG) {
+ /* close tx */
+ *reg_val &= AW88081_I2STXEN_MASK;
+ *reg_val |= AW88081_I2STXEN_DISABLE_VALUE;
+ }
+
+ return 0;
+}
+
+static int aw88083_dev_reg_value_check(struct aw_device *aw_dev,
+ unsigned int reg_addr, unsigned int *reg_val)
+{
+ unsigned int read_vol;
+
+ if (reg_addr == AW88081_SYSCTRL_REG) {
+ *reg_val &= ~(~AW88083_AMPPD_MASK |
+ ~AW88081_PWDN_MASK |
+ ~AW88081_HMUTE_MASK |
+ ~AW88083_I2C_WEN_MASK);
+
+ *reg_val |= AW88083_AMPPD_POWER_DOWN_VALUE |
+ AW88081_PWDN_POWER_DOWN_VALUE |
+ AW88081_HMUTE_ENABLE_VALUE |
+ AW88083_I2C_WEN_ENABLE_VALUE;
+ }
+
+ if (reg_addr == AW88081_SYSCTRL2_REG) {
+ read_vol = (*reg_val & (~AW88081_VOL_MASK)) >> AW88081_VOL_START_BIT;
+ aw_dev->volume_desc.init_volume = read_vol;
+ }
+
+ return 0;
+}
+
+static int aw8808x_reg_value_check(struct aw88081 *aw88081,
+ unsigned int reg_addr, unsigned int *reg_val)
+{
+ struct aw_device *aw_dev = aw88081->aw_pa;
+ int ret;
+
+ switch (aw88081->devtype) {
+ case AW88081:
+ ret = aw88081_dev_reg_value_check(aw_dev, reg_addr, reg_val);
+ break;
+ case AW88083:
+ ret = aw88083_dev_reg_value_check(aw_dev, reg_addr, reg_val);
+ break;
+ default:
+ dev_err(aw_dev, "unsupported this device\n");
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
static int aw88081_dev_reg_update(struct aw88081 *aw88081,
unsigned char *data, unsigned int len)
{
struct aw_device *aw_dev = aw88081->aw_pa;
struct aw_volume_desc *vol_desc = &aw_dev->volume_desc;
- unsigned int read_vol;
int data_len, i, ret;
int16_t *reg_data;
u16 reg_val;
@@ -312,30 +439,9 @@ static int aw88081_dev_reg_update(struct aw88081 *aw88081,
reg_addr = reg_data[i];
reg_val = reg_data[i + 1];
- if (reg_addr == AW88081_SYSCTRL_REG) {
- reg_val &= ~(~AW88081_EN_PA_MASK |
- ~AW88081_PWDN_MASK |
- ~AW88081_HMUTE_MASK |
- ~AW88081_ULS_HMUTE_MASK);
-
- reg_val |= AW88081_EN_PA_POWER_DOWN_VALUE |
- AW88081_PWDN_POWER_DOWN_VALUE |
- AW88081_HMUTE_ENABLE_VALUE |
- AW88081_ULS_HMUTE_ENABLE_VALUE;
- }
-
- if (reg_addr == AW88081_SYSCTRL2_REG) {
- read_vol = (reg_val & (~AW88081_VOL_MASK)) >>
- AW88081_VOL_START_BIT;
- aw_dev->volume_desc.init_volume = read_vol;
- }
-
- /* i2stxen */
- if (reg_addr == AW88081_I2SCTRL3_REG) {
- /* close tx */
- reg_val &= AW88081_I2STXEN_MASK;
- reg_val |= AW88081_I2STXEN_DISABLE_VALUE;
- }
+ ret = aw8808x_reg_value_check(aw88081, reg_addr, ®_val);
+ if (ret)
+ return ret;
ret = regmap_write(aw_dev->regmap, reg_addr, reg_val);
if (ret)
@@ -474,8 +580,59 @@ static int aw88081_dev_start(struct aw88081 *aw88081)
return ret;
}
-static int aw88081_dev_stop(struct aw_device *aw_dev)
+static int aw88083_dev_start(struct aw88081 *aw88081)
+{
+ struct aw_device *aw_dev = aw88081->aw_pa;
+
+ if (aw_dev->status == 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 = AW88081_DEV_PW_ON;
+
+ return 0;
+}
+
+static int aw8808x_dev_start(struct aw88081 *aw88081)
+{
+ int ret;
+
+ switch (aw88081->devtype) {
+ case AW88081:
+ ret = aw88081_dev_start(aw88081);
+ break;
+ case AW88083:
+ ret = aw88083_dev_start(aw88081);
+ break;
+ default:
+ ret = -EINVAL;
+ dev_err(aw88081->aw_pa->dev, "unsupport device\n");
+ break;
+ }
+
+ return ret;
+}
+
+static int aw88081_dev_stop(struct aw88081 *aw88081)
{
+ struct aw_device *aw_dev = aw88081->aw_pa;
+
if (aw_dev->status == 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;
}
+static int aw88083_dev_stop(struct aw88081 *aw88081)
+{
+ struct aw_device *aw_dev = aw88081->aw_pa;
+
+ if (aw_dev->status == AW88081_DEV_PW_OFF) {
+ dev_dbg(aw_dev->dev, "already power off");
+ return 0;
+ }
+
+ aw_dev->status = 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 aw8808x_stop(struct aw88081 *aw88081)
+{
+ int ret;
+
+ switch (aw88081->devtype) {
+ case AW88081:
+ ret = aw88081_dev_stop(aw88081);
+ break;
+ case AW88083:
+ ret = aw88083_dev_stop(aw88081);
+ break;
+ default:
+ dev_err(aw88081->aw_pa->dev, "unsupport device\n");
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
static int aw88081_reg_update(struct aw88081 *aw88081, bool force)
{
struct aw_device *aw_dev = aw88081->aw_pa;
@@ -530,7 +737,7 @@ static int aw88081_reg_update(struct aw88081 *aw88081, bool force)
return 0;
}
-static void aw88081_start_pa(struct aw88081 *aw88081)
+static void aw8808x_start_pa(struct aw88081 *aw88081)
{
int ret, i;
@@ -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 = aw88081_dev_start(aw88081);
+ ret = aw8808x_dev_start(aw88081);
if (ret) {
dev_err(aw88081->aw_pa->dev, "aw88081 device start failed. retry = %d", i);
continue;
@@ -557,11 +764,11 @@ static void aw88081_startup_work(struct work_struct *work)
container_of(work, struct aw88081, start_work.work);
mutex_lock(&aw88081->lock);
- aw88081_start_pa(aw88081);
+ aw8808x_start_pa(aw88081);
mutex_unlock(&aw88081->lock);
}
-static void aw88081_start(struct aw88081 *aw88081, bool sync_start)
+static void aw8808x_start(struct aw88081 *aw88081, bool sync_start)
{
if (aw88081->aw_pa->fw_status != AW88081_DEV_FW_OK)
return;
@@ -570,7 +777,7 @@ static void aw88081_start(struct aw88081 *aw88081, bool sync_start)
return;
if (sync_start == AW88081_SYNC_START)
- aw88081_start_pa(aw88081);
+ aw8808x_start_pa(aw88081);
else
queue_delayed_work(system_wq,
&aw88081->start_work,
@@ -745,8 +952,8 @@ static int aw88081_profile_set(struct snd_kcontrol *kcontrol,
}
if (aw88081->aw_pa->status) {
- aw88081_dev_stop(aw88081->aw_pa);
- aw88081_start(aw88081, AW88081_SYNC_START);
+ aw8808x_stop(aw88081);
+ aw8808x_start(aw88081, AW88081_SYNC_START);
}
mutex_unlock(&aw88081->lock);
@@ -781,12 +988,15 @@ static int aw88081_volume_set(struct snd_kcontrol *kcontrol,
if (value < mc->min || value > mc->max)
return -EINVAL;
+ aw88083_i2c_wen(aw88081, true);
+
if (vol_desc->ctl_volume != value) {
vol_desc->ctl_volume = value;
aw88081_dev_set_volume(aw88081->aw_pa, vol_desc->ctl_volume);
return 1;
}
+ aw88083_i2c_wen(aw88081, false);
return 0;
}
@@ -860,13 +1070,19 @@ static int aw88081_init(struct aw88081 *aw88081, struct i2c_client *i2c, struct
dev_err(&i2c->dev, "%s read chipid error. ret = %d", __func__, ret);
return ret;
}
- if (chip_id != AW88081_CHIP_ID) {
+
+ switch (chip_id) {
+ case AW88081_CHIP_ID:
+ dev_dbg(&i2c->dev, "chip id = %x\n", chip_id);
+ break;
+ case AW88083_CHIP_ID:
+ dev_dbg(&i2c->dev, "chip id = %x\n", chip_id);
+ break;
+ default:
dev_err(&i2c->dev, "unsupported device");
return -ENXIO;
}
- dev_dbg(&i2c->dev, "chip id = %x\n", chip_id);
-
aw_dev = devm_kzalloc(&i2c->dev, sizeof(*aw_dev), GFP_KERNEL);
if (!aw_dev)
return -ENOMEM;
@@ -875,7 +1091,7 @@ static int aw88081_init(struct aw88081 *aw88081, struct i2c_client *i2c, struct
aw_dev->i2c = i2c;
aw_dev->regmap = regmap;
aw_dev->dev = &i2c->dev;
- aw_dev->chip_id = AW88081_CHIP_ID;
+ aw_dev->chip_id = chip_id;
aw_dev->acf = NULL;
aw_dev->prof_info.prof_desc = NULL;
aw_dev->prof_info.prof_type = AW88395_DEV_NONE_TYPE_ID;
@@ -912,21 +1128,8 @@ static int aw88081_dev_init(struct aw88081 *aw88081, struct aw_container *aw_cfg
return ret;
}
- 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 = AW88081_DEV_PW_ON;
+ aw8808x_stop(aw88081);
return 0;
}
@@ -974,10 +1177,10 @@ 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);
+ aw8808x_start(aw88081, AW88081_ASYNC_START);
break;
case SND_SOC_DAPM_POST_PMD:
- aw88081_dev_stop(aw88081->aw_pa);
+ aw8808x_stop(aw88081);
break;
default:
break;
@@ -1036,8 +1239,17 @@ static const struct snd_soc_component_driver soc_codec_dev_aw88081 = {
.num_controls = ARRAY_SIZE(aw88081_controls),
};
+static const struct i2c_device_id aw88081_i2c_id[] = {
+ { 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;
@@ -1049,11 +1261,25 @@ static int aw88081_i2c_probe(struct i2c_client *i2c)
if (!aw88081)
return -ENOMEM;
+ id = i2c_match_id(aw88081_i2c_id, i2c);
+ aw88081->devtype = id->driver_data;
+
mutex_init(&aw88081->lock);
i2c_set_clientdata(i2c, aw88081);
- aw88081->regmap = devm_regmap_init_i2c(i2c, &aw88081_regmap_config);
+ switch (aw88081->devtype) {
+ case AW88081:
+ regmap_config = &aw88081_regmap_config;
+ break;
+ case AW88083:
+ regmap_config = &aw88083_regmap_config;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ aw88081->regmap = 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 +1294,6 @@ static int aw88081_i2c_probe(struct i2c_client *i2c)
aw88081_dai, ARRAY_SIZE(aw88081_dai));
}
-static const struct i2c_device_id aw88081_i2c_id[] = {
- { AW88081_I2C_NAME },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, aw88081_i2c_id);
-
static struct i2c_driver aw88081_i2c_driver = {
.driver = {
.name = 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)
+#define AW88083_I2C_WEN_START_BIT (14)
+#define AW88083_I2C_WEN_BITS_LEN (2)
+#define AW88083_I2C_WEN_MASK \
+ (~(((1<<AW88083_I2C_WEN_BITS_LEN)-1) << AW88083_I2C_WEN_START_BIT))
+
+#define AW88083_I2C_WEN_DISABLE (0)
+#define AW88083_I2C_WEN_DISABLE_VALUE \
+ (AW88083_I2C_WEN_DISABLE << AW88083_I2C_WEN_START_BIT)
+
+#define AW88083_I2C_WEN_ENABLE (2)
+#define AW88083_I2C_WEN_ENABLE_VALUE \
+ (AW88083_I2C_WEN_ENABLE << AW88083_I2C_WEN_START_BIT)
+
+#define AW88083_PLL_PD_START_BIT (2)
+#define AW88083_PLL_PD_BITS_LEN (1)
+#define AW88083_PLL_PD_MASK \
+ (~(((1<<AW88083_PLL_PD_BITS_LEN)-1) << AW88083_PLL_PD_START_BIT))
+
+#define AW88083_PLL_PD_POWER_DOWN (1)
+#define AW88083_PLL_PD_POWER_DOWN_VALUE \
+ (AW88083_PLL_PD_POWER_DOWN << AW88083_PLL_PD_START_BIT)
+
+#define AW88083_PLL_PD_WORKING (0)
+#define AW88083_PLL_PD_WORKING_VALUE \
+ (AW88083_PLL_PD_WORKING << AW88083_PLL_PD_START_BIT)
+
+#define AW88083_AMPPD_START_BIT (1)
+#define AW88083_AMPPD_BITS_LEN (1)
+#define AW88083_AMPPD_MASK \
+ (~(((1<<AW88083_AMPPD_BITS_LEN)-1) << AW88083_AMPPD_START_BIT))
+
+#define AW88083_AMPPD_WORKING (0)
+#define AW88083_AMPPD_WORKING_VALUE \
+ (AW88083_AMPPD_WORKING << AW88083_AMPPD_START_BIT)
+
+#define AW88083_AMPPD_POWER_DOWN (1)
+#define AW88083_AMPPD_POWER_DOWN_VALUE \
+ (AW88083_AMPPD_POWER_DOWN << AW88083_AMPPD_START_BIT)
+
+#define AW88083_REG_MAX (0x7D)
+#define AW88083_I2C_NAME "aw88083"
+#define AW88083_CHIP_ID 0x2407
+
#define AW88081_START_RETRIES (5)
#define AW88081_START_WORK_DELAY_MS (0)
--
2.47.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH V2 2/2] ASoC: codecs: Add aw88083 amplifier driver
2024-12-19 12:30 ` [PATCH V2 2/2] ASoC: codecs: Add aw88083 amplifier driver wangweidong.a
@ 2024-12-20 10:17 ` kernel test robot
2024-12-20 13:42 ` kernel test robot
1 sibling, 0 replies; 5+ messages in thread
From: kernel test robot @ 2024-12-20 10:17 UTC (permalink / raw)
To: wangweidong.a, lgirdwood, broonie, robh, krzk+dt, conor+dt, perex,
tiwai, ivprusov, neil.armstrong, jack.yu, rf, zhoubinbin,
quic_pkumpatl, herve.codina, masahiroy, nuno.sa, yesanishhere,
linux-sound, devicetree, linux-kernel
Cc: oe-kbuild-all, yijiangtao
Hi,
kernel test robot noticed the following build errors:
[auto build test ERROR on eabcdba3ad4098460a376538df2ae36500223c1e]
url: https://github.com/intel-lab-lkp/linux/commits/wangweidong-a-awinic-com/ASoC-dt-bindings-Add-schema-for-awinic-aw88083/20241219-203933
base: eabcdba3ad4098460a376538df2ae36500223c1e
patch link: https://lore.kernel.org/r/20241219123047.33330-3-wangweidong.a%40awinic.com
patch subject: [PATCH V2 2/2] ASoC: codecs: Add aw88083 amplifier driver
config: arc-randconfig-002-20241220 (https://download.01.org/0day-ci/archive/20241220/202412201745.fBpf3Ui5-lkp@intel.com/config)
compiler: arc-elf-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241220/202412201745.fBpf3Ui5-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202412201745.fBpf3Ui5-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from include/linux/device.h:15,
from include/linux/acpi.h:14,
from include/linux/i2c.h:13,
from sound/soc/codecs/aw88081.c:11:
sound/soc/codecs/aw88081.c: In function 'aw8808x_reg_value_check':
>> sound/soc/codecs/aw88081.c:407:25: error: passing argument 1 of '_dev_err' from incompatible pointer type [-Werror=incompatible-pointer-types]
407 | dev_err(aw_dev, "unsupported this device\n");
| ^~~~~~
| |
| struct aw_device *
include/linux/dev_printk.h:110:25: note: in definition of macro 'dev_printk_index_wrap'
110 | _p_func(dev, fmt, ##__VA_ARGS__); \
| ^~~
sound/soc/codecs/aw88081.c:407:17: note: in expansion of macro 'dev_err'
407 | dev_err(aw_dev, "unsupported this device\n");
| ^~~~~~~
include/linux/dev_printk.h:50:36: note: expected 'const struct device *' but argument is of type 'struct aw_device *'
50 | void _dev_err(const struct device *dev, const char *fmt, ...);
| ~~~~~~~~~~~~~~~~~~~~~^~~
sound/soc/codecs/aw88081.c: In function 'aw88081_dev_reg_update':
>> sound/soc/codecs/aw88081.c:442:66: error: passing argument 3 of 'aw8808x_reg_value_check' from incompatible pointer type [-Werror=incompatible-pointer-types]
442 | ret = aw8808x_reg_value_check(aw88081, reg_addr, ®_val);
| ^~~~~~~~
| |
| u16 * {aka short unsigned int *}
sound/soc/codecs/aw88081.c:394:78: note: expected 'unsigned int *' but argument is of type 'u16 *' {aka 'short unsigned int *'}
394 | unsigned int reg_addr, unsigned int *reg_val)
| ~~~~~~~~~~~~~~^~~~~~~
cc1: some warnings being treated as errors
vim +/_dev_err +407 sound/soc/codecs/aw88081.c
392
393 static int aw8808x_reg_value_check(struct aw88081 *aw88081,
394 unsigned int reg_addr, unsigned int *reg_val)
395 {
396 struct aw_device *aw_dev = aw88081->aw_pa;
397 int ret;
398
399 switch (aw88081->devtype) {
400 case AW88081:
401 ret = aw88081_dev_reg_value_check(aw_dev, reg_addr, reg_val);
402 break;
403 case AW88083:
404 ret = aw88083_dev_reg_value_check(aw_dev, reg_addr, reg_val);
405 break;
406 default:
> 407 dev_err(aw_dev, "unsupported this device\n");
408 ret = -EINVAL;
409 break;
410 }
411
412 return ret;
413 }
414
415 static int aw88081_dev_reg_update(struct aw88081 *aw88081,
416 unsigned char *data, unsigned int len)
417 {
418 struct aw_device *aw_dev = aw88081->aw_pa;
419 struct aw_volume_desc *vol_desc = &aw_dev->volume_desc;
420 int data_len, i, ret;
421 int16_t *reg_data;
422 u16 reg_val;
423 u8 reg_addr;
424
425 if (!len || !data) {
426 dev_err(aw_dev->dev, "reg data is null or len is 0");
427 return -EINVAL;
428 }
429
430 reg_data = (int16_t *)data;
431 data_len = len >> 1;
432
433 if (data_len & 0x1) {
434 dev_err(aw_dev->dev, "data len:%d unsupported", data_len);
435 return -EINVAL;
436 }
437
438 for (i = 0; i < data_len; i += 2) {
439 reg_addr = reg_data[i];
440 reg_val = reg_data[i + 1];
441
> 442 ret = aw8808x_reg_value_check(aw88081, reg_addr, ®_val);
443 if (ret)
444 return ret;
445
446 ret = regmap_write(aw_dev->regmap, reg_addr, reg_val);
447 if (ret)
448 return ret;
449 }
450
451 if (aw_dev->prof_cur != aw_dev->prof_index)
452 vol_desc->ctl_volume = 0;
453
454 /* keep min volume */
455 aw88081_dev_set_volume(aw_dev, vol_desc->mute_volume);
456
457 return 0;
458 }
459
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH V2 2/2] ASoC: codecs: Add aw88083 amplifier driver
2024-12-19 12:30 ` [PATCH V2 2/2] ASoC: codecs: Add aw88083 amplifier driver wangweidong.a
2024-12-20 10:17 ` kernel test robot
@ 2024-12-20 13:42 ` kernel test robot
1 sibling, 0 replies; 5+ messages in thread
From: kernel test robot @ 2024-12-20 13:42 UTC (permalink / raw)
To: wangweidong.a, lgirdwood, broonie, robh, krzk+dt, conor+dt, perex,
tiwai, ivprusov, neil.armstrong, jack.yu, rf, zhoubinbin,
quic_pkumpatl, herve.codina, masahiroy, nuno.sa, yesanishhere,
linux-sound, devicetree, linux-kernel
Cc: llvm, oe-kbuild-all, yijiangtao
Hi,
kernel test robot noticed the following build errors:
[auto build test ERROR on eabcdba3ad4098460a376538df2ae36500223c1e]
url: https://github.com/intel-lab-lkp/linux/commits/wangweidong-a-awinic-com/ASoC-dt-bindings-Add-schema-for-awinic-aw88083/20241219-203933
base: eabcdba3ad4098460a376538df2ae36500223c1e
patch link: https://lore.kernel.org/r/20241219123047.33330-3-wangweidong.a%40awinic.com
patch subject: [PATCH V2 2/2] ASoC: codecs: Add aw88083 amplifier driver
config: i386-randconfig-014-20241220 (https://download.01.org/0day-ci/archive/20241220/202412202139.OayEq3D3-lkp@intel.com/config)
compiler: clang version 19.1.3 (https://github.com/llvm/llvm-project ab51eccf88f5321e7c60591c5546b254b6afab99)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241220/202412202139.OayEq3D3-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202412202139.OayEq3D3-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from sound/soc/codecs/aw88081.c:11:
In file included from include/linux/i2c.h:19:
In file included from include/linux/regulator/consumer.h:35:
In file included from include/linux/suspend.h:5:
In file included from include/linux/swap.h:9:
In file included from include/linux/memcontrol.h:21:
In file included from include/linux/mm.h:2223:
include/linux/vmstat.h:518:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
518 | return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
| ~~~~~~~~~~~ ^ ~~~
>> sound/soc/codecs/aw88081.c:407:11: error: incompatible pointer types passing 'struct aw_device *' to parameter of type 'const struct device *' [-Werror,-Wincompatible-pointer-types]
407 | dev_err(aw_dev, "unsupported this device\n");
| ^~~~~~
include/linux/dev_printk.h:154:44: note: expanded from macro 'dev_err'
154 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__)
| ^~~
include/linux/dev_printk.h:110:11: note: expanded from macro 'dev_printk_index_wrap'
110 | _p_func(dev, fmt, ##__VA_ARGS__); \
| ^~~
include/linux/dev_printk.h:50:36: note: passing argument to parameter 'dev' here
50 | void _dev_err(const struct device *dev, const char *fmt, ...);
| ^
>> sound/soc/codecs/aw88081.c:442:52: error: incompatible pointer types passing 'u16 *' (aka 'unsigned short *') to parameter of type 'unsigned int *' [-Werror,-Wincompatible-pointer-types]
442 | ret = aw8808x_reg_value_check(aw88081, reg_addr, ®_val);
| ^~~~~~~~
sound/soc/codecs/aw88081.c:394:43: note: passing argument to parameter 'reg_val' here
394 | unsigned int reg_addr, unsigned int *reg_val)
| ^
1 warning and 2 errors generated.
vim +407 sound/soc/codecs/aw88081.c
392
393 static int aw8808x_reg_value_check(struct aw88081 *aw88081,
394 unsigned int reg_addr, unsigned int *reg_val)
395 {
396 struct aw_device *aw_dev = aw88081->aw_pa;
397 int ret;
398
399 switch (aw88081->devtype) {
400 case AW88081:
401 ret = aw88081_dev_reg_value_check(aw_dev, reg_addr, reg_val);
402 break;
403 case AW88083:
404 ret = aw88083_dev_reg_value_check(aw_dev, reg_addr, reg_val);
405 break;
406 default:
> 407 dev_err(aw_dev, "unsupported this device\n");
408 ret = -EINVAL;
409 break;
410 }
411
412 return ret;
413 }
414
415 static int aw88081_dev_reg_update(struct aw88081 *aw88081,
416 unsigned char *data, unsigned int len)
417 {
418 struct aw_device *aw_dev = aw88081->aw_pa;
419 struct aw_volume_desc *vol_desc = &aw_dev->volume_desc;
420 int data_len, i, ret;
421 int16_t *reg_data;
422 u16 reg_val;
423 u8 reg_addr;
424
425 if (!len || !data) {
426 dev_err(aw_dev->dev, "reg data is null or len is 0");
427 return -EINVAL;
428 }
429
430 reg_data = (int16_t *)data;
431 data_len = len >> 1;
432
433 if (data_len & 0x1) {
434 dev_err(aw_dev->dev, "data len:%d unsupported", data_len);
435 return -EINVAL;
436 }
437
438 for (i = 0; i < data_len; i += 2) {
439 reg_addr = reg_data[i];
440 reg_val = reg_data[i + 1];
441
> 442 ret = aw8808x_reg_value_check(aw88081, reg_addr, ®_val);
443 if (ret)
444 return ret;
445
446 ret = regmap_write(aw_dev->regmap, reg_addr, reg_val);
447 if (ret)
448 return ret;
449 }
450
451 if (aw_dev->prof_cur != aw_dev->prof_index)
452 vol_desc->ctl_volume = 0;
453
454 /* keep min volume */
455 aw88081_dev_set_volume(aw_dev, vol_desc->mute_volume);
456
457 return 0;
458 }
459
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2024-12-20 13:43 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-19 12:30 [PATCH V2 0/2] ASoC: codecs: Add aw88083 amplifier driver wangweidong.a
2024-12-19 12:30 ` [PATCH V2 1/2] ASoC: dt-bindings: Add schema for "awinic,aw88083" wangweidong.a
2024-12-19 12:30 ` [PATCH V2 2/2] ASoC: codecs: Add aw88083 amplifier driver wangweidong.a
2024-12-20 10:17 ` kernel test robot
2024-12-20 13:42 ` kernel test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox