diff options
Diffstat (limited to 'sound/soc/intel')
-rw-r--r-- | sound/soc/intel/Kconfig | 31 | ||||
-rw-r--r-- | sound/soc/intel/atom/sst/sst_acpi.c | 37 | ||||
-rw-r--r-- | sound/soc/intel/boards/bytcr_rt5640.c | 28 | ||||
-rw-r--r-- | sound/soc/intel/boards/bytcr_rt5651.c | 3 | ||||
-rw-r--r-- | sound/soc/intel/boards/cht_bsw_rt5645.c | 98 | ||||
-rw-r--r-- | sound/soc/intel/skylake/skl-sst.c | 3 | ||||
-rw-r--r-- | sound/soc/intel/skylake/skl-topology.c | 2 |
7 files changed, 157 insertions, 45 deletions
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index fd5d1e091038..e18fe9d6f08f 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -33,11 +33,9 @@ config SND_SOC_INTEL_SST select SND_SOC_INTEL_SST_MATCH if ACPI depends on (X86 || COMPILE_TEST) -# firmware stuff depends DW_DMAC_CORE; since there is no depends-on from -# the reverse selection, each machine driver needs to select -# SND_SOC_INTEL_SST_FIRMWARE carefully depending on DW_DMAC_CORE config SND_SOC_INTEL_SST_FIRMWARE tristate + select DW_DMAC_CORE config SND_SOC_INTEL_SST_ACPI tristate @@ -47,16 +45,18 @@ config SND_SOC_INTEL_SST_MATCH config SND_SOC_INTEL_HASWELL tristate + select SND_SOC_INTEL_SST select SND_SOC_INTEL_SST_FIRMWARE config SND_SOC_INTEL_BAYTRAIL tristate + select SND_SOC_INTEL_SST + select SND_SOC_INTEL_SST_FIRMWARE 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 DW_DMAC_CORE - select SND_SOC_INTEL_SST + depends on DMADEVICES select SND_SOC_INTEL_HASWELL select SND_SOC_RT5640 help @@ -99,9 +99,8 @@ config SND_SOC_INTEL_BXT_RT298_MACH 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 DW_DMAC_CORE && (SND_SST_IPC_ACPI = n) - select SND_SOC_INTEL_SST - select SND_SOC_INTEL_SST_FIRMWARE + depends on DMADEVICES + depends on SND_SST_IPC_ACPI = n select SND_SOC_INTEL_BAYTRAIL select SND_SOC_RT5640 help @@ -112,9 +111,8 @@ config SND_SOC_INTEL_BYT_RT5640_MACH 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 DW_DMAC_CORE && (SND_SST_IPC_ACPI = n) - select SND_SOC_INTEL_SST - select SND_SOC_INTEL_SST_FIRMWARE + depends on DMADEVICES + depends on SND_SST_IPC_ACPI = n select SND_SOC_INTEL_BAYTRAIL select SND_SOC_MAX98090 help @@ -123,9 +121,8 @@ config SND_SOC_INTEL_BYT_MAX98090_MACH config SND_SOC_INTEL_BDW_RT5677_MACH tristate "ASoC Audio driver for Intel Broadwell with RT5677 codec" - depends on X86_INTEL_LPSS && GPIOLIB && I2C && DW_DMAC - depends on DW_DMAC_CORE=y - select SND_SOC_INTEL_SST + depends on X86_INTEL_LPSS && GPIOLIB && I2C + depends on DMADEVICES select SND_SOC_INTEL_HASWELL select SND_SOC_RT5677 help @@ -134,10 +131,8 @@ config SND_SOC_INTEL_BDW_RT5677_MACH config SND_SOC_INTEL_BROADWELL_MACH tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint" - depends on X86_INTEL_LPSS && I2C && DW_DMAC && \ - I2C_DESIGNWARE_PLATFORM - depends on DW_DMAC_CORE - select SND_SOC_INTEL_SST + depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM + depends on DMADEVICES select SND_SOC_INTEL_HASWELL select SND_SOC_RT286 help diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c index 0a88537ca58a..0bfa68862460 100644 --- a/sound/soc/intel/atom/sst/sst_acpi.c +++ b/sound/soc/intel/atom/sst/sst_acpi.c @@ -400,6 +400,7 @@ static int sst_acpi_remove(struct platform_device *pdev) static unsigned long cht_machine_id; #define CHT_SURFACE_MACH 1 +#define BYT_THINKPAD_10 2 static int cht_surface_quirk_cb(const struct dmi_system_id *id) { @@ -407,6 +408,23 @@ static int cht_surface_quirk_cb(const struct dmi_system_id *id) return 1; } +static int byt_thinkpad10_quirk_cb(const struct dmi_system_id *id) +{ + cht_machine_id = BYT_THINKPAD_10; + return 1; +} + + +static const struct dmi_system_id byt_table[] = { + { + .callback = byt_thinkpad10_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "20C3001VHH"), + }, + }, + { } +}; static const struct dmi_system_id cht_table[] = { { @@ -424,6 +442,10 @@ static struct sst_acpi_mach cht_surface_mach = { "10EC5640", "cht-bsw-rt5645", "intel/fw_sst_22a8.bin", "cht-bsw", NULL, &chv_platform_data }; +static struct sst_acpi_mach byt_thinkpad_10 = { + "10EC5640", "cht-bsw-rt5672", "intel/fw_sst_0f28.bin", "cht-bsw", NULL, + &byt_rvp_platform_data }; + static struct sst_acpi_mach *cht_quirk(void *arg) { struct sst_acpi_mach *mach = arg; @@ -436,8 +458,21 @@ static struct sst_acpi_mach *cht_quirk(void *arg) return mach; } +static struct sst_acpi_mach *byt_quirk(void *arg) +{ + struct sst_acpi_mach *mach = arg; + + dmi_check_system(byt_table); + + if (cht_machine_id == BYT_THINKPAD_10) + return &byt_thinkpad_10; + else + return mach; +} + + static struct sst_acpi_mach sst_acpi_bytcr[] = { - {"10EC5640", "bytcr_rt5640", "intel/fw_sst_0f28.bin", "bytcr_rt5640", NULL, + {"10EC5640", "bytcr_rt5640", "intel/fw_sst_0f28.bin", "bytcr_rt5640", byt_quirk, &byt_rvp_platform_data }, {"10EC5642", "bytcr_rt5640", "intel/fw_sst_0f28.bin", "bytcr_rt5640", NULL, &byt_rvp_platform_data }, diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index bff77a1f27fc..c17f262f0834 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -57,9 +57,7 @@ struct byt_rt5640_private { struct clk *mclk; }; -static unsigned long byt_rt5640_quirk = BYT_RT5640_DMIC1_MAP | - BYT_RT5640_DMIC_EN | - BYT_RT5640_MCLK_EN; +static unsigned long byt_rt5640_quirk = BYT_RT5640_MCLK_EN; static void log_quirks(struct device *dev) { @@ -144,7 +142,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, * for Jack detection and button press */ ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_RCCLK, - 0, + 48000 * 512, SND_SOC_CLOCK_IN); if (!ret) { if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk) @@ -389,6 +387,16 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { BYT_RT5640_SSP0_AIF1), }, + { + .callback = byt_rt5640_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), + }, + .driver_data = (unsigned long *)(BYT_RT5640_IN3_MAP | + BYT_RT5640_MCLK_EN | + BYT_RT5640_SSP0_AIF1), + + }, {} }; @@ -613,7 +621,7 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .platform_name = "sst-mfld-platform", - .ignore_suspend = 1, + .nonatomic = true, .dynamic = 1, .dpcm_playback = 1, .dpcm_capture = 1, @@ -626,7 +634,6 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .platform_name = "sst-mfld-platform", - .ignore_suspend = 1, .nonatomic = true, .dynamic = 1, .dpcm_playback = 1, @@ -653,6 +660,7 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = { | SND_SOC_DAIFMT_CBS_CFS, .be_hw_params_fixup = byt_rt5640_codec_fixup, .ignore_suspend = 1, + .nonatomic = true, .dpcm_playback = 1, .dpcm_capture = 1, .init = byt_rt5640_init, @@ -738,6 +746,13 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) if (res_info->acpi_ipc_irq_index == 0) { byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2; } + + /* change defaults for Baytrail-CR capture */ + byt_rt5640_quirk |= BYT_RT5640_IN1_MAP; + byt_rt5640_quirk |= BYT_RT5640_DIFF_MIC; + } else { + byt_rt5640_quirk |= (BYT_RT5640_DMIC1_MAP | + BYT_RT5640_DMIC_EN); } /* check quirks before creating card */ @@ -792,7 +807,6 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) static struct platform_driver snd_byt_rt5640_mc_driver = { .driver = { .name = "bytcr_rt5640", - .pm = &snd_soc_pm_ops, }, .probe = snd_byt_rt5640_mc_probe, }; diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index 35f591eab3c9..ae49f8199e45 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -235,7 +235,6 @@ static struct snd_soc_dai_link byt_rt5651_dais[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .platform_name = "sst-mfld-platform", - .ignore_suspend = 1, .nonatomic = true, .dynamic = 1, .dpcm_playback = 1, @@ -249,7 +248,6 @@ static struct snd_soc_dai_link byt_rt5651_dais[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .platform_name = "sst-mfld-platform", - .ignore_suspend = 1, .nonatomic = true, .dynamic = 1, .dpcm_playback = 1, @@ -319,7 +317,6 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) static struct platform_driver snd_byt_rt5651_mc_driver = { .driver = { .name = "bytcr_rt5651", - .pm = &snd_soc_pm_ops, }, .probe = snd_byt_rt5651_mc_probe, }; diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c index 16c94c45ce50..90525614c20a 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5645.c +++ b/sound/soc/intel/boards/cht_bsw_rt5645.c @@ -24,6 +24,9 @@ #include <linux/acpi.h> #include <linux/platform_device.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> @@ -45,6 +48,7 @@ struct cht_mc_private { struct snd_soc_jack jack; struct cht_acpi_card *acpi_card; char codec_name[16]; + struct clk *mclk; }; static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card) @@ -65,6 +69,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, 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 = cht_get_codec_dai(card); @@ -73,19 +78,30 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, return -EIO; } - if (!SND_SOC_DAPM_EVENT_OFF(event)) - return 0; + 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; + } + } + } else { + /* Set codec sysclk source to its internal clock because codec PLL will + * be off when idle and MCLK will also be off when codec is + * runtime suspended. Codec needs clock for jack detection and button + * press. MCLK is turned off with clock framework or ACPI. + */ + ret = snd_soc_dai_set_sysclk(codec_dai, RT5645_SCLK_S_RCCLK, + 48000 * 512, SND_SOC_CLOCK_IN); + if (ret < 0) { + dev_err(card->dev, "can't set codec sysclk: %d\n", ret); + return ret; + } - /* Set codec sysclk source to its internal clock because codec PLL will - * be off when idle and MCLK will also be off by ACPI when codec is - * runtime suspended. Codec needs clock for jack detection and button - * press. - */ - ret = snd_soc_dai_set_sysclk(codec_dai, RT5645_SCLK_S_RCCLK, - 0, SND_SOC_CLOCK_IN); - if (ret < 0) { - dev_err(card->dev, "can't set codec sysclk: %d\n", ret); - return ret; + if (ctx->mclk) + clk_disable_unprepare(ctx->mclk); } return 0; @@ -97,7 +113,7 @@ static const struct snd_soc_dapm_widget cht_dapm_widgets[] = { 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_POST_PMD), + platform_clock_control, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), }; static const struct snd_soc_dapm_route cht_rt5645_audio_map[] = { @@ -225,6 +241,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); + + if (ret) + dev_err(runtime->dev, "unable to set MCLK rate\n"); + } return ret; } @@ -349,6 +385,18 @@ static struct cht_acpi_card snd_soc_cards[] = { static char cht_rt5640_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */ +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; +} + static int snd_cht_mc_probe(struct platform_device *pdev) { int ret_val = 0; @@ -358,22 +406,32 @@ static int snd_cht_mc_probe(struct platform_device *pdev) struct sst_acpi_mach *mach; const char *i2c_name = NULL; int dai_index = 0; + bool found = false; drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC); if (!drv) return -ENOMEM; + mach = (&pdev->dev)->platform_data; + for (i = 0; i < ARRAY_SIZE(snd_soc_cards); i++) { - if (acpi_dev_found(snd_soc_cards[i].codec_id)) { + if (acpi_dev_found(snd_soc_cards[i].codec_id) && + (!strncmp(snd_soc_cards[i].codec_id, mach->id, 8))) { dev_dbg(&pdev->dev, "found codec %s\n", snd_soc_cards[i].codec_id); card = snd_soc_cards[i].soc_card; drv->acpi_card = &snd_soc_cards[i]; + found = true; break; } } + + if (!found) { + dev_err(&pdev->dev, "No matching HID found in supported list\n"); + return -ENODEV; + } + card->dev = &pdev->dev; - mach = card->dev->platform_data; sprintf(drv->codec_name, "i2c-%s:00", drv->acpi_card->codec_id); /* set correct codec name */ @@ -391,6 +449,16 @@ static int snd_cht_mc_probe(struct platform_device *pdev) cht_dailink[dai_index].codec_name = cht_rt5640_codec_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); + } + } + snd_soc_card_set_drvdata(card, drv); ret_val = devm_snd_soc_register_card(&pdev->dev, card); if (ret_val) { diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c index 8fc3178bc79c..b30bd384c8d3 100644 --- a/sound/soc/intel/skylake/skl-sst.c +++ b/sound/soc/intel/skylake/skl-sst.c @@ -515,6 +515,9 @@ EXPORT_SYMBOL_GPL(skl_sst_init_fw); void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) { + + if (ctx->dsp->fw) + release_firmware(ctx->dsp->fw); skl_clear_module_table(ctx->dsp); skl_freeup_uuid_list(ctx); skl_ipc_free(&ctx->ipc); diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index b5b1934d8550..bef8a4546c12 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -448,7 +448,7 @@ static int skl_tplg_set_module_init_data(struct snd_soc_dapm_widget *w) if (bc->set_params != SKL_PARAM_INIT) continue; - mconfig->formats_config.caps = (u32 *)&bc->params; + mconfig->formats_config.caps = (u32 *)bc->params; mconfig->formats_config.caps_size = bc->size; break; |