aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/amd
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/amd')
-rw-r--r--sound/soc/amd/Kconfig1
-rw-r--r--sound/soc/amd/acp-da7219-max98357a.c14
-rw-r--r--sound/soc/amd/acp-pcm-dma.c2
-rw-r--r--sound/soc/amd/acp-rt5645.c4
-rw-r--r--sound/soc/amd/acp3x-rt5682-max9836.c236
-rw-r--r--sound/soc/amd/raven/acp3x-i2s.c14
-rw-r--r--sound/soc/amd/raven/acp3x-pcm-dma.c12
-rw-r--r--sound/soc/amd/raven/pci-acp3x.c21
-rw-r--r--sound/soc/amd/renoir/rn-pci-acp3x.c33
-rw-r--r--sound/soc/amd/renoir/rn_acp3x.h2
10 files changed, 248 insertions, 91 deletions
diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig
index e37cf72f2bab..a6ce000fac3f 100644
--- a/sound/soc/amd/Kconfig
+++ b/sound/soc/amd/Kconfig
@@ -33,6 +33,7 @@ config SND_SOC_AMD_RV_RT5682_MACH
select SND_SOC_MAX98357A
select SND_SOC_CROS_EC_CODEC
select I2C_CROS_EC_TUNNEL
+ select SND_SOC_RT1015
depends on SND_SOC_AMD_ACP3x && I2C && CROS_EC
help
This option enables machine driver for RT5682 and MAX9835.
diff --git a/sound/soc/amd/acp-da7219-max98357a.c b/sound/soc/amd/acp-da7219-max98357a.c
index 9414d7269c4f..a7702e64ec51 100644
--- a/sound/soc/amd/acp-da7219-max98357a.c
+++ b/sound/soc/amd/acp-da7219-max98357a.c
@@ -99,7 +99,7 @@ static int cz_da7219_init(struct snd_soc_pcm_runtime *rtd)
static int da7219_clk_enable(struct snd_pcm_substream *substream)
{
int ret = 0;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
/*
* Set wclk to 48000 because the rate constraint of this driver is
@@ -146,7 +146,7 @@ static const struct snd_pcm_hw_constraint_list constraints_channels = {
static int cz_da7219_play_startup(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card;
struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
@@ -167,7 +167,7 @@ static int cz_da7219_play_startup(struct snd_pcm_substream *substream)
static int cz_da7219_cap_startup(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card;
struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
@@ -189,7 +189,7 @@ static int cz_da7219_cap_startup(struct snd_pcm_substream *substream)
static int cz_max_startup(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card;
struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
@@ -210,7 +210,7 @@ static int cz_max_startup(struct snd_pcm_substream *substream)
static int cz_dmic0_startup(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card;
struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
@@ -231,7 +231,7 @@ static int cz_dmic0_startup(struct snd_pcm_substream *substream)
static int cz_dmic1_startup(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card;
struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
@@ -450,11 +450,13 @@ static int cz_probe(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_ACPI
static const struct acpi_device_id cz_audio_acpi_match[] = {
{ "AMD7219", 0 },
{},
};
MODULE_DEVICE_TABLE(acpi, cz_audio_acpi_match);
+#endif
static struct platform_driver cz_pcm_driver = {
.driver = {
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c
index f54beb7f39a8..143155a840ac 100644
--- a/sound/soc/amd/acp-pcm-dma.c
+++ b/sound/soc/amd/acp-pcm-dma.c
@@ -840,7 +840,7 @@ static int acp_dma_hw_params(struct snd_soc_component *component,
u32 val = 0;
struct snd_pcm_runtime *runtime;
struct audio_substream_data *rtd;
- struct snd_soc_pcm_runtime *prtd = substream->private_data;
+ struct snd_soc_pcm_runtime *prtd = asoc_substream_to_rtd(substream);
struct audio_drv_data *adata = dev_get_drvdata(component->dev);
struct snd_soc_card *card = prtd->card;
struct acp_platform_info *pinfo = snd_soc_card_get_drvdata(card);
diff --git a/sound/soc/amd/acp-rt5645.c b/sound/soc/amd/acp-rt5645.c
index 73b31f88a6b5..d6ba94677ac2 100644
--- a/sound/soc/amd/acp-rt5645.c
+++ b/sound/soc/amd/acp-rt5645.c
@@ -47,7 +47,7 @@ static int cz_aif1_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
int ret = 0;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
ret = snd_soc_dai_set_pll(codec_dai, 0, RT5645_PLL1_S_MCLK,
@@ -182,11 +182,13 @@ static int cz_probe(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_ACPI
static const struct acpi_device_id cz_audio_acpi_match[] = {
{ "AMDI1002", 0 },
{},
};
MODULE_DEVICE_TABLE(acpi, cz_audio_acpi_match);
+#endif
static struct platform_driver cz_pcm_driver = {
.driver = {
diff --git a/sound/soc/amd/acp3x-rt5682-max9836.c b/sound/soc/amd/acp3x-rt5682-max9836.c
index e499c00e0c66..55815fdaa1aa 100644
--- a/sound/soc/amd/acp3x-rt5682-max9836.c
+++ b/sound/soc/amd/acp3x-rt5682-max9836.c
@@ -21,6 +21,7 @@
#include "raven/acp3x.h"
#include "../codecs/rt5682.h"
+#include "../codecs/rt1015.h"
#define PCO_PLAT_CLK 48000000
#define RT5682_PLL_FREQ (48000 * 512)
@@ -30,6 +31,13 @@ static struct snd_soc_jack pco_jack;
static struct clk *rt5682_dai_wclk;
static struct clk *rt5682_dai_bclk;
static struct gpio_desc *dmic_sel;
+void *soc_is_rltk_max(struct device *dev);
+
+enum {
+ RT5682 = 0,
+ MAX,
+ EC,
+};
static int acp3x_5682_init(struct snd_soc_pcm_runtime *rtd)
{
@@ -105,7 +113,7 @@ static int acp3x_5682_init(struct snd_soc_pcm_runtime *rtd)
static int rt5682_clk_enable(struct snd_pcm_substream *substream)
{
int ret = 0;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
/* RT5682 will support only 48K output with 48M mclk */
clk_set_rate(rt5682_dai_wclk, 48000);
@@ -119,6 +127,34 @@ static int rt5682_clk_enable(struct snd_pcm_substream *substream)
return ret;
}
+static int acp3x_1015_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai;
+ int srate, i, ret;
+
+ ret = 0;
+ srate = params_rate(params);
+
+ for_each_rtd_codec_dais(rtd, i, codec_dai) {
+ if (strcmp(codec_dai->component->name, "rt1015-aif"))
+ continue;
+ ret = snd_soc_dai_set_bclk_ratio(codec_dai, 64);
+ if (ret < 0)
+ return ret;
+ ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK,
+ 64 * srate, 256 * srate);
+ if (ret < 0)
+ return ret;
+ ret = snd_soc_dai_set_sysclk(codec_dai, RT1015_SCLK_S_PLL,
+ 256 * srate, SND_SOC_CLOCK_IN);
+ if (ret < 0)
+ return ret;
+ }
+ return ret;
+}
+
static void rt5682_clk_disable(void)
{
clk_disable_unprepare(rt5682_dai_wclk);
@@ -147,7 +183,7 @@ static const struct snd_pcm_hw_constraint_list constraints_channels = {
static int acp3x_5682_startup(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card;
struct acp3x_platform_info *machine = snd_soc_card_get_drvdata(card);
@@ -165,7 +201,7 @@ static int acp3x_5682_startup(struct snd_pcm_substream *substream)
static int acp3x_max_startup(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card;
struct acp3x_platform_info *machine = snd_soc_card_get_drvdata(card);
@@ -181,32 +217,34 @@ static int acp3x_max_startup(struct snd_pcm_substream *substream)
static int acp3x_ec_dmic0_startup(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card;
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
struct acp3x_platform_info *machine = snd_soc_card_get_drvdata(card);
machine->cap_i2s_instance = I2S_BT_INSTANCE;
snd_soc_dai_set_bclk_ratio(codec_dai, 64);
- if (dmic_sel)
- gpiod_set_value(dmic_sel, 0);
return rt5682_clk_enable(substream);
}
-static int acp3x_ec_dmic1_startup(struct snd_pcm_substream *substream)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_card *card = rtd->card;
- struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
- struct acp3x_platform_info *machine = snd_soc_card_get_drvdata(card);
+static int dmic_switch;
- machine->cap_i2s_instance = I2S_BT_INSTANCE;
- snd_soc_dai_set_bclk_ratio(codec_dai, 64);
- if (dmic_sel)
- gpiod_set_value(dmic_sel, 1);
+static int dmic_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = dmic_switch;
+ return 0;
+}
- return rt5682_clk_enable(substream);
+static int dmic_set(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ if (dmic_sel) {
+ dmic_switch = ucontrol->value.integer.value[0];
+ gpiod_set_value(dmic_sel, dmic_switch);
+ }
+ return 0;
}
static void rt5682_shutdown(struct snd_pcm_substream *substream)
@@ -222,6 +260,7 @@ static const struct snd_soc_ops acp3x_5682_ops = {
static const struct snd_soc_ops acp3x_max_play_ops = {
.startup = acp3x_max_startup,
.shutdown = rt5682_shutdown,
+ .hw_params = acp3x_1015_hw_params,
};
static const struct snd_soc_ops acp3x_ec_cap0_ops = {
@@ -229,11 +268,6 @@ static const struct snd_soc_ops acp3x_ec_cap0_ops = {
.shutdown = rt5682_shutdown,
};
-static const struct snd_soc_ops acp3x_ec_cap1_ops = {
- .startup = acp3x_ec_dmic1_startup,
- .shutdown = rt5682_shutdown,
-};
-
SND_SOC_DAILINK_DEF(acp3x_i2s,
DAILINK_COMP_ARRAY(COMP_CPU("acp3x_i2s_playcap.0")));
SND_SOC_DAILINK_DEF(acp3x_bt,
@@ -243,14 +277,28 @@ SND_SOC_DAILINK_DEF(rt5682,
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5682:00", "rt5682-aif1")));
SND_SOC_DAILINK_DEF(max,
DAILINK_COMP_ARRAY(COMP_CODEC("MX98357A:00", "HiFi")));
+SND_SOC_DAILINK_DEF(rt1015,
+ DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1015:00", "rt1015-aif"),
+ COMP_CODEC("i2c-10EC1015:01", "rt1015-aif")));
SND_SOC_DAILINK_DEF(cros_ec,
DAILINK_COMP_ARRAY(COMP_CODEC("GOOG0013:00", "EC Codec I2S RX")));
SND_SOC_DAILINK_DEF(platform,
DAILINK_COMP_ARRAY(COMP_PLATFORM("acp3x_rv_i2s_dma.0")));
-static struct snd_soc_dai_link acp3x_dai_5682_98357[] = {
+static struct snd_soc_codec_conf rt1015_conf[] = {
+ {
+ .dlc = COMP_CODEC_CONF("i2c-10EC1015:00"),
+ .name_prefix = "Left",
+ },
{
+ .dlc = COMP_CODEC_CONF("i2c-10EC1015:01"),
+ .name_prefix = "Right",
+ },
+};
+
+static struct snd_soc_dai_link acp3x_dai[] = {
+ [RT5682] = {
.name = "acp3x-5682-play",
.stream_name = "Playback",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
@@ -261,16 +309,19 @@ static struct snd_soc_dai_link acp3x_dai_5682_98357[] = {
.ops = &acp3x_5682_ops,
SND_SOC_DAILINK_REG(acp3x_i2s, rt5682, platform),
},
- {
+ [MAX] = {
.name = "acp3x-max98357-play",
.stream_name = "HiFi Playback",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
- | SND_SOC_DAIFMT_CBM_CFM,
+ | SND_SOC_DAIFMT_CBS_CFS,
.dpcm_playback = 1,
.ops = &acp3x_max_play_ops,
- SND_SOC_DAILINK_REG(acp3x_bt, max, platform),
+ .cpus = acp3x_bt,
+ .num_cpus = ARRAY_SIZE(acp3x_bt),
+ .platforms = platform,
+ .num_platforms = ARRAY_SIZE(platform),
},
- {
+ [EC] = {
.name = "acp3x-ec-dmic0-capture",
.stream_name = "Capture DMIC0",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
@@ -279,61 +330,136 @@ static struct snd_soc_dai_link acp3x_dai_5682_98357[] = {
.ops = &acp3x_ec_cap0_ops,
SND_SOC_DAILINK_REG(acp3x_bt, cros_ec, platform),
},
- {
- .name = "acp3x-ec-dmic1-capture",
- .stream_name = "Capture DMIC1",
- .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
- | SND_SOC_DAIFMT_CBS_CFS,
- .dpcm_capture = 1,
- .ops = &acp3x_ec_cap1_ops,
- SND_SOC_DAILINK_REG(acp3x_bt, cros_ec, platform),
- },
};
-static const struct snd_soc_dapm_widget acp3x_widgets[] = {
+static const char * const dmic_mux_text[] = {
+ "Front Mic",
+ "Rear Mic",
+};
+
+static SOC_ENUM_SINGLE_DECL(
+ acp3x_dmic_enum, SND_SOC_NOPM, 0, dmic_mux_text);
+
+static const struct snd_kcontrol_new acp3x_dmic_mux_control =
+ SOC_DAPM_ENUM_EXT("DMIC Select Mux", acp3x_dmic_enum,
+ dmic_get, dmic_set);
+
+static const struct snd_soc_dapm_widget acp3x_5682_widgets[] = {
SND_SOC_DAPM_HP("Headphone Jack", NULL),
SND_SOC_DAPM_SPK("Spk", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_MUX("Dmic Mux", SND_SOC_NOPM, 0, 0,
+ &acp3x_dmic_mux_control),
};
-static const struct snd_soc_dapm_route acp3x_audio_route[] = {
+static const struct snd_soc_dapm_route acp3x_5682_audio_route[] = {
{"Headphone Jack", NULL, "HPOL"},
{"Headphone Jack", NULL, "HPOR"},
{"IN1P", NULL, "Headset Mic"},
{"Spk", NULL, "Speaker"},
+ {"Dmic Mux", "Front Mic", "DMIC"},
+ {"Dmic Mux", "Rear Mic", "DMIC"},
};
-static const struct snd_kcontrol_new acp3x_mc_controls[] = {
+static const struct snd_kcontrol_new acp3x_5682_mc_controls[] = {
SOC_DAPM_PIN_SWITCH("Headphone Jack"),
SOC_DAPM_PIN_SWITCH("Spk"),
SOC_DAPM_PIN_SWITCH("Headset Mic"),
};
-static struct snd_soc_card acp3x_card = {
+static struct snd_soc_card acp3x_5682 = {
.name = "acp3xalc5682m98357",
.owner = THIS_MODULE,
- .dai_link = acp3x_dai_5682_98357,
- .num_links = ARRAY_SIZE(acp3x_dai_5682_98357),
- .dapm_widgets = acp3x_widgets,
- .num_dapm_widgets = ARRAY_SIZE(acp3x_widgets),
- .dapm_routes = acp3x_audio_route,
- .num_dapm_routes = ARRAY_SIZE(acp3x_audio_route),
- .controls = acp3x_mc_controls,
- .num_controls = ARRAY_SIZE(acp3x_mc_controls),
+ .dai_link = acp3x_dai,
+ .num_links = ARRAY_SIZE(acp3x_dai),
+ .dapm_widgets = acp3x_5682_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(acp3x_5682_widgets),
+ .dapm_routes = acp3x_5682_audio_route,
+ .num_dapm_routes = ARRAY_SIZE(acp3x_5682_audio_route),
+ .controls = acp3x_5682_mc_controls,
+ .num_controls = ARRAY_SIZE(acp3x_5682_mc_controls),
+};
+
+static const struct snd_soc_dapm_widget acp3x_1015_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_MUX("Dmic Mux", SND_SOC_NOPM, 0, 0,
+ &acp3x_dmic_mux_control),
+ SND_SOC_DAPM_SPK("Left Spk", NULL),
+ SND_SOC_DAPM_SPK("Right Spk", NULL),
+};
+
+static const struct snd_soc_dapm_route acp3x_1015_route[] = {
+ {"Headphone Jack", NULL, "HPOL"},
+ {"Headphone Jack", NULL, "HPOR"},
+ {"IN1P", NULL, "Headset Mic"},
+ {"Dmic Mux", "Front Mic", "DMIC"},
+ {"Dmic Mux", "Rear Mic", "DMIC"},
+ {"Left Spk", NULL, "Left SPO"},
+ {"Right Spk", NULL, "Right SPO"},
+};
+
+static const struct snd_kcontrol_new acp3x_mc_1015_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Headphone Jack"),
+ SOC_DAPM_PIN_SWITCH("Headset Mic"),
+ SOC_DAPM_PIN_SWITCH("Left Spk"),
+ SOC_DAPM_PIN_SWITCH("Right Spk"),
+};
+
+static struct snd_soc_card acp3x_1015 = {
+ .name = "acp3xalc56821015",
+ .owner = THIS_MODULE,
+ .dai_link = acp3x_dai,
+ .num_links = ARRAY_SIZE(acp3x_dai),
+ .dapm_widgets = acp3x_1015_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(acp3x_1015_widgets),
+ .dapm_routes = acp3x_1015_route,
+ .num_dapm_routes = ARRAY_SIZE(acp3x_1015_route),
+ .codec_conf = rt1015_conf,
+ .num_configs = ARRAY_SIZE(rt1015_conf),
+ .controls = acp3x_mc_1015_controls,
+ .num_controls = ARRAY_SIZE(acp3x_mc_1015_controls),
};
+void *soc_is_rltk_max(struct device *dev)
+{
+ const struct acpi_device_id *match;
+
+ match = acpi_match_device(dev->driver->acpi_match_table, dev);
+ if (!match)
+ return NULL;
+ return (void *)match->driver_data;
+}
+
+static void card_spk_dai_link_present(struct snd_soc_dai_link *links,
+ const char *card_name)
+{
+ if (!strcmp(card_name, "acp3xalc56821015")) {
+ links[1].codecs = rt1015;
+ links[1].num_codecs = ARRAY_SIZE(rt1015);
+ } else {
+ links[1].codecs = max;
+ links[1].num_codecs = ARRAY_SIZE(max);
+ }
+}
+
static int acp3x_probe(struct platform_device *pdev)
{
int ret;
struct snd_soc_card *card;
struct acp3x_platform_info *machine;
+ struct device *dev = &pdev->dev;
+
+ card = (struct snd_soc_card *)soc_is_rltk_max(dev);
+ if (!card)
+ return -ENODEV;
machine = devm_kzalloc(&pdev->dev, sizeof(*machine), GFP_KERNEL);
if (!machine)
return -ENOMEM;
- card = &acp3x_card;
- acp3x_card.dev = &pdev->dev;
+ card_spk_dai_link_present(card->dai_link, card->name);
+ card->dev = &pdev->dev;
platform_set_drvdata(pdev, card);
snd_soc_card_set_drvdata(card, machine);
@@ -344,18 +470,19 @@ static int acp3x_probe(struct platform_device *pdev)
return PTR_ERR(dmic_sel);
}
- ret = devm_snd_soc_register_card(&pdev->dev, &acp3x_card);
+ ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) {
dev_err(&pdev->dev,
"devm_snd_soc_register_card(%s) failed: %d\n",
- acp3x_card.name, ret);
+ card->name, ret);
return ret;
}
return 0;
}
static const struct acpi_device_id acp3x_audio_acpi_match[] = {
- { "AMDI5682", 0 },
+ { "AMDI5682", (unsigned long)&acp3x_5682},
+ { "AMDI1015", (unsigned long)&acp3x_1015},
{},
};
MODULE_DEVICE_TABLE(acpi, acp3x_audio_acpi_match);
@@ -372,5 +499,6 @@ static struct platform_driver acp3x_audio = {
module_platform_driver(acp3x_audio);
MODULE_AUTHOR("akshu.agrawal@amd.com");
-MODULE_DESCRIPTION("ALC5682 & MAX98357 audio support");
+MODULE_AUTHOR("Vishnuvardhanrao.Ravulapati@amd.com");
+MODULE_DESCRIPTION("ALC5682 ALC1015 & MAX98357 audio support");
MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/amd/raven/acp3x-i2s.c b/sound/soc/amd/raven/acp3x-i2s.c
index a532e01a2622..5bc028692fcf 100644
--- a/sound/soc/amd/raven/acp3x-i2s.c
+++ b/sound/soc/amd/raven/acp3x-i2s.c
@@ -80,7 +80,7 @@ static int acp3x_i2s_hwparams(struct snd_pcm_substream *substream,
u32 val;
u32 reg_val, frmt_reg;
- prtd = substream->private_data;
+ prtd = asoc_substream_to_rtd(substream);
rtd = substream->runtime->private_data;
card = prtd->card;
adata = snd_soc_dai_get_drvdata(dai);
@@ -149,22 +149,10 @@ static int acp3x_i2s_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai)
{
struct i2s_stream_instance *rtd;
- struct snd_soc_pcm_runtime *prtd;
- struct snd_soc_card *card;
- struct acp3x_platform_info *pinfo;
u32 ret, val, period_bytes, reg_val, ier_val, water_val;
u32 buf_size, buf_reg;
- prtd = substream->private_data;
rtd = substream->runtime->private_data;
- card = prtd->card;
- pinfo = snd_soc_card_get_drvdata(card);
- if (pinfo) {
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- rtd->i2s_instance = pinfo->play_i2s_instance;
- else
- rtd->i2s_instance = pinfo->cap_i2s_instance;
- }
period_bytes = frames_to_bytes(substream->runtime,
substream->runtime->period_size);
buf_size = frames_to_bytes(substream->runtime,
diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c
index e6386de20ac7..417cda24030c 100644
--- a/sound/soc/amd/raven/acp3x-pcm-dma.c
+++ b/sound/soc/amd/raven/acp3x-pcm-dma.c
@@ -217,7 +217,7 @@ static int acp3x_dma_open(struct snd_soc_component *component,
int ret;
runtime = substream->runtime;
- prtd = substream->private_data;
+ prtd = asoc_substream_to_rtd(substream);
component = snd_soc_rtdcom_lookup(prtd, DRV_NAME);
adata = dev_get_drvdata(component->dev);
i2s_data = kzalloc(sizeof(*i2s_data), GFP_KERNEL);
@@ -238,7 +238,7 @@ static int acp3x_dma_open(struct snd_soc_component *component,
}
if (!adata->play_stream && !adata->capture_stream &&
- adata->i2ssp_play_stream && !adata->i2ssp_capture_stream)
+ !adata->i2ssp_play_stream && !adata->i2ssp_capture_stream)
rv_writel(1, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB);
i2s_data->acp3x_base = adata->acp3x_base;
@@ -258,7 +258,7 @@ static int acp3x_dma_hw_params(struct snd_soc_component *component,
struct i2s_dev_data *adata;
u64 size;
- prtd = substream->private_data;
+ prtd = asoc_substream_to_rtd(substream);
card = prtd->card;
pinfo = snd_soc_card_get_drvdata(card);
adata = dev_get_drvdata(component->dev);
@@ -301,15 +301,11 @@ static int acp3x_dma_hw_params(struct snd_soc_component *component,
static snd_pcm_uframes_t acp3x_dma_pointer(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *prtd;
- struct snd_soc_card *card;
struct i2s_stream_instance *rtd;
u32 pos;
u32 buffersize;
u64 bytescount;
- prtd = substream->private_data;
- card = prtd->card;
rtd = substream->runtime->private_data;
buffersize = frames_to_bytes(substream->runtime,
@@ -344,7 +340,7 @@ static int acp3x_dma_close(struct snd_soc_component *component,
struct i2s_dev_data *adata;
struct i2s_stream_instance *ins;
- prtd = substream->private_data;
+ prtd = asoc_substream_to_rtd(substream);
component = snd_soc_rtdcom_lookup(prtd, DRV_NAME);
adata = dev_get_drvdata(component->dev);
ins = substream->runtime->private_data;
diff --git a/sound/soc/amd/raven/pci-acp3x.c b/sound/soc/amd/raven/pci-acp3x.c
index ebf4388b6262..31b797c8bfe6 100644
--- a/sound/soc/amd/raven/pci-acp3x.c
+++ b/sound/soc/amd/raven/pci-acp3x.c
@@ -19,10 +19,12 @@ struct acp3x_dev_data {
bool acp3x_audio_mode;
struct resource *res;
struct platform_device *pdev[ACP3x_DEVS];
+ u32 pme_en;
};
-static int acp3x_power_on(void __iomem *acp3x_base)
+static int acp3x_power_on(struct acp3x_dev_data *adata)
{
+ void __iomem *acp3x_base = adata->acp3x_base;
u32 val;
int timeout;
@@ -39,10 +41,10 @@ static int acp3x_power_on(void __iomem *acp3x_base)
while (++timeout < 500) {
val = rv_readl(acp3x_base + mmACP_PGFSM_STATUS);
if (!val) {
- /* Set PME_EN as after ACP power On,
- * PME_EN gets cleared
+ /* ACP power On clears PME_EN.
+ * Restore the value to its prior state
*/
- rv_writel(0x1, acp3x_base + mmACP_PME_EN);
+ rv_writel(adata->pme_en, acp3x_base + mmACP_PME_EN);
return 0;
}
udelay(1);
@@ -74,12 +76,13 @@ static int acp3x_reset(void __iomem *acp3x_base)
return -ETIMEDOUT;
}
-static int acp3x_init(void __iomem *acp3x_base)
+static int acp3x_init(struct acp3x_dev_data *adata)
{
+ void __iomem *acp3x_base = adata->acp3x_base;
int ret;
/* power on */
- ret = acp3x_power_on(acp3x_base);
+ ret = acp3x_power_on(adata);
if (ret) {
pr_err("ACP3x power on failed\n");
return ret;
@@ -151,7 +154,9 @@ static int snd_acp3x_probe(struct pci_dev *pci,
}
pci_set_master(pci);
pci_set_drvdata(pci, adata);
- ret = acp3x_init(adata->acp3x_base);
+ /* Save ACP_PME_EN state */
+ adata->pme_en = rv_readl(adata->acp3x_base + mmACP_PME_EN);
+ ret = acp3x_init(adata);
if (ret)
goto disable_msi;
@@ -274,7 +279,7 @@ static int snd_acp3x_resume(struct device *dev)
struct acp3x_dev_data *adata;
adata = dev_get_drvdata(dev);
- ret = acp3x_init(adata->acp3x_base);
+ ret = acp3x_init(adata);
if (ret) {
dev_err(dev, "ACP init failed\n");
return ret;
diff --git a/sound/soc/amd/renoir/rn-pci-acp3x.c b/sound/soc/amd/renoir/rn-pci-acp3x.c
index 859ed67b93cf..b943e59fc302 100644
--- a/sound/soc/amd/renoir/rn-pci-acp3x.c
+++ b/sound/soc/amd/renoir/rn-pci-acp3x.c
@@ -5,6 +5,7 @@
//Copyright 2020 Advanced Micro Devices, Inc.
#include <linux/pci.h>
+#include <linux/acpi.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/delay.h>
@@ -18,6 +19,16 @@ static int acp_power_gating;
module_param(acp_power_gating, int, 0644);
MODULE_PARM_DESC(acp_power_gating, "Enable acp power gating");
+/**
+ * dmic_acpi_check = -1 - Checks ACPI method to know DMIC hardware status runtime
+ * = 0 - Skips the DMIC device creation and returns probe failure
+ * = 1 - Assumes that platform has DMIC support and skips ACPI
+ * method check
+ */
+static int dmic_acpi_check = ACP_DMIC_AUTO;
+module_param(dmic_acpi_check, bint, 0644);
+MODULE_PARM_DESC(dmic_acpi_check, "checks Dmic hardware runtime");
+
struct acp_dev_data {
void __iomem *acp_base;
struct resource *res;
@@ -157,6 +168,10 @@ static int snd_rn_acp_probe(struct pci_dev *pci,
{
struct acp_dev_data *adata;
struct platform_device_info pdevinfo[ACP_DEVS];
+#if defined(CONFIG_ACPI)
+ acpi_handle handle;
+ acpi_integer dmic_status;
+#endif
unsigned int irqflags;
int ret, index;
u32 addr;
@@ -201,6 +216,24 @@ static int snd_rn_acp_probe(struct pci_dev *pci,
if (ret)
goto disable_msi;
+ if (!dmic_acpi_check) {
+ ret = -ENODEV;
+ goto de_init;
+ } else if (dmic_acpi_check == ACP_DMIC_AUTO) {
+#if defined(CONFIG_ACPI)
+ handle = ACPI_HANDLE(&pci->dev);
+ ret = acpi_evaluate_integer(handle, "_WOV", NULL, &dmic_status);
+ if (ACPI_FAILURE(ret)) {
+ ret = -EINVAL;
+ goto de_init;
+ }
+ if (!dmic_status) {
+ ret = -ENODEV;
+ goto de_init;
+ }
+#endif
+ }
+
adata->res = devm_kzalloc(&pci->dev,
sizeof(struct resource) * 2,
GFP_KERNEL);
diff --git a/sound/soc/amd/renoir/rn_acp3x.h b/sound/soc/amd/renoir/rn_acp3x.h
index 75228e306e0b..14620399d766 100644
--- a/sound/soc/amd/renoir/rn_acp3x.h
+++ b/sound/soc/amd/renoir/rn_acp3x.h
@@ -55,6 +55,8 @@
#define MAX_BUFFER (CAPTURE_MAX_PERIOD_SIZE * CAPTURE_MAX_NUM_PERIODS)
#define MIN_BUFFER MAX_BUFFER
+#define ACP_DMIC_AUTO -1
+
struct pdm_dev_data {
u32 pdm_irq;
void __iomem *acp_base;