Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: sun4i-codec: add headphone dectection for

Merge series from Ryan Walklin <ryan@testtoast.com>:

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

+62 -1
+6
Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml
··· 102 102 maxItems: 1 103 103 description: GPIO to enable the external amplifier 104 104 105 + hp-det-gpios: 106 + maxItems: 1 107 + description: GPIO for headphone/line-out detection 108 + 105 109 required: 106 110 - "#sound-dai-cells" 107 111 - compatible ··· 255 251 allwinner,audio-routing: 256 252 items: 257 253 enum: 254 + - Headphone 258 255 - LINEOUT 259 256 - Line Out 257 + - Speaker 260 258 261 259 dmas: 262 260 items:
+56 -1
sound/soc/sunxi/sun4i-codec.c
··· 22 22 #include <linux/gpio/consumer.h> 23 23 24 24 #include <sound/core.h> 25 + #include <sound/jack.h> 25 26 #include <sound/pcm.h> 26 27 #include <sound/pcm_params.h> 27 28 #include <sound/soc.h> ··· 332 331 struct clk *clk_module; 333 332 struct reset_control *rst; 334 333 struct gpio_desc *gpio_pa; 334 + struct gpio_desc *gpio_hp; 335 335 336 336 /* ADC_FIFOC register is at different offset on different SoCs */ 337 337 struct regmap_field *reg_adc_fifoc; ··· 1585 1583 .ops = &dummy_dai_ops, 1586 1584 }; 1587 1585 1586 + static struct snd_soc_jack sun4i_headphone_jack; 1587 + 1588 + static struct snd_soc_jack_pin sun4i_headphone_jack_pins[] = { 1589 + { .pin = "Headphone", .mask = SND_JACK_HEADPHONE }, 1590 + }; 1591 + 1592 + static struct snd_soc_jack_gpio sun4i_headphone_jack_gpio = { 1593 + .name = "hp-det", 1594 + .report = SND_JACK_HEADPHONE, 1595 + .debounce_time = 150, 1596 + }; 1597 + 1598 + static int sun4i_codec_machine_init(struct snd_soc_pcm_runtime *rtd) 1599 + { 1600 + struct snd_soc_card *card = rtd->card; 1601 + struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card); 1602 + int ret; 1603 + 1604 + if (scodec->gpio_hp) { 1605 + ret = snd_soc_card_jack_new_pins(card, "Headphone Jack", 1606 + SND_JACK_HEADPHONE, 1607 + &sun4i_headphone_jack, 1608 + sun4i_headphone_jack_pins, 1609 + ARRAY_SIZE(sun4i_headphone_jack_pins)); 1610 + if (ret) { 1611 + dev_err(rtd->dev, 1612 + "Headphone jack creation failed: %d\n", ret); 1613 + return ret; 1614 + } 1615 + 1616 + sun4i_headphone_jack_gpio.desc = scodec->gpio_hp; 1617 + ret = snd_soc_jack_add_gpios(&sun4i_headphone_jack, 1, 1618 + &sun4i_headphone_jack_gpio); 1619 + 1620 + if (ret) { 1621 + dev_err(rtd->dev, "Headphone GPIO not added: %d\n", ret); 1622 + return ret; 1623 + } 1624 + } 1625 + 1626 + return 0; 1627 + } 1628 + 1588 1629 static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev, 1589 1630 int *num_links) 1590 1631 { ··· 1653 1608 link->codecs->name = dev_name(dev); 1654 1609 link->platforms->name = dev_name(dev); 1655 1610 link->dai_fmt = SND_SOC_DAIFMT_I2S; 1611 + link->init = sun4i_codec_machine_init; 1656 1612 1657 1613 *num_links = 1; 1658 1614 ··· 1962 1916 }; 1963 1917 1964 1918 static const struct snd_kcontrol_new sun50i_h616_card_controls[] = { 1965 - SOC_DAPM_PIN_SWITCH("LINEOUT"), 1919 + SOC_DAPM_PIN_SWITCH("Speaker"), 1966 1920 }; 1967 1921 1968 1922 static const struct snd_soc_dapm_widget sun50i_h616_codec_card_dapm_widgets[] = { 1923 + SND_SOC_DAPM_HP("Headphone", NULL), 1969 1924 SND_SOC_DAPM_LINE("Line Out", NULL), 1970 1925 SND_SOC_DAPM_SPK("Speaker", sun4i_codec_spk_event), 1971 1926 }; ··· 2013 1966 card->dev = dev; 2014 1967 card->owner = THIS_MODULE; 2015 1968 card->name = "H616 Audio Codec"; 1969 + card->long_name = "h616-audio-codec"; 2016 1970 card->driver_name = "sun4i-codec"; 2017 1971 card->controls = sun50i_h616_card_controls; 2018 1972 card->num_controls = ARRAY_SIZE(sun50i_h616_card_controls); ··· 2346 2298 if (IS_ERR(scodec->gpio_pa)) { 2347 2299 ret = PTR_ERR(scodec->gpio_pa); 2348 2300 dev_err_probe(&pdev->dev, ret, "Failed to get pa gpio\n"); 2301 + return ret; 2302 + } 2303 + 2304 + scodec->gpio_hp = devm_gpiod_get_optional(&pdev->dev, "hp-det", GPIOD_IN); 2305 + if (IS_ERR(scodec->gpio_hp)) { 2306 + ret = PTR_ERR(scodec->gpio_hp); 2307 + dev_err_probe(&pdev->dev, ret, "Failed to get hp-det gpio\n"); 2349 2308 return ret; 2350 2309 } 2351 2310