From 1f93a7dfd1f8d5ff7a5c53246c7534fe2332d6f4 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 11 Dec 2023 02:46:07 +0000 Subject: [PATCH] add audio --- kernel/sound/soc/intel/boards/broadwell.c | 165 ++++++++++++++++++++++++++++++++++-------------------- 1 files changed, 104 insertions(+), 61 deletions(-) diff --git a/kernel/sound/soc/intel/boards/broadwell.c b/kernel/sound/soc/intel/boards/broadwell.c index 78ec97b..77c85f1 100644 --- a/kernel/sound/soc/intel/boards/broadwell.c +++ b/kernel/sound/soc/intel/boards/broadwell.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Intel Broadwell Wildcatpoint SST Audio * * Copyright (C) 2013, Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <linux/module.h> @@ -21,9 +12,7 @@ #include <sound/soc.h> #include <sound/jack.h> #include <sound/pcm_params.h> - -#include "../common/sst-dsp.h" -#include "../haswell/sst-haswell-ipc.h" +#include <sound/soc-acpi.h> #include "../../codecs/rt286.h" @@ -78,7 +67,7 @@ static int broadwell_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *component = rtd->codec_dai->component; + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; int ret = 0; ret = snd_soc_card_jack_new(rtd->card, "Headset", SND_JACK_HEADSET | SND_JACK_BTN_0, &broadwell_headset, @@ -95,13 +84,13 @@ struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *channels = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_CHANNELS); + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *chan = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); /* The ADSP will covert the FE rate to 48k, stereo */ rate->min = rate->max = 48000; - channels->min = channels->max = 2; + chan->min = chan->max = 2; /* set SSP0 to 16 bit */ params_set_format(params, SNDRV_PCM_FORMAT_S16_LE); @@ -111,8 +100,8 @@ static int broadwell_rt286_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, RT286_SCLK_S_PLL, 24000000, @@ -130,24 +119,54 @@ .hw_params = broadwell_rt286_hw_params, }; -static int broadwell_rtd_init(struct snd_soc_pcm_runtime *rtd) +static const unsigned int channels[] = { + 2, +}; + +static const struct snd_pcm_hw_constraint_list constraints_channels = { + .count = ARRAY_SIZE(channels), + .list = channels, + .mask = 0, +}; + +static int broadwell_fe_startup(struct snd_pcm_substream *substream) { - struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME); - struct sst_pdata *pdata = dev_get_platdata(component->dev); - struct sst_hsw *broadwell = pdata->dsp; - int ret; + struct snd_pcm_runtime *runtime = substream->runtime; - /* Set ADSP SSP port settings */ - ret = sst_hsw_device_set_config(broadwell, SST_HSW_DEVICE_SSP_0, - SST_HSW_DEVICE_MCLK_FREQ_24_MHZ, - SST_HSW_DEVICE_CLOCK_MASTER, 9); - if (ret < 0) { - dev_err(rtd->dev, "error: failed to set device config\n"); - return ret; - } - - return 0; + /* Board supports stereo configuration only */ + runtime->hw.channels_max = 2; + return snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_CHANNELS, + &constraints_channels); } + +static const struct snd_soc_ops broadwell_fe_ops = { + .startup = broadwell_fe_startup, +}; + +SND_SOC_DAILINK_DEF(system, + DAILINK_COMP_ARRAY(COMP_CPU("System Pin"))); + +SND_SOC_DAILINK_DEF(offload0, + DAILINK_COMP_ARRAY(COMP_CPU("Offload0 Pin"))); + +SND_SOC_DAILINK_DEF(offload1, + DAILINK_COMP_ARRAY(COMP_CPU("Offload1 Pin"))); + +SND_SOC_DAILINK_DEF(loopback, + DAILINK_COMP_ARRAY(COMP_CPU("Loopback Pin"))); + +SND_SOC_DAILINK_DEF(dummy, + DAILINK_COMP_ARRAY(COMP_DUMMY())); + +SND_SOC_DAILINK_DEF(platform, + DAILINK_COMP_ARRAY(COMP_PLATFORM("haswell-pcm-audio"))); + +SND_SOC_DAILINK_DEF(codec, + DAILINK_COMP_ARRAY(COMP_CODEC("i2c-INT343A:00", "rt286-aif1"))); + +SND_SOC_DAILINK_DEF(ssp0_port, + DAILINK_COMP_ARRAY(COMP_CPU("ssp0-port"))); /* broadwell digital audio interface glue - connects codec <--> CPU */ static struct snd_soc_dai_link broadwell_rt286_dais[] = { @@ -155,75 +174,64 @@ { .name = "System PCM", .stream_name = "System Playback/Capture", - .cpu_dai_name = "System Pin", - .platform_name = "haswell-pcm-audio", + .nonatomic = 1, .dynamic = 1, - .codec_name = "snd-soc-dummy", - .codec_dai_name = "snd-soc-dummy-dai", - .init = broadwell_rtd_init, .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, + .ops = &broadwell_fe_ops, .dpcm_playback = 1, .dpcm_capture = 1, + SND_SOC_DAILINK_REG(system, dummy, platform), }, { .name = "Offload0", .stream_name = "Offload0 Playback", - .cpu_dai_name = "Offload0 Pin", - .platform_name = "haswell-pcm-audio", + .nonatomic = 1, .dynamic = 1, - .codec_name = "snd-soc-dummy", - .codec_dai_name = "snd-soc-dummy-dai", .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .dpcm_playback = 1, + SND_SOC_DAILINK_REG(offload0, dummy, platform), }, { .name = "Offload1", .stream_name = "Offload1 Playback", - .cpu_dai_name = "Offload1 Pin", - .platform_name = "haswell-pcm-audio", + .nonatomic = 1, .dynamic = 1, - .codec_name = "snd-soc-dummy", - .codec_dai_name = "snd-soc-dummy-dai", .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .dpcm_playback = 1, + SND_SOC_DAILINK_REG(offload1, dummy, platform), }, { .name = "Loopback PCM", .stream_name = "Loopback", - .cpu_dai_name = "Loopback Pin", - .platform_name = "haswell-pcm-audio", + .nonatomic = 1, .dynamic = 1, - .codec_name = "snd-soc-dummy", - .codec_dai_name = "snd-soc-dummy-dai", .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .dpcm_capture = 1, + SND_SOC_DAILINK_REG(loopback, dummy, platform), }, /* Back End DAI links */ { /* SSP0 - Codec */ .name = "Codec", .id = 0, - .cpu_dai_name = "snd-soc-dummy-dai", - .platform_name = "snd-soc-dummy", .no_pcm = 1, - .codec_name = "i2c-INT343A:00", - .codec_dai_name = "rt286-aif1", .init = broadwell_rt286_codec_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS, - .ignore_suspend = 1, .ignore_pmdown_time = 1, .be_hw_params_fixup = broadwell_ssp0_fixup, .ops = &broadwell_rt286_ops, .dpcm_playback = 1, .dpcm_capture = 1, + SND_SOC_DAILINK_REG(ssp0_port, codec, platform), }, }; -static int broadwell_suspend(struct snd_soc_card *card){ +static int broadwell_disable_jack(struct snd_soc_card *card) +{ struct snd_soc_component *component; - list_for_each_entry(component, &card->component_dev_list, card_list) { + for_each_card_components(card, component) { if (!strcmp(component->name, "i2c-INT343A:00")) { dev_dbg(component->dev, "disabling jack detect before going to suspend.\n"); @@ -231,13 +239,19 @@ break; } } + return 0; +} + +static int broadwell_suspend(struct snd_soc_card *card) +{ + return broadwell_disable_jack(card); } static int broadwell_resume(struct snd_soc_card *card){ struct snd_soc_component *component; - list_for_each_entry(component, &card->component_dev_list, card_list) { + for_each_card_components(card, component) { if (!strcmp(component->name, "i2c-INT343A:00")) { dev_dbg(component->dev, "enabling jack detect for resume.\n"); @@ -248,9 +262,19 @@ return 0; } +#if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL) +/* use space before codec name to simplify card ID, and simplify driver name */ +#define CARD_NAME "bdw rt286" /* card name will be 'sof-bdw rt286' */ +#define DRIVER_NAME "SOF" +#else +#define CARD_NAME "broadwell-rt286" +#define DRIVER_NAME NULL /* card name will be used for driver name */ +#endif + /* broadwell audio machine driver for WPT + RT286S */ static struct snd_soc_card broadwell_rt286 = { - .name = "broadwell-rt286", + .name = CARD_NAME, + .driver_name = DRIVER_NAME, .owner = THIS_MODULE, .dai_link = broadwell_rt286_dais, .num_links = ARRAY_SIZE(broadwell_rt286_dais), @@ -267,12 +291,31 @@ static int broadwell_audio_probe(struct platform_device *pdev) { + struct snd_soc_acpi_mach *mach; + int ret; + broadwell_rt286.dev = &pdev->dev; + + /* override plaform name, if required */ + mach = pdev->dev.platform_data; + ret = snd_soc_fixup_dai_links_platform_name(&broadwell_rt286, + mach->mach_params.platform); + if (ret) + return ret; + return devm_snd_soc_register_card(&pdev->dev, &broadwell_rt286); +} + +static int broadwell_audio_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + + return broadwell_disable_jack(card); } static struct platform_driver broadwell_audio = { .probe = broadwell_audio_probe, + .remove = broadwell_audio_remove, .driver = { .name = "broadwell-audio", }, -- Gitblit v1.6.2