diff options
Diffstat (limited to 'sound/soc/intel/boards')
30 files changed, 775 insertions, 70 deletions
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index aa12d7e3dd2f..a472de1909f4 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -668,6 +668,7 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH select SND_SOC_RT1308_SDW select SND_SOC_RT1308 select SND_SOC_RT1316_SDW + select SND_SOC_RT1318_SDW select SND_SOC_RT715_SDW select SND_SOC_RT715_SDCA_SDW select SND_SOC_RT5682_SDW diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile index 53458e748191..7e1a4ff77ac3 100644 --- a/sound/soc/intel/boards/Makefile +++ b/sound/soc/intel/boards/Makefile @@ -37,8 +37,8 @@ snd-soc-sof_da7219_max98373-objs := sof_da7219_max98373.o snd-soc-ehl-rt5660-objs := ehl_rt5660.o snd-soc-sof-ssp-amp-objs := sof_ssp_amp.o snd-soc-sof-sdw-objs += sof_sdw.o \ - sof_sdw_max98373.o \ - sof_sdw_rt1308.o sof_sdw_rt1316.o \ + sof_sdw_max98373.o sof_sdw_rt1308.o \ + sof_sdw_rt1316.o sof_sdw_rt1318.o \ sof_sdw_rt5682.o sof_sdw_rt700.o \ sof_sdw_rt711.o sof_sdw_rt711_sdca.o \ sof_sdw_rt715.o sof_sdw_rt715_sdca.o \ diff --git a/sound/soc/intel/boards/bdw-rt5650.c b/sound/soc/intel/boards/bdw-rt5650.c index 67c3f49b924c..d0682bc543c9 100644 --- a/sound/soc/intel/boards/bdw-rt5650.c +++ b/sound/soc/intel/boards/bdw-rt5650.c @@ -88,7 +88,7 @@ static int broadwell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_interval *chan = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); - /* The ADSP will covert the FE rate to 48k, max 4-channels */ + /* The ADSP will convert the FE rate to 48k, max 4-channels */ rate->min = rate->max = 48000; chan->min = 2; chan->max = 4; diff --git a/sound/soc/intel/boards/bdw-rt5677.c b/sound/soc/intel/boards/bdw-rt5677.c index 31488702768e..f3e08d258ac1 100644 --- a/sound/soc/intel/boards/bdw-rt5677.c +++ b/sound/soc/intel/boards/bdw-rt5677.c @@ -141,7 +141,7 @@ static int broadwell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_interval *chan = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); - /* The ADSP will covert the FE rate to 48k, stereo */ + /* The ADSP will convert the FE rate to 48k, stereo */ rate->min = rate->max = 48000; chan->min = chan->max = 2; diff --git a/sound/soc/intel/boards/bdw_rt286.c b/sound/soc/intel/boards/bdw_rt286.c index 6b76df0e7c9b..b7687a93a923 100644 --- a/sound/soc/intel/boards/bdw_rt286.c +++ b/sound/soc/intel/boards/bdw_rt286.c @@ -73,6 +73,13 @@ static int codec_link_init(struct snd_soc_pcm_runtime *rtd) return snd_soc_component_set_jack(codec, &card_headset, NULL); } +static void codec_link_exit(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_component *codec = asoc_rtd_to_codec(rtd, 0)->component; + + snd_soc_component_set_jack(codec, NULL, NULL); +} + static int codec_link_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { @@ -165,6 +172,7 @@ static struct snd_soc_dai_link card_dai_links[] = { .nonatomic = 1, .no_pcm = 1, .init = codec_link_init, + .exit = codec_link_exit, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC, .ignore_pmdown_time = 1, .be_hw_params_fixup = codec_link_hw_params_fixup, @@ -175,43 +183,24 @@ static struct snd_soc_dai_link card_dai_links[] = { }, }; -static void bdw_rt286_disable_jack(struct snd_soc_card *card) -{ - struct snd_soc_component *component; - - for_each_card_components(card, component) { - if (!strcmp(component->name, "i2c-INT343A:00")) { - dev_dbg(component->dev, "disabling jack detect before going to suspend.\n"); - snd_soc_component_set_jack(component, NULL, NULL); - break; - } - } -} - -static int bdw_rt286_suspend(struct snd_soc_card *card) +static int card_suspend_pre(struct snd_soc_card *card) { - bdw_rt286_disable_jack(card); + struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, "rt286-aif1"); - return 0; + return snd_soc_component_set_jack(codec_dai->component, NULL, NULL); } -static int bdw_rt286_resume(struct snd_soc_card *card) +static int card_resume_post(struct snd_soc_card *card) { - struct snd_soc_component *component; - - for_each_card_components(card, component) { - if (!strcmp(component->name, "i2c-INT343A:00")) { - dev_dbg(component->dev, "enabling jack detect for resume.\n"); - snd_soc_component_set_jack(component, &card_headset, NULL); - break; - } - } + struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, "rt286-aif1"); - return 0; + return snd_soc_component_set_jack(codec_dai->component, &card_headset, NULL); } static struct snd_soc_card bdw_rt286_card = { .owner = THIS_MODULE, + .suspend_pre = card_suspend_pre, + .resume_post = card_resume_post, .dai_link = card_dai_links, .num_links = ARRAY_SIZE(card_dai_links), .controls = card_controls, @@ -221,8 +210,6 @@ static struct snd_soc_card bdw_rt286_card = { .dapm_routes = card_routes, .num_dapm_routes = ARRAY_SIZE(card_routes), .fully_routed = true, - .suspend_pre = bdw_rt286_suspend, - .resume_post = bdw_rt286_resume, }; /* Use space before codec name to simplify card ID, and simplify driver name. */ @@ -254,18 +241,8 @@ static int bdw_rt286_probe(struct platform_device *pdev) return devm_snd_soc_register_card(dev, &bdw_rt286_card); } -static int bdw_rt286_remove(struct platform_device *pdev) -{ - struct snd_soc_card *card = platform_get_drvdata(pdev); - - bdw_rt286_disable_jack(card); - - return 0; -} - static struct platform_driver bdw_rt286_driver = { .probe = bdw_rt286_probe, - .remove = bdw_rt286_remove, .driver = { .name = "bdw_rt286", .pm = &snd_soc_pm_ops diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c index 7c6c95e99ade..c593995facaa 100644 --- a/sound/soc/intel/boards/bxt_da7219_max98357a.c +++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c @@ -19,7 +19,6 @@ #include <sound/soc-acpi.h> #include "../../codecs/hdac_hdmi.h" #include "../../codecs/da7219.h" -#include "../../codecs/da7219-aad.h" #include "../common/soc-intel-quirks.h" #include "hda_dsp_common.h" @@ -259,7 +258,7 @@ static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); - da7219_aad_jack_det(component, &broxton_headset); + snd_soc_component_set_jack(component, &broxton_headset, NULL); snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c index 4bd93c3ba377..bf89fe80423d 100644 --- a/sound/soc/intel/boards/bxt_rt298.c +++ b/sound/soc/intel/boards/bxt_rt298.c @@ -210,7 +210,7 @@ static int broxton_ssp5_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_CHANNELS); struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - /* The ADSP will covert the FE rate to 48k, stereo */ + /* The ADSP will convert the FE rate to 48k, stereo */ rate->min = rate->max = 48000; chan->min = chan->max = 2; diff --git a/sound/soc/intel/boards/bytcht_cx2072x.c b/sound/soc/intel/boards/bytcht_cx2072x.c index ae899866863e..41cec67157b6 100644 --- a/sound/soc/intel/boards/bytcht_cx2072x.c +++ b/sound/soc/intel/boards/bytcht_cx2072x.c @@ -111,7 +111,7 @@ static int byt_cht_cx2072x_fixup(struct snd_soc_pcm_runtime *rtd, hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); int ret; - /* The DSP will covert the FE rate to 48k, stereo, 24bits */ + /* The DSP will convert the FE rate to 48k, stereo, 24bits */ rate->min = rate->max = 48000; channels->min = channels->max = 2; diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c index a935c5fd9edb..09d1f0f6d686 100644 --- a/sound/soc/intel/boards/bytcht_es8316.c +++ b/sound/soc/intel/boards/bytcht_es8316.c @@ -243,7 +243,7 @@ static int byt_cht_es8316_codec_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_CHANNELS); int ret, bits; - /* The DSP will covert the FE rate to 48k, stereo */ + /* The DSP will convert the FE rate to 48k, stereo */ rate->min = rate->max = 48000; channels->min = channels->max = 2; diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index fb9d9e271845..6db07b2417ca 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -1390,7 +1390,7 @@ static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_CHANNELS); int ret, bits; - /* The DSP will covert the FE rate to 48k, stereo */ + /* The DSP will convert the FE rate to 48k, stereo */ rate->min = rate->max = 48000; channels->min = channels->max = 2; diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index 2beb686768f2..81ac6eeda2e6 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -683,7 +683,7 @@ static int byt_rt5651_codec_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_CHANNELS); int ret, bits; - /* The DSP will covert the FE rate to 48k, stereo */ + /* The DSP will convert the FE rate to 48k, stereo */ rate->min = rate->max = 48000; channels->min = channels->max = 2; diff --git a/sound/soc/intel/boards/bytcr_wm5102.c b/sound/soc/intel/boards/bytcr_wm5102.c index 45a6805787f5..1669eb3bd80f 100644 --- a/sound/soc/intel/boards/bytcr_wm5102.c +++ b/sound/soc/intel/boards/bytcr_wm5102.c @@ -248,7 +248,7 @@ static int byt_wm5102_codec_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_CHANNELS); int ret; - /* The DSP will covert the FE rate to 48k, stereo */ + /* The DSP will convert the FE rate to 48k, stereo */ rate->min = 48000; rate->max = 48000; channels->min = 2; diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c index 64eb73525ee3..2c086e901aae 100644 --- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c +++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c @@ -272,7 +272,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } - /* The DSP will covert the FE rate to 48k, stereo, 24bits */ + /* The DSP will convert the FE rate to 48k, stereo, 24bits */ rate->min = rate->max = 48000; channels->min = channels->max = 2; diff --git a/sound/soc/intel/boards/cht_bsw_nau8824.c b/sound/soc/intel/boards/cht_bsw_nau8824.c index 4c1d83b317c7..af2d9a78465d 100644 --- a/sound/soc/intel/boards/cht_bsw_nau8824.c +++ b/sound/soc/intel/boards/cht_bsw_nau8824.c @@ -136,7 +136,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); int ret; - /* The DSP will covert the FE rate to 48k, stereo, 24bits */ + /* The DSP will convert the FE rate to 48k, stereo, 24bits */ rate->min = rate->max = 48000; channels->min = channels->max = 2; diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c index 96501aed8bee..25a054bd4073 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5645.c +++ b/sound/soc/intel/boards/cht_bsw_rt5645.c @@ -344,7 +344,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); - /* The DSP will covert the FE rate to 48k, stereo, 24bits */ + /* The DSP will convert the FE rate to 48k, stereo, 24bits */ rate->min = rate->max = 48000; channels->min = channels->max = 2; diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c index ca47f6476b07..49d3da8f7316 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5672.c +++ b/sound/soc/intel/boards/cht_bsw_rt5672.c @@ -270,7 +270,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_CHANNELS); int ret, bits; - /* The DSP will covert the FE rate to 48k, stereo, 24bits */ + /* The DSP will convert the FE rate to 48k, stereo, 24bits */ rate->min = rate->max = 48000; channels->min = channels->max = 2; diff --git a/sound/soc/intel/boards/kbl_da7219_max98357a.c b/sound/soc/intel/boards/kbl_da7219_max98357a.c index 329457e3e3a2..18365ce6bcba 100644 --- a/sound/soc/intel/boards/kbl_da7219_max98357a.c +++ b/sound/soc/intel/boards/kbl_da7219_max98357a.c @@ -19,7 +19,6 @@ #include <sound/soc.h> #include "../../codecs/da7219.h" #include "../../codecs/hdac_hdmi.h" -#include "../../codecs/da7219-aad.h" #define KBL_DIALOG_CODEC_DAI "da7219-hifi" #define KBL_MAXIM_CODEC_DAI "HiFi" @@ -207,7 +206,7 @@ static int kabylake_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP); snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); - da7219_aad_jack_det(component, &ctx->kabylake_headset); + snd_soc_component_set_jack(component, &ctx->kabylake_headset, NULL); ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); if (ret) diff --git a/sound/soc/intel/boards/kbl_da7219_max98927.c b/sound/soc/intel/boards/kbl_da7219_max98927.c index 362579f25835..ad4223fee0c5 100644 --- a/sound/soc/intel/boards/kbl_da7219_max98927.c +++ b/sound/soc/intel/boards/kbl_da7219_max98927.c @@ -19,7 +19,6 @@ #include <sound/soc.h> #include "../../codecs/da7219.h" #include "../../codecs/hdac_hdmi.h" -#include "../../codecs/da7219-aad.h" #define KBL_DIALOG_CODEC_DAI "da7219-hifi" #define MAX98927_CODEC_DAI "max98927-aif1" @@ -382,7 +381,7 @@ static int kabylake_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); - da7219_aad_jack_det(component, &ctx->kabylake_headset); + snd_soc_component_set_jack(component, &ctx->kabylake_headset, NULL); return 0; } diff --git a/sound/soc/intel/boards/skl_nau88l25_max98357a.c b/sound/soc/intel/boards/skl_nau88l25_max98357a.c index 8dceb0b02581..e13a5a4d8f7e 100644 --- a/sound/soc/intel/boards/skl_nau88l25_max98357a.c +++ b/sound/soc/intel/boards/skl_nau88l25_max98357a.c @@ -154,7 +154,7 @@ static int skylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_CHANNELS); struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - /* The ADSP will covert the FE rate to 48k, stereo */ + /* The ADSP will convert the FE rate to 48k, stereo */ rate->min = rate->max = 48000; chan->min = chan->max = 2; diff --git a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c index 62c0d46d0086..575604dc8936 100644 --- a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c +++ b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c @@ -333,7 +333,7 @@ static int skylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_CHANNELS); struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - /* The ADSP will covert the FE rate to 48k, stereo */ + /* The ADSP will convert the FE rate to 48k, stereo */ rate->min = rate->max = 48000; chan->min = chan->max = 2; diff --git a/sound/soc/intel/boards/sof_cirrus_common.c b/sound/soc/intel/boards/sof_cirrus_common.c index 6e39eda77385..851c516c8f5b 100644 --- a/sound/soc/intel/boards/sof_cirrus_common.c +++ b/sound/soc/intel/boards/sof_cirrus_common.c @@ -155,7 +155,7 @@ static const char * const cs35l41_name_prefixes[] = { "WL", "WR", "TL", "TR" }; */ static int cs35l41_compute_codec_conf(void) { - const char * const uid_strings[] = { "0", "1", "2", "3" }; + static const char * const uid_strings[] = { "0", "1", "2", "3" }; unsigned int uid, sz = 0; struct acpi_device *adev; struct device *physdev; diff --git a/sound/soc/intel/boards/sof_da7219_max98373.c b/sound/soc/intel/boards/sof_da7219_max98373.c index e048e789e633..740aa11cb019 100644 --- a/sound/soc/intel/boards/sof_da7219_max98373.c +++ b/sound/soc/intel/boards/sof_da7219_max98373.c @@ -7,13 +7,13 @@ #include <linux/input.h> #include <linux/module.h> +#include <sound/jack.h> #include <sound/pcm.h> #include <sound/pcm_params.h> #include <linux/platform_device.h> #include <sound/soc.h> #include <sound/soc-acpi.h> #include "../../codecs/da7219.h" -#include "../../codecs/da7219-aad.h" #include "hda_dsp_common.h" #define DIALOG_CODEC_DAI "da7219-hifi" @@ -184,7 +184,7 @@ static int da7219_codec_init(struct snd_soc_pcm_runtime *rtd) snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP); snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); - da7219_aad_jack_det(component, jack); + snd_soc_component_set_jack(component, jack, NULL); return ret; } diff --git a/sound/soc/intel/boards/sof_nau8825.c b/sound/soc/intel/boards/sof_nau8825.c index 5585c217f78d..27880224359d 100644 --- a/sound/soc/intel/boards/sof_nau8825.c +++ b/sound/soc/intel/boards/sof_nau8825.c @@ -47,6 +47,7 @@ #define SOF_RT1019P_SPEAKER_AMP_PRESENT BIT(14) #define SOF_MAX98373_SPEAKER_AMP_PRESENT BIT(15) #define SOF_MAX98360A_SPEAKER_AMP_PRESENT BIT(16) +#define SOF_RT1015P_SPEAKER_AMP_PRESENT BIT(17) static unsigned long sof_nau8825_quirk = SOF_NAU8825_SSP_CODEC(0); @@ -483,6 +484,8 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, } else if (sof_nau8825_quirk & SOF_MAX98360A_SPEAKER_AMP_PRESENT) { max_98360a_dai_link(&links[id]); + } else if (sof_nau8825_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) { + sof_rt1015p_dai_link(&links[id]); } else { goto devm_err; } @@ -576,6 +579,8 @@ static int sof_audio_probe(struct platform_device *pdev) if (sof_nau8825_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) max_98373_set_codec_conf(&sof_audio_card_nau8825); + else if (sof_nau8825_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) + sof_rt1015p_codec_conf(&sof_audio_card_nau8825); if (sof_nau8825_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) sof_audio_card_nau8825.num_links++; @@ -642,6 +647,16 @@ static const struct platform_device_id board_ids[] = { SOF_SSP_BT_OFFLOAD_PRESENT), }, + { + .name = "adl_rt1015p_nau8825", + .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | + SOF_SPEAKER_AMP_PRESENT | + SOF_RT1015P_SPEAKER_AMP_PRESENT | + SOF_NAU8825_SSP_AMP(1) | + SOF_NAU8825_NUM_HDMIDEV(4) | + SOF_BT_OFFLOAD_SSP(2) | + SOF_SSP_BT_OFFLOAD_PRESENT), + }, { } }; MODULE_DEVICE_TABLE(platform, board_ids); @@ -663,3 +678,4 @@ MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>"); MODULE_LICENSE("GPL"); MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON); +MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON); diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index 2358be208c1f..4a2f91249b10 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -867,10 +867,6 @@ static int sof_audio_probe(struct platform_device *pdev) if (acpi_dev_present("RTL5682", NULL, -1)) sof_rt5682_quirk |= SOF_RT5682S_HEADPHONE_CODEC_PRESENT; - /* Detect the headset codec variant to support machines in DMI quirk */ - if (acpi_dev_present("RTL5682", NULL, -1)) - sof_rt5682_quirk |= SOF_RT5682S_HEADPHONE_CODEC_PRESENT; - if (soc_intel_is_byt() || soc_intel_is_cht()) { is_legacy_cpu = 1; dmic_be_num = 0; @@ -1092,10 +1088,9 @@ static const struct platform_device_id board_ids[] = { SOF_SSP_BT_OFFLOAD_PRESENT), }, { - .name = "adl_rt1019_rt5682s", + .name = "adl_rt1019_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_RT5682S_HEADPHONE_CODEC_PRESENT | SOF_SPEAKER_AMP_PRESENT | SOF_RT1019_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1) | diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index ee9857dc3135..b58c7b35599d 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -355,6 +355,47 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { .driver_data = (void *)(SOF_SDW_TGL_HDMI | RT711_JD2), }, + /* RaptorLake devices */ + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C10"), + }, + /* No Jack */ + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + SOF_SDW_FOUR_SPK), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C11") + }, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + RT711_JD2 | + SOF_SDW_FOUR_SPK), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C40") + }, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + RT711_JD2 | + SOF_SDW_FOUR_SPK), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C4F") + }, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + RT711_JD2 | + SOF_SDW_FOUR_SPK), + }, /* MeteorLake devices */ { .callback = sof_sdw_quirk_cb, @@ -510,6 +551,7 @@ static struct sof_sdw_codec_info codec_info_list[] = { .dai_name = "rt1308-aif", .ops = &sof_sdw_rt1308_i2s_ops, .init = sof_sdw_rt1308_init, + .exit = sof_sdw_rt1308_exit, .codec_type = SOF_SDW_CODEC_TYPE_AMP, }, { @@ -517,6 +559,14 @@ static struct sof_sdw_codec_info codec_info_list[] = { .direction = {true, true}, .dai_name = "rt1316-aif", .init = sof_sdw_rt1316_init, + .exit = sof_sdw_rt1316_exit, + .codec_type = SOF_SDW_CODEC_TYPE_AMP, + }, + { + .part_id = 0x1318, + .direction = {true, true}, + .dai_name = "rt1318-aif", + .init = sof_sdw_rt1318_init, .codec_type = SOF_SDW_CODEC_TYPE_AMP, }, { diff --git a/sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h b/sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h new file mode 100644 index 000000000000..4a3e6fdbd623 --- /dev/null +++ b/sound/soc/intel/boards/sof_sdw_amp_coeff_tables.h @@ -0,0 +1,300 @@ +/* SPDX-License-Identifier: GPL-2.0-only + */ + +/* + * sof_sdw_amp_coeff_tables.h - related coefficients for amplifier parameters + */ + +#ifndef SND_SOC_SOF_SDW_AMP_COEFF_H +#define SND_SOC_SOF_SDW_AMP_COEFF_H + +#define RT1308_MAX_BQ_REG 480 +#define RT1316_MAX_BQ_REG 580 + +static const u8 __maybe_unused dell_0a5d_bq_params[] = { + 0xb0, 0xc5, 0x00, /* address: 0xc5b0; data: 0x00 */ + 0xb1, 0xc5, 0x32, + 0xb2, 0xc5, 0x44, + 0xb3, 0xc5, 0x19, + 0xc0, 0xc5, 0x04, + 0xc1, 0xc5, 0x00, + 0xc2, 0xc5, 0x00, + 0xc3, 0xc5, 0x00, + 0xd0, 0xc5, 0x02, + 0xd1, 0xc5, 0x00, + 0xd2, 0xc5, 0x00, + 0xd3, 0xc5, 0x00, + 0xe0, 0xc5, 0x01, + 0xe1, 0xc5, 0xe8, + 0xe2, 0xc5, 0x5f, + 0xe3, 0xc5, 0x8a, + 0xf0, 0xc5, 0x1f, + 0xf1, 0xc5, 0x4e, + 0xf2, 0xc5, 0x90, + 0xf3, 0xc5, 0x11, + 0x50, 0xc6, 0x01, + 0x51, 0xc6, 0xff, + 0x52, 0xc6, 0x45, + 0x53, 0xc6, 0x41, + 0x60, 0xc6, 0x1c, + 0x61, 0xc6, 0x00, + 0x62, 0xc6, 0x00, + 0x63, 0xc6, 0x00, + 0x70, 0xc6, 0x02, + 0x71, 0xc6, 0x00, + 0x72, 0xc6, 0x00, + 0x73, 0xc6, 0x00, + 0x80, 0xc6, 0x03, + 0x81, 0xc6, 0xfe, + 0x82, 0xc6, 0x89, + 0x83, 0xc6, 0xfa, + 0x90, 0xc6, 0x1e, + 0x91, 0xc6, 0x01, + 0x92, 0xc6, 0x74, + 0x93, 0xc6, 0xf6, + 0x00, 0xc6, 0x01, + 0x01, 0xc6, 0xd9, + 0x02, 0xc6, 0xfb, + 0x03, 0xc6, 0xc4, + 0x10, 0xc6, 0x1c, + 0x11, 0xc6, 0x00, + 0x12, 0xc6, 0x00, + 0x13, 0xc6, 0x00, + 0x20, 0xc6, 0x02, + 0x21, 0xc6, 0x00, + 0x22, 0xc6, 0x00, + 0x23, 0xc6, 0x00, + 0x30, 0xc6, 0x03, + 0x31, 0xc6, 0xaf, + 0x32, 0xc6, 0x23, + 0x33, 0xc6, 0xcb, + 0x40, 0xc6, 0x1e, + 0x41, 0xc6, 0x47, + 0x42, 0xc6, 0x34, + 0x43, 0xc6, 0xba, + 0xa0, 0xc6, 0x01, + 0xa1, 0xc6, 0xff, + 0xa2, 0xc6, 0x45, + 0xa3, 0xc6, 0x41, + 0xb0, 0xc6, 0x1c, + 0xb1, 0xc6, 0x00, + 0xb2, 0xc6, 0x00, + 0xb3, 0xc6, 0x00, + 0xc0, 0xc6, 0x02, + 0xc1, 0xc6, 0x00, + 0xc2, 0xc6, 0x00, + 0xc3, 0xc6, 0x00, + 0xd0, 0xc6, 0x03, + 0xd1, 0xc6, 0xfe, + 0xd2, 0xc6, 0x89, + 0xd3, 0xc6, 0xfa, + 0xe0, 0xc6, 0x1e, + 0xe1, 0xc6, 0x01, + 0xe2, 0xc6, 0x74, + 0xe3, 0xc6, 0xf6, + 0x40, 0xc5, 0x0d, + 0x30, 0xc7, 0x15, + 0x31, 0xc7, 0x7c, + 0x32, 0xc7, 0x0f, + 0x33, 0xc7, 0xa0, + 0x40, 0xc7, 0x00, + 0x41, 0xc7, 0x00, + 0x42, 0xc7, 0xf8, + 0x43, 0xc7, 0xf8, + 0x50, 0xc7, 0x00, + 0x51, 0xc7, 0x00, + 0x52, 0xc7, 0x00, + 0x53, 0xc7, 0x01, + 0x90, 0xc7, 0x00, + 0x91, 0xc7, 0x14, + 0x92, 0xc7, 0x00, + 0x93, 0xc7, 0x14, + 0xa0, 0xc7, 0x00, + 0xa1, 0xc7, 0x00, + 0xa2, 0xc7, 0xf8, + 0xa3, 0xc7, 0xf8, + 0xb0, 0xc7, 0x00, + 0xb1, 0xc7, 0x00, + 0xb2, 0xc7, 0x00, + 0xb3, 0xc7, 0x00, + 0x60, 0xc7, 0x03, + 0x61, 0xc7, 0xe8, + 0x62, 0xc7, 0x03, + 0x63, 0xc7, 0xb6, + 0x70, 0xc7, 0x00, + 0x71, 0xc7, 0x00, + 0x72, 0xc7, 0xf8, + 0x73, 0xc7, 0xf8, + 0x80, 0xc7, 0x00, + 0x81, 0xc7, 0x00, + 0x82, 0xc7, 0x00, + 0x83, 0xc7, 0x00, + 0xc0, 0xc7, 0x00, + 0xc1, 0xc7, 0x14, + 0xc2, 0xc7, 0x00, + 0xc3, 0xc7, 0x14, + 0xd0, 0xc7, 0x00, + 0xd1, 0xc7, 0x00, + 0xd2, 0xc7, 0xf8, + 0xd3, 0xc7, 0xf8, + 0xe0, 0xc7, 0x00, + 0xe1, 0xc7, 0x00, + 0xe2, 0xc7, 0x00, + 0xe3, 0xc7, 0x00, + 0x60, 0xc5, 0x02, + 0x61, 0xc5, 0x00, + 0x62, 0xc5, 0x00, + 0x63, 0xc5, 0x00, + 0x70, 0xc5, 0x02, + 0x71, 0xc5, 0x00, + 0x72, 0xc5, 0x00, + 0x73, 0xc5, 0x00, + 0x80, 0xc5, 0x02, + 0x81, 0xc5, 0x00, + 0x82, 0xc5, 0x00, + 0x83, 0xc5, 0x00, + 0x90, 0xc5, 0x02, + 0x91, 0xc5, 0x00, + 0x92, 0xc5, 0x00, + 0x93, 0xc5, 0x00, + 0x50, 0xc5, 0x01, +}; + +static const u8 __maybe_unused dell_0b00_bq_params[] = { + 0x03, 0xc2, 0x00, + 0x04, 0xc2, 0xb2, + 0x05, 0xc2, 0xe0, + 0x06, 0xc2, 0x3a, + 0x07, 0xc2, 0x01, + 0x08, 0xc2, 0x65, + 0x09, 0xc2, 0xc0, + 0x0a, 0xc2, 0x75, + 0x0b, 0xc2, 0x00, + 0x0c, 0xc2, 0xb2, + 0x0d, 0xc2, 0xe0, + 0x0e, 0xc2, 0x3a, + 0x0f, 0xc2, 0xf7, + 0x10, 0xc2, 0x4d, + 0x11, 0xc2, 0x5b, + 0x12, 0xc2, 0xe9, + 0x13, 0xc2, 0x03, + 0x14, 0xc2, 0x7e, + 0x15, 0xc2, 0x25, + 0x16, 0xc2, 0x01, + 0x17, 0xc2, 0x07, + 0x18, 0xc2, 0xfd, + 0x19, 0xc2, 0x15, + 0x1a, 0xc2, 0x04, + 0x1b, 0xc2, 0xf0, + 0x1c, 0xc2, 0x05, + 0x1d, 0xc2, 0xd5, + 0x1e, 0xc2, 0xf7, + 0x1f, 0xc2, 0x07, + 0x20, 0xc2, 0xfd, + 0x21, 0xc2, 0x15, + 0x22, 0xc2, 0x04, + 0x23, 0xc2, 0xf0, + 0x24, 0xc2, 0x05, + 0x25, 0xc2, 0xd8, + 0x26, 0xc2, 0x17, + 0x27, 0xc2, 0x07, + 0x28, 0xc2, 0xfa, + 0x29, 0xc2, 0x2c, + 0x2a, 0xc2, 0x29, + 0x2b, 0xc2, 0x07, + 0x2c, 0xc2, 0x74, + 0x2d, 0xc2, 0xe0, + 0x2e, 0xc2, 0x33, + 0x2f, 0xc2, 0xf1, + 0x30, 0xc2, 0x16, + 0x31, 0xc2, 0x3f, + 0x32, 0xc2, 0x9b, + 0x33, 0xc2, 0x07, + 0x34, 0xc2, 0x74, + 0x35, 0xc2, 0xe0, + 0x36, 0xc2, 0x33, + 0x37, 0xc2, 0xf1, + 0x38, 0xc2, 0x29, + 0x39, 0xc2, 0xb0, + 0x3a, 0xc2, 0x4d, + 0x3b, 0xc2, 0x06, + 0x3c, 0xc2, 0xfd, + 0x3d, 0xc2, 0x31, + 0x3e, 0xc2, 0x18, + 0x3f, 0xc2, 0x07, + 0x40, 0xc2, 0xfd, + 0x41, 0xc2, 0x15, + 0x42, 0xc2, 0x04, + 0x43, 0xc2, 0xf0, + 0x44, 0xc2, 0x05, + 0x45, 0xc2, 0xd5, + 0x46, 0xc2, 0xf7, + 0x47, 0xc2, 0x07, + 0x48, 0xc2, 0xfd, + 0x49, 0xc2, 0x15, + 0x4a, 0xc2, 0x04, + 0x4b, 0xc2, 0xf0, + 0x4c, 0xc2, 0x05, + 0x4d, 0xc2, 0xd8, + 0x4e, 0xc2, 0x17, + 0x4f, 0xc2, 0x07, + 0x50, 0xc2, 0xfa, + 0x51, 0xc2, 0x2c, + 0x52, 0xc2, 0x29, + 0x0b, 0xc0, 0x30, + 0x80, 0xc3, 0x13, + 0x81, 0xc3, 0x88, + 0x82, 0xc3, 0x17, + 0x83, 0xc3, 0x70, + 0x84, 0xc3, 0x00, + 0x85, 0xc3, 0x00, + 0x86, 0xc3, 0xff, + 0x87, 0xc3, 0xee, + 0x88, 0xc3, 0x02, + 0x92, 0xc3, 0x00, + 0x93, 0xc3, 0x14, + 0x94, 0xc3, 0x00, + 0x95, 0xc3, 0x14, + 0x96, 0xc3, 0x00, + 0x97, 0xc3, 0x00, + 0x98, 0xc3, 0x00, + 0x99, 0xc3, 0x00, + 0x9a, 0xc3, 0x01, + 0x89, 0xc3, 0x03, + 0x8a, 0xc3, 0xe8, + 0x8b, 0xc3, 0x03, + 0x8c, 0xc3, 0xb6, + 0x8d, 0xc3, 0x00, + 0x8e, 0xc3, 0x00, + 0x8f, 0xc3, 0xff, + 0x90, 0xc3, 0xee, + 0x91, 0xc3, 0x01, + 0x9b, 0xc3, 0x00, + 0x9c, 0xc3, 0x14, + 0x9d, 0xc3, 0x00, + 0x9e, 0xc3, 0x14, + 0x9f, 0xc3, 0x00, + 0xa0, 0xc3, 0x00, + 0xa1, 0xc3, 0x00, + 0xa2, 0xc3, 0x00, + 0xa3, 0xc3, 0x01, + 0x61, 0xc2, 0x08, + 0x62, 0xc2, 0x00, + 0x63, 0xc2, 0x00, + 0x64, 0xc2, 0x00, + 0x65, 0xc2, 0x08, + 0x66, 0xc2, 0x00, + 0x67, 0xc2, 0x00, + 0x68, 0xc2, 0x00, + 0x69, 0xc2, 0x08, + 0x6a, 0xc2, 0x00, + 0x6b, 0xc2, 0x00, + 0x6c, 0xc2, 0x00, + 0x6d, 0xc2, 0x08, + 0x6e, 0xc2, 0x00, + 0x6f, 0xc2, 0x00, + 0x70, 0xc2, 0x00, + 0x00, 0xc2, 0xc0, +}; + +#endif diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h index e2457738a332..54a50f7da4da 100644 --- a/sound/soc/intel/boards/sof_sdw_common.h +++ b/sound/soc/intel/boards/sof_sdw_common.h @@ -83,6 +83,7 @@ struct mc_private { bool idisp_codec; struct snd_soc_jack sdw_headset; struct device *headset_codec_dev; /* only one headset per card */ + struct device *amp_dev1, *amp_dev2; }; extern unsigned long sof_sdw_quirk; @@ -132,6 +133,7 @@ int sof_sdw_rt1308_init(struct snd_soc_card *card, struct snd_soc_dai_link *dai_links, struct sof_sdw_codec_info *info, bool playback); +int sof_sdw_rt1308_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); /* RT1316 support */ int sof_sdw_rt1316_init(struct snd_soc_card *card, @@ -139,6 +141,14 @@ int sof_sdw_rt1316_init(struct snd_soc_card *card, struct snd_soc_dai_link *dai_links, struct sof_sdw_codec_info *info, bool playback); +int sof_sdw_rt1316_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); + +/* RT1318 support */ +int sof_sdw_rt1318_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback); /* RT715 support */ int sof_sdw_rt715_init(struct snd_soc_card *card, diff --git a/sound/soc/intel/boards/sof_sdw_rt1308.c b/sound/soc/intel/boards/sof_sdw_rt1308.c index f078fb1aad02..a19b055b9c6f 100644 --- a/sound/soc/intel/boards/sof_sdw_rt1308.c +++ b/sound/soc/intel/boards/sof_sdw_rt1308.c @@ -11,9 +11,86 @@ #include <sound/soc.h> #include <sound/soc-acpi.h> #include <sound/soc-dapm.h> +#include <linux/soundwire/sdw.h> +#include <linux/soundwire/sdw_type.h> +#include <linux/dmi.h> #include "sof_sdw_common.h" +#include "sof_sdw_amp_coeff_tables.h" #include "../../codecs/rt1308.h" +struct rt1308_platform_data { + const unsigned char *bq_params; + const unsigned int bq_params_cnt; +}; + +static const struct rt1308_platform_data dell_0a5d_platform_data = { + .bq_params = dell_0a5d_bq_params, + .bq_params_cnt = ARRAY_SIZE(dell_0a5d_bq_params), +}; + +static const struct dmi_system_id dmi_platform_data[] = { + /* CometLake devices */ + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990") + }, + .driver_data = (void *)&dell_0a5d_platform_data, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F") + }, + .driver_data = (void *)&dell_0a5d_platform_data, + }, + /* TigerLake devices */ + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5D") + }, + .driver_data = (void *)&dell_0a5d_platform_data, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5E") + }, + .driver_data = (void *)&dell_0a5d_platform_data, + }, +}; + +static int rt1308_add_device_props(struct device *sdw_dev) +{ + struct property_entry props[3] = {}; + struct fwnode_handle *fwnode; + const struct dmi_system_id *dmi_data; + const struct rt1308_platform_data *pdata; + unsigned char params[RT1308_MAX_BQ_REG]; + int ret; + + dmi_data = dmi_first_match(dmi_platform_data); + if (!dmi_data) + return 0; + + pdata = dmi_data->driver_data; + memcpy(¶ms, pdata->bq_params, sizeof(unsigned char) * pdata->bq_params_cnt); + + props[0] = PROPERTY_ENTRY_U8_ARRAY("realtek,bq-params", params); + props[1] = PROPERTY_ENTRY_U32("realtek,bq-params-cnt", pdata->bq_params_cnt); + + fwnode = fwnode_create_software_node(props, NULL); + if (IS_ERR(fwnode)) + return PTR_ERR(fwnode); + + ret = device_add_software_node(sdw_dev, to_software_node(fwnode)); + + fwnode_handle_put(fwnode); + + return ret; +} + static const struct snd_soc_dapm_widget rt1308_widgets[] = { SND_SOC_DAPM_SPK("Speaker", NULL), }; @@ -127,12 +204,33 @@ struct snd_soc_ops sof_sdw_rt1308_i2s_ops = { .hw_params = rt1308_i2s_hw_params, }; +int sof_sdw_rt1308_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link) +{ + struct mc_private *ctx = snd_soc_card_get_drvdata(card); + + if (ctx->amp_dev1) { + device_remove_software_node(ctx->amp_dev1); + put_device(ctx->amp_dev1); + } + + if (ctx->amp_dev2) { + device_remove_software_node(ctx->amp_dev2); + put_device(ctx->amp_dev2); + } + + return 0; +} + int sof_sdw_rt1308_init(struct snd_soc_card *card, const struct snd_soc_acpi_link_adr *link, struct snd_soc_dai_link *dai_links, struct sof_sdw_codec_info *info, bool playback) { + struct mc_private *ctx = snd_soc_card_get_drvdata(card); + struct device *sdw_dev1, *sdw_dev2; + int ret; + /* Count amp number and do init on playback link only. */ if (!playback) return 0; @@ -142,6 +240,28 @@ int sof_sdw_rt1308_init(struct snd_soc_card *card, dai_links->init = first_spk_init; if (info->amp_num == 2) { + sdw_dev1 = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[0].name); + if (!sdw_dev1) + return -EPROBE_DEFER; + + ret = rt1308_add_device_props(sdw_dev1); + if (ret < 0) { + put_device(sdw_dev1); + return ret; + } + ctx->amp_dev1 = sdw_dev1; + + sdw_dev2 = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[1].name); + if (!sdw_dev2) + return -EPROBE_DEFER; + + ret = rt1308_add_device_props(sdw_dev2); + if (ret < 0) { + put_device(sdw_dev2); + return ret; + } + ctx->amp_dev2 = sdw_dev2; + /* * if two 1308s are in one dai link, the init function * in this dai link will be first set for the first speaker, diff --git a/sound/soc/intel/boards/sof_sdw_rt1316.c b/sound/soc/intel/boards/sof_sdw_rt1316.c index 58194b380232..f6bbea0d3810 100644 --- a/sound/soc/intel/boards/sof_sdw_rt1316.c +++ b/sound/soc/intel/boards/sof_sdw_rt1316.c @@ -11,7 +11,83 @@ #include <sound/soc.h> #include <sound/soc-acpi.h> #include <sound/soc-dapm.h> +#include <linux/soundwire/sdw.h> +#include <linux/soundwire/sdw_type.h> +#include <linux/dmi.h> #include "sof_sdw_common.h" +#include "sof_sdw_amp_coeff_tables.h" + +struct rt1316_platform_data { + const unsigned char *bq_params; + const unsigned int bq_params_cnt; +}; + +static const struct rt1316_platform_data dell_0b00_platform_data = { + .bq_params = dell_0b00_bq_params, + .bq_params_cnt = ARRAY_SIZE(dell_0b00_bq_params), +}; + +static const struct dmi_system_id dmi_platform_data[] = { + /* AlderLake devices */ + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B00") + }, + .driver_data = (void *)&dell_0b00_platform_data, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B01") + }, + .driver_data = (void *)&dell_0b00_platform_data, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AFF") + }, + .driver_data = (void *)&dell_0b00_platform_data, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0AFE") + }, + .driver_data = (void *)&dell_0b00_platform_data, + }, +}; + +static int rt1316_add_device_props(struct device *sdw_dev) +{ + struct property_entry props[3] = {}; + struct fwnode_handle *fwnode; + const struct dmi_system_id *dmi_data; + const struct rt1316_platform_data *pdata; + unsigned char params[RT1316_MAX_BQ_REG]; + int ret; + + dmi_data = dmi_first_match(dmi_platform_data); + if (!dmi_data) + return 0; + + pdata = dmi_data->driver_data; + memcpy(¶ms, pdata->bq_params, sizeof(unsigned char) * pdata->bq_params_cnt); + + props[0] = PROPERTY_ENTRY_U8_ARRAY("realtek,bq-params", params); + props[1] = PROPERTY_ENTRY_U32("realtek,bq-params-cnt", pdata->bq_params_cnt); + + fwnode = fwnode_create_software_node(props, NULL); + if (IS_ERR(fwnode)) + return PTR_ERR(fwnode); + + ret = device_add_software_node(sdw_dev, to_software_node(fwnode)); + + fwnode_handle_put(fwnode); + + return ret; +} static const struct snd_soc_dapm_widget rt1316_widgets[] = { SND_SOC_DAPM_SPK("Speaker", NULL), @@ -89,12 +165,33 @@ static int all_spk_init(struct snd_soc_pcm_runtime *rtd) return second_spk_init(rtd); } +int sof_sdw_rt1316_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link) +{ + struct mc_private *ctx = snd_soc_card_get_drvdata(card); + + if (ctx->amp_dev1) { + device_remove_software_node(ctx->amp_dev1); + put_device(ctx->amp_dev1); + } + + if (ctx->amp_dev2) { + device_remove_software_node(ctx->amp_dev2); + put_device(ctx->amp_dev2); + } + + return 0; +} + int sof_sdw_rt1316_init(struct snd_soc_card *card, const struct snd_soc_acpi_link_adr *link, struct snd_soc_dai_link *dai_links, struct sof_sdw_codec_info *info, bool playback) { + struct mc_private *ctx = snd_soc_card_get_drvdata(card); + struct device *sdw_dev1, *sdw_dev2; + int ret; + /* Count amp number and do init on playback link only. */ if (!playback) return 0; @@ -104,6 +201,28 @@ int sof_sdw_rt1316_init(struct snd_soc_card *card, dai_links->init = first_spk_init; if (info->amp_num == 2) { + sdw_dev1 = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[0].name); + if (!sdw_dev1) + return -EPROBE_DEFER; + + ret = rt1316_add_device_props(sdw_dev1); + if (ret < 0) { + put_device(sdw_dev1); + return ret; + } + ctx->amp_dev1 = sdw_dev1; + + sdw_dev2 = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[1].name); + if (!sdw_dev2) + return -EPROBE_DEFER; + + ret = rt1316_add_device_props(sdw_dev2); + if (ret < 0) { + put_device(sdw_dev2); + return ret; + } + ctx->amp_dev2 = sdw_dev2; + /* * if two 1316s are in one dai link, the init function * in this dai link will be first set for the first speaker, diff --git a/sound/soc/intel/boards/sof_sdw_rt1318.c b/sound/soc/intel/boards/sof_sdw_rt1318.c new file mode 100644 index 000000000000..dbee4bf5c814 --- /dev/null +++ b/sound/soc/intel/boards/sof_sdw_rt1318.c @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2022 Intel Corporation + +/* + * sof_sdw_rt1318 - Helpers to handle RT1318 from generic machine driver + */ + +#include <linux/device.h> +#include <linux/errno.h> +#include <sound/control.h> +#include <sound/soc.h> +#include <sound/soc-acpi.h> +#include <sound/soc-dapm.h> +#include "sof_sdw_common.h" + +static const struct snd_soc_dapm_widget rt1318_widgets[] = { + SND_SOC_DAPM_SPK("Speaker", NULL), +}; + +/* + * dapm routes for rt1318 will be registered dynamically according + * to the number of rt1318 used. The first two entries will be registered + * for one codec case, and the last two entries are also registered + * if two 1318s are used. + */ +static const struct snd_soc_dapm_route rt1318_map[] = { + { "Speaker", NULL, "rt1318-1 SPOL" }, + { "Speaker", NULL, "rt1318-1 SPOR" }, + { "Speaker", NULL, "rt1318-2 SPOL" }, + { "Speaker", NULL, "rt1318-2 SPOR" }, +}; + +static const struct snd_kcontrol_new rt1318_controls[] = { + SOC_DAPM_PIN_SWITCH("Speaker"), +}; + +static int first_spk_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + int ret; + + card->components = devm_kasprintf(card->dev, GFP_KERNEL, + "%s spk:rt1318", + card->components); + if (!card->components) + return -ENOMEM; + + ret = snd_soc_add_card_controls(card, rt1318_controls, + ARRAY_SIZE(rt1318_controls)); + if (ret) { + dev_err(card->dev, "rt1318 controls addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_new_controls(&card->dapm, rt1318_widgets, + ARRAY_SIZE(rt1318_widgets)); + if (ret) { + dev_err(card->dev, "rt1318 widgets addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, rt1318_map, 2); + if (ret) + dev_err(rtd->dev, "failed to add first SPK map: %d\n", ret); + + return ret; +} + +static int second_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, rt1318_map + 2, 2); + if (ret) + dev_err(rtd->dev, "failed to add second SPK map: %d\n", ret); + + return ret; +} + +static int all_spk_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret; + + ret = first_spk_init(rtd); + if (ret) + return ret; + + return second_spk_init(rtd); +} + +int sof_sdw_rt1318_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback) +{ + /* Count amp number and do init on playback link only. */ + if (!playback) + return 0; + + info->amp_num++; + if (info->amp_num == 1) + dai_links->init = first_spk_init; + + if (info->amp_num == 2) { + /* + * if two 1318s are in one dai link, the init function + * in this dai link will be first set for the first speaker, + * and it should be reset to initialize all speakers when + * the second speaker is found. + */ + if (dai_links->init) + dai_links->init = all_spk_init; + else + dai_links->init = second_spk_init; + } + + return 0; +} |