ASoC: sun4i-codec: support hp-det-gpios property
[ Upstream commit a149377c033afe6557c50892ebbfc0e8b7e2e253 ] 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. Signed-off-by: Chris Morgan <macromorgan@hotmail.com> Signed-off-by: Ryan Walklin <ryan@testtoast.com> -- Changelog v1..v2: - Separate DAPM changes into separate patch and add rationale. Tested-by: Philippe Simons <simons.philippe@gmail.com> Link: https://patch.msgid.link/20250214220247.10810-4-ryan@testtoast.com Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
f8d9460347
commit
baf667f23f
@@ -25,6 +25,7 @@
|
|||||||
#include <linux/gpio/consumer.h>
|
#include <linux/gpio/consumer.h>
|
||||||
|
|
||||||
#include <sound/core.h>
|
#include <sound/core.h>
|
||||||
|
#include <sound/jack.h>
|
||||||
#include <sound/pcm.h>
|
#include <sound/pcm.h>
|
||||||
#include <sound/pcm_params.h>
|
#include <sound/pcm_params.h>
|
||||||
#include <sound/soc.h>
|
#include <sound/soc.h>
|
||||||
@@ -239,6 +240,7 @@ struct sun4i_codec {
|
|||||||
struct clk *clk_module;
|
struct clk *clk_module;
|
||||||
struct reset_control *rst;
|
struct reset_control *rst;
|
||||||
struct gpio_desc *gpio_pa;
|
struct gpio_desc *gpio_pa;
|
||||||
|
struct gpio_desc *gpio_hp;
|
||||||
|
|
||||||
/* ADC_FIFOC register is at different offset on different SoCs */
|
/* ADC_FIFOC register is at different offset on different SoCs */
|
||||||
struct regmap_field *reg_adc_fifoc;
|
struct regmap_field *reg_adc_fifoc;
|
||||||
@@ -1277,6 +1279,49 @@ static struct snd_soc_dai_driver dummy_cpu_dai = {
|
|||||||
.ops = &dummy_dai_ops,
|
.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,
|
static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev,
|
||||||
int *num_links)
|
int *num_links)
|
||||||
{
|
{
|
||||||
@@ -1302,6 +1347,7 @@ static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev,
|
|||||||
link->codecs->name = dev_name(dev);
|
link->codecs->name = dev_name(dev);
|
||||||
link->platforms->name = dev_name(dev);
|
link->platforms->name = dev_name(dev);
|
||||||
link->dai_fmt = SND_SOC_DAIFMT_I2S;
|
link->dai_fmt = SND_SOC_DAIFMT_I2S;
|
||||||
|
link->init = sun4i_codec_machine_init;
|
||||||
|
|
||||||
*num_links = 1;
|
*num_links = 1;
|
||||||
|
|
||||||
@@ -1742,6 +1788,13 @@ static int sun4i_codec_probe(struct platform_device *pdev)
|
|||||||
return ret;
|
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 */
|
/* reg_field setup */
|
||||||
scodec->reg_adc_fifoc = devm_regmap_field_alloc(&pdev->dev,
|
scodec->reg_adc_fifoc = devm_regmap_field_alloc(&pdev->dev,
|
||||||
scodec->regmap,
|
scodec->regmap,
|
||||||
|
|||||||
Reference in New Issue
Block a user