summaryrefslogtreecommitdiffstats
path: root/sound/soc/intel/boards/sof_rt5682.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-08-30 13:45:05 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2023-08-30 13:45:05 -0700
commit4fb0dacb78c6a041bbd38ddd998df806af5c2c69 (patch)
treef175caac9bc11c78632959a954a6b618fbf8f5c1 /sound/soc/intel/boards/sof_rt5682.c
parent461f35f014466c4e26dca6be0f431f57297df3f2 (diff)
parent358040e3807754944dbddf948a23c6d914297ed7 (diff)
downloadlinux-stable-4fb0dacb78c6a041bbd38ddd998df806af5c2c69.tar.gz
linux-stable-4fb0dacb78c6a041bbd38ddd998df806af5c2c69.tar.bz2
linux-stable-4fb0dacb78c6a041bbd38ddd998df806af5c2c69.zip
Merge tag 'sound-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "We've received a fairly wide range of changes at this time, including for ALSA and ASoC core, but all of them are rather small changes. Here are some highlights: ALSA / ASoC Core: - Fixes of inconsistent locking around control API helpers - A few new control API functions and cleanups - Workarounds for potential UAFs by delayed kobj releases - Unified PCM copy ops with iov_iter - Continued efforts for ASoC API cleanups ASoC: - An adaptor to allow use of IIO DACs and ADCs in ASoC which pulls in some IIO changes - Create a library function for intlog10() and use it in the NAU8825 driver - Convert drivers to use the more modern maple tree register cache - Lots of work on the SOF framework, AMD and Intel drivers, including a lot of cleanup and new device support - Standardization of the presentation of jacks from drivers - Provision of some generic sound card DT properties - Support for AMD Van Gogh, AMD machines with MAX98388 and NAU8821, AWInic AW88261, Cirrus Logic CS35L36 and CS42L43, various Intel platforms including AVS machines with ES8336 and RT5663, Mediatek MT7986, NXP i.MX93, RealTek RT1017 and StarFive JH7110 Others: - New test coverage including ASoC and topology tests in KUnit; this also involves enabling UML builds of ALSA since that's the default KUnit test environment which pulls in the addition of some stubs to the driver - More enhancement of pcmtest driver - A few fixes / enhancements of MIDI 2.0 UMP core - Using PCI definitions in allover HD-audio code - Support for Cirrus CS35L56 and TI TAS2781 HD-audio sub-codecs - CS35L41 HD-audio sub-codec improvements - Continued emu10k1 improvements" * tag 'sound-6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (693 commits) ALSA: pcm: Fix missing fixup call in compat hw_refine ioctl ASoC: dwc: i2s: Fix unused functions ALSA: usb-audio: Don't try to submit URBs after disconnection ALSA: emu10k1: add separate documentation for E-MU cards ALSA: emu10k1: more documentation updates ALSA: emu10k1: de-duplicate audigy-mixer.rst vs. sb-live-mixer.rst ALSA: ump: Fix -Wformat-truncation warnings ALSA: hda: Add missing dependency on CONFIG_EFI for Cirrus/TI sub-codecs ALSA: doc: Fix missing backquote in midi-2.0.rst ALSA: hda/realtek: Add quirk for mute LEDs on HP ENVY x360 15-eu0xxx ALSA: hda/tas2781: Switch back to use struct i2c_driver's .probe() ASoC: soc-core.c: Do not error if a DAI link component is not found ASoC: codecs: Fix error code in aw88261_i2c_probe() ASoC: audio-graph-card.c: move audio_graph_parse_of() ASoC: cs42l43: Use new-style PM runtime macros ALSA: documentation: Add description for USB MIDI 2.0 gadget driver ALSA: ump: Don't create unused substreams for static blocks ALSA: ump: Fill group names for legacy rawmidi substreams ALSA: usb-audio: Attach legacy rawmidi after probing all UMP EPs ALSA: ac97: Fix possible error value of *rac97 ...
Diffstat (limited to 'sound/soc/intel/boards/sof_rt5682.c')
-rw-r--r--sound/soc/intel/boards/sof_rt5682.c172
1 files changed, 135 insertions, 37 deletions
diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c
index 7c034d671cf3..fae091b9b55c 100644
--- a/sound/soc/intel/boards/sof_rt5682.c
+++ b/sound/soc/intel/boards/sof_rt5682.c
@@ -22,6 +22,7 @@
#include <sound/soc-acpi.h>
#include "../../codecs/rt5682.h"
#include "../../codecs/rt5682s.h"
+#include "../../codecs/rt5645.h"
#include "../../codecs/hdac_hdmi.h"
#include "../common/soc-intel-quirks.h"
#include "hda_dsp_common.h"
@@ -58,9 +59,14 @@
#define SOF_SSP_BT_OFFLOAD_PRESENT BIT(22)
#define SOF_RT5682S_HEADPHONE_CODEC_PRESENT BIT(23)
#define SOF_MAX98390_SPEAKER_AMP_PRESENT BIT(24)
-#define SOF_MAX98390_TWEETER_SPEAKER_PRESENT BIT(25)
#define SOF_RT1019_SPEAKER_AMP_PRESENT BIT(26)
+#define SOF_RT5650_HEADPHONE_CODEC_PRESENT BIT(27)
+/* HDMI capture*/
+#define SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT 27
+#define SOF_SSP_HDMI_CAPTURE_PRESENT_MASK (GENMASK(30, 27))
+#define SOF_HDMI_CAPTURE_SSP_MASK(quirk) \
+ (((quirk) << SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT) & SOF_SSP_HDMI_CAPTURE_PRESENT_MASK)
/* Default: MCLK on, MCLK 19.2M, SSP0 */
static unsigned long sof_rt5682_quirk = SOF_RT5682_MCLK_EN |
@@ -197,23 +203,6 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = {
.callback = sof_rt5682_quirk_cb,
.matches = {
DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Brya"),
- DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98390_ALC5682I_I2S_4SPK"),
- },
- .driver_data = (void *)(SOF_RT5682_MCLK_EN |
- SOF_RT5682_SSP_CODEC(0) |
- SOF_SPEAKER_AMP_PRESENT |
- SOF_MAX98390_SPEAKER_AMP_PRESENT |
- SOF_MAX98390_TWEETER_SPEAKER_PRESENT |
- SOF_RT5682_SSP_AMP(1) |
- SOF_RT5682_NUM_HDMIDEV(4) |
- SOF_BT_OFFLOAD_SSP(2) |
- SOF_SSP_BT_OFFLOAD_PRESENT),
-
- },
- {
- .callback = sof_rt5682_quirk_cb,
- .matches = {
- DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Brya"),
DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98360_ALC5682I_I2S_AMP_SSP2"),
},
.driver_data = (void *)(SOF_RT5682_MCLK_EN |
@@ -305,6 +294,7 @@ static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd)
struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
struct snd_soc_jack *jack;
+ int extra_jack_data;
int ret;
/* need to enable ASRC function for 24MHz mclk rate */
@@ -315,7 +305,16 @@ static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd)
RT5682S_DA_STEREO1_FILTER |
RT5682S_AD_STEREO1_FILTER,
RT5682S_CLK_SEL_I2S1_ASRC);
- else
+ else if (sof_rt5682_quirk & SOF_RT5650_HEADPHONE_CODEC_PRESENT) {
+ rt5645_sel_asrc_clk_src(component,
+ RT5645_DA_STEREO_FILTER |
+ RT5645_AD_STEREO_FILTER,
+ RT5645_CLK_SEL_I2S1_ASRC);
+ rt5645_sel_asrc_clk_src(component,
+ RT5645_DA_MONO_L_FILTER |
+ RT5645_DA_MONO_R_FILTER,
+ RT5645_CLK_SEL_I2S2_ASRC);
+ } else
rt5682_sel_asrc_clk_src(component,
RT5682_DA_STEREO1_FILTER |
RT5682_AD_STEREO1_FILTER,
@@ -365,7 +364,12 @@ static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd)
snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
- ret = snd_soc_component_set_jack(component, jack, NULL);
+
+ if (sof_rt5682_quirk & SOF_RT5650_HEADPHONE_CODEC_PRESENT) {
+ extra_jack_data = SND_JACK_MICROPHONE | SND_JACK_BTN_0;
+ ret = snd_soc_component_set_jack(component, jack, &extra_jack_data);
+ } else
+ ret = snd_soc_component_set_jack(component, jack, NULL);
if (ret) {
dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
@@ -402,6 +406,8 @@ static int sof_rt5682_hw_params(struct snd_pcm_substream *substream,
if (sof_rt5682_quirk & SOF_RT5682S_HEADPHONE_CODEC_PRESENT)
pll_source = RT5682S_PLL_S_MCLK;
+ else if (sof_rt5682_quirk & SOF_RT5650_HEADPHONE_CODEC_PRESENT)
+ pll_source = RT5645_PLL1_S_MCLK;
else
pll_source = RT5682_PLL1_S_MCLK;
@@ -422,6 +428,8 @@ static int sof_rt5682_hw_params(struct snd_pcm_substream *substream,
} else {
if (sof_rt5682_quirk & SOF_RT5682S_HEADPHONE_CODEC_PRESENT)
pll_source = RT5682S_PLL_S_BCLK1;
+ else if (sof_rt5682_quirk & SOF_RT5650_HEADPHONE_CODEC_PRESENT)
+ pll_source = RT5645_PLL1_S_BCLK1;
else
pll_source = RT5682_PLL1_S_BCLK1;
@@ -431,6 +439,9 @@ static int sof_rt5682_hw_params(struct snd_pcm_substream *substream,
if (sof_rt5682_quirk & SOF_RT5682S_HEADPHONE_CODEC_PRESENT) {
pll_id = RT5682S_PLL2;
clk_id = RT5682S_SCLK_S_PLL2;
+ } else if (sof_rt5682_quirk & SOF_RT5650_HEADPHONE_CODEC_PRESENT) {
+ pll_id = 0; /* not used in codec driver */
+ clk_id = RT5645_SCLK_S_PLL1;
} else {
pll_id = RT5682_PLL1;
clk_id = RT5682_SCLK_S_PLL1;
@@ -559,11 +570,30 @@ static const struct snd_soc_dapm_route sof_map[] = {
{ "IN1P", NULL, "Headset Mic" },
};
+static const struct snd_soc_dapm_route rt5650_spk_dapm_routes[] = {
+ /* speaker */
+ { "Left Spk", NULL, "SPOL" },
+ { "Right Spk", NULL, "SPOR" },
+};
+
static const struct snd_soc_dapm_route dmic_map[] = {
/* digital mics */
{"DMic", NULL, "SoC DMIC"},
};
+static int rt5650_spk_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_card *card = rtd->card;
+ int ret;
+
+ ret = snd_soc_dapm_add_routes(&card->dapm, rt5650_spk_dapm_routes,
+ ARRAY_SIZE(rt5650_spk_dapm_routes));
+ if (ret)
+ dev_err(rtd->dev, "fail to add dapm routes, ret=%d\n", ret);
+
+ return ret;
+}
+
static int dmic_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_card *card = rtd->card;
@@ -614,6 +644,17 @@ static struct snd_soc_dai_link_component rt5682s_component[] = {
}
};
+static struct snd_soc_dai_link_component rt5650_components[] = {
+ {
+ .name = "i2c-10EC5650:00",
+ .dai_name = "rt5645-aif1",
+ },
+ {
+ .name = "i2c-10EC5650:00",
+ .dai_name = "rt5645-aif2",
+ }
+};
+
static struct snd_soc_dai_link_component dmic_component[] = {
{
.name = "dmic-codec",
@@ -634,6 +675,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
struct snd_soc_dai_link_component *cpus;
struct snd_soc_dai_link *links;
int i, id = 0;
+ int hdmi_id_offset = 0;
links = devm_kcalloc(dev, sof_audio_card_rt5682.num_links,
sizeof(struct snd_soc_dai_link), GFP_KERNEL);
@@ -652,6 +694,9 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
if (sof_rt5682_quirk & SOF_RT5682S_HEADPHONE_CODEC_PRESENT) {
links[id].codecs = rt5682s_component;
links[id].num_codecs = ARRAY_SIZE(rt5682s_component);
+ } else if (sof_rt5682_quirk & SOF_RT5650_HEADPHONE_CODEC_PRESENT) {
+ links[id].codecs = &rt5650_components[0];
+ links[id].num_codecs = 1;
} else {
links[id].codecs = rt5682_component;
links[id].num_codecs = ARRAY_SIZE(rt5682_component);
@@ -793,17 +838,12 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
sof_rt1011_dai_link(&links[id]);
} else if (sof_rt5682_quirk &
SOF_MAX98390_SPEAKER_AMP_PRESENT) {
- if (sof_rt5682_quirk &
- SOF_MAX98390_TWEETER_SPEAKER_PRESENT) {
- links[id].codecs = max_98390_4spk_components;
- links[id].num_codecs = ARRAY_SIZE(max_98390_4spk_components);
- } else {
- links[id].codecs = max_98390_components;
- links[id].num_codecs = ARRAY_SIZE(max_98390_components);
- }
- links[id].init = max_98390_spk_codec_init;
- links[id].ops = &max_98390_ops;
-
+ max_98390_dai_link(dev, &links[id]);
+ } else if (sof_rt5682_quirk & SOF_RT5650_HEADPHONE_CODEC_PRESENT) {
+ links[id].codecs = &rt5650_components[1];
+ links[id].num_codecs = 1;
+ links[id].init = rt5650_spk_init;
+ links[id].ops = &sof_rt5682_ops;
} else {
max_98357a_dai_link(&links[id]);
}
@@ -857,6 +897,34 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
links[id].num_cpus = 1;
}
+ /* HDMI-In SSP */
+ if (sof_rt5682_quirk & SOF_SSP_HDMI_CAPTURE_PRESENT_MASK) {
+ unsigned long hdmi_in_ssp = (sof_rt5682_quirk &
+ SOF_SSP_HDMI_CAPTURE_PRESENT_MASK) >>
+ SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT;
+ int port = 0;
+
+ for_each_set_bit(port, &hdmi_in_ssp, 32) {
+ links[id].cpus = &cpus[id];
+ links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
+ "SSP%d Pin", port);
+ if (!links[id].cpus->dai_name)
+ return NULL;
+ links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-HDMI", port);
+ if (!links[id].name)
+ return NULL;
+ links[id].id = id + hdmi_id_offset;
+ links[id].codecs = &asoc_dummy_dlc;
+ links[id].num_codecs = 1;
+ links[id].platforms = platform_component;
+ links[id].num_platforms = ARRAY_SIZE(platform_component);
+ links[id].dpcm_capture = 1;
+ links[id].no_pcm = 1;
+ links[id].num_cpus = 1;
+ id++;
+ }
+ }
+
return links;
devm_err:
return NULL;
@@ -890,6 +958,12 @@ static int sof_audio_probe(struct platform_device *pdev)
/* Detect the headset codec variant */
if (acpi_dev_present("RTL5682", NULL, -1))
sof_rt5682_quirk |= SOF_RT5682S_HEADPHONE_CODEC_PRESENT;
+ else if (acpi_dev_present("10EC5650", NULL, -1)) {
+ sof_rt5682_quirk |= SOF_RT5650_HEADPHONE_CODEC_PRESENT;
+
+ sof_audio_card_rt5682.name = devm_kstrdup(&pdev->dev, "rt5650",
+ GFP_KERNEL);
+ }
if (soc_intel_is_byt() || soc_intel_is_cht()) {
is_legacy_cpu = 1;
@@ -951,17 +1025,17 @@ static int sof_audio_probe(struct platform_device *pdev)
else if (sof_rt5682_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT)
sof_rt1015p_codec_conf(&sof_audio_card_rt5682);
else if (sof_rt5682_quirk & SOF_MAX98390_SPEAKER_AMP_PRESENT) {
- if (sof_rt5682_quirk & SOF_MAX98390_TWEETER_SPEAKER_PRESENT)
- max_98390_set_codec_conf(&sof_audio_card_rt5682,
- ARRAY_SIZE(max_98390_4spk_components));
- else
- max_98390_set_codec_conf(&sof_audio_card_rt5682,
- ARRAY_SIZE(max_98390_components));
+ max_98390_set_codec_conf(&pdev->dev, &sof_audio_card_rt5682);
}
if (sof_rt5682_quirk & SOF_SSP_BT_OFFLOAD_PRESENT)
sof_audio_card_rt5682.num_links++;
+ if (sof_rt5682_quirk & SOF_SSP_HDMI_CAPTURE_PRESENT_MASK)
+ sof_audio_card_rt5682.num_links +=
+ hweight32((sof_rt5682_quirk & SOF_SSP_HDMI_CAPTURE_PRESENT_MASK) >>
+ SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT);
+
dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp,
dmic_be_num, hdmi_num, ctx->idisp_codec);
if (!dai_links)
@@ -1129,6 +1203,22 @@ static const struct platform_device_id board_ids[] = {
SOF_SSP_BT_OFFLOAD_PRESENT),
},
{
+ .name = "adl_rt5682_c1_h02",
+ .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
+ SOF_RT5682_SSP_CODEC(1) |
+ SOF_RT5682_NUM_HDMIDEV(3) |
+ /* SSP 0 and SSP 2 are used for HDMI IN */
+ SOF_HDMI_CAPTURE_SSP_MASK(0x5)),
+ },
+ {
+ .name = "rpl_mx98357_rt5682",
+ .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
+ SOF_RT5682_SSP_CODEC(0) |
+ SOF_SPEAKER_AMP_PRESENT |
+ SOF_RT5682_SSP_AMP(2) |
+ SOF_RT5682_NUM_HDMIDEV(4)),
+ },
+ {
.name = "rpl_mx98360_rt5682",
.driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
SOF_RT5682_SSP_CODEC(0) |
@@ -1178,6 +1268,14 @@ static const struct platform_device_id board_ids[] = {
SOF_RT5682_SSP_AMP(0) |
SOF_RT5682_NUM_HDMIDEV(3)),
},
+ {
+ .name = "jsl_rt5650",
+ .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN |
+ SOF_RT5682_MCLK_24MHZ |
+ SOF_RT5682_SSP_CODEC(0) |
+ SOF_SPEAKER_AMP_PRESENT |
+ SOF_RT5682_SSP_AMP(1)),
+ },
{ }
};
MODULE_DEVICE_TABLE(platform, board_ids);