Skip to contentSkip to conversation

ASoC: sun4i-codec: add headphone dectection for Anbernic RG35XX devices

PATCH Applied Ryan Walklin 4 participants 11 messages Feb 14, 2025 – Apr 13, 2025

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

v3 cover ASoC: sun4i-codec: add headphone dectection for Anbernic RG35XX devices

Hi All,

V3 of this patch adding headphone jack detection support to the Anbernic RGnnXX series of handhelds. V3 corrects my misunderstanding of derivation of ALSA UCM file paths, and adds recieved Reviewed-by and Tested-by tags. Thanks to those that have reviewed and fed back on previous versions.

Original message below:

This series adds the required device tree bindings to describe GPIOs for jack detection in the sun4i-codec driver, adds support for jack detection to the codec machine driver, and describes the hardware configuration in the RG35XX DTS. The existing speaker amplifier GPIO pin can then be used in concert with jack detection to enable userspace sound servers (via an ALSA UCM configuration) to disable the speaker route when headphones are connected.

Thanks to Chris Morgan for his assistance putting this series together.

Regards,

Ryan

Chris Morgan (2):
ASoC: dt-bindings: sun4i-a10-codec: add hp-det-gpios
arm64: dts: allwinner: h700: Add hp-det-gpios for Anbernic RG35XX

Ryan Walklin (3):
ASoC: sun4i-codec: correct dapm widgets and controls for h616
ASoC: sun4i-codec: support hp-det-gpios property
ASoC: sun4i-codec: add h616 card long_name

 .../sound/allwinner,sun4i-a10-codec.yaml      |  6 ++
 .../sun50i-h700-anbernic-rg35xx-2024.dts      |  5 +-
 sound/soc/sunxi/sun4i-codec.c                 | 57 ++++++++++++++++++-
 3 files changed, 66 insertions(+), 2 deletions(-)
Signature · 1 line
2.48.1
#1 lore raw

PATCH v3 1/5 ASoC: dt-bindings: sun4i-a10-codec: add hp-det-gpios

From: Chris Morgan <[email protected]>

Devices integrating Allwinner SoCs may use line-out or headphone jacks with jack detection circuits attached to a GPIO. Support defining these in DTs.

A number of Anbernic devices featuring the H700 SoC use this mechanism to switch between a headphone jack and an internal speaker, so add these to the allowed routing items.

--

Changelog v1..v2:
- Remove vendor prefix from hp-det-gpios

Changelog v2..v3:
- Add Reviewed-by tag

---
 .../bindings/sound/allwinner,sun4i-a10-codec.yaml           | 6 ++++++
 1 file changed, 6 insertions(+)
Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml +6 -0
index ccae64ce30719..b4eca702febc7 100644
@@ -102,6 +102,10 @@ properties:
     maxItems: 1
     description: GPIO to enable the external amplifier
 
+  hp-det-gpios:
+    maxItems: 1
+    description: GPIO for headphone/line-out detection
+
 required:
   - "#sound-dai-cells"
   - compatible
@@ -251,8 +255,10 @@ allOf:
         allwinner,audio-routing:
           items:
             enum:
+              - Headphone
               - LINEOUT
               - Line Out
+              - Speaker
 
         dmas:
           items:
Signature · 1 line
2.48.1
#2 lore raw

PATCH v3 2/5 ASoC: sun4i-codec: correct dapm widgets and controls for h616

In reply to Ryan Walklin

The previous H616 support patch added a single LINEOUT DAPM pin switch to the card controls. As the codec in this SoC only has a single route, this seemed reasonable at the time, however is redundant given the existing DAPM codec widget definitions controlling the digital and analog sides of the codec.

It is also insufficient to describe the scenario where separate components (muxes, jack detection etc) are used to modify the audio route external to the SoC. For example the Anbernic RG(##)XX series of devices uses a headphone jack detection switch, GPIO-controlled speaker amplifier and a passive external mux chip to route audio.

Remove the redundant LINEOUT card control, and add a Speaker pin switch control and Headphone DAPM widget to allow control of the above hardware.

---
 sound/soc/sunxi/sun4i-codec.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
sound/soc/sunxi/sun4i-codec.c +2 -1
index 886b3fa537d26..f24bbefeb3923 100644
@@ -1916,10 +1916,11 @@ static const struct snd_soc_component_driver sun50i_h616_codec_codec = {
 };
 
 static const struct snd_kcontrol_new sun50i_h616_card_controls[] = {
-	SOC_DAPM_PIN_SWITCH("LINEOUT"),
+	SOC_DAPM_PIN_SWITCH("Speaker"),
 };
 
 static const struct snd_soc_dapm_widget sun50i_h616_codec_card_dapm_widgets[] = {
+	SND_SOC_DAPM_HP("Headphone", NULL),
 	SND_SOC_DAPM_LINE("Line Out", NULL),
 	SND_SOC_DAPM_SPK("Speaker", sun4i_codec_spk_event),
 };
Signature · 1 line
2.48.1
maintainer
#3 lore raw

Re: [PATCH v3 2/5] ASoC: sun4i-codec: correct dapm widgets and controls for h616

Dne petek, 14. februar 2025 ob 23:02:24 Srednjeevropski standardni čas je Ryan Walklin napisal(a):

Quoted 27 lines

The previous H616 support patch added a single LINEOUT DAPM pin switch to the card controls. As the codec in this SoC only has a single route, this seemed reasonable at the time, however is redundant given the existing DAPM codec widget definitions controlling the digital and analog sides of the codec.

It is also insufficient to describe the scenario where separate components (muxes, jack detection etc) are used to modify the audio route external to the SoC. For example the Anbernic RG(##)XX series of devices uses a headphone jack detection switch, GPIO-controlled speaker amplifier and a passive external mux chip to route audio.

Remove the redundant LINEOUT card control, and add a Speaker pin switch control and Headphone DAPM widget to allow control of the above hardware.

---
 sound/soc/sunxi/sun4i-codec.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
sound/soc/sunxi/sun4i-codec.c +0 -0
index 886b3fa537d26..f24bbefeb3923 100644

sound/soc/sunxi/sun4i-codec.c static const struct snd_soc_component_driver sun50i_h616_codec_codec = { · line 1919

Quoted 5 lines
sound/soc/sunxi/sun4i-codec.c +1 -1
@@ -1916,10 +1916,11 @@ static const struct snd_soc_component_driver sun50i_h616_codec_codec = {
 };
 
 static const struct snd_kcontrol_new sun50i_h616_card_controls[] = {
-	SOC_DAPM_PIN_SWITCH("LINEOUT"),
+	SOC_DAPM_PIN_SWITCH("Speaker"),

Will this break sun50i-h616-x96-mate and sun50i-h616-orangepi-zero based boards? If so, other solution must be found.

Best regards,
Jernej

Quoted 8 lines
sound/soc/sunxi/sun4i-codec.c +1 -0
 };
 
 static const struct snd_soc_dapm_widget sun50i_h616_codec_card_dapm_widgets[] = {
+	SND_SOC_DAPM_HP("Headphone", NULL),
 	SND_SOC_DAPM_LINE("Line Out", NULL),
 	SND_SOC_DAPM_SPK("Speaker", sun4i_codec_spk_event),
 };
#4 lore raw

Re: [PATCH v3 2/5] ASoC: sun4i-codec: correct dapm widgets and controls for h616

Quoted 9 lines · Jernej Škrabec

Dne petek, 14. februar 2025 ob 23:02:24 Srednjeevropski standardni čas je Ryan Walklin napisal(a):

sound/soc/sunxi/sun4i-codec.c static const struct snd_soc_component_driver sun50i_h616_codec_codec = { · line 1919

Quoted 3 lines

static const struct snd_kcontrol_new sun50i_h616_card_controls[] = {

sound/soc/sunxi/sun4i-codec.c +1 -1
-	SOC_DAPM_PIN_SWITCH("LINEOUT"),
+	SOC_DAPM_PIN_SWITCH("Speaker"),

Will this break sun50i-h616-x96-mate and sun50i-h616-orangepi-zero based boards? If so, other solution must be found.

My understanding is that this a separate concept from the codec power control itself, which is already covered by the analog and digital power supply DAPM widgets. For the H616's single lineout output, it doesn't make sense to have a separate control for this, as the codec should power off when idle using the existing DAPM widgets, and the lineout route is always active when the codec is on. The LINEOUT control here is redundant, and not connected to any userspace mechanism in the current state.

However for the RG35XX, which has a speaker amp controlled externally, with audio routed via a passive mux, it make sense to specify this as a separate route in userspace with a corresponding control (via GPIO pin in this case).

The other H616 devices (Orange Pi etc) only have a single route defined in their DTS, and no internal speaker to require a speaker switch. This control does not do anything for them, and removing it should not have an impact. I do not have this hardware to test, but on the RG35XX devices audio is produced without it being present, and with the speaker switch in either state (headphones plugged in and speaker amp off, or speaker amp on and headphones connected).

I did try to convey in the commit message but happy to correct the comment if you feel it is not clear.

Regards,

Ryan

#5 lore raw

PATCH v3 3/5 ASoC: sun4i-codec: support hp-det-gpios property

In reply to Ryan Walklin

Add support for GPIO headphone detection with the hp-det-gpios property. In order for this to properly disable the path upon removal of headphones, the output must be labelled Headphone which is a common sink in the driver.

Describe a headphone jack and detection GPIO in the driver, check for a corresponding device tree node, and enable jack detection in a new machine init function if described.

--
Changelog v1..v2:
- Separate DAPM changes into separate patch and add rationale.

---
 sound/soc/sunxi/sun4i-codec.c | 53 +++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)
sound/soc/sunxi/sun4i-codec.c +53 -0
index f24bbefeb3923..3701f56c72756 100644
@@ -22,6 +22,7 @@
 #include <linux/gpio/consumer.h>
 
 #include <sound/core.h>
+#include <sound/jack.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
@@ -331,6 +332,7 @@ struct sun4i_codec {
 	struct clk	*clk_module;
 	struct reset_control *rst;
 	struct gpio_desc *gpio_pa;
+	struct gpio_desc *gpio_hp;
 
 	/* ADC_FIFOC register is at different offset on different SoCs */
 	struct regmap_field *reg_adc_fifoc;
@@ -1583,6 +1585,49 @@ static struct snd_soc_dai_driver dummy_cpu_dai = {
 	.ops = &dummy_dai_ops,
 };
 
+static struct snd_soc_jack sun4i_headphone_jack;
+
+static struct snd_soc_jack_pin sun4i_headphone_jack_pins[] = {
+	{ .pin = "Headphone", .mask = SND_JACK_HEADPHONE },
+};
+
+static struct snd_soc_jack_gpio sun4i_headphone_jack_gpio = {
+	.name = "hp-det",
+	.report = SND_JACK_HEADPHONE,
+	.debounce_time = 150,
+};
+
+static int sun4i_codec_machine_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_soc_card *card = rtd->card;
+	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card);
+	int ret;
+
+	if (scodec->gpio_hp) {
+		ret = snd_soc_card_jack_new_pins(card, "Headphone Jack",
+						 SND_JACK_HEADPHONE,
+						 &sun4i_headphone_jack,
+						 sun4i_headphone_jack_pins,
+						 ARRAY_SIZE(sun4i_headphone_jack_pins));
+		if (ret) {
+			dev_err(rtd->dev,
+				"Headphone jack creation failed: %d\n", ret);
+			return ret;
+		}
+
+		sun4i_headphone_jack_gpio.desc = scodec->gpio_hp;
+		ret = snd_soc_jack_add_gpios(&sun4i_headphone_jack, 1,
+					     &sun4i_headphone_jack_gpio);
+
+		if (ret) {
+			dev_err(rtd->dev, "Headphone GPIO not added: %d\n", ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
 static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev,
 							int *num_links)
 {
@@ -1608,6 +1653,7 @@ static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev,
 	link->codecs->name	= dev_name(dev);
 	link->platforms->name	= dev_name(dev);
 	link->dai_fmt		= SND_SOC_DAIFMT_I2S;
+	link->init		= sun4i_codec_machine_init;
 
 	*num_links = 1;
 
@@ -2302,6 +2348,13 @@ static int sun4i_codec_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	scodec->gpio_hp = devm_gpiod_get_optional(&pdev->dev, "hp-det", GPIOD_IN);
+	if (IS_ERR(scodec->gpio_hp)) {
+		ret = PTR_ERR(scodec->gpio_hp);
+		dev_err_probe(&pdev->dev, ret, "Failed to get hp-det gpio\n");
+		return ret;
+	}
+
 	/* reg_field setup */
 	scodec->reg_adc_fifoc = devm_regmap_field_alloc(&pdev->dev,
 							scodec->regmap,
Signature · 1 line
2.48.1
#6 lore raw

PATCH v3 4/5 arm64: dts: allwinner: h700: Add hp-det-gpios for Anbernic RG35XX

In reply to Ryan Walklin

From: Chris Morgan <[email protected]>

Add support for headphone insertion detection via GPIO for the RG35XX series, and add the corresponding routing to the codec node.

--
Changelog v1..v2:
- Remove vendor prefix from GPIO description.
- Whitespace fix

Changelog v2..v3:
- Add Tested-by tag

---
 .../boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts  | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts +4 -1
index a231abf1684ad..b482fdf1fdba8 100644
@@ -178,8 +178,11 @@ reg_vcc5v: regulator-vcc5v { /* USB-C power input */
 };
 
 &codec {
-	allwinner,audio-routing = "Line Out", "LINEOUT";
+	/* Both speakers and headphone jack connected to 74HC4052D analog mux*/
+	allwinner,audio-routing = "Speaker", "LINEOUT",
+				  "Headphone", "LINEOUT";
 	allwinner,pa-gpios = <&pio 8 5 GPIO_ACTIVE_HIGH>; // PI5
+	hp-det-gpios = <&pio 8 3 GPIO_ACTIVE_HIGH>; // PI3
 	status = "okay";
 };
 
Signature · 1 line
2.48.1
#7 lore raw

Re: [PATCH v3 4/5] arm64: dts: allwinner: h700: Add hp-det-gpios for Anbernic RG35XX

Quoted 9 lines · Ryan Walklin

From: Chris Morgan <[email protected]>

Add support for headphone insertion detection via GPIO for the RG35XX series, and add the corresponding routing to the codec node.

Hi all, this DT patch did not get picked up for 6.15, however the rest of this set have been merged as part of the 6.15 sound tree [1]. Would appreciate if this could be picked up.

Regards,

Ryan

1. https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e50da555ca4d42b1b98d0f26789db64f26a0919a

#8 lore raw

PATCH v3 5/5 ASoC: sun4i-codec: add h616 card long_name

In reply to Ryan Walklin

Adding jack detection requires sound servers to act on the emitted events, which are described by ALSA Use Case Manager configurations in userspace. These configurations include the long card name in the file path (falling back to card->name if this is not present), so add a long card name for the H616 without spaces, making UCM referencing easier.

The corresponding ALSA UCM patch is here (now merged):
https://github.com/alsa-project/alsa-ucm-conf/pull/491

--
Changelog v1..v2:
- Separate patch for card->long_name
- Note UCM patch link

Changelog v2..v3:
- Add card->long_name rather than change existing card->name

---
 sound/soc/sunxi/sun4i-codec.c | 1 +
 1 file changed, 1 insertion(+)
sound/soc/sunxi/sun4i-codec.c +1 -0
index 3701f56c72756..93733ff2e32a0 100644
@@ -2013,6 +2013,7 @@ static struct snd_soc_card *sun50i_h616_codec_create_card(struct device *dev)
 	card->dev		= dev;
 	card->owner		= THIS_MODULE;
 	card->name		= "H616 Audio Codec";
+	card->long_name		= "h616-audio-codec";
 	card->driver_name	= "sun4i-codec";
 	card->controls		= sun50i_h616_card_controls;
 	card->num_controls	= ARRAY_SIZE(sun50i_h616_card_controls);
Signature · 1 line
2.48.1
maintainer
#9 lore raw

Re: (subset) [PATCH v3 0/5] ASoC: sun4i-codec: add headphone dectection for Anbernic RG35XX devices

In reply to Ryan Walklin
Quoted 9 lines · Ryan Walklin

V3 of this patch adding headphone jack detection support to the Anbernic RGnnXX series of handhelds. V3 corrects my misunderstanding of derivation of ALSA UCM file paths, and adds recieved Reviewed-by and Tested-by tags. Thanks to those that have reviewed and fed back on previous versions.

Original message below:

This series adds the required device tree bindings to describe GPIOs for jack detection in the sun4i-codec driver, adds support for jack detection to the codec machine driver, and describes the hardware configuration in the RG35XX DTS. The existing speaker amplifier GPIO pin can then be used in concert with jack detection to enable userspace sound servers (via an ALSA UCM configuration) to disable the speaker route when headphones are connected.

Thanks to Chris Morgan for his assistance putting this series together.

[...]

Applied to

https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/5] ASoC: dt-bindings: sun4i-a10-codec: add hp-det-gpios

      commit: 7bda89a2489fb012c4c63f3338827ad1f35c8880
[2/5] ASoC: sun4i-codec: correct dapm widgets and controls for h616
      commit: ae5f76d4044d1580849316c49290678605e0889d
[3/5] ASoC: sun4i-codec: support hp-det-gpios property
      commit: a149377c033afe6557c50892ebbfc0e8b7e2e253
[5/5] ASoC: sun4i-codec: add h616 card long_name
      commit: d389719fb4ece17ea28c0cf908066815d3ab0e25

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

Applied
#10 lore raw

Re: (subset) [PATCH v3 0/5] ASoC: sun4i-codec: add headphone dectection for Anbernic RG35XX devices

In reply to Ryan Walklin
Quoted 9 lines · Ryan Walklin

V3 of this patch adding headphone jack detection support to the Anbernic RGnnXX series of handhelds. V3 corrects my misunderstanding of derivation of ALSA UCM file paths, and adds recieved Reviewed-by and Tested-by tags. Thanks to those that have reviewed and fed back on previous versions.

Original message below:

This series adds the required device tree bindings to describe GPIOs for jack detection in the sun4i-codec driver, adds support for jack detection to the codec machine driver, and describes the hardware configuration in the RG35XX DTS. The existing speaker amplifier GPIO pin can then be used in concert with jack detection to enable userspace sound servers (via an ALSA UCM configuration) to disable the speaker route when headphones are connected.

Thanks to Chris Morgan for his assistance putting this series together.

[...]

Applied to dt-for-6.16 in [email protected]:linux-sunxi/linux-sunxi.git, thanks!

[4/5] arm64: dts: allwinner: h700: Add hp-det-gpios for Anbernic RG35XX

      commit: 69714722df19a7d9e81b7e8f208ca8f325af4502

Best regards,

Signature · 1 line
Chen-Yu Tsai <[email protected]>