* [PATCH V2 0/3] Anbernic RG-DS AW87391 Speaker Amps
@ 2026-01-28 17:46 Chris Morgan
2026-01-28 17:46 ` [PATCH V2 1/3] ASoC: dt-bindings: aw87390: Add Anbernic RG-DS Amplifier Chris Morgan
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Chris Morgan @ 2026-01-28 17:46 UTC (permalink / raw)
To: linux-sound
Cc: devicetree, wangweidong.a, tiwai, perex, conor+dt, krzk+dt, robh,
broonie, lgirdwood, heiko, linux-rockchip, Chris Morgan
From: Chris Morgan <macromorgan@hotmail.com>
Add support for the Anbernic RG-DS Speaker Amplifiers. The Anbernic
RG-DS uses two AW87391 ICs at 0x58 and 0x5B on i2c2. However, the
manufacturer did not provide a firmware file, only a sequence of
register writes to each device to enable and disable them.
Add support for this *specific* configuration in the AW87390 driver.
Since we are relying on a device specific sequence I am using a
device specific compatible string. This driver does not currently
support the aw87391 for any other device as I have none to test
with valid firmware. Attempts to create firmware with the AwinicSCPv4
have not been successful.
Changes since V1:
- Correct an uninitalized ret value error identified by kernel test
robot. [1]
https://lore.kernel.org/oe-kbuild-all/202601240757.gYdQGsXp-lkp@intel.com/
- Added devicetree binding for the Anbernic RG-DS. This is based on
the following commit that has since been accepted. [2]
[1] https://lore.kernel.org/oe-kbuild-all/202601240757.gYdQGsXp-lkp@intel.com/
[2] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit?id=9e3f8ae040009f66367b2ba1081b7e313b39aeff
Chris Morgan (3):
ASoC: dt-bindings: aw87390: Add Anbernic RG-DS Amplifier
ASoC: codecs: aw87390: Add Anbernic RG-DS amp driver
arm64: dts: rockchip: add Awinic aw87391 for Anbernic RG-DS
.../bindings/sound/awinic,aw87390.yaml | 34 +++-
.../dts/rockchip/rk3568-anbernic-rg-ds.dts | 44 ++++-
sound/soc/codecs/aw87390.c | 175 +++++++++++++++++-
sound/soc/codecs/aw87390.h | 86 +++++++++
4 files changed, 322 insertions(+), 17 deletions(-)
--
2.43.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH V2 1/3] ASoC: dt-bindings: aw87390: Add Anbernic RG-DS Amplifier
2026-01-28 17:46 [PATCH V2 0/3] Anbernic RG-DS AW87391 Speaker Amps Chris Morgan
@ 2026-01-28 17:46 ` Chris Morgan
2026-01-28 17:46 ` [PATCH V2 2/3] ASoC: codecs: aw87390: Add Anbernic RG-DS amp driver Chris Morgan
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Chris Morgan @ 2026-01-28 17:46 UTC (permalink / raw)
To: linux-sound
Cc: devicetree, wangweidong.a, tiwai, perex, conor+dt, krzk+dt, robh,
broonie, lgirdwood, heiko, linux-rockchip, Chris Morgan,
Conor Dooley
From: Chris Morgan <macromorgan@hotmail.com>
Add a binding for the Anbernic RG-DS Amplifier, which is an Awinic
aw87391 audio amplifier. This manufacturer did not provide firmware
so we have to use a list of init commands instead, requiring device
specific functionality rather than generic aw87391 functionality.
Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
---
.../bindings/sound/awinic,aw87390.yaml | 34 ++++++++++++++++---
1 file changed, 29 insertions(+), 5 deletions(-)
diff --git a/Documentation/devicetree/bindings/sound/awinic,aw87390.yaml b/Documentation/devicetree/bindings/sound/awinic,aw87390.yaml
index ba9d8767c5d5..9c1baae767c4 100644
--- a/Documentation/devicetree/bindings/sound/awinic,aw87390.yaml
+++ b/Documentation/devicetree/bindings/sound/awinic,aw87390.yaml
@@ -15,12 +15,15 @@ description:
sound quallity, which is a new high efficiency, low
noise, constant large volume, 6th Smart K audio amplifier.
-allOf:
- - $ref: dai-common.yaml#
-
properties:
compatible:
- const: awinic,aw87390
+ oneOf:
+ - enum:
+ - awinic,aw87390
+ - items:
+ - enum:
+ - anbernic,rgds-amp
+ - const: awinic,aw87391
reg:
maxItems: 1
@@ -40,10 +43,31 @@ required:
- compatible
- reg
- "#sound-dai-cells"
- - awinic,audio-channel
unevaluatedProperties: false
+allOf:
+ - $ref: dai-common.yaml#
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - awinic,aw87390
+ then:
+ required:
+ - awinic,audio-channel
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - anbernic,rgds-amp
+ then:
+ properties:
+ vdd-supply: true
+
examples:
- |
i2c {
--
2.43.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH V2 2/3] ASoC: codecs: aw87390: Add Anbernic RG-DS amp driver
2026-01-28 17:46 [PATCH V2 0/3] Anbernic RG-DS AW87391 Speaker Amps Chris Morgan
2026-01-28 17:46 ` [PATCH V2 1/3] ASoC: dt-bindings: aw87390: Add Anbernic RG-DS Amplifier Chris Morgan
@ 2026-01-28 17:46 ` Chris Morgan
2026-01-28 17:46 ` [PATCH V2 3/3] arm64: dts: rockchip: add Awinic aw87391 for Anbernic RG-DS Chris Morgan
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Chris Morgan @ 2026-01-28 17:46 UTC (permalink / raw)
To: linux-sound
Cc: devicetree, wangweidong.a, tiwai, perex, conor+dt, krzk+dt, robh,
broonie, lgirdwood, heiko, linux-rockchip, Chris Morgan
From: Chris Morgan <macromorgan@hotmail.com>
Add support for Anbernic's RG-DS audio amplifiers, powered by
Awinic AW87391 amplifier ICs. These chips typically require an
init sequence provided by firmware, but the manufacturer did not
provide firmware in this case. As a result we had to hard-code
the init sequence and use a device specific binding (rather than
a binding just for the aw87391).
Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
---
sound/soc/codecs/aw87390.c | 175 +++++++++++++++++++++++++++++++++++--
sound/soc/codecs/aw87390.h | 86 ++++++++++++++++++
2 files changed, 253 insertions(+), 8 deletions(-)
diff --git a/sound/soc/codecs/aw87390.c b/sound/soc/codecs/aw87390.c
index d7fd865c349f..613daccca3af 100644
--- a/sound/soc/codecs/aw87390.c
+++ b/sound/soc/codecs/aw87390.c
@@ -314,6 +314,45 @@ static int aw87390_drv_event(struct snd_soc_dapm_widget *w,
return ret;
}
+static int aw87391_rgds_drv_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+ struct aw87390 *aw87390 = snd_soc_component_get_drvdata(component);
+ struct aw_device *aw_dev = aw87390->aw_pa;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ if (!IS_ERR(aw87390->vdd_reg)) {
+ if (regulator_enable(aw87390->vdd_reg))
+ dev_warn(aw_dev->dev, "Failed to enable vdd\n");
+ }
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ regmap_write(aw_dev->regmap, AW87391_SYSCTRL_REG,
+ AW87391_REG_VER_SEL_LOW | AW87391_REG_EN_ADAP |
+ AW87391_REG_EN_2X | AW87391_EN_SPK |
+ AW87391_EN_PA | AW87391_REG_EN_CP |
+ AW87391_EN_SW);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ regmap_write(aw_dev->regmap, AW87390_SYSCTRL_REG,
+ AW87390_POWER_DOWN_VALUE);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ if (!IS_ERR(aw87390->vdd_reg)) {
+ if (regulator_disable(aw87390->vdd_reg))
+ dev_warn(aw_dev->dev, "Failed to disable vdd\n");
+ }
+ break;
+ default:
+ dev_err(aw_dev->dev, "%s: invalid event %d\n", __func__, event);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static const struct snd_soc_dapm_widget aw87390_dapm_widgets[] = {
SND_SOC_DAPM_INPUT("IN"),
SND_SOC_DAPM_PGA_E("SPK PA", SND_SOC_NOPM, 0, 0, NULL, 0, aw87390_drv_event,
@@ -321,6 +360,14 @@ static const struct snd_soc_dapm_widget aw87390_dapm_widgets[] = {
SND_SOC_DAPM_OUTPUT("OUT"),
};
+static const struct snd_soc_dapm_widget aw87391_rgds_dapm_widgets[] = {
+ SND_SOC_DAPM_INPUT("IN"),
+ SND_SOC_DAPM_PGA_E("SPK PA", SND_SOC_NOPM, 0, 0, NULL, 0, aw87391_rgds_drv_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_OUTPUT("OUT"),
+};
+
static const struct snd_soc_dapm_route aw87390_dapm_routes[] = {
{ "SPK PA", NULL, "IN" },
{ "OUT", NULL, "SPK PA" },
@@ -339,6 +386,80 @@ static int aw87390_codec_probe(struct snd_soc_component *component)
return 0;
}
+/*
+ * Firmware typically is used to load the sequence of init commands,
+ * however for the Anbernic RG-DS we don't have a firmware file just
+ * a list of registers and values. Most of these values are undocumented
+ * in the AW87391 datasheet.
+ */
+static void aw87391_rgds_codec_init(struct aw87390 *aw87390)
+{
+ struct aw_device *aw_dev = aw87390->aw_pa;
+
+ /* Undocumented command per datasheet. */
+ regmap_write(aw_dev->regmap, 0x64, 0x3a);
+
+ /* Bits 7:4 are undocumented but provided by manufacturer. */
+ regmap_write(aw_dev->regmap, AW87391_CP_REG,
+ (5 << 4) | AW87391_REG_CP_OVP_8_50V);
+
+ regmap_write(aw_dev->regmap, AW87391_AGCPO_REG,
+ AW87391_AK1_S_016 | AW87391_AGC2PO_MW(500));
+
+ regmap_write(aw_dev->regmap, AW87391_AGC2PA_REG,
+ AW87391_RK_S_20_48 | AW87391_AK2_S_41 | AW87391_AK2F_S_41);
+
+ /* Undocumented commands per datasheet. */
+ regmap_write(aw_dev->regmap, 0x5d, 0x00);
+ regmap_write(aw_dev->regmap, 0x5e, 0xb4);
+ regmap_write(aw_dev->regmap, 0x5f, 0x30);
+ regmap_write(aw_dev->regmap, 0x60, 0x39);
+ regmap_write(aw_dev->regmap, 0x61, 0x10);
+ regmap_write(aw_dev->regmap, 0x62, 0x03);
+ regmap_write(aw_dev->regmap, 0x63, 0x7d);
+ regmap_write(aw_dev->regmap, 0x65, 0xa0);
+ regmap_write(aw_dev->regmap, 0x66, 0x21);
+ regmap_write(aw_dev->regmap, 0x67, 0x41);
+ regmap_write(aw_dev->regmap, 0x68, 0x3b);
+ regmap_write(aw_dev->regmap, 0x6e, 0x00);
+ regmap_write(aw_dev->regmap, 0x6f, 0x00);
+ regmap_write(aw_dev->regmap, 0x70, 0x00);
+ regmap_write(aw_dev->regmap, 0x71, 0x00);
+ regmap_write(aw_dev->regmap, 0x72, 0x34);
+ regmap_write(aw_dev->regmap, 0x73, 0x06);
+ regmap_write(aw_dev->regmap, 0x74, 0x10);
+ regmap_write(aw_dev->regmap, 0x75, 0x00);
+ regmap_write(aw_dev->regmap, 0x7a, 0x00);
+ regmap_write(aw_dev->regmap, 0x7b, 0x00);
+ regmap_write(aw_dev->regmap, 0x7c, 0x00);
+ regmap_write(aw_dev->regmap, 0x7d, 0x00);
+
+ regmap_write(aw_dev->regmap, AW87391_PAG_REG, AW87391_GAIN_12DB);
+ regmap_write(aw_dev->regmap, AW87391_SYSCTRL_REG,
+ AW87391_EN_PA | AW87391_REG_EN_CP | AW87391_EN_SW);
+ regmap_write(aw_dev->regmap, AW87391_SYSCTRL_REG,
+ AW87391_REG_VER_SEL_LOW | AW87391_REG_EN_ADAP |
+ AW87391_REG_EN_2X | AW87391_EN_SPK | AW87391_EN_PA |
+ AW87391_REG_EN_CP | AW87391_EN_SW);
+ regmap_write(aw_dev->regmap, AW87391_PAG_REG, AW87391_GAIN_15DB);
+}
+
+static int aw87391_rgds_codec_probe(struct snd_soc_component *component)
+{
+ struct aw87390 *aw87390 = snd_soc_component_get_drvdata(component);
+
+ aw87390->vdd_reg = devm_regulator_get_optional(aw87390->aw_pa->dev,
+ "vdd");
+ if (IS_ERR(aw87390->vdd_reg) && PTR_ERR(aw87390->vdd_reg) != -ENODEV)
+ return dev_err_probe(aw87390->aw_pa->dev,
+ PTR_ERR(aw87390->vdd_reg),
+ "Could not get vdd regulator\n");
+
+ aw87391_rgds_codec_init(aw87390);
+
+ return 0;
+}
+
static const struct snd_soc_component_driver soc_codec_dev_aw87390 = {
.probe = aw87390_codec_probe,
.dapm_widgets = aw87390_dapm_widgets,
@@ -349,6 +470,14 @@ static const struct snd_soc_component_driver soc_codec_dev_aw87390 = {
.num_controls = ARRAY_SIZE(aw87390_controls),
};
+static const struct snd_soc_component_driver soc_codec_dev_anbernic_rgds = {
+ .probe = aw87391_rgds_codec_probe,
+ .dapm_widgets = aw87391_rgds_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(aw87391_rgds_dapm_widgets),
+ .dapm_routes = aw87390_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(aw87390_dapm_routes),
+};
+
static void aw87390_parse_channel_dt(struct aw87390 *aw87390)
{
struct aw_device *aw_dev = aw87390->aw_pa;
@@ -366,6 +495,10 @@ static int aw87390_init(struct aw87390 *aw87390, struct i2c_client *i2c, struct
unsigned int chip_id;
int ret;
+ aw_dev = devm_kzalloc(&i2c->dev, sizeof(*aw_dev), GFP_KERNEL);
+ if (!aw_dev)
+ return -ENOMEM;
+
/* read chip id */
ret = regmap_read(regmap, AW87390_ID_REG, &chip_id);
if (ret) {
@@ -373,22 +506,24 @@ static int aw87390_init(struct aw87390 *aw87390, struct i2c_client *i2c, struct
return ret;
}
- if (chip_id != AW87390_CHIP_ID) {
+ switch (chip_id) {
+ case AW87390_CHIP_ID:
+ aw_dev->chip_id = AW87390_CHIP_ID;
+ break;
+ case AW87391_CHIP_ID:
+ aw_dev->chip_id = AW87391_CHIP_ID;
+ break;
+ default:
dev_err(&i2c->dev, "unsupported device\n");
return -ENXIO;
}
dev_dbg(&i2c->dev, "chip id = 0x%x\n", chip_id);
- aw_dev = devm_kzalloc(&i2c->dev, sizeof(*aw_dev), GFP_KERNEL);
- if (!aw_dev)
- return -ENOMEM;
-
aw87390->aw_pa = aw_dev;
aw_dev->i2c = i2c;
aw_dev->regmap = regmap;
aw_dev->dev = &i2c->dev;
- aw_dev->chip_id = AW87390_CHIP_ID;
aw_dev->acf = NULL;
aw_dev->prof_info.prof_desc = NULL;
aw_dev->prof_info.count = 0;
@@ -406,6 +541,7 @@ static int aw87390_init(struct aw87390 *aw87390, struct i2c_client *i2c, struct
static int aw87390_i2c_probe(struct i2c_client *i2c)
{
struct aw87390 *aw87390;
+ const struct snd_soc_component_driver *priv;
int ret;
ret = i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C);
@@ -434,16 +570,38 @@ static int aw87390_i2c_probe(struct i2c_client *i2c)
if (ret)
return ret;
- ret = devm_snd_soc_register_component(&i2c->dev,
- &soc_codec_dev_aw87390, NULL, 0);
+ switch (aw87390->aw_pa->chip_id) {
+ case AW87390_CHIP_ID:
+ ret = devm_snd_soc_register_component(&i2c->dev,
+ &soc_codec_dev_aw87390, NULL, 0);
+ break;
+ case AW87391_CHIP_ID:
+ priv = of_device_get_match_data(&i2c->dev);
+ if (!priv)
+ return dev_err_probe(&i2c->dev, -EINVAL,
+ "aw87391 not currently supported\n");
+ ret = devm_snd_soc_register_component(&i2c->dev, priv, NULL, 0);
+ break;
+ default:
+ return -ENXIO;
+ }
+
if (ret)
dev_err(&i2c->dev, "failed to register aw87390: %d\n", ret);
return ret;
}
+static const struct of_device_id aw87390_of_match[] = {
+ { .compatible = "awinic,aw87390" },
+ { .compatible = "anbernic,rgds-amp", .data = &soc_codec_dev_anbernic_rgds },
+ {},
+};
+MODULE_DEVICE_TABLE(of, aw87390_of_match);
+
static const struct i2c_device_id aw87390_i2c_id[] = {
{ AW87390_I2C_NAME },
+ { AW87391_I2C_NAME },
{ }
};
MODULE_DEVICE_TABLE(i2c, aw87390_i2c_id);
@@ -451,6 +609,7 @@ MODULE_DEVICE_TABLE(i2c, aw87390_i2c_id);
static struct i2c_driver aw87390_i2c_driver = {
.driver = {
.name = AW87390_I2C_NAME,
+ .of_match_table = of_match_ptr(aw87390_of_match),
},
.probe = aw87390_i2c_probe,
.id_table = aw87390_i2c_id,
diff --git a/sound/soc/codecs/aw87390.h b/sound/soc/codecs/aw87390.h
index d0d049e65991..f48b207e4bb4 100644
--- a/sound/soc/codecs/aw87390.h
+++ b/sound/soc/codecs/aw87390.h
@@ -52,6 +52,90 @@
#define AW87390_I2C_NAME "aw87390"
#define AW87390_ACF_FILE "aw87390_acf.bin"
+#define AW87391_SYSCTRL_REG (0x01)
+#define AW87391_REG_VER_SEL_LOW (0 << 6)
+#define AW87391_REG_VER_SEL_NORMAL (1 << 6)
+#define AW87391_REG_VER_SEL_SUPER (2 << 6)
+#define AW87391_REG_EN_ADAP BIT(5)
+#define AW87391_REG_EN_2X BIT(4)
+#define AW87391_EN_SPK BIT(3)
+#define AW87391_EN_PA BIT(2)
+#define AW87391_REG_EN_CP BIT(1)
+#define AW87391_EN_SW BIT(0)
+
+#define AW87391_CP_REG (0x02)
+#define AW87391_REG_CP_OVP_6_50V 0
+#define AW87391_REG_CP_OVP_6_75V 1
+#define AW87391_REG_CP_OVP_7_00V 2
+#define AW87391_REG_CP_OVP_7_25V 3
+#define AW87391_REG_CP_OVP_7_50V 4
+#define AW87391_REG_CP_OVP_7_75V 5
+#define AW87391_REG_CP_OVP_8_00V 6
+#define AW87391_REG_CP_OVP_8_25V 7
+#define AW87391_REG_CP_OVP_8_50V 8
+
+#define AW87391_PAG_REG (0x03)
+#define AW87391_GAIN_12DB 0
+#define AW87391_GAIN_15DB 1
+#define AW87391_GAIN_18DB 2
+#define AW87391_GAIN_21DB 3
+#define AW87391_GAIN_24DB 4
+
+#define AW87391_AGCPO_REG (0x04)
+#define AW87391_AK1_S_016 (2 << 5)
+#define AW87391_AK1_S_032 (3 << 5)
+#define AW87391_PD_AGC1_PWRDN BIT(4)
+/* AGC2PO supports values between 500mW (0000) to 1600mW (1011) */
+#define AW87391_AGC2PO_MW(n) ((n / 100) - 5)
+
+#define AW87391_AGC2PA_REG (0x05)
+#define AW87391_RK_S_5_12 (0 << 5)
+#define AW87391_RK_S_10_24 (1 << 5)
+#define AW87391_RK_S_20_48 (2 << 5)
+#define AW87391_RK_S_41 (3 << 5)
+#define AW87391_RK_S_82 (4 << 5)
+#define AW87391_RK_S_164 (5 << 5)
+#define AW87391_RK_S_328 (6 << 5)
+#define AW87391_RK_S_656 (7 << 5)
+#define AW87391_AK2_S_1_28 (0 << 2)
+#define AW87391_AK2_S_2_56 (1 << 2)
+#define AW87391_AK2_S_10_24 (2 << 2)
+#define AW87391_AK2_S_41 (3 << 2)
+#define AW87391_AK2_S_82 (4 << 2)
+#define AW87391_AK2_S_164 (5 << 2)
+#define AW87391_AK2_S_328 (6 << 2)
+#define AW87391_AK2_S_656 (7 << 2)
+#define AW87391_AK2F_S_10_24 0
+#define AW87391_AK2F_S_20_48 1
+#define AW87391_AK2F_S_41 2
+#define AW87391_AK2F_S_82 3
+
+#define AW87391_SYSST_REG (0x06)
+#define AW87391_UVLO BIT(7)
+#define AW87391_OTN BIT(6)
+#define AW87391_OC_FLAG BIT(5)
+#define AW87391_ADAP_CP BIT(4)
+#define AW87391_STARTOK BIT(3)
+#define AW87391_CP_OVP BIT(2)
+#define AW87391_PORN BIT(1)
+
+#define AW87391_SYSINT_REG (0x07)
+#define AW87391_UVLOI BIT(7)
+#define AW87391_ONTI BIT(6)
+#define AW87391_OC_FLAGI BIT(5)
+#define AW87391_ADAP_CPI BIT(4)
+#define AW87391_STARTOKI BIT(3)
+#define AW87391_CP_OVPI BIT(2)
+#define AW87391_PORNI BIT(1)
+
+#define AW87391_DFT_THGEN0_REG (0x63)
+#define AW87391_ADAPVTH_01W (0 << 2)
+#define AW87391_ADAPVTH_02W (1 << 2)
+#define AW87391_ADAPVTH_03W (2 << 2)
+#define AW87391_ADAPVTH_04W (3 << 2)
+
+#define AW87391_I2C_NAME "aw87391"
+
#define AW87390_PROFILE_EXT(xname, profile_info, profile_get, profile_set) \
{ \
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
@@ -63,6 +147,7 @@
enum aw87390_id {
AW87390_CHIP_ID = 0x76,
+ AW87391_CHIP_ID = 0xc1,
};
enum {
@@ -80,6 +165,7 @@ struct aw87390 {
struct mutex lock;
struct regmap *regmap;
struct aw_container *aw_cfg;
+ struct regulator *vdd_reg;
};
#endif
--
2.43.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH V2 3/3] arm64: dts: rockchip: add Awinic aw87391 for Anbernic RG-DS
2026-01-28 17:46 [PATCH V2 0/3] Anbernic RG-DS AW87391 Speaker Amps Chris Morgan
2026-01-28 17:46 ` [PATCH V2 1/3] ASoC: dt-bindings: aw87390: Add Anbernic RG-DS Amplifier Chris Morgan
2026-01-28 17:46 ` [PATCH V2 2/3] ASoC: codecs: aw87390: Add Anbernic RG-DS amp driver Chris Morgan
@ 2026-01-28 17:46 ` Chris Morgan
2026-02-03 12:05 ` (subset) [PATCH V2 0/3] Anbernic RG-DS AW87391 Speaker Amps Mark Brown
2026-02-22 22:39 ` Heiko Stuebner
4 siblings, 0 replies; 6+ messages in thread
From: Chris Morgan @ 2026-01-28 17:46 UTC (permalink / raw)
To: linux-sound
Cc: devicetree, wangweidong.a, tiwai, perex, conor+dt, krzk+dt, robh,
broonie, lgirdwood, heiko, linux-rockchip, Chris Morgan
From: Chris Morgan <macromorgan@hotmail.com>
Add support for the two Awinic aw87391 audio amplifiers used in the
Anbernic RG-DS. These amplifiers require a specific init sequence to
start which is usually provided by a firmware file, but in our case
the manufacturer only provided the sequence. As a result, we hard-code
a device specific compatible.
Additionally, add support for the VDD regulator used to power both
amplifiers. Note that the amps can accept and respond to i2c commands
even without regulator power (perhaps due to a secondary power source)
but cannot play audio.
Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
---
.../dts/rockchip/rk3568-anbernic-rg-ds.dts | 44 +++++++++++++++++--
1 file changed, 40 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-anbernic-rg-ds.dts b/arch/arm64/boot/dts/rockchip/rk3568-anbernic-rg-ds.dts
index 6ac1fe0d3c98..8d906ab02c5f 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-anbernic-rg-ds.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-anbernic-rg-ds.dts
@@ -354,6 +354,7 @@ sound {
compatible = "simple-audio-card";
pinctrl-0 = <&hp_det>;
pinctrl-names = "default";
+ simple-audio-card,aux-devs = <&aw87391_pa_l>, <&aw87391_pa_r>;
simple-audio-card,format = "i2s";
simple-audio-card,hp-det-gpios = <&gpio4 RK_PC2 GPIO_ACTIVE_HIGH>;
simple-audio-card,mclk-fs = <256>;
@@ -363,8 +364,10 @@ sound {
"MICL", "Mic Jack",
"Headphones", "HPOL",
"Headphones", "HPOR",
- "Internal Speakers", "HPOL",
- "Internal Speakers", "HPOR";
+ "Internal Speakers", "Left Amp OUT",
+ "Internal Speakers", "Right Amp OUT",
+ "Left Amp IN", "HPOL",
+ "Right Amp IN", "HPOR";
simple-audio-card,widgets =
"Microphone", "Mic Jack",
"Headphone", "Headphones",
@@ -468,6 +471,18 @@ vcc_wifi: regulator-vcc-wifi {
regulator-max-microvolt = <3300000>;
regulator-name = "vcc_wifi";
};
+
+ vdd_amp: regulator-vcc-amp {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio4 RK_PC3 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&vdd_amp_h>;
+ pinctrl-names = "default";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vccio_acodec>;
+ regulator-name = "vdd_amp";
+ };
};
&cpu0 {
@@ -840,8 +855,22 @@ &i2c2 {
pinctrl-names = "default";
status = "okay";
- /* awinic,aw87391 at 0x58 */
- /* awinic,aw87391 at 0x5b */
+ aw87391_pa_l: audio-codec@58 {
+ compatible = "anbernic,rgds-amp", "awinic,aw87391";
+ reg = <0x58>;
+ vdd-supply = <&vdd_amp>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "Left Amp";
+ };
+
+ aw87391_pa_r: audio-codec@5b {
+ compatible = "anbernic,rgds-amp", "awinic,aw87391";
+ reg = <0x5b>;
+ vdd-supply = <&vdd_amp>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "Right Amp";
+ };
+
/* invensense,icm42607p at 0x68 */
};
@@ -1014,6 +1043,13 @@ touch1_irq: touch1-irq {
};
};
+ vdd-amp {
+ vdd_amp_h: vdd-amp-h {
+ rockchip,pins =
+ <4 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
vcc-lcd {
vdd_lcd0_h: vdd-lcd0-h {
rockchip,pins =
--
2.43.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: (subset) [PATCH V2 0/3] Anbernic RG-DS AW87391 Speaker Amps
2026-01-28 17:46 [PATCH V2 0/3] Anbernic RG-DS AW87391 Speaker Amps Chris Morgan
` (2 preceding siblings ...)
2026-01-28 17:46 ` [PATCH V2 3/3] arm64: dts: rockchip: add Awinic aw87391 for Anbernic RG-DS Chris Morgan
@ 2026-02-03 12:05 ` Mark Brown
2026-02-22 22:39 ` Heiko Stuebner
4 siblings, 0 replies; 6+ messages in thread
From: Mark Brown @ 2026-02-03 12:05 UTC (permalink / raw)
To: linux-sound, Chris Morgan
Cc: devicetree, wangweidong.a, tiwai, perex, conor+dt, krzk+dt, robh,
lgirdwood, heiko, linux-rockchip, Chris Morgan
On Wed, 28 Jan 2026 11:46:05 -0600, Chris Morgan wrote:
> Add support for the Anbernic RG-DS Speaker Amplifiers. The Anbernic
> RG-DS uses two AW87391 ICs at 0x58 and 0x5B on i2c2. However, the
> manufacturer did not provide a firmware file, only a sequence of
> register writes to each device to enable and disable them.
>
> Add support for this *specific* configuration in the AW87390 driver.
> Since we are relying on a device specific sequence I am using a
> device specific compatible string. This driver does not currently
> support the aw87391 for any other device as I have none to test
> with valid firmware. Attempts to create firmware with the AwinicSCPv4
> have not been successful.
>
> [...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/3] ASoC: dt-bindings: aw87390: Add Anbernic RG-DS Amplifier
commit: c26d6cdade6c2a96049f24fac64a8e3734188703
[2/3] ASoC: codecs: aw87390: Add Anbernic RG-DS amp driver
commit: a145cfd0ffe7bd7d61ce25839cec737c449b0d2c
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: (subset) [PATCH V2 0/3] Anbernic RG-DS AW87391 Speaker Amps
2026-01-28 17:46 [PATCH V2 0/3] Anbernic RG-DS AW87391 Speaker Amps Chris Morgan
` (3 preceding siblings ...)
2026-02-03 12:05 ` (subset) [PATCH V2 0/3] Anbernic RG-DS AW87391 Speaker Amps Mark Brown
@ 2026-02-22 22:39 ` Heiko Stuebner
4 siblings, 0 replies; 6+ messages in thread
From: Heiko Stuebner @ 2026-02-22 22:39 UTC (permalink / raw)
To: linux-sound, Chris Morgan
Cc: Heiko Stuebner, devicetree, wangweidong.a, tiwai, perex, conor+dt,
krzk+dt, robh, broonie, lgirdwood, linux-rockchip, Chris Morgan
On Wed, 28 Jan 2026 11:46:05 -0600, Chris Morgan wrote:
> Add support for the Anbernic RG-DS Speaker Amplifiers. The Anbernic
> RG-DS uses two AW87391 ICs at 0x58 and 0x5B on i2c2. However, the
> manufacturer did not provide a firmware file, only a sequence of
> register writes to each device to enable and disable them.
>
> Add support for this *specific* configuration in the AW87390 driver.
> Since we are relying on a device specific sequence I am using a
> device specific compatible string. This driver does not currently
> support the aw87391 for any other device as I have none to test
> with valid firmware. Attempts to create firmware with the AwinicSCPv4
> have not been successful.
>
> [...]
Applied, thanks!
[3/3] arm64: dts: rockchip: add Awinic aw87391 for Anbernic RG-DS
commit: 1ee69b9cdcd1b838e514520fb4103ca77acd068a
Best regards,
--
Heiko Stuebner <heiko@sntech.de>
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-02-22 22:40 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-28 17:46 [PATCH V2 0/3] Anbernic RG-DS AW87391 Speaker Amps Chris Morgan
2026-01-28 17:46 ` [PATCH V2 1/3] ASoC: dt-bindings: aw87390: Add Anbernic RG-DS Amplifier Chris Morgan
2026-01-28 17:46 ` [PATCH V2 2/3] ASoC: codecs: aw87390: Add Anbernic RG-DS amp driver Chris Morgan
2026-01-28 17:46 ` [PATCH V2 3/3] arm64: dts: rockchip: add Awinic aw87391 for Anbernic RG-DS Chris Morgan
2026-02-03 12:05 ` (subset) [PATCH V2 0/3] Anbernic RG-DS AW87391 Speaker Amps Mark Brown
2026-02-22 22:39 ` Heiko Stuebner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox