Commit ad83b1ad authored by Brent Lu's avatar Brent Lu Committed by Mark Brown

ASoC: Intel: sof_rt5682: Add ALC1015Q-VB speaker amp support

This patch adds jsl_rt5682_rt1015p which supports the RT5682 headset
codec and ALC1015Q-VB speaker amplifier combination on JasperLake
platform.

This driver also supports ALC1015Q-CG if running in auto-mode.
Following table shows the audio interface support of the two
amplifiers.

          | ALC1015Q-CG | ALC1015Q-VB
=====================================
I2C       | Yes         | No
Auto-mode | 48K, 64fs   | 16k, 32fs
                        | 48k, 32fs
                        | 48k, 64fs
Signed-off-by: default avatarBrent Lu <brent.lu@intel.com>
Acked-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20210317110824.20814-1-brent.lu@intel.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 7ec79d38
...@@ -457,6 +457,7 @@ config SND_SOC_INTEL_SOF_RT5682_MACH ...@@ -457,6 +457,7 @@ config SND_SOC_INTEL_SOF_RT5682_MACH
select SND_SOC_MAX98373_I2C select SND_SOC_MAX98373_I2C
select SND_SOC_RT1011 select SND_SOC_RT1011
select SND_SOC_RT1015 select SND_SOC_RT1015
select SND_SOC_RT1015P
select SND_SOC_RT5682_I2C select SND_SOC_RT5682_I2C
select SND_SOC_DMIC select SND_SOC_DMIC
select SND_SOC_HDAC_HDMI select SND_SOC_HDAC_HDMI
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#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>
#include <sound/soc-acpi.h>
#include <sound/soc-dai.h> #include <sound/soc-dai.h>
#include <sound/soc-dapm.h> #include <sound/soc-dapm.h>
#include <uapi/sound/asound.h> #include <uapi/sound/asound.h>
...@@ -136,3 +137,107 @@ void sof_rt1011_codec_conf(struct snd_soc_card *card) ...@@ -136,3 +137,107 @@ void sof_rt1011_codec_conf(struct snd_soc_card *card)
card->codec_conf = rt1011_codec_confs; card->codec_conf = rt1011_codec_confs;
card->num_configs = ARRAY_SIZE(rt1011_codec_confs); card->num_configs = ARRAY_SIZE(rt1011_codec_confs);
} }
/*
* rt1015: i2c mode driver for ALC1015 and ALC1015Q
* rt1015p: auto-mode driver for ALC1015, ALC1015Q, and ALC1015Q-VB
*
* For stereo output, there are always two amplifiers on the board.
* However, the ACPI implements only one device instance (UID=0) if they
* are sharing the same enable pin. The code will detect the number of
* device instance and use corresponding DAPM structures for
* initialization.
*/
static const struct snd_soc_dapm_route rt1015p_1dev_dapm_routes[] = {
/* speaker */
{ "Left Spk", NULL, "Speaker" },
{ "Right Spk", NULL, "Speaker" },
};
static const struct snd_soc_dapm_route rt1015p_2dev_dapm_routes[] = {
/* speaker */
{ "Left Spk", NULL, "Left Speaker" },
{ "Right Spk", NULL, "Right Speaker" },
};
static struct snd_soc_codec_conf rt1015p_codec_confs[] = {
{
.dlc = COMP_CODEC_CONF(RT1015P_DEV0_NAME),
.name_prefix = "Left",
},
{
.dlc = COMP_CODEC_CONF(RT1015P_DEV1_NAME),
.name_prefix = "Right",
},
};
static struct snd_soc_dai_link_component rt1015p_dai_link_components[] = {
{
.name = RT1015P_DEV0_NAME,
.dai_name = RT1015P_CODEC_DAI,
},
{
.name = RT1015P_DEV1_NAME,
.dai_name = RT1015P_CODEC_DAI,
},
};
static int rt1015p_get_num_codecs(void)
{
static int dev_num;
if (dev_num)
return dev_num;
if (!acpi_dev_present("RTL1015", "1", -1))
dev_num = 1;
else
dev_num = 2;
return dev_num;
}
static int rt1015p_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
/* reserved for debugging purpose */
return 0;
}
static const struct snd_soc_ops rt1015p_ops = {
.hw_params = rt1015p_hw_params,
};
static int rt1015p_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_card *card = rtd->card;
int ret;
if (rt1015p_get_num_codecs() == 1)
ret = snd_soc_dapm_add_routes(&card->dapm, rt1015p_1dev_dapm_routes,
ARRAY_SIZE(rt1015p_1dev_dapm_routes));
else
ret = snd_soc_dapm_add_routes(&card->dapm, rt1015p_2dev_dapm_routes,
ARRAY_SIZE(rt1015p_2dev_dapm_routes));
if (ret)
dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret);
return ret;
}
void sof_rt1015p_dai_link(struct snd_soc_dai_link *link)
{
link->codecs = rt1015p_dai_link_components;
link->num_codecs = rt1015p_get_num_codecs();
link->init = rt1015p_init;
link->ops = &rt1015p_ops;
}
void sof_rt1015p_codec_conf(struct snd_soc_card *card)
{
if (rt1015p_get_num_codecs() == 1)
return;
card->codec_conf = rt1015p_codec_confs;
card->num_configs = ARRAY_SIZE(rt1015p_codec_confs);
}
...@@ -21,4 +21,11 @@ ...@@ -21,4 +21,11 @@
void sof_rt1011_dai_link(struct snd_soc_dai_link *link); void sof_rt1011_dai_link(struct snd_soc_dai_link *link);
void sof_rt1011_codec_conf(struct snd_soc_card *card); void sof_rt1011_codec_conf(struct snd_soc_card *card);
#define RT1015P_CODEC_DAI "HiFi"
#define RT1015P_DEV0_NAME "RTL1015:00"
#define RT1015P_DEV1_NAME "RTL1015:01"
void sof_rt1015p_dai_link(struct snd_soc_dai_link *link);
void sof_rt1015p_codec_conf(struct snd_soc_card *card);
#endif /* __SOF_REALTEK_COMMON_H */ #endif /* __SOF_REALTEK_COMMON_H */
...@@ -45,8 +45,9 @@ ...@@ -45,8 +45,9 @@
#define SOF_RT1011_SPEAKER_AMP_PRESENT BIT(13) #define SOF_RT1011_SPEAKER_AMP_PRESENT BIT(13)
#define SOF_RT1015_SPEAKER_AMP_PRESENT BIT(14) #define SOF_RT1015_SPEAKER_AMP_PRESENT BIT(14)
#define SOF_RT1015_SPEAKER_AMP_100FS BIT(15) #define SOF_RT1015_SPEAKER_AMP_100FS BIT(15)
#define SOF_MAX98373_SPEAKER_AMP_PRESENT BIT(16) #define SOF_RT1015P_SPEAKER_AMP_PRESENT BIT(16)
#define SOF_MAX98360A_SPEAKER_AMP_PRESENT BIT(17) #define SOF_MAX98373_SPEAKER_AMP_PRESENT BIT(17)
#define SOF_MAX98360A_SPEAKER_AMP_PRESENT BIT(18)
/* Default: MCLK on, MCLK 19.2M, SSP0 */ /* Default: MCLK on, MCLK 19.2M, SSP0 */
static unsigned long sof_rt5682_quirk = SOF_RT5682_MCLK_EN | static unsigned long sof_rt5682_quirk = SOF_RT5682_MCLK_EN |
...@@ -723,6 +724,8 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, ...@@ -723,6 +724,8 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
links[id].num_codecs = ARRAY_SIZE(rt1015_components); links[id].num_codecs = ARRAY_SIZE(rt1015_components);
links[id].init = speaker_codec_init_lr; links[id].init = speaker_codec_init_lr;
links[id].ops = &sof_rt1015_ops; links[id].ops = &sof_rt1015_ops;
} else if (sof_rt5682_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) {
sof_rt1015p_dai_link(&links[id]);
} else if (sof_rt5682_quirk & } else if (sof_rt5682_quirk &
SOF_MAX98373_SPEAKER_AMP_PRESENT) { SOF_MAX98373_SPEAKER_AMP_PRESENT) {
links[id].codecs = max_98373_components; links[id].codecs = max_98373_components;
...@@ -851,6 +854,8 @@ static int sof_audio_probe(struct platform_device *pdev) ...@@ -851,6 +854,8 @@ static int sof_audio_probe(struct platform_device *pdev)
sof_max98373_codec_conf(&sof_audio_card_rt5682); sof_max98373_codec_conf(&sof_audio_card_rt5682);
else if (sof_rt5682_quirk & SOF_RT1011_SPEAKER_AMP_PRESENT) else if (sof_rt5682_quirk & SOF_RT1011_SPEAKER_AMP_PRESENT)
sof_rt1011_codec_conf(&sof_audio_card_rt5682); sof_rt1011_codec_conf(&sof_audio_card_rt5682);
else if (sof_rt5682_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT)
sof_rt1015p_codec_conf(&sof_audio_card_rt5682);
dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp, dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp,
dmic_be_num, hdmi_num); dmic_be_num, hdmi_num);
...@@ -940,6 +945,15 @@ static const struct platform_device_id board_ids[] = { ...@@ -940,6 +945,15 @@ static const struct platform_device_id board_ids[] = {
SOF_RT5682_SSP_AMP(1) | SOF_RT5682_SSP_AMP(1) |
SOF_RT5682_NUM_HDMIDEV(4)), SOF_RT5682_NUM_HDMIDEV(4)),
}, },
{
.name = "jsl_rt5682_rt1015p",
.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
SOF_RT5682_MCLK_24MHZ |
SOF_RT5682_SSP_CODEC(0) |
SOF_SPEAKER_AMP_PRESENT |
SOF_RT1015P_SPEAKER_AMP_PRESENT |
SOF_RT5682_SSP_AMP(1)),
},
{ } { }
}; };
...@@ -966,3 +980,4 @@ MODULE_ALIAS("platform:tgl_max98373_rt5682"); ...@@ -966,3 +980,4 @@ MODULE_ALIAS("platform:tgl_max98373_rt5682");
MODULE_ALIAS("platform:jsl_rt5682_max98360a"); MODULE_ALIAS("platform:jsl_rt5682_max98360a");
MODULE_ALIAS("platform:cml_rt1015_rt5682"); MODULE_ALIAS("platform:cml_rt1015_rt5682");
MODULE_ALIAS("platform:tgl_rt1011_rt5682"); MODULE_ALIAS("platform:tgl_rt1011_rt5682");
MODULE_ALIAS("platform:jsl_rt5682_rt1015p");
...@@ -19,6 +19,11 @@ static struct snd_soc_acpi_codecs rt1015_spk = { ...@@ -19,6 +19,11 @@ static struct snd_soc_acpi_codecs rt1015_spk = {
.codecs = {"10EC1015"} .codecs = {"10EC1015"}
}; };
static struct snd_soc_acpi_codecs rt1015p_spk = {
.num_codecs = 1,
.codecs = {"RTL1015"}
};
static struct snd_soc_acpi_codecs mx98360a_spk = { static struct snd_soc_acpi_codecs mx98360a_spk = {
.num_codecs = 1, .num_codecs = 1,
.codecs = {"MX98360A"} .codecs = {"MX98360A"}
...@@ -52,6 +57,14 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_jsl_machines[] = { ...@@ -52,6 +57,14 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_jsl_machines[] = {
.quirk_data = &rt1015_spk, .quirk_data = &rt1015_spk,
.sof_tplg_filename = "sof-jsl-rt5682-rt1015.tplg", .sof_tplg_filename = "sof-jsl-rt5682-rt1015.tplg",
}, },
{
.id = "10EC5682",
.drv_name = "jsl_rt5682_rt1015p",
.sof_fw_filename = "sof-jsl.ri",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &rt1015p_spk,
.sof_tplg_filename = "sof-jsl-rt5682-rt1015.tplg",
},
{ {
.id = "10EC5682", .id = "10EC5682",
.drv_name = "jsl_rt5682_max98360a", .drv_name = "jsl_rt5682_max98360a",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment