forked from Minki/linux
ASoC: amd: acp: Power on/off the speaker enable gpio pin based on DAPM callback.
Configure the speaker gpio pin based on power sequence of the DAPM speaker events. Enable speaker after widget power up and Disable before widget powerdown. Signed-off-by: V sujith kumar Reddy <vsujithkumar.reddy@amd.com> Link: https://lore.kernel.org/r/20211224150058.2444776-1-vsujithkumar.reddy@amd.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
b2fde4deff
commit
5c5f08f7fc
@ -32,7 +32,7 @@ config SND_AMD_ASOC_RENOIR
|
|||||||
|
|
||||||
config SND_SOC_AMD_MACH_COMMON
|
config SND_SOC_AMD_MACH_COMMON
|
||||||
tristate
|
tristate
|
||||||
depends on X86 && PCI && I2C
|
depends on X86 && PCI && I2C && GPIOLIB
|
||||||
select CLK_FIXED_FCH
|
select CLK_FIXED_FCH
|
||||||
select SND_SOC_RT5682_I2C
|
select SND_SOC_RT5682_I2C
|
||||||
select SND_SOC_DMIC
|
select SND_SOC_DMIC
|
||||||
@ -44,14 +44,14 @@ config SND_SOC_AMD_MACH_COMMON
|
|||||||
|
|
||||||
config SND_SOC_AMD_LEGACY_MACH
|
config SND_SOC_AMD_LEGACY_MACH
|
||||||
tristate "AMD Legacy Machine Driver Support"
|
tristate "AMD Legacy Machine Driver Support"
|
||||||
depends on X86 && PCI && I2C
|
depends on X86 && PCI && I2C && GPIOLIB
|
||||||
select SND_SOC_AMD_MACH_COMMON
|
select SND_SOC_AMD_MACH_COMMON
|
||||||
help
|
help
|
||||||
This option enables legacy sound card support for ACP audio.
|
This option enables legacy sound card support for ACP audio.
|
||||||
|
|
||||||
config SND_SOC_AMD_SOF_MACH
|
config SND_SOC_AMD_SOF_MACH
|
||||||
tristate "AMD SOF Machine Driver Support"
|
tristate "AMD SOF Machine Driver Support"
|
||||||
depends on X86 && PCI && I2C
|
depends on X86 && PCI && I2C && GPIOLIB
|
||||||
select SND_SOC_AMD_MACH_COMMON
|
select SND_SOC_AMD_MACH_COMMON
|
||||||
help
|
help
|
||||||
This option enables SOF sound card support for ACP audio.
|
This option enables SOF sound card support for ACP audio.
|
||||||
|
@ -27,6 +27,7 @@ static struct acp_card_drvdata rt5682_rt1019_data = {
|
|||||||
.hs_codec_id = RT5682,
|
.hs_codec_id = RT5682,
|
||||||
.amp_codec_id = RT1019,
|
.amp_codec_id = RT1019,
|
||||||
.dmic_codec_id = NONE,
|
.dmic_codec_id = NONE,
|
||||||
|
.gpio_spkr_en = EN_SPKR_GPIO_GB,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct snd_kcontrol_new acp_controls[] = {
|
static const struct snd_kcontrol_new acp_controls[] = {
|
||||||
@ -41,15 +42,16 @@ static const struct snd_kcontrol_new acp_controls[] = {
|
|||||||
static const struct snd_soc_dapm_widget acp_widgets[] = {
|
static const struct snd_soc_dapm_widget acp_widgets[] = {
|
||||||
SND_SOC_DAPM_HP("Headphone Jack", NULL),
|
SND_SOC_DAPM_HP("Headphone Jack", NULL),
|
||||||
SND_SOC_DAPM_MIC("Headset Mic", NULL),
|
SND_SOC_DAPM_MIC("Headset Mic", NULL),
|
||||||
SND_SOC_DAPM_SPK("Spk", NULL),
|
SND_SOC_DAPM_SPK("Spk", event_spkr_handler),
|
||||||
SND_SOC_DAPM_SPK("Left Spk", NULL),
|
SND_SOC_DAPM_SPK("Left Spk", event_spkr_handler),
|
||||||
SND_SOC_DAPM_SPK("Right Spk", NULL),
|
SND_SOC_DAPM_SPK("Right Spk", event_spkr_handler),
|
||||||
};
|
};
|
||||||
|
|
||||||
static int acp_asoc_probe(struct platform_device *pdev)
|
static int acp_asoc_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct snd_soc_card *card = NULL;
|
struct snd_soc_card *card = NULL;
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
|
unsigned int spkr_gpio;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!pdev->id_entry)
|
if (!pdev->id_entry)
|
||||||
@ -67,9 +69,20 @@ static int acp_asoc_probe(struct platform_device *pdev)
|
|||||||
card->controls = acp_controls;
|
card->controls = acp_controls;
|
||||||
card->num_controls = ARRAY_SIZE(acp_controls);
|
card->num_controls = ARRAY_SIZE(acp_controls);
|
||||||
card->drvdata = (struct acp_card_drvdata *)pdev->id_entry->driver_data;
|
card->drvdata = (struct acp_card_drvdata *)pdev->id_entry->driver_data;
|
||||||
|
spkr_gpio = ((struct acp_card_drvdata *)(card->drvdata))->gpio_spkr_en;
|
||||||
|
|
||||||
acp_legacy_dai_links_create(card);
|
acp_legacy_dai_links_create(card);
|
||||||
|
|
||||||
|
if (gpio_is_valid(spkr_gpio)) {
|
||||||
|
ret = devm_gpio_request(dev, spkr_gpio, "spkren");
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev, "(%s) gpio request failed: %d\n",
|
||||||
|
__func__, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
gpio_direction_output(spkr_gpio, 0);
|
||||||
|
}
|
||||||
|
|
||||||
ret = devm_snd_soc_register_card(&pdev->dev, card);
|
ret = devm_snd_soc_register_card(&pdev->dev, card);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
|
@ -71,6 +71,31 @@ static const struct snd_soc_dapm_route rt5682_map[] = {
|
|||||||
{ "IN1P", NULL, "Headset Mic" },
|
{ "IN1P", NULL, "Headset Mic" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int event_spkr_handler(struct snd_soc_dapm_widget *w,
|
||||||
|
struct snd_kcontrol *k, int event)
|
||||||
|
{
|
||||||
|
struct snd_soc_dapm_context *dapm = w->dapm;
|
||||||
|
struct snd_soc_card *card = dapm->card;
|
||||||
|
struct acp_card_drvdata *drvdata = snd_soc_card_get_drvdata(card);
|
||||||
|
|
||||||
|
if (!gpio_is_valid(drvdata->gpio_spkr_en))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case SND_SOC_DAPM_POST_PMU:
|
||||||
|
gpio_set_value(drvdata->gpio_spkr_en, 1);
|
||||||
|
break;
|
||||||
|
case SND_SOC_DAPM_PRE_PMD:
|
||||||
|
gpio_set_value(drvdata->gpio_spkr_en, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dev_warn(card->dev, "%s invalid setting\n", __func__);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_NS_GPL(event_spkr_handler, SND_SOC_AMD_MACH);
|
||||||
|
|
||||||
/* Define card ops for RT5682 CODEC */
|
/* Define card ops for RT5682 CODEC */
|
||||||
static int acp_card_rt5682_init(struct snd_soc_pcm_runtime *rtd)
|
static int acp_card_rt5682_init(struct snd_soc_pcm_runtime *rtd)
|
||||||
{
|
{
|
||||||
|
@ -17,6 +17,12 @@
|
|||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <sound/soc.h>
|
#include <sound/soc.h>
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
#include <linux/gpio/consumer.h>
|
||||||
|
|
||||||
|
#define EN_SPKR_GPIO_GB 0x11F
|
||||||
|
#define EN_SPKR_GPIO_NK 0x146
|
||||||
|
#define EN_SPKR_GPIO_NONE -EINVAL
|
||||||
|
|
||||||
enum be_id {
|
enum be_id {
|
||||||
HEADSET_BE_ID = 0,
|
HEADSET_BE_ID = 0,
|
||||||
@ -49,9 +55,11 @@ struct acp_card_drvdata {
|
|||||||
unsigned int dai_fmt;
|
unsigned int dai_fmt;
|
||||||
struct clk *wclk;
|
struct clk *wclk;
|
||||||
struct clk *bclk;
|
struct clk *bclk;
|
||||||
|
unsigned int gpio_spkr_en;
|
||||||
};
|
};
|
||||||
|
|
||||||
int acp_sofdsp_dai_links_create(struct snd_soc_card *card);
|
int acp_sofdsp_dai_links_create(struct snd_soc_card *card);
|
||||||
int acp_legacy_dai_links_create(struct snd_soc_card *card);
|
int acp_legacy_dai_links_create(struct snd_soc_card *card);
|
||||||
|
int event_spkr_handler(struct snd_soc_dapm_widget *w,
|
||||||
|
struct snd_kcontrol *k, int event);
|
||||||
#endif
|
#endif
|
||||||
|
@ -27,6 +27,7 @@ static struct acp_card_drvdata sof_rt5682_rt1019_data = {
|
|||||||
.hs_codec_id = RT5682,
|
.hs_codec_id = RT5682,
|
||||||
.amp_codec_id = RT1019,
|
.amp_codec_id = RT1019,
|
||||||
.dmic_codec_id = DMIC,
|
.dmic_codec_id = DMIC,
|
||||||
|
.gpio_spkr_en = EN_SPKR_GPIO_GB,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct acp_card_drvdata sof_rt5682_max_data = {
|
static struct acp_card_drvdata sof_rt5682_max_data = {
|
||||||
@ -36,6 +37,7 @@ static struct acp_card_drvdata sof_rt5682_max_data = {
|
|||||||
.hs_codec_id = RT5682,
|
.hs_codec_id = RT5682,
|
||||||
.amp_codec_id = MAX98360A,
|
.amp_codec_id = MAX98360A,
|
||||||
.dmic_codec_id = DMIC,
|
.dmic_codec_id = DMIC,
|
||||||
|
.gpio_spkr_en = EN_SPKR_GPIO_NK,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct acp_card_drvdata sof_rt5682s_max_data = {
|
static struct acp_card_drvdata sof_rt5682s_max_data = {
|
||||||
@ -45,6 +47,7 @@ static struct acp_card_drvdata sof_rt5682s_max_data = {
|
|||||||
.hs_codec_id = RT5682S,
|
.hs_codec_id = RT5682S,
|
||||||
.amp_codec_id = MAX98360A,
|
.amp_codec_id = MAX98360A,
|
||||||
.dmic_codec_id = DMIC,
|
.dmic_codec_id = DMIC,
|
||||||
|
.gpio_spkr_en = EN_SPKR_GPIO_NK,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct snd_kcontrol_new acp_controls[] = {
|
static const struct snd_kcontrol_new acp_controls[] = {
|
||||||
@ -58,15 +61,16 @@ static const struct snd_kcontrol_new acp_controls[] = {
|
|||||||
static const struct snd_soc_dapm_widget acp_widgets[] = {
|
static const struct snd_soc_dapm_widget acp_widgets[] = {
|
||||||
SND_SOC_DAPM_HP("Headphone Jack", NULL),
|
SND_SOC_DAPM_HP("Headphone Jack", NULL),
|
||||||
SND_SOC_DAPM_MIC("Headset Mic", NULL),
|
SND_SOC_DAPM_MIC("Headset Mic", NULL),
|
||||||
SND_SOC_DAPM_SPK("Spk", NULL),
|
SND_SOC_DAPM_SPK("Spk", event_spkr_handler),
|
||||||
SND_SOC_DAPM_SPK("Left Spk", NULL),
|
SND_SOC_DAPM_SPK("Left Spk", event_spkr_handler),
|
||||||
SND_SOC_DAPM_SPK("Right Spk", NULL),
|
SND_SOC_DAPM_SPK("Right Spk", event_spkr_handler),
|
||||||
};
|
};
|
||||||
|
|
||||||
static int acp_sof_probe(struct platform_device *pdev)
|
static int acp_sof_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct snd_soc_card *card = NULL;
|
struct snd_soc_card *card = NULL;
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
|
unsigned int spkr_gpio;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!pdev->id_entry)
|
if (!pdev->id_entry)
|
||||||
@ -84,9 +88,20 @@ static int acp_sof_probe(struct platform_device *pdev)
|
|||||||
card->controls = acp_controls;
|
card->controls = acp_controls;
|
||||||
card->num_controls = ARRAY_SIZE(acp_controls);
|
card->num_controls = ARRAY_SIZE(acp_controls);
|
||||||
card->drvdata = (struct acp_card_drvdata *)pdev->id_entry->driver_data;
|
card->drvdata = (struct acp_card_drvdata *)pdev->id_entry->driver_data;
|
||||||
|
spkr_gpio = ((struct acp_card_drvdata *)(card->drvdata))->gpio_spkr_en;
|
||||||
|
|
||||||
acp_sofdsp_dai_links_create(card);
|
acp_sofdsp_dai_links_create(card);
|
||||||
|
|
||||||
|
if (gpio_is_valid(spkr_gpio)) {
|
||||||
|
ret = devm_gpio_request(dev, spkr_gpio, "spkren");
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev, "(%s) gpio request failed: %d\n",
|
||||||
|
__func__, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
gpio_direction_output(spkr_gpio, 0);
|
||||||
|
}
|
||||||
|
|
||||||
ret = devm_snd_soc_register_card(&pdev->dev, card);
|
ret = devm_snd_soc_register_card(&pdev->dev, card);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
|
Loading…
Reference in New Issue
Block a user