diff options
Diffstat (limited to 'sound/soc/intel/boards')
-rw-r--r-- | sound/soc/intel/boards/Kconfig | 265 | ||||
-rw-r--r-- | sound/soc/intel/boards/Makefile | 1 | ||||
-rw-r--r-- | sound/soc/intel/boards/bxt_da7219_max98357a.c | 16 | ||||
-rw-r--r-- | sound/soc/intel/boards/bxt_rt298.c | 86 | ||||
-rw-r--r-- | sound/soc/intel/boards/byt-max98090.c | 12 | ||||
-rw-r--r-- | sound/soc/intel/boards/bytcht_da7213.c | 23 | ||||
-rw-r--r-- | sound/soc/intel/boards/bytcht_es8316.c | 27 | ||||
-rw-r--r-- | sound/soc/intel/boards/bytcht_nocodec.c | 10 | ||||
-rw-r--r-- | sound/soc/intel/boards/bytcr_rt5640.c | 118 | ||||
-rw-r--r-- | sound/soc/intel/boards/bytcr_rt5651.c | 297 | ||||
-rw-r--r-- | sound/soc/intel/boards/cht_bsw_max98090_ti.c | 185 | ||||
-rw-r--r-- | sound/soc/intel/boards/cht_bsw_rt5645.c | 128 | ||||
-rw-r--r-- | sound/soc/intel/boards/cht_bsw_rt5672.c | 78 | ||||
-rw-r--r-- | sound/soc/intel/boards/kbl_rt5663_max98927.c | 384 | ||||
-rw-r--r-- | sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c | 97 | ||||
-rw-r--r-- | sound/soc/intel/boards/mfld_machine.c | 4 | ||||
-rw-r--r-- | sound/soc/intel/boards/skl_nau88l25_max98357a.c | 16 | ||||
-rw-r--r-- | sound/soc/intel/boards/skl_nau88l25_ssm4567.c | 16 |
18 files changed, 1307 insertions, 456 deletions
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig new file mode 100644 index 000000000000..6f754708a48c --- /dev/null +++ b/sound/soc/intel/boards/Kconfig @@ -0,0 +1,265 @@ +config SND_SOC_INTEL_MACH + tristate "Intel Audio machine drivers" + depends on SND_SOC_INTEL_SST_TOPLEVEL + select SND_SOC_ACPI_INTEL_MATCH if ACPI + +if SND_SOC_INTEL_MACH + +config SND_MFLD_MACHINE + tristate "SOC Machine Audio driver for Intel Medfield MID platform" + depends on INTEL_SCU_IPC + select SND_SOC_SN95031 + depends on SND_SST_ATOM_HIFI2_PLATFORM + select SND_SST_IPC_PCI + help + This adds support for ASoC machine driver for Intel(R) MID Medfield platform + used as alsa device in audio substem in Intel(R) MID devices + Say Y if you have such a device. + If unsure select "N". + +config SND_SOC_INTEL_HASWELL_MACH + tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint" + depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM + depends on SND_SOC_INTEL_HASWELL + select SND_SOC_RT5640 + help + This adds support for the Lynxpoint Audio DSP on Intel(R) Haswell + Ultrabook platforms. + Say Y if you have such a device. + If unsure select "N". + +config SND_SOC_INTEL_BDW_RT5677_MACH + tristate "ASoC Audio driver for Intel Broadwell with RT5677 codec" + depends on X86_INTEL_LPSS && GPIOLIB && I2C + depends on SND_SOC_INTEL_HASWELL + select SND_SOC_RT5677 + help + This adds support for Intel Broadwell platform based boards with + the RT5677 audio codec. + +config SND_SOC_INTEL_BROADWELL_MACH + tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint" + depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM + depends on SND_SOC_INTEL_HASWELL + select SND_SOC_RT286 + help + This adds support for the Wilcatpoint Audio DSP on Intel(R) Broadwell + Ultrabook platforms. + Say Y if you have such a device. + If unsure select "N". + +config SND_SOC_INTEL_BYT_MAX98090_MACH + tristate "ASoC Audio driver for Intel Baytrail with MAX98090 codec" + depends on X86_INTEL_LPSS && I2C + depends on SND_SST_IPC_ACPI = n + depends on SND_SOC_INTEL_BAYTRAIL + select SND_SOC_MAX98090 + help + This adds audio driver for Intel Baytrail platform based boards + with the MAX98090 audio codec. + +config SND_SOC_INTEL_BYT_RT5640_MACH + tristate "ASoC Audio driver for Intel Baytrail with RT5640 codec" + depends on X86_INTEL_LPSS && I2C + depends on SND_SST_IPC_ACPI = n + depends on SND_SOC_INTEL_BAYTRAIL + select SND_SOC_RT5640 + help + This adds audio driver for Intel Baytrail platform based boards + with the RT5640 audio codec. This driver is deprecated, use + SND_SOC_INTEL_BYTCR_RT5640_MACH instead for better functionality. + +config SND_SOC_INTEL_BYTCR_RT5640_MACH + tristate "ASoC Audio driver for Intel Baytrail and Baytrail-CR with RT5640 codec" + depends on X86 && I2C && ACPI + select SND_SOC_RT5640 + depends on SND_SST_ATOM_HIFI2_PLATFORM + select SND_SST_IPC_ACPI + help + This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR + platforms with RT5640 audio codec. + Say Y if you have such a device. + If unsure select "N". + +config SND_SOC_INTEL_BYTCR_RT5651_MACH + tristate "ASoC Audio driver for Intel Baytrail and Baytrail-CR with RT5651 codec" + depends on X86 && I2C && ACPI + select SND_SOC_RT5651 + depends on SND_SST_ATOM_HIFI2_PLATFORM + select SND_SST_IPC_ACPI + help + This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR + platforms with RT5651 audio codec. + Say Y if you have such a device. + If unsure select "N". + +config SND_SOC_INTEL_CHT_BSW_RT5672_MACH + tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5672 codec" + depends on X86_INTEL_LPSS && I2C && ACPI + select SND_SOC_RT5670 + depends on SND_SST_ATOM_HIFI2_PLATFORM + select SND_SST_IPC_ACPI + help + This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell + platforms with RT5672 audio codec. + Say Y if you have such a device. + If unsure select "N". + +config SND_SOC_INTEL_CHT_BSW_RT5645_MACH + tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5645/5650 codec" + depends on X86_INTEL_LPSS && I2C && ACPI + select SND_SOC_RT5645 + depends on SND_SST_ATOM_HIFI2_PLATFORM + select SND_SST_IPC_ACPI + help + This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell + platforms with RT5645/5650 audio codec. + If unsure select "N". + +config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH + tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with MAX98090 & TI codec" + depends on X86_INTEL_LPSS && I2C && ACPI + select SND_SOC_MAX98090 + select SND_SOC_TS3A227E + depends on SND_SST_ATOM_HIFI2_PLATFORM + select SND_SST_IPC_ACPI + help + This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell + platforms with MAX98090 audio codec it also can support TI jack chip as aux device. + If unsure select "N". + +config SND_SOC_INTEL_BYT_CHT_DA7213_MACH + tristate "ASoC Audio driver for Intel Baytrail & Cherrytrail with DA7212/7213 codec" + depends on X86_INTEL_LPSS && I2C && ACPI + select SND_SOC_DA7213 + depends on SND_SST_ATOM_HIFI2_PLATFORM + select SND_SST_IPC_ACPI + help + This adds support for ASoC machine driver for Intel(R) Baytrail & CherryTrail + platforms with DA7212/7213 audio codec. + If unsure select "N". + +config SND_SOC_INTEL_BYT_CHT_ES8316_MACH + tristate "ASoC Audio driver for Intel Baytrail & Cherrytrail with ES8316 codec" + depends on X86_INTEL_LPSS && I2C && ACPI + select SND_SOC_ES8316 + depends on SND_SST_ATOM_HIFI2_PLATFORM + select SND_SST_IPC_ACPI + help + This adds support for ASoC machine driver for Intel(R) Baytrail & + Cherrytrail platforms with ES8316 audio codec. + If unsure select "N". + +config SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH + tristate "ASoC Audio driver for Intel Baytrail & Cherrytrail platform with no codec (MinnowBoard MAX, Up)" + depends on X86_INTEL_LPSS && I2C && ACPI + depends on SND_SST_ATOM_HIFI2_PLATFORM + select SND_SST_IPC_ACPI + help + This adds support for ASoC machine driver for the MinnowBoard Max or + Up boards and provides access to I2S signals on the Low-Speed + connector + If unsure select "N". + +config SND_SOC_INTEL_SKL_RT286_MACH + tristate "ASoC Audio driver for SKL with RT286 I2S mode" + depends on X86 && ACPI && I2C + depends on SND_SOC_INTEL_SKYLAKE + select SND_SOC_RT286 + select SND_SOC_DMIC + select SND_SOC_HDAC_HDMI + help + This adds support for ASoC machine driver for Skylake platforms + with RT286 I2S audio codec. + Say Y if you have such a device. + If unsure select "N". + +config SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH + tristate "ASoC Audio driver for SKL with NAU88L25 and SSM4567 in I2S Mode" + depends on X86_INTEL_LPSS && I2C + depends on SND_SOC_INTEL_SKYLAKE + select SND_SOC_NAU8825 + select SND_SOC_SSM4567 + select SND_SOC_DMIC + select SND_SOC_HDAC_HDMI + help + This adds support for ASoC Onboard Codec I2S machine driver. This will + create an alsa sound card for NAU88L25 + SSM4567. + Say Y if you have such a device. + If unsure select "N". + +config SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH + tristate "ASoC Audio driver for SKL with NAU88L25 and MAX98357A in I2S Mode" + depends on X86_INTEL_LPSS && I2C + depends on SND_SOC_INTEL_SKYLAKE + select SND_SOC_NAU8825 + select SND_SOC_MAX98357A + select SND_SOC_DMIC + select SND_SOC_HDAC_HDMI + help + This adds support for ASoC Onboard Codec I2S machine driver. This will + create an alsa sound card for NAU88L25 + MAX98357A. + Say Y if you have such a device. + If unsure select "N". + +config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH + tristate "ASoC Audio driver for Broxton with DA7219 and MAX98357A in I2S Mode" + depends on X86 && ACPI && I2C + depends on SND_SOC_INTEL_SKYLAKE + select SND_SOC_DA7219 + select SND_SOC_MAX98357A + select SND_SOC_DMIC + select SND_SOC_HDAC_HDMI + select SND_HDA_DSP_LOADER + help + This adds support for ASoC machine driver for Broxton-P platforms + with DA7219 + MAX98357A I2S audio codec. + Say Y if you have such a device. + If unsure select "N". + +config SND_SOC_INTEL_BXT_RT298_MACH + tristate "ASoC Audio driver for Broxton with RT298 I2S mode" + depends on X86 && ACPI && I2C + depends on SND_SOC_INTEL_SKYLAKE + select SND_SOC_RT298 + select SND_SOC_DMIC + select SND_SOC_HDAC_HDMI + select SND_HDA_DSP_LOADER + help + This adds support for ASoC machine driver for Broxton platforms + with RT286 I2S audio codec. + Say Y if you have such a device. + If unsure select "N". + +config SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH + tristate "ASoC Audio driver for KBL with RT5663 and MAX98927 in I2S Mode" + depends on X86_INTEL_LPSS && I2C + select SND_SOC_INTEL_SST + depends on SND_SOC_INTEL_SKYLAKE + select SND_SOC_RT5663 + select SND_SOC_MAX98927 + select SND_SOC_DMIC + select SND_SOC_HDAC_HDMI + help + This adds support for ASoC Onboard Codec I2S machine driver. This will + create an alsa sound card for RT5663 + MAX98927. + Say Y if you have such a device. + If unsure select "N". + +config SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH + tristate "ASoC Audio driver for KBL with RT5663, RT5514 and MAX98927 in I2S Mode" + depends on X86_INTEL_LPSS && I2C && SPI + select SND_SOC_INTEL_SST + depends on SND_SOC_INTEL_SKYLAKE + select SND_SOC_RT5663 + select SND_SOC_RT5514 + select SND_SOC_RT5514_SPI + select SND_SOC_MAX98927 + select SND_SOC_HDAC_HDMI + help + This adds support for ASoC Onboard Codec I2S machine driver. This will + create an alsa sound card for RT5663 + RT5514 + MAX98927. + Say Y if you have such a device. + If unsure select "N". + +endif diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile index a5c5bc5732a2..69d2dfaeb00c 100644 --- a/sound/soc/intel/boards/Makefile +++ b/sound/soc/intel/boards/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 snd-soc-sst-haswell-objs := haswell.o snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c index ce35ec7884d1..f8a91a6f2a17 100644 --- a/sound/soc/intel/boards/bxt_da7219_max98357a.c +++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c @@ -55,20 +55,6 @@ enum { BXT_DPCM_AUDIO_HDMI3_PB, }; -static inline struct snd_soc_dai *bxt_get_codec_dai(struct snd_soc_card *card) -{ - struct snd_soc_pcm_runtime *rtd; - - list_for_each_entry(rtd, &card->rtd_list, list) { - - if (!strncmp(rtd->codec_dai->name, BXT_DIALOG_CODEC_DAI, - strlen(BXT_DIALOG_CODEC_DAI))) - return rtd->codec_dai; - } - - return NULL; -} - static int platform_clock_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { @@ -77,7 +63,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, struct snd_soc_card *card = dapm->card; struct snd_soc_dai *codec_dai; - codec_dai = bxt_get_codec_dai(card); + codec_dai = snd_soc_card_get_codec_dai(card, BXT_DIALOG_CODEC_DAI); if (!codec_dai) { dev_err(card->dev, "Codec dai not found; Unable to set/unset codec pll\n"); return -EIO; diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c index 0c3a3cbcb884..7843104fadcb 100644 --- a/sound/soc/intel/boards/bxt_rt298.c +++ b/sound/soc/intel/boards/bxt_rt298.c @@ -114,7 +114,44 @@ static const struct snd_soc_dapm_route broxton_rt298_map[] = { { "iDisp2 Tx", NULL, "iDisp2_out"}, { "hifi1", NULL, "iDisp1 Tx"}, { "iDisp1 Tx", NULL, "iDisp1_out"}, +}; + +static const struct snd_soc_dapm_route geminilake_rt298_map[] = { + /* speaker */ + {"Speaker", NULL, "SPOR"}, + {"Speaker", NULL, "SPOL"}, + + /* HP jack connectors - unknown if we have jack detect */ + {"Headphone Jack", NULL, "HPO Pin"}, + + /* other jacks */ + {"MIC1", NULL, "Mic Jack"}, + + /* digital mics */ + {"DMIC1 Pin", NULL, "DMIC2"}, + {"DMic", NULL, "SoC DMIC"}, + + {"HDMI1", NULL, "hif5-0 Output"}, + {"HDMI2", NULL, "hif6-0 Output"}, + {"HDMI2", NULL, "hif7-0 Output"}, + + /* CODEC BE connections */ + { "AIF1 Playback", NULL, "ssp2 Tx"}, + { "ssp2 Tx", NULL, "codec0_out"}, + { "ssp2 Tx", NULL, "codec1_out"}, + + { "codec0_in", NULL, "ssp2 Rx" }, + { "ssp2 Rx", NULL, "AIF1 Capture" }, + { "dmic01_hifi", NULL, "DMIC01 Rx" }, + { "DMIC01 Rx", NULL, "Capture" }, + + { "hifi3", NULL, "iDisp3 Tx"}, + { "iDisp3 Tx", NULL, "iDisp3_out"}, + { "hifi2", NULL, "iDisp2 Tx"}, + { "iDisp2 Tx", NULL, "iDisp2_out"}, + { "hifi1", NULL, "iDisp1 Tx"}, + { "iDisp1 Tx", NULL, "iDisp1_out"}, }; static int broxton_rt298_fe_init(struct snd_soc_pcm_runtime *rtd) @@ -492,7 +529,6 @@ static int bxt_card_late_probe(struct snd_soc_card *card) /* broxton audio machine driver for SPT + RT298S */ static struct snd_soc_card broxton_rt298 = { .name = "broxton-rt298", - .owner = THIS_MODULE, .dai_link = broxton_rt298_dais, .num_links = ARRAY_SIZE(broxton_rt298_dais), .controls = broxton_controls, @@ -506,9 +542,41 @@ static struct snd_soc_card broxton_rt298 = { }; +static struct snd_soc_card geminilake_rt298 = { + .name = "geminilake-rt298", + .dai_link = broxton_rt298_dais, + .num_links = ARRAY_SIZE(broxton_rt298_dais), + .controls = broxton_controls, + .num_controls = ARRAY_SIZE(broxton_controls), + .dapm_widgets = broxton_widgets, + .num_dapm_widgets = ARRAY_SIZE(broxton_widgets), + .dapm_routes = geminilake_rt298_map, + .num_dapm_routes = ARRAY_SIZE(geminilake_rt298_map), + .fully_routed = true, + .late_probe = bxt_card_late_probe, +}; + static int broxton_audio_probe(struct platform_device *pdev) { struct bxt_rt286_private *ctx; + struct snd_soc_card *card = + (struct snd_soc_card *)pdev->id_entry->driver_data; + int i; + + for (i = 0; i < ARRAY_SIZE(broxton_rt298_dais); i++) { + if (!strncmp(card->dai_link[i].codec_name, "i2c-INT343A:00", + I2C_NAME_SIZE)) { + if (!strncmp(card->name, "broxton-rt298", + PLATFORM_NAME_SIZE)) { + card->dai_link[i].name = "SSP5-Codec"; + card->dai_link[i].cpu_dai_name = "SSP5 Pin"; + } else if (!strncmp(card->name, "geminilake-rt298", + PLATFORM_NAME_SIZE)) { + card->dai_link[i].name = "SSP2-Codec"; + card->dai_link[i].cpu_dai_name = "SSP2 Pin"; + } + } + } ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); if (!ctx) @@ -516,18 +584,27 @@ static int broxton_audio_probe(struct platform_device *pdev) INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - broxton_rt298.dev = &pdev->dev; - snd_soc_card_set_drvdata(&broxton_rt298, ctx); + card->dev = &pdev->dev; + snd_soc_card_set_drvdata(card, ctx); - return devm_snd_soc_register_card(&pdev->dev, &broxton_rt298); + return devm_snd_soc_register_card(&pdev->dev, card); } +static const struct platform_device_id bxt_board_ids[] = { + { .name = "bxt_alc298s_i2s", .driver_data = + (unsigned long)&broxton_rt298 }, + { .name = "glk_alc298s_i2s", .driver_data = + (unsigned long)&geminilake_rt298 }, + {} +}; + static struct platform_driver broxton_audio = { .probe = broxton_audio_probe, .driver = { .name = "bxt_alc298s_i2s", .pm = &snd_soc_pm_ops, }, + .id_table = bxt_board_ids, }; module_platform_driver(broxton_audio) @@ -537,3 +614,4 @@ MODULE_AUTHOR("Senthilnathan Veppur <senthilnathanx.veppur@intel.com>"); MODULE_DESCRIPTION("Intel SST Audio for Broxton"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:bxt_alc298s_i2s"); +MODULE_ALIAS("platform:glk_alc298s_i2s"); diff --git a/sound/soc/intel/boards/byt-max98090.c b/sound/soc/intel/boards/byt-max98090.c index 047be7fa0ce9..0f8b8209c020 100644 --- a/sound/soc/intel/boards/byt-max98090.c +++ b/sound/soc/intel/boards/byt-max98090.c @@ -173,20 +173,8 @@ static int byt_max98090_probe(struct platform_device *pdev) return 0; } -static int byt_max98090_remove(struct platform_device *pdev) -{ - struct snd_soc_card *card = platform_get_drvdata(pdev); - struct byt_max98090_private *priv = snd_soc_card_get_drvdata(card); - - snd_soc_jack_free_gpios(&priv->jack, ARRAY_SIZE(hs_jack_gpios), - hs_jack_gpios); - - return 0; -} - static struct platform_driver byt_max98090_driver = { .probe = byt_max98090_probe, - .remove = byt_max98090_remove, .driver = { .name = "byt-max98090", .pm = &snd_soc_pm_ops, diff --git a/sound/soc/intel/boards/bytcht_da7213.c b/sound/soc/intel/boards/bytcht_da7213.c index 18873e23f404..c4d82ad41bd7 100644 --- a/sound/soc/intel/boards/bytcht_da7213.c +++ b/sound/soc/intel/boards/bytcht_da7213.c @@ -27,9 +27,9 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> +#include <sound/soc-acpi.h> #include "../../codecs/da7213.h" #include "../atom/sst-atom-controls.h" -#include "../common/sst-acpi.h" static const struct snd_kcontrol_new controls[] = { SOC_DAPM_PIN_SWITCH("Headphone Jack"), @@ -185,19 +185,11 @@ static struct snd_soc_dai_link dailink[] = { .dpcm_playback = 1, .ops = &aif1_ops, }, - [MERR_DPCM_COMPR] = { - .name = "Compressed Port", - .stream_name = "Compress", - .cpu_dai_name = "compress-cpu-dai", - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .platform_name = "sst-mfld-platform", - }, /* CODEC<->CODEC link */ /* back ends */ { .name = "SSP2-Codec", - .id = 1, + .id = 0, .cpu_dai_name = "ssp2-port", .platform_name = "sst-mfld-platform", .no_pcm = 1, @@ -231,19 +223,18 @@ static char codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */ static int bytcht_da7213_probe(struct platform_device *pdev) { - int ret_val = 0; - int i; struct snd_soc_card *card; - struct sst_acpi_mach *mach; + struct snd_soc_acpi_mach *mach; const char *i2c_name = NULL; int dai_index = 0; + int ret_val = 0; + int i; mach = (&pdev->dev)->platform_data; card = &bytcht_da7213_card; card->dev = &pdev->dev; /* fix index of codec dai */ - dai_index = MERR_DPCM_COMPR + 1; for (i = 0; i < ARRAY_SIZE(dailink); i++) { if (!strcmp(dailink[i].codec_name, "i2c-DLGS7213:00")) { dai_index = i; @@ -252,8 +243,8 @@ static int bytcht_da7213_probe(struct platform_device *pdev) } /* fixup codec name based on HID */ - i2c_name = sst_acpi_find_name_from_hid(mach->id); - if (i2c_name != NULL) { + i2c_name = snd_soc_acpi_find_name_from_hid(mach->id); + if (i2c_name) { snprintf(codec_name, sizeof(codec_name), "%s%s", "i2c-", i2c_name); dailink[dai_index].codec_name = codec_name; diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c index 52635462dac6..8088396717e3 100644 --- a/sound/soc/intel/boards/bytcht_es8316.c +++ b/sound/soc/intel/boards/bytcht_es8316.c @@ -29,28 +29,14 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> +#include <sound/soc-acpi.h> #include "../atom/sst-atom-controls.h" -#include "../common/sst-acpi.h" #include "../common/sst-dsp.h" struct byt_cht_es8316_private { struct clk *mclk; }; -#define CODEC_DAI1 "ES8316 HiFi" - -static inline struct snd_soc_dai *get_codec_dai(struct snd_soc_card *card) -{ - struct snd_soc_pcm_runtime *rtd; - - list_for_each_entry(rtd, &card->rtd_list, list) { - if (!strncmp(rtd->codec_dai->name, CODEC_DAI1, - strlen(CODEC_DAI1))) - return rtd->codec_dai; - } - return NULL; -} - static const struct snd_soc_dapm_widget byt_cht_es8316_widgets[] = { SND_SOC_DAPM_HP("Headphone", NULL), @@ -208,22 +194,13 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = { .ops = &byt_cht_es8316_aif1_ops, }, - [MERR_DPCM_COMPR] = { - .name = "Compressed Port", - .stream_name = "Compress", - .cpu_dai_name = "compress-cpu-dai", - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .platform_name = "sst-mfld-platform", - }, - /* back ends */ { /* Only SSP2 has been tested here, so BYT-CR platforms that * require SSP0 will not work. */ .name = "SSP2-Codec", - .id = 1, + .id = 0, .cpu_dai_name = "ssp2-port", .platform_name = "sst-mfld-platform", .no_pcm = 1, diff --git a/sound/soc/intel/boards/bytcht_nocodec.c b/sound/soc/intel/boards/bytcht_nocodec.c index 1dd9441806fa..b80ec027a0e8 100644 --- a/sound/soc/intel/boards/bytcht_nocodec.c +++ b/sound/soc/intel/boards/bytcht_nocodec.c @@ -133,19 +133,11 @@ static struct snd_soc_dai_link dais[] = { .dpcm_playback = 1, .ops = &aif1_ops, }, - [MERR_DPCM_COMPR] = { - .name = "Compressed Port", - .stream_name = "Compress", - .cpu_dai_name = "compress-cpu-dai", - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .platform_name = "sst-mfld-platform", - }, /* CODEC<->CODEC link */ /* back ends */ { .name = "SSP2-LowSpeed Connector", - .id = 1, + .id = 0, .cpu_dai_name = "ssp2-port", .platform_name = "sst-mfld-platform", .no_pcm = 1, diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 4a76b099a508..f2c0fc415e52 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -22,19 +22,19 @@ #include <linux/moduleparam.h> #include <linux/platform_device.h> #include <linux/acpi.h> +#include <linux/clk.h> #include <linux/device.h> #include <linux/dmi.h> #include <linux/slab.h> #include <asm/cpu_device_id.h> #include <asm/platform_sst_audio.h> -#include <linux/clk.h> #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> #include <sound/jack.h> +#include <sound/soc-acpi.h> #include "../../codecs/rt5640.h" #include "../atom/sst-atom-controls.h" -#include "../common/sst-acpi.h" #include "../common/sst-dsp.h" enum { @@ -44,13 +44,13 @@ enum { BYT_RT5640_IN3_MAP, }; -#define BYT_RT5640_MAP(quirk) ((quirk) & 0xff) +#define BYT_RT5640_MAP(quirk) ((quirk) & GENMASK(7, 0)) #define BYT_RT5640_DMIC_EN BIT(16) #define BYT_RT5640_MONO_SPEAKER BIT(17) #define BYT_RT5640_DIFF_MIC BIT(18) /* defaut is single-ended */ -#define BYT_RT5640_SSP2_AIF2 BIT(19) /* default is using AIF1 */ -#define BYT_RT5640_SSP0_AIF1 BIT(20) -#define BYT_RT5640_SSP0_AIF2 BIT(21) +#define BYT_RT5640_SSP2_AIF2 BIT(19) /* default is using AIF1 */ +#define BYT_RT5640_SSP0_AIF1 BIT(20) +#define BYT_RT5640_SSP0_AIF2 BIT(21) #define BYT_RT5640_MCLK_EN BIT(22) #define BYT_RT5640_MCLK_25MHZ BIT(23) @@ -145,22 +145,6 @@ static void log_quirks(struct device *dev) #define BYT_CODEC_DAI1 "rt5640-aif1" #define BYT_CODEC_DAI2 "rt5640-aif2" -static inline struct snd_soc_dai *byt_get_codec_dai(struct snd_soc_card *card) -{ - struct snd_soc_pcm_runtime *rtd; - - list_for_each_entry(rtd, &card->rtd_list, list) { - if (!strncmp(rtd->codec_dai->name, BYT_CODEC_DAI1, - strlen(BYT_CODEC_DAI1))) - return rtd->codec_dai; - if (!strncmp(rtd->codec_dai->name, BYT_CODEC_DAI2, - strlen(BYT_CODEC_DAI2))) - return rtd->codec_dai; - - } - return NULL; -} - static int platform_clock_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { @@ -170,7 +154,10 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card); int ret; - codec_dai = byt_get_codec_dai(card); + codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI1); + if (!codec_dai) + codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI2); + if (!codec_dai) { dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n"); @@ -178,7 +165,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, } if (SND_SOC_DAPM_EVENT_ON(event)) { - if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk) { + if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) { ret = clk_prepare_enable(priv->mclk); if (ret < 0) { dev_err(card->dev, @@ -199,7 +186,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, 48000 * 512, SND_SOC_CLOCK_IN); if (!ret) { - if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk) + if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) clk_disable_unprepare(priv->mclk); } } @@ -376,8 +363,8 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"), }, - .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP | - BYT_RT5640_MCLK_EN), + .driver_data = (void *)(BYT_RT5640_IN1_MAP | + BYT_RT5640_MCLK_EN), }, { .callback = byt_rt5640_quirk_cb, @@ -385,12 +372,11 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"), }, - .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP | - BYT_RT5640_MONO_SPEAKER | - BYT_RT5640_DIFF_MIC | - BYT_RT5640_SSP0_AIF2 | - BYT_RT5640_MCLK_EN - ), + .driver_data = (void *)(BYT_RT5640_IN1_MAP | + BYT_RT5640_MONO_SPEAKER | + BYT_RT5640_DIFF_MIC | + BYT_RT5640_SSP0_AIF2 | + BYT_RT5640_MCLK_EN), }, { .callback = byt_rt5640_quirk_cb, @@ -398,9 +384,9 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "DellInc."), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"), }, - .driver_data = (unsigned long *)(BYT_RT5640_DMIC2_MAP | - BYT_RT5640_DMIC_EN | - BYT_RT5640_MCLK_EN), + .driver_data = (void *)(BYT_RT5640_DMIC2_MAP | + BYT_RT5640_DMIC_EN | + BYT_RT5640_MCLK_EN), }, { .callback = byt_rt5640_quirk_cb, @@ -408,8 +394,8 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"), }, - .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP | - BYT_RT5640_MCLK_EN), + .driver_data = (void *)(BYT_RT5640_IN1_MAP | + BYT_RT5640_MCLK_EN), }, { .callback = byt_rt5640_quirk_cb, @@ -417,8 +403,8 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"), DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"), }, - .driver_data = (unsigned long *)(BYT_RT5640_DMIC1_MAP | - BYT_RT5640_DMIC_EN), + .driver_data = (void *)(BYT_RT5640_DMIC1_MAP | + BYT_RT5640_DMIC_EN), }, { .callback = byt_rt5640_quirk_cb, @@ -426,9 +412,9 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"), DMI_MATCH(DMI_BOARD_NAME, "tPAD"), }, - .driver_data = (unsigned long *)(BYT_RT5640_IN3_MAP | - BYT_RT5640_MCLK_EN | - BYT_RT5640_SSP0_AIF1), + .driver_data = (void *)(BYT_RT5640_IN3_MAP | + BYT_RT5640_MCLK_EN | + BYT_RT5640_SSP0_AIF1), }, { .callback = byt_rt5640_quirk_cb, @@ -436,7 +422,7 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"), DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"), }, - .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP | + .driver_data = (void *)(BYT_RT5640_IN1_MAP | BYT_RT5640_MCLK_EN | BYT_RT5640_SSP0_AIF1), @@ -446,9 +432,9 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), }, - .driver_data = (unsigned long *)(BYT_RT5640_IN3_MAP | - BYT_RT5640_MCLK_EN | - BYT_RT5640_SSP0_AIF1), + .driver_data = (void *)(BYT_RT5640_IN3_MAP | + BYT_RT5640_MCLK_EN | + BYT_RT5640_SSP0_AIF1), }, {} @@ -456,12 +442,12 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) { - int ret; - struct snd_soc_codec *codec = runtime->codec; struct snd_soc_card *card = runtime->card; - const struct snd_soc_dapm_route *custom_map; struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card); + struct snd_soc_codec *codec = runtime->codec; + const struct snd_soc_dapm_route *custom_map; int num_routes; + int ret; card->dapm.idle_bias_off = true; @@ -549,7 +535,7 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone"); snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker"); - if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk) { + if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) { /* * The firmware might enable the clock at * boot (this information may or may not @@ -693,18 +679,10 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = { .dpcm_playback = 1, .ops = &byt_rt5640_aif1_ops, }, - [MERR_DPCM_COMPR] = { - .name = "Baytrail Compressed Port", - .stream_name = "Baytrail Compress", - .cpu_dai_name = "compress-cpu-dai", - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .platform_name = "sst-mfld-platform", - }, /* back ends */ { .name = "SSP2-Codec", - .id = 1, + .id = 0, .cpu_dai_name = "ssp2-port", /* overwritten for ssp0 routing */ .platform_name = "sst-mfld-platform", .no_pcm = 1, @@ -758,12 +736,12 @@ struct acpi_chan_package { /* ACPICA seems to require 64 bit integers */ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) { - int ret_val = 0; - struct sst_acpi_mach *mach; + struct byt_rt5640_private *priv; + struct snd_soc_acpi_mach *mach; const char *i2c_name = NULL; + int ret_val = 0; + int dai_index = 0; int i; - int dai_index; - struct byt_rt5640_private *priv; is_bytcr = false; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC); @@ -776,7 +754,6 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) snd_soc_card_set_drvdata(&byt_rt5640_card, priv); /* fix index of codec dai */ - dai_index = MERR_DPCM_COMPR + 1; for (i = 0; i < ARRAY_SIZE(byt_rt5640_dais); i++) { if (!strcmp(byt_rt5640_dais[i].codec_name, "i2c-10EC5640:00")) { dai_index = i; @@ -785,8 +762,8 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) } /* fixup codec name based on HID */ - i2c_name = sst_acpi_find_name_from_hid(mach->id); - if (i2c_name != NULL) { + i2c_name = snd_soc_acpi_find_name_from_hid(mach->id); + if (i2c_name) { snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name), "%s%s", "i2c-", i2c_name); @@ -819,7 +796,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) /* format specified: 2 64-bit integers */ struct acpi_buffer format = {sizeof("NN"), "NN"}; struct acpi_buffer state = {0, NULL}; - struct sst_acpi_package_context pkg_ctx; + struct snd_soc_acpi_package_context pkg_ctx; bool pkg_found = false; state.length = sizeof(chan_package); @@ -831,7 +808,8 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) pkg_ctx.state = &state; pkg_ctx.data_valid = false; - pkg_found = sst_acpi_find_package_from_hid(mach->id, &pkg_ctx); + pkg_found = snd_soc_acpi_find_package_from_hid(mach->id, + &pkg_ctx); if (pkg_found) { if (chan_package.aif_value == 1) { dev_info(&pdev->dev, "BIOS Routing: AIF1 connected\n"); @@ -891,7 +869,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) byt_rt5640_cpu_dai_name; } - if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && (is_valleyview())) { + if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) { priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); if (IS_ERR(priv->mclk)) { ret_val = PTR_ERR(priv->mclk); diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index 4a3516b38c2c..d955836c6870 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -21,24 +21,124 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/acpi.h> +#include <linux/clk.h> #include <linux/device.h> #include <linux/dmi.h> #include <linux/slab.h> +#include <asm/platform_sst_audio.h> #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> #include <sound/jack.h> +#include <sound/soc-acpi.h> #include "../../codecs/rt5651.h" #include "../atom/sst-atom-controls.h" +enum { + BYT_RT5651_DMIC_MAP, + BYT_RT5651_IN1_MAP, + BYT_RT5651_IN2_MAP, +}; + +#define BYT_RT5651_MAP(quirk) ((quirk) & GENMASK(7, 0)) +#define BYT_RT5651_DMIC_EN BIT(16) +#define BYT_RT5651_MCLK_EN BIT(17) +#define BYT_RT5651_MCLK_25MHZ BIT(18) + +struct byt_rt5651_private { + struct clk *mclk; + struct snd_soc_jack jack; +}; + +static unsigned long byt_rt5651_quirk = BYT_RT5651_DMIC_MAP | + BYT_RT5651_DMIC_EN | + BYT_RT5651_MCLK_EN; + +static void log_quirks(struct device *dev) +{ + if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_DMIC_MAP) + dev_info(dev, "quirk DMIC_MAP enabled"); + if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN1_MAP) + dev_info(dev, "quirk IN1_MAP enabled"); + if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN2_MAP) + dev_info(dev, "quirk IN2_MAP enabled"); + if (byt_rt5651_quirk & BYT_RT5651_DMIC_EN) + dev_info(dev, "quirk DMIC enabled"); + if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) + dev_info(dev, "quirk MCLK_EN enabled"); + if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ) + dev_info(dev, "quirk MCLK_25MHZ enabled"); +} + +#define BYT_CODEC_DAI1 "rt5651-aif1" + +static int platform_clock_control(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_dapm_context *dapm = w->dapm; + struct snd_soc_card *card = dapm->card; + struct snd_soc_dai *codec_dai; + struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card); + int ret; + + codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI1); + if (!codec_dai) { + dev_err(card->dev, + "Codec dai not found; Unable to set platform clock\n"); + return -EIO; + } + + if (SND_SOC_DAPM_EVENT_ON(event)) { + if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) { + ret = clk_prepare_enable(priv->mclk); + if (ret < 0) { + dev_err(card->dev, + "could not configure MCLK state"); + return ret; + } + } + ret = snd_soc_dai_set_sysclk(codec_dai, RT5651_SCLK_S_PLL1, + 48000 * 512, + SND_SOC_CLOCK_IN); + } else { + /* + * Set codec clock source to internal clock before + * turning off the platform clock. Codec needs clock + * for Jack detection and button press + */ + ret = snd_soc_dai_set_sysclk(codec_dai, RT5651_SCLK_S_RCCLK, + 48000 * 512, + SND_SOC_CLOCK_IN); + if (!ret) + if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) + clk_disable_unprepare(priv->mclk); + } + + if (ret < 0) { + dev_err(card->dev, "can't set codec sysclk: %d\n", ret); + return ret; + } + + return 0; +} + static const struct snd_soc_dapm_widget byt_rt5651_widgets[] = { SND_SOC_DAPM_HP("Headphone", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), SND_SOC_DAPM_MIC("Internal Mic", NULL), SND_SOC_DAPM_SPK("Speaker", 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), + }; static const struct snd_soc_dapm_route byt_rt5651_audio_map[] = { + {"Headphone", NULL, "Platform Clock"}, + {"Headset Mic", NULL, "Platform Clock"}, + {"Internal Mic", NULL, "Platform Clock"}, + {"Speaker", NULL, "Platform Clock"}, + {"AIF1 Playback", NULL, "ssp2 Tx"}, {"ssp2 Tx", NULL, "codec_out0"}, {"ssp2 Tx", NULL, "codec_out1"}, @@ -47,38 +147,30 @@ static const struct snd_soc_dapm_route byt_rt5651_audio_map[] = { {"ssp2 Rx", NULL, "AIF1 Capture"}, {"Headset Mic", NULL, "micbias1"}, /* lowercase for rt5651 */ - {"IN2P", NULL, "Headset Mic"}, {"Headphone", NULL, "HPOL"}, {"Headphone", NULL, "HPOR"}, {"Speaker", NULL, "LOUTL"}, {"Speaker", NULL, "LOUTR"}, }; -static const struct snd_soc_dapm_route byt_rt5651_intmic_dmic1_map[] = { - {"DMIC1", NULL, "Internal Mic"}, -}; - -static const struct snd_soc_dapm_route byt_rt5651_intmic_dmic2_map[] = { - {"DMIC2", NULL, "Internal Mic"}, +static const struct snd_soc_dapm_route byt_rt5651_intmic_dmic_map[] = { + {"IN2P", NULL, "Headset Mic"}, + {"DMIC L1", NULL, "Internal Mic"}, + {"DMIC R1", NULL, "Internal Mic"}, }; static const struct snd_soc_dapm_route byt_rt5651_intmic_in1_map[] = { {"Internal Mic", NULL, "micbias1"}, + {"IN2P", NULL, "Headset Mic"}, {"IN1P", NULL, "Internal Mic"}, }; -enum { - BYT_RT5651_DMIC1_MAP, - BYT_RT5651_DMIC2_MAP, - BYT_RT5651_IN1_MAP, +static const struct snd_soc_dapm_route byt_rt5651_intmic_in2_map[] = { + {"Internal Mic", NULL, "micbias1"}, + {"IN1P", NULL, "Headset Mic"}, + {"IN2P", NULL, "Internal Mic"}, }; -#define BYT_RT5651_MAP(quirk) ((quirk) & 0xff) -#define BYT_RT5651_DMIC_EN BIT(16) - -static unsigned long byt_rt5651_quirk = BYT_RT5651_DMIC1_MAP | - BYT_RT5651_DMIC_EN; - static const struct snd_kcontrol_new byt_rt5651_controls[] = { SOC_DAPM_PIN_SWITCH("Headphone"), SOC_DAPM_PIN_SWITCH("Headset Mic"), @@ -86,6 +178,17 @@ static const struct snd_kcontrol_new byt_rt5651_controls[] = { SOC_DAPM_PIN_SWITCH("Speaker"), }; +static struct snd_soc_jack_pin bytcr_jack_pins[] = { + { + .pin = "Headphone", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + static int byt_rt5651_aif1_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -103,9 +206,26 @@ static int byt_rt5651_aif1_hw_params(struct snd_pcm_substream *substream, return ret; } - ret = snd_soc_dai_set_pll(codec_dai, 0, RT5651_PLL1_S_BCLK1, - params_rate(params) * 50, - params_rate(params) * 512); + if (!(byt_rt5651_quirk & BYT_RT5651_MCLK_EN)) { + /* 2x25 bit slots on SSP2 */ + ret = snd_soc_dai_set_pll(codec_dai, 0, + RT5651_PLL1_S_BCLK1, + params_rate(params) * 50, + params_rate(params) * 512); + } else { + if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ) { + ret = snd_soc_dai_set_pll(codec_dai, 0, + RT5651_PLL1_S_MCLK, + 25000000, + params_rate(params) * 512); + } else { + ret = snd_soc_dai_set_pll(codec_dai, 0, + RT5651_PLL1_S_MCLK, + 19200000, + params_rate(params) * 512); + } + } + if (ret < 0) { dev_err(rtd->dev, "can't set codec pll: %d\n", ret); return ret; @@ -114,33 +234,60 @@ static int byt_rt5651_aif1_hw_params(struct snd_pcm_substream *substream, return 0; } +static int byt_rt5651_quirk_cb(const struct dmi_system_id *id) +{ + byt_rt5651_quirk = (unsigned long)id->driver_data; + return 1; +} + static const struct dmi_system_id byt_rt5651_quirk_table[] = { + { + .callback = byt_rt5651_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"), + DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"), + }, + .driver_data = (void *)(BYT_RT5651_DMIC_MAP | + BYT_RT5651_DMIC_EN), + }, + { + .callback = byt_rt5651_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "KIANO"), + DMI_MATCH(DMI_PRODUCT_NAME, "KIANO SlimNote 14.2"), + }, + .driver_data = (void *)(BYT_RT5651_IN2_MAP), + }, {} }; static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime) { - int ret; struct snd_soc_card *card = runtime->card; + struct snd_soc_codec *codec = runtime->codec; + struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card); const struct snd_soc_dapm_route *custom_map; int num_routes; + int ret; card->dapm.idle_bias_off = true; - dmi_check_system(byt_rt5651_quirk_table); switch (BYT_RT5651_MAP(byt_rt5651_quirk)) { case BYT_RT5651_IN1_MAP: custom_map = byt_rt5651_intmic_in1_map; num_routes = ARRAY_SIZE(byt_rt5651_intmic_in1_map); break; - case BYT_RT5651_DMIC2_MAP: - custom_map = byt_rt5651_intmic_dmic2_map; - num_routes = ARRAY_SIZE(byt_rt5651_intmic_dmic2_map); + case BYT_RT5651_IN2_MAP: + custom_map = byt_rt5651_intmic_in2_map; + num_routes = ARRAY_SIZE(byt_rt5651_intmic_in2_map); break; default: - custom_map = byt_rt5651_intmic_dmic1_map; - num_routes = ARRAY_SIZE(byt_rt5651_intmic_dmic1_map); + custom_map = byt_rt5651_intmic_dmic_map; + num_routes = ARRAY_SIZE(byt_rt5651_intmic_dmic_map); } + ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); + if (ret) + return ret; ret = snd_soc_add_card_controls(card, byt_rt5651_controls, ARRAY_SIZE(byt_rt5651_controls)); @@ -151,6 +298,40 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime) snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone"); snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker"); + if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) { + /* + * The firmware might enable the clock at + * boot (this information may or may not + * be reflected in the enable clock register). + * To change the rate we must disable the clock + * first to cover these cases. Due to common + * clock framework restrictions that do not allow + * to disable a clock that has not been enabled, + * we need to enable the clock first. + */ + ret = clk_prepare_enable(priv->mclk); + if (!ret) + clk_disable_unprepare(priv->mclk); + + if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ) + ret = clk_set_rate(priv->mclk, 25000000); + else + ret = clk_set_rate(priv->mclk, 19200000); + + if (ret) + dev_err(card->dev, "unable to set MCLK rate\n"); + } + + ret = snd_soc_card_jack_new(runtime->card, "Headset", + SND_JACK_HEADSET, &priv->jack, + bytcr_jack_pins, ARRAY_SIZE(bytcr_jack_pins)); + if (ret) { + dev_err(runtime->dev, "Headset jack creation failed %d\n", ret); + return ret; + } + + rt5651_set_jack_detect(codec, &priv->jack); + return ret; } @@ -253,19 +434,11 @@ static struct snd_soc_dai_link byt_rt5651_dais[] = { .dpcm_playback = 1, .ops = &byt_rt5651_aif1_ops, }, - [MERR_DPCM_COMPR] = { - .name = "Compressed Port", - .stream_name = "Compress", - .cpu_dai_name = "compress-cpu-dai", - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .platform_name = "sst-mfld-platform", - }, /* CODEC<->CODEC link */ /* back ends */ { .name = "SSP2-Codec", - .id = 1, + .id = 0, .cpu_dai_name = "ssp2-port", .platform_name = "sst-mfld-platform", .no_pcm = 1, @@ -296,13 +469,65 @@ static struct snd_soc_card byt_rt5651_card = { .fully_routed = true, }; +static char byt_rt5651_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */ + static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) { + struct byt_rt5651_private *priv; + struct snd_soc_acpi_mach *mach; + const char *i2c_name = NULL; int ret_val = 0; + int dai_index = 0; + int i; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC); + if (!priv) + return -ENOMEM; /* register the soc card */ byt_rt5651_card.dev = &pdev->dev; + mach = byt_rt5651_card.dev->platform_data; + snd_soc_card_set_drvdata(&byt_rt5651_card, priv); + + /* fix index of codec dai */ + for (i = 0; i < ARRAY_SIZE(byt_rt5651_dais); i++) { + if (!strcmp(byt_rt5651_dais[i].codec_name, "i2c-10EC5651:00")) { + dai_index = i; + break; + } + } + + /* fixup codec name based on HID */ + i2c_name = snd_soc_acpi_find_name_from_hid(mach->id); + if (i2c_name) { + snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name), + "%s%s", "i2c-", i2c_name); + + byt_rt5651_dais[dai_index].codec_name = byt_rt5651_codec_name; + } + + /* check quirks before creating card */ + dmi_check_system(byt_rt5651_quirk_table); + log_quirks(&pdev->dev); + + if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) { + priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); + if (IS_ERR(priv->mclk)) { + dev_err(&pdev->dev, + "Failed to get MCLK from pmc_plt_clk_3: %ld\n", + PTR_ERR(priv->mclk)); + /* + * Fall back to bit clock usage for -ENOENT (clock not + * available likely due to missing dependencies), bail + * for all other errors, including -EPROBE_DEFER + */ + if (ret_val != -ENOENT) + return ret_val; + byt_rt5651_quirk &= ~BYT_RT5651_MCLK_EN; + } + } + ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5651_card); if (ret_val) { diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c index 20755ecc7f9e..d3e1c7e12004 100644 --- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c +++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c @@ -23,6 +23,7 @@ #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/acpi.h> +#include <linux/clk.h> #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> @@ -35,15 +36,48 @@ #define CHT_CODEC_DAI "HiFi" struct cht_mc_private { + struct clk *mclk; struct snd_soc_jack jack; bool ts3a227e_present; }; +static int platform_clock_control(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + struct snd_soc_dapm_context *dapm = w->dapm; + struct snd_soc_card *card = dapm->card; + struct snd_soc_dai *codec_dai; + struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card); + int ret; + + codec_dai = snd_soc_card_get_codec_dai(card, CHT_CODEC_DAI); + if (!codec_dai) { + dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n"); + return -EIO; + } + + if (SND_SOC_DAPM_EVENT_ON(event)) { + ret = clk_prepare_enable(ctx->mclk); + if (ret < 0) { + dev_err(card->dev, + "could not configure MCLK state"); + return ret; + } + } else { + clk_disable_unprepare(ctx->mclk); + } + + return 0; +} + static const struct snd_soc_dapm_widget cht_dapm_widgets[] = { SND_SOC_DAPM_HP("Headphone", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), SND_SOC_DAPM_MIC("Int Mic", NULL), SND_SOC_DAPM_SPK("Ext Spk", 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), }; static const struct snd_soc_dapm_route cht_audio_map[] = { @@ -60,6 +94,10 @@ static const struct snd_soc_dapm_route cht_audio_map[] = { {"codec_in0", NULL, "ssp2 Rx" }, {"codec_in1", NULL, "ssp2 Rx" }, {"ssp2 Rx", NULL, "HiFi 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[] = { @@ -109,6 +147,40 @@ static struct notifier_block cht_jack_nb = { .notifier_call = cht_ti_jack_event, }; +static struct snd_soc_jack_pin hs_jack_pins[] = { + { + .pin = "Headphone", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + +static struct snd_soc_jack_gpio hs_jack_gpios[] = { + { + .name = "hp", + .report = SND_JACK_HEADPHONE | SND_JACK_LINEOUT, + .debounce_time = 200, + }, + { + .name = "mic", + .invert = 1, + .report = SND_JACK_MICROPHONE, + .debounce_time = 200, + }, +}; + +static const struct acpi_gpio_params hp_gpios = { 0, 0, false }; +static const struct acpi_gpio_params mic_gpios = { 1, 0, false }; + +static const struct acpi_gpio_mapping acpi_max98090_gpios[] = { + { "hp-gpios", &hp_gpios, 1 }, + { "mic-gpios", &mic_gpios, 1 }, + {}, +}; + static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) { int ret; @@ -116,30 +188,55 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); struct snd_soc_jack *jack = &ctx->jack; - /** - * TI supports 4 butons headset detection - * KEY_MEDIA - * KEY_VOICECOMMAND - * KEY_VOLUMEUP - * KEY_VOLUMEDOWN - */ - if (ctx->ts3a227e_present) - jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE | - SND_JACK_BTN_0 | SND_JACK_BTN_1 | - SND_JACK_BTN_2 | SND_JACK_BTN_3; - else - jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE; + if (ctx->ts3a227e_present) { + /* + * The jack has already been created in the + * cht_max98090_headset_init() function. + */ + snd_soc_jack_notifier_register(jack, &cht_jack_nb); + return 0; + } - ret = snd_soc_card_jack_new(runtime->card, "Headset Jack", - jack_type, jack, NULL, 0); + jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE; + ret = snd_soc_card_jack_new(runtime->card, "Headset Jack", + jack_type, jack, + hs_jack_pins, ARRAY_SIZE(hs_jack_pins)); if (ret) { dev_err(runtime->dev, "Headset Jack creation failed %d\n", ret); return ret; } - if (ctx->ts3a227e_present) - snd_soc_jack_notifier_register(jack, &cht_jack_nb); + ret = snd_soc_jack_add_gpiods(runtime->card->dev->parent, jack, + ARRAY_SIZE(hs_jack_gpios), + hs_jack_gpios); + if (ret) { + /* + * flag error but don't bail if jack detect is broken + * due to platform issues or bad BIOS/configuration + */ + dev_err(runtime->dev, + "jack detection gpios not added, error %d\n", ret); + } + + /* + * The firmware might enable the clock at + * boot (this information may or may not + * be reflected in the enable clock register). + * To change the rate we must disable the clock + * first to cover these cases. Due to common + * clock framework restrictions that do not allow + * to disable a clock that has not been enabled, + * we need to enable the clock first. + */ + ret = clk_prepare_enable(ctx->mclk); + if (!ret) + clk_disable_unprepare(ctx->mclk); + + ret = clk_set_rate(ctx->mclk, CHT_PLAT_CLK_3_HZ); + + if (ret) + dev_err(runtime->dev, "unable to set MCLK rate\n"); return ret; } @@ -160,7 +257,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } - fmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF + fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; ret = snd_soc_dai_set_fmt(rtd->cpu_dai, fmt); @@ -173,8 +270,8 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, rate->min = rate->max = 48000; channels->min = channels->max = 2; - /* set SSP2 to 24-bit */ - params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); + /* set SSP2 to 16-bit */ + params_set_format(params, SNDRV_PCM_FORMAT_S16_LE); return 0; } @@ -188,8 +285,29 @@ static int cht_max98090_headset_init(struct snd_soc_component *component) { struct snd_soc_card *card = component->card; struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card); + struct snd_soc_jack *jack = &ctx->jack; + int jack_type; + int ret; - return ts3a227e_enable_jack_detect(component, &ctx->jack); + /* + * TI supports 4 butons headset detection + * KEY_MEDIA + * KEY_VOICECOMMAND + * KEY_VOLUMEUP + * KEY_VOLUMEDOWN + */ + jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE | + 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", jack_type, + jack, NULL, 0); + if (ret) { + dev_err(card->dev, "Headset Jack creation failed %d\n", ret); + return ret; + } + + return ts3a227e_enable_jack_detect(component, jack); } static const struct snd_soc_ops cht_aif1_ops = { @@ -232,18 +350,10 @@ static struct snd_soc_dai_link cht_dailink[] = { .dpcm_playback = 1, .ops = &cht_aif1_ops, }, - [MERR_DPCM_COMPR] = { - .name = "Compressed Port", - .stream_name = "Compress", - .cpu_dai_name = "compress-cpu-dai", - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .platform_name = "sst-mfld-platform", - }, /* back ends */ { .name = "SSP2-Codec", - .id = 1, + .id = 0, .cpu_dai_name = "ssp2-port", .platform_name = "sst-mfld-platform", .no_pcm = 1, @@ -277,6 +387,7 @@ static struct snd_soc_card snd_soc_card_cht = { static int snd_cht_mc_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; int ret_val = 0; struct cht_mc_private *drv; @@ -289,11 +400,25 @@ static int snd_cht_mc_probe(struct platform_device *pdev) /* no need probe TI jack detection chip */ snd_soc_card_cht.aux_dev = NULL; snd_soc_card_cht.num_aux_devs = 0; + + ret_val = devm_acpi_dev_add_driver_gpios(dev->parent, + acpi_max98090_gpios); + if (ret_val) + dev_dbg(dev, "Unable to add GPIO mapping table\n"); } /* register the soc card */ snd_soc_card_cht.dev = &pdev->dev; snd_soc_card_set_drvdata(&snd_soc_card_cht, drv); + + drv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); + if (IS_ERR(drv->mclk)) { + dev_err(&pdev->dev, + "Failed to get MCLK from pmc_plt_clk_3: %ld\n", + PTR_ERR(drv->mclk)); + return PTR_ERR(drv->mclk); + } + ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_cht); if (ret_val) { dev_err(&pdev->dev, diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c index 5bcde01d15e6..18d129caa974 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5645.c +++ b/sound/soc/intel/boards/cht_bsw_rt5645.c @@ -21,20 +21,20 @@ */ #include <linux/module.h> -#include <linux/acpi.h> #include <linux/platform_device.h> +#include <linux/acpi.h> +#include <linux/clk.h> #include <linux/dmi.h> #include <linux/slab.h> #include <asm/cpu_device_id.h> #include <asm/platform_sst_audio.h> -#include <linux/clk.h> #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> #include <sound/jack.h> +#include <sound/soc-acpi.h> #include "../../codecs/rt5645.h" #include "../atom/sst-atom-controls.h" -#include "../common/sst-acpi.h" #define CHT_PLAT_CLK_3_HZ 19200000 #define CHT_CODEC_DAI1 "rt5645-aif1" @@ -53,7 +53,7 @@ struct cht_mc_private { struct clk *mclk; }; -#define CHT_RT5645_MAP(quirk) ((quirk) & 0xff) +#define CHT_RT5645_MAP(quirk) ((quirk) & GENMASK(7, 0)) #define CHT_RT5645_SSP2_AIF2 BIT(16) /* default is using AIF1 */ #define CHT_RT5645_SSP0_AIF1 BIT(17) #define CHT_RT5645_SSP0_AIF2 BIT(18) @@ -70,21 +70,6 @@ static void log_quirks(struct device *dev) dev_info(dev, "quirk SSP0_AIF2 enabled"); } -static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card) -{ - struct snd_soc_pcm_runtime *rtd; - - list_for_each_entry(rtd, &card->rtd_list, list) { - if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI1, - strlen(CHT_CODEC_DAI1))) - return rtd->codec_dai; - if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI2, - strlen(CHT_CODEC_DAI2))) - return rtd->codec_dai; - } - return NULL; -} - static int platform_clock_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { @@ -94,20 +79,21 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card); int ret; - codec_dai = cht_get_codec_dai(card); + codec_dai = snd_soc_card_get_codec_dai(card, CHT_CODEC_DAI1); + if (!codec_dai) + codec_dai = snd_soc_card_get_codec_dai(card, CHT_CODEC_DAI2); + if (!codec_dai) { dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n"); return -EIO; } if (SND_SOC_DAPM_EVENT_ON(event)) { - if (ctx->mclk) { - ret = clk_prepare_enable(ctx->mclk); - if (ret < 0) { - dev_err(card->dev, - "could not configure MCLK state"); - return ret; - } + ret = clk_prepare_enable(ctx->mclk); + if (ret < 0) { + dev_err(card->dev, + "could not configure MCLK state"); + return ret; } } else { /* Set codec sysclk source to its internal clock because codec PLL will @@ -122,8 +108,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, return ret; } - if (ctx->mclk) - clk_disable_unprepare(ctx->mclk); + clk_disable_unprepare(ctx->mclk); } return 0; @@ -258,11 +243,11 @@ static const struct dmi_system_id cht_rt5645_quirk_table[] = { static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) { - int ret; - int jack_type; - struct snd_soc_codec *codec = runtime->codec; struct snd_soc_card *card = runtime->card; struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); + struct snd_soc_codec *codec = runtime->codec; + int jack_type; + int ret; if ((cht_rt5645_quirk & CHT_RT5645_SSP2_AIF2) || (cht_rt5645_quirk & CHT_RT5645_SSP0_AIF2)) { @@ -320,26 +305,26 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) rt5645_set_jack_detect(codec, &ctx->jack, &ctx->jack, &ctx->jack); - if (ctx->mclk) { - /* - * The firmware might enable the clock at - * boot (this information may or may not - * be reflected in the enable clock register). - * To change the rate we must disable the clock - * first to cover these cases. Due to common - * clock framework restrictions that do not allow - * to disable a clock that has not been enabled, - * we need to enable the clock first. - */ - ret = clk_prepare_enable(ctx->mclk); - if (!ret) - clk_disable_unprepare(ctx->mclk); - ret = clk_set_rate(ctx->mclk, CHT_PLAT_CLK_3_HZ); + /* + * The firmware might enable the clock at + * boot (this information may or may not + * be reflected in the enable clock register). + * To change the rate we must disable the clock + * first to cover these cases. Due to common + * clock framework restrictions that do not allow + * to disable a clock that has not been enabled, + * we need to enable the clock first. + */ + ret = clk_prepare_enable(ctx->mclk); + if (!ret) + clk_disable_unprepare(ctx->mclk); + + ret = clk_set_rate(ctx->mclk, CHT_PLAT_CLK_3_HZ); + + if (ret) + dev_err(runtime->dev, "unable to set MCLK rate\n"); - if (ret) - dev_err(runtime->dev, "unable to set MCLK rate\n"); - } return ret; } @@ -460,19 +445,11 @@ static struct snd_soc_dai_link cht_dailink[] = { .dpcm_playback = 1, .ops = &cht_aif1_ops, }, - [MERR_DPCM_COMPR] = { - .name = "Compressed Port", - .stream_name = "Compress", - .cpu_dai_name = "compress-cpu-dai", - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .platform_name = "sst-mfld-platform", - }, /* CODEC<->CODEC link */ /* back ends */ { .name = "SSP2-Codec", - .id = 1, + .id = 0, .cpu_dai_name = "ssp2-port", .platform_name = "sst-mfld-platform", .no_pcm = 1, @@ -545,15 +522,15 @@ struct acpi_chan_package { /* ACPICA seems to require 64 bit integers */ static int snd_cht_mc_probe(struct platform_device *pdev) { - int ret_val = 0; - int i; - struct cht_mc_private *drv; struct snd_soc_card *card = snd_soc_cards[0].soc_card; - struct sst_acpi_mach *mach; + struct snd_soc_acpi_mach *mach; + struct cht_mc_private *drv; const char *i2c_name = NULL; - int dai_index = 0; bool found = false; bool is_bytcr = false; + int dai_index = 0; + int ret_val = 0; + int i; drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC); if (!drv) @@ -589,8 +566,8 @@ static int snd_cht_mc_probe(struct platform_device *pdev) } /* fixup codec name based on HID */ - i2c_name = sst_acpi_find_name_from_hid(mach->id); - if (i2c_name != NULL) { + i2c_name = snd_soc_acpi_find_name_from_hid(mach->id); + if (i2c_name) { snprintf(cht_rt5645_codec_name, sizeof(cht_rt5645_codec_name), "%s%s", "i2c-", i2c_name); cht_dailink[dai_index].codec_name = cht_rt5645_codec_name; @@ -622,7 +599,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev) /* format specified: 2 64-bit integers */ struct acpi_buffer format = {sizeof("NN"), "NN"}; struct acpi_buffer state = {0, NULL}; - struct sst_acpi_package_context pkg_ctx; + struct snd_soc_acpi_package_context pkg_ctx; bool pkg_found = false; state.length = sizeof(chan_package); @@ -634,7 +611,8 @@ static int snd_cht_mc_probe(struct platform_device *pdev) pkg_ctx.state = &state; pkg_ctx.data_valid = false; - pkg_found = sst_acpi_find_package_from_hid(mach->id, &pkg_ctx); + pkg_found = snd_soc_acpi_find_package_from_hid(mach->id, + &pkg_ctx); if (pkg_found) { if (chan_package.aif_value == 1) { dev_info(&pdev->dev, "BIOS Routing: AIF1 connected\n"); @@ -682,14 +660,12 @@ static int snd_cht_mc_probe(struct platform_device *pdev) cht_rt5645_cpu_dai_name; } - if (is_valleyview()) { - drv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); - if (IS_ERR(drv->mclk)) { - dev_err(&pdev->dev, - "Failed to get MCLK from pmc_plt_clk_3: %ld\n", - PTR_ERR(drv->mclk)); - return PTR_ERR(drv->mclk); - } + drv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); + if (IS_ERR(drv->mclk)) { + dev_err(&pdev->dev, + "Failed to get MCLK from pmc_plt_clk_3: %ld\n", + PTR_ERR(drv->mclk)); + return PTR_ERR(drv->mclk); } snd_soc_card_set_drvdata(card, drv); diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c index bc2a52de06a3..f8f21eee9b2d 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5672.c +++ b/sound/soc/intel/boards/cht_bsw_rt5672.c @@ -20,14 +20,14 @@ #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/clk.h> -#include <asm/cpu_device_id.h> #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> #include <sound/jack.h> +#include <sound/soc-acpi.h> #include "../../codecs/rt5670.h" #include "../atom/sst-atom-controls.h" -#include "../common/sst-acpi.h" + /* The platform clock #3 outputs 19.2Mhz clock to codec as I2S MCLK */ #define CHT_PLAT_CLK_3_HZ 19200000 @@ -51,18 +51,6 @@ static struct snd_soc_jack_pin cht_bsw_headset_pins[] = { }, }; -static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card) -{ - struct snd_soc_pcm_runtime *rtd; - - list_for_each_entry(rtd, &card->rtd_list, list) { - if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI, - strlen(CHT_CODEC_DAI))) - return rtd->codec_dai; - } - return NULL; -} - static int platform_clock_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { @@ -72,7 +60,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card); int ret; - codec_dai = cht_get_codec_dai(card); + codec_dai = snd_soc_card_get_codec_dai(card, CHT_CODEC_DAI); if (!codec_dai) { dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n"); return -EIO; @@ -184,6 +172,13 @@ static int cht_aif1_hw_params(struct snd_pcm_substream *substream, return 0; } +static const struct acpi_gpio_params headset_gpios = { 0, 0, false }; + +static const struct acpi_gpio_mapping cht_rt5672_gpios[] = { + { "headset-gpios", &headset_gpios, 1 }, + {}, +}; + static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) { int ret; @@ -191,6 +186,9 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) struct snd_soc_codec *codec = codec_dai->codec; struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); + if (devm_acpi_dev_add_driver_gpios(codec->dev, cht_rt5672_gpios)) + dev_warn(runtime->dev, "Unable to add GPIO mapping table\n"); + /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */ ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF, 0xF, 4, 24); if (ret < 0) { @@ -305,20 +303,12 @@ static struct snd_soc_dai_link cht_dailink[] = { .dpcm_playback = 1, .ops = &cht_aif1_ops, }, - [MERR_DPCM_COMPR] = { - .name = "Compressed Port", - .stream_name = "Compress", - .cpu_dai_name = "compress-cpu-dai", - .codec_dai_name = "snd-soc-dummy-dai", - .codec_name = "snd-soc-dummy", - .platform_name = "sst-mfld-platform", - }, /* Back End DAI links */ { /* SSP2 - Codec */ .name = "SSP2-Codec", - .id = 1, + .id = 0, .cpu_dai_name = "ssp2-port", .platform_name = "sst-mfld-platform", .no_pcm = 1, @@ -338,9 +328,11 @@ static struct snd_soc_dai_link cht_dailink[] = { static int cht_suspend_pre(struct snd_soc_card *card) { struct snd_soc_component *component; + struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card); list_for_each_entry(component, &card->component_dev_list, card_list) { - if (!strcmp(component->name, "i2c-10EC5670:00")) { + if (!strncmp(component->name, + ctx->codec_name, sizeof(ctx->codec_name))) { struct snd_soc_codec *codec = snd_soc_component_to_codec(component); dev_dbg(codec->dev, "disabling jack detect before going to suspend.\n"); @@ -354,9 +346,11 @@ static int cht_suspend_pre(struct snd_soc_card *card) static int cht_resume_post(struct snd_soc_card *card) { struct snd_soc_component *component; + struct cht_mc_private *ctx = snd_soc_card_get_drvdata(card); list_for_each_entry(component, &card->component_dev_list, card_list) { - if (!strcmp(component->name, "i2c-10EC5670:00")) { + if (!strncmp(component->name, + ctx->codec_name, sizeof(ctx->codec_name))) { struct snd_soc_codec *codec = snd_soc_component_to_codec(component); dev_dbg(codec->dev, "enabling jack detect for resume.\n"); @@ -370,7 +364,7 @@ static int cht_resume_post(struct snd_soc_card *card) /* SoC card */ static struct snd_soc_card snd_soc_card_cht = { - .name = "cherrytrailcraudio", + .name = "cht-bsw-rt5672", .owner = THIS_MODULE, .dai_link = cht_dailink, .num_links = ARRAY_SIZE(cht_dailink), @@ -384,25 +378,13 @@ static struct snd_soc_card snd_soc_card_cht = { .resume_post = cht_resume_post, }; -static bool is_valleyview(void) -{ - static const struct x86_cpu_id cpu_ids[] = { - { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */ - {} - }; - - if (!x86_match_cpu(cpu_ids)) - return false; - return true; -} - #define RT5672_I2C_DEFAULT "i2c-10EC5670:00" static int snd_cht_mc_probe(struct platform_device *pdev) { int ret_val = 0; struct cht_mc_private *drv; - struct sst_acpi_mach *mach = pdev->dev.platform_data; + struct snd_soc_acpi_mach *mach = pdev->dev.platform_data; const char *i2c_name; int i; @@ -414,7 +396,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev) /* fixup codec name based on HID */ if (mach) { - i2c_name = sst_acpi_find_name_from_hid(mach->id); + i2c_name = snd_soc_acpi_find_name_from_hid(mach->id); if (i2c_name) { snprintf(drv->codec_name, sizeof(drv->codec_name), "i2c-%s", i2c_name); @@ -429,14 +411,12 @@ static int snd_cht_mc_probe(struct platform_device *pdev) } } - if (is_valleyview()) { - drv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); - if (IS_ERR(drv->mclk)) { - dev_err(&pdev->dev, - "Failed to get MCLK from pmc_plt_clk_3: %ld\n", - PTR_ERR(drv->mclk)); - return PTR_ERR(drv->mclk); - } + drv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); + if (IS_ERR(drv->mclk)) { + dev_err(&pdev->dev, + "Failed to get MCLK from pmc_plt_clk_3: %ld\n", + PTR_ERR(drv->mclk)); + return PTR_ERR(drv->mclk); } snd_soc_card_set_drvdata(&snd_soc_card_cht, drv); diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c b/sound/soc/intel/boards/kbl_rt5663_max98927.c index f9ba97788157..6f9a8bcf20f3 100644 --- a/sound/soc/intel/boards/kbl_rt5663_max98927.c +++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c @@ -17,6 +17,7 @@ * GNU General Public License for more details. */ +#include <linux/input.h> #include <linux/module.h> #include <linux/platform_device.h> #include <sound/core.h> @@ -34,7 +35,7 @@ #define MAXIM_DEV0_NAME "i2c-MX98927:00" #define MAXIM_DEV1_NAME "i2c-MX98927:01" -static struct snd_soc_card kabylake_audio_card; +static struct snd_soc_card *kabylake_audio_card; static const struct snd_pcm_hw_constraint_list *dmic_constraints; static struct snd_soc_jack skylake_hdmi[3]; @@ -52,6 +53,8 @@ struct kbl_rt5663_private { enum { KBL_DPCM_AUDIO_PB = 0, KBL_DPCM_AUDIO_CP, + KBL_DPCM_AUDIO_HS_PB, + KBL_DPCM_AUDIO_ECHO_REF_CP, KBL_DPCM_AUDIO_REF_CP, KBL_DPCM_AUDIO_DMIC_CP, KBL_DPCM_AUDIO_HDMI1_PB, @@ -72,8 +75,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), }; @@ -91,20 +95,22 @@ static const struct snd_soc_dapm_route kabylake_map[] = { { "IN1N", NULL, "Headset Mic" }, { "DMic", NULL, "SoC DMIC" }, - { "HDMI", NULL, "hif5 Output" }, - { "DP", NULL, "hif6 Output" }, - /* CODEC BE connections */ { "Left HiFi Playback", NULL, "ssp0 Tx" }, { "Right HiFi Playback", NULL, "ssp0 Tx" }, - { "ssp0 Tx", NULL, "codec0_out" }, + { "ssp0 Tx", NULL, "spk_out" }, { "AIF Playback", NULL, "ssp1 Tx" }, - { "ssp1 Tx", NULL, "codec1_out" }, + { "ssp1 Tx", NULL, "hs_out" }, - { "codec0_in", NULL, "ssp1 Rx" }, + { "hs_in", NULL, "ssp1 Rx" }, { "ssp1 Rx", NULL, "AIF Capture" }, + /* IV feedback path */ + { "codec0_fb_in", NULL, "ssp0 Rx"}, + { "ssp0 Rx", NULL, "Left HiFi Capture" }, + { "ssp0 Rx", NULL, "Right HiFi Capture" }, + /* DMIC */ { "dmic01_hifi", NULL, "DMIC01 Rx" }, { "DMIC01 Rx", NULL, "DMIC AIF" }, @@ -117,6 +123,49 @@ static const struct snd_soc_dapm_route kabylake_map[] = { { "iDisp1 Tx", NULL, "iDisp1_out"}, }; +enum { + KBL_DPCM_AUDIO_5663_PB = 0, + KBL_DPCM_AUDIO_5663_CP, + KBL_DPCM_AUDIO_5663_HDMI1_PB, + KBL_DPCM_AUDIO_5663_HDMI2_PB, +}; + +static const struct snd_kcontrol_new kabylake_5663_controls[] = { + SOC_DAPM_PIN_SWITCH("Headphone Jack"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), +}; + +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), +}; + +static const struct snd_soc_dapm_route kabylake_5663_map[] = { + { "Headphone Jack", NULL, "HPOL" }, + { "Headphone Jack", NULL, "HPOR" }, + + /* other jacks */ + { "IN1P", NULL, "Headset Mic" }, + { "IN1N", NULL, "Headset Mic" }, + + { "HDMI", NULL, "hif5 Output" }, + { "DP", NULL, "hif6 Output" }, + + /* CODEC BE connections */ + { "AIF Playback", NULL, "ssp1 Tx" }, + { "ssp1 Tx", NULL, "codec1_out" }, + + { "codec0_in", NULL, "ssp1 Rx" }, + { "ssp1 Rx", NULL, "AIF Capture" }, + + { "hifi2", NULL, "iDisp2 Tx"}, + { "iDisp2 Tx", NULL, "iDisp2_out"}, + { "hifi1", NULL, "iDisp1 Tx"}, + { "iDisp1 Tx", NULL, "iDisp1_out"}, +}; + static struct snd_soc_codec_conf max98927_codec_conf[] = { { .dev_name = MAXIM_DEV0_NAME, @@ -160,12 +209,13 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) int ret; struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card); struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_jack *jack; /* * Headset buttons map to the google Reference headset. * These can be configured by userspace. */ - ret = snd_soc_card_jack_new(&kabylake_audio_card, "Headset Jack", + ret = snd_soc_card_jack_new(kabylake_audio_card, "Headset Jack", SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3, &ctx->kabylake_headset, NULL, 0); @@ -174,7 +224,24 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) return ret; } + jack = &ctx->kabylake_headset; + snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA); + 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); + rt5663_set_jack_detect(codec, &ctx->kabylake_headset); + return ret; +} + +static int kabylake_rt5663_max98927_codec_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret; + + ret = kabylake_rt5663_codec_init(rtd); + if (ret) + return ret; + ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); if (ret) { dev_err(rtd->dev, "SoC DMIC ignore suspend failed %d\n", ret); @@ -184,7 +251,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) return ret; } -static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) +static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device) { struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card); struct snd_soc_dai *dai = rtd->codec_dai; @@ -194,7 +261,7 @@ static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) if (!pcm) return -ENOMEM; - pcm->device = KBL_DPCM_AUDIO_HDMI1_PB; + pcm->device = device; pcm->codec_dai = dai; list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); @@ -202,47 +269,36 @@ static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) return 0; } -static int kabylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) +static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) { - struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = rtd->codec_dai; - struct kbl_hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - pcm->device = KBL_DPCM_AUDIO_HDMI2_PB; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); + return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI1_PB); +} - return 0; +static int kabylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) +{ + return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI2_PB); } static int kabylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) { - struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = rtd->codec_dai; - struct kbl_hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - pcm->device = KBL_DPCM_AUDIO_HDMI3_PB; - pcm->codec_dai = dai; + return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI3_PB); +} - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); +static int kabylake_5663_hdmi1_init(struct snd_soc_pcm_runtime *rtd) +{ + return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_5663_HDMI1_PB); +} - return 0; +static int kabylake_5663_hdmi2_init(struct snd_soc_pcm_runtime *rtd) +{ + return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_5663_HDMI2_PB); } static unsigned int rates[] = { 48000, }; -static struct snd_pcm_hw_constraint_list constraints_rates = { +static const struct snd_pcm_hw_constraint_list constraints_rates = { .count = ARRAY_SIZE(rates), .list = rates, .mask = 0, @@ -252,7 +308,7 @@ static unsigned int channels[] = { 2, }; -static struct snd_pcm_hw_constraint_list constraints_channels = { +static const struct snd_pcm_hw_constraint_list constraints_channels = { .count = ARRAY_SIZE(channels), .list = channels, .mask = 0, @@ -294,13 +350,28 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + struct snd_soc_dpcm *dpcm = container_of( + params, struct snd_soc_dpcm, hw_params); + struct snd_soc_dai_link *fe_dai_link = dpcm->fe->dai_link; + struct snd_soc_dai_link *be_dai_link = dpcm->be->dai_link; - /* The ADSP will convert the FE rate to 48k, stereo */ - rate->min = rate->max = 48000; - channels->min = channels->max = 2; - /* set SSP1 to 24 bit */ - snd_mask_none(fmt); - snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE); + /* + * The ADSP will convert the FE rate to 48k, stereo, 24 bit + */ + if (!strcmp(fe_dai_link->name, "Kbl Audio Port") || + !strcmp(fe_dai_link->name, "Kbl Audio Headset Playback") || + !strcmp(fe_dai_link->name, "Kbl Audio Capture Port")) { + rate->min = rate->max = 48000; + channels->min = channels->max = 2; + snd_mask_none(fmt); + snd_mask_set(fmt, SNDRV_PCM_FORMAT_S24_LE); + } + /* + * The speaker on the SSP0 supports S16_LE and not S24_LE. + * thus changing the mask here + */ + if (!strcmp(be_dai_link->name, "SSP0-Codec")) + snd_mask_set(fmt, SNDRV_PCM_FORMAT_S16_LE); return 0; } @@ -312,11 +383,13 @@ static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *codec_dai = rtd->codec_dai; int ret; - ret = snd_soc_dai_set_sysclk(codec_dai, - RT5663_SCLK_S_MCLK, 24576000, SND_SOC_CLOCK_IN); /* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */ - rt5663_sel_asrc_clk_src(codec_dai->codec, RT5663_DA_STEREO_FILTER, 1); + rt5663_sel_asrc_clk_src(codec_dai->codec, + RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER, + RT5663_CLK_SEL_I2S1_ASRC); + ret = snd_soc_dai_set_sysclk(codec_dai, + RT5663_SCLK_S_MCLK, 24576000, SND_SOC_CLOCK_IN); if (ret < 0) dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret); @@ -341,6 +414,43 @@ static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd, return 0; } +static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int ret = 0, j; + + for (j = 0; j < rtd->num_codecs; j++) { + struct snd_soc_dai *codec_dai = rtd->codec_dais[j]; + + if (!strcmp(codec_dai->component->name, MAXIM_DEV0_NAME)) { + /* + * Use channel 4 and 5 for the first amp + */ + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x30, 3, 8, 16); + if (ret < 0) { + dev_err(rtd->dev, "set TDM slot err:%d\n", ret); + return ret; + } + } + if (!strcmp(codec_dai->component->name, MAXIM_DEV1_NAME)) { + /* + * Use channel 6 and 7 for the second amp + */ + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xC0, 3, 8, 16); + if (ret < 0) { + dev_err(rtd->dev, "set TDM slot err:%d\n", ret); + return ret; + } + } + } + return ret; +} + +static struct snd_soc_ops kabylake_ssp0_ops = { + .hw_params = kabylake_ssp0_hw_params, +}; + static unsigned int channels_dmic[] = { 2, 4, }; @@ -381,7 +491,7 @@ static unsigned int rates_16000[] = { 16000, }; -static struct snd_pcm_hw_constraint_list constraints_16000 = { +static const struct snd_pcm_hw_constraint_list constraints_16000 = { .count = ARRAY_SIZE(rates_16000), .list = rates_16000, }; @@ -443,6 +553,28 @@ static struct snd_soc_dai_link kabylake_dais[] = { .dpcm_capture = 1, .ops = &kabylake_rt5663_fe_ops, }, + [KBL_DPCM_AUDIO_HS_PB] = { + .name = "Kbl Audio Headset Playback", + .stream_name = "Headset Audio", + .cpu_dai_name = "System Pin2", + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .platform_name = "0000:00:1f.3", + .dpcm_playback = 1, + .nonatomic = 1, + .dynamic = 1, + }, + [KBL_DPCM_AUDIO_ECHO_REF_CP] = { + .name = "Kbl Audio Echo Reference cap", + .stream_name = "Echoreference Capture", + .cpu_dai_name = "Echoref Pin", + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .platform_name = "0000:00:1f.3", + .init = NULL, + .capture_only = 1, + .nonatomic = 1, + }, [KBL_DPCM_AUDIO_REF_CP] = { .name = "Kbl Audio Reference cap", .stream_name = "Wake on Voice", @@ -522,12 +654,13 @@ static struct snd_soc_dai_link kabylake_dais[] = { .no_pcm = 1, .codecs = max98927_codec_components, .num_codecs = ARRAY_SIZE(max98927_codec_components), - .dai_fmt = SND_SOC_DAIFMT_I2S | + .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS, .ignore_pmdown_time = 1, .be_hw_params_fixup = kabylake_ssp_fixup, .dpcm_playback = 1, + .ops = &kabylake_ssp0_ops, }, { /* SSP1 - Codec */ @@ -538,7 +671,7 @@ static struct snd_soc_dai_link kabylake_dais[] = { .no_pcm = 1, .codec_name = "i2c-10EC5663:00", .codec_dai_name = KBL_REALTEK_CODEC_DAI, - .init = kabylake_rt5663_codec_init, + .init = kabylake_rt5663_max98927_codec_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS, .ignore_pmdown_time = 1, @@ -594,15 +727,119 @@ static struct snd_soc_dai_link kabylake_dais[] = { }, }; +static struct snd_soc_dai_link kabylake_5663_dais[] = { + /* Front End DAI links */ + [KBL_DPCM_AUDIO_5663_PB] = { + .name = "Kbl Audio Port", + .stream_name = "Audio", + .cpu_dai_name = "System Pin", + .platform_name = "0000:00:1f.3", + .dynamic = 1, + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .nonatomic = 1, + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, + .dpcm_playback = 1, + .ops = &kabylake_rt5663_fe_ops, + }, + [KBL_DPCM_AUDIO_5663_CP] = { + .name = "Kbl Audio Capture Port", + .stream_name = "Audio Record", + .cpu_dai_name = "System Pin", + .platform_name = "0000:00:1f.3", + .dynamic = 1, + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .nonatomic = 1, + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, + .dpcm_capture = 1, + .ops = &kabylake_rt5663_fe_ops, + }, + [KBL_DPCM_AUDIO_5663_HDMI1_PB] = { + .name = "Kbl HDMI Port1", + .stream_name = "Hdmi1", + .cpu_dai_name = "HDMI1 Pin", + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .platform_name = "0000:00:1f.3", + .dpcm_playback = 1, + .init = NULL, + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, + .nonatomic = 1, + .dynamic = 1, + }, + [KBL_DPCM_AUDIO_5663_HDMI2_PB] = { + .name = "Kbl HDMI Port2", + .stream_name = "Hdmi2", + .cpu_dai_name = "HDMI2 Pin", + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .platform_name = "0000:00:1f.3", + .dpcm_playback = 1, + .init = NULL, + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, + .nonatomic = 1, + .dynamic = 1, + }, + + /* Back End DAI links */ + { + /* SSP1 - Codec */ + .name = "SSP1-Codec", + .id = 0, + .cpu_dai_name = "SSP1 Pin", + .platform_name = "0000:00:1f.3", + .no_pcm = 1, + .codec_name = "i2c-10EC5663:00", + .codec_dai_name = KBL_REALTEK_CODEC_DAI, + .init = kabylake_rt5663_codec_init, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, + .ignore_pmdown_time = 1, + .be_hw_params_fixup = kabylake_ssp_fixup, + .ops = &kabylake_rt5663_ops, + .dpcm_playback = 1, + .dpcm_capture = 1, + }, + { + .name = "iDisp1", + .id = 1, + .cpu_dai_name = "iDisp1 Pin", + .codec_name = "ehdaudio0D2", + .codec_dai_name = "intel-hdmi-hifi1", + .platform_name = "0000:00:1f.3", + .dpcm_playback = 1, + .init = kabylake_5663_hdmi1_init, + .no_pcm = 1, + }, + { + .name = "iDisp2", + .id = 2, + .cpu_dai_name = "iDisp2 Pin", + .codec_name = "ehdaudio0D2", + .codec_dai_name = "intel-hdmi-hifi2", + .platform_name = "0000:00:1f.3", + .init = kabylake_5663_hdmi2_init, + .dpcm_playback = 1, + .no_pcm = 1, + }, +}; + #define NAME_SIZE 32 static int kabylake_card_late_probe(struct snd_soc_card *card) { struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(card); struct kbl_hdmi_pcm *pcm; + struct snd_soc_codec *codec = NULL; int err, i = 0; char jack_name[NAME_SIZE]; list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { + codec = pcm->codec_dai->codec; snprintf(jack_name, sizeof(jack_name), "HDMI/DP, pcm=%d Jack", pcm->device); err = snd_soc_card_jack_new(card, jack_name, @@ -620,11 +857,14 @@ static int kabylake_card_late_probe(struct snd_soc_card *card) i++; } - return 0; + if (!codec) + return -EINVAL; + + return hdac_hdmi_jack_port_init(codec, &card->dapm); } /* kabylake audio machine driver for SPT + RT5663 */ -static struct snd_soc_card kabylake_audio_card = { +static struct snd_soc_card kabylake_audio_card_rt5663_m98927 = { .name = "kblrt5663max", .owner = THIS_MODULE, .dai_link = kabylake_dais, @@ -641,6 +881,22 @@ static struct snd_soc_card kabylake_audio_card = { .late_probe = kabylake_card_late_probe, }; +/* kabylake audio machine driver for RT5663 */ +static struct snd_soc_card kabylake_audio_card_rt5663 = { + .name = "kblrt5663", + .owner = THIS_MODULE, + .dai_link = kabylake_5663_dais, + .num_links = ARRAY_SIZE(kabylake_5663_dais), + .controls = kabylake_5663_controls, + .num_controls = ARRAY_SIZE(kabylake_5663_controls), + .dapm_widgets = kabylake_5663_widgets, + .num_dapm_widgets = ARRAY_SIZE(kabylake_5663_widgets), + .dapm_routes = kabylake_5663_map, + .num_dapm_routes = ARRAY_SIZE(kabylake_5663_map), + .fully_routed = true, + .late_probe = kabylake_card_late_probe, +}; + static int kabylake_audio_probe(struct platform_device *pdev) { struct kbl_rt5663_private *ctx; @@ -652,19 +908,30 @@ static int kabylake_audio_probe(struct platform_device *pdev) INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - kabylake_audio_card.dev = &pdev->dev; - snd_soc_card_set_drvdata(&kabylake_audio_card, ctx); + kabylake_audio_card = + (struct snd_soc_card *)pdev->id_entry->driver_data; + + kabylake_audio_card->dev = &pdev->dev; + snd_soc_card_set_drvdata(kabylake_audio_card, ctx); pdata = dev_get_drvdata(&pdev->dev); if (pdata) dmic_constraints = pdata->dmic_num == 2 ? &constraints_dmic_2ch : &constraints_dmic_channels; - return devm_snd_soc_register_card(&pdev->dev, &kabylake_audio_card); + return devm_snd_soc_register_card(&pdev->dev, kabylake_audio_card); } static const struct platform_device_id kbl_board_ids[] = { - { .name = "kbl_rt5663_m98927" }, + { + .name = "kbl_rt5663", + .driver_data = (kernel_ulong_t)&kabylake_audio_card_rt5663, + }, + { + .name = "kbl_rt5663_m98927", + .driver_data = + (kernel_ulong_t)&kabylake_audio_card_rt5663_m98927, + }, { } }; @@ -684,4 +951,5 @@ MODULE_DESCRIPTION("Audio Machine driver-RT5663 & MAX98927 in I2S mode"); MODULE_AUTHOR("Naveen M <naveen.m@intel.com>"); MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>"); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:kbl_rt5663"); MODULE_ALIAS("platform:kbl_rt5663_m98927"); diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c index 3fe4a0807095..6072164f2d43 100644 --- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c +++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c @@ -18,6 +18,7 @@ * GNU General Public License for more details. */ +#include <linux/input.h> #include <linux/module.h> #include <linux/platform_device.h> #include <sound/core.h> @@ -62,7 +63,10 @@ struct kbl_codec_private { enum { KBL_DPCM_AUDIO_PB = 0, KBL_DPCM_AUDIO_CP, + KBL_DPCM_AUDIO_HS_PB, + KBL_DPCM_AUDIO_ECHO_REF_CP, KBL_DPCM_AUDIO_DMIC_CP, + KBL_DPCM_AUDIO_RT5514_DSP, KBL_DPCM_AUDIO_HDMI1_PB, KBL_DPCM_AUDIO_HDMI2_PB, }; @@ -81,8 +85,8 @@ 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("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), }; @@ -99,23 +103,25 @@ static const struct snd_soc_dapm_route kabylake_map[] = { { "IN1P", NULL, "Headset Mic" }, { "IN1N", NULL, "Headset Mic" }, - { "HDMI", NULL, "hif5 Output" }, - { "DP", NULL, "hif6 Output" }, - /* CODEC BE connections */ { "Left HiFi Playback", NULL, "ssp0 Tx" }, { "Right HiFi Playback", NULL, "ssp0 Tx" }, - { "ssp0 Tx", NULL, "codec0_out" }, + { "ssp0 Tx", NULL, "spk_out" }, { "AIF Playback", NULL, "ssp1 Tx" }, - { "ssp1 Tx", NULL, "codec1_out" }, + { "ssp1 Tx", NULL, "hs_out" }, - { "codec0_in", NULL, "ssp1 Rx" }, + { "hs_in", NULL, "ssp1 Rx" }, { "ssp1 Rx", NULL, "AIF Capture" }, { "codec1_in", NULL, "ssp0 Rx" }, { "ssp0 Rx", NULL, "AIF1 Capture" }, + /* IV feedback path */ + { "codec0_fb_in", NULL, "ssp0 Rx"}, + { "ssp0 Rx", NULL, "Left HiFi Capture" }, + { "ssp0 Rx", NULL, "Right HiFi Capture" }, + /* DMIC */ { "DMIC1L", NULL, "DMIC" }, { "DMIC1R", NULL, "DMIC" }, @@ -173,6 +179,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) int ret; struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_jack *jack; /* * Headset buttons map to the google Reference headset. @@ -187,6 +194,12 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) return ret; } + jack = &ctx->kabylake_headset; + snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA); + 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); + rt5663_set_jack_detect(codec, &ctx->kabylake_headset); ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "DMIC"); @@ -289,6 +302,7 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, * The ADSP will convert the FE rate to 48k, stereo, 24 bit */ if (!strcmp(fe_dai_link->name, "Kbl Audio Port") || + !strcmp(fe_dai_link->name, "Kbl Audio Headset Playback") || !strcmp(fe_dai_link->name, "Kbl Audio Capture Port")) { rate->min = rate->max = 48000; channels->min = channels->max = 2; @@ -319,7 +333,9 @@ static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream, int ret; /* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */ - rt5663_sel_asrc_clk_src(codec_dai->codec, RT5663_DA_STEREO_FILTER, 1); + rt5663_sel_asrc_clk_src(codec_dai->codec, + RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER, + RT5663_CLK_SEL_I2S1_ASRC); ret = snd_soc_dai_set_sysclk(codec_dai, RT5663_SCLK_S_MCLK, 24576000, SND_SOC_CLOCK_IN); @@ -349,27 +365,25 @@ static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream, return ret; } - ret = snd_soc_dai_set_pll(codec_dai, 0, - RT5514_PLL1_S_BCLK, RT5514_AIF1_BCLK_FREQ, - RT5514_AIF1_SYSCLK_FREQ); + ret = snd_soc_dai_set_sysclk(codec_dai, + RT5514_SCLK_S_MCLK, 24576000, SND_SOC_CLOCK_IN); if (ret < 0) { - dev_err(rtd->dev, "set bclk err: %d\n", ret); + dev_err(rtd->dev, "set sysclk err: %d\n", ret); return ret; } - - ret = snd_soc_dai_set_sysclk(codec_dai, - RT5514_SCLK_S_PLL1, RT5514_AIF1_SYSCLK_FREQ, - SND_SOC_CLOCK_IN); + } + if (!strcmp(codec_dai->component->name, MAXIM_DEV0_NAME)) { + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x30, 3, 8, 16); if (ret < 0) { - dev_err(rtd->dev, "set sclk err: %d\n", ret); + dev_err(rtd->dev, "DEV0 TDM slot err:%d\n", ret); return ret; } } - if (!strcmp(codec_dai->component->name, MAXIM_DEV0_NAME) || - !strcmp(codec_dai->component->name, MAXIM_DEV1_NAME)) { - ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF0, 3, 8, 16); + + if (!strcmp(codec_dai->component->name, MAXIM_DEV1_NAME)) { + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xC0, 3, 8, 16); if (ret < 0) { - dev_err(rtd->dev, "set TDM slot err:%d\n", ret); + dev_err(rtd->dev, "DEV1 TDM slot err:%d\n", ret); return ret; } } @@ -449,6 +463,36 @@ static struct snd_soc_dai_link kabylake_dais[] = { .dpcm_capture = 1, .ops = &kabylake_rt5663_fe_ops, }, + [KBL_DPCM_AUDIO_HS_PB] = { + .name = "Kbl Audio Headset Playback", + .stream_name = "Headset Audio", + .cpu_dai_name = "System Pin2", + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .platform_name = "0000:00:1f.3", + .dpcm_playback = 1, + .nonatomic = 1, + .dynamic = 1, + }, + [KBL_DPCM_AUDIO_ECHO_REF_CP] = { + .name = "Kbl Audio Echo Reference cap", + .stream_name = "Echoreference Capture", + .cpu_dai_name = "Echoref Pin", + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .platform_name = "0000:00:1f.3", + .init = NULL, + .capture_only = 1, + .nonatomic = 1, + }, + [KBL_DPCM_AUDIO_RT5514_DSP] = { + .name = "rt5514 dsp", + .stream_name = "Wake on Voice", + .cpu_dai_name = "spi-PRP0001:00", + .platform_name = "spi-PRP0001:00", + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + }, [KBL_DPCM_AUDIO_DMIC_CP] = { .name = "Kbl Audio DMIC cap", .stream_name = "dmiccap", @@ -555,10 +599,14 @@ static int kabylake_card_late_probe(struct snd_soc_card *card) { struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card); struct kbl_hdmi_pcm *pcm; + struct snd_soc_codec *codec = NULL; int err, i = 0; char jack_name[NAME_SIZE]; list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { + codec = pcm->codec_dai->codec; + snprintf(jack_name, sizeof(jack_name), + "HDMI/DP,pcm=%d Jack", pcm->device); err = snd_soc_card_jack_new(card, jack_name, SND_JACK_AVOUT, &ctx->kabylake_hdmi[i], NULL, 0); @@ -572,7 +620,10 @@ static int kabylake_card_late_probe(struct snd_soc_card *card) i++; } - return 0; + if (!codec) + return -EINVAL; + + return hdac_hdmi_jack_port_init(codec, &card->dapm); } /* diff --git a/sound/soc/intel/boards/mfld_machine.c b/sound/soc/intel/boards/mfld_machine.c index 4e08885f37aa..6f44acfb4aae 100644 --- a/sound/soc/intel/boards/mfld_machine.c +++ b/sound/soc/intel/boards/mfld_machine.c @@ -376,10 +376,8 @@ static int snd_mfld_mc_probe(struct platform_device *pdev) /* audio interrupt base of SRAM location where * interrupts are stored by System FW */ mc_drv_ctx = devm_kzalloc(&pdev->dev, sizeof(*mc_drv_ctx), GFP_ATOMIC); - if (!mc_drv_ctx) { - pr_err("allocation failed\n"); + if (!mc_drv_ctx) return -ENOMEM; - } irq_mem = platform_get_resource_byname( pdev, IORESOURCE_MEM, "IRQ_BASE"); diff --git a/sound/soc/intel/boards/skl_nau88l25_max98357a.c b/sound/soc/intel/boards/skl_nau88l25_max98357a.c index 5ed0aa27b467..1b5a689dc99b 100644 --- a/sound/soc/intel/boards/skl_nau88l25_max98357a.c +++ b/sound/soc/intel/boards/skl_nau88l25_max98357a.c @@ -54,20 +54,6 @@ enum { SKL_DPCM_AUDIO_HDMI3_PB, }; -static inline struct snd_soc_dai *skl_get_codec_dai(struct snd_soc_card *card) -{ - struct snd_soc_pcm_runtime *rtd; - - list_for_each_entry(rtd, &card->rtd_list, list) { - - if (!strncmp(rtd->codec_dai->name, SKL_NUVOTON_CODEC_DAI, - strlen(SKL_NUVOTON_CODEC_DAI))) - return rtd->codec_dai; - } - - return NULL; -} - static int platform_clock_control(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { @@ -76,7 +62,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, struct snd_soc_dai *codec_dai; int ret; - codec_dai = skl_get_codec_dai(card); + codec_dai = snd_soc_card_get_codec_dai(card, SKL_NUVOTON_CODEC_DAI); if (!codec_dai) { dev_err(card->dev, "Codec dai not found; Unable to set platform clock\n"); return -EIO; diff --git a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c index 01b8b140bb08..7bea4bc77481 100644 --- a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c +++ b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c @@ -57,20 +57,6 @@ enum { SKL_DPCM_AUDIO_HDMI3_PB, }; -static inline struct snd_soc_dai *skl_get_codec_dai(struct snd_soc_card *card) -{ - struct snd_soc_pcm_runtime *rtd; - - list_for_each_entry(rtd, &card->rtd_list, list) { - - if (!strncmp(rtd->codec_dai->name, SKL_NUVOTON_CODEC_DAI, - strlen(SKL_NUVOTON_CODEC_DAI))) - return rtd->codec_dai; - } - - return NULL; -} - static const struct snd_kcontrol_new skylake_controls[] = { SOC_DAPM_PIN_SWITCH("Headphone Jack"), SOC_DAPM_PIN_SWITCH("Headset Mic"), @@ -86,7 +72,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, struct snd_soc_dai *codec_dai; int ret; - codec_dai = skl_get_codec_dai(card); + codec_dai = snd_soc_card_get_codec_dai(card, SKL_NUVOTON_CODEC_DAI); if (!codec_dai) { dev_err(card->dev, "Codec dai not found\n"); return -EIO; |