Skip to content

Commit d9a0693

Browse files
committed
ASoC: sun4i-codec: add headphone dectection for
Merge series from Ryan Walklin <[email protected]>: 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(-) -- 2.48.1
2 parents e0afd7d + d389719 commit d9a0693

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ properties:
102102
maxItems: 1
103103
description: GPIO to enable the external amplifier
104104

105+
hp-det-gpios:
106+
maxItems: 1
107+
description: GPIO for headphone/line-out detection
108+
105109
required:
106110
- "#sound-dai-cells"
107111
- compatible
@@ -251,8 +255,10 @@ allOf:
251255
allwinner,audio-routing:
252256
items:
253257
enum:
258+
- Headphone
254259
- LINEOUT
255260
- Line Out
261+
- Speaker
256262

257263
dmas:
258264
items:

sound/soc/sunxi/sun4i-codec.c

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/gpio/consumer.h>
2323

2424
#include <sound/core.h>
25+
#include <sound/jack.h>
2526
#include <sound/pcm.h>
2627
#include <sound/pcm_params.h>
2728
#include <sound/soc.h>
@@ -331,6 +332,7 @@ struct sun4i_codec {
331332
struct clk *clk_module;
332333
struct reset_control *rst;
333334
struct gpio_desc *gpio_pa;
335+
struct gpio_desc *gpio_hp;
334336

335337
/* ADC_FIFOC register is at different offset on different SoCs */
336338
struct regmap_field *reg_adc_fifoc;
@@ -1583,6 +1585,49 @@ static struct snd_soc_dai_driver dummy_cpu_dai = {
15831585
.ops = &dummy_dai_ops,
15841586
};
15851587

1588+
static struct snd_soc_jack sun4i_headphone_jack;
1589+
1590+
static struct snd_soc_jack_pin sun4i_headphone_jack_pins[] = {
1591+
{ .pin = "Headphone", .mask = SND_JACK_HEADPHONE },
1592+
};
1593+
1594+
static struct snd_soc_jack_gpio sun4i_headphone_jack_gpio = {
1595+
.name = "hp-det",
1596+
.report = SND_JACK_HEADPHONE,
1597+
.debounce_time = 150,
1598+
};
1599+
1600+
static int sun4i_codec_machine_init(struct snd_soc_pcm_runtime *rtd)
1601+
{
1602+
struct snd_soc_card *card = rtd->card;
1603+
struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card);
1604+
int ret;
1605+
1606+
if (scodec->gpio_hp) {
1607+
ret = snd_soc_card_jack_new_pins(card, "Headphone Jack",
1608+
SND_JACK_HEADPHONE,
1609+
&sun4i_headphone_jack,
1610+
sun4i_headphone_jack_pins,
1611+
ARRAY_SIZE(sun4i_headphone_jack_pins));
1612+
if (ret) {
1613+
dev_err(rtd->dev,
1614+
"Headphone jack creation failed: %d\n", ret);
1615+
return ret;
1616+
}
1617+
1618+
sun4i_headphone_jack_gpio.desc = scodec->gpio_hp;
1619+
ret = snd_soc_jack_add_gpios(&sun4i_headphone_jack, 1,
1620+
&sun4i_headphone_jack_gpio);
1621+
1622+
if (ret) {
1623+
dev_err(rtd->dev, "Headphone GPIO not added: %d\n", ret);
1624+
return ret;
1625+
}
1626+
}
1627+
1628+
return 0;
1629+
}
1630+
15861631
static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev,
15871632
int *num_links)
15881633
{
@@ -1608,6 +1653,7 @@ static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev,
16081653
link->codecs->name = dev_name(dev);
16091654
link->platforms->name = dev_name(dev);
16101655
link->dai_fmt = SND_SOC_DAIFMT_I2S;
1656+
link->init = sun4i_codec_machine_init;
16111657

16121658
*num_links = 1;
16131659

@@ -1916,10 +1962,11 @@ static const struct snd_soc_component_driver sun50i_h616_codec_codec = {
19161962
};
19171963

19181964
static const struct snd_kcontrol_new sun50i_h616_card_controls[] = {
1919-
SOC_DAPM_PIN_SWITCH("LINEOUT"),
1965+
SOC_DAPM_PIN_SWITCH("Speaker"),
19201966
};
19211967

19221968
static const struct snd_soc_dapm_widget sun50i_h616_codec_card_dapm_widgets[] = {
1969+
SND_SOC_DAPM_HP("Headphone", NULL),
19231970
SND_SOC_DAPM_LINE("Line Out", NULL),
19241971
SND_SOC_DAPM_SPK("Speaker", sun4i_codec_spk_event),
19251972
};
@@ -1966,6 +2013,7 @@ static struct snd_soc_card *sun50i_h616_codec_create_card(struct device *dev)
19662013
card->dev = dev;
19672014
card->owner = THIS_MODULE;
19682015
card->name = "H616 Audio Codec";
2016+
card->long_name = "h616-audio-codec";
19692017
card->driver_name = "sun4i-codec";
19702018
card->controls = sun50i_h616_card_controls;
19712019
card->num_controls = ARRAY_SIZE(sun50i_h616_card_controls);
@@ -2301,6 +2349,13 @@ static int sun4i_codec_probe(struct platform_device *pdev)
23012349
return ret;
23022350
}
23032351

2352+
scodec->gpio_hp = devm_gpiod_get_optional(&pdev->dev, "hp-det", GPIOD_IN);
2353+
if (IS_ERR(scodec->gpio_hp)) {
2354+
ret = PTR_ERR(scodec->gpio_hp);
2355+
dev_err_probe(&pdev->dev, ret, "Failed to get hp-det gpio\n");
2356+
return ret;
2357+
}
2358+
23042359
/* reg_field setup */
23052360
scodec->reg_adc_fifoc = devm_regmap_field_alloc(&pdev->dev,
23062361
scodec->regmap,

0 commit comments

Comments
 (0)