ASoC: Intel: sof_rt5682: Add ALC1015Q-VB speaker amp support
authorBrent Lu <brent.lu@intel.com>
Wed, 17 Mar 2021 11:08:24 +0000 (19:08 +0800)
committerMark Brown <broonie@kernel.org>
Thu, 18 Mar 2021 13:54:45 +0000 (13:54 +0000)
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: Brent Lu <brent.lu@intel.com>
Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20210317110824.20814-1-brent.lu@intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/intel/boards/Kconfig
sound/soc/intel/boards/sof_realtek_common.c
sound/soc/intel/boards/sof_realtek_common.h
sound/soc/intel/boards/sof_rt5682.c
sound/soc/intel/common/soc-acpi-intel-jsl-match.c

index d1d2812..5837939 100644 (file)
@@ -457,6 +457,7 @@ config SND_SOC_INTEL_SOF_RT5682_MACH
        select SND_SOC_MAX98373_I2C
        select SND_SOC_RT1011
        select SND_SOC_RT1015
+       select SND_SOC_RT1015P
        select SND_SOC_RT5682_I2C
        select SND_SOC_DMIC
        select SND_SOC_HDAC_HDMI
index f3cf73c..2ec34f8 100644 (file)
@@ -7,6 +7,7 @@
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
+#include <sound/soc-acpi.h>
 #include <sound/soc-dai.h>
 #include <sound/soc-dapm.h>
 #include <uapi/sound/asound.h>
@@ -136,3 +137,107 @@ void sof_rt1011_codec_conf(struct snd_soc_card *card)
        card->codec_conf = 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);
+}
index 87cb381..cb0b49b 100644 (file)
 void sof_rt1011_dai_link(struct snd_soc_dai_link *link);
 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 */
index 55505e2..f4b898c 100644 (file)
@@ -45,8 +45,9 @@
 #define SOF_RT1011_SPEAKER_AMP_PRESENT         BIT(13)
 #define SOF_RT1015_SPEAKER_AMP_PRESENT         BIT(14)
 #define SOF_RT1015_SPEAKER_AMP_100FS           BIT(15)
-#define SOF_MAX98373_SPEAKER_AMP_PRESENT       BIT(16)
-#define SOF_MAX98360A_SPEAKER_AMP_PRESENT      BIT(17)
+#define SOF_RT1015P_SPEAKER_AMP_PRESENT                BIT(16)
+#define SOF_MAX98373_SPEAKER_AMP_PRESENT       BIT(17)
+#define SOF_MAX98360A_SPEAKER_AMP_PRESENT      BIT(18)
 
 /* Default: MCLK on, MCLK 19.2M, SSP0  */
 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,
                        links[id].num_codecs = ARRAY_SIZE(rt1015_components);
                        links[id].init = speaker_codec_init_lr;
                        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 &
                                SOF_MAX98373_SPEAKER_AMP_PRESENT) {
                        links[id].codecs = max_98373_components;
@@ -851,6 +854,8 @@ static int sof_audio_probe(struct platform_device *pdev)
                sof_max98373_codec_conf(&sof_audio_card_rt5682);
        else if (sof_rt5682_quirk & SOF_RT1011_SPEAKER_AMP_PRESENT)
                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,
                                              dmic_be_num, hdmi_num);
@@ -940,6 +945,15 @@ static const struct platform_device_id board_ids[] = {
                                        SOF_RT5682_SSP_AMP(1) |
                                        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");
 MODULE_ALIAS("platform:jsl_rt5682_max98360a");
 MODULE_ALIAS("platform:cml_rt1015_rt5682");
 MODULE_ALIAS("platform:tgl_rt1011_rt5682");
+MODULE_ALIAS("platform:jsl_rt5682_rt1015p");
index 52238db..73fe4f8 100644 (file)
@@ -19,6 +19,11 @@ static struct snd_soc_acpi_codecs rt1015_spk = {
        .codecs = {"10EC1015"}
 };
 
+static struct snd_soc_acpi_codecs rt1015p_spk = {
+       .num_codecs = 1,
+       .codecs = {"RTL1015"}
+};
+
 static struct snd_soc_acpi_codecs mx98360a_spk = {
        .num_codecs = 1,
        .codecs = {"MX98360A"}
@@ -54,6 +59,14 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_jsl_machines[] = {
        },
        {
                .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",
                .drv_name = "jsl_rt5682_max98360a",
                .sof_fw_filename = "sof-jsl.ri",
                .machine_quirk = snd_soc_acpi_codec_list,