[PATCH 2/3] ASoC: sun4i-codec: support hp-det-gpios property
Chen-Yu Tsai
wens at csie.org
Sun Dec 22 09:15:13 PST 2024
On Sat, Dec 21, 2024 at 5:41 PM Ryan Walklin <ryan at testtoast.com> wrote:
>
> From: Chris Morgan <macromorgan at hotmail.com>
>
> 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. Note this patch also adds the output
> of Headphone for the H616 codec.
>
> Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
> Signed-off-by: Ryan Walklin <ryan at testtoast.com>
> ---
> sound/soc/sunxi/sun4i-codec.c | 59 +++++++++++++++++++++++++++++++++--
> 1 file changed, 57 insertions(+), 2 deletions(-)
>
> diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
> index 933a0913237c8..5f718dd3fcf0a 100644
> --- a/sound/soc/sunxi/sun4i-codec.c
> +++ b/sound/soc/sunxi/sun4i-codec.c
> @@ -21,6 +21,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>
> @@ -272,6 +273,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;
> @@ -1302,6 +1304,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)
> {
> @@ -1327,6 +1372,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;
>
> @@ -1635,10 +1681,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"),
Why?
> };
>
> 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),
> };
> @@ -1684,7 +1731,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->name = "h616-audio-codec";
Why?
> card->driver_name = "sun4i-codec";
> card->controls = sun50i_h616_card_controls;
> card->num_controls = ARRAY_SIZE(sun50i_h616_card_controls);
> @@ -1940,6 +1987,14 @@ static int sun4i_codec_probe(struct platform_device *pdev)
> return ret;
> }
>
> + scodec->gpio_hp = devm_gpiod_get_optional(&pdev->dev, "allwinner,hp-det",
> + GPIOD_IN);
Just put it on the same line. Lines can go up to 100 characters.
> + 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,
> --
> 2.47.1
>
>
More information about the linux-arm-kernel
mailing list