diff options
Diffstat (limited to 'sound/soc/intel/boards')
-rw-r--r-- | sound/soc/intel/boards/Kconfig | 1 | ||||
-rw-r--r-- | sound/soc/intel/boards/bxt_da7219_max98357a.c | 1 | ||||
-rw-r--r-- | sound/soc/intel/boards/bytcr_rt5640.c | 31 | ||||
-rw-r--r-- | sound/soc/intel/boards/bytcr_wm5102.c | 36 | ||||
-rw-r--r-- | sound/soc/intel/boards/cht_bsw_rt5672.c | 77 | ||||
-rw-r--r-- | sound/soc/intel/boards/kbl_da7219_max98357a.c | 58 | ||||
-rw-r--r-- | sound/soc/intel/boards/kbl_da7219_max98927.c | 10 | ||||
-rw-r--r-- | sound/soc/intel/boards/kbl_rt5663_max98927.c | 14 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_realtek_common.c | 105 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_realtek_common.h | 7 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_rt5682.c | 35 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_sdw.c | 11 | ||||
-rw-r--r-- | sound/soc/intel/boards/sof_wm8804.c | 6 |
13 files changed, 349 insertions, 43 deletions
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index d1d28129a32b..58379393b8e4 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -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 diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c index 0c0a717823c4..9ffef396f8f2 100644 --- a/sound/soc/intel/boards/bxt_da7219_max98357a.c +++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c @@ -813,6 +813,7 @@ static int broxton_audio_probe(struct platform_device *pdev) if (ctx->spkamp == SPKAMP_MAX98390) { broxton_dais[i].codecs = max98390_codec; broxton_dais[i].num_codecs = ARRAY_SIZE(max98390_codec); + broxton_dais[i].dpcm_capture = 1; } } /* DIALOG_CODEC is connected to SSP0 */ diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 5d48cc359c3d..df2f5d55e8ff 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -482,6 +482,9 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"), }, .driver_data = (void *)(BYT_RT5640_IN1_MAP | + BYT_RT5640_JD_SRC_JD2_IN4N | + BYT_RT5640_OVCD_TH_2000UA | + BYT_RT5640_OVCD_SF_0P75 | BYT_RT5640_MONO_SPEAKER | BYT_RT5640_DIFF_MIC | BYT_RT5640_SSP0_AIF2 | @@ -516,6 +519,23 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { BYT_RT5640_MCLK_EN), }, { + /* Chuwi Hi8 (CWI509) */ + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"), + DMI_MATCH(DMI_BOARD_NAME, "BYT-PA03C"), + DMI_MATCH(DMI_SYS_VENDOR, "ilife"), + DMI_MATCH(DMI_PRODUCT_NAME, "S806"), + }, + .driver_data = (void *)(BYT_RT5640_IN1_MAP | + BYT_RT5640_JD_SRC_JD2_IN4N | + BYT_RT5640_OVCD_TH_2000UA | + BYT_RT5640_OVCD_SF_0P75 | + BYT_RT5640_MONO_SPEAKER | + BYT_RT5640_DIFF_MIC | + BYT_RT5640_SSP0_AIF1 | + BYT_RT5640_MCLK_EN), + }, + { .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"), DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"), @@ -1252,6 +1272,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) int ret_val = 0; int dai_index = 0; int i, cfg_spk; + int aif; is_bytcr = false; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); @@ -1363,8 +1384,12 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) log_quirks(&pdev->dev); if ((byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) || - (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) + (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) { byt_rt5640_dais[dai_index].codecs->dai_name = "rt5640-aif2"; + aif = 2; + } else { + aif = 1; + } if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) || (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) @@ -1402,8 +1427,8 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) } snprintf(byt_rt5640_components, sizeof(byt_rt5640_components), - "cfg-spk:%d cfg-mic:%s", cfg_spk, - map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]); + "cfg-spk:%d cfg-mic:%s aif:%d", cfg_spk, + map_name[BYT_RT5640_MAP(byt_rt5640_quirk)], aif); byt_rt5640_card.components = byt_rt5640_components; #if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES) snprintf(byt_rt5640_long_name, sizeof(byt_rt5640_long_name), diff --git a/sound/soc/intel/boards/bytcr_wm5102.c b/sound/soc/intel/boards/bytcr_wm5102.c index f38850eb2eaf..8d8ab9be256f 100644 --- a/sound/soc/intel/boards/bytcr_wm5102.c +++ b/sound/soc/intel/boards/bytcr_wm5102.c @@ -18,6 +18,7 @@ #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/spi/spi.h> +#include <sound/jack.h> #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> @@ -31,6 +32,7 @@ #define WM5102_MAX_SYSCLK_11025 45158400 /* max sysclk for 11.025K family */ struct byt_wm5102_private { + struct snd_soc_jack jack; struct clk *mclk; struct gpio_desc *spkvdd_en_gpio; }; @@ -177,11 +179,23 @@ static const struct snd_kcontrol_new byt_wm5102_controls[] = { SOC_DAPM_PIN_SWITCH("Speaker"), }; +static struct snd_soc_jack_pin byt_wm5102_pins[] = { + { + .pin = "Headphone", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + static int byt_wm5102_init(struct snd_soc_pcm_runtime *runtime) { struct snd_soc_card *card = runtime->card; struct byt_wm5102_private *priv = snd_soc_card_get_drvdata(card); - int ret; + struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; + int ret, jack_type; card->dapm.idle_bias_off = true; @@ -210,17 +224,21 @@ static int byt_wm5102_init(struct snd_soc_pcm_runtime *runtime) return ret; } + jack_type = ARIZONA_JACK_MASK | SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3; + ret = snd_soc_card_jack_new(card, "Headset", jack_type, + &priv->jack, byt_wm5102_pins, + ARRAY_SIZE(byt_wm5102_pins)); + if (ret) { + dev_err(card->dev, "Error creating jack: %d\n", ret); + return ret; + } + + snd_soc_component_set_jack(component, &priv->jack, NULL); + return 0; } -static const struct snd_soc_pcm_stream byt_wm5102_dai_params = { - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .rate_min = 48000, - .rate_max = 48000, - .channels_min = 2, - .channels_max = 2, -}; - static int byt_wm5102_codec_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c index 10c88ef2f85d..e358632f50d7 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5672.c +++ b/sound/soc/intel/boards/cht_bsw_rt5672.c @@ -21,6 +21,7 @@ #include <sound/soc-acpi.h> #include "../../codecs/rt5670.h" #include "../atom/sst-atom-controls.h" +#include "../common/soc-intel-quirks.h" /* The platform clock #3 outputs 19.2Mhz clock to codec as I2S MCLK */ @@ -31,6 +32,7 @@ struct cht_mc_private { struct snd_soc_jack headset; char codec_name[SND_ACPI_I2C_ID_LEN]; struct clk *mclk; + bool use_ssp0; }; /* Headset jack detection DAPM pins */ @@ -121,16 +123,26 @@ static const struct snd_soc_dapm_route cht_audio_map[] = { {"Ext Spk", NULL, "SPOLN"}, {"Ext Spk", NULL, "SPORP"}, {"Ext Spk", NULL, "SPORN"}, + {"Headphone", NULL, "Platform Clock"}, + {"Headset Mic", NULL, "Platform Clock"}, + {"Int Mic", NULL, "Platform Clock"}, + {"Ext Spk", NULL, "Platform Clock"}, +}; + +static const struct snd_soc_dapm_route cht_audio_ssp0_map[] = { + {"AIF1 Playback", NULL, "ssp0 Tx"}, + {"ssp0 Tx", NULL, "modem_out"}, + {"modem_in", NULL, "ssp0 Rx"}, + {"ssp0 Rx", NULL, "AIF1 Capture"}, +}; + +static const struct snd_soc_dapm_route cht_audio_ssp2_map[] = { {"AIF1 Playback", NULL, "ssp2 Tx"}, {"ssp2 Tx", NULL, "codec_out0"}, {"ssp2 Tx", NULL, "codec_out1"}, {"codec_in0", NULL, "ssp2 Rx"}, {"codec_in1", NULL, "ssp2 Rx"}, {"ssp2 Rx", NULL, "AIF1 Capture"}, - {"Headphone", NULL, "Platform Clock"}, - {"Headset Mic", NULL, "Platform Clock"}, - {"Int Mic", NULL, "Platform Clock"}, - {"Ext Spk", NULL, "Platform Clock"}, }; static const struct snd_kcontrol_new cht_mc_controls[] = { @@ -197,6 +209,18 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) | RT5670_AD_MONO_R_FILTER, RT5670_CLK_SEL_I2S1_ASRC); + if (ctx->use_ssp0) { + ret = snd_soc_dapm_add_routes(&runtime->card->dapm, + cht_audio_ssp0_map, + ARRAY_SIZE(cht_audio_ssp0_map)); + } else { + ret = snd_soc_dapm_add_routes(&runtime->card->dapm, + cht_audio_ssp2_map, + ARRAY_SIZE(cht_audio_ssp2_map)); + } + if (ret) + return ret; + ret = snd_soc_card_jack_new(runtime->card, "Headset", SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2, @@ -239,18 +263,26 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { + struct cht_mc_private *ctx = snd_soc_card_get_drvdata(rtd->card); struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); - int ret; + int ret, bits; /* The DSP will covert the FE rate to 48k, stereo, 24bits */ rate->min = rate->max = 48000; channels->min = channels->max = 2; - /* set SSP2 to 24-bit */ - params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); + if (ctx->use_ssp0) { + /* set SSP0 to 16-bit */ + params_set_format(params, SNDRV_PCM_FORMAT_S16_LE); + bits = 16; + } else { + /* set SSP2 to 24-bit */ + params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); + bits = 24; + } /* * The default mode for the cpu-dai is TDM 4 slot. The default mode @@ -274,6 +306,12 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } + ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits); + if (ret < 0) { + dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); + return ret; + } + return 0; } @@ -414,6 +452,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev) const char *platform_name; struct acpi_device *adev; bool sof_parent; + int dai_index = 0; int i; drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL); @@ -422,19 +461,27 @@ static int snd_cht_mc_probe(struct platform_device *pdev) strcpy(drv->codec_name, RT5672_I2C_DEFAULT); + /* find index of codec dai */ + for (i = 0; i < ARRAY_SIZE(cht_dailink); i++) { + if (!strcmp(cht_dailink[i].codecs->name, RT5672_I2C_DEFAULT)) { + dai_index = i; + break; + } + } + /* fixup codec name based on HID */ adev = acpi_dev_get_first_match_dev(mach->id, NULL, -1); if (adev) { snprintf(drv->codec_name, sizeof(drv->codec_name), "i2c-%s", acpi_dev_name(adev)); put_device(&adev->dev); - for (i = 0; i < ARRAY_SIZE(cht_dailink); i++) { - if (!strcmp(cht_dailink[i].codecs->name, - RT5672_I2C_DEFAULT)) { - cht_dailink[i].codecs->name = drv->codec_name; - break; - } - } + cht_dailink[dai_index].codecs->name = drv->codec_name; + } + + /* Use SSP0 on Bay Trail CR devices */ + if (soc_intel_is_byt() && mach->mach_params.acpi_ipc_irq_index == 0) { + cht_dailink[dai_index].cpus->dai_name = "ssp0-port"; + drv->use_ssp0 = true; } /* override plaform name, if required */ @@ -446,6 +493,8 @@ static int snd_cht_mc_probe(struct platform_device *pdev) if (ret_val) return ret_val; + snd_soc_card_cht.components = rt5670_components(); + drv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); if (IS_ERR(drv->mclk)) { dev_err(&pdev->dev, diff --git a/sound/soc/intel/boards/kbl_da7219_max98357a.c b/sound/soc/intel/boards/kbl_da7219_max98357a.c index dc3d897ad280..c0d8a73c6d21 100644 --- a/sound/soc/intel/boards/kbl_da7219_max98357a.c +++ b/sound/soc/intel/boards/kbl_da7219_max98357a.c @@ -44,6 +44,7 @@ struct kbl_codec_private { enum { KBL_DPCM_AUDIO_PB = 0, KBL_DPCM_AUDIO_CP, + KBL_DPCM_AUDIO_REF_CP, KBL_DPCM_AUDIO_DMIC_CP, KBL_DPCM_AUDIO_HDMI1_PB, KBL_DPCM_AUDIO_HDMI2_PB, @@ -90,8 +91,9 @@ static const struct snd_soc_dapm_widget kabylake_widgets[] = { SND_SOC_DAPM_MIC("Headset Mic", NULL), SND_SOC_DAPM_SPK("Spk", NULL), SND_SOC_DAPM_MIC("SoC DMIC", NULL), - SND_SOC_DAPM_SPK("DP", NULL), - SND_SOC_DAPM_SPK("HDMI", NULL), + SND_SOC_DAPM_SPK("HDMI1", NULL), + SND_SOC_DAPM_SPK("HDMI2", NULL), + SND_SOC_DAPM_SPK("HDMI3", NULL), SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, platform_clock_control, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), @@ -108,8 +110,9 @@ static const struct snd_soc_dapm_route kabylake_map[] = { { "MIC", NULL, "Headset Mic" }, { "DMic", NULL, "SoC DMIC" }, - { "HDMI", NULL, "hif5 Output" }, - { "DP", NULL, "hif6 Output" }, + {"HDMI1", NULL, "hif5-0 Output"}, + {"HDMI2", NULL, "hif6-0 Output"}, + {"HDMI3", NULL, "hif7-0 Output"}, /* CODEC BE connections */ { "HiFi Playback", NULL, "ssp0 Tx" }, @@ -336,12 +339,49 @@ static struct snd_soc_ops kabylake_dmic_ops = { .startup = kabylake_dmic_startup, }; +static unsigned int rates_16000[] = { + 16000, +}; + +static const struct snd_pcm_hw_constraint_list constraints_16000 = { + .count = ARRAY_SIZE(rates_16000), + .list = rates_16000, +}; + +static const unsigned int ch_mono[] = { + 1, +}; + +static const struct snd_pcm_hw_constraint_list constraints_refcap = { + .count = ARRAY_SIZE(ch_mono), + .list = ch_mono, +}; + +static int kabylake_refcap_startup(struct snd_pcm_substream *substream) +{ + substream->runtime->hw.channels_max = 1; + snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_CHANNELS, + &constraints_refcap); + + return snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_16000); +} + +static struct snd_soc_ops skylake_refcap_ops = { + .startup = kabylake_refcap_startup, +}; + SND_SOC_DAILINK_DEF(dummy, DAILINK_COMP_ARRAY(COMP_DUMMY())); SND_SOC_DAILINK_DEF(system, DAILINK_COMP_ARRAY(COMP_CPU("System Pin"))); +SND_SOC_DAILINK_DEF(reference, + DAILINK_COMP_ARRAY(COMP_CPU("Reference Pin"))); + SND_SOC_DAILINK_DEF(dmic, DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin"))); @@ -416,6 +456,16 @@ static struct snd_soc_dai_link kabylake_dais[] = { .ops = &kabylake_da7219_fe_ops, SND_SOC_DAILINK_REG(system, dummy, platform), }, + [KBL_DPCM_AUDIO_REF_CP] = { + .name = "Kbl Audio Reference cap", + .stream_name = "Wake on Voice", + .init = NULL, + .dpcm_capture = 1, + .nonatomic = 1, + .dynamic = 1, + .ops = &skylake_refcap_ops, + SND_SOC_DAILINK_REG(reference, dummy, platform), + }, [KBL_DPCM_AUDIO_DMIC_CP] = { .name = "Kbl Audio DMIC cap", .stream_name = "dmiccap", diff --git a/sound/soc/intel/boards/kbl_da7219_max98927.c b/sound/soc/intel/boards/kbl_da7219_max98927.c index e0149cf6127d..4b7b4a044f81 100644 --- a/sound/soc/intel/boards/kbl_da7219_max98927.c +++ b/sound/soc/intel/boards/kbl_da7219_max98927.c @@ -111,8 +111,9 @@ static const struct snd_soc_dapm_widget kabylake_widgets[] = { SND_SOC_DAPM_SPK("Left Spk", NULL), SND_SOC_DAPM_SPK("Right Spk", NULL), SND_SOC_DAPM_MIC("SoC DMIC", NULL), - SND_SOC_DAPM_SPK("DP", NULL), - SND_SOC_DAPM_SPK("HDMI", NULL), + SND_SOC_DAPM_SPK("HDMI1", NULL), + SND_SOC_DAPM_SPK("HDMI2", NULL), + SND_SOC_DAPM_SPK("HDMI3", NULL), SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, platform_clock_control, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), @@ -126,8 +127,9 @@ static const struct snd_soc_dapm_route kabylake_map[] = { /* other jacks */ { "DMic", NULL, "SoC DMIC" }, - { "HDMI", NULL, "hif5 Output" }, - { "DP", NULL, "hif6 Output" }, + {"HDMI1", NULL, "hif5-0 Output"}, + {"HDMI2", NULL, "hif6-0 Output"}, + {"HDMI3", NULL, "hif7-0 Output"}, /* CODEC BE connections */ { "Left HiFi Playback", NULL, "ssp0 Tx" }, diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c b/sound/soc/intel/boards/kbl_rt5663_max98927.c index 9a4b3d0973f6..a3de55a3b58d 100644 --- a/sound/soc/intel/boards/kbl_rt5663_max98927.c +++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c @@ -151,6 +151,10 @@ static const struct snd_soc_dapm_route kabylake_map[] = { { "IN1N", NULL, "Headset Mic" }, { "DMic", NULL, "SoC DMIC" }, + {"HDMI1", NULL, "hif5-0 Output"}, + {"HDMI2", NULL, "hif6-0 Output"}, + {"HDMI3", NULL, "hif7-0 Output"}, + /* CODEC BE connections */ { "Left HiFi Playback", NULL, "ssp0 Tx" }, { "Right HiFi Playback", NULL, "ssp0 Tx" }, @@ -194,8 +198,9 @@ static const struct snd_kcontrol_new kabylake_5663_controls[] = { static const struct snd_soc_dapm_widget kabylake_5663_widgets[] = { SND_SOC_DAPM_HP("Headphone Jack", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_SPK("DP", NULL), - SND_SOC_DAPM_SPK("HDMI", NULL), + SND_SOC_DAPM_SPK("HDMI1", NULL), + SND_SOC_DAPM_SPK("HDMI2", NULL), + SND_SOC_DAPM_SPK("HDMI3", NULL), SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, platform_clock_control, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), @@ -211,8 +216,9 @@ static const struct snd_soc_dapm_route kabylake_5663_map[] = { { "IN1P", NULL, "Headset Mic" }, { "IN1N", NULL, "Headset Mic" }, - { "HDMI", NULL, "hif5 Output" }, - { "DP", NULL, "hif6 Output" }, + {"HDMI1", NULL, "hif5-0 Output"}, + {"HDMI2", NULL, "hif6-0 Output"}, + {"HDMI3", NULL, "hif7-0 Output"}, /* CODEC BE connections */ { "AIF Playback", NULL, "ssp1 Tx" }, diff --git a/sound/soc/intel/boards/sof_realtek_common.c b/sound/soc/intel/boards/sof_realtek_common.c index f3cf73c620ba..2ec34f8df9e1 100644 --- a/sound/soc/intel/boards/sof_realtek_common.c +++ b/sound/soc/intel/boards/sof_realtek_common.c @@ -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); +} diff --git a/sound/soc/intel/boards/sof_realtek_common.h b/sound/soc/intel/boards/sof_realtek_common.h index 87cb3812b926..cb0b49b2855c 100644 --- a/sound/soc/intel/boards/sof_realtek_common.h +++ b/sound/soc/intel/boards/sof_realtek_common.h @@ -21,4 +21,11 @@ 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 */ diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index 55505e207bc0..58548ea0d915 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -16,6 +16,7 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> +#include <sound/sof.h> #include <sound/rt5682.h> #include <sound/soc-acpi.h> #include "../../codecs/rt1015.h" @@ -45,8 +46,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 | @@ -267,10 +269,21 @@ static int sof_rt5682_hw_params(struct snd_pcm_substream *substream, } clk_id = RT5682_PLL1_S_MCLK; - if (sof_rt5682_quirk & SOF_RT5682_MCLK_24MHZ) + + /* get the tplg configured mclk. */ + clk_freq = sof_dai_get_mclk(rtd); + + /* mclk from the quirk is the first choice */ + if (sof_rt5682_quirk & SOF_RT5682_MCLK_24MHZ) { + if (clk_freq != 24000000) + dev_warn(rtd->dev, "configure wrong mclk in tplg, please use 24MHz.\n"); clk_freq = 24000000; - else + } else if (clk_freq == 0) { + /* use default mclk if not specified correct in topology */ clk_freq = 19200000; + } else if (clk_freq < 0) { + return clk_freq; + } } else { clk_id = RT5682_PLL1_S_BCLK1; clk_freq = params_rate(params) * 50; @@ -723,6 +736,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 +866,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 +957,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 +992,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"); diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 8adce6417b02..ecd3f90f4bbe 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -187,6 +187,17 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { SOF_RT715_DAI_ID_FIX | SOF_SDW_FOUR_SPK), }, + /* AlderLake devices */ + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "Alder Lake Client Platform"), + }, + .driver_data = (void *)(SOF_RT711_JD_SRC_JD1 | + SOF_SDW_TGL_HDMI | + SOF_SDW_PCH_DMIC), + }, {} }; diff --git a/sound/soc/intel/boards/sof_wm8804.c b/sound/soc/intel/boards/sof_wm8804.c index a46ba13e8eb0..6a181e45143d 100644 --- a/sound/soc/intel/boards/sof_wm8804.c +++ b/sound/soc/intel/boards/sof_wm8804.c @@ -124,7 +124,11 @@ static int sof_wm8804_hw_params(struct snd_pcm_substream *substream, } snd_soc_dai_set_clkdiv(codec_dai, WM8804_MCLK_DIV, mclk_div); - snd_soc_dai_set_pll(codec_dai, 0, 0, sysclk, mclk_freq); + ret = snd_soc_dai_set_pll(codec_dai, 0, 0, sysclk, mclk_freq); + if (ret < 0) { + dev_err(rtd->card->dev, "Failed to set WM8804 PLL\n"); + return ret; + } ret = snd_soc_dai_set_sysclk(codec_dai, WM8804_TX_CLKSRC_PLL, sysclk, SND_SOC_CLOCK_OUT); |