diff options
Diffstat (limited to '')
106 files changed, 3240 insertions, 2199 deletions
diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c index 6f986c7bbc..8652b4a200 100644 --- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c +++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c @@ -273,7 +273,7 @@ static int sst_platform_init_stream(struct snd_pcm_substream *substream) { struct sst_runtime_stream *stream = substream->runtime->private_data; - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); int ret_val; dev_dbg(rtd->dev, "setting buffer ptr param\n"); @@ -593,7 +593,7 @@ static int sst_soc_trigger(struct snd_soc_component *component, int ret_val = 0, str_id; struct sst_runtime_stream *stream; int status; - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); dev_dbg(rtd->dev, "%s called\n", __func__); if (substream->pcm->internal) @@ -641,7 +641,7 @@ static snd_pcm_uframes_t sst_soc_pointer(struct snd_soc_component *component, struct sst_runtime_stream *stream; int ret_val, status; struct pcm_stream_info *str_info; - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); stream = substream->runtime->private_data; status = sst_get_stream_status(stream); @@ -671,7 +671,7 @@ static snd_pcm_sframes_t sst_soc_delay(struct snd_soc_component *component, static int sst_soc_pcm_new(struct snd_soc_component *component, struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0); struct snd_pcm *pcm = rtd->pcm; if (dai->driver->playback.channels_min || @@ -762,7 +762,7 @@ static int sst_soc_prepare(struct device *dev) /* set the SSPs to idle */ for_each_card_rtds(drv->soc_card, rtd) { - struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0); if (snd_soc_dai_active(dai)) { send_ssp_cmd(dai, dai->name, 0); @@ -783,7 +783,7 @@ static void sst_soc_complete(struct device *dev) /* restart SSPs */ for_each_card_rtds(drv->soc_card, rtd) { - struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0); if (snd_soc_dai_active(dai)) { sst_handle_vb_timer(dai, true); diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h index 0cf38c9e76..d694e08e44 100644 --- a/sound/soc/intel/avs/avs.h +++ b/sound/soc/intel/avs/avs.h @@ -121,6 +121,7 @@ struct avs_dev { struct avs_mods_info *mods_info; struct ida **mod_idas; struct mutex modres_mutex; + void *modcfg_buf; /* module configuration buffer */ struct ida ppl_ida; struct list_head fw_list; int *core_refs; /* reference count per core */ @@ -224,39 +225,22 @@ struct avs_ipc { #define AVS_IPC_RET(ret) \ (((ret) <= 0) ? (ret) : -AVS_EIPC) -static inline void avs_ipc_err(struct avs_dev *adev, struct avs_ipc_msg *tx, - const char *name, int error) -{ - /* - * If IPC channel is blocked e.g.: due to ongoing recovery, - * -EPERM error code is expected and thus it's not an actual error. - * - * Unsupported IPCs are of no harm either. - */ - if (error == -EPERM || error == AVS_IPC_NOT_SUPPORTED) - dev_dbg(adev->dev, "%s 0x%08x 0x%08x failed: %d\n", name, - tx->glb.primary, tx->glb.ext.val, error); - else - dev_err(adev->dev, "%s 0x%08x 0x%08x failed: %d\n", name, - tx->glb.primary, tx->glb.ext.val, error); -} - irqreturn_t avs_dsp_irq_handler(int irq, void *dev_id); irqreturn_t avs_dsp_irq_thread(int irq, void *dev_id); void avs_dsp_process_response(struct avs_dev *adev, u64 header); -int avs_dsp_send_msg_timeout(struct avs_dev *adev, - struct avs_ipc_msg *request, - struct avs_ipc_msg *reply, int timeout); -int avs_dsp_send_msg(struct avs_dev *adev, - struct avs_ipc_msg *request, struct avs_ipc_msg *reply); +int avs_dsp_send_msg_timeout(struct avs_dev *adev, struct avs_ipc_msg *request, + struct avs_ipc_msg *reply, int timeout, const char *name); +int avs_dsp_send_msg(struct avs_dev *adev, struct avs_ipc_msg *request, + struct avs_ipc_msg *reply, const char *name); /* Two variants below are for messages that control DSP power states. */ int avs_dsp_send_pm_msg_timeout(struct avs_dev *adev, struct avs_ipc_msg *request, - struct avs_ipc_msg *reply, int timeout, bool wake_d0i0); + struct avs_ipc_msg *reply, int timeout, bool wake_d0i0, + const char *name); int avs_dsp_send_pm_msg(struct avs_dev *adev, struct avs_ipc_msg *request, - struct avs_ipc_msg *reply, bool wake_d0i0); -int avs_dsp_send_rom_msg_timeout(struct avs_dev *adev, - struct avs_ipc_msg *request, int timeout); -int avs_dsp_send_rom_msg(struct avs_dev *adev, struct avs_ipc_msg *request); + struct avs_ipc_msg *reply, bool wake_d0i0, const char *name); +int avs_dsp_send_rom_msg_timeout(struct avs_dev *adev, struct avs_ipc_msg *request, int timeout, + const char *name); +int avs_dsp_send_rom_msg(struct avs_dev *adev, struct avs_ipc_msg *request, const char *name); void avs_dsp_interrupt_control(struct avs_dev *adev, bool enable); int avs_ipc_init(struct avs_ipc *ipc, struct device *dev); void avs_ipc_block(struct avs_ipc *ipc); diff --git a/sound/soc/intel/avs/board_selection.c b/sound/soc/intel/avs/board_selection.c index 59a13feec5..8e91eece99 100644 --- a/sound/soc/intel/avs/board_selection.c +++ b/sound/soc/intel/avs/board_selection.c @@ -136,6 +136,15 @@ static struct snd_soc_acpi_mach avs_kbl_i2s_machines[] = { .tplg_filename = "max98927-tplg.bin", }, { + .id = "10EC5514", + .drv_name = "avs_rt5514", + .mach_params = { + .i2s_link_mask = AVS_SSP(0), + }, + .pdata = (unsigned long[]){ 0x2, 0, 0, 0, 0, 0 }, /* SSP0 TDMs */ + .tplg_filename = "rt5514-tplg.bin", + }, + { .id = "10EC5663", .drv_name = "avs_rt5663", .mach_params = { @@ -193,7 +202,7 @@ static struct snd_soc_acpi_mach avs_apl_i2s_machines[] = { .mach_params = { .i2s_link_mask = AVS_SSP_RANGE(0, 5), }, - .pdata = (unsigned long[]){ 0, 0, 0x14, 0, 0, 0 }, /* SSP2 TDMs */ + .pdata = (unsigned long[]){ 0x1, 0x1, 0x14, 0x1, 0x1, 0x1 }, /* SSP2 TDMs */ .tplg_filename = "tdf8532-tplg.bin", }, { diff --git a/sound/soc/intel/avs/boards/Kconfig b/sound/soc/intel/avs/boards/Kconfig index 07353d37ec..00b0f6c176 100644 --- a/sound/soc/intel/avs/boards/Kconfig +++ b/sound/soc/intel/avs/boards/Kconfig @@ -125,6 +125,16 @@ config SND_SOC_INTEL_AVS_MACH_RT298 Say Y or m if you have such a device. This is a recommended option. If unsure select "N". +config SND_SOC_INTEL_AVS_MACH_RT5514 + tristate "rt5514 in I2S mode" + depends on I2C + depends on MFD_INTEL_LPSS || COMPILE_TEST + select SND_SOC_RT5514 + help + This adds support for ASoC machine driver with RT5514 I2S audio codec. + Say Y or m if you have such a device. This is a recommended option. + If unsure select "N". + config SND_SOC_INTEL_AVS_MACH_RT5663 tristate "rt5663 in I2S mode" depends on I2C diff --git a/sound/soc/intel/avs/boards/Makefile b/sound/soc/intel/avs/boards/Makefile index 34347bcd1e..0ff21d55be 100644 --- a/sound/soc/intel/avs/boards/Makefile +++ b/sound/soc/intel/avs/boards/Makefile @@ -13,6 +13,7 @@ snd-soc-avs-probe-objs := probe.o snd-soc-avs-rt274-objs := rt274.o snd-soc-avs-rt286-objs := rt286.o snd-soc-avs-rt298-objs := rt298.o +snd-soc-avs-rt5514-objs := rt5514.o snd-soc-avs-rt5663-objs := rt5663.o snd-soc-avs-rt5682-objs := rt5682.o snd-soc-avs-ssm4567-objs := ssm4567.o @@ -30,6 +31,7 @@ obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_PROBE) += snd-soc-avs-probe.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT274) += snd-soc-avs-rt274.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT286) += snd-soc-avs-rt286.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT298) += snd-soc-avs-rt298.o +obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT5514) += snd-soc-avs-rt5514.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT5663) += snd-soc-avs-rt5663.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_RT5682) += snd-soc-avs-rt5682.o obj-$(CONFIG_SND_SOC_INTEL_AVS_MACH_SSM4567) += snd-soc-avs-ssm4567.o diff --git a/sound/soc/intel/avs/boards/da7219.c b/sound/soc/intel/avs/boards/da7219.c index 85014d98f7..6060894954 100644 --- a/sound/soc/intel/avs/boards/da7219.c +++ b/sound/soc/intel/avs/boards/da7219.c @@ -16,6 +16,7 @@ #include <sound/soc-dapm.h> #include <uapi/linux/input-event-codes.h> #include "../../../codecs/da7219.h" +#include "../utils.h" #define DA7219_DAI_NAME "da7219-hifi" @@ -90,7 +91,7 @@ static const struct snd_soc_jack_pin card_headset_pins[] = { static int avs_da7219_codec_init(struct snd_soc_pcm_runtime *runtime) { - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(runtime, 0); struct snd_soc_component *component = codec_dai->component; struct snd_soc_card *card = runtime->card; struct snd_soc_jack_pin *pins; @@ -140,7 +141,7 @@ static int avs_da7219_codec_init(struct snd_soc_pcm_runtime *runtime) static void avs_da7219_codec_exit(struct snd_soc_pcm_runtime *rtd) { - snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component, NULL, NULL); + snd_soc_component_set_jack(snd_soc_rtd_to_codec(rtd, 0)->component, NULL, NULL); } static int @@ -164,7 +165,7 @@ avs_da7219_be_fixup(struct snd_soc_pcm_runtime *runrime, struct snd_pcm_hw_param } static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - struct snd_soc_dai_link **dai_link) + int tdm_slot, struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -177,12 +178,15 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in platform->name = platform_name; dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + dl->name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL); if (!dl->name || !dl->cpus || !dl->codecs) return -ENOMEM; - dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", " Pin", ssp_port, tdm_slot)); dl->codecs->name = devm_kasprintf(dev, GFP_KERNEL, "i2c-DLGS7219:00"); dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, DA7219_DAI_NAME); if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) @@ -230,13 +234,16 @@ static int avs_da7219_probe(struct platform_device *pdev) struct snd_soc_jack *jack; struct device *dev = &pdev->dev; const char *pname; - int ssp_port, ret; + int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); pname = mach->mach_params.platform; - ssp_port = __ffs(mach->mach_params.i2s_link_mask); - ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link); + ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); + if (ret) + return ret; + + ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); return ret; diff --git a/sound/soc/intel/avs/boards/es8336.c b/sound/soc/intel/avs/boards/es8336.c index 0a023f871d..f972ef64d2 100644 --- a/sound/soc/intel/avs/boards/es8336.c +++ b/sound/soc/intel/avs/boards/es8336.c @@ -19,6 +19,7 @@ #include <sound/soc.h> #include <sound/soc-acpi.h> #include <asm/intel-family.h> +#include "../utils.h" #define ES8336_CODEC_DAI "ES8316 HiFi" @@ -97,7 +98,7 @@ static struct snd_soc_jack_pin card_headset_pins[] = { static int avs_es8336_codec_init(struct snd_soc_pcm_runtime *runtime) { - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(runtime, 0); struct snd_soc_component *component = codec_dai->component; struct snd_soc_card *card = runtime->card; struct snd_soc_jack_pin *pins; @@ -138,7 +139,7 @@ static int avs_es8336_codec_init(struct snd_soc_pcm_runtime *runtime) static void avs_es8336_codec_exit(struct snd_soc_pcm_runtime *runtime) { struct avs_card_drvdata *data = snd_soc_card_get_drvdata(runtime->card); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(runtime, 0); snd_soc_component_set_jack(codec_dai->component, NULL, NULL); gpiod_put(data->gpiod); @@ -147,8 +148,8 @@ static void avs_es8336_codec_exit(struct snd_soc_pcm_runtime *runtime) static int avs_es8336_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *runtime = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, 0); + struct snd_soc_pcm_runtime *runtime = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(runtime, 0); int clk_freq; int ret; @@ -194,7 +195,7 @@ static int avs_es8336_be_fixup(struct snd_soc_pcm_runtime *runtime, return 0; } static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - struct snd_soc_dai_link **dai_link) + int tdm_slot, struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -206,13 +207,15 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + dl->name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL); if (!dl->name || !dl->cpus || !dl->codecs) return -ENOMEM; - dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", " Pin", ssp_port, tdm_slot)); dl->codecs->name = devm_kasprintf(dev, GFP_KERNEL, "i2c-ESSX8336:00"); dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, ES8336_CODEC_DAI); if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) @@ -261,13 +264,16 @@ static int avs_es8336_probe(struct platform_device *pdev) struct snd_soc_card *card; struct device *dev = &pdev->dev; const char *pname; - int ssp_port, ret; + int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); pname = mach->mach_params.platform; - ssp_port = __ffs(mach->mach_params.i2s_link_mask); - ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link); + ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); + if (ret) + return ret; + + ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); return ret; diff --git a/sound/soc/intel/avs/boards/i2s_test.c b/sound/soc/intel/avs/boards/i2s_test.c index bc3065c6ce..3d03e1eed3 100644 --- a/sound/soc/intel/avs/boards/i2s_test.c +++ b/sound/soc/intel/avs/boards/i2s_test.c @@ -12,9 +12,10 @@ #include <sound/soc.h> #include <sound/soc-acpi.h> #include <sound/soc-dapm.h> +#include "../utils.h" static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - struct snd_soc_dai_link **dai_link) + int tdm_slot, struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -26,13 +27,15 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + dl->name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); if (!dl->name || !dl->cpus) return -ENOMEM; - dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); - dl->codecs = &asoc_dummy_dlc; + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", " Pin", ssp_port, tdm_slot)); + dl->codecs = &snd_soc_dummy_dlc; if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) return -ENOMEM; @@ -51,7 +54,7 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in return 0; } -static int avs_create_dapm_routes(struct device *dev, int ssp_port, +static int avs_create_dapm_routes(struct device *dev, int ssp_port, int tdm_slot, struct snd_soc_dapm_route **routes, int *num_routes) { struct snd_soc_dapm_route *dr; @@ -61,13 +64,17 @@ static int avs_create_dapm_routes(struct device *dev, int ssp_port, if (!dr) return -ENOMEM; - dr[0].sink = devm_kasprintf(dev, GFP_KERNEL, "ssp%dpb", ssp_port); - dr[0].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); + dr[0].sink = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("ssp", "pb", ssp_port, tdm_slot)); + dr[0].source = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("ssp", " Tx", ssp_port, tdm_slot)); if (!dr[0].sink || !dr[0].source) return -ENOMEM; - dr[1].sink = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Rx", ssp_port); - dr[1].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%dcp", ssp_port); + dr[1].sink = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("ssp", " Rx", ssp_port, tdm_slot)); + dr[1].source = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("ssp", "cp", ssp_port, tdm_slot)); if (!dr[1].sink || !dr[1].source) return -ENOMEM; @@ -77,7 +84,7 @@ static int avs_create_dapm_routes(struct device *dev, int ssp_port, return 0; } -static int avs_create_dapm_widgets(struct device *dev, int ssp_port, +static int avs_create_dapm_widgets(struct device *dev, int ssp_port, int tdm_slot, struct snd_soc_dapm_widget **widgets, int *num_widgets) { struct snd_soc_dapm_widget *dw; @@ -89,13 +96,15 @@ static int avs_create_dapm_widgets(struct device *dev, int ssp_port, dw[0].id = snd_soc_dapm_hp; dw[0].reg = SND_SOC_NOPM; - dw[0].name = devm_kasprintf(dev, GFP_KERNEL, "ssp%dpb", ssp_port); + dw[0].name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("ssp", "pb", ssp_port, tdm_slot)); if (!dw[0].name) return -ENOMEM; dw[1].id = snd_soc_dapm_mic; dw[1].reg = SND_SOC_NOPM; - dw[1].name = devm_kasprintf(dev, GFP_KERNEL, "ssp%dcp", ssp_port); + dw[1].name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("ssp", "cp", ssp_port, tdm_slot)); if (!dw[1].name) return -ENOMEM; @@ -115,33 +124,45 @@ static int avs_i2s_test_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; const char *pname; int num_routes, num_widgets; - int ssp_port, ret; + int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); pname = mach->mach_params.platform; - ssp_port = __ffs(mach->mach_params.i2s_link_mask); + + if (!avs_mach_singular_ssp(mach)) { + dev_err(dev, "Invalid SSP configuration\n"); + return -EINVAL; + } + ssp_port = avs_mach_ssp_port(mach); + + if (!avs_mach_singular_tdm(mach, ssp_port)) { + dev_err(dev, "Invalid TDM configuration\n"); + return -EINVAL; + } + tdm_slot = avs_mach_ssp_tdm(mach, ssp_port); card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); if (!card) return -ENOMEM; - card->name = devm_kasprintf(dev, GFP_KERNEL, "ssp%d-loopback", ssp_port); + card->name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("ssp", "-loopback", ssp_port, tdm_slot)); if (!card->name) return -ENOMEM; - ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link); + ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d\n", ret); return ret; } - ret = avs_create_dapm_routes(dev, ssp_port, &routes, &num_routes); + ret = avs_create_dapm_routes(dev, ssp_port, tdm_slot, &routes, &num_routes); if (ret) { dev_err(dev, "Failed to create dapm routes: %d\n", ret); return ret; } - ret = avs_create_dapm_widgets(dev, ssp_port, &widgets, &num_widgets); + ret = avs_create_dapm_widgets(dev, ssp_port, tdm_slot, &widgets, &num_widgets); if (ret) { dev_err(dev, "Failed to create dapm widgets: %d\n", ret); return ret; diff --git a/sound/soc/intel/avs/boards/max98357a.c b/sound/soc/intel/avs/boards/max98357a.c index b9b20562c6..6ba7b65642 100644 --- a/sound/soc/intel/avs/boards/max98357a.c +++ b/sound/soc/intel/avs/boards/max98357a.c @@ -12,6 +12,7 @@ #include <sound/soc.h> #include <sound/soc-acpi.h> #include <sound/soc-dapm.h> +#include "../utils.h" static const struct snd_kcontrol_new card_controls[] = { SOC_DAPM_PIN_SWITCH("Spk"), @@ -46,7 +47,7 @@ avs_max98357a_be_fixup(struct snd_soc_pcm_runtime *runrime, struct snd_pcm_hw_pa } static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - struct snd_soc_dai_link **dai_link) + int tdm_slot, struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -58,13 +59,15 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + dl->name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL); if (!dl->name || !dl->cpus || !dl->codecs) return -ENOMEM; - dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", " Pin", ssp_port, tdm_slot)); dl->codecs->name = devm_kasprintf(dev, GFP_KERNEL, "MX98357A:00"); dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, "HiFi"); if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) @@ -93,13 +96,16 @@ static int avs_max98357a_probe(struct platform_device *pdev) struct snd_soc_card *card; struct device *dev = &pdev->dev; const char *pname; - int ssp_port, ret; + int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); pname = mach->mach_params.platform; - ssp_port = __ffs(mach->mach_params.i2s_link_mask); - ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link); + ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); + if (ret) + return ret; + + ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); return ret; diff --git a/sound/soc/intel/avs/boards/max98373.c b/sound/soc/intel/avs/boards/max98373.c index 3833251ade..cc7dfdf720 100644 --- a/sound/soc/intel/avs/boards/max98373.c +++ b/sound/soc/intel/avs/boards/max98373.c @@ -12,6 +12,7 @@ #include <sound/soc.h> #include <sound/soc-acpi.h> #include <sound/soc-dapm.h> +#include "../utils.h" #define MAX98373_DEV0_NAME "i2c-MX98373:00" #define MAX98373_DEV1_NAME "i2c-MX98373:01" @@ -66,7 +67,7 @@ avs_max98373_be_fixup(struct snd_soc_pcm_runtime *runrime, struct snd_pcm_hw_par static int avs_max98373_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *runtime = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *runtime = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; int ret, i; @@ -95,7 +96,7 @@ static const struct snd_soc_ops avs_max98373_ops = { }; static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - struct snd_soc_dai_link **dai_link) + int tdm_slot, struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -107,13 +108,15 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + dl->name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs) * 2, GFP_KERNEL); if (!dl->name || !dl->cpus || !dl->codecs) return -ENOMEM; - dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", " Pin", ssp_port, tdm_slot)); dl->codecs[0].name = devm_kasprintf(dev, GFP_KERNEL, MAX98373_DEV0_NAME); dl->codecs[0].dai_name = devm_kasprintf(dev, GFP_KERNEL, MAX98373_CODEC_NAME); dl->codecs[1].name = devm_kasprintf(dev, GFP_KERNEL, MAX98373_DEV1_NAME); @@ -148,13 +151,16 @@ static int avs_max98373_probe(struct platform_device *pdev) struct snd_soc_card *card; struct device *dev = &pdev->dev; const char *pname; - int ssp_port, ret; + int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); pname = mach->mach_params.platform; - ssp_port = __ffs(mach->mach_params.i2s_link_mask); - ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link); + ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); + if (ret) + return ret; + + ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); return ret; diff --git a/sound/soc/intel/avs/boards/max98927.c b/sound/soc/intel/avs/boards/max98927.c index 09b231bf4e..fb0175f37d 100644 --- a/sound/soc/intel/avs/boards/max98927.c +++ b/sound/soc/intel/avs/boards/max98927.c @@ -12,6 +12,7 @@ #include <sound/soc.h> #include <sound/soc-acpi.h> #include <sound/soc-dapm.h> +#include "../utils.h" #define MAX98927_DEV0_NAME "i2c-MX98927:00" #define MAX98927_DEV1_NAME "i2c-MX98927:01" @@ -66,7 +67,7 @@ avs_max98927_be_fixup(struct snd_soc_pcm_runtime *runrime, struct snd_pcm_hw_par static int avs_max98927_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *runtime = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *runtime = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; int ret = 0; int i; @@ -92,7 +93,7 @@ static const struct snd_soc_ops avs_max98927_ops = { }; static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - struct snd_soc_dai_link **dai_link) + int tdm_slot, struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -104,13 +105,15 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + dl->name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs) * 2, GFP_KERNEL); if (!dl->name || !dl->cpus || !dl->codecs) return -ENOMEM; - dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", " Pin", ssp_port, tdm_slot)); dl->codecs[0].name = devm_kasprintf(dev, GFP_KERNEL, MAX98927_DEV0_NAME); dl->codecs[0].dai_name = devm_kasprintf(dev, GFP_KERNEL, MAX98927_CODEC_NAME); dl->codecs[1].name = devm_kasprintf(dev, GFP_KERNEL, MAX98927_DEV1_NAME); @@ -145,13 +148,16 @@ static int avs_max98927_probe(struct platform_device *pdev) struct snd_soc_card *card; struct device *dev = &pdev->dev; const char *pname; - int ssp_port, ret; + int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); pname = mach->mach_params.platform; - ssp_port = __ffs(mach->mach_params.i2s_link_mask); - ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link); + ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); + if (ret) + return ret; + + ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); return ret; diff --git a/sound/soc/intel/avs/boards/nau8825.c b/sound/soc/intel/avs/boards/nau8825.c index 38c5087d98..d98b5deb78 100644 --- a/sound/soc/intel/avs/boards/nau8825.c +++ b/sound/soc/intel/avs/boards/nau8825.c @@ -16,6 +16,7 @@ #include <sound/soc.h> #include <sound/soc-acpi.h> #include "../../../codecs/nau8825.h" +#include "../utils.h" #define SKL_NUVOTON_CODEC_DAI "nau8825-hifi" @@ -106,12 +107,12 @@ static int avs_nau8825_codec_init(struct snd_soc_pcm_runtime *runtime) snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); - return snd_soc_component_set_jack(asoc_rtd_to_codec(runtime, 0)->component, jack, NULL); + return snd_soc_component_set_jack(snd_soc_rtd_to_codec(runtime, 0)->component, jack, NULL); } static void avs_nau8825_codec_exit(struct snd_soc_pcm_runtime *rtd) { - snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component, NULL, NULL); + snd_soc_component_set_jack(snd_soc_rtd_to_codec(rtd, 0)->component, NULL, NULL); } static int @@ -138,8 +139,8 @@ avs_nau8825_be_fixup(struct snd_soc_pcm_runtime *runtime, struct snd_pcm_hw_para static int avs_nau8825_trigger(struct snd_pcm_substream *substream, int cmd) { struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_soc_pcm_runtime *rtm = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtm, 0); + struct snd_soc_pcm_runtime *rtm = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtm, 0); int ret = 0; switch (cmd) { @@ -171,7 +172,7 @@ static const struct snd_soc_ops avs_nau8825_ops = { }; static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - struct snd_soc_dai_link **dai_link) + int tdm_slot, struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -183,13 +184,15 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + dl->name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL); if (!dl->name || !dl->cpus || !dl->codecs) return -ENOMEM; - dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", " Pin", ssp_port, tdm_slot)); dl->codecs->name = devm_kasprintf(dev, GFP_KERNEL, "i2c-10508825:00"); dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, SKL_NUVOTON_CODEC_DAI); if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) @@ -248,13 +251,16 @@ static int avs_nau8825_probe(struct platform_device *pdev) struct snd_soc_jack *jack; struct device *dev = &pdev->dev; const char *pname; - int ssp_port, ret; + int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); pname = mach->mach_params.platform; - ssp_port = __ffs(mach->mach_params.i2s_link_mask); - ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link); + ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); + if (ret) + return ret; + + ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); return ret; diff --git a/sound/soc/intel/avs/boards/rt274.c b/sound/soc/intel/avs/boards/rt274.c index ebfee54814..157183b1de 100644 --- a/sound/soc/intel/avs/boards/rt274.c +++ b/sound/soc/intel/avs/boards/rt274.c @@ -13,6 +13,7 @@ #include <sound/soc.h> #include <sound/soc-acpi.h> #include "../../../codecs/rt274.h" +#include "../utils.h" #define AVS_RT274_FREQ_OUT 24000000 #define AVS_RT274_BE_FIXUP_RATE 48000 @@ -87,7 +88,7 @@ static struct snd_soc_jack_pin card_headset_pins[] = { static int avs_rt274_codec_init(struct snd_soc_pcm_runtime *runtime) { - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(runtime, 0); struct snd_soc_component *component = codec_dai->component; struct snd_soc_jack_pin *pins; struct snd_soc_jack *jack; @@ -121,7 +122,7 @@ static int avs_rt274_codec_init(struct snd_soc_pcm_runtime *runtime) static void avs_rt274_codec_exit(struct snd_soc_pcm_runtime *rtd) { - snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component, NULL, NULL); + snd_soc_component_set_jack(snd_soc_rtd_to_codec(rtd, 0)->component, NULL, NULL); } static int avs_rt274_be_fixup(struct snd_soc_pcm_runtime *runtime, struct snd_pcm_hw_params *params) @@ -145,7 +146,7 @@ static int avs_rt274_be_fixup(struct snd_soc_pcm_runtime *runtime, struct snd_pc } static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - struct snd_soc_dai_link **dai_link) + int tdm_slot, struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -157,13 +158,15 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + dl->name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL); if (!dl->name || !dl->cpus || !dl->codecs) return -ENOMEM; - dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", " Pin", ssp_port, tdm_slot)); dl->codecs->name = devm_kasprintf(dev, GFP_KERNEL, "i2c-INT34C2:00"); dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, RT274_CODEC_DAI); if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) @@ -211,13 +214,16 @@ static int avs_rt274_probe(struct platform_device *pdev) struct snd_soc_jack *jack; struct device *dev = &pdev->dev; const char *pname; - int ssp_port, ret; + int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); pname = mach->mach_params.platform; - ssp_port = __ffs(mach->mach_params.i2s_link_mask); - ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link); + ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); + if (ret) + return ret; + + ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); return ret; diff --git a/sound/soc/intel/avs/boards/rt286.c b/sound/soc/intel/avs/boards/rt286.c index 84cf9a0c8d..131237471e 100644 --- a/sound/soc/intel/avs/boards/rt286.c +++ b/sound/soc/intel/avs/boards/rt286.c @@ -13,6 +13,7 @@ #include <sound/soc.h> #include <sound/soc-acpi.h> #include "../../../codecs/rt286.h" +#include "../utils.h" #define RT286_CODEC_DAI "rt286-aif1" @@ -67,12 +68,12 @@ static int avs_rt286_codec_init(struct snd_soc_pcm_runtime *runtime) if (ret) return ret; - return snd_soc_component_set_jack(asoc_rtd_to_codec(runtime, 0)->component, jack, NULL); + return snd_soc_component_set_jack(snd_soc_rtd_to_codec(runtime, 0)->component, jack, NULL); } static void avs_rt286_codec_exit(struct snd_soc_pcm_runtime *rtd) { - snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component, NULL, NULL); + snd_soc_component_set_jack(snd_soc_rtd_to_codec(rtd, 0)->component, NULL, NULL); } static int avs_rt286_be_fixup(struct snd_soc_pcm_runtime *runtime, struct snd_pcm_hw_params *params) @@ -98,8 +99,8 @@ static int avs_rt286_be_fixup(struct snd_soc_pcm_runtime *runtime, struct snd_pc static int avs_rt286_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *runtime = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, 0); + struct snd_soc_pcm_runtime *runtime = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(runtime, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, RT286_SCLK_S_PLL, 24000000, SND_SOC_CLOCK_IN); @@ -114,7 +115,7 @@ static const struct snd_soc_ops avs_rt286_ops = { }; static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - struct snd_soc_dai_link **dai_link) + int tdm_slot, struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -126,13 +127,15 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + dl->name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL); if (!dl->name || !dl->cpus || !dl->codecs) return -ENOMEM; - dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", " Pin", ssp_port, tdm_slot)); dl->codecs->name = devm_kasprintf(dev, GFP_KERNEL, "i2c-INT343A:00"); dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, RT286_CODEC_DAI); if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) @@ -181,13 +184,17 @@ static int avs_rt286_probe(struct platform_device *pdev) struct snd_soc_jack *jack; struct device *dev = &pdev->dev; const char *pname; - int ssp_port, ret; + int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); pname = mach->mach_params.platform; - ssp_port = __ffs(mach->mach_params.i2s_link_mask); - ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link); + ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); + if (ret) + return ret; + + ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); + if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); return ret; diff --git a/sound/soc/intel/avs/boards/rt298.c b/sound/soc/intel/avs/boards/rt298.c index 3b0e2b1a32..ea32a7690c 100644 --- a/sound/soc/intel/avs/boards/rt298.c +++ b/sound/soc/intel/avs/boards/rt298.c @@ -14,6 +14,7 @@ #include <sound/soc.h> #include <sound/soc-acpi.h> #include "../../../codecs/rt298.h" +#include "../utils.h" #define RT298_CODEC_DAI "rt298-aif1" @@ -78,12 +79,12 @@ static int avs_rt298_codec_init(struct snd_soc_pcm_runtime *runtime) if (ret) return ret; - return snd_soc_component_set_jack(asoc_rtd_to_codec(runtime, 0)->component, jack, NULL); + return snd_soc_component_set_jack(snd_soc_rtd_to_codec(runtime, 0)->component, jack, NULL); } static void avs_rt298_codec_exit(struct snd_soc_pcm_runtime *rtd) { - snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component, NULL, NULL); + snd_soc_component_set_jack(snd_soc_rtd_to_codec(rtd, 0)->component, NULL, NULL); } static int avs_rt298_be_fixup(struct snd_soc_pcm_runtime *runtime, struct snd_pcm_hw_params *params) @@ -109,8 +110,8 @@ static int avs_rt298_be_fixup(struct snd_soc_pcm_runtime *runtime, struct snd_pc static int avs_rt298_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); unsigned int clk_freq; int ret; @@ -131,7 +132,7 @@ static const struct snd_soc_ops avs_rt298_ops = { }; static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - struct snd_soc_dai_link **dai_link) + int tdm_slot, struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -143,13 +144,15 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + dl->name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL); if (!dl->name || !dl->cpus || !dl->codecs) return -ENOMEM; - dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", " Pin", ssp_port, tdm_slot)); dl->codecs->name = devm_kasprintf(dev, GFP_KERNEL, "i2c-INT343A:00"); dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, RT298_CODEC_DAI); if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) @@ -201,13 +204,16 @@ static int avs_rt298_probe(struct platform_device *pdev) struct snd_soc_jack *jack; struct device *dev = &pdev->dev; const char *pname; - int ssp_port, ret; + int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); pname = mach->mach_params.platform; - ssp_port = __ffs(mach->mach_params.i2s_link_mask); - ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link); + ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); + if (ret) + return ret; + + ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); return ret; diff --git a/sound/soc/intel/avs/boards/rt5514.c b/sound/soc/intel/avs/boards/rt5514.c new file mode 100644 index 0000000000..ad486a52e5 --- /dev/null +++ b/sound/soc/intel/avs/boards/rt5514.c @@ -0,0 +1,187 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2021-2023 Intel Corporation. All rights reserved. +// +// Authors: Cezary Rojewski <cezary.rojewski@intel.com> +// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com> +// + +#include <linux/clk.h> +#include <linux/input.h> +#include <linux/module.h> +#include <sound/jack.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> +#include <sound/soc-acpi.h> +#include "../../../codecs/rt5514.h" +#include "../utils.h" + +#define RT5514_CODEC_DAI "rt5514-aif1" + +static const struct snd_soc_dapm_widget card_widgets[] = { + SND_SOC_DAPM_MIC("DMIC", NULL), +}; + +static const struct snd_soc_dapm_route card_base_routes[] = { + /* DMIC */ + { "DMIC1L", NULL, "DMIC" }, + { "DMIC1R", NULL, "DMIC" }, + { "DMIC2L", NULL, "DMIC" }, + { "DMIC2R", NULL, "DMIC" }, +}; + +static int avs_rt5514_codec_init(struct snd_soc_pcm_runtime *runtime) +{ + int ret = snd_soc_dapm_ignore_suspend(&runtime->card->dapm, "DMIC"); + + if (ret) + dev_err(runtime->dev, "DMIC - Ignore suspend failed = %d\n", ret); + + return ret; +} + +static int avs_rt5514_be_fixup(struct snd_soc_pcm_runtime *runtime, + struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate, *channels; + struct snd_mask *fmt; + + rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); + channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + + rate->min = rate->max = 48000; + channels->min = channels->max = 4; + + snd_mask_none(fmt); + snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE); + + return 0; +} + +static int avs_rt5514_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); + int ret; + + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF, 0, 8, 16); + if (ret < 0) { + dev_err(rtd->dev, "set TDM slot err:%d\n", ret); + return ret; + } + + 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 sysclk err: %d\n", ret); + + return ret; +} + +static const struct snd_soc_ops avs_rt5514_ops = { + .hw_params = avs_rt5514_hw_params, +}; + +static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, + int tdm_slot, struct snd_soc_dai_link **dai_link) +{ + struct snd_soc_dai_link_component *platform; + struct snd_soc_dai_link *dl; + + dl = devm_kzalloc(dev, sizeof(*dl), GFP_KERNEL); + platform = devm_kzalloc(dev, sizeof(*platform), GFP_KERNEL); + if (!dl || !platform) + return -ENOMEM; + + platform->name = platform_name; + + dl->name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); + dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); + dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL); + if (!dl->name || !dl->cpus || !dl->codecs) + return -ENOMEM; + + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", " Pin", ssp_port, tdm_slot)); + dl->codecs->name = devm_kasprintf(dev, GFP_KERNEL, "i2c-10EC5514:00"); + dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, RT5514_CODEC_DAI); + if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) + return -ENOMEM; + + dl->num_cpus = 1; + dl->num_codecs = 1; + dl->platforms = platform; + dl->num_platforms = 1; + dl->id = 0; + dl->dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; + dl->init = avs_rt5514_codec_init; + dl->be_hw_params_fixup = avs_rt5514_be_fixup; + dl->nonatomic = 1; + dl->no_pcm = 1; + dl->dpcm_capture = 1; + dl->ops = &avs_rt5514_ops; + + *dai_link = dl; + + return 0; +} + +static int avs_rt5514_probe(struct platform_device *pdev) +{ + struct snd_soc_dai_link *dai_link; + struct snd_soc_acpi_mach *mach; + struct snd_soc_card *card; + struct device *dev = &pdev->dev; + const char *pname; + int ssp_port, tdm_slot, ret; + + mach = dev_get_platdata(dev); + pname = mach->mach_params.platform; + + ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); + if (ret) + return ret; + + ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); + if (ret) { + dev_err(dev, "Failed to create dai link: %d", ret); + return ret; + } + + card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); + if (!card) + return -ENOMEM; + + card->name = "avs_rt5514"; + card->dev = dev; + card->owner = THIS_MODULE; + card->dai_link = dai_link; + card->num_links = 1; + card->dapm_widgets = card_widgets; + card->num_dapm_widgets = ARRAY_SIZE(card_widgets); + card->dapm_routes = card_base_routes; + card->num_dapm_routes = ARRAY_SIZE(card_base_routes); + card->fully_routed = true; + + ret = snd_soc_fixup_dai_links_platform_name(card, pname); + if (ret) + return ret; + + return devm_snd_soc_register_card(dev, card); +} + +static struct platform_driver avs_rt5514_driver = { + .probe = avs_rt5514_probe, + .driver = { + .name = "avs_rt5514", + .pm = &snd_soc_pm_ops, + }, +}; + +module_platform_driver(avs_rt5514_driver); + +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:avs_rt5514"); diff --git a/sound/soc/intel/avs/boards/rt5663.c b/sound/soc/intel/avs/boards/rt5663.c index 770b36d05b..3effd789a4 100644 --- a/sound/soc/intel/avs/boards/rt5663.c +++ b/sound/soc/intel/avs/boards/rt5663.c @@ -15,6 +15,7 @@ #include <sound/soc.h> #include <sound/soc-acpi.h> #include "../../../codecs/rt5663.h" +#include "../utils.h" #define RT5663_CODEC_DAI "rt5663-aif" @@ -79,14 +80,14 @@ static int avs_rt5663_codec_init(struct snd_soc_pcm_runtime *runtime) snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); - snd_soc_component_set_jack(asoc_rtd_to_codec(runtime, 0)->component, jack, NULL); + snd_soc_component_set_jack(snd_soc_rtd_to_codec(runtime, 0)->component, jack, NULL); return 0; } static void avs_rt5663_codec_exit(struct snd_soc_pcm_runtime *runtime) { - snd_soc_component_set_jack(asoc_rtd_to_codec(runtime, 0)->component, NULL, NULL); + snd_soc_component_set_jack(snd_soc_rtd_to_codec(runtime, 0)->component, NULL, NULL); } static int @@ -113,8 +114,8 @@ avs_rt5663_be_fixup(struct snd_soc_pcm_runtime *runtime, struct snd_pcm_hw_param static int avs_rt5663_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; /* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */ @@ -133,7 +134,7 @@ static const struct snd_soc_ops avs_rt5663_ops = { static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - struct snd_soc_dai_link **dai_link) + int tdm_slot, struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -145,13 +146,15 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + dl->name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL); if (!dl->name || !dl->cpus || !dl->codecs) return -ENOMEM; - dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", " Pin", ssp_port, tdm_slot)); dl->codecs->name = devm_kasprintf(dev, GFP_KERNEL, "i2c-10EC5663:00"); dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, RT5663_CODEC_DAI); if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) @@ -200,13 +203,16 @@ static int avs_rt5663_probe(struct platform_device *pdev) struct rt5663_private *priv; struct device *dev = &pdev->dev; const char *pname; - int ssp_port, ret; + int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); pname = mach->mach_params.platform; - ssp_port = __ffs(mach->mach_params.i2s_link_mask); - ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link); + ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); + if (ret) + return ret; + + ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); return ret; diff --git a/sound/soc/intel/avs/boards/rt5682.c b/sound/soc/intel/avs/boards/rt5682.c index b93468ae09..84e850c0b0 100644 --- a/sound/soc/intel/avs/boards/rt5682.c +++ b/sound/soc/intel/avs/boards/rt5682.c @@ -21,6 +21,7 @@ #include <sound/soc-acpi.h> #include "../../common/soc-intel-quirks.h" #include "../../../codecs/rt5682.h" +#include "../utils.h" #define AVS_RT5682_SSP_CODEC(quirk) ((quirk) & GENMASK(2, 0)) #define AVS_RT5682_SSP_CODEC_MASK (GENMASK(2, 0)) @@ -92,7 +93,7 @@ static struct snd_soc_jack_pin card_jack_pins[] = { static int avs_rt5682_codec_init(struct snd_soc_pcm_runtime *runtime) { - struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(runtime, 0)->component; struct snd_soc_card *card = runtime->card; struct snd_soc_jack_pin *pins; struct snd_soc_jack *jack; @@ -137,14 +138,14 @@ static int avs_rt5682_codec_init(struct snd_soc_pcm_runtime *runtime) static void avs_rt5682_codec_exit(struct snd_soc_pcm_runtime *rtd) { - snd_soc_component_set_jack(asoc_rtd_to_codec(rtd, 0)->component, NULL, NULL); + snd_soc_component_set_jack(snd_soc_rtd_to_codec(rtd, 0)->component, NULL, NULL); } static int avs_rt5682_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *runtime = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, 0); + struct snd_soc_pcm_runtime *runtime = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(runtime, 0); int pll_source, freq_in, freq_out; int ret; @@ -203,7 +204,7 @@ avs_rt5682_be_fixup(struct snd_soc_pcm_runtime *runtime, struct snd_pcm_hw_param } static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - struct snd_soc_dai_link **dai_link) + int tdm_slot, struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -215,13 +216,15 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + dl->name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL); if (!dl->name || !dl->cpus || !dl->codecs) return -ENOMEM; - dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", " Pin", ssp_port, tdm_slot)); dl->codecs->name = devm_kasprintf(dev, GFP_KERNEL, "i2c-10EC5682:00"); dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, AVS_RT5682_CODEC_DAI_NAME); if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) @@ -270,7 +273,7 @@ static int avs_rt5682_probe(struct platform_device *pdev) struct snd_soc_jack *jack; struct device *dev = &pdev->dev; const char *pname; - int ssp_port, ret; + int ssp_port, tdm_slot, ret; if (pdev->id_entry && pdev->id_entry->driver_data) avs_rt5682_quirk = (unsigned long)pdev->id_entry->driver_data; @@ -280,9 +283,12 @@ static int avs_rt5682_probe(struct platform_device *pdev) mach = dev_get_platdata(dev); pname = mach->mach_params.platform; - ssp_port = __ffs(mach->mach_params.i2s_link_mask); - ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link); + ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); + if (ret) + return ret; + + ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); return ret; diff --git a/sound/soc/intel/avs/boards/ssm4567.c b/sound/soc/intel/avs/boards/ssm4567.c index 7324869d61..6bcab9deae 100644 --- a/sound/soc/intel/avs/boards/ssm4567.c +++ b/sound/soc/intel/avs/boards/ssm4567.c @@ -14,6 +14,7 @@ #include <sound/soc.h> #include <sound/soc-acpi.h> #include "../../../codecs/nau8825.h" +#include "../utils.h" #define SKL_SSM_CODEC_DAI "ssm4567-hifi" @@ -50,12 +51,12 @@ static int avs_ssm4567_codec_init(struct snd_soc_pcm_runtime *runtime) int ret; /* Slot 1 for left */ - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(runtime, 0), 0x01, 0x01, 2, 48); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_codec(runtime, 0), 0x01, 0x01, 2, 48); if (ret < 0) return ret; /* Slot 2 for right */ - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(runtime, 1), 0x02, 0x02, 2, 48); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_codec(runtime, 1), 0x02, 0x02, 2, 48); if (ret < 0) return ret; @@ -83,7 +84,7 @@ avs_ssm4567_be_fixup(struct snd_soc_pcm_runtime *runrime, struct snd_pcm_hw_para } static int avs_create_dai_link(struct device *dev, const char *platform_name, int ssp_port, - struct snd_soc_dai_link **dai_link) + int tdm_slot, struct snd_soc_dai_link **dai_link) { struct snd_soc_dai_link_component *platform; struct snd_soc_dai_link *dl; @@ -95,13 +96,15 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in platform->name = platform_name; - dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); + dl->name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", "-Codec", ssp_port, tdm_slot)); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs) * 2, GFP_KERNEL); if (!dl->name || !dl->cpus || !dl->codecs) return -ENOMEM; - dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); + dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, + AVS_STRING_FMT("SSP", " Pin", ssp_port, tdm_slot)); dl->codecs[0].name = devm_kasprintf(dev, GFP_KERNEL, "i2c-INT343B:00"); dl->codecs[0].dai_name = devm_kasprintf(dev, GFP_KERNEL, "ssm4567-hifi"); dl->codecs[1].name = devm_kasprintf(dev, GFP_KERNEL, "i2c-INT343B:01"); @@ -136,13 +139,16 @@ static int avs_ssm4567_probe(struct platform_device *pdev) struct snd_soc_card *card; struct device *dev = &pdev->dev; const char *pname; - int ssp_port, ret; + int ssp_port, tdm_slot, ret; mach = dev_get_platdata(dev); pname = mach->mach_params.platform; - ssp_port = __ffs(mach->mach_params.i2s_link_mask); - ret = avs_create_dai_link(dev, pname, ssp_port, &dai_link); + ret = avs_mach_get_ssp_tdm(dev, mach, &ssp_port, &tdm_slot); + if (ret) + return ret; + + ret = avs_create_dai_link(dev, pname, ssp_port, tdm_slot, &dai_link); if (ret) { dev_err(dev, "Failed to create dai link: %d", ret); return ret; diff --git a/sound/soc/intel/avs/cldma.h b/sound/soc/intel/avs/cldma.h index 754fcf9ee5..223d3431ab 100644 --- a/sound/soc/intel/avs/cldma.h +++ b/sound/soc/intel/avs/cldma.h @@ -8,7 +8,9 @@ #ifndef __SOUND_SOC_INTEL_AVS_CLDMA_H #define __SOUND_SOC_INTEL_AVS_CLDMA_H -#define AVS_CL_DEFAULT_BUFFER_SIZE (32 * PAGE_SIZE) +#include <linux/sizes.h> + +#define AVS_CL_DEFAULT_BUFFER_SIZE SZ_128K struct hda_cldma; extern struct hda_cldma code_loader; diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c index 859b217fc7..db78eb2f01 100644 --- a/sound/soc/intel/avs/core.c +++ b/sound/soc/intel/avs/core.c @@ -26,6 +26,7 @@ #include "../../codecs/hda.h" #include "avs.h" #include "cldma.h" +#include "messages.h" static u32 pgctl_mask = AZX_PGCTL_LSRMD_MASK; module_param(pgctl_mask, uint, 0444); @@ -191,10 +192,6 @@ static void avs_hda_probe_work(struct work_struct *work) pm_runtime_set_active(bus->dev); /* clear runtime_error flag */ - ret = snd_hdac_i915_init(bus); - if (ret < 0) - dev_info(bus->dev, "i915 init unsuccessful: %d\n", ret); - snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, true); avs_hdac_bus_init_chip(bus, true); avs_hdac_bus_probe_codecs(bus); @@ -380,6 +377,10 @@ static int avs_bus_init(struct avs_dev *adev, struct pci_dev *pci, const struct if (ret < 0) return ret; + adev->modcfg_buf = devm_kzalloc(dev, AVS_MAILBOX_SIZE, GFP_KERNEL); + if (!adev->modcfg_buf) + return -ENOMEM; + adev->dev = dev; adev->spec = (const struct avs_spec *)id->driver_data; adev->ipc = ipc; @@ -465,10 +466,22 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) pci_set_drvdata(pci, bus); device_disable_async_suspend(dev); + ret = snd_hdac_i915_init(bus); + if (ret == -EPROBE_DEFER) + goto err_i915_init; + else if (ret < 0) + dev_info(bus->dev, "i915 init unsuccessful: %d\n", ret); + schedule_work(&adev->probe_work); return 0; +err_i915_init: + pci_free_irq(pci, 0, adev); + pci_free_irq(pci, 0, bus); + pci_free_irq_vectors(pci); + pci_clear_master(pci); + pci_set_drvdata(pci, NULL); err_acquire_irq: snd_hdac_bus_free_stream_pages(bus); snd_hdac_ext_stream_free_all(bus); diff --git a/sound/soc/intel/avs/debugfs.c b/sound/soc/intel/avs/debugfs.c index bdd388ec01..4dfbff0ce5 100644 --- a/sound/soc/intel/avs/debugfs.c +++ b/sound/soc/intel/avs/debugfs.c @@ -236,6 +236,9 @@ static int strace_open(struct inode *inode, struct file *file) struct avs_dev *adev = inode->i_private; int ret; + if (!try_module_get(adev->dev->driver->owner)) + return -ENODEV; + if (kfifo_initialized(&adev->trace_fifo)) return -EBUSY; @@ -270,6 +273,7 @@ static int strace_release(struct inode *inode, struct file *file) spin_unlock_irqrestore(&adev->trace_lock, flags); + module_put(adev->dev->driver->owner); return 0; } diff --git a/sound/soc/intel/avs/ipc.c b/sound/soc/intel/avs/ipc.c index bdf013c3dd..65bfc83bd1 100644 --- a/sound/soc/intel/avs/ipc.c +++ b/sound/soc/intel/avs/ipc.c @@ -455,7 +455,7 @@ static void avs_dsp_send_tx(struct avs_dev *adev, struct avs_ipc_msg *tx, bool r } static int avs_dsp_do_send_msg(struct avs_dev *adev, struct avs_ipc_msg *request, - struct avs_ipc_msg *reply, int timeout) + struct avs_ipc_msg *reply, int timeout, const char *name) { struct avs_ipc *ipc = adev->ipc; int ret; @@ -482,6 +482,19 @@ static int avs_dsp_do_send_msg(struct avs_dev *adev, struct avs_ipc_msg *request } ret = ipc->rx.rsp.status; + /* + * If IPC channel is blocked e.g.: due to ongoing recovery, + * -EPERM error code is expected and thus it's not an actual error. + * + * Unsupported IPCs are of no harm either. + */ + if (ret == -EPERM || ret == AVS_IPC_NOT_SUPPORTED) + dev_dbg(adev->dev, "%s (0x%08x 0x%08x) failed: %d\n", + name, request->glb.primary, request->glb.ext.val, ret); + else if (ret) + dev_err(adev->dev, "%s (0x%08x 0x%08x) failed: %d\n", + name, request->glb.primary, request->glb.ext.val, ret); + if (reply) { reply->header = ipc->rx.header; reply->size = ipc->rx.size; @@ -496,7 +509,7 @@ exit: static int avs_dsp_send_msg_sequence(struct avs_dev *adev, struct avs_ipc_msg *request, struct avs_ipc_msg *reply, int timeout, bool wake_d0i0, - bool schedule_d0ix) + bool schedule_d0ix, const char *name) { int ret; @@ -507,7 +520,7 @@ static int avs_dsp_send_msg_sequence(struct avs_dev *adev, struct avs_ipc_msg *r return ret; } - ret = avs_dsp_do_send_msg(adev, request, reply, timeout); + ret = avs_dsp_do_send_msg(adev, request, reply, timeout, name); if (ret) return ret; @@ -519,34 +532,37 @@ static int avs_dsp_send_msg_sequence(struct avs_dev *adev, struct avs_ipc_msg *r } int avs_dsp_send_msg_timeout(struct avs_dev *adev, struct avs_ipc_msg *request, - struct avs_ipc_msg *reply, int timeout) + struct avs_ipc_msg *reply, int timeout, const char *name) { bool wake_d0i0 = avs_dsp_op(adev, d0ix_toggle, request, true); bool schedule_d0ix = avs_dsp_op(adev, d0ix_toggle, request, false); - return avs_dsp_send_msg_sequence(adev, request, reply, timeout, wake_d0i0, schedule_d0ix); + return avs_dsp_send_msg_sequence(adev, request, reply, timeout, wake_d0i0, schedule_d0ix, + name); } int avs_dsp_send_msg(struct avs_dev *adev, struct avs_ipc_msg *request, - struct avs_ipc_msg *reply) + struct avs_ipc_msg *reply, const char *name) { - return avs_dsp_send_msg_timeout(adev, request, reply, adev->ipc->default_timeout_ms); + return avs_dsp_send_msg_timeout(adev, request, reply, adev->ipc->default_timeout_ms, name); } int avs_dsp_send_pm_msg_timeout(struct avs_dev *adev, struct avs_ipc_msg *request, - struct avs_ipc_msg *reply, int timeout, bool wake_d0i0) + struct avs_ipc_msg *reply, int timeout, bool wake_d0i0, + const char *name) { - return avs_dsp_send_msg_sequence(adev, request, reply, timeout, wake_d0i0, false); + return avs_dsp_send_msg_sequence(adev, request, reply, timeout, wake_d0i0, false, name); } int avs_dsp_send_pm_msg(struct avs_dev *adev, struct avs_ipc_msg *request, - struct avs_ipc_msg *reply, bool wake_d0i0) + struct avs_ipc_msg *reply, bool wake_d0i0, const char *name) { return avs_dsp_send_pm_msg_timeout(adev, request, reply, adev->ipc->default_timeout_ms, - wake_d0i0); + wake_d0i0, name); } -static int avs_dsp_do_send_rom_msg(struct avs_dev *adev, struct avs_ipc_msg *request, int timeout) +static int avs_dsp_do_send_rom_msg(struct avs_dev *adev, struct avs_ipc_msg *request, int timeout, + const char *name) { struct avs_ipc *ipc = adev->ipc; int ret; @@ -568,20 +584,24 @@ static int avs_dsp_do_send_rom_msg(struct avs_dev *adev, struct avs_ipc_msg *req ret = wait_for_completion_timeout(&ipc->done_completion, msecs_to_jiffies(timeout)); ret = ret ? 0 : -ETIMEDOUT; } + if (ret) + dev_err(adev->dev, "%s (0x%08x 0x%08x) failed: %d\n", + name, request->glb.primary, request->glb.ext.val, ret); mutex_unlock(&ipc->msg_mutex); return ret; } -int avs_dsp_send_rom_msg_timeout(struct avs_dev *adev, struct avs_ipc_msg *request, int timeout) +int avs_dsp_send_rom_msg_timeout(struct avs_dev *adev, struct avs_ipc_msg *request, int timeout, + const char *name) { - return avs_dsp_do_send_rom_msg(adev, request, timeout); + return avs_dsp_do_send_rom_msg(adev, request, timeout, name); } -int avs_dsp_send_rom_msg(struct avs_dev *adev, struct avs_ipc_msg *request) +int avs_dsp_send_rom_msg(struct avs_dev *adev, struct avs_ipc_msg *request, const char *name) { - return avs_dsp_send_rom_msg_timeout(adev, request, adev->ipc->default_timeout_ms); + return avs_dsp_send_rom_msg_timeout(adev, request, adev->ipc->default_timeout_ms, name); } void avs_dsp_interrupt_control(struct avs_dev *adev, bool enable) diff --git a/sound/soc/intel/avs/loader.c b/sound/soc/intel/avs/loader.c index 56bb0a5924..65dd8f140f 100644 --- a/sound/soc/intel/avs/loader.c +++ b/sound/soc/intel/avs/loader.c @@ -662,6 +662,10 @@ int avs_dsp_first_boot_firmware(struct avs_dev *adev) } } + ret = avs_dsp_core_disable(adev, AVS_MAIN_CORE_MASK); + if (ret < 0) + return ret; + ret = avs_dsp_boot_firmware(adev, true); if (ret < 0) { dev_err(adev->dev, "firmware boot failed: %d\n", ret); diff --git a/sound/soc/intel/avs/messages.c b/sound/soc/intel/avs/messages.c index f887ab5b03..06b4394cab 100644 --- a/sound/soc/intel/avs/messages.c +++ b/sound/soc/intel/avs/messages.c @@ -16,71 +16,52 @@ int avs_ipc_set_boot_config(struct avs_dev *adev, u32 dma_id, u32 purge) { union avs_global_msg msg = AVS_GLOBAL_REQUEST(ROM_CONTROL); struct avs_ipc_msg request = {{0}}; - int ret; msg.boot_cfg.rom_ctrl_msg_type = AVS_ROM_SET_BOOT_CONFIG; msg.boot_cfg.dma_id = dma_id; msg.boot_cfg.purge_request = purge; request.header = msg.val; - ret = avs_dsp_send_rom_msg(adev, &request); - if (ret) - avs_ipc_err(adev, &request, "set boot config", ret); - - return ret; + return avs_dsp_send_rom_msg(adev, &request, "set boot config"); } int avs_ipc_load_modules(struct avs_dev *adev, u16 *mod_ids, u32 num_mod_ids) { union avs_global_msg msg = AVS_GLOBAL_REQUEST(LOAD_MULTIPLE_MODULES); struct avs_ipc_msg request; - int ret; msg.load_multi_mods.mod_cnt = num_mod_ids; request.header = msg.val; request.data = mod_ids; request.size = sizeof(*mod_ids) * num_mod_ids; - ret = avs_dsp_send_msg_timeout(adev, &request, NULL, AVS_CL_TIMEOUT_MS); - if (ret) - avs_ipc_err(adev, &request, "load multiple modules", ret); - - return ret; + return avs_dsp_send_msg_timeout(adev, &request, NULL, AVS_CL_TIMEOUT_MS, + "load multiple modules"); } int avs_ipc_unload_modules(struct avs_dev *adev, u16 *mod_ids, u32 num_mod_ids) { union avs_global_msg msg = AVS_GLOBAL_REQUEST(UNLOAD_MULTIPLE_MODULES); struct avs_ipc_msg request; - int ret; msg.load_multi_mods.mod_cnt = num_mod_ids; request.header = msg.val; request.data = mod_ids; request.size = sizeof(*mod_ids) * num_mod_ids; - ret = avs_dsp_send_msg(adev, &request, NULL); - if (ret) - avs_ipc_err(adev, &request, "unload multiple modules", ret); - - return ret; + return avs_dsp_send_msg(adev, &request, NULL, "unload multiple modules"); } int avs_ipc_load_library(struct avs_dev *adev, u32 dma_id, u32 lib_id) { union avs_global_msg msg = AVS_GLOBAL_REQUEST(LOAD_LIBRARY); struct avs_ipc_msg request = {{0}}; - int ret; msg.load_lib.dma_id = dma_id; msg.load_lib.lib_id = lib_id; request.header = msg.val; - ret = avs_dsp_send_msg_timeout(adev, &request, NULL, AVS_CL_TIMEOUT_MS); - if (ret) - avs_ipc_err(adev, &request, "load library", ret); - - return ret; + return avs_dsp_send_msg_timeout(adev, &request, NULL, AVS_CL_TIMEOUT_MS, "load library"); } int avs_ipc_create_pipeline(struct avs_dev *adev, u16 req_size, u8 priority, @@ -88,7 +69,6 @@ int avs_ipc_create_pipeline(struct avs_dev *adev, u16 req_size, u8 priority, { union avs_global_msg msg = AVS_GLOBAL_REQUEST(CREATE_PIPELINE); struct avs_ipc_msg request = {{0}}; - int ret; msg.create_ppl.ppl_mem_size = req_size; msg.create_ppl.ppl_priority = priority; @@ -97,27 +77,18 @@ int avs_ipc_create_pipeline(struct avs_dev *adev, u16 req_size, u8 priority, msg.ext.create_ppl.attributes = attributes; request.header = msg.val; - ret = avs_dsp_send_msg(adev, &request, NULL); - if (ret) - avs_ipc_err(adev, &request, "create pipeline", ret); - - return ret; + return avs_dsp_send_msg(adev, &request, NULL, "create pipeline"); } int avs_ipc_delete_pipeline(struct avs_dev *adev, u8 instance_id) { union avs_global_msg msg = AVS_GLOBAL_REQUEST(DELETE_PIPELINE); struct avs_ipc_msg request = {{0}}; - int ret; msg.ppl.instance_id = instance_id; request.header = msg.val; - ret = avs_dsp_send_msg(adev, &request, NULL); - if (ret) - avs_ipc_err(adev, &request, "delete pipeline", ret); - - return ret; + return avs_dsp_send_msg(adev, &request, NULL, "delete pipeline"); } int avs_ipc_set_pipeline_state(struct avs_dev *adev, u8 instance_id, @@ -125,17 +96,12 @@ int avs_ipc_set_pipeline_state(struct avs_dev *adev, u8 instance_id, { union avs_global_msg msg = AVS_GLOBAL_REQUEST(SET_PIPELINE_STATE); struct avs_ipc_msg request = {{0}}; - int ret; msg.set_ppl_state.ppl_id = instance_id; msg.set_ppl_state.state = state; request.header = msg.val; - ret = avs_dsp_send_msg(adev, &request, NULL); - if (ret) - avs_ipc_err(adev, &request, "set pipeline state", ret); - - return ret; + return avs_dsp_send_msg(adev, &request, NULL, "set pipeline state"); } int avs_ipc_get_pipeline_state(struct avs_dev *adev, u8 instance_id, @@ -149,13 +115,9 @@ int avs_ipc_get_pipeline_state(struct avs_dev *adev, u8 instance_id, msg.get_ppl_state.ppl_id = instance_id; request.header = msg.val; - ret = avs_dsp_send_msg(adev, &request, &reply); - if (ret) { - avs_ipc_err(adev, &request, "get pipeline state", ret); - return ret; - } - - *state = reply.rsp.ext.get_ppl_state.state; + ret = avs_dsp_send_msg(adev, &request, &reply, "get pipeline state"); + if (!ret) + *state = reply.rsp.ext.get_ppl_state.state; return ret; } @@ -183,7 +145,6 @@ int avs_ipc_init_instance(struct avs_dev *adev, u16 module_id, u8 instance_id, { union avs_module_msg msg = AVS_MODULE_REQUEST(INIT_INSTANCE); struct avs_ipc_msg request; - int ret; msg.module_id = module_id; msg.instance_id = instance_id; @@ -197,11 +158,7 @@ int avs_ipc_init_instance(struct avs_dev *adev, u16 module_id, u8 instance_id, request.data = param; request.size = param_size; - ret = avs_dsp_send_msg(adev, &request, NULL); - if (ret) - avs_ipc_err(adev, &request, "init instance", ret); - - return ret; + return avs_dsp_send_msg(adev, &request, NULL, "init instance"); } /* @@ -222,17 +179,12 @@ int avs_ipc_delete_instance(struct avs_dev *adev, u16 module_id, u8 instance_id) { union avs_module_msg msg = AVS_MODULE_REQUEST(DELETE_INSTANCE); struct avs_ipc_msg request = {{0}}; - int ret; msg.module_id = module_id; msg.instance_id = instance_id; request.header = msg.val; - ret = avs_dsp_send_msg(adev, &request, NULL); - if (ret) - avs_ipc_err(adev, &request, "delete instance", ret); - - return ret; + return avs_dsp_send_msg(adev, &request, NULL, "delete instance"); } /* @@ -252,7 +204,6 @@ int avs_ipc_bind(struct avs_dev *adev, u16 module_id, u8 instance_id, { union avs_module_msg msg = AVS_MODULE_REQUEST(BIND); struct avs_ipc_msg request = {{0}}; - int ret; msg.module_id = module_id; msg.instance_id = instance_id; @@ -262,11 +213,7 @@ int avs_ipc_bind(struct avs_dev *adev, u16 module_id, u8 instance_id, msg.ext.bind_unbind.src_queue = src_queue; request.header = msg.val; - ret = avs_dsp_send_msg(adev, &request, NULL); - if (ret) - avs_ipc_err(adev, &request, "bind modules", ret); - - return ret; + return avs_dsp_send_msg(adev, &request, NULL, "bind modules"); } /* @@ -286,7 +233,6 @@ int avs_ipc_unbind(struct avs_dev *adev, u16 module_id, u8 instance_id, { union avs_module_msg msg = AVS_MODULE_REQUEST(UNBIND); struct avs_ipc_msg request = {{0}}; - int ret; msg.module_id = module_id; msg.instance_id = instance_id; @@ -296,11 +242,7 @@ int avs_ipc_unbind(struct avs_dev *adev, u16 module_id, u8 instance_id, msg.ext.bind_unbind.src_queue = src_queue; request.header = msg.val; - ret = avs_dsp_send_msg(adev, &request, NULL); - if (ret) - avs_ipc_err(adev, &request, "unbind modules", ret); - - return ret; + return avs_dsp_send_msg(adev, &request, NULL, "unbind modules"); } static int __avs_ipc_set_large_config(struct avs_dev *adev, u16 module_id, u8 instance_id, @@ -309,7 +251,6 @@ static int __avs_ipc_set_large_config(struct avs_dev *adev, u16 module_id, u8 in { union avs_module_msg msg = AVS_MODULE_REQUEST(LARGE_CONFIG_SET); struct avs_ipc_msg request; - int ret; msg.module_id = module_id; msg.instance_id = instance_id; @@ -322,11 +263,7 @@ static int __avs_ipc_set_large_config(struct avs_dev *adev, u16 module_id, u8 in request.data = request_data; request.size = request_size; - ret = avs_dsp_send_msg(adev, &request, NULL); - if (ret) - avs_ipc_err(adev, &request, "large config set", ret); - - return ret; + return avs_dsp_send_msg(adev, &request, NULL, "large config set"); } int avs_ipc_set_large_config(struct avs_dev *adev, u16 module_id, @@ -398,9 +335,8 @@ int avs_ipc_get_large_config(struct avs_dev *adev, u16 module_id, u8 instance_id request.size = request_size; reply.size = AVS_MAILBOX_SIZE; - ret = avs_dsp_send_msg(adev, &request, &reply); + ret = avs_dsp_send_msg(adev, &request, &reply, "large config get"); if (ret) { - avs_ipc_err(adev, &request, "large config get", ret); kfree(reply.data); return ret; } @@ -422,7 +358,6 @@ int avs_ipc_set_dx(struct avs_dev *adev, u32 core_mask, bool powerup) union avs_module_msg msg = AVS_MODULE_REQUEST(SET_DX); struct avs_ipc_msg request; struct avs_dxstate_info dx; - int ret; dx.core_mask = core_mask; dx.dx_mask = powerup ? core_mask : 0; @@ -430,11 +365,7 @@ int avs_ipc_set_dx(struct avs_dev *adev, u32 core_mask, bool powerup) request.data = &dx; request.size = sizeof(dx); - ret = avs_dsp_send_pm_msg(adev, &request, NULL, true); - if (ret) - avs_ipc_err(adev, &request, "set dx", ret); - - return ret; + return avs_dsp_send_pm_msg(adev, &request, NULL, true, "set dx"); } /* @@ -447,18 +378,13 @@ int avs_ipc_set_d0ix(struct avs_dev *adev, bool enable_pg, bool streaming) { union avs_module_msg msg = AVS_MODULE_REQUEST(SET_D0IX); struct avs_ipc_msg request = {{0}}; - int ret; msg.ext.set_d0ix.wake = enable_pg; msg.ext.set_d0ix.streaming = streaming; request.header = msg.val; - ret = avs_dsp_send_pm_msg(adev, &request, NULL, false); - if (ret) - avs_ipc_err(adev, &request, "set d0ix", ret); - - return ret; + return avs_dsp_send_pm_msg(adev, &request, NULL, false, "set d0ix"); } int avs_ipc_get_fw_config(struct avs_dev *adev, struct avs_fw_cfg *cfg) diff --git a/sound/soc/intel/avs/messages.h b/sound/soc/intel/avs/messages.h index 7f23a304b4..d0344e242e 100644 --- a/sound/soc/intel/avs/messages.h +++ b/sound/soc/intel/avs/messages.h @@ -9,9 +9,11 @@ #ifndef __SOUND_SOC_INTEL_AVS_MSGS_H #define __SOUND_SOC_INTEL_AVS_MSGS_H +#include <linux/sizes.h> + struct avs_dev; -#define AVS_MAILBOX_SIZE 4096 +#define AVS_MAILBOX_SIZE SZ_4K enum avs_msg_target { AVS_FW_GEN_MSG = 0, diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c index adbe23a478..aa8b50b931 100644 --- a/sound/soc/intel/avs/path.c +++ b/sound/soc/intel/avs/path.c @@ -237,11 +237,11 @@ static int avs_copier_create(struct avs_dev *adev, struct avs_path_module *mod) /* Every config-BLOB contains gateway attributes. */ if (data_size) cfg_size -= sizeof(cfg->gtw_cfg.config.attrs); + if (cfg_size > AVS_MAILBOX_SIZE) + return -EINVAL; - cfg = kzalloc(cfg_size, GFP_KERNEL); - if (!cfg) - return -ENOMEM; - + cfg = adev->modcfg_buf; + memset(cfg, 0, cfg_size); cfg->base.cpc = t->cfg_base->cpc; cfg->base.ibs = t->cfg_base->ibs; cfg->base.obs = t->cfg_base->obs; @@ -261,7 +261,6 @@ static int avs_copier_create(struct avs_dev *adev, struct avs_path_module *mod) ret = avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id, t->core_id, t->domain, cfg, cfg_size, &mod->instance_id); - kfree(cfg); return ret; } @@ -294,7 +293,7 @@ static int avs_peakvol_create(struct avs_dev *adev, struct avs_path_module *mod) struct avs_control_data *ctl_data; struct avs_peakvol_cfg *cfg; int volume = S32_MAX; - size_t size; + size_t cfg_size; int ret; ctl_data = avs_get_module_control(mod); @@ -302,11 +301,12 @@ static int avs_peakvol_create(struct avs_dev *adev, struct avs_path_module *mod) volume = ctl_data->volume; /* As 2+ channels controls are unsupported, have a single block for all channels. */ - size = struct_size(cfg, vols, 1); - cfg = kzalloc(size, GFP_KERNEL); - if (!cfg) - return -ENOMEM; + cfg_size = struct_size(cfg, vols, 1); + if (cfg_size > AVS_MAILBOX_SIZE) + return -EINVAL; + cfg = adev->modcfg_buf; + memset(cfg, 0, cfg_size); cfg->base.cpc = t->cfg_base->cpc; cfg->base.ibs = t->cfg_base->ibs; cfg->base.obs = t->cfg_base->obs; @@ -318,9 +318,8 @@ static int avs_peakvol_create(struct avs_dev *adev, struct avs_path_module *mod) cfg->vols[0].curve_duration = 0; ret = avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id, t->core_id, - t->domain, cfg, size, &mod->instance_id); + t->domain, cfg, cfg_size, &mod->instance_id); - kfree(cfg); return ret; } @@ -480,10 +479,11 @@ static int avs_modext_create(struct avs_dev *adev, struct avs_path_module *mod) num_pins = tcfg->generic.num_input_pins + tcfg->generic.num_output_pins; cfg_size = struct_size(cfg, pin_fmts, num_pins); - cfg = kzalloc(cfg_size, GFP_KERNEL); - if (!cfg) - return -ENOMEM; + if (cfg_size > AVS_MAILBOX_SIZE) + return -EINVAL; + cfg = adev->modcfg_buf; + memset(cfg, 0, cfg_size); cfg->base.cpc = t->cfg_base->cpc; cfg->base.ibs = t->cfg_base->ibs; cfg->base.obs = t->cfg_base->obs; @@ -505,7 +505,6 @@ static int avs_modext_create(struct avs_dev *adev, struct avs_path_module *mod) ret = avs_dsp_init_module(adev, mod->module_id, mod->owner->instance_id, t->core_id, t->domain, cfg, cfg_size, &mod->instance_id); - kfree(cfg); return ret; } diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c index 8565a53070..463dbba184 100644 --- a/sound/soc/intel/avs/pcm.c +++ b/sound/soc/intel/avs/pcm.c @@ -58,7 +58,7 @@ avs_dai_find_path_template(struct snd_soc_dai *dai, bool is_fe, int direction) static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai, bool is_fe, const struct snd_soc_dai_ops *ops) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct avs_dev *adev = to_avs_dev(dai->dev); struct avs_tplg_path_template *template; struct avs_dma_data *data; @@ -127,7 +127,7 @@ static int avs_dai_be_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *fe, *be; struct snd_soc_dpcm *dpcm; - be = asoc_substream_to_rtd(substream); + be = snd_soc_substream_to_rtd(substream); for_each_dpcm_fe(be, substream->stream, dpcm) { fe = dpcm->fe; fe_hw_params = &fe->dpcm[substream->stream].hw_params; @@ -167,7 +167,7 @@ static int avs_dai_nonhda_be_startup(struct snd_pcm_substream *substream, struct static void avs_dai_nonhda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct avs_dev *adev = to_avs_dev(dai->dev); struct avs_dma_data *data; @@ -216,7 +216,7 @@ static int avs_dai_nonhda_be_prepare(struct snd_pcm_substream *substream, struct static int avs_dai_nonhda_be_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct avs_dma_data *data; int ret = 0; @@ -303,7 +303,7 @@ static int avs_dai_hda_be_hw_params(struct snd_pcm_substream *substream, static int avs_dai_hda_be_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct avs_dma_data *data; - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct hdac_ext_stream *link_stream; struct hdac_ext_link *link; struct hda_codec *codec; @@ -320,7 +320,7 @@ static int avs_dai_hda_be_hw_free(struct snd_pcm_substream *substream, struct sn data->path = NULL; /* clear link <-> stream mapping */ - codec = dev_to_hda_codec(asoc_rtd_to_codec(rtd, 0)->dev); + codec = dev_to_hda_codec(snd_soc_rtd_to_codec(rtd, 0)->dev); link = snd_hdac_ext_bus_get_hlink_by_addr(&codec->bus->core, codec->core.addr); if (!link) return -EINVAL; @@ -333,7 +333,7 @@ static int avs_dai_hda_be_hw_free(struct snd_pcm_substream *substream, struct sn static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_pcm_runtime *runtime = substream->runtime; struct hdac_ext_stream *link_stream = runtime->private_data; struct hdac_ext_link *link; @@ -345,12 +345,11 @@ static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct sn if (link_stream->link_prepared) return 0; - codec = dev_to_hda_codec(asoc_rtd_to_codec(rtd, 0)->dev); + codec = dev_to_hda_codec(snd_soc_rtd_to_codec(rtd, 0)->dev); bus = &codec->bus->core; format_val = snd_hdac_calc_stream_format(runtime->rate, runtime->channels, runtime->format, runtime->sample_bits, 0); - snd_hdac_ext_stream_decouple(bus, link_stream, true); snd_hdac_ext_stream_reset(link_stream); snd_hdac_ext_stream_setup(link_stream, format_val); @@ -372,7 +371,7 @@ static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct sn static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct hdac_ext_stream *link_stream; struct avs_dma_data *data; int ret = 0; @@ -500,7 +499,7 @@ err: static void avs_dai_fe_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct avs_dev *adev = to_avs_dev(dai->dev); struct avs_dma_data *data; @@ -534,7 +533,7 @@ static int avs_dai_fe_hw_params(struct snd_pcm_substream *substream, hdac_stream(host_stream)->period_bytes = 0; hdac_stream(host_stream)->format_val = 0; - fe = asoc_substream_to_rtd(substream); + fe = snd_soc_substream_to_rtd(substream); for_each_dpcm_be(fe, substream->stream, dpcm) { be = dpcm->be; be_hw_params = &be->dpcm[substream->stream].hw_params; @@ -604,7 +603,6 @@ static int avs_dai_fe_prepare(struct snd_pcm_substream *substream, struct snd_so struct avs_dma_data *data; struct avs_dev *adev = to_avs_dev(dai->dev); struct hdac_ext_stream *host_stream; - struct hdac_bus *bus; unsigned int format_val; int ret; @@ -614,8 +612,6 @@ static int avs_dai_fe_prepare(struct snd_pcm_substream *substream, struct snd_so if (hdac_stream(host_stream)->prepared) return 0; - bus = hdac_stream(host_stream)->bus; - snd_hdac_ext_stream_decouple(bus, data->host_stream, true); snd_hdac_stream_reset(hdac_stream(host_stream)); format_val = snd_hdac_calc_stream_format(runtime->rate, runtime->channels, runtime->format, @@ -625,7 +621,7 @@ static int avs_dai_fe_prepare(struct snd_pcm_substream *substream, struct snd_so if (ret < 0) return ret; - ret = snd_hdac_stream_setup(hdac_stream(host_stream)); + ret = snd_hdac_ext_host_stream_setup(host_stream, false); if (ret < 0) return ret; @@ -639,7 +635,7 @@ static int avs_dai_fe_prepare(struct snd_pcm_substream *substream, struct snd_so static int avs_dai_fe_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct avs_dma_data *data; struct hdac_ext_stream *host_stream; struct hdac_bus *bus; @@ -869,7 +865,7 @@ static int avs_dai_resume_hw_params(struct snd_soc_dai *dai, struct avs_dma_data int ret; substream = data->substream; - rtd = asoc_substream_to_rtd(substream); + rtd = snd_soc_substream_to_rtd(substream); ret = dai->driver->ops->hw_params(substream, &rtd->dpcm[substream->stream].hw_params, dai); if (ret) @@ -964,7 +960,7 @@ static int avs_component_pm_op(struct snd_soc_component *component, bool be, for_each_component_dais(component, dai) { data = snd_soc_dai_dma_data_get_playback(dai); if (data) { - rtd = asoc_substream_to_rtd(data->substream); + rtd = snd_soc_substream_to_rtd(data->substream); if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) { ret = op(dai, data); if (ret < 0) { @@ -977,7 +973,7 @@ static int avs_component_pm_op(struct snd_soc_component *component, bool be, data = snd_soc_dai_dma_data_get_capture(dai); if (data) { - rtd = asoc_substream_to_rtd(data->substream); + rtd = snd_soc_substream_to_rtd(data->substream); if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) { ret = op(dai, data); if (ret < 0) { @@ -1081,7 +1077,7 @@ static const struct snd_pcm_hardware avs_pcm_hardware = { static int avs_component_open(struct snd_soc_component *component, struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); /* only FE DAI links are handled here */ if (rtd->dai_link->no_pcm) @@ -1099,12 +1095,12 @@ static unsigned int avs_hda_stream_dpib_read(struct hdac_ext_stream *stream) static snd_pcm_uframes_t avs_component_pointer(struct snd_soc_component *component, struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct avs_dma_data *data; struct hdac_ext_stream *host_stream; unsigned int pos; - data = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); + data = snd_soc_dai_get_dma_data(snd_soc_rtd_to_cpu(rtd, 0), substream); if (!data->host_stream) return 0; @@ -1129,7 +1125,7 @@ static int avs_component_mmap(struct snd_soc_component *component, static int avs_component_construct(struct snd_soc_component *component, struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0); struct snd_pcm *pcm = rtd->pcm; if (dai->driver->playback.channels_min) @@ -1242,7 +1238,11 @@ int avs_i2s_platform_register(struct avs_dev *adev, const char *name, unsigned l int i, j; ssp_count = adev->hw_cfg.i2s_caps.ctrl_count; - cpu_count = hweight_long(port_mask); + + cpu_count = 0; + for_each_set_bit(i, &port_mask, ssp_count) + if (!tdms || test_bit(0, &tdms[i])) + cpu_count++; if (tdms) for_each_set_bit(i, &port_mask, ssp_count) cpu_count += hweight_long(tdms[i]); @@ -1253,18 +1253,20 @@ int avs_i2s_platform_register(struct avs_dev *adev, const char *name, unsigned l dai = cpus; for_each_set_bit(i, &port_mask, ssp_count) { - memcpy(dai, &i2s_dai_template, sizeof(*dai)); + if (!tdms || test_bit(0, &tdms[i])) { + memcpy(dai, &i2s_dai_template, sizeof(*dai)); - dai->name = - devm_kasprintf(adev->dev, GFP_KERNEL, "SSP%d Pin", i); - dai->playback.stream_name = - devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d Tx", i); - dai->capture.stream_name = - devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d Rx", i); + dai->name = + devm_kasprintf(adev->dev, GFP_KERNEL, "SSP%d Pin", i); + dai->playback.stream_name = + devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d Tx", i); + dai->capture.stream_name = + devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d Rx", i); - if (!dai->name || !dai->playback.stream_name || !dai->capture.stream_name) - return -ENOMEM; - dai++; + if (!dai->name || !dai->playback.stream_name || !dai->capture.stream_name) + return -ENOMEM; + dai++; + } } if (!tdms) @@ -1430,7 +1432,7 @@ static void avs_component_hda_remove(struct snd_soc_component *component) static int avs_component_hda_open(struct snd_soc_component *component, struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct hdac_ext_stream *link_stream; struct hda_codec *codec; @@ -1464,7 +1466,7 @@ static int avs_component_hda_open(struct snd_soc_component *component, return snd_soc_set_runtime_hwparams(substream, &hwparams); } - codec = dev_to_hda_codec(asoc_rtd_to_codec(rtd, 0)->dev); + codec = dev_to_hda_codec(snd_soc_rtd_to_codec(rtd, 0)->dev); link_stream = snd_hdac_ext_stream_assign(&codec->bus->core, substream, HDAC_EXT_STREAM_TYPE_LINK); if (!link_stream) @@ -1477,7 +1479,7 @@ static int avs_component_hda_open(struct snd_soc_component *component, static int avs_component_hda_close(struct snd_soc_component *component, struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct hdac_ext_stream *link_stream; /* only BE DAI links are handled here */ diff --git a/sound/soc/intel/avs/probes.c b/sound/soc/intel/avs/probes.c index 4cab8c6c45..bdc6b30dc0 100644 --- a/sound/soc/intel/avs/probes.c +++ b/sound/soc/intel/avs/probes.c @@ -145,7 +145,7 @@ static int avs_probe_compr_set_params(struct snd_compr_stream *cstream, ret = snd_hdac_stream_set_params(hdac_stream(host_stream), format_val); if (ret < 0) return ret; - ret = snd_hdac_stream_setup(hdac_stream(host_stream)); + ret = snd_hdac_stream_setup(hdac_stream(host_stream), false); if (ret < 0) return ret; diff --git a/sound/soc/intel/avs/registers.h b/sound/soc/intel/avs/registers.h index 2b464e466e..078a0ebafa 100644 --- a/sound/soc/intel/avs/registers.h +++ b/sound/soc/intel/avs/registers.h @@ -9,6 +9,8 @@ #ifndef __SOUND_SOC_INTEL_AVS_REGS_H #define __SOUND_SOC_INTEL_AVS_REGS_H +#include <linux/sizes.h> + #define AZX_PCIREG_PGCTL 0x44 #define AZX_PCIREG_CGCTL 0x48 #define AZX_PGCTL_LSRMD_MASK BIT(4) @@ -59,7 +61,7 @@ #define AVS_FW_REG_STATUS(adev) (AVS_FW_REG_BASE(adev) + 0x0) #define AVS_FW_REG_ERROR_CODE(adev) (AVS_FW_REG_BASE(adev) + 0x4) -#define AVS_WINDOW_CHUNK_SIZE PAGE_SIZE +#define AVS_WINDOW_CHUNK_SIZE SZ_4K #define AVS_FW_REGS_SIZE AVS_WINDOW_CHUNK_SIZE #define AVS_FW_REGS_WINDOW 0 /* DSP -> HOST communication window */ diff --git a/sound/soc/intel/avs/topology.c b/sound/soc/intel/avs/topology.c index 45d0eb2a8e..41020409ff 100644 --- a/sound/soc/intel/avs/topology.c +++ b/sound/soc/intel/avs/topology.c @@ -15,6 +15,7 @@ #include "avs.h" #include "control.h" #include "topology.h" +#include "utils.h" /* Get pointer to vendor array at the specified offset. */ #define avs_tplg_vendor_array_at(array, offset) \ @@ -371,22 +372,50 @@ parse_audio_format_bitfield(struct snd_soc_component *comp, void *elem, void *ob return 0; } +static int avs_ssp_sprint(char *buf, size_t size, const char *fmt, int port, int tdm) +{ + char *needle = strstr(fmt, "%d"); + int retsize; + + /* + * If there is %d present in fmt string it should be replaced by either + * SSP or SSP:TDM, where SSP and TDM are numbers, all other formatting + * will be ignored. + */ + if (needle) { + retsize = scnprintf(buf, min_t(size_t, size, needle - fmt + 1), "%s", fmt); + retsize += scnprintf(buf + retsize, size - retsize, "%d", port); + if (tdm) + retsize += scnprintf(buf + retsize, size - retsize, ":%d", tdm); + retsize += scnprintf(buf + retsize, size - retsize, "%s", needle + 2); + return retsize; + } + + return snprintf(buf, size, "%s", fmt); +} + static int parse_link_formatted_string(struct snd_soc_component *comp, void *elem, void *object, u32 offset) { struct snd_soc_tplg_vendor_string_elem *tuple = elem; struct snd_soc_acpi_mach *mach = dev_get_platdata(comp->card->dev); char *val = (char *)((u8 *)object + offset); + int ssp_port, tdm_slot; /* * Dynamic naming - string formats, e.g.: ssp%d - supported only for * topologies describing single device e.g.: an I2S codec on SSP0. */ - if (hweight_long(mach->mach_params.i2s_link_mask) != 1) + if (!avs_mach_singular_ssp(mach)) + return avs_parse_string_token(comp, elem, object, offset); + + ssp_port = avs_mach_ssp_port(mach); + if (!avs_mach_singular_tdm(mach, ssp_port)) return avs_parse_string_token(comp, elem, object, offset); - snprintf(val, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, tuple->string, - __ffs(mach->mach_params.i2s_link_mask)); + tdm_slot = avs_mach_ssp_tdm(mach, ssp_port); + + avs_ssp_sprint(val, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, tuple->string, ssp_port, tdm_slot); return 0; } @@ -813,6 +842,7 @@ static void assign_copier_gtw_instance(struct snd_soc_component *comp, struct avs_tplg_modcfg_ext *cfg) { struct snd_soc_acpi_mach *mach; + int ssp_port, tdm_slot; if (!guid_equal(&cfg->type, &AVS_COPIER_MOD_UUID)) return; @@ -826,11 +856,22 @@ assign_copier_gtw_instance(struct snd_soc_component *comp, struct avs_tplg_modcf return; } + /* If topology sets value don't overwrite it */ + if (cfg->copier.vindex.val) + return; + mach = dev_get_platdata(comp->card->dev); - /* Automatic assignment only when board describes single SSP. */ - if (hweight_long(mach->mach_params.i2s_link_mask) == 1 && !cfg->copier.vindex.i2s.instance) - cfg->copier.vindex.i2s.instance = __ffs(mach->mach_params.i2s_link_mask); + if (!avs_mach_singular_ssp(mach)) + return; + ssp_port = avs_mach_ssp_port(mach); + + if (!avs_mach_singular_tdm(mach, ssp_port)) + return; + tdm_slot = avs_mach_ssp_tdm(mach, ssp_port); + + cfg->copier.vindex.i2s.instance = ssp_port; + cfg->copier.vindex.i2s.time_slot = tdm_slot; } static int avs_tplg_parse_modcfg_ext(struct snd_soc_component *comp, @@ -1381,20 +1422,24 @@ static int avs_route_load(struct snd_soc_component *comp, int index, struct snd_soc_acpi_mach *mach = dev_get_platdata(comp->card->dev); size_t len = SNDRV_CTL_ELEM_ID_NAME_MAXLEN; char buf[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; - u32 port; + int ssp_port, tdm_slot; /* See parse_link_formatted_string() for dynamic naming when(s). */ - if (hweight_long(mach->mach_params.i2s_link_mask) == 1) { - port = __ffs(mach->mach_params.i2s_link_mask); - - snprintf(buf, len, route->source, port); - strscpy((char *)route->source, buf, len); - snprintf(buf, len, route->sink, port); - strscpy((char *)route->sink, buf, len); - if (route->control) { - snprintf(buf, len, route->control, port); - strscpy((char *)route->control, buf, len); - } + if (!avs_mach_singular_ssp(mach)) + return 0; + ssp_port = avs_mach_ssp_port(mach); + + if (!avs_mach_singular_tdm(mach, ssp_port)) + return 0; + tdm_slot = avs_mach_ssp_tdm(mach, ssp_port); + + avs_ssp_sprint(buf, len, route->source, ssp_port, tdm_slot); + strscpy((char *)route->source, buf, len); + avs_ssp_sprint(buf, len, route->sink, ssp_port, tdm_slot); + strscpy((char *)route->sink, buf, len); + if (route->control) { + avs_ssp_sprint(buf, len, route->control, ssp_port, tdm_slot); + strscpy((char *)route->control, buf, len); } return 0; @@ -1408,6 +1453,7 @@ static int avs_widget_load(struct snd_soc_component *comp, int index, struct avs_tplg_path_template *template; struct avs_soc_component *acomp = to_avs_soc_component(comp); struct avs_tplg *tplg; + int ssp_port, tdm_slot; if (!le32_to_cpu(dw->priv.size)) return 0; @@ -1419,16 +1465,28 @@ static int avs_widget_load(struct snd_soc_component *comp, int index, tplg = acomp->tplg; mach = dev_get_platdata(comp->card->dev); + if (!avs_mach_singular_ssp(mach)) + goto static_name; + ssp_port = avs_mach_ssp_port(mach); /* See parse_link_formatted_string() for dynamic naming when(s). */ - if (hweight_long(mach->mach_params.i2s_link_mask) == 1) { + if (avs_mach_singular_tdm(mach, ssp_port)) { + /* size is based on possible %d -> SSP:TDM, where SSP and TDM < 10 + '\0' */ + size_t size = strlen(dw->name) + 2; + char *buf; + + tdm_slot = avs_mach_ssp_tdm(mach, ssp_port); + + buf = kmalloc(size, GFP_KERNEL); + if (!buf) + return -ENOMEM; + avs_ssp_sprint(buf, size, dw->name, ssp_port, tdm_slot); kfree(w->name); /* w->name is freed later by soc_tplg_dapm_widget_create() */ - w->name = kasprintf(GFP_KERNEL, dw->name, __ffs(mach->mach_params.i2s_link_mask)); - if (!w->name) - return -ENOMEM; + w->name = buf; } +static_name: template = avs_tplg_path_template_create(comp, tplg, dw->priv.array, le32_to_cpu(dw->priv.size)); if (IS_ERR(template)) { diff --git a/sound/soc/intel/avs/utils.h b/sound/soc/intel/avs/utils.h new file mode 100644 index 0000000000..0b82a98ed0 --- /dev/null +++ b/sound/soc/intel/avs/utils.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright(c) 2023 Intel Corporation. All rights reserved. + * + * Authors: Cezary Rojewski <cezary.rojewski@intel.com> + * Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com> + */ + +#ifndef __SOUND_SOC_INTEL_AVS_UTILS_H +#define __SOUND_SOC_INTEL_AVS_UTILS_H + +#include <sound/soc-acpi.h> + +static inline bool avs_mach_singular_ssp(struct snd_soc_acpi_mach *mach) +{ + return hweight_long(mach->mach_params.i2s_link_mask) == 1; +} + +static inline u32 avs_mach_ssp_port(struct snd_soc_acpi_mach *mach) +{ + return __ffs(mach->mach_params.i2s_link_mask); +} + +static inline bool avs_mach_singular_tdm(struct snd_soc_acpi_mach *mach, u32 port) +{ + unsigned long *tdms = mach->pdata; + + return !tdms || (hweight_long(tdms[port]) == 1); +} + +static inline u32 avs_mach_ssp_tdm(struct snd_soc_acpi_mach *mach, u32 port) +{ + unsigned long *tdms = mach->pdata; + + return tdms ? __ffs(tdms[port]) : 0; +} + +static inline int avs_mach_get_ssp_tdm(struct device *dev, struct snd_soc_acpi_mach *mach, + int *ssp_port, int *tdm_slot) +{ + int port; + + if (!avs_mach_singular_ssp(mach)) { + dev_err(dev, "Invalid SSP configuration\n"); + return -EINVAL; + } + port = avs_mach_ssp_port(mach); + + if (!avs_mach_singular_tdm(mach, port)) { + dev_err(dev, "Invalid TDM configuration\n"); + return -EINVAL; + } + *ssp_port = port; + *tdm_slot = avs_mach_ssp_tdm(mach, *ssp_port); + + return 0; +} + +/* + * Macro to easily generate format strings + */ +#define AVS_STRING_FMT(prefix, suffix, ssp, tdm) \ + (tdm) ? prefix "%d:%d" suffix : prefix "%d" suffix, (ssp), (tdm) + +#endif diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index 0ae6eecc88..9e427f00de 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -38,6 +38,15 @@ config SND_SOC_INTEL_SOF_REALTEK_COMMON config SND_SOC_INTEL_SOF_CIRRUS_COMMON tristate +config SND_SOC_INTEL_SOF_NUVOTON_COMMON + tristate + +config SND_SOC_INTEL_SOF_SSP_COMMON + tristate + +config SND_SOC_INTEL_SOF_BOARD_HELPERS + tristate + if SND_SOC_INTEL_CATPT config SND_SOC_INTEL_HASWELL_MACH @@ -489,10 +498,11 @@ config SND_SOC_INTEL_SOF_RT5682_MACH select SND_SOC_RT5682_I2C select SND_SOC_RT5682S select SND_SOC_DMIC - select SND_SOC_HDAC_HDMI select SND_SOC_INTEL_HDA_DSP_COMMON + select SND_SOC_INTEL_SOF_BOARD_HELPERS select SND_SOC_INTEL_SOF_MAXIM_COMMON select SND_SOC_INTEL_SOF_REALTEK_COMMON + select SND_SOC_INTEL_SOF_SSP_COMMON help This adds support for ASoC machine driver for SOF platforms with rt5650 or rt5682 codec. @@ -507,9 +517,10 @@ config SND_SOC_INTEL_SOF_CS42L42_MACH select SND_SOC_CS42L42 select SND_SOC_MAX98357A select SND_SOC_DMIC - select SND_SOC_HDAC_HDMI select SND_SOC_INTEL_HDA_DSP_COMMON + select SND_SOC_INTEL_SOF_BOARD_HELPERS select SND_SOC_INTEL_SOF_MAXIM_COMMON + select SND_SOC_INTEL_SOF_SSP_COMMON help This adds support for ASoC machine driver for SOF platforms with cs42l42 codec. @@ -557,10 +568,12 @@ config SND_SOC_INTEL_SOF_NAU8825_MACH select SND_SOC_MAX98357A select SND_SOC_NAU8315 select SND_SOC_DMIC - select SND_SOC_HDAC_HDMI select SND_SOC_INTEL_HDA_DSP_COMMON + select SND_SOC_INTEL_SOF_BOARD_HELPERS select SND_SOC_INTEL_SOF_MAXIM_COMMON + select SND_SOC_INTEL_SOF_NUVOTON_COMMON select SND_SOC_INTEL_SOF_REALTEK_COMMON + select SND_SOC_INTEL_SOF_SSP_COMMON help This adds support for ASoC machine driver for SOF platforms with nau8825 codec. @@ -600,25 +613,24 @@ config SND_SOC_INTEL_SOF_CML_RT1011_RT5682_MACH endif ## SND_SOC_SOF_COMETLAKE && SND_SOC_SOF_HDA_LINK -if SND_SOC_SOF_JASPERLAKE - -config SND_SOC_INTEL_SOF_DA7219_MAX98373_MACH - tristate "SOF with DA7219 and MAX98373/MAX98360A in I2S Mode" +config SND_SOC_INTEL_SOF_DA7219_MACH + tristate "SOF with DA7219 codec in I2S Mode" depends on I2C && ACPI depends on MFD_INTEL_LPSS || COMPILE_TEST depends on SND_HDA_CODEC_HDMI && SND_SOC_SOF_HDA_AUDIO_CODEC select SND_SOC_INTEL_HDA_DSP_COMMON select SND_SOC_DA7219 + select SND_SOC_MAX98357A select SND_SOC_MAX98373_I2C select SND_SOC_DMIC + select SND_SOC_INTEL_SOF_MAXIM_COMMON + select SND_SOC_INTEL_SOF_SSP_COMMON help This adds support for ASoC machine driver for SOF platforms - with DA7219 + MAX98373/MAX98360A I2S audio codec. + with Dialog DA7219 I2S audio codec. Say Y if you have such a device. If unsure select "N". -endif ## SND_SOC_SOF_JASPERLAKE - if SND_SOC_SOF_HDA_LINK config SND_SOC_INTEL_SOF_SSP_AMP_MACH @@ -628,10 +640,11 @@ config SND_SOC_INTEL_SOF_SSP_AMP_MACH select SND_SOC_RT1308 select SND_SOC_CS35L41_I2C select SND_SOC_DMIC - select SND_SOC_HDAC_HDMI select SND_SOC_INTEL_HDA_DSP_COMMON + select SND_SOC_INTEL_SOF_BOARD_HELPERS select SND_SOC_INTEL_SOF_REALTEK_COMMON select SND_SOC_INTEL_SOF_CIRRUS_COMMON + select SND_SOC_INTEL_SOF_SSP_COMMON help This adds support for ASoC machine driver for SOF platforms with RT1308/CS35L41 I2S audio codec. @@ -679,6 +692,10 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH select SND_SOC_RT1318_SDW select SND_SOC_RT5682_SDW select SND_SOC_CS42L42_SDW + select SND_SOC_CS42L43 + select SND_SOC_CS42L43_SDW + select MFD_CS42L43 + select MFD_CS42L43_SDW select SND_SOC_CS35L56_SDW select SND_SOC_DMIC select SND_SOC_INTEL_HDA_DSP_COMMON diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile index a570b5b40f..943bf8b80e 100644 --- a/sound/soc/intel/boards/Makefile +++ b/sound/soc/intel/boards/Makefile @@ -23,6 +23,7 @@ snd-soc-sof_rt5682-objs := sof_rt5682.o snd-soc-sof_cs42l42-objs := sof_cs42l42.o snd-soc-sof_es8336-objs := sof_es8336.o snd-soc-sof_nau8825-objs := sof_nau8825.o +snd-soc-sof_da7219-objs := sof_da7219.o snd-soc-cml_rt1011_rt5682-objs := cml_rt1011_rt5682.o snd-soc-kbl_da7219_max98357a-objs := kbl_da7219_max98357a.o snd-soc-kbl_da7219_max98927-objs := kbl_da7219_max98927.o @@ -33,7 +34,6 @@ snd-soc-skl_rt286-objs := skl_rt286.o snd-soc-skl_hda_dsp-objs := skl_hda_dsp_generic.o skl_hda_dsp_common.o snd-skl_nau88l25_max98357a-objs := skl_nau88l25_max98357a.o snd-soc-skl_nau88l25_ssm4567-objs := skl_nau88l25_ssm4567.o -snd-soc-sof_da7219_max98373-objs := sof_da7219_max98373.o snd-soc-ehl-rt5660-objs := ehl_rt5660.o snd-soc-sof-ssp-amp-objs := sof_ssp_amp.o snd-soc-sof-sdw-objs += sof_sdw.o \ @@ -42,12 +42,14 @@ snd-soc-sof-sdw-objs += sof_sdw.o \ sof_sdw_rt711.o sof_sdw_rt_sdca_jack_common.o \ sof_sdw_rt712_sdca.o sof_sdw_rt715.o \ sof_sdw_rt715_sdca.o sof_sdw_dmic.o \ - sof_sdw_cs42l42.o sof_sdw_cs_amp.o \ + sof_sdw_cs42l42.o sof_sdw_cs42l43.o \ + sof_sdw_cs_amp.o \ sof_sdw_hdmi.o obj-$(CONFIG_SND_SOC_INTEL_SOF_RT5682_MACH) += snd-soc-sof_rt5682.o obj-$(CONFIG_SND_SOC_INTEL_SOF_CS42L42_MACH) += snd-soc-sof_cs42l42.o obj-$(CONFIG_SND_SOC_INTEL_SOF_ES8336_MACH) += snd-soc-sof_es8336.o obj-$(CONFIG_SND_SOC_INTEL_SOF_NAU8825_MACH) += snd-soc-sof_nau8825.o +obj-$(CONFIG_SND_SOC_INTEL_SOF_DA7219_MACH) += snd-soc-sof_da7219.o obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-hsw-rt5640.o obj-$(CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON) += snd-soc-sst-bxt-da7219_max98357a.o obj-$(CONFIG_SND_SOC_INTEL_BXT_RT298_MACH) += snd-soc-sst-bxt-rt298.o @@ -78,7 +80,6 @@ obj-$(CONFIG_SND_SOC_INTEL_SKL_RT286_MACH) += snd-soc-skl_rt286.o obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH) += snd-skl_nau88l25_max98357a.o obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH) += snd-soc-skl_nau88l25_ssm4567.o obj-$(CONFIG_SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH) += snd-soc-skl_hda_dsp.o -obj-$(CONFIG_SND_SOC_INTEL_SOF_DA7219_MAX98373_MACH) += snd-soc-sof_da7219_max98373.o obj-$(CONFIG_SND_SOC_INTEL_EHL_RT5660_MACH) += snd-soc-ehl-rt5660.o obj-$(CONFIG_SND_SOC_INTEL_SOUNDWIRE_SOF_MACH) += snd-soc-sof-sdw.o obj-$(CONFIG_SND_SOC_INTEL_SOF_SSP_AMP_MACH) += snd-soc-sof-ssp-amp.o @@ -95,3 +96,12 @@ obj-$(CONFIG_SND_SOC_INTEL_SOF_REALTEK_COMMON) += snd-soc-intel-sof-realtek-comm snd-soc-intel-sof-cirrus-common-objs += sof_cirrus_common.o obj-$(CONFIG_SND_SOC_INTEL_SOF_CIRRUS_COMMON) += snd-soc-intel-sof-cirrus-common.o + +snd-soc-intel-sof-nuvoton-common-objs += sof_nuvoton_common.o +obj-$(CONFIG_SND_SOC_INTEL_SOF_NUVOTON_COMMON) += snd-soc-intel-sof-nuvoton-common.o + +snd-soc-intel-sof-ssp-common-objs += sof_ssp_common.o +obj-$(CONFIG_SND_SOC_INTEL_SOF_SSP_COMMON) += snd-soc-intel-sof-ssp-common.o + +snd-soc-intel-sof-board-helpers-objs += sof_board_helpers.o +obj-$(CONFIG_SND_SOC_INTEL_SOF_BOARD_HELPERS) += snd-soc-intel-sof-board-helpers.o diff --git a/sound/soc/intel/boards/bdw-rt5650.c b/sound/soc/intel/boards/bdw-rt5650.c index d0682bc543..3ae26f2145 100644 --- a/sound/soc/intel/boards/bdw-rt5650.c +++ b/sound/soc/intel/boards/bdw-rt5650.c @@ -103,8 +103,8 @@ static int broadwell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, static int bdw_rt5650_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; /* Workaround: set codec PLL to 19.2MHz that PLL source is @@ -167,7 +167,7 @@ static int bdw_rt5650_init(struct snd_soc_pcm_runtime *rtd) { struct bdw_rt5650_priv *bdw_rt5650 = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_component *component = codec_dai->component; int ret; diff --git a/sound/soc/intel/boards/bdw-rt5677.c b/sound/soc/intel/boards/bdw-rt5677.c index f3e08d258a..304af3d06d 100644 --- a/sound/soc/intel/boards/bdw-rt5677.c +++ b/sound/soc/intel/boards/bdw-rt5677.c @@ -153,8 +153,8 @@ static int broadwell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, static int bdw_rt5677_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, RT5677_SCLK_S_MCLK, 24576000, @@ -170,8 +170,8 @@ static int bdw_rt5677_hw_params(struct snd_pcm_substream *substream, static int bdw_rt5677_dsp_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, RT5677_SCLK_S_PLL1, 24576000, @@ -227,7 +227,7 @@ static int bdw_rt5677_init(struct snd_soc_pcm_runtime *rtd) { struct bdw_rt5677_priv *bdw_rt5677 = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); int ret; diff --git a/sound/soc/intel/boards/bdw_rt286.c b/sound/soc/intel/boards/bdw_rt286.c index 036579331d..7f20159c23 100644 --- a/sound/soc/intel/boards/bdw_rt286.c +++ b/sound/soc/intel/boards/bdw_rt286.c @@ -61,7 +61,7 @@ static const struct snd_soc_dapm_route card_routes[] = { static int codec_link_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *codec = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *codec = snd_soc_rtd_to_codec(rtd, 0)->component; int ret; ret = snd_soc_card_jack_new_pins(rtd->card, "Headset", SND_JACK_HEADSET | SND_JACK_BTN_0, @@ -75,7 +75,7 @@ static int codec_link_init(struct snd_soc_pcm_runtime *rtd) static void codec_link_exit(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *codec = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *codec = snd_soc_rtd_to_codec(rtd, 0)->component; snd_soc_component_set_jack(codec, NULL, NULL); } @@ -98,8 +98,8 @@ static int codec_link_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, static int codec_link_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, RT286_SCLK_S_PLL, 24000000, SND_SOC_CLOCK_IN); diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c index cbfff466c5..816fad8c1f 100644 --- a/sound/soc/intel/boards/bxt_da7219_max98357a.c +++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c @@ -226,8 +226,8 @@ static int broxton_ssp_fixup(struct snd_soc_pcm_runtime *rtd, static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) { int ret; - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; int clk_freq; /* Configure sysclk for codec */ @@ -275,7 +275,7 @@ static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) static int broxton_hdmi_init(struct snd_soc_pcm_runtime *rtd) { struct bxt_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct bxt_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -293,7 +293,7 @@ static int broxton_hdmi_init(struct snd_soc_pcm_runtime *rtd) static int broxton_da7219_fe_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dapm_context *dapm; - struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_cpu(rtd, 0)->component; dapm = snd_soc_component_get_dapm(component); snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c index bf89fe8042..4631106f2a 100644 --- a/sound/soc/intel/boards/bxt_rt298.c +++ b/sound/soc/intel/boards/bxt_rt298.c @@ -155,7 +155,7 @@ static const struct snd_soc_dapm_route geminilake_rt298_map[] = { static int broxton_rt298_fe_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dapm_context *dapm; - struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_cpu(rtd, 0)->component; dapm = snd_soc_component_get_dapm(component); snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); @@ -165,7 +165,7 @@ static int broxton_rt298_fe_init(struct snd_soc_pcm_runtime *rtd) static int broxton_rt298_codec_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; int ret = 0; ret = snd_soc_card_jack_new_pins(rtd->card, "Headset", @@ -186,7 +186,7 @@ static int broxton_rt298_codec_init(struct snd_soc_pcm_runtime *rtd) static int broxton_hdmi_init(struct snd_soc_pcm_runtime *rtd) { struct bxt_rt286_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct bxt_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -224,8 +224,8 @@ static int broxton_ssp5_fixup(struct snd_soc_pcm_runtime *rtd, static int broxton_rt298_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, RT298_SCLK_S_PLL, diff --git a/sound/soc/intel/boards/bytcht_cx2072x.c b/sound/soc/intel/boards/bytcht_cx2072x.c index 9942a2de6f..10a84a2c10 100644 --- a/sound/soc/intel/boards/bytcht_cx2072x.c +++ b/sound/soc/intel/boards/bytcht_cx2072x.c @@ -70,7 +70,7 @@ static const struct acpi_gpio_mapping byt_cht_cx2072x_acpi_gpios[] = { static int byt_cht_cx2072x_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; - struct snd_soc_component *codec = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *codec = snd_soc_rtd_to_codec(rtd, 0)->component; int ret; if (devm_acpi_dev_add_driver_gpios(codec->dev, @@ -80,7 +80,7 @@ static int byt_cht_cx2072x_init(struct snd_soc_pcm_runtime *rtd) card->dapm.idle_bias_off = true; /* set the default PLL rate, the clock is handled by the codec driver */ - ret = snd_soc_dai_set_sysclk(asoc_rtd_to_codec(rtd, 0), CX2072X_MCLK_EXTERNAL_PLL, + ret = snd_soc_dai_set_sysclk(snd_soc_rtd_to_codec(rtd, 0), CX2072X_MCLK_EXTERNAL_PLL, 19200000, SND_SOC_CLOCK_IN); if (ret) { dev_err(rtd->dev, "Could not set sysclk\n"); @@ -97,7 +97,7 @@ static int byt_cht_cx2072x_init(struct snd_soc_pcm_runtime *rtd) snd_soc_component_set_jack(codec, &byt_cht_cx2072x_headset, NULL); - snd_soc_dai_set_bclk_ratio(asoc_rtd_to_codec(rtd, 0), 50); + snd_soc_dai_set_bclk_ratio(snd_soc_rtd_to_codec(rtd, 0), 50); return 0; } @@ -123,7 +123,7 @@ static int byt_cht_cx2072x_fixup(struct snd_soc_pcm_runtime *rtd, * with explicit setting to I2S 2ch 24-bit. The word length is set with * dai_set_tdm_slot() since there is no other API exposed */ - ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), + ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BP_FP); @@ -132,7 +132,7 @@ static int byt_cht_cx2072x_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 24); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 24); if (ret < 0) { dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); return ret; diff --git a/sound/soc/intel/boards/bytcht_da7213.c b/sound/soc/intel/boards/bytcht_da7213.c index a3b0cfab17..7e5eea6900 100644 --- a/sound/soc/intel/boards/bytcht_da7213.c +++ b/sound/soc/intel/boards/bytcht_da7213.c @@ -78,7 +78,7 @@ static int codec_fixup(struct snd_soc_pcm_runtime *rtd, * with explicit setting to I2S 2ch 24-bit. The word length is set with * dai_set_tdm_slot() since there is no other API exposed */ - ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), + ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BP_FP); @@ -87,7 +87,7 @@ static int codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 24); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 24); if (ret < 0) { dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); return ret; @@ -105,8 +105,8 @@ static int aif1_startup(struct snd_pcm_substream *substream) static int aif1_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, DA7213_CLKSRC_MCLK, @@ -126,8 +126,8 @@ static int aif1_hw_params(struct snd_pcm_substream *substream, static int aif1_hw_free(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_pll(codec_dai, 0, diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c index 7a30d2d36f..8a0b0e864f 100644 --- a/sound/soc/intel/boards/bytcht_es8316.c +++ b/sound/soc/intel/boards/bytcht_es8316.c @@ -157,7 +157,7 @@ static struct snd_soc_jack_pin byt_cht_es8316_jack_pins[] = { static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime) { - struct snd_soc_component *codec = asoc_rtd_to_codec(runtime, 0)->component; + struct snd_soc_component *codec = snd_soc_rtd_to_codec(runtime, 0)->component; struct snd_soc_card *card = runtime->card; struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card); const struct snd_soc_dapm_route *custom_map; @@ -212,7 +212,7 @@ static int byt_cht_es8316_init(struct snd_soc_pcm_runtime *runtime) if (ret) dev_err(card->dev, "unable to enable MCLK\n"); - ret = snd_soc_dai_set_sysclk(asoc_rtd_to_codec(runtime, 0), 0, 19200000, + ret = snd_soc_dai_set_sysclk(snd_soc_rtd_to_codec(runtime, 0), 0, 19200000, SND_SOC_CLOCK_IN); if (ret < 0) { dev_err(card->dev, "can't set codec clock %d\n", ret); @@ -262,7 +262,7 @@ static int byt_cht_es8316_codec_fixup(struct snd_soc_pcm_runtime *rtd, * with explicit setting to I2S 2ch 24-bit. The word length is set with * dai_set_tdm_slot() since there is no other API exposed */ - ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), + ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BP_FP @@ -272,7 +272,7 @@ static int byt_cht_es8316_codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits); if (ret < 0) { dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); return ret; diff --git a/sound/soc/intel/boards/bytcht_nocodec.c b/sound/soc/intel/boards/bytcht_nocodec.c index 7fc03f2efd..4a957d1cec 100644 --- a/sound/soc/intel/boards/bytcht_nocodec.c +++ b/sound/soc/intel/boards/bytcht_nocodec.c @@ -58,7 +58,7 @@ static int codec_fixup(struct snd_soc_pcm_runtime *rtd, * with explicit setting to I2S 2ch 24-bit. The word length is set with * dai_set_tdm_slot() since there is no other API exposed */ - ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), + ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BP_FP); @@ -68,7 +68,7 @@ static int codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 24); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 24); if (ret < 0) { dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); return ret; diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 6b631a608a..42466b4b1c 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -528,8 +528,8 @@ static int byt_rt5640_hp_elitepad_1000g2_jack2_check(void *data) static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); return byt_rt5640_prepare_and_enable_pll1(dai, params_rate(params)); } @@ -1245,7 +1245,7 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) struct snd_soc_card *card = runtime->card; struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card); struct rt5640_set_jack_data *jack_data = &priv->jack_data; - struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(runtime, 0)->component; const struct snd_soc_dapm_route *custom_map = NULL; int num_routes = 0; int ret; @@ -1463,7 +1463,7 @@ static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd, * with explicit setting to I2S 2ch. The word length is set with * dai_set_tdm_slot() since there is no other API exposed */ - ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), + ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BP_FP); @@ -1472,7 +1472,7 @@ static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits); if (ret < 0) { dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); return ret; diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index 805afaf47b..f9fe8414f4 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -344,8 +344,8 @@ static struct snd_soc_jack_pin bytcr_jack_pins[] = { static int byt_rt5651_aif1_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); snd_pcm_format_t format = params_format(params); int rate = params_rate(params); int bclk_ratio; @@ -563,7 +563,7 @@ static int byt_rt5651_add_codec_device_props(struct device *i2c_dev, static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime) { struct snd_soc_card *card = runtime->card; - struct snd_soc_component *codec = asoc_rtd_to_codec(runtime, 0)->component; + struct snd_soc_component *codec = snd_soc_rtd_to_codec(runtime, 0)->component; struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card); const struct snd_soc_dapm_route *custom_map; int num_routes; @@ -703,7 +703,7 @@ static int byt_rt5651_codec_fixup(struct snd_soc_pcm_runtime *rtd, * with explicit setting to I2S 2ch. The word length is set with * dai_set_tdm_slot() since there is no other API exposed */ - ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), + ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BP_FP @@ -714,7 +714,7 @@ static int byt_rt5651_codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits); if (ret < 0) { dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); return ret; diff --git a/sound/soc/intel/boards/bytcr_wm5102.c b/sound/soc/intel/boards/bytcr_wm5102.c index 5c9e06ed1a..6978ebde66 100644 --- a/sound/soc/intel/boards/bytcr_wm5102.c +++ b/sound/soc/intel/boards/bytcr_wm5102.c @@ -10,11 +10,13 @@ */ #include <linux/acpi.h> +#include <linux/bitfield.h> #include <linux/clk.h> #include <linux/device.h> #include <linux/init.h> #include <linux/module.h> #include <linux/moduleparam.h> +#include <linux/platform_data/x86/soc.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/spi/spi.h> @@ -26,8 +28,6 @@ #include "../../codecs/wm5102.h" #include "../atom/sst-atom-controls.h" -#define MCLK_FREQ 25000000 - #define WM5102_MAX_SYSCLK_4K 49152000 /* max sysclk for 4K family */ #define WM5102_MAX_SYSCLK_11025 45158400 /* max sysclk for 11.025K family */ @@ -35,8 +35,67 @@ struct byt_wm5102_private { struct snd_soc_jack jack; struct clk *mclk; struct gpio_desc *spkvdd_en_gpio; + int mclk_freq; }; +#define BYT_WM5102_IN_MAP GENMASK(3, 0) +#define BYT_WM5102_OUT_MAP GENMASK(7, 4) +#define BYT_WM5102_SSP2 BIT(16) +#define BYT_WM5102_MCLK_19_2MHZ BIT(17) + +enum { + BYT_WM5102_INTMIC_IN3L_HSMIC_IN1L, + BYT_WM5102_INTMIC_IN1L_HSMIC_IN2L, +}; + +/* Note these values are pre-shifted for easy use of setting quirks */ +enum { + BYT_WM5102_SPK_SPK_MAP = FIELD_PREP_CONST(BYT_WM5102_OUT_MAP, 0), + BYT_WM5102_SPK_HPOUT2_MAP = FIELD_PREP_CONST(BYT_WM5102_OUT_MAP, 1), +}; + +static unsigned long quirk; + +static int quirk_override = -1; +module_param_named(quirk, quirk_override, int, 0444); +MODULE_PARM_DESC(quirk, "Board-specific quirk override"); + +static void log_quirks(struct device *dev) +{ + switch (quirk & BYT_WM5102_IN_MAP) { + case BYT_WM5102_INTMIC_IN3L_HSMIC_IN1L: + dev_info_once(dev, "quirk INTMIC_IN3L_HSMIC_IN1L enabled\n"); + break; + case BYT_WM5102_INTMIC_IN1L_HSMIC_IN2L: + dev_info_once(dev, "quirk INTMIC_IN1L_HSMIC_IN2L enabled\n"); + break; + default: + dev_warn_once(dev, "quirk sets invalid input map: 0x%lx, defaulting to INTMIC_IN3L_HSMIC_IN1L\n", + quirk & BYT_WM5102_IN_MAP); + quirk &= ~BYT_WM5102_IN_MAP; + quirk |= BYT_WM5102_INTMIC_IN3L_HSMIC_IN1L; + break; + } + switch (quirk & BYT_WM5102_OUT_MAP) { + case BYT_WM5102_SPK_SPK_MAP: + dev_info_once(dev, "quirk SPK_SPK_MAP enabled\n"); + break; + case BYT_WM5102_SPK_HPOUT2_MAP: + dev_info_once(dev, "quirk SPK_HPOUT2_MAP enabled\n"); + break; + default: + dev_warn_once(dev, "quirk sets invalid output map: 0x%lx, defaulting to SPK_SPK_MAP\n", + quirk & BYT_WM5102_OUT_MAP); + quirk &= ~BYT_WM5102_OUT_MAP; + quirk |= BYT_WM5102_SPK_SPK_MAP; + break; + } + if (quirk & BYT_WM5102_SSP2) + dev_info_once(dev, "quirk SSP2 enabled"); + if (quirk & BYT_WM5102_MCLK_19_2MHZ) + dev_info_once(dev, "quirk MCLK 19.2MHz enabled"); +} + static int byt_wm5102_spkvdd_power_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -52,6 +111,7 @@ static int byt_wm5102_spkvdd_power_event(struct snd_soc_dapm_widget *w, static int byt_wm5102_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai, int rate) { struct snd_soc_component *codec_component = codec_dai->component; + struct byt_wm5102_private *priv = snd_soc_card_get_drvdata(codec_component->card); int sr_mult = ((rate % 4000) == 0) ? (WM5102_MAX_SYSCLK_4K / rate) : (WM5102_MAX_SYSCLK_11025 / rate); @@ -63,7 +123,7 @@ static int byt_wm5102_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai, int /* Configure the FLL1 PLL before selecting it */ ret = snd_soc_dai_set_pll(codec_dai, WM5102_FLL1, ARIZONA_CLK_SRC_MCLK1, - MCLK_FREQ, rate * sr_mult); + priv->mclk_freq, rate * sr_mult); if (ret) { dev_err(codec_component->dev, "Error setting PLL: %d\n", ret); return ret; @@ -145,35 +205,58 @@ static const struct snd_soc_dapm_route byt_wm5102_audio_map[] = { {"Headset Mic", NULL, "Platform Clock"}, {"Internal Mic", NULL, "Platform Clock"}, {"Speaker", NULL, "Platform Clock"}, - {"Line Out", NULL, "Platform Clock"}, - - {"Speaker", NULL, "SPKOUTLP"}, - {"Speaker", NULL, "SPKOUTLN"}, - {"Speaker", NULL, "SPKOUTRP"}, - {"Speaker", NULL, "SPKOUTRN"}, {"Speaker", NULL, "Speaker VDD"}, {"Headphone", NULL, "HPOUT1L"}, {"Headphone", NULL, "HPOUT1R"}, - {"Internal Mic", NULL, "MICBIAS3"}, - {"IN3L", NULL, "Internal Mic"}, - /* * The Headset Mix uses MICBIAS1 or 2 depending on if a CTIA/OMTP Headset * is connected, as the MICBIAS is applied after the CTIA/OMTP cross-switch. */ {"Headset Mic", NULL, "MICBIAS1"}, {"Headset Mic", NULL, "MICBIAS2"}, - {"IN1L", NULL, "Headset Mic"}, + {"Internal Mic", NULL, "MICBIAS3"}, +}; +static const struct snd_soc_dapm_route bytcr_wm5102_ssp0_map[] = { {"AIF1 Playback", NULL, "ssp0 Tx"}, {"ssp0 Tx", NULL, "modem_out"}, - {"modem_in", NULL, "ssp0 Rx"}, {"ssp0 Rx", NULL, "AIF1 Capture"}, }; +static const struct snd_soc_dapm_route bytcr_wm5102_ssp2_map[] = { + {"AIF1 Playback", NULL, "ssp2 Tx"}, + {"ssp2 Tx", NULL, "codec_out0"}, + {"ssp2 Tx", NULL, "codec_out1"}, + {"codec_in0", NULL, "ssp2 Rx"}, + {"codec_in1", NULL, "ssp2 Rx"}, + {"ssp2 Rx", NULL, "AIF1 Capture"}, +}; + +static const struct snd_soc_dapm_route byt_wm5102_spk_spk_map[] = { + {"Speaker", NULL, "SPKOUTLP"}, + {"Speaker", NULL, "SPKOUTLN"}, + {"Speaker", NULL, "SPKOUTRP"}, + {"Speaker", NULL, "SPKOUTRN"}, +}; + +static const struct snd_soc_dapm_route byt_wm5102_spk_hpout2_map[] = { + {"Speaker", NULL, "HPOUT2L"}, + {"Speaker", NULL, "HPOUT2R"}, +}; + +static const struct snd_soc_dapm_route byt_wm5102_intmic_in3l_hsmic_in1l_map[] = { + {"IN3L", NULL, "Internal Mic"}, + {"IN1L", NULL, "Headset Mic"}, +}; + +static const struct snd_soc_dapm_route byt_wm5102_intmic_in1l_hsmic_in2l_map[] = { + {"IN1L", NULL, "Internal Mic"}, + {"IN2L", NULL, "Headset Mic"}, +}; + static const struct snd_kcontrol_new byt_wm5102_controls[] = { SOC_DAPM_PIN_SWITCH("Headphone"), SOC_DAPM_PIN_SWITCH("Headset Mic"), @@ -201,8 +284,9 @@ static int byt_wm5102_init(struct snd_soc_pcm_runtime *runtime) { struct snd_soc_card *card = runtime->card; struct byt_wm5102_private *priv = snd_soc_card_get_drvdata(card); - struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; - int ret, jack_type; + struct snd_soc_component *component = snd_soc_rtd_to_codec(runtime, 0)->component; + const struct snd_soc_dapm_route *custom_map = NULL; + int ret, jack_type, num_routes = 0; card->dapm.idle_bias_off = true; @@ -213,6 +297,50 @@ static int byt_wm5102_init(struct snd_soc_pcm_runtime *runtime) return ret; } + switch (quirk & BYT_WM5102_IN_MAP) { + case BYT_WM5102_INTMIC_IN3L_HSMIC_IN1L: + custom_map = byt_wm5102_intmic_in3l_hsmic_in1l_map; + num_routes = ARRAY_SIZE(byt_wm5102_intmic_in3l_hsmic_in1l_map); + break; + case BYT_WM5102_INTMIC_IN1L_HSMIC_IN2L: + custom_map = byt_wm5102_intmic_in1l_hsmic_in2l_map; + num_routes = ARRAY_SIZE(byt_wm5102_intmic_in1l_hsmic_in2l_map); + break; + } + ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); + if (ret) + return ret; + + switch (quirk & BYT_WM5102_OUT_MAP) { + case BYT_WM5102_SPK_SPK_MAP: + custom_map = byt_wm5102_spk_spk_map; + num_routes = ARRAY_SIZE(byt_wm5102_spk_spk_map); + break; + case BYT_WM5102_SPK_HPOUT2_MAP: + custom_map = byt_wm5102_spk_hpout2_map; + num_routes = ARRAY_SIZE(byt_wm5102_spk_hpout2_map); + break; + } + ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); + if (ret) + return ret; + + if (quirk & BYT_WM5102_SSP2) { + custom_map = bytcr_wm5102_ssp2_map; + num_routes = ARRAY_SIZE(bytcr_wm5102_ssp2_map); + } else { + custom_map = bytcr_wm5102_ssp0_map; + num_routes = ARRAY_SIZE(bytcr_wm5102_ssp0_map); + } + ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); + if (ret) + return ret; + + if (quirk & BYT_WM5102_MCLK_19_2MHZ) + priv->mclk_freq = 19200000; + else + priv->mclk_freq = 25000000; + /* * The firmware might enable the clock at boot (this information * may or may not be reflected in the enable clock register). @@ -225,7 +353,7 @@ static int byt_wm5102_init(struct snd_soc_pcm_runtime *runtime) if (!ret) clk_disable_unprepare(priv->mclk); - ret = clk_set_rate(priv->mclk, MCLK_FREQ); + ret = clk_set_rate(priv->mclk, priv->mclk_freq); if (ret) { dev_err(card->dev, "Error setting MCLK rate: %d\n", ret); return ret; @@ -253,7 +381,7 @@ static int byt_wm5102_codec_fixup(struct snd_soc_pcm_runtime *rtd, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); - int ret; + int ret, bits; /* The DSP will convert the FE rate to 48k, stereo */ rate->min = 48000; @@ -261,15 +389,22 @@ static int byt_wm5102_codec_fixup(struct snd_soc_pcm_runtime *rtd, channels->min = 2; channels->max = 2; - /* set SSP0 to 16-bit */ - params_set_format(params, SNDRV_PCM_FORMAT_S16_LE); + if (quirk & BYT_WM5102_SSP2) { + /* set SSP2 to 24-bit */ + params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); + bits = 24; + } else { + /* set SSP0 to 16-bit */ + params_set_format(params, SNDRV_PCM_FORMAT_S16_LE); + bits = 16; + } /* * Default mode for SSP configuration is TDM 4 slot, override config * with explicit setting to I2S 2ch 16-bit. The word length is set with * dai_set_tdm_slot() since there is no other API exposed */ - ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), + ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BP_FP); @@ -278,7 +413,7 @@ static int byt_wm5102_codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 16); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits); if (ret) { dev_err(rtd->dev, "Error setting I2S config: %d\n", ret); return ret; @@ -345,12 +480,9 @@ static struct snd_soc_dai_link byt_wm5102_dais[] = { /* back ends */ { /* - * This must be named SSP2-Codec even though this machine driver - * always uses SSP0. Most machine drivers support both and dynamically - * update the dailink to point to SSP0 or SSP2, while keeping the name - * as "SSP2-Codec". The SOF tplg files hardcode the "SSP2-Codec" even - * in the byt-foo-ssp0.tplg versions because the other machine-drivers - * use "SSP2-Codec" even when SSP0 is used. + * This dailink is updated dynamically to point to SSP0 or SSP2. + * Yet its name is always kept as "SSP2-Codec" because the SOF + * tplg files hardcode "SSP2-Codec" even in byt-foo-ssp0.tplg. */ .name = "SSP2-Codec", .id = 0, @@ -384,8 +516,13 @@ static struct snd_soc_card byt_wm5102_card = { .fully_routed = true, }; +static char byt_wm5102_components[64]; /* = "cfg-spk:* cfg-int-mic:* cfg-hs-mic:* ..." */ + static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) { + static const char * const out_map_name[] = { "spk", "hpout2" }; + static const char * const intmic_map_name[] = { "in3l", "in1l" }; + static const char * const hsmic_map_name[] = { "in1l", "in2l" }; char codec_name[SND_ACPI_I2C_ID_LEN]; struct device *dev = &pdev->dev; struct byt_wm5102_private *priv; @@ -393,8 +530,9 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) const char *platform_name; struct acpi_device *adev; struct device *codec_dev; + int dai_index = 0; bool sof_parent; - int ret; + int i, ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -413,14 +551,15 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) */ mach = dev->platform_data; adev = acpi_dev_get_first_match_dev(mach->id, NULL, -1); - if (!adev) { - dev_err(dev, "Error cannot find acpi-dev for codec\n"); - return -ENOENT; + if (adev) { + snprintf(codec_name, sizeof(codec_name), "spi-%s", acpi_dev_name(adev)); + acpi_dev_put(adev); + } else { + /* Special case for when the codec is missing from the DSTD */ + strscpy(codec_name, "spi1.0", sizeof(codec_name)); } - snprintf(codec_name, sizeof(codec_name), "spi-%s", acpi_dev_name(adev)); codec_dev = bus_find_device_by_name(&spi_bus_type, NULL, codec_name); - acpi_dev_put(adev); if (!codec_dev) return -EPROBE_DEFER; @@ -440,6 +579,39 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) return dev_err_probe(dev, ret, "getting spkvdd-GPIO\n"); } + if (soc_intel_is_cht()) { + /* + * CHT always uses SSP2 and 19.2 MHz; and + * the one currently supported CHT design uses HPOUT2 as + * speaker output and has the intmic on IN1L + hsmic on IN2L. + */ + quirk = BYT_WM5102_SSP2 | BYT_WM5102_MCLK_19_2MHZ | + BYT_WM5102_INTMIC_IN1L_HSMIC_IN2L | + BYT_WM5102_SPK_HPOUT2_MAP; + } + if (quirk_override != -1) { + dev_info_once(dev, "Overriding quirk 0x%lx => 0x%x\n", + quirk, quirk_override); + quirk = quirk_override; + } + log_quirks(dev); + + snprintf(byt_wm5102_components, sizeof(byt_wm5102_components), + "cfg-spk:%s cfg-intmic:%s cfg-hsmic:%s", + out_map_name[FIELD_GET(BYT_WM5102_OUT_MAP, quirk)], + intmic_map_name[FIELD_GET(BYT_WM5102_IN_MAP, quirk)], + hsmic_map_name[FIELD_GET(BYT_WM5102_IN_MAP, quirk)]); + byt_wm5102_card.components = byt_wm5102_components; + + /* find index of codec dai */ + for (i = 0; i < ARRAY_SIZE(byt_wm5102_dais); i++) { + if (!strcmp(byt_wm5102_dais[i].codecs->name, + "wm5102-codec")) { + dai_index = i; + break; + } + } + /* override platform name, if required */ byt_wm5102_card.dev = dev; platform_name = mach->mach_params.platform; @@ -447,6 +619,10 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) if (ret) goto out_put_gpio; + /* override SSP port, if required */ + if (quirk & BYT_WM5102_SSP2) + byt_wm5102_dais[dai_index].cpus->dai_name = "ssp2-port"; + /* set card and driver name and pm-ops */ sof_parent = snd_soc_acpi_sof_parent(dev); if (sof_parent) { diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c index 850310de77..f43bc20d6a 100644 --- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c +++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c @@ -112,8 +112,8 @@ static const struct snd_kcontrol_new cht_mc_controls[] = { static int cht_aif1_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, M98090_REG_SYSTEM_CLOCK, @@ -258,7 +258,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, int ret = 0; unsigned int fmt = 0; - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 16); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 16); if (ret < 0) { dev_err(rtd->dev, "can't set cpu_dai slot fmt: %d\n", ret); return ret; @@ -266,7 +266,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BP_FP; - ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), fmt); + ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0), fmt); if (ret < 0) { dev_err(rtd->dev, "can't set cpu_dai set fmt: %d\n", ret); return ret; diff --git a/sound/soc/intel/boards/cht_bsw_nau8824.c b/sound/soc/intel/boards/cht_bsw_nau8824.c index af2d9a7846..7651b83632 100644 --- a/sound/soc/intel/boards/cht_bsw_nau8824.c +++ b/sound/soc/intel/boards/cht_bsw_nau8824.c @@ -72,8 +72,8 @@ static const struct snd_kcontrol_new cht_mc_controls[] = { static int cht_aif1_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, NAU8824_CLK_FLL_FS, 0, @@ -96,7 +96,7 @@ 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; - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(runtime, 0); struct snd_soc_component *component = codec_dai->component; int ret, jack_type; @@ -145,7 +145,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */ - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(rtd, 0), 0xf, 0x1, 4, 24); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_codec(rtd, 0), 0xf, 0x1, 4, 24); if (ret < 0) { dev_err(rtd->dev, "can't set codec TDM slot %d\n", ret); return ret; diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c index 875bc0b3d8..df23a581c1 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5645.c +++ b/sound/soc/intel/boards/cht_bsw_rt5645.c @@ -207,8 +207,8 @@ static struct snd_soc_jack_pin cht_bsw_jack_pins[] = { static int cht_aif1_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; /* set codec PLL source to the 19.2MHz platform clock (MCLK) */ @@ -252,7 +252,7 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) { struct snd_soc_card *card = runtime->card; struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); - struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(runtime, 0)->component; int jack_type; int ret; @@ -359,7 +359,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, * with explicit setting to I2S 2ch 16-bit. The word length is set with * dai_set_tdm_slot() since there is no other API exposed */ - ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), + ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BP_FP @@ -369,7 +369,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } - ret = snd_soc_dai_set_fmt(asoc_rtd_to_codec(rtd, 0), + ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_codec(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BC_FC @@ -379,7 +379,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 16); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, 16); if (ret < 0) { dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); return ret; @@ -393,7 +393,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, /* * Default mode for SSP configuration is TDM 4 slot */ - ret = snd_soc_dai_set_fmt(asoc_rtd_to_codec(rtd, 0), + ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_codec(rtd, 0), SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_BC_FC); @@ -403,7 +403,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, } /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */ - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(rtd, 0), 0xF, 0xF, 4, 24); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_codec(rtd, 0), 0xF, 0xF, 4, 24); if (ret < 0) { dev_err(rtd->dev, "can't set codec TDM slot %d\n", ret); return ret; diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c index daa630a0ef..f6da24f3c4 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5672.c +++ b/sound/soc/intel/boards/cht_bsw_rt5672.c @@ -155,8 +155,8 @@ static const struct snd_kcontrol_new cht_mc_controls[] = { static int cht_aif1_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; /* set codec PLL source to the 19.2MHz platform clock (MCLK) */ @@ -188,7 +188,7 @@ static const struct acpi_gpio_mapping cht_rt5672_gpios[] = { static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) { int ret; - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(runtime, 0); struct snd_soc_component *component = codec_dai->component; struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); @@ -297,7 +297,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, * board. Since we only support 2 channels anyways, there is no need * for TDM on any cht-bsw-rt5672 designs. So we use I2S 2ch everywhere. */ - ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), + ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0), SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BP_FP); @@ -306,7 +306,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, return ret; } - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits); if (ret < 0) { dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); return ret; diff --git a/sound/soc/intel/boards/cml_rt1011_rt5682.c b/sound/soc/intel/boards/cml_rt1011_rt5682.c index 20da83d9ee..679a09b63e 100644 --- a/sound/soc/intel/boards/cml_rt1011_rt5682.c +++ b/sound/soc/intel/boards/cml_rt1011_rt5682.c @@ -135,7 +135,7 @@ static struct snd_soc_jack_pin jack_pins[] = { static int cml_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) { struct card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; struct snd_soc_jack *jack; int ret; @@ -175,7 +175,7 @@ static int cml_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) static void cml_rt5682_codec_exit(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; snd_soc_component_set_jack(component, NULL, NULL); } @@ -212,8 +212,8 @@ static int cml_rt1011_spk_init(struct snd_soc_pcm_runtime *rtd) static int cml_rt5682_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int clk_id, clk_freq, pll_out, ret; clk_id = RT5682_PLL1_S_MCLK; @@ -245,7 +245,7 @@ static int cml_rt5682_hw_params(struct snd_pcm_substream *substream, static int cml_rt1011_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; struct snd_soc_card *card = rtd->card; int srate, i, ret = 0; @@ -369,7 +369,7 @@ static int sof_card_late_probe(struct snd_soc_card *card) static int hdmi_init(struct snd_soc_pcm_runtime *rtd) { struct card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); diff --git a/sound/soc/intel/boards/ehl_rt5660.c b/sound/soc/intel/boards/ehl_rt5660.c index fee80638cb..686e603212 100644 --- a/sound/soc/intel/boards/ehl_rt5660.c +++ b/sound/soc/intel/boards/ehl_rt5660.c @@ -74,7 +74,7 @@ struct sof_hdmi_pcm { static int hdmi_init(struct snd_soc_pcm_runtime *rtd) { struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct sof_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -109,8 +109,8 @@ static int card_late_probe(struct snd_soc_card *card) static int rt5660_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, @@ -267,7 +267,7 @@ static void hdmi_link_init(struct snd_soc_card *card, * hdmi codec is not supported */ for (i = HDMI_LINK_START; i <= HDMI_LINE_END; i++) - card->dai_link[i].codecs[0] = asoc_dummy_dlc; + card->dai_link[i].codecs[0] = snd_soc_dummy_dlc; } static int snd_ehl_rt5660_probe(struct platform_device *pdev) diff --git a/sound/soc/intel/boards/glk_rt5682_max98357a.c b/sound/soc/intel/boards/glk_rt5682_max98357a.c index cf0f89db3e..657e465823 100644 --- a/sound/soc/intel/boards/glk_rt5682_max98357a.c +++ b/sound/soc/intel/boards/glk_rt5682_max98357a.c @@ -152,8 +152,8 @@ static int geminilake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, static int geminilake_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) { struct glk_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_jack *jack; int pll_id, pll_source, clk_id, ret; @@ -215,8 +215,8 @@ static int geminilake_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) static int geminilake_rt5682_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; /* Set valid bitmask & configuration for I2S in 24 bit */ @@ -236,7 +236,7 @@ static struct snd_soc_ops geminilake_rt5682_ops = { static int geminilake_hdmi_init(struct snd_soc_pcm_runtime *rtd) { struct glk_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct glk_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -253,7 +253,7 @@ static int geminilake_hdmi_init(struct snd_soc_pcm_runtime *rtd) static int geminilake_rt5682_fe_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_cpu(rtd, 0)->component; struct snd_soc_dapm_context *dapm; int ret; diff --git a/sound/soc/intel/boards/hsw_rt5640.c b/sound/soc/intel/boards/hsw_rt5640.c index 050c53ebd6..2a2fe27dff 100644 --- a/sound/soc/intel/boards/hsw_rt5640.c +++ b/sound/soc/intel/boards/hsw_rt5640.c @@ -47,8 +47,8 @@ static int codec_link_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, static int codec_link_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_MCLK, 12288000, SND_SOC_CLOCK_IN); diff --git a/sound/soc/intel/boards/kbl_da7219_max98357a.c b/sound/soc/intel/boards/kbl_da7219_max98357a.c index 9714951307..a5d8965303 100644 --- a/sound/soc/intel/boards/kbl_da7219_max98357a.c +++ b/sound/soc/intel/boards/kbl_da7219_max98357a.c @@ -179,8 +179,8 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, static int kabylake_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) { struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_jack *jack; int ret; @@ -225,7 +225,7 @@ static int kabylake_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device) { struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct kbl_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -258,7 +258,7 @@ static int kabylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) static int kabylake_da7219_fe_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dapm_context *dapm; - struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_cpu(rtd, 0)->component; dapm = snd_soc_component_get_dapm(component); snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); diff --git a/sound/soc/intel/boards/kbl_da7219_max98927.c b/sound/soc/intel/boards/kbl_da7219_max98927.c index a1f8234c77..98c11ec0ad 100644 --- a/sound/soc/intel/boards/kbl_da7219_max98927.c +++ b/sound/soc/intel/boards/kbl_da7219_max98927.c @@ -194,7 +194,7 @@ static const struct snd_soc_dapm_route kabylake_ssp1_map[] = { static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *runtime = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *runtime = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; int ret, j; @@ -239,7 +239,7 @@ static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream, static int kabylake_ssp0_trigger(struct snd_pcm_substream *substream, int cmd) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; int j, ret; @@ -354,7 +354,7 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, static int kabylake_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) { struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; struct snd_soc_jack *jack; struct snd_soc_card *card = rtd->card; int ret; @@ -406,7 +406,7 @@ static int kabylake_dmic_init(struct snd_soc_pcm_runtime *rtd) static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device) { struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct kbl_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -439,7 +439,7 @@ static int kabylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) static int kabylake_da7219_fe_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dapm_context *dapm; - struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_cpu(rtd, 0)->component; dapm = snd_soc_component_get_dapm(component); snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); diff --git a/sound/soc/intel/boards/kbl_rt5660.c b/sound/soc/intel/boards/kbl_rt5660.c index 2c7a547f63..30e0aca161 100644 --- a/sound/soc/intel/boards/kbl_rt5660.c +++ b/sound/soc/intel/boards/kbl_rt5660.c @@ -157,7 +157,7 @@ static int kabylake_rt5660_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_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); ret = devm_acpi_dev_add_driver_gpios(component->dev, acpi_rt5660_gpios); @@ -222,7 +222,7 @@ static void kabylake_rt5660_codec_exit(struct snd_soc_pcm_runtime *rtd) static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device) { struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct kbl_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -255,8 +255,8 @@ static int kabylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) static int kabylake_rt5660_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c b/sound/soc/intel/boards/kbl_rt5663_max98927.c index 2d4224c5b1..9071b1f1cb 100644 --- a/sound/soc/intel/boards/kbl_rt5663_max98927.c +++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c @@ -259,7 +259,7 @@ static int kabylake_rt5663_fe_init(struct snd_soc_pcm_runtime *rtd) { int ret; struct snd_soc_dapm_context *dapm; - struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_cpu(rtd, 0)->component; dapm = snd_soc_component_get_dapm(component); ret = snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); @@ -275,7 +275,7 @@ 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_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; struct snd_soc_jack *jack; /* @@ -324,7 +324,7 @@ static int kabylake_rt5663_max98927_codec_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 = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct kbl_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -472,8 +472,8 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; /* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */ @@ -510,7 +510,7 @@ static int kabylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd, static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; int ret = 0, j; diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c index 2c79fca57b..178fe9c37d 100644 --- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c +++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c @@ -217,7 +217,7 @@ static struct snd_soc_codec_conf max98927_codec_conf[] = { static int kabylake_rt5663_fe_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dapm_context *dapm; - struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_cpu(rtd, 0)->component; int ret; dapm = snd_soc_component_get_dapm(component); @@ -232,7 +232,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_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; struct snd_soc_jack *jack; /* @@ -268,7 +268,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device) { struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct kbl_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -407,8 +407,8 @@ static int kabylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; /* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */ @@ -431,7 +431,7 @@ static struct snd_soc_ops kabylake_rt5663_ops = { static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; int ret = 0, j; diff --git a/sound/soc/intel/boards/skl_hda_dsp_generic.c b/sound/soc/intel/boards/skl_hda_dsp_generic.c index 70c806cc5b..6e172719c9 100644 --- a/sound/soc/intel/boards/skl_hda_dsp_generic.c +++ b/sound/soc/intel/boards/skl_hda_dsp_generic.c @@ -157,7 +157,7 @@ static int skl_hda_fill_card_info(struct snd_soc_acpi_mach_params *mach_params) card->dapm_routes = &skl_hda_map[IDISP_ROUTE_COUNT]; num_route -= IDISP_ROUTE_COUNT; for (i = 0; i < IDISP_DAI_COUNT; i++) { - skl_hda_be_dai_links[i].codecs = &asoc_dummy_dlc; + skl_hda_be_dai_links[i].codecs = &snd_soc_dummy_dlc; skl_hda_be_dai_links[i].num_codecs = 1; } } @@ -181,7 +181,7 @@ static void skl_set_hda_codec_autosuspend_delay(struct snd_soc_card *card) for_each_card_rtds(card, rtd) { if (!strstr(rtd->dai_link->codecs->name, "ehdaudio0D0")) continue; - dai = asoc_rtd_to_codec(rtd, 0); + dai = snd_soc_rtd_to_codec(rtd, 0); hda_pvt = snd_soc_component_get_drvdata(dai->component); if (hda_pvt) { /* diff --git a/sound/soc/intel/boards/skl_nau88l25_max98357a.c b/sound/soc/intel/boards/skl_nau88l25_max98357a.c index e13a5a4d8f..0e70258345 100644 --- a/sound/soc/intel/boards/skl_nau88l25_max98357a.c +++ b/sound/soc/intel/boards/skl_nau88l25_max98357a.c @@ -168,7 +168,7 @@ static int skylake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) { int ret; - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; /* * Headset buttons map to the google Reference headset. @@ -194,7 +194,7 @@ static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) static int skylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) { struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct skl_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -212,7 +212,7 @@ static int skylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) static int skylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) { struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct skl_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -230,7 +230,7 @@ static int skylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) static int skylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) { struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct skl_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -248,7 +248,7 @@ static int skylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dapm_context *dapm; - struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_cpu(rtd, 0)->component; dapm = snd_soc_component_get_dapm(component); snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); @@ -307,8 +307,8 @@ static const struct snd_soc_ops skylake_nau8825_fe_ops = { static int skylake_nau8825_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, diff --git a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c index 575604dc89..fadc25a536 100644 --- a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c +++ b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c @@ -172,12 +172,12 @@ static int skylake_ssm4567_codec_init(struct snd_soc_pcm_runtime *rtd) int ret; /* Slot 1 for left */ - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(rtd, 0), 0x01, 0x01, 2, 48); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_codec(rtd, 0), 0x01, 0x01, 2, 48); if (ret < 0) return ret; /* Slot 2 for right */ - ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_codec(rtd, 1), 0x02, 0x02, 2, 48); + ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_codec(rtd, 1), 0x02, 0x02, 2, 48); if (ret < 0) return ret; @@ -187,7 +187,7 @@ static int skylake_ssm4567_codec_init(struct snd_soc_pcm_runtime *rtd) static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) { int ret; - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; /* * 4 buttons here map to the google Reference headset @@ -213,7 +213,7 @@ static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) static int skylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) { struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct skl_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -231,7 +231,7 @@ static int skylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) static int skylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) { struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct skl_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -250,7 +250,7 @@ static int skylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) static int skylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) { struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct skl_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -268,7 +268,7 @@ static int skylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) static int skylake_nau8825_fe_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dapm_context *dapm; - struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_cpu(rtd, 0)->component; dapm = snd_soc_component_get_dapm(component); snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); @@ -359,8 +359,8 @@ static int skylake_dmic_fixup(struct snd_soc_pcm_runtime *rtd, static int skylake_nau8825_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, diff --git a/sound/soc/intel/boards/skl_rt286.c b/sound/soc/intel/boards/skl_rt286.c index 4f3d655e2b..c59c60e280 100644 --- a/sound/soc/intel/boards/skl_rt286.c +++ b/sound/soc/intel/boards/skl_rt286.c @@ -112,7 +112,7 @@ static const struct snd_soc_dapm_route skylake_rt286_map[] = { static int skylake_rt286_fe_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dapm_context *dapm; - struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_cpu(rtd, 0)->component; dapm = snd_soc_component_get_dapm(component); snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); @@ -122,7 +122,7 @@ static int skylake_rt286_fe_init(struct snd_soc_pcm_runtime *rtd) static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; int ret; ret = snd_soc_card_jack_new_pins(rtd->card, "Headset", @@ -143,7 +143,7 @@ static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd) static int skylake_hdmi_init(struct snd_soc_pcm_runtime *rtd) { struct skl_rt286_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct skl_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -228,8 +228,8 @@ static int skylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd, static int skylake_rt286_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(codec_dai, RT286_SCLK_S_PLL, 24000000, diff --git a/sound/soc/intel/boards/sof_board_helpers.c b/sound/soc/intel/boards/sof_board_helpers.c new file mode 100644 index 0000000000..ce2967850c --- /dev/null +++ b/sound/soc/intel/boards/sof_board_helpers.c @@ -0,0 +1,204 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2023 Intel Corporation. All rights reserved. + +#include <sound/soc.h> +#include "hda_dsp_common.h" +#include "sof_board_helpers.h" + +/* + * Intel HDMI DAI Link + */ +static int hdmi_init(struct snd_soc_pcm_runtime *rtd) +{ + struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); + + ctx->hdmi.hdmi_comp = dai->component; + + return 0; +} + +int sof_intel_board_card_late_probe(struct snd_soc_card *card) +{ + struct sof_card_private *ctx = snd_soc_card_get_drvdata(card); + + if (!ctx->hdmi_num) + return 0; + + if (!ctx->hdmi.idisp_codec) + return 0; + + if (!ctx->hdmi.hdmi_comp) + return -EINVAL; + + return hda_dsp_hdmi_build_controls(card, ctx->hdmi.hdmi_comp); +} +EXPORT_SYMBOL_NS(sof_intel_board_card_late_probe, SND_SOC_INTEL_SOF_BOARD_HELPERS); + +/* + * DMIC DAI Link + */ +static const struct snd_soc_dapm_widget dmic_widgets[] = { + SND_SOC_DAPM_MIC("SoC DMIC", NULL), +}; + +static const struct snd_soc_dapm_route dmic_routes[] = { + {"DMic", NULL, "SoC DMIC"}, +}; + +static int dmic_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + int ret; + + ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets, + ARRAY_SIZE(dmic_widgets)); + if (ret) { + dev_err(rtd->dev, "fail to add dmic widgets, ret %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, dmic_routes, + ARRAY_SIZE(dmic_routes)); + if (ret) { + dev_err(rtd->dev, "fail to add dmic routes, ret %d\n", ret); + return ret; + } + + return 0; +} + +/* + * DAI Link Helpers + */ +static struct snd_soc_dai_link_component dmic_component[] = { + { + .name = "dmic-codec", + .dai_name = "dmic-hifi", + } +}; + +static struct snd_soc_dai_link_component platform_component[] = { + { + /* name might be overridden during probe */ + .name = "0000:00:1f.3" + } +}; + +int sof_intel_board_set_dmic_link(struct device *dev, + struct snd_soc_dai_link *link, int be_id, + enum sof_dmic_be_type be_type) +{ + struct snd_soc_dai_link_component *cpus; + + /* cpus */ + cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component), + GFP_KERNEL); + if (!cpus) + return -ENOMEM; + + switch (be_type) { + case SOF_DMIC_01: + dev_dbg(dev, "link %d: dmic01\n", be_id); + + link->name = "dmic01"; + cpus->dai_name = "DMIC01 Pin"; + break; + case SOF_DMIC_16K: + dev_dbg(dev, "link %d: dmic16k\n", be_id); + + link->name = "dmic16k"; + cpus->dai_name = "DMIC16k Pin"; + break; + default: + dev_err(dev, "invalid be type %d\n", be_type); + return -EINVAL; + } + + link->cpus = cpus; + link->num_cpus = 1; + + /* codecs */ + link->codecs = dmic_component; + link->num_codecs = ARRAY_SIZE(dmic_component); + + /* platforms */ + link->platforms = platform_component; + link->num_platforms = ARRAY_SIZE(platform_component); + + link->id = be_id; + if (be_type == SOF_DMIC_01) + link->init = dmic_init; + link->ignore_suspend = 1; + link->no_pcm = 1; + link->dpcm_capture = 1; + + return 0; +} +EXPORT_SYMBOL_NS(sof_intel_board_set_dmic_link, SND_SOC_INTEL_SOF_BOARD_HELPERS); + +int sof_intel_board_set_intel_hdmi_link(struct device *dev, + struct snd_soc_dai_link *link, int be_id, + int hdmi_id, bool idisp_codec) +{ + struct snd_soc_dai_link_component *cpus, *codecs; + + dev_dbg(dev, "link %d: intel hdmi, hdmi id %d, idisp codec %d\n", + be_id, hdmi_id, idisp_codec); + + /* link name */ + link->name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d", hdmi_id); + if (!link->name) + return -ENOMEM; + + /* cpus */ + cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component), + GFP_KERNEL); + if (!cpus) + return -ENOMEM; + + cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d Pin", hdmi_id); + if (!cpus->dai_name) + return -ENOMEM; + + link->cpus = cpus; + link->num_cpus = 1; + + /* codecs */ + if (idisp_codec) { + codecs = devm_kzalloc(dev, + sizeof(struct snd_soc_dai_link_component), + GFP_KERNEL); + if (!codecs) + return -ENOMEM; + + codecs->name = "ehdaudio0D2"; + codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, + "intel-hdmi-hifi%d", hdmi_id); + if (!codecs->dai_name) + return -ENOMEM; + + link->codecs = codecs; + } else { + link->codecs = &snd_soc_dummy_dlc; + } + link->num_codecs = 1; + + /* platforms */ + link->platforms = platform_component; + link->num_platforms = ARRAY_SIZE(platform_component); + + link->id = be_id; + link->init = (hdmi_id == 1) ? hdmi_init : NULL; + link->no_pcm = 1; + link->dpcm_playback = 1; + + return 0; +} +EXPORT_SYMBOL_NS(sof_intel_board_set_intel_hdmi_link, SND_SOC_INTEL_SOF_BOARD_HELPERS); + +MODULE_DESCRIPTION("ASoC Intel SOF Machine Driver Board Helpers"); +MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); diff --git a/sound/soc/intel/boards/sof_board_helpers.h b/sound/soc/intel/boards/sof_board_helpers.h new file mode 100644 index 0000000000..df99f576c1 --- /dev/null +++ b/sound/soc/intel/boards/sof_board_helpers.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright(c) 2023 Intel Corporation. + */ + +#ifndef __SOF_INTEL_BOARD_HELPERS_H +#define __SOF_INTEL_BOARD_HELPERS_H + +#include <sound/soc.h> +#include "sof_hdmi_common.h" +#include "sof_ssp_common.h" + +/* + * sof_rt5682_private: private data for rt5682 machine driver + * + * @mclk: mclk clock data + * @is_legacy_cpu: true for BYT/CHT boards + */ +struct sof_rt5682_private { + struct clk *mclk; + bool is_legacy_cpu; +}; + +/* + * sof_card_private: common data for machine drivers + * + * @headset_jack: headset jack data + * @hdmi: init data for hdmi dai link + * @codec_type: type of headset codec + * @amp_type: type of speaker amplifier + * @dmic_be_num: number of Intel PCH DMIC BE link + * @hdmi_num: number of Intel HDMI BE link + * @rt5682: private data for rt5682 machine driver + */ +struct sof_card_private { + struct snd_soc_jack headset_jack; + struct sof_hdmi_private hdmi; + + enum sof_ssp_codec codec_type; + enum sof_ssp_codec amp_type; + + int dmic_be_num; + int hdmi_num; + + union { + struct sof_rt5682_private rt5682; + }; +}; + +enum sof_dmic_be_type { + SOF_DMIC_01, + SOF_DMIC_16K, +}; + +int sof_intel_board_card_late_probe(struct snd_soc_card *card); + +int sof_intel_board_set_dmic_link(struct device *dev, + struct snd_soc_dai_link *link, int be_id, + enum sof_dmic_be_type be_type); +int sof_intel_board_set_intel_hdmi_link(struct device *dev, + struct snd_soc_dai_link *link, int be_id, + int hdmi_id, bool idisp_codec); + +#endif /* __SOF_INTEL_BOARD_HELPERS_H */ diff --git a/sound/soc/intel/boards/sof_cirrus_common.c b/sound/soc/intel/boards/sof_cirrus_common.c index 8b8b07e4f2..e71e09124b 100644 --- a/sound/soc/intel/boards/sof_cirrus_common.c +++ b/sound/soc/intel/boards/sof_cirrus_common.c @@ -91,7 +91,7 @@ static const struct { static int cs35l41_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; int clk_freq, i, ret; diff --git a/sound/soc/intel/boards/sof_cirrus_common.h b/sound/soc/intel/boards/sof_cirrus_common.h index ca438c12c3..d4ecf8d023 100644 --- a/sound/soc/intel/boards/sof_cirrus_common.h +++ b/sound/soc/intel/boards/sof_cirrus_common.h @@ -9,15 +9,16 @@ #define __SOF_CIRRUS_COMMON_H #include <sound/soc.h> +#include "sof_ssp_common.h" /* * Cirrus Logic CS35L41/CS35L53 */ #define CS35L41_CODEC_DAI "cs35l41-pcm" -#define CS35L41_DEV0_NAME "i2c-CSC3541:00" -#define CS35L41_DEV1_NAME "i2c-CSC3541:01" -#define CS35L41_DEV2_NAME "i2c-CSC3541:02" -#define CS35L41_DEV3_NAME "i2c-CSC3541:03" +#define CS35L41_DEV0_NAME "i2c-" CS35L41_ACPI_HID ":00" +#define CS35L41_DEV1_NAME "i2c-" CS35L41_ACPI_HID ":01" +#define CS35L41_DEV2_NAME "i2c-" CS35L41_ACPI_HID ":02" +#define CS35L41_DEV3_NAME "i2c-" CS35L41_ACPI_HID ":03" void cs35l41_set_dai_link(struct snd_soc_dai_link *link); void cs35l41_set_codec_conf(struct snd_soc_card *card); diff --git a/sound/soc/intel/boards/sof_cs42l42.c b/sound/soc/intel/boards/sof_cs42l42.c index e6695e77d5..1f760fc4ca 100644 --- a/sound/soc/intel/boards/sof_cs42l42.c +++ b/sound/soc/intel/boards/sof_cs42l42.c @@ -19,16 +19,13 @@ #include <sound/sof.h> #include <sound/soc-acpi.h> #include <dt-bindings/sound/cs42l42.h> -#include "../../codecs/hdac_hdmi.h" #include "../common/soc-intel-quirks.h" -#include "hda_dsp_common.h" +#include "sof_board_helpers.h" #include "sof_maxim_common.h" - -#define NAME_SIZE 32 +#include "sof_ssp_common.h" #define SOF_CS42L42_SSP_CODEC(quirk) ((quirk) & GENMASK(2, 0)) #define SOF_CS42L42_SSP_CODEC_MASK (GENMASK(2, 0)) -#define SOF_SPEAKER_AMP_PRESENT BIT(3) #define SOF_CS42L42_SSP_AMP_SHIFT 4 #define SOF_CS42L42_SSP_AMP_MASK (GENMASK(6, 4)) #define SOF_CS42L42_SSP_AMP(quirk) \ @@ -46,8 +43,6 @@ #define SOF_CS42L42_SSP_BT_MASK (GENMASK(28, 26)) #define SOF_CS42L42_SSP_BT(quirk) \ (((quirk) << SOF_CS42L42_SSP_BT_SHIFT) & SOF_CS42L42_SSP_BT_MASK) -#define SOF_MAX98357A_SPEAKER_AMP_PRESENT BIT(29) -#define SOF_MAX98360A_SPEAKER_AMP_PRESENT BIT(30) enum { LINK_NONE = 0, @@ -72,42 +67,10 @@ static struct snd_soc_jack_pin jack_pins[] = { /* Default: SSP2 */ static unsigned long sof_cs42l42_quirk = SOF_CS42L42_SSP_CODEC(2); -struct sof_hdmi_pcm { - struct list_head head; - struct snd_soc_dai *codec_dai; - struct snd_soc_jack hdmi_jack; - int device; -}; - -struct sof_card_private { - struct snd_soc_jack headset_jack; - struct list_head hdmi_pcm_list; - bool common_hdmi_codec_drv; -}; - -static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd) -{ - struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); - struct sof_hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - /* dai_link id is 1:1 mapped to the PCM device */ - pcm->device = rtd->dai_link->id; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); - - return 0; -} - static int sof_cs42l42_init(struct snd_soc_pcm_runtime *rtd) { struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; struct snd_soc_jack *jack = &ctx->headset_jack; int ret; @@ -143,7 +106,7 @@ static int sof_cs42l42_init(struct snd_soc_pcm_runtime *rtd) static void sof_cs42l42_exit(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; snd_soc_component_set_jack(component, NULL, NULL); } @@ -151,8 +114,8 @@ static void sof_cs42l42_exit(struct snd_soc_pcm_runtime *rtd) static int sof_cs42l42_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int clk_freq, ret; clk_freq = sof_dai_get_bclk(rtd); /* BCLK freq */ @@ -184,39 +147,7 @@ static struct snd_soc_dai_link_component platform_component[] = { static int sof_card_late_probe(struct snd_soc_card *card) { - struct sof_card_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_component *component = NULL; - char jack_name[NAME_SIZE]; - struct sof_hdmi_pcm *pcm; - int err; - - if (list_empty(&ctx->hdmi_pcm_list)) - return -EINVAL; - - if (ctx->common_hdmi_codec_drv) { - pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm, - head); - component = pcm->codec_dai->component; - return hda_dsp_hdmi_build_controls(card, component); - } - - list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { - component = pcm->codec_dai->component; - 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, &pcm->hdmi_jack); - - if (err) - return err; - - err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, - &pcm->hdmi_jack); - if (err < 0) - return err; - } - - return hdac_hdmi_jack_port_init(component, &card->dapm); + return sof_intel_board_card_late_probe(card); } static const struct snd_kcontrol_new sof_controls[] = { @@ -229,10 +160,6 @@ static const struct snd_soc_dapm_widget sof_widgets[] = { SND_SOC_DAPM_MIC("Headset Mic", NULL), }; -static const struct snd_soc_dapm_widget dmic_widgets[] = { - SND_SOC_DAPM_MIC("SoC DMIC", NULL), -}; - static const struct snd_soc_dapm_route sof_map[] = { /* HP jack connectors - unknown if we have jack detection */ {"Headphone Jack", NULL, "HP"}, @@ -241,33 +168,6 @@ static const struct snd_soc_dapm_route sof_map[] = { {"HS", NULL, "Headset Mic"}, }; -static const struct snd_soc_dapm_route dmic_map[] = { - /* digital mics */ - {"DMic", NULL, "SoC DMIC"}, -}; - -static int dmic_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_card *card = rtd->card; - int ret; - - ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets, - ARRAY_SIZE(dmic_widgets)); - if (ret) { - dev_err(card->dev, "DMic widget addition failed: %d\n", ret); - /* Don't need to add routes if widget addition failed */ - return ret; - } - - ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map, - ARRAY_SIZE(dmic_map)); - - if (ret) - dev_err(card->dev, "DMic map addition failed: %d\n", ret); - - return ret; -} - /* sof audio machine driver for cs42l42 codec */ static struct snd_soc_card sof_audio_card_cs42l42 = { .name = "cs42l42", /* the sof- prefix is added by the core */ @@ -289,22 +189,16 @@ static struct snd_soc_dai_link_component cs42l42_component[] = { } }; -static struct snd_soc_dai_link_component dmic_component[] = { - { - .name = "dmic-codec", - .dai_name = "dmic-hifi", - } -}; - static int create_spk_amp_dai_links(struct device *dev, struct snd_soc_dai_link *links, struct snd_soc_dai_link_component *cpus, - int *id, int ssp_amp) + int *id, enum sof_ssp_codec amp_type, + int ssp_amp) { int ret = 0; /* speaker amp */ - if (!(sof_cs42l42_quirk & SOF_SPEAKER_AMP_PRESENT)) + if (amp_type == CODEC_NONE) return 0; links[*id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", @@ -316,14 +210,16 @@ static int create_spk_amp_dai_links(struct device *dev, links[*id].id = *id; - if (sof_cs42l42_quirk & SOF_MAX98357A_SPEAKER_AMP_PRESENT) { + switch (amp_type) { + case CODEC_MAX98357A: max_98357a_dai_link(&links[*id]); - } else if (sof_cs42l42_quirk & SOF_MAX98360A_SPEAKER_AMP_PRESENT) { + break; + case CODEC_MAX98360A: max_98360a_dai_link(&links[*id]); - } else { - dev_err(dev, "no amp defined\n"); - ret = -EINVAL; - goto devm_err; + break; + default: + dev_err(dev, "invalid amp type %d\n", amp_type); + return -EINVAL; } links[*id].platforms = platform_component; @@ -388,106 +284,6 @@ devm_err: return -ENOMEM; } -static int create_dmic_dai_links(struct device *dev, - struct snd_soc_dai_link *links, - struct snd_soc_dai_link_component *cpus, - int *id, int dmic_be_num) -{ - int i; - - /* dmic */ - if (dmic_be_num <= 0) - return 0; - - /* at least we have dmic01 */ - links[*id].name = "dmic01"; - links[*id].cpus = &cpus[*id]; - links[*id].cpus->dai_name = "DMIC01 Pin"; - links[*id].init = dmic_init; - if (dmic_be_num > 1) { - /* set up 2 BE links at most */ - links[*id + 1].name = "dmic16k"; - links[*id + 1].cpus = &cpus[*id + 1]; - links[*id + 1].cpus->dai_name = "DMIC16k Pin"; - dmic_be_num = 2; - } - - for (i = 0; i < dmic_be_num; i++) { - links[*id].id = *id; - links[*id].num_cpus = 1; - links[*id].codecs = dmic_component; - links[*id].num_codecs = ARRAY_SIZE(dmic_component); - links[*id].platforms = platform_component; - links[*id].num_platforms = ARRAY_SIZE(platform_component); - links[*id].ignore_suspend = 1; - links[*id].dpcm_capture = 1; - links[*id].no_pcm = 1; - - (*id)++; - } - - return 0; -} - -static int create_hdmi_dai_links(struct device *dev, - struct snd_soc_dai_link *links, - struct snd_soc_dai_link_component *cpus, - int *id, int hdmi_num) -{ - struct snd_soc_dai_link_component *idisp_components; - int i; - - /* HDMI */ - if (hdmi_num <= 0) - return 0; - - idisp_components = devm_kcalloc(dev, - hdmi_num, - sizeof(struct snd_soc_dai_link_component), GFP_KERNEL); - if (!idisp_components) - goto devm_err; - - for (i = 1; i <= hdmi_num; i++) { - links[*id].name = devm_kasprintf(dev, GFP_KERNEL, - "iDisp%d", i); - if (!links[*id].name) - goto devm_err; - - links[*id].id = *id; - links[*id].cpus = &cpus[*id]; - links[*id].num_cpus = 1; - links[*id].cpus->dai_name = devm_kasprintf(dev, - GFP_KERNEL, - "iDisp%d Pin", - i); - if (!links[*id].cpus->dai_name) - goto devm_err; - - idisp_components[i - 1].name = "ehdaudio0D2"; - idisp_components[i - 1].dai_name = devm_kasprintf(dev, - GFP_KERNEL, - "intel-hdmi-hifi%d", - i); - if (!idisp_components[i - 1].dai_name) - goto devm_err; - - links[*id].codecs = &idisp_components[i - 1]; - links[*id].num_codecs = 1; - links[*id].platforms = platform_component; - links[*id].num_platforms = ARRAY_SIZE(platform_component); - links[*id].init = sof_hdmi_init; - links[*id].dpcm_playback = 1; - links[*id].no_pcm = 1; - - (*id)++; - } - - return 0; - -devm_err: - return -ENOMEM; -} - static int create_bt_offload_dai_links(struct device *dev, struct snd_soc_dai_link *links, struct snd_soc_dai_link_component *cpus, @@ -503,7 +299,7 @@ static int create_bt_offload_dai_links(struct device *dev, goto devm_err; links[*id].id = *id; - links[*id].codecs = &asoc_dummy_dlc; + links[*id].codecs = &snd_soc_dummy_dlc; links[*id].num_codecs = 1; links[*id].platforms = platform_component; links[*id].num_platforms = ARRAY_SIZE(platform_component); @@ -528,16 +324,17 @@ devm_err: return -ENOMEM; } -static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, - int ssp_codec, - int ssp_amp, - int ssp_bt, - int dmic_be_num, - int hdmi_num) +static struct snd_soc_dai_link * +sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec amp_type, + int ssp_codec, int ssp_amp, int ssp_bt, + int dmic_be_num, int hdmi_num, bool idisp_codec) { struct snd_soc_dai_link_component *cpus; struct snd_soc_dai_link *links; - int ret, id = 0, link_seq; + int ret; + int id = 0; + int link_seq; + int i; links = devm_kcalloc(dev, sof_audio_card_cs42l42.num_links, sizeof(struct snd_soc_dai_link), GFP_KERNEL); @@ -561,7 +358,8 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, } break; case LINK_SPK: - ret = create_spk_amp_dai_links(dev, links, cpus, &id, ssp_amp); + ret = create_spk_amp_dai_links(dev, links, cpus, &id, + amp_type, ssp_amp); if (ret < 0) { dev_err(dev, "fail to create spk amp dai links, ret %d\n", ret); @@ -569,19 +367,49 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, } break; case LINK_DMIC: - ret = create_dmic_dai_links(dev, links, cpus, &id, dmic_be_num); - if (ret < 0) { - dev_err(dev, "fail to create dmic dai links, ret %d\n", - ret); - goto devm_err; + if (dmic_be_num > 0) { + /* at least we have dmic01 */ + ret = sof_intel_board_set_dmic_link(dev, + &links[id], + id, + SOF_DMIC_01); + if (ret) { + dev_err(dev, "fail to create dmic01 link, ret %d\n", + ret); + goto devm_err; + } + + id++; + } + + if (dmic_be_num > 1) { + /* set up 2 BE links at most */ + ret = sof_intel_board_set_dmic_link(dev, + &links[id], + id, + SOF_DMIC_16K); + if (ret) { + dev_err(dev, "fail to create dmic16k link, ret %d\n", + ret); + goto devm_err; + } + + id++; } break; case LINK_HDMI: - ret = create_hdmi_dai_links(dev, links, cpus, &id, hdmi_num); - if (ret < 0) { - dev_err(dev, "fail to create hdmi dai links, ret %d\n", - ret); - goto devm_err; + for (i = 1; i <= hdmi_num; i++) { + ret = sof_intel_board_set_intel_hdmi_link(dev, + &links[id], + id, i, + idisp_codec); + if (ret) { + dev_err(dev, "fail to create hdmi link, ret %d\n", + ret); + goto devm_err; + } + + id++; } break; case LINK_BT: @@ -609,10 +437,9 @@ devm_err: static int sof_audio_probe(struct platform_device *pdev) { + struct snd_soc_acpi_mach *mach = pdev->dev.platform_data; struct snd_soc_dai_link *dai_links; - struct snd_soc_acpi_mach *mach; struct sof_card_private *ctx; - int dmic_be_num, hdmi_num; int ret, ssp_bt, ssp_amp, ssp_codec; ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); @@ -622,20 +449,24 @@ static int sof_audio_probe(struct platform_device *pdev) if (pdev->id_entry && pdev->id_entry->driver_data) sof_cs42l42_quirk = (unsigned long)pdev->id_entry->driver_data; - mach = pdev->dev.platform_data; + ctx->codec_type = sof_ssp_detect_codec_type(&pdev->dev); + ctx->amp_type = sof_ssp_detect_amp_type(&pdev->dev); if (soc_intel_is_glk()) { - dmic_be_num = 1; - hdmi_num = 3; + ctx->dmic_be_num = 1; + ctx->hdmi_num = 3; } else { - dmic_be_num = 2; - hdmi_num = (sof_cs42l42_quirk & SOF_CS42L42_NUM_HDMIDEV_MASK) >> + ctx->dmic_be_num = 2; + ctx->hdmi_num = (sof_cs42l42_quirk & SOF_CS42L42_NUM_HDMIDEV_MASK) >> SOF_CS42L42_NUM_HDMIDEV_SHIFT; /* default number of HDMI DAI's */ - if (!hdmi_num) - hdmi_num = 3; + if (!ctx->hdmi_num) + ctx->hdmi_num = 3; } + if (mach->mach_params.codec_mask & IDISP_CODEC_MASK) + ctx->hdmi.idisp_codec = true; + dev_dbg(&pdev->dev, "sof_cs42l42_quirk = %lx\n", sof_cs42l42_quirk); ssp_bt = (sof_cs42l42_quirk & SOF_CS42L42_SSP_BT_MASK) >> @@ -647,22 +478,22 @@ static int sof_audio_probe(struct platform_device *pdev) ssp_codec = sof_cs42l42_quirk & SOF_CS42L42_SSP_CODEC_MASK; /* compute number of dai links */ - sof_audio_card_cs42l42.num_links = 1 + dmic_be_num + hdmi_num; + sof_audio_card_cs42l42.num_links = 1 + ctx->dmic_be_num + ctx->hdmi_num; - if (sof_cs42l42_quirk & SOF_SPEAKER_AMP_PRESENT) + if (ctx->amp_type != CODEC_NONE) sof_audio_card_cs42l42.num_links++; if (sof_cs42l42_quirk & SOF_BT_OFFLOAD_PRESENT) sof_audio_card_cs42l42.num_links++; - dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp, - ssp_bt, dmic_be_num, hdmi_num); + dai_links = sof_card_dai_links_create(&pdev->dev, ctx->amp_type, + ssp_codec, ssp_amp, ssp_bt, + ctx->dmic_be_num, ctx->hdmi_num, + ctx->hdmi.idisp_codec); if (!dai_links) return -ENOMEM; sof_audio_card_cs42l42.dai_link = dai_links; - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - sof_audio_card_cs42l42.dev = &pdev->dev; /* set platform name for each dailink */ @@ -671,8 +502,6 @@ static int sof_audio_probe(struct platform_device *pdev) if (ret) return ret; - ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv; - snd_soc_card_set_drvdata(&sof_audio_card_cs42l42, ctx); return devm_snd_soc_register_card(&pdev->dev, @@ -683,24 +512,18 @@ static const struct platform_device_id board_ids[] = { { .name = "glk_cs4242_mx98357a", .driver_data = (kernel_ulong_t)(SOF_CS42L42_SSP_CODEC(2) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98357A_SPEAKER_AMP_PRESENT | SOF_CS42L42_SSP_AMP(1)) | SOF_CS42L42_DAILINK(LINK_SPK, LINK_HP, LINK_DMIC, LINK_HDMI, LINK_NONE), }, { .name = "jsl_cs4242_mx98360a", .driver_data = (kernel_ulong_t)(SOF_CS42L42_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98360A_SPEAKER_AMP_PRESENT | SOF_CS42L42_SSP_AMP(1)) | SOF_CS42L42_DAILINK(LINK_HP, LINK_DMIC, LINK_HDMI, LINK_SPK, LINK_NONE), }, { .name = "adl_mx98360a_cs4242", .driver_data = (kernel_ulong_t)(SOF_CS42L42_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98360A_SPEAKER_AMP_PRESENT | SOF_CS42L42_SSP_AMP(1) | SOF_CS42L42_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_PRESENT | @@ -725,5 +548,6 @@ module_platform_driver(sof_audio) MODULE_DESCRIPTION("SOF Audio Machine driver for CS42L42"); MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); +MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS); MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON); +MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_SSP_COMMON); diff --git a/sound/soc/intel/boards/sof_da7219_max98373.c b/sound/soc/intel/boards/sof_da7219.c index bbd47e7e43..6eb5a6144e 100644 --- a/sound/soc/intel/boards/sof_da7219_max98373.c +++ b/sound/soc/intel/boards/sof_da7219.c @@ -2,7 +2,7 @@ // Copyright(c) 2019 Intel Corporation. /* - * Intel SOF Machine driver for DA7219 + MAX98373/MAX98360A codec + * Intel SOF Machine driver for Dialog headphone codec */ #include <linux/input.h> @@ -13,24 +13,25 @@ #include <linux/platform_device.h> #include <sound/soc.h> #include <sound/soc-acpi.h> +#include <sound/sof.h> #include "../../codecs/da7219.h" #include "hda_dsp_common.h" +#include "sof_hdmi_common.h" +#include "sof_maxim_common.h" +#include "sof_ssp_common.h" -#define DIALOG_CODEC_DAI "da7219-hifi" -#define MAX98373_CODEC_DAI "max98373-aif1" -#define MAXIM_DEV0_NAME "i2c-MX98373:00" -#define MAXIM_DEV1_NAME "i2c-MX98373:01" +/* Board Quirks */ +#define SOF_DA7219_JSL_BOARD BIT(2) -struct hdmi_pcm { - struct list_head head; - struct snd_soc_dai *codec_dai; - int device; -}; +#define DIALOG_CODEC_DAI "da7219-hifi" struct card_private { - struct snd_soc_jack headset; - struct list_head hdmi_pcm_list; - struct snd_soc_jack hdmi[3]; + struct snd_soc_jack headset_jack; + struct sof_hdmi_private hdmi; + enum sof_ssp_codec codec_type; + enum sof_ssp_codec amp_type; + + unsigned int pll_bypass:1; }; static int platform_clock_control(struct snd_soc_dapm_widget *w, @@ -38,9 +39,14 @@ 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 card_private *ctx = snd_soc_card_get_drvdata(card); struct snd_soc_dai *codec_dai; int ret = 0; + if (ctx->pll_bypass) + return ret; + + /* PLL SRM mode */ codec_dai = snd_soc_card_get_codec_dai(card, DIALOG_CODEC_DAI); if (!codec_dai) { dev_err(card->dev, "Codec dai not found; Unable to set/unset codec pll\n"); @@ -53,6 +59,8 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, if (ret) dev_err(card->dev, "failed to stop PLL: %d\n", ret); } else if (SND_SOC_DAPM_EVENT_ON(event)) { + dev_dbg(card->dev, "pll srm mode\n"); + ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_PLL_SRM, 0, DA7219_PLL_FREQ_OUT_98304); if (ret) @@ -70,14 +78,6 @@ static const struct snd_kcontrol_new controls[] = { SOC_DAPM_PIN_SWITCH("Right Spk"), }; -static const struct snd_kcontrol_new m98360a_controls[] = { - SOC_DAPM_PIN_SWITCH("Headphone Jack"), - SOC_DAPM_PIN_SWITCH("Headset Mic"), - SOC_DAPM_PIN_SWITCH("Line Out"), - SOC_DAPM_PIN_SWITCH("Spk"), -}; - -/* For MAX98373 amp */ static const struct snd_soc_dapm_widget widgets[] = { SND_SOC_DAPM_HP("Headphone Jack", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), @@ -103,40 +103,6 @@ static const struct snd_soc_dapm_route audio_map[] = { { "Headset Mic", NULL, "Platform Clock" }, { "Line Out", NULL, "Platform Clock" }, - { "Left Spk", NULL, "Left BE_OUT" }, - { "Right Spk", NULL, "Right BE_OUT" }, - - /* digital mics */ - {"DMic", NULL, "SoC DMIC"}, -}; - -/* For MAX98360A amp */ -static const struct snd_soc_dapm_widget max98360a_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_LINE("Line Out", NULL), - - SND_SOC_DAPM_SPK("Spk", NULL), - - SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, - platform_clock_control, SND_SOC_DAPM_POST_PMD | - SND_SOC_DAPM_PRE_PMU), - - SND_SOC_DAPM_MIC("SoC DMIC", NULL), -}; - -static const struct snd_soc_dapm_route max98360a_map[] = { - { "Headphone Jack", NULL, "HPL" }, - { "Headphone Jack", NULL, "HPR" }, - - { "MIC", NULL, "Headset Mic" }, - - { "Headphone Jack", NULL, "Platform Clock" }, - { "Headset Mic", NULL, "Platform Clock" }, - { "Line Out", NULL, "Platform Clock" }, - - {"Spk", NULL, "Speaker"}, - /* digital mics */ {"DMic", NULL, "SoC DMIC"}, }; @@ -156,24 +122,45 @@ static struct snd_soc_jack_pin jack_pins[] = { }, }; -static struct snd_soc_jack headset; - static int da7219_codec_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct card_private *ctx = snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_component *component = codec_dai->component; - struct snd_soc_jack *jack; - int ret; + struct snd_soc_jack *jack = &ctx->headset_jack; + int mclk_rate, ret; + + mclk_rate = sof_dai_get_mclk(rtd); + if (mclk_rate <= 0) { + dev_err(rtd->dev, "invalid mclk freq %d\n", mclk_rate); + return -EINVAL; + } - /* Configure sysclk for codec */ - ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, 24000000, + ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, mclk_rate, SND_SOC_CLOCK_IN); if (ret) { - dev_err(rtd->dev, "can't set codec sysclk configuration\n"); + dev_err(rtd->dev, "fail to set sysclk, ret %d\n", ret); return ret; } /* + * Use PLL bypass mode if MCLK is available, be sure to set the + * frequency of MCLK to 12.288 or 24.576MHz on topology side. + */ + if (mclk_rate == 12288000 || mclk_rate == 24576000) { + /* PLL bypass mode */ + dev_dbg(rtd->dev, "pll bypass mode, mclk rate %d\n", mclk_rate); + + ret = snd_soc_dai_set_pll(codec_dai, 0, DA7219_SYSCLK_MCLK, 0, 0); + if (ret) { + dev_err(rtd->dev, "fail to set pll, ret %d\n", ret); + return ret; + } + + ctx->pll_bypass = 1; + } + + /* * Headset buttons map to the google Reference headset. * These can be configured by userspace. */ @@ -181,34 +168,36 @@ static int da7219_codec_init(struct snd_soc_pcm_runtime *rtd) SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT, - &headset, - jack_pins, - ARRAY_SIZE(jack_pins)); + jack, jack_pins, ARRAY_SIZE(jack_pins)); if (ret) { dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); return ret; } - jack = &headset; snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP); snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND); - snd_soc_component_set_jack(component, jack, NULL); + + ret = snd_soc_component_set_jack(component, jack, NULL); + if (ret) { + dev_err(rtd->dev, "fail to set component jack, ret %d\n", ret); + return ret; + } return ret; } -static int ssp1_hw_params(struct snd_pcm_substream *substream, +static int max98373_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *runtime = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *runtime = snd_soc_substream_to_rtd(substream); int ret, j; for (j = 0; j < runtime->dai_link->num_codecs; j++) { - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(runtime, j); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(runtime, j); - if (!strcmp(codec_dai->component->name, MAXIM_DEV0_NAME)) { + if (!strcmp(codec_dai->component->name, MAX_98373_DEV0_NAME)) { /* vmon_slot_no = 0 imon_slot_no = 1 for TX slots */ ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x3, 3, 4, 16); if (ret < 0) { @@ -216,7 +205,7 @@ static int ssp1_hw_params(struct snd_pcm_substream *substream, return ret; } } - if (!strcmp(codec_dai->component->name, MAXIM_DEV1_NAME)) { + if (!strcmp(codec_dai->component->name, MAX_98373_DEV1_NAME)) { /* vmon_slot_no = 2 imon_slot_no = 3 for TX slots */ ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xC, 3, 4, 16); if (ret < 0) { @@ -229,35 +218,16 @@ static int ssp1_hw_params(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_ops ssp1_ops = { - .hw_params = ssp1_hw_params, -}; - -static struct snd_soc_codec_conf max98373_codec_conf[] = { - { - .dlc = COMP_CODEC_CONF(MAXIM_DEV0_NAME), - .name_prefix = "Right", - }, - { - .dlc = COMP_CODEC_CONF(MAXIM_DEV1_NAME), - .name_prefix = "Left", - }, +static const struct snd_soc_ops max98373_ops = { + .hw_params = max98373_hw_params, }; static int hdmi_init(struct snd_soc_pcm_runtime *rtd) { struct card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); - struct hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); - pcm->device = dai->id; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); + ctx->hdmi.hdmi_comp = dai->component; return 0; } @@ -265,17 +235,14 @@ static int hdmi_init(struct snd_soc_pcm_runtime *rtd) static int card_late_probe(struct snd_soc_card *card) { struct card_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_acpi_mach *mach = (card->dev)->platform_data; - struct hdmi_pcm *pcm; - - if (mach->mach_params.common_hdmi_codec_drv) { - pcm = list_first_entry(&ctx->hdmi_pcm_list, struct hdmi_pcm, - head); - return hda_dsp_hdmi_build_controls(card, - pcm->codec_dai->component); - } - return -EINVAL; + if (!ctx->hdmi.idisp_codec) + return 0; + + if (!ctx->hdmi.hdmi_comp) + return -EINVAL; + + return hda_dsp_hdmi_build_controls(card, ctx->hdmi.hdmi_comp); } SND_SOC_DAILINK_DEF(ssp0_pin, @@ -285,13 +252,11 @@ SND_SOC_DAILINK_DEF(ssp0_codec, SND_SOC_DAILINK_DEF(ssp1_pin, DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin"))); -SND_SOC_DAILINK_DEF(ssp1_amps, - DAILINK_COMP_ARRAY( - /* Left */ COMP_CODEC(MAXIM_DEV0_NAME, MAX98373_CODEC_DAI), - /* Right */ COMP_CODEC(MAXIM_DEV1_NAME, MAX98373_CODEC_DAI))); -SND_SOC_DAILINK_DEF(ssp1_m98360a, - DAILINK_COMP_ARRAY(COMP_CODEC("MX98360A:00", "HiFi"))); +SND_SOC_DAILINK_DEF(ssp2_pin, + DAILINK_COMP_ARRAY(COMP_CPU("SSP2 Pin"))); +SND_SOC_DAILINK_DEF(dummy_codec, + DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai"))); SND_SOC_DAILINK_DEF(dmic_pin, DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin"))); @@ -316,10 +281,15 @@ SND_SOC_DAILINK_DEF(idisp3_pin, SND_SOC_DAILINK_DEF(idisp3_codec, DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi3"))); +SND_SOC_DAILINK_DEF(idisp4_pin, + DAILINK_COMP_ARRAY(COMP_CPU("iDisp4 Pin"))); +SND_SOC_DAILINK_DEF(idisp4_codec, + DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi4"))); + SND_SOC_DAILINK_DEF(platform, /* subject to be overridden during probe */ DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:1f.3"))); -static struct snd_soc_dai_link dais[] = { +static struct snd_soc_dai_link jsl_dais[] = { /* Back End DAI links */ { .name = "SSP1-Codec", @@ -328,8 +298,7 @@ static struct snd_soc_dai_link dais[] = { .no_pcm = 1, .dpcm_playback = 1, .dpcm_capture = 1, /* IV feedback */ - .ops = &ssp1_ops, - SND_SOC_DAILINK_REG(ssp1_pin, ssp1_amps, platform), + SND_SOC_DAILINK_REG(ssp1_pin, max_98373_components, platform), }, { .name = "SSP0-Codec", @@ -383,83 +352,198 @@ static struct snd_soc_dai_link dais[] = { } }; -static struct snd_soc_card card_da7219_m98373 = { - .name = "da7219max", +static struct snd_soc_dai_link adl_dais[] = { + /* Back End DAI links */ + { + .name = "SSP0-Codec", + .id = 0, + .no_pcm = 1, + .init = da7219_codec_init, + .ignore_pmdown_time = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(ssp0_pin, ssp0_codec, platform), + }, + { + .name = "dmic01", + .id = 1, + .ignore_suspend = 1, + .dpcm_capture = 1, + .no_pcm = 1, + SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform), + }, + { + .name = "dmic16k", + .id = 2, + .ignore_suspend = 1, + .dpcm_capture = 1, + .no_pcm = 1, + SND_SOC_DAILINK_REG(dmic16k_pin, dmic_codec, platform), + }, + { + .name = "iDisp1", + .id = 3, + .init = hdmi_init, + .dpcm_playback = 1, + .no_pcm = 1, + SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform), + }, + { + .name = "iDisp2", + .id = 4, + .init = hdmi_init, + .dpcm_playback = 1, + .no_pcm = 1, + SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform), + }, + { + .name = "iDisp3", + .id = 5, + .init = hdmi_init, + .dpcm_playback = 1, + .no_pcm = 1, + SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform), + }, + { + .name = "iDisp4", + .id = 6, + .init = hdmi_init, + .dpcm_playback = 1, + .no_pcm = 1, + SND_SOC_DAILINK_REG(idisp4_pin, idisp4_codec, platform), + }, + { + .name = "SSP1-Codec", + .id = 7, + .no_pcm = 1, + .dpcm_playback = 1, + /* feedback stream or firmware-generated echo reference */ + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(ssp1_pin, max_98373_components, platform), + }, + { + .name = "SSP2-BT", + .id = 8, + .no_pcm = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(ssp2_pin, dummy_codec, platform), + }, +}; + +static struct snd_soc_card card_da7219 = { + .name = "da7219", /* the sof- prefix is added by the core */ .owner = THIS_MODULE, - .dai_link = dais, - .num_links = ARRAY_SIZE(dais), .controls = controls, .num_controls = ARRAY_SIZE(controls), .dapm_widgets = widgets, .num_dapm_widgets = ARRAY_SIZE(widgets), .dapm_routes = audio_map, .num_dapm_routes = ARRAY_SIZE(audio_map), - .codec_conf = max98373_codec_conf, - .num_configs = ARRAY_SIZE(max98373_codec_conf), - .fully_routed = true, - .late_probe = card_late_probe, -}; - -static struct snd_soc_card card_da7219_m98360a = { - .name = "da7219max98360a", - .owner = THIS_MODULE, - .dai_link = dais, - .num_links = ARRAY_SIZE(dais), - .controls = m98360a_controls, - .num_controls = ARRAY_SIZE(m98360a_controls), - .dapm_widgets = max98360a_widgets, - .num_dapm_widgets = ARRAY_SIZE(max98360a_widgets), - .dapm_routes = max98360a_map, - .num_dapm_routes = ARRAY_SIZE(max98360a_map), .fully_routed = true, .late_probe = card_late_probe, }; static int audio_probe(struct platform_device *pdev) { - static struct snd_soc_card *card; - struct snd_soc_acpi_mach *mach; + struct snd_soc_acpi_mach *mach = pdev->dev.platform_data; + struct snd_soc_dai_link *dai_links; struct card_private *ctx; - int ret; + unsigned long board_quirk = 0; + int ret, amp_idx; ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; - /* By default dais[0] is configured for max98373 */ - if (!strcmp(pdev->name, "sof_da7219_mx98360a")) { - dais[0] = (struct snd_soc_dai_link) { - .name = "SSP1-Codec", - .id = 0, - .no_pcm = 1, - .dpcm_playback = 1, - .ignore_pmdown_time = 1, - SND_SOC_DAILINK_REG(ssp1_pin, ssp1_m98360a, platform) }; + if (pdev->id_entry && pdev->id_entry->driver_data) + board_quirk = (unsigned long)pdev->id_entry->driver_data; + + ctx->codec_type = sof_ssp_detect_codec_type(&pdev->dev); + ctx->amp_type = sof_ssp_detect_amp_type(&pdev->dev); + + if (mach->mach_params.codec_mask & IDISP_CODEC_MASK) + ctx->hdmi.idisp_codec = true; + + if (board_quirk & SOF_DA7219_JSL_BOARD) { + /* backward-compatible with existing devices */ + switch (ctx->amp_type) { + case CODEC_MAX98360A: + card_da7219.name = devm_kstrdup(&pdev->dev, + "da7219max98360a", + GFP_KERNEL); + break; + case CODEC_MAX98373: + card_da7219.name = devm_kstrdup(&pdev->dev, "da7219max", + GFP_KERNEL); + break; + default: + break; + } + + dai_links = jsl_dais; + amp_idx = 0; + + card_da7219.num_links = ARRAY_SIZE(jsl_dais); + } else { + dai_links = adl_dais; + amp_idx = 7; + + card_da7219.num_links = ARRAY_SIZE(adl_dais); } - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - card = (struct snd_soc_card *)pdev->id_entry->driver_data; - card->dev = &pdev->dev; + dev_dbg(&pdev->dev, "board_quirk = %lx\n", board_quirk); + + /* speaker amp */ + switch (ctx->amp_type) { + case CODEC_MAX98360A: + max_98360a_dai_link(&dai_links[amp_idx]); + break; + case CODEC_MAX98373: + dai_links[amp_idx].codecs = max_98373_components; + dai_links[amp_idx].num_codecs = ARRAY_SIZE(max_98373_components); + dai_links[amp_idx].init = max_98373_spk_codec_init; + if (board_quirk & SOF_DA7219_JSL_BOARD) { + dai_links[amp_idx].ops = &max98373_ops; /* use local ops */ + } else { + /* TBD: implement the amp for later platform */ + dev_err(&pdev->dev, "max98373 not support yet\n"); + return -EINVAL; + } + + max_98373_set_codec_conf(&card_da7219); + break; + default: + dev_err(&pdev->dev, "invalid amp type %d\n", ctx->amp_type); + return -EINVAL; + } - mach = pdev->dev.platform_data; - ret = snd_soc_fixup_dai_links_platform_name(card, + card_da7219.dai_link = dai_links; + + card_da7219.dev = &pdev->dev; + + ret = snd_soc_fixup_dai_links_platform_name(&card_da7219, mach->mach_params.platform); if (ret) return ret; - snd_soc_card_set_drvdata(card, ctx); + snd_soc_card_set_drvdata(&card_da7219, ctx); - return devm_snd_soc_register_card(&pdev->dev, card); + return devm_snd_soc_register_card(&pdev->dev, &card_da7219); } static const struct platform_device_id board_ids[] = { { - .name = "sof_da7219_mx98373", - .driver_data = (kernel_ulong_t)&card_da7219_m98373, + .name = "jsl_mx98373_da7219", + .driver_data = (kernel_ulong_t)(SOF_DA7219_JSL_BOARD), + }, + { + .name = "jsl_mx98360_da7219", + .driver_data = (kernel_ulong_t)(SOF_DA7219_JSL_BOARD), }, { - .name = "sof_da7219_mx98360a", - .driver_data = (kernel_ulong_t)&card_da7219_m98360a, + .name = "adl_mx98360_da7219", + /* no quirk needed for this board */ }, { } }; @@ -468,7 +552,7 @@ MODULE_DEVICE_TABLE(platform, board_ids); static struct platform_driver audio = { .probe = audio_probe, .driver = { - .name = "sof_da7219_max98_360a_373", + .name = "sof_da7219", .pm = &snd_soc_pm_ops, }, .id_table = board_ids, @@ -476,7 +560,10 @@ static struct platform_driver audio = { module_platform_driver(audio) /* Module information */ -MODULE_DESCRIPTION("ASoC Intel(R) SOF Machine driver"); +MODULE_DESCRIPTION("ASoC Intel(R) SOF Machine driver for Dialog codec"); MODULE_AUTHOR("Yong Zhi <yong.zhi@intel.com>"); +MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>"); MODULE_LICENSE("GPL v2"); MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); +MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON); +MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_SSP_COMMON); diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c index 9904a9e33c..c1fcc156a5 100644 --- a/sound/soc/intel/boards/sof_es8336.c +++ b/sound/soc/intel/boards/sof_es8336.c @@ -126,7 +126,7 @@ static void pcm_pop_work_events(struct work_struct *work) static int sof_8336_trigger(struct snd_pcm_substream *substream, int cmd) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_card *card = rtd->card; struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card); @@ -251,7 +251,7 @@ static int dmic_init(struct snd_soc_pcm_runtime *runtime) static int sof_hdmi_init(struct snd_soc_pcm_runtime *runtime) { struct sof_es8336_private *priv = snd_soc_card_get_drvdata(runtime->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(runtime, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(runtime, 0); struct sof_hdmi_pcm *pcm; pcm = devm_kzalloc(runtime->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -269,7 +269,7 @@ static int sof_hdmi_init(struct snd_soc_pcm_runtime *runtime) static int sof_es8316_init(struct snd_soc_pcm_runtime *runtime) { - struct snd_soc_component *codec = asoc_rtd_to_codec(runtime, 0)->component; + struct snd_soc_component *codec = snd_soc_rtd_to_codec(runtime, 0)->component; struct snd_soc_card *card = runtime->card; struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card); const struct snd_soc_dapm_route *custom_map; @@ -308,7 +308,7 @@ static int sof_es8316_init(struct snd_soc_pcm_runtime *runtime) static void sof_es8316_exit(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; snd_soc_component_set_jack(component, NULL, NULL); } @@ -355,8 +355,8 @@ static const struct dmi_system_id sof_es8336_quirk_table[] = { static int sof_es8336_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); const int sysclk = 19200000; int ret; @@ -565,7 +565,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, if (!links[id].name) return NULL; links[id].id = id + hdmi_id_offset; - links[id].codecs = &asoc_dummy_dlc; + links[id].codecs = &snd_soc_dummy_dlc; links[id].num_codecs = 1; links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); diff --git a/sound/soc/intel/boards/sof_hdmi_common.h b/sound/soc/intel/boards/sof_hdmi_common.h new file mode 100644 index 0000000000..1573e089c0 --- /dev/null +++ b/sound/soc/intel/boards/sof_hdmi_common.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright(c) 2023 Intel Corporation. + */ + +#ifndef __SOF_HDMI_COMMON_H +#define __SOF_HDMI_COMMON_H + +#include <sound/soc.h> + +#define IDISP_CODEC_MASK 0x4 + +/* + * sof_hdmi_private: data for Intel HDMI dai link (idisp) initialization + * + * @hdmi_comp: ASoC component of idisp codec + * @idisp_codec: true to indicate idisp codec is present + */ +struct sof_hdmi_private { + struct snd_soc_component *hdmi_comp; + bool idisp_codec; +}; + +#endif /* __SOF_HDMI_COMMON_H */ diff --git a/sound/soc/intel/boards/sof_maxim_common.c b/sound/soc/intel/boards/sof_maxim_common.c index 628b6d5d3e..3c00afc328 100644 --- a/sound/soc/intel/boards/sof_maxim_common.c +++ b/sound/soc/intel/boards/sof_maxim_common.c @@ -59,7 +59,7 @@ EXPORT_SYMBOL_NS(max_98373_components, SND_SOC_INTEL_SOF_MAXIM_COMMON); static int max_98373_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; int j; @@ -78,7 +78,7 @@ static int max_98373_hw_params(struct snd_pcm_substream *substream, int max_98373_trigger(struct snd_pcm_substream *substream, int cmd) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; struct snd_soc_dai *cpu_dai; int j; @@ -88,7 +88,7 @@ int max_98373_trigger(struct snd_pcm_substream *substream, int cmd) if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) return 0; - cpu_dai = asoc_rtd_to_cpu(rtd, 0); + cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); for_each_rtd_codec_dais(rtd, j, codec_dai) { struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cpu_dai->component); @@ -223,7 +223,7 @@ static const struct { static int max_98390_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; int i, ret; diff --git a/sound/soc/intel/boards/sof_maxim_common.h b/sound/soc/intel/boards/sof_maxim_common.h index a095b47b85..fe0212fbad 100644 --- a/sound/soc/intel/boards/sof_maxim_common.h +++ b/sound/soc/intel/boards/sof_maxim_common.h @@ -11,10 +11,14 @@ #define __SOF_MAXIM_COMMON_H #include <sound/soc.h> +#include "sof_ssp_common.h" +/* + * Maxim MAX98373 + */ #define MAX_98373_CODEC_DAI "max98373-aif1" -#define MAX_98373_DEV0_NAME "i2c-MX98373:00" -#define MAX_98373_DEV1_NAME "i2c-MX98373:01" +#define MAX_98373_DEV0_NAME "i2c-" MAX_98373_ACPI_HID ":00" +#define MAX_98373_DEV1_NAME "i2c-" MAX_98373_ACPI_HID ":01" extern struct snd_soc_dai_link_component max_98373_components[2]; extern struct snd_soc_ops max_98373_ops; @@ -27,7 +31,6 @@ int max_98373_trigger(struct snd_pcm_substream *substream, int cmd); /* * Maxim MAX98390 */ -#define MAX_98390_ACPI_HID "MX98390" #define MAX_98390_CODEC_DAI "max98390-aif1" #define MAX_98390_DEV0_NAME "i2c-" MAX_98390_ACPI_HID ":00" #define MAX_98390_DEV1_NAME "i2c-" MAX_98390_ACPI_HID ":01" @@ -41,8 +44,8 @@ void max_98390_set_codec_conf(struct device *dev, struct snd_soc_card *card); * Maxim MAX98357A/MAX98360A */ #define MAX_98357A_CODEC_DAI "HiFi" -#define MAX_98357A_DEV0_NAME "MX98357A:00" -#define MAX_98360A_DEV0_NAME "MX98360A:00" +#define MAX_98357A_DEV0_NAME MAX_98357A_ACPI_HID ":00" +#define MAX_98360A_DEV0_NAME MAX_98360A_ACPI_HID ":00" void max_98357a_dai_link(struct snd_soc_dai_link *link); void max_98360a_dai_link(struct snd_soc_dai_link *link); diff --git a/sound/soc/intel/boards/sof_nau8825.c b/sound/soc/intel/boards/sof_nau8825.c index 46b7ecf6f9..dc2821a012 100644 --- a/sound/soc/intel/boards/sof_nau8825.c +++ b/sound/soc/intel/boards/sof_nau8825.c @@ -20,15 +20,14 @@ #include <sound/soc-acpi.h> #include "../../codecs/nau8825.h" #include "../common/soc-intel-quirks.h" -#include "hda_dsp_common.h" +#include "sof_board_helpers.h" #include "sof_realtek_common.h" #include "sof_maxim_common.h" - -#define NAME_SIZE 32 +#include "sof_nuvoton_common.h" +#include "sof_ssp_common.h" #define SOF_NAU8825_SSP_CODEC(quirk) ((quirk) & GENMASK(2, 0)) #define SOF_NAU8825_SSP_CODEC_MASK (GENMASK(2, 0)) -#define SOF_SPEAKER_AMP_PRESENT BIT(3) #define SOF_NAU8825_SSP_AMP_SHIFT 4 #define SOF_NAU8825_SSP_AMP_MASK (GENMASK(6, 4)) #define SOF_NAU8825_SSP_AMP(quirk) \ @@ -44,45 +43,9 @@ #define SOF_BT_OFFLOAD_SSP(quirk) \ (((quirk) << SOF_BT_OFFLOAD_SSP_SHIFT) & SOF_BT_OFFLOAD_SSP_MASK) #define SOF_SSP_BT_OFFLOAD_PRESENT BIT(13) -#define SOF_RT1019P_SPEAKER_AMP_PRESENT BIT(14) -#define SOF_MAX98373_SPEAKER_AMP_PRESENT BIT(15) -#define SOF_MAX98360A_SPEAKER_AMP_PRESENT BIT(16) -#define SOF_RT1015P_SPEAKER_AMP_PRESENT BIT(17) -#define SOF_NAU8318_SPEAKER_AMP_PRESENT BIT(18) static unsigned long sof_nau8825_quirk = SOF_NAU8825_SSP_CODEC(0); -struct sof_hdmi_pcm { - struct list_head head; - struct snd_soc_dai *codec_dai; - int device; -}; - -struct sof_card_private { - struct clk *mclk; - struct snd_soc_jack sof_headset; - struct list_head hdmi_pcm_list; -}; - -static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd) -{ - struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); - struct sof_hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - /* dai_link id is 1:1 mapped to the PCM device */ - pcm->device = rtd->dai_link->id; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); - - return 0; -} - static struct snd_soc_jack_pin jack_pins[] = { { .pin = "Headphone Jack", @@ -97,9 +60,8 @@ static struct snd_soc_jack_pin jack_pins[] = { static int sof_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) { struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; - - struct snd_soc_jack *jack; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_jack *jack = &ctx->headset_jack; int ret; /* @@ -110,7 +72,7 @@ static int sof_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3, - &ctx->sof_headset, + jack, jack_pins, ARRAY_SIZE(jack_pins)); if (ret) { @@ -118,14 +80,12 @@ static int sof_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) return ret; } - jack = &ctx->sof_headset; - snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); 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); - ret = snd_soc_component_set_jack(component, jack, NULL); + ret = snd_soc_component_set_jack(component, jack, NULL); if (ret) { dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret); return ret; @@ -136,7 +96,7 @@ static int sof_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) static void sof_nau8825_codec_exit(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; snd_soc_component_set_jack(component, NULL, NULL); } @@ -144,8 +104,8 @@ static void sof_nau8825_codec_exit(struct snd_soc_pcm_runtime *rtd) static int sof_nau8825_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int clk_freq, ret; clk_freq = sof_dai_get_bclk(rtd); /* BCLK freq */ @@ -189,10 +149,9 @@ static int sof_card_late_probe(struct snd_soc_card *card) { struct sof_card_private *ctx = snd_soc_card_get_drvdata(card); struct snd_soc_dapm_context *dapm = &card->dapm; - struct sof_hdmi_pcm *pcm; int err; - if (sof_nau8825_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) { + if (ctx->amp_type == CODEC_MAX98373) { /* Disable Left and Right Spk pin after boot */ snd_soc_dapm_disable_pin(dapm, "Left Spk"); snd_soc_dapm_disable_pin(dapm, "Right Spk"); @@ -201,12 +160,7 @@ static int sof_card_late_probe(struct snd_soc_card *card) return err; } - if (list_empty(&ctx->hdmi_pcm_list)) - return -EINVAL; - - pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm, head); - - return hda_dsp_hdmi_build_controls(card, pcm->codec_dai->component); + return sof_intel_board_card_late_probe(card); } static const struct snd_kcontrol_new sof_controls[] = { @@ -216,10 +170,6 @@ static const struct snd_kcontrol_new sof_controls[] = { SOC_DAPM_PIN_SWITCH("Right Spk"), }; -static const struct snd_kcontrol_new speaker_controls[] = { - SOC_DAPM_PIN_SWITCH("Spk"), -}; - static const struct snd_soc_dapm_widget sof_widgets[] = { SND_SOC_DAPM_HP("Headphone Jack", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), @@ -227,14 +177,6 @@ static const struct snd_soc_dapm_widget sof_widgets[] = { SND_SOC_DAPM_SPK("Right Spk", NULL), }; -static const struct snd_soc_dapm_widget speaker_widgets[] = { - SND_SOC_DAPM_SPK("Spk", NULL), -}; - -static const struct snd_soc_dapm_widget dmic_widgets[] = { - SND_SOC_DAPM_MIC("SoC DMIC", NULL), -}; - static const struct snd_soc_dapm_route sof_map[] = { /* HP jack connectors - unknown if we have jack detection */ { "Headphone Jack", NULL, "HPOL" }, @@ -244,66 +186,6 @@ static const struct snd_soc_dapm_route sof_map[] = { { "MIC", NULL, "Headset Mic" }, }; -static const struct snd_soc_dapm_route speaker_map[] = { - /* speaker */ - { "Spk", NULL, "Speaker" }, -}; - -static const struct snd_soc_dapm_route dmic_map[] = { - /* digital mics */ - {"DMic", NULL, "SoC DMIC"}, -}; - -static int speaker_codec_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_card *card = rtd->card; - int ret; - - ret = snd_soc_dapm_new_controls(&card->dapm, speaker_widgets, - ARRAY_SIZE(speaker_widgets)); - if (ret) { - dev_err(rtd->dev, "unable to add dapm controls, ret %d\n", ret); - /* Don't need to add routes if widget addition failed */ - return ret; - } - - ret = snd_soc_add_card_controls(card, speaker_controls, - ARRAY_SIZE(speaker_controls)); - if (ret) { - dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_add_routes(&card->dapm, speaker_map, - ARRAY_SIZE(speaker_map)); - - if (ret) - dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret); - return ret; -} - -static int dmic_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_card *card = rtd->card; - int ret; - - ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets, - ARRAY_SIZE(dmic_widgets)); - if (ret) { - dev_err(card->dev, "DMic widget addition failed: %d\n", ret); - /* Don't need to add routes if widget addition failed */ - return ret; - } - - ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map, - ARRAY_SIZE(dmic_map)); - - if (ret) - dev_err(card->dev, "DMic map addition failed: %d\n", ret); - - return ret; -} - /* sof audio machine driver for nau8825 codec */ static struct snd_soc_card sof_audio_card_nau8825 = { .name = "nau8825", /* the sof- prefix is added by the core */ @@ -325,37 +207,16 @@ static struct snd_soc_dai_link_component nau8825_component[] = { } }; -static struct snd_soc_dai_link_component dmic_component[] = { - { - .name = "dmic-codec", - .dai_name = "dmic-hifi", - } -}; - -static struct snd_soc_dai_link_component rt1019p_component[] = { - { - .name = "RTL1019:00", - .dai_name = "HiFi", - } -}; - -static struct snd_soc_dai_link_component nau8318_components[] = { - { - .name = "NVTN2012:00", - .dai_name = "nau8315-hifi", - } -}; - -static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, - int ssp_codec, - int ssp_amp, - int dmic_be_num, - int hdmi_num) +static struct snd_soc_dai_link * +sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec amp_type, + int ssp_codec, int ssp_amp, int dmic_be_num, + int hdmi_num, bool idisp_codec) { - struct snd_soc_dai_link_component *idisp_components; struct snd_soc_dai_link_component *cpus; struct snd_soc_dai_link *links; - int i, id = 0; + int i; + int id = 0; + int ret; links = devm_kcalloc(dev, sof_audio_card_nau8825.num_links, sizeof(struct snd_soc_dai_link), GFP_KERNEL); @@ -395,103 +256,65 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, /* dmic */ if (dmic_be_num > 0) { /* at least we have dmic01 */ - links[id].name = "dmic01"; - links[id].cpus = &cpus[id]; - links[id].cpus->dai_name = "DMIC01 Pin"; - links[id].init = dmic_init; - if (dmic_be_num > 1) { - /* set up 2 BE links at most */ - links[id + 1].name = "dmic16k"; - links[id + 1].cpus = &cpus[id + 1]; - links[id + 1].cpus->dai_name = "DMIC16k Pin"; - dmic_be_num = 2; - } + ret = sof_intel_board_set_dmic_link(dev, &links[id], id, + SOF_DMIC_01); + if (ret) + return NULL; + + id++; } - for (i = 0; i < dmic_be_num; i++) { - links[id].id = id; - links[id].num_cpus = 1; - links[id].codecs = dmic_component; - links[id].num_codecs = ARRAY_SIZE(dmic_component); - links[id].platforms = platform_component; - links[id].num_platforms = ARRAY_SIZE(platform_component); - links[id].ignore_suspend = 1; - links[id].dpcm_capture = 1; - links[id].no_pcm = 1; + if (dmic_be_num > 1) { + /* set up 2 BE links at most */ + ret = sof_intel_board_set_dmic_link(dev, &links[id], id, + SOF_DMIC_16K); + if (ret) + return NULL; + id++; } /* HDMI */ - if (hdmi_num > 0) { - idisp_components = devm_kcalloc(dev, - hdmi_num, - sizeof(struct snd_soc_dai_link_component), - GFP_KERNEL); - if (!idisp_components) - goto devm_err; - } for (i = 1; i <= hdmi_num; i++) { - links[id].name = devm_kasprintf(dev, GFP_KERNEL, - "iDisp%d", i); - if (!links[id].name) - goto devm_err; - - links[id].id = id; - links[id].cpus = &cpus[id]; - links[id].num_cpus = 1; - links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, - "iDisp%d Pin", i); - if (!links[id].cpus->dai_name) - goto devm_err; - - idisp_components[i - 1].name = "ehdaudio0D2"; - idisp_components[i - 1].dai_name = devm_kasprintf(dev, - GFP_KERNEL, - "intel-hdmi-hifi%d", - i); - if (!idisp_components[i - 1].dai_name) - goto devm_err; + ret = sof_intel_board_set_intel_hdmi_link(dev, &links[id], id, + i, idisp_codec); + if (ret) + return NULL; - links[id].codecs = &idisp_components[i - 1]; - links[id].num_codecs = 1; - links[id].platforms = platform_component; - links[id].num_platforms = ARRAY_SIZE(platform_component); - links[id].init = sof_hdmi_init; - links[id].dpcm_playback = 1; - links[id].no_pcm = 1; id++; } /* speaker amp */ - if (sof_nau8825_quirk & SOF_SPEAKER_AMP_PRESENT) { + if (amp_type != CODEC_NONE) { links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_amp); if (!links[id].name) goto devm_err; links[id].id = id; - if (sof_nau8825_quirk & SOF_RT1019P_SPEAKER_AMP_PRESENT) { - links[id].codecs = rt1019p_component; - links[id].num_codecs = ARRAY_SIZE(rt1019p_component); - links[id].init = speaker_codec_init; - } else if (sof_nau8825_quirk & - SOF_MAX98373_SPEAKER_AMP_PRESENT) { + + switch (amp_type) { + case CODEC_MAX98360A: + max_98360a_dai_link(&links[id]); + break; + case CODEC_MAX98373: links[id].codecs = max_98373_components; links[id].num_codecs = ARRAY_SIZE(max_98373_components); links[id].init = max_98373_spk_codec_init; links[id].ops = &max_98373_ops; - } else if (sof_nau8825_quirk & - SOF_MAX98360A_SPEAKER_AMP_PRESENT) { - max_98360a_dai_link(&links[id]); - } else if (sof_nau8825_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) { + break; + case CODEC_NAU8318: + nau8318_set_dai_link(&links[id]); + break; + case CODEC_RT1015P: sof_rt1015p_dai_link(&links[id]); - } else if (sof_nau8825_quirk & - SOF_NAU8318_SPEAKER_AMP_PRESENT) { - links[id].codecs = nau8318_components; - links[id].num_codecs = ARRAY_SIZE(nau8318_components); - links[id].init = speaker_codec_init; - } else { - goto devm_err; + break; + case CODEC_RT1019P: + sof_rt1019p_dai_link(&links[id]); + break; + default: + dev_err(dev, "invalid amp type %d\n", amp_type); + return NULL; } links[id].platforms = platform_component; @@ -525,7 +348,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port); if (!links[id].name) goto devm_err; - links[id].codecs = &asoc_dummy_dlc; + links[id].codecs = &snd_soc_dummy_dlc; links[id].num_codecs = 1; links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); @@ -542,10 +365,9 @@ devm_err: static int sof_audio_probe(struct platform_device *pdev) { + struct snd_soc_acpi_mach *mach = pdev->dev.platform_data; struct snd_soc_dai_link *dai_links; - struct snd_soc_acpi_mach *mach; struct sof_card_private *ctx; - int dmic_be_num, hdmi_num; int ret, ssp_amp, ssp_codec; ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); @@ -555,23 +377,21 @@ static int sof_audio_probe(struct platform_device *pdev) if (pdev->id_entry && pdev->id_entry->driver_data) sof_nau8825_quirk = (unsigned long)pdev->id_entry->driver_data; - mach = pdev->dev.platform_data; - - /* A speaker amp might not be present when the quirk claims one is. - * Detect this via whether the machine driver match includes quirk_data. - */ - if ((sof_nau8825_quirk & SOF_SPEAKER_AMP_PRESENT) && !mach->quirk_data) - sof_nau8825_quirk &= ~SOF_SPEAKER_AMP_PRESENT; + ctx->codec_type = sof_ssp_detect_codec_type(&pdev->dev); + ctx->amp_type = sof_ssp_detect_amp_type(&pdev->dev); dev_dbg(&pdev->dev, "sof_nau8825_quirk = %lx\n", sof_nau8825_quirk); /* default number of DMIC DAI's */ - dmic_be_num = 2; - hdmi_num = (sof_nau8825_quirk & SOF_NAU8825_NUM_HDMIDEV_MASK) >> + ctx->dmic_be_num = 2; + ctx->hdmi_num = (sof_nau8825_quirk & SOF_NAU8825_NUM_HDMIDEV_MASK) >> SOF_NAU8825_NUM_HDMIDEV_SHIFT; /* default number of HDMI DAI's */ - if (!hdmi_num) - hdmi_num = 3; + if (!ctx->hdmi_num) + ctx->hdmi_num = 3; + + if (mach->mach_params.codec_mask & IDISP_CODEC_MASK) + ctx->hdmi.idisp_codec = true; ssp_amp = (sof_nau8825_quirk & SOF_NAU8825_SSP_AMP_MASK) >> SOF_NAU8825_SSP_AMP_SHIFT; @@ -579,27 +399,41 @@ static int sof_audio_probe(struct platform_device *pdev) ssp_codec = sof_nau8825_quirk & SOF_NAU8825_SSP_CODEC_MASK; /* compute number of dai links */ - sof_audio_card_nau8825.num_links = 1 + dmic_be_num + hdmi_num; + sof_audio_card_nau8825.num_links = 1 + ctx->dmic_be_num + ctx->hdmi_num; - if (sof_nau8825_quirk & SOF_SPEAKER_AMP_PRESENT) + if (ctx->amp_type != CODEC_NONE) sof_audio_card_nau8825.num_links++; - if (sof_nau8825_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) - max_98373_set_codec_conf(&sof_audio_card_nau8825); - else if (sof_nau8825_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) - sof_rt1015p_codec_conf(&sof_audio_card_nau8825); - if (sof_nau8825_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) sof_audio_card_nau8825.num_links++; - dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp, - dmic_be_num, hdmi_num); + dai_links = sof_card_dai_links_create(&pdev->dev, ctx->amp_type, + ssp_codec, ssp_amp, + ctx->dmic_be_num, ctx->hdmi_num, + ctx->hdmi.idisp_codec); if (!dai_links) return -ENOMEM; sof_audio_card_nau8825.dai_link = dai_links; - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); + /* update codec_conf */ + switch (ctx->amp_type) { + case CODEC_MAX98373: + max_98373_set_codec_conf(&sof_audio_card_nau8825); + break; + case CODEC_RT1015P: + sof_rt1015p_codec_conf(&sof_audio_card_nau8825); + break; + case CODEC_NONE: + case CODEC_MAX98360A: + case CODEC_NAU8318: + case CODEC_RT1019P: + /* no codec conf required */ + break; + default: + dev_err(&pdev->dev, "invalid amp type %d\n", ctx->amp_type); + return -EINVAL; + } sof_audio_card_nau8825.dev = &pdev->dev; @@ -627,16 +461,12 @@ static const struct platform_device_id board_ids[] = { { .name = "adl_rt1019p_8825", .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_RT1019P_SPEAKER_AMP_PRESENT | SOF_NAU8825_SSP_AMP(2) | SOF_NAU8825_NUM_HDMIDEV(4)), }, { .name = "adl_max98373_8825", .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98373_SPEAKER_AMP_PRESENT | SOF_NAU8825_SSP_AMP(1) | SOF_NAU8825_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -646,8 +476,6 @@ static const struct platform_device_id board_ids[] = { /* The limitation of length of char array, shorten the name */ .name = "adl_mx98360a_8825", .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98360A_SPEAKER_AMP_PRESENT | SOF_NAU8825_SSP_AMP(1) | SOF_NAU8825_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -657,8 +485,6 @@ static const struct platform_device_id board_ids[] = { { .name = "adl_rt1015p_8825", .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_RT1015P_SPEAKER_AMP_PRESENT | SOF_NAU8825_SSP_AMP(1) | SOF_NAU8825_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -667,8 +493,6 @@ static const struct platform_device_id board_ids[] = { { .name = "adl_nau8318_8825", .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_NAU8318_SPEAKER_AMP_PRESENT | SOF_NAU8825_SSP_AMP(1) | SOF_NAU8825_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -677,8 +501,14 @@ static const struct platform_device_id board_ids[] = { { .name = "rpl_max98373_8825", .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98373_SPEAKER_AMP_PRESENT | + SOF_NAU8825_SSP_AMP(1) | + SOF_NAU8825_NUM_HDMIDEV(4) | + SOF_BT_OFFLOAD_SSP(2) | + SOF_SSP_BT_OFFLOAD_PRESENT), + }, + { + .name = "rpl_mx98360a_8825", + .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | SOF_NAU8825_SSP_AMP(1) | SOF_NAU8825_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -687,8 +517,6 @@ static const struct platform_device_id board_ids[] = { { .name = "rpl_nau8318_8825", .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_NAU8318_SPEAKER_AMP_PRESENT | SOF_NAU8825_SSP_AMP(1) | SOF_NAU8825_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -712,7 +540,10 @@ module_platform_driver(sof_audio) MODULE_DESCRIPTION("SOF Audio Machine driver for NAU8825"); MODULE_AUTHOR("David Lin <ctlin0@nuvoton.com>"); MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>"); +MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); +MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS); MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON); +MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_NUVOTON_COMMON); MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON); +MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_SSP_COMMON); diff --git a/sound/soc/intel/boards/sof_nuvoton_common.c b/sound/soc/intel/boards/sof_nuvoton_common.c new file mode 100644 index 0000000000..549a412f5d --- /dev/null +++ b/sound/soc/intel/boards/sof_nuvoton_common.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * This file defines data structures and functions used in Machine + * Driver for Intel platforms with Nuvoton Codecs. + * + * Copyright 2023 Intel Corporation. + */ +#include <linux/module.h> +#include <sound/sof.h> +#include "sof_nuvoton_common.h" + +/* + * Nuvoton NAU8318 + */ +static const struct snd_kcontrol_new nau8318_kcontrols[] = { + SOC_DAPM_PIN_SWITCH("Spk"), +}; + +static const struct snd_soc_dapm_widget nau8318_widgets[] = { + SND_SOC_DAPM_SPK("Spk", NULL), +}; + +static const struct snd_soc_dapm_route nau8318_routes[] = { + { "Spk", NULL, "Speaker" }, +}; + +static struct snd_soc_dai_link_component nau8318_components[] = { + { + .name = NAU8318_DEV0_NAME, + .dai_name = NAU8318_CODEC_DAI, + } +}; + +static int nau8318_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + int ret; + + ret = snd_soc_dapm_new_controls(&card->dapm, nau8318_widgets, + ARRAY_SIZE(nau8318_widgets)); + if (ret) { + dev_err(rtd->dev, "fail to add nau8318 widgets, ret %d\n", ret); + return ret; + } + + ret = snd_soc_add_card_controls(card, nau8318_kcontrols, + ARRAY_SIZE(nau8318_kcontrols)); + if (ret) { + dev_err(rtd->dev, "fail to add nau8318 kcontrols, ret %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, nau8318_routes, + ARRAY_SIZE(nau8318_routes)); + + if (ret) { + dev_err(rtd->dev, "fail to add nau8318 routes, ret %d\n", ret); + return ret; + } + + return ret; +} + +void nau8318_set_dai_link(struct snd_soc_dai_link *link) +{ + link->codecs = nau8318_components; + link->num_codecs = ARRAY_SIZE(nau8318_components); + link->init = nau8318_init; +} +EXPORT_SYMBOL_NS(nau8318_set_dai_link, SND_SOC_INTEL_SOF_NUVOTON_COMMON); + +MODULE_DESCRIPTION("ASoC Intel SOF Nuvoton helpers"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/intel/boards/sof_nuvoton_common.h b/sound/soc/intel/boards/sof_nuvoton_common.h new file mode 100644 index 0000000000..53a84f9a67 --- /dev/null +++ b/sound/soc/intel/boards/sof_nuvoton_common.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * This file defines data structures used in Machine Driver for Intel + * platforms with Nuvoton Codecs. + * + * Copyright 2023 Intel Corporation. + */ +#ifndef __SOF_NUVOTON_COMMON_H +#define __SOF_NUVOTON_COMMON_H + +#include <sound/soc.h> +#include "sof_ssp_common.h" + +/* + * Nuvoton NAU8318 + */ +#define NAU8318_CODEC_DAI "nau8315-hifi" +#define NAU8318_DEV0_NAME "i2c-" NAU8318_ACPI_HID ":00" + +void nau8318_set_dai_link(struct snd_soc_dai_link *link); + +#endif /* __SOF_NUVOTON_COMMON_H */ diff --git a/sound/soc/intel/boards/sof_pcm512x.c b/sound/soc/intel/boards/sof_pcm512x.c index 9f673ccf81..b01cb23295 100644 --- a/sound/soc/intel/boards/sof_pcm512x.c +++ b/sound/soc/intel/boards/sof_pcm512x.c @@ -71,7 +71,7 @@ static const struct dmi_system_id sof_pcm512x_quirk_table[] = { static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd) { struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct sof_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -89,7 +89,7 @@ static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd) static int sof_pcm512x_codec_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *codec = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *codec = snd_soc_rtd_to_codec(rtd, 0)->component; snd_soc_component_update_bits(codec, PCM512x_GPIO_EN, 0x08, 0x08); snd_soc_component_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0x0f, 0x02); @@ -101,8 +101,8 @@ static int sof_pcm512x_codec_init(struct snd_soc_pcm_runtime *rtd) static int aif1_startup(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_component *codec = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_component *codec = snd_soc_rtd_to_codec(rtd, 0)->component; snd_soc_component_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x08); @@ -112,8 +112,8 @@ static int aif1_startup(struct snd_pcm_substream *substream) static void aif1_shutdown(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_component *codec = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_component *codec = snd_soc_rtd_to_codec(rtd, 0)->component; snd_soc_component_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x00); @@ -331,7 +331,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, devm_kasprintf(dev, GFP_KERNEL, "intel-hdmi-hifi%d", i); } else { - idisp_components[i - 1] = asoc_dummy_dlc; + idisp_components[i - 1] = snd_soc_dummy_dlc; } if (!idisp_components[i - 1].dai_name) goto devm_err; diff --git a/sound/soc/intel/boards/sof_realtek_common.c b/sound/soc/intel/boards/sof_realtek_common.c index 6c12ca92f3..80c8687cd1 100644 --- a/sound/soc/intel/boards/sof_realtek_common.c +++ b/sound/soc/intel/boards/sof_realtek_common.c @@ -68,7 +68,7 @@ static const struct { static int rt1011_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; int srate, i, ret = 0; @@ -264,7 +264,7 @@ static const struct { static int rt1015_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai_link *dai_link = rtd->dai_link; struct snd_soc_dai *codec_dai; int i, clk_freq; @@ -423,9 +423,9 @@ static int rt1308_init(struct snd_soc_pcm_runtime *rtd) static int rt1308_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_card *card = rtd->card; - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int clk_id, clk_freq, pll_out; int ret; diff --git a/sound/soc/intel/boards/sof_realtek_common.h b/sound/soc/intel/boards/sof_realtek_common.h index 3ae99d8239..e3fa2924c1 100644 --- a/sound/soc/intel/boards/sof_realtek_common.h +++ b/sound/soc/intel/boards/sof_realtek_common.h @@ -11,36 +11,53 @@ #define __SOF_REALTEK_COMMON_H #include <sound/soc.h> +#include "sof_ssp_common.h" + +/* + * Realtek ALC1011 + */ #define RT1011_CODEC_DAI "rt1011-aif" -#define RT1011_DEV0_NAME "i2c-10EC1011:00" -#define RT1011_DEV1_NAME "i2c-10EC1011:01" -#define RT1011_DEV2_NAME "i2c-10EC1011:02" -#define RT1011_DEV3_NAME "i2c-10EC1011:03" +#define RT1011_DEV0_NAME "i2c-" RT1011_ACPI_HID ":00" +#define RT1011_DEV1_NAME "i2c-" RT1011_ACPI_HID ":01" +#define RT1011_DEV2_NAME "i2c-" RT1011_ACPI_HID ":02" +#define RT1011_DEV3_NAME "i2c-" RT1011_ACPI_HID ":03" void sof_rt1011_dai_link(struct snd_soc_dai_link *link); void sof_rt1011_codec_conf(struct snd_soc_card *card); +/* + * Realtek ALC1015 (AUTO) + */ #define RT1015P_CODEC_DAI "HiFi" -#define RT1015P_DEV0_NAME "RTL1015:00" -#define RT1015P_DEV1_NAME "RTL1015:01" +#define RT1015P_DEV0_NAME RT1015P_ACPI_HID ":00" +#define RT1015P_DEV1_NAME RT1015P_ACPI_HID ":01" void sof_rt1015p_dai_link(struct snd_soc_dai_link *link); void sof_rt1015p_codec_conf(struct snd_soc_card *card); +/* + * Realtek ALC1015 (I2C) + */ #define RT1015_CODEC_DAI "rt1015-aif" -#define RT1015_DEV0_NAME "i2c-10EC1015:00" -#define RT1015_DEV1_NAME "i2c-10EC1015:01" +#define RT1015_DEV0_NAME "i2c-" RT1015_ACPI_HID ":00" +#define RT1015_DEV1_NAME "i2c-" RT1015_ACPI_HID ":01" void sof_rt1015_dai_link(struct snd_soc_dai_link *link); void sof_rt1015_codec_conf(struct snd_soc_card *card); +/* + * Realtek ALC1308 + */ #define RT1308_CODEC_DAI "rt1308-aif" -#define RT1308_DEV0_NAME "i2c-10EC1308:00" +#define RT1308_DEV0_NAME "i2c-" RT1308_ACPI_HID ":00" void sof_rt1308_dai_link(struct snd_soc_dai_link *link); +/* + * Realtek ALC1019 + */ #define RT1019P_CODEC_DAI "HiFi" -#define RT1019P_DEV0_NAME "RTL1019:00" +#define RT1019P_DEV0_NAME RT1019P_ACPI_HID ":00" void sof_rt1019p_dai_link(struct snd_soc_dai_link *link); diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index fae091b9b5..06ad15af46 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -23,19 +23,15 @@ #include "../../codecs/rt5682.h" #include "../../codecs/rt5682s.h" #include "../../codecs/rt5645.h" -#include "../../codecs/hdac_hdmi.h" #include "../common/soc-intel-quirks.h" -#include "hda_dsp_common.h" +#include "sof_board_helpers.h" #include "sof_maxim_common.h" #include "sof_realtek_common.h" - -#define NAME_SIZE 32 +#include "sof_ssp_common.h" #define SOF_RT5682_SSP_CODEC(quirk) ((quirk) & GENMASK(2, 0)) #define SOF_RT5682_SSP_CODEC_MASK (GENMASK(2, 0)) #define SOF_RT5682_MCLK_EN BIT(3) -#define SOF_RT5682_MCLK_24MHZ BIT(4) -#define SOF_SPEAKER_AMP_PRESENT BIT(5) #define SOF_RT5682_SSP_AMP_SHIFT 6 #define SOF_RT5682_SSP_AMP_MASK (GENMASK(8, 6)) #define SOF_RT5682_SSP_AMP(quirk) \ @@ -45,11 +41,6 @@ #define SOF_RT5682_NUM_HDMIDEV_MASK (GENMASK(12, 10)) #define SOF_RT5682_NUM_HDMIDEV(quirk) \ ((quirk << SOF_RT5682_NUM_HDMIDEV_SHIFT) & SOF_RT5682_NUM_HDMIDEV_MASK) -#define SOF_RT1011_SPEAKER_AMP_PRESENT BIT(13) -#define SOF_RT1015_SPEAKER_AMP_PRESENT BIT(14) -#define SOF_RT1015P_SPEAKER_AMP_PRESENT BIT(16) -#define SOF_MAX98373_SPEAKER_AMP_PRESENT BIT(17) -#define SOF_MAX98360A_SPEAKER_AMP_PRESENT BIT(18) /* BT audio offload: reserve 3 bits for future */ #define SOF_BT_OFFLOAD_SSP_SHIFT 19 @@ -57,10 +48,6 @@ #define SOF_BT_OFFLOAD_SSP(quirk) \ (((quirk) << SOF_BT_OFFLOAD_SSP_SHIFT) & SOF_BT_OFFLOAD_SSP_MASK) #define SOF_SSP_BT_OFFLOAD_PRESENT BIT(22) -#define SOF_RT5682S_HEADPHONE_CODEC_PRESENT BIT(23) -#define SOF_MAX98390_SPEAKER_AMP_PRESENT BIT(24) -#define SOF_RT1019_SPEAKER_AMP_PRESENT BIT(26) -#define SOF_RT5650_HEADPHONE_CODEC_PRESENT BIT(27) /* HDMI capture*/ #define SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT 27 @@ -72,23 +59,6 @@ static unsigned long sof_rt5682_quirk = SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0); -static int is_legacy_cpu; - -struct sof_hdmi_pcm { - struct list_head head; - struct snd_soc_dai *codec_dai; - struct snd_soc_jack hdmi_jack; - int device; -}; - -struct sof_card_private { - struct clk *mclk; - struct snd_soc_jack sof_headset; - struct list_head hdmi_pcm_list; - bool common_hdmi_codec_drv; - bool idisp_codec; -}; - static int sof_rt5682_quirk_cb(const struct dmi_system_id *id) { sof_rt5682_quirk = (unsigned long)id->driver_data; @@ -119,35 +89,15 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "WhiskeyLake Client"), }, .driver_data = (void *)(SOF_RT5682_MCLK_EN | - SOF_RT5682_MCLK_24MHZ | SOF_RT5682_SSP_CODEC(1)), }, { - /* - * Dooly is hatch family but using rt1015 amp so it - * requires a quirk before "Google_Hatch". - */ - .callback = sof_rt5682_quirk_cb, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "HP"), - DMI_MATCH(DMI_PRODUCT_NAME, "Dooly"), - }, - .driver_data = (void *)(SOF_RT5682_MCLK_EN | - SOF_RT5682_MCLK_24MHZ | - SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_RT1015_SPEAKER_AMP_PRESENT | - SOF_RT5682_SSP_AMP(1)), - }, - { .callback = sof_rt5682_quirk_cb, .matches = { DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Hatch"), }, .driver_data = (void *)(SOF_RT5682_MCLK_EN | - SOF_RT5682_MCLK_24MHZ | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1)), }, { @@ -167,8 +117,6 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { }, .driver_data = (void *)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98373_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(2) | SOF_RT5682_NUM_HDMIDEV(4)), }, @@ -181,8 +129,6 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { }, .driver_data = (void *)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98373_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(2) | SOF_RT5682_NUM_HDMIDEV(4)), }, @@ -194,8 +140,6 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { }, .driver_data = (void *)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98390_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(2) | SOF_RT5682_NUM_HDMIDEV(4)), }, @@ -207,8 +151,6 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { }, .driver_data = (void *)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98360A_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(2) | SOF_RT5682_NUM_HDMIDEV(4)), }, @@ -220,10 +162,22 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { }, .driver_data = (void *)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(2) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98360A_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(0) | - SOF_RT5682_NUM_HDMIDEV(4) | + SOF_RT5682_NUM_HDMIDEV(3) | + SOF_BT_OFFLOAD_SSP(1) | + SOF_SSP_BT_OFFLOAD_PRESENT + ), + }, + { + .callback = sof_rt5682_quirk_cb, + .matches = { + DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Rex"), + DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98360_ALC5682I_DISCRETE_I2S_BT"), + }, + .driver_data = (void *)(SOF_RT5682_MCLK_EN | + SOF_RT5682_SSP_CODEC(2) | + SOF_RT5682_SSP_AMP(0) | + SOF_RT5682_NUM_HDMIDEV(3) | SOF_BT_OFFLOAD_SSP(1) | SOF_SSP_BT_OFFLOAD_PRESENT ), @@ -236,8 +190,6 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { }, .driver_data = (void *)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(2) | - SOF_SPEAKER_AMP_PRESENT | - SOF_RT1019_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(0) | SOF_RT5682_NUM_HDMIDEV(3) ), @@ -249,9 +201,8 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { }, .driver_data = (void *)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(2) | - SOF_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(0) | - SOF_RT5682_NUM_HDMIDEV(4) | + SOF_RT5682_NUM_HDMIDEV(3) | SOF_BT_OFFLOAD_SSP(1) | SOF_SSP_BT_OFFLOAD_PRESENT ), @@ -259,25 +210,6 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { {} }; -static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd) -{ - struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); - struct sof_hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - /* dai_link id is 1:1 mapped to the PCM device */ - pcm->device = rtd->dai_link->id; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); - - return 0; -} - static struct snd_soc_jack_pin jack_pins[] = { { .pin = "Headphone Jack", @@ -292,54 +224,72 @@ static struct snd_soc_jack_pin jack_pins[] = { static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) { struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; - struct snd_soc_jack *jack; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_jack *jack = &ctx->headset_jack; int extra_jack_data; - int ret; - - /* need to enable ASRC function for 24MHz mclk rate */ - if ((sof_rt5682_quirk & SOF_RT5682_MCLK_EN) && - (sof_rt5682_quirk & SOF_RT5682_MCLK_24MHZ)) { - if (sof_rt5682_quirk & SOF_RT5682S_HEADPHONE_CODEC_PRESENT) - rt5682s_sel_asrc_clk_src(component, - RT5682S_DA_STEREO1_FILTER | - RT5682S_AD_STEREO1_FILTER, - RT5682S_CLK_SEL_I2S1_ASRC); - else if (sof_rt5682_quirk & SOF_RT5650_HEADPHONE_CODEC_PRESENT) { - rt5645_sel_asrc_clk_src(component, - RT5645_DA_STEREO_FILTER | - RT5645_AD_STEREO_FILTER, - RT5645_CLK_SEL_I2S1_ASRC); - rt5645_sel_asrc_clk_src(component, - RT5645_DA_MONO_L_FILTER | - RT5645_DA_MONO_R_FILTER, - RT5645_CLK_SEL_I2S2_ASRC); - } else - rt5682_sel_asrc_clk_src(component, - RT5682_DA_STEREO1_FILTER | - RT5682_AD_STEREO1_FILTER, - RT5682_CLK_SEL_I2S1_ASRC); - } + int ret, mclk_freq; - if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_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(ctx->mclk); - if (!ret) - clk_disable_unprepare(ctx->mclk); + if (sof_rt5682_quirk & SOF_RT5682_MCLK_EN) { + mclk_freq = sof_dai_get_mclk(rtd); + if (mclk_freq <= 0) { + dev_err(rtd->dev, "invalid mclk freq %d\n", mclk_freq); + return -EINVAL; + } - ret = clk_set_rate(ctx->mclk, 19200000); + /* need to enable ASRC function for 24MHz mclk rate */ + if (mclk_freq == 24000000) { + dev_info(rtd->dev, "enable ASRC\n"); + + switch (ctx->codec_type) { + case CODEC_RT5650: + rt5645_sel_asrc_clk_src(component, + RT5645_DA_STEREO_FILTER | + RT5645_AD_STEREO_FILTER, + RT5645_CLK_SEL_I2S1_ASRC); + rt5645_sel_asrc_clk_src(component, + RT5645_DA_MONO_L_FILTER | + RT5645_DA_MONO_R_FILTER, + RT5645_CLK_SEL_I2S2_ASRC); + break; + case CODEC_RT5682: + rt5682_sel_asrc_clk_src(component, + RT5682_DA_STEREO1_FILTER | + RT5682_AD_STEREO1_FILTER, + RT5682_CLK_SEL_I2S1_ASRC); + break; + case CODEC_RT5682S: + rt5682s_sel_asrc_clk_src(component, + RT5682S_DA_STEREO1_FILTER | + RT5682S_AD_STEREO1_FILTER, + RT5682S_CLK_SEL_I2S1_ASRC); + break; + default: + dev_err(rtd->dev, "invalid codec type %d\n", + ctx->codec_type); + return -EINVAL; + } + } - if (ret) - dev_err(rtd->dev, "unable to set MCLK rate\n"); + if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_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(ctx->rt5682.mclk); + if (!ret) + clk_disable_unprepare(ctx->rt5682.mclk); + + ret = clk_set_rate(ctx->rt5682.mclk, 19200000); + + if (ret) + dev_err(rtd->dev, "unable to set MCLK rate\n"); + } } /* @@ -350,7 +300,7 @@ static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3, - &ctx->sof_headset, + jack, jack_pins, ARRAY_SIZE(jack_pins)); if (ret) { @@ -358,14 +308,12 @@ static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) return ret; } - jack = &ctx->sof_headset; - snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); 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); - if (sof_rt5682_quirk & SOF_RT5650_HEADPHONE_CODEC_PRESENT) { + if (ctx->codec_type == CODEC_RT5650) { extra_jack_data = SND_JACK_MICROPHONE | SND_JACK_BTN_0; ret = snd_soc_component_set_jack(component, jack, &extra_jack_data); } else @@ -381,7 +329,7 @@ static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) static void sof_rt5682_codec_exit(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; snd_soc_component_set_jack(component, NULL, NULL); } @@ -389,14 +337,14 @@ static void sof_rt5682_codec_exit(struct snd_soc_pcm_runtime *rtd) static int sof_rt5682_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int pll_id, pll_source, pll_in, pll_out, clk_id, ret; if (sof_rt5682_quirk & SOF_RT5682_MCLK_EN) { if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) { - ret = clk_prepare_enable(ctx->mclk); + ret = clk_prepare_enable(ctx->rt5682.mclk); if (ret < 0) { dev_err(rtd->dev, "could not configure MCLK state"); @@ -404,55 +352,86 @@ static int sof_rt5682_hw_params(struct snd_pcm_substream *substream, } } - if (sof_rt5682_quirk & SOF_RT5682S_HEADPHONE_CODEC_PRESENT) - pll_source = RT5682S_PLL_S_MCLK; - else if (sof_rt5682_quirk & SOF_RT5650_HEADPHONE_CODEC_PRESENT) + switch (ctx->codec_type) { + case CODEC_RT5650: pll_source = RT5645_PLL1_S_MCLK; - else + break; + case CODEC_RT5682: pll_source = RT5682_PLL1_S_MCLK; + break; + case CODEC_RT5682S: + pll_source = RT5682S_PLL_S_MCLK; + break; + default: + dev_err(rtd->dev, "invalid codec type %d\n", + ctx->codec_type); + return -EINVAL; + } /* get the tplg configured mclk. */ pll_in = sof_dai_get_mclk(rtd); - - /* mclk from the quirk is the first choice */ - if (sof_rt5682_quirk & SOF_RT5682_MCLK_24MHZ) { - if (pll_in != 24000000) - dev_warn(rtd->dev, "configure wrong mclk in tplg, please use 24MHz.\n"); - pll_in = 24000000; - } else if (pll_in == 0) { - /* use default mclk if not specified correct in topology */ - pll_in = 19200000; - } else if (pll_in < 0) { - return pll_in; + if (pll_in <= 0) { + dev_err(rtd->dev, "invalid mclk freq %d\n", pll_in); + return -EINVAL; } } else { - if (sof_rt5682_quirk & SOF_RT5682S_HEADPHONE_CODEC_PRESENT) - pll_source = RT5682S_PLL_S_BCLK1; - else if (sof_rt5682_quirk & SOF_RT5650_HEADPHONE_CODEC_PRESENT) + switch (ctx->codec_type) { + case CODEC_RT5650: pll_source = RT5645_PLL1_S_BCLK1; - else + break; + case CODEC_RT5682: pll_source = RT5682_PLL1_S_BCLK1; + break; + case CODEC_RT5682S: + pll_source = RT5682S_PLL_S_BCLK1; + break; + default: + dev_err(rtd->dev, "invalid codec type %d\n", + ctx->codec_type); + return -EINVAL; + } pll_in = params_rate(params) * 50; } - if (sof_rt5682_quirk & SOF_RT5682S_HEADPHONE_CODEC_PRESENT) { - pll_id = RT5682S_PLL2; - clk_id = RT5682S_SCLK_S_PLL2; - } else if (sof_rt5682_quirk & SOF_RT5650_HEADPHONE_CODEC_PRESENT) { + switch (ctx->codec_type) { + case CODEC_RT5650: pll_id = 0; /* not used in codec driver */ clk_id = RT5645_SCLK_S_PLL1; - } else { + break; + case CODEC_RT5682: pll_id = RT5682_PLL1; clk_id = RT5682_SCLK_S_PLL1; + break; + case CODEC_RT5682S: + pll_id = RT5682S_PLL2; + clk_id = RT5682S_SCLK_S_PLL2; + break; + default: + dev_err(rtd->dev, "invalid codec type %d\n", ctx->codec_type); + return -EINVAL; } pll_out = params_rate(params) * 512; /* when MCLK is 512FS, no need to set PLL configuration additionally. */ - if (pll_in == pll_out) - clk_id = RT5682S_SCLK_S_MCLK; - else { + if (pll_in == pll_out) { + switch (ctx->codec_type) { + case CODEC_RT5650: + clk_id = RT5645_SCLK_S_MCLK; + break; + case CODEC_RT5682: + clk_id = RT5682_SCLK_S_MCLK; + break; + case CODEC_RT5682S: + clk_id = RT5682S_SCLK_S_MCLK; + break; + default: + dev_err(rtd->dev, "invalid codec type %d\n", + ctx->codec_type); + return -EINVAL; + } + } else { /* Configure pll for codec */ ret = snd_soc_dai_set_pll(codec_dai, pll_id, pll_source, pll_in, pll_out); @@ -494,13 +473,10 @@ static struct snd_soc_dai_link_component platform_component[] = { static int sof_card_late_probe(struct snd_soc_card *card) { struct sof_card_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_component *component = NULL; struct snd_soc_dapm_context *dapm = &card->dapm; - char jack_name[NAME_SIZE]; - struct sof_hdmi_pcm *pcm; int err; - if (sof_rt5682_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) { + if (ctx->amp_type == CODEC_MAX98373) { /* Disable Left and Right Spk pin after boot */ snd_soc_dapm_disable_pin(dapm, "Left Spk"); snd_soc_dapm_disable_pin(dapm, "Right Spk"); @@ -509,37 +485,7 @@ static int sof_card_late_probe(struct snd_soc_card *card) return err; } - /* HDMI is not supported by SOF on Baytrail/CherryTrail */ - if (is_legacy_cpu || !ctx->idisp_codec) - return 0; - - if (list_empty(&ctx->hdmi_pcm_list)) - return -EINVAL; - - if (ctx->common_hdmi_codec_drv) { - pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm, - head); - component = pcm->codec_dai->component; - return hda_dsp_hdmi_build_controls(card, component); - } - - list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { - component = pcm->codec_dai->component; - 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, &pcm->hdmi_jack); - - if (err) - return err; - - err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, - &pcm->hdmi_jack); - if (err < 0) - return err; - } - - return hdac_hdmi_jack_port_init(component, &card->dapm); + return sof_intel_board_card_late_probe(card); } static const struct snd_kcontrol_new sof_controls[] = { @@ -557,10 +503,6 @@ static const struct snd_soc_dapm_widget sof_widgets[] = { SND_SOC_DAPM_SPK("Right Spk", NULL), }; -static const struct snd_soc_dapm_widget dmic_widgets[] = { - SND_SOC_DAPM_MIC("SoC DMIC", NULL), -}; - static const struct snd_soc_dapm_route sof_map[] = { /* HP jack connectors - unknown if we have jack detection */ { "Headphone Jack", NULL, "HPOL" }, @@ -576,11 +518,6 @@ static const struct snd_soc_dapm_route rt5650_spk_dapm_routes[] = { { "Right Spk", NULL, "SPOR" }, }; -static const struct snd_soc_dapm_route dmic_map[] = { - /* digital mics */ - {"DMic", NULL, "SoC DMIC"}, -}; - static int rt5650_spk_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; @@ -594,28 +531,6 @@ static int rt5650_spk_init(struct snd_soc_pcm_runtime *rtd) return ret; } -static int dmic_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_card *card = rtd->card; - int ret; - - ret = snd_soc_dapm_new_controls(&card->dapm, dmic_widgets, - ARRAY_SIZE(dmic_widgets)); - if (ret) { - dev_err(card->dev, "DMic widget addition failed: %d\n", ret); - /* Don't need to add routes if widget addition failed */ - return ret; - } - - ret = snd_soc_dapm_add_routes(&card->dapm, dmic_map, - ARRAY_SIZE(dmic_map)); - - if (ret) - dev_err(card->dev, "DMic map addition failed: %d\n", ret); - - return ret; -} - /* sof audio machine driver for rt5682 codec */ static struct snd_soc_card sof_audio_card_rt5682 = { .name = "rt5682", /* the sof- prefix is added by the core */ @@ -655,26 +570,17 @@ static struct snd_soc_dai_link_component rt5650_components[] = { } }; -static struct snd_soc_dai_link_component dmic_component[] = { - { - .name = "dmic-codec", - .dai_name = "dmic-hifi", - } -}; - -#define IDISP_CODEC_MASK 0x4 - -static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, - int ssp_codec, - int ssp_amp, - int dmic_be_num, - int hdmi_num, - bool idisp_codec) +static struct snd_soc_dai_link * +sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec codec_type, + enum sof_ssp_codec amp_type, int ssp_codec, + int ssp_amp, int dmic_be_num, int hdmi_num, + bool idisp_codec, bool is_legacy_cpu) { - struct snd_soc_dai_link_component *idisp_components; struct snd_soc_dai_link_component *cpus; struct snd_soc_dai_link *links; - int i, id = 0; + int i; + int id = 0; + int ret; int hdmi_id_offset = 0; links = devm_kcalloc(dev, sof_audio_card_rt5682.num_links, @@ -691,16 +597,25 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, goto devm_err; links[id].id = id; - if (sof_rt5682_quirk & SOF_RT5682S_HEADPHONE_CODEC_PRESENT) { - links[id].codecs = rt5682s_component; - links[id].num_codecs = ARRAY_SIZE(rt5682s_component); - } else if (sof_rt5682_quirk & SOF_RT5650_HEADPHONE_CODEC_PRESENT) { + + switch (codec_type) { + case CODEC_RT5650: links[id].codecs = &rt5650_components[0]; links[id].num_codecs = 1; - } else { + break; + case CODEC_RT5682: links[id].codecs = rt5682_component; links[id].num_codecs = ARRAY_SIZE(rt5682_component); + break; + case CODEC_RT5682S: + links[id].codecs = rt5682s_component; + links[id].num_codecs = ARRAY_SIZE(rt5682s_component); + break; + default: + dev_err(dev, "invalid codec type %d\n", codec_type); + return NULL; } + links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); links[id].init = sof_rt5682_codec_init; @@ -739,114 +654,83 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, /* dmic */ if (dmic_be_num > 0) { /* at least we have dmic01 */ - links[id].name = "dmic01"; - links[id].cpus = &cpus[id]; - links[id].cpus->dai_name = "DMIC01 Pin"; - links[id].init = dmic_init; - if (dmic_be_num > 1) { - /* set up 2 BE links at most */ - links[id + 1].name = "dmic16k"; - links[id + 1].cpus = &cpus[id + 1]; - links[id + 1].cpus->dai_name = "DMIC16k Pin"; - dmic_be_num = 2; - } + ret = sof_intel_board_set_dmic_link(dev, &links[id], id, + SOF_DMIC_01); + if (ret) + return NULL; + + id++; } - for (i = 0; i < dmic_be_num; i++) { - links[id].id = id; - links[id].num_cpus = 1; - links[id].codecs = dmic_component; - links[id].num_codecs = ARRAY_SIZE(dmic_component); - links[id].platforms = platform_component; - links[id].num_platforms = ARRAY_SIZE(platform_component); - links[id].ignore_suspend = 1; - links[id].dpcm_capture = 1; - links[id].no_pcm = 1; + if (dmic_be_num > 1) { + /* set up 2 BE links at most */ + ret = sof_intel_board_set_dmic_link(dev, &links[id], id, + SOF_DMIC_16K); + if (ret) + return NULL; + id++; } /* HDMI */ - if (hdmi_num > 0) { - idisp_components = devm_kcalloc(dev, - hdmi_num, - sizeof(struct snd_soc_dai_link_component), - GFP_KERNEL); - if (!idisp_components) - goto devm_err; - } for (i = 1; i <= hdmi_num; i++) { - links[id].name = devm_kasprintf(dev, GFP_KERNEL, - "iDisp%d", i); - if (!links[id].name) - goto devm_err; - - links[id].id = id; - links[id].cpus = &cpus[id]; - links[id].num_cpus = 1; - links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, - "iDisp%d Pin", i); - if (!links[id].cpus->dai_name) - goto devm_err; - - if (idisp_codec) { - idisp_components[i - 1].name = "ehdaudio0D2"; - idisp_components[i - 1].dai_name = devm_kasprintf(dev, - GFP_KERNEL, - "intel-hdmi-hifi%d", - i); - if (!idisp_components[i - 1].dai_name) - goto devm_err; - } else { - idisp_components[i - 1] = asoc_dummy_dlc; - } + ret = sof_intel_board_set_intel_hdmi_link(dev, &links[id], id, + i, idisp_codec); + if (ret) + return NULL; - links[id].codecs = &idisp_components[i - 1]; - links[id].num_codecs = 1; - links[id].platforms = platform_component; - links[id].num_platforms = ARRAY_SIZE(platform_component); - links[id].init = sof_hdmi_init; - links[id].dpcm_playback = 1; - links[id].no_pcm = 1; id++; } /* speaker amp */ - if (sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT) { + if (amp_type != CODEC_NONE) { links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_amp); if (!links[id].name) goto devm_err; links[id].id = id; - if (sof_rt5682_quirk & SOF_RT1015_SPEAKER_AMP_PRESENT) { - sof_rt1015_dai_link(&links[id]); - } else if (sof_rt5682_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) { - sof_rt1015p_dai_link(&links[id]); - } else if (sof_rt5682_quirk & SOF_RT1019_SPEAKER_AMP_PRESENT) { - sof_rt1019p_dai_link(&links[id]); - } else if (sof_rt5682_quirk & - SOF_MAX98373_SPEAKER_AMP_PRESENT) { + + switch (amp_type) { + case CODEC_MAX98357A: + max_98357a_dai_link(&links[id]); + break; + case CODEC_MAX98360A: + max_98360a_dai_link(&links[id]); + break; + case CODEC_MAX98373: links[id].codecs = max_98373_components; links[id].num_codecs = ARRAY_SIZE(max_98373_components); links[id].init = max_98373_spk_codec_init; links[id].ops = &max_98373_ops; - } else if (sof_rt5682_quirk & - SOF_MAX98360A_SPEAKER_AMP_PRESENT) { - max_98360a_dai_link(&links[id]); - } else if (sof_rt5682_quirk & - SOF_RT1011_SPEAKER_AMP_PRESENT) { - sof_rt1011_dai_link(&links[id]); - } else if (sof_rt5682_quirk & - SOF_MAX98390_SPEAKER_AMP_PRESENT) { + break; + case CODEC_MAX98390: max_98390_dai_link(dev, &links[id]); - } else if (sof_rt5682_quirk & SOF_RT5650_HEADPHONE_CODEC_PRESENT) { + break; + case CODEC_RT1011: + sof_rt1011_dai_link(&links[id]); + break; + case CODEC_RT1015: + sof_rt1015_dai_link(&links[id]); + break; + case CODEC_RT1015P: + sof_rt1015p_dai_link(&links[id]); + break; + case CODEC_RT1019P: + sof_rt1019p_dai_link(&links[id]); + break; + case CODEC_RT5650: + /* use AIF2 to support speaker pipeline */ links[id].codecs = &rt5650_components[1]; links[id].num_codecs = 1; links[id].init = rt5650_spk_init; links[id].ops = &sof_rt5682_ops; - } else { - max_98357a_dai_link(&links[id]); + break; + default: + dev_err(dev, "invalid amp type %d\n", amp_type); + return NULL; } + links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); links[id].dpcm_playback = 1; @@ -887,7 +771,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port); if (!links[id].name) goto devm_err; - links[id].codecs = &asoc_dummy_dlc; + links[id].codecs = &snd_soc_dummy_dlc; links[id].num_codecs = 1; links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); @@ -914,7 +798,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, if (!links[id].name) return NULL; links[id].id = id + hdmi_id_offset; - links[id].codecs = &asoc_dummy_dlc; + links[id].codecs = &snd_soc_dummy_dlc; links[id].num_codecs = 1; links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); @@ -932,10 +816,9 @@ devm_err: static int sof_audio_probe(struct platform_device *pdev) { + struct snd_soc_acpi_mach *mach = pdev->dev.platform_data; struct snd_soc_dai_link *dai_links; - struct snd_soc_acpi_mach *mach; struct sof_card_private *ctx; - int dmic_be_num, hdmi_num; int ret, ssp_amp, ssp_codec; ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); @@ -947,49 +830,44 @@ static int sof_audio_probe(struct platform_device *pdev) dmi_check_system(sof_rt5682_quirk_table); - mach = pdev->dev.platform_data; - - /* A speaker amp might not be present when the quirk claims one is. - * Detect this via whether the machine driver match includes quirk_data. - */ - if ((sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT) && !mach->quirk_data) - sof_rt5682_quirk &= ~SOF_SPEAKER_AMP_PRESENT; - - /* Detect the headset codec variant */ - if (acpi_dev_present("RTL5682", NULL, -1)) - sof_rt5682_quirk |= SOF_RT5682S_HEADPHONE_CODEC_PRESENT; - else if (acpi_dev_present("10EC5650", NULL, -1)) { - sof_rt5682_quirk |= SOF_RT5650_HEADPHONE_CODEC_PRESENT; + ctx->codec_type = sof_ssp_detect_codec_type(&pdev->dev); + ctx->amp_type = sof_ssp_detect_amp_type(&pdev->dev); + if (ctx->codec_type == CODEC_RT5650) { sof_audio_card_rt5682.name = devm_kstrdup(&pdev->dev, "rt5650", GFP_KERNEL); + + /* create speaker dai link also */ + if (ctx->amp_type == CODEC_NONE) + ctx->amp_type = CODEC_RT5650; } if (soc_intel_is_byt() || soc_intel_is_cht()) { - is_legacy_cpu = 1; - dmic_be_num = 0; - hdmi_num = 0; + ctx->rt5682.is_legacy_cpu = true; + ctx->dmic_be_num = 0; + /* HDMI is not supported by SOF on Baytrail/CherryTrail */ + ctx->hdmi_num = 0; /* default quirk for legacy cpu */ sof_rt5682_quirk = SOF_RT5682_MCLK_EN | SOF_RT5682_MCLK_BYTCHT_EN | SOF_RT5682_SSP_CODEC(2); } else { - dmic_be_num = 2; - hdmi_num = (sof_rt5682_quirk & SOF_RT5682_NUM_HDMIDEV_MASK) >> + ctx->dmic_be_num = 2; + ctx->hdmi_num = (sof_rt5682_quirk & SOF_RT5682_NUM_HDMIDEV_MASK) >> SOF_RT5682_NUM_HDMIDEV_SHIFT; /* default number of HDMI DAI's */ - if (!hdmi_num) - hdmi_num = 3; + if (!ctx->hdmi_num) + ctx->hdmi_num = 3; if (mach->mach_params.codec_mask & IDISP_CODEC_MASK) - ctx->idisp_codec = true; + ctx->hdmi.idisp_codec = true; } /* need to get main clock from pmc */ if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) { - ctx->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); - if (IS_ERR(ctx->mclk)) { - ret = PTR_ERR(ctx->mclk); + ctx->rt5682.mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); + if (IS_ERR(ctx->rt5682.mclk)) { + ret = PTR_ERR(ctx->rt5682.mclk); dev_err(&pdev->dev, "Failed to get MCLK from pmc_plt_clk_3: %d\n", @@ -997,7 +875,7 @@ static int sof_audio_probe(struct platform_device *pdev) return ret; } - ret = clk_prepare_enable(ctx->mclk); + ret = clk_prepare_enable(ctx->rt5682.mclk); if (ret < 0) { dev_err(&pdev->dev, "could not configure MCLK state"); @@ -1013,21 +891,11 @@ static int sof_audio_probe(struct platform_device *pdev) ssp_codec = sof_rt5682_quirk & SOF_RT5682_SSP_CODEC_MASK; /* compute number of dai links */ - sof_audio_card_rt5682.num_links = 1 + dmic_be_num + hdmi_num; + sof_audio_card_rt5682.num_links = 1 + ctx->dmic_be_num + ctx->hdmi_num; - if (sof_rt5682_quirk & SOF_SPEAKER_AMP_PRESENT) + if (ctx->amp_type != CODEC_NONE) sof_audio_card_rt5682.num_links++; - if (sof_rt5682_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) - max_98373_set_codec_conf(&sof_audio_card_rt5682); - else if (sof_rt5682_quirk & SOF_RT1011_SPEAKER_AMP_PRESENT) - sof_rt1011_codec_conf(&sof_audio_card_rt5682); - else if (sof_rt5682_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) - sof_rt1015p_codec_conf(&sof_audio_card_rt5682); - else if (sof_rt5682_quirk & SOF_MAX98390_SPEAKER_AMP_PRESENT) { - max_98390_set_codec_conf(&pdev->dev, &sof_audio_card_rt5682); - } - if (sof_rt5682_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) sof_audio_card_rt5682.num_links++; @@ -1036,17 +904,44 @@ static int sof_audio_probe(struct platform_device *pdev) hweight32((sof_rt5682_quirk & SOF_SSP_HDMI_CAPTURE_PRESENT_MASK) >> SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT); - dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, ssp_amp, - dmic_be_num, hdmi_num, ctx->idisp_codec); + dai_links = sof_card_dai_links_create(&pdev->dev, ctx->codec_type, + ctx->amp_type, ssp_codec, ssp_amp, + ctx->dmic_be_num, ctx->hdmi_num, + ctx->hdmi.idisp_codec, + ctx->rt5682.is_legacy_cpu); if (!dai_links) return -ENOMEM; sof_audio_card_rt5682.dai_link = dai_links; - if (sof_rt5682_quirk & SOF_RT1015_SPEAKER_AMP_PRESENT) + /* update codec_conf */ + switch (ctx->amp_type) { + case CODEC_MAX98373: + max_98373_set_codec_conf(&sof_audio_card_rt5682); + break; + case CODEC_MAX98390: + max_98390_set_codec_conf(&pdev->dev, &sof_audio_card_rt5682); + break; + case CODEC_RT1011: + sof_rt1011_codec_conf(&sof_audio_card_rt5682); + break; + case CODEC_RT1015: sof_rt1015_codec_conf(&sof_audio_card_rt5682); - - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); + break; + case CODEC_RT1015P: + sof_rt1015p_codec_conf(&sof_audio_card_rt5682); + break; + case CODEC_NONE: + case CODEC_MAX98357A: + case CODEC_MAX98360A: + case CODEC_RT1019P: + case CODEC_RT5650: + /* no codec conf required */ + break; + default: + dev_err(&pdev->dev, "invalid amp type %d\n", ctx->amp_type); + return -EINVAL; + } sof_audio_card_rt5682.dev = &pdev->dev; @@ -1056,8 +951,6 @@ static int sof_audio_probe(struct platform_device *pdev) if (ret) return ret; - ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv; - snd_soc_card_set_drvdata(&sof_audio_card_rt5682, ctx); return devm_snd_soc_register_card(&pdev->dev, @@ -1071,50 +964,42 @@ static const struct platform_device_id board_ids[] = { { .name = "cml_rt1015_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | - SOF_RT5682_MCLK_24MHZ | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_RT1015_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1)), }, { .name = "jsl_rt5682_rt1015", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | - SOF_RT5682_MCLK_24MHZ | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_RT1015_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1)), }, { .name = "jsl_rt5682_mx98360", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | - SOF_RT5682_MCLK_24MHZ | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98360A_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1)), }, { .name = "jsl_rt5682_rt1015p", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | - SOF_RT5682_MCLK_24MHZ | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_RT1015P_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1)), }, { .name = "jsl_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | - SOF_RT5682_MCLK_24MHZ | SOF_RT5682_SSP_CODEC(0)), }, { + .name = "jsl_rt5650", + .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | + SOF_RT5682_SSP_CODEC(0) | + SOF_RT5682_SSP_AMP(1)), + }, + { .name = "tgl_mx98357_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1) | SOF_RT5682_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -1124,8 +1009,6 @@ static const struct platform_device_id board_ids[] = { .name = "tgl_rt1011_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_RT1011_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1) | SOF_RT5682_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -1135,8 +1018,6 @@ static const struct platform_device_id board_ids[] = { .name = "tgl_mx98373_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98373_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1) | SOF_RT5682_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -1146,8 +1027,6 @@ static const struct platform_device_id board_ids[] = { .name = "adl_mx98373_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98373_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1) | SOF_RT5682_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -1157,7 +1036,6 @@ static const struct platform_device_id board_ids[] = { .name = "adl_mx98357_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(2) | SOF_RT5682_NUM_HDMIDEV(4)), }, @@ -1165,8 +1043,6 @@ static const struct platform_device_id board_ids[] = { .name = "adl_max98390_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98390_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1) | SOF_RT5682_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -1176,8 +1052,6 @@ static const struct platform_device_id board_ids[] = { .name = "adl_mx98360_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98360A_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1) | SOF_RT5682_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -1195,8 +1069,6 @@ static const struct platform_device_id board_ids[] = { .name = "adl_rt1019_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_RT1019_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1) | SOF_RT5682_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -1211,10 +1083,18 @@ static const struct platform_device_id board_ids[] = { SOF_HDMI_CAPTURE_SSP_MASK(0x5)), }, { + .name = "adl_rt5650", + .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | + SOF_RT5682_SSP_CODEC(0) | + SOF_RT5682_SSP_AMP(1) | + SOF_RT5682_NUM_HDMIDEV(4) | + SOF_BT_OFFLOAD_SSP(2) | + SOF_SSP_BT_OFFLOAD_PRESENT), + }, + { .name = "rpl_mx98357_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(2) | SOF_RT5682_NUM_HDMIDEV(4)), }, @@ -1222,8 +1102,6 @@ static const struct platform_device_id board_ids[] = { .name = "rpl_mx98360_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98360A_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1) | SOF_RT5682_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | @@ -1233,20 +1111,25 @@ static const struct platform_device_id board_ids[] = { .name = "rpl_rt1019_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_RT1019_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1) | SOF_RT5682_NUM_HDMIDEV(4) | SOF_BT_OFFLOAD_SSP(2) | SOF_SSP_BT_OFFLOAD_PRESENT), }, { + .name = "rpl_rt5682_c1_h02", + .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | + SOF_RT5682_SSP_CODEC(1) | + SOF_RT5682_NUM_HDMIDEV(3) | + /* SSP 0 and SSP 2 are used for HDMI IN */ + SOF_HDMI_CAPTURE_SSP_MASK(0x5)), + }, + { .name = "mtl_mx98357_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1) | - SOF_RT5682_NUM_HDMIDEV(4) | + SOF_RT5682_NUM_HDMIDEV(3) | SOF_BT_OFFLOAD_SSP(2) | SOF_SSP_BT_OFFLOAD_PRESENT), }, @@ -1254,28 +1137,16 @@ static const struct platform_device_id board_ids[] = { .name = "mtl_mx98360_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98360A_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1) | - SOF_RT5682_NUM_HDMIDEV(4)), + SOF_RT5682_NUM_HDMIDEV(3)), }, { .name = "mtl_rt1019_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(2) | - SOF_SPEAKER_AMP_PRESENT | - SOF_RT1019_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(0) | SOF_RT5682_NUM_HDMIDEV(3)), }, - { - .name = "jsl_rt5650", - .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | - SOF_RT5682_MCLK_24MHZ | - SOF_RT5682_SSP_CODEC(0) | - SOF_SPEAKER_AMP_PRESENT | - SOF_RT5682_SSP_AMP(1)), - }, { } }; MODULE_DEVICE_TABLE(platform, board_ids); @@ -1297,6 +1168,7 @@ MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>"); MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>"); MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); +MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS); MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON); MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON); +MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_SSP_COMMON); diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 9ed572141f..1e788859c8 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -20,13 +20,6 @@ static int quirk_override = -1; module_param_named(quirk, quirk_override, int, 0444); MODULE_PARM_DESC(quirk, "Board-specific quirk override"); -#define INC_ID(BE, CPU, LINK) do { (BE)++; (CPU)++; (LINK)++; } while (0) - -#define SDW_MAX_LINKS 4 - -/* To store SDW Pin index for each SoundWire link */ -static unsigned int sdw_pin_index[SDW_MAX_LINKS]; - static void log_quirks(struct device *dev) { if (SOF_JACK_JDSRC(sof_sdw_quirk)) @@ -409,7 +402,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { .callback = sof_sdw_quirk_cb, .matches = { DMI_MATCH(DMI_SYS_VENDOR, "HP"), - DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16-k0xxx"), + DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16"), }, .driver_data = (void *)(SOF_SDW_TGL_HDMI | RT711_JD2), @@ -503,13 +496,6 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { {} }; -static struct snd_soc_dai_link_component dmic_component[] = { - { - .name = "dmic-codec", - .dai_name = "dmic-hifi", - } -}; - static struct snd_soc_dai_link_component platform_component[] = { { /* name might be overridden during probe */ @@ -525,12 +511,12 @@ int sdw_startup(struct snd_pcm_substream *substream) int sdw_prepare(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct sdw_stream_runtime *sdw_stream; struct snd_soc_dai *dai; /* Find stream from first CPU DAI */ - dai = asoc_rtd_to_cpu(rtd, 0); + dai = snd_soc_rtd_to_cpu(rtd, 0); sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); if (IS_ERR(sdw_stream)) { @@ -543,13 +529,13 @@ int sdw_prepare(struct snd_pcm_substream *substream) int sdw_trigger(struct snd_pcm_substream *substream, int cmd) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct sdw_stream_runtime *sdw_stream; struct snd_soc_dai *dai; int ret; /* Find stream from first CPU DAI */ - dai = asoc_rtd_to_cpu(rtd, 0); + dai = snd_soc_rtd_to_cpu(rtd, 0); sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); if (IS_ERR(sdw_stream)) { @@ -583,7 +569,7 @@ int sdw_trigger(struct snd_pcm_substream *substream, int cmd) int sdw_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); int ch = params_channels(params); struct snd_soc_dai *codec_dai; struct snd_soc_dai *cpu_dai; @@ -631,12 +617,12 @@ int sdw_hw_params(struct snd_pcm_substream *substream, int sdw_hw_free(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct sdw_stream_runtime *sdw_stream; struct snd_soc_dai *dai; /* Find stream from first CPU DAI */ - dai = asoc_rtd_to_cpu(rtd, 0); + dai = snd_soc_rtd_to_cpu(rtd, 0); sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); if (IS_ERR(sdw_stream)) { @@ -940,6 +926,33 @@ static struct sof_sdw_codec_info codec_info_list[] = { .dai_num = 1, }, { + .part_id = 0x4243, + .codec_name = "cs42l43-codec", + .dais = { + { + .direction = {true, false}, + .dai_name = "cs42l43-dp5", + .dai_type = SOF_SDW_DAI_TYPE_JACK, + .dailink = {SDW_JACK_OUT_DAI_ID, SDW_UNUSED_DAI_ID}, + .init = sof_sdw_cs42l43_hs_init, + }, + { + .direction = {false, true}, + .dai_name = "cs42l43-dp1", + .dai_type = SOF_SDW_DAI_TYPE_MIC, + .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, + .init = sof_sdw_cs42l43_dmic_init, + }, + { + .direction = {false, true}, + .dai_name = "cs42l43-dp2", + .dai_type = SOF_SDW_DAI_TYPE_JACK, + .dailink = {SDW_UNUSED_DAI_ID, SDW_JACK_IN_DAI_ID}, + }, + }, + .dai_num = 3, + }, + { .part_id = 0xaaaa, /* generic codec mockup */ .version_id = 0, .dais = { @@ -1039,7 +1052,7 @@ static inline int find_codec_info_acpi(const u8 *acpi_id) */ static int get_dailink_info(struct device *dev, const struct snd_soc_acpi_link_adr *adr_link, - int *sdw_be_num, int *sdw_cpu_dai_num, int *codecs_num) + int *sdw_be_num, int *codecs_num) { bool group_visited[SDW_MAX_GROUPS]; bool no_aggregation; @@ -1047,7 +1060,6 @@ static int get_dailink_info(struct device *dev, int j; no_aggregation = sof_sdw_quirk & SOF_SDW_NO_AGGREGATION; - *sdw_cpu_dai_num = 0; *sdw_be_num = 0; if (!adr_link) @@ -1096,8 +1108,6 @@ static int get_dailink_info(struct device *dev, if (!codec_info->dais[j].direction[stream]) continue; - (*sdw_cpu_dai_num)++; - /* count BE for each non-aggregated slave or group */ if (!endpoint->aggregated || no_aggregation || !group_visited[endpoint->group_id]) @@ -1114,14 +1124,14 @@ static int get_dailink_info(struct device *dev, } static void init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links, - int be_id, char *name, int playback, int capture, + int *be_id, char *name, int playback, int capture, struct snd_soc_dai_link_component *cpus, int cpus_num, struct snd_soc_dai_link_component *codecs, int codecs_num, int (*init)(struct snd_soc_pcm_runtime *rtd), const struct snd_soc_ops *ops) { - dev_dbg(dev, "create dai link %s, id %d\n", name, be_id); - dai_links->id = be_id; + dev_dbg(dev, "create dai link %s, id %d\n", name, *be_id); + dai_links->id = (*be_id)++; dai_links->name = name; dai_links->platforms = platform_component; dai_links->num_platforms = ARRAY_SIZE(platform_component); @@ -1136,6 +1146,31 @@ static void init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links dai_links->ops = ops; } +static int init_simple_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links, + int *be_id, char *name, int playback, int capture, + const char *cpu_dai_name, + const char *codec_name, const char *codec_dai_name, + int (*init)(struct snd_soc_pcm_runtime *rtd), + const struct snd_soc_ops *ops) +{ + struct snd_soc_dai_link_component *dlc; + + /* Allocate two DLCs one for the CPU, one for the CODEC */ + dlc = devm_kcalloc(dev, 2, sizeof(*dlc), GFP_KERNEL); + if (!dlc || !name || !cpu_dai_name || !codec_name || !codec_dai_name) + return -ENOMEM; + + dlc[0].dai_name = cpu_dai_name; + + dlc[1].name = codec_name; + dlc[1].dai_name = codec_dai_name; + + init_dai_link(dev, dai_links, be_id, name, playback, capture, + &dlc[0], 1, &dlc[1], 1, init, ops); + + return 0; +} + static bool is_unique_device(const struct snd_soc_acpi_link_adr *adr_link, unsigned int sdw_version, unsigned int mfg_id, @@ -1329,11 +1364,9 @@ static void set_dailink_map(struct snd_soc_dai_link_codec_ch_map *sdw_codec_ch_m static const char * const type_strings[] = {"SimpleJack", "SmartAmp", "SmartMic"}; static int create_sdw_dailink(struct snd_soc_card *card, int *link_index, - struct snd_soc_dai_link *dai_links, - int sdw_be_num, int sdw_cpu_dai_num, - struct snd_soc_dai_link_component *cpus, + struct snd_soc_dai_link *dai_links, int sdw_be_num, const struct snd_soc_acpi_link_adr *adr_link, - int *cpu_id, struct snd_soc_codec_conf *codec_conf, + struct snd_soc_codec_conf *codec_conf, int codec_count, int *be_id, int *codec_conf_index, bool *ignore_pch_dmic, @@ -1341,12 +1374,14 @@ static int create_sdw_dailink(struct snd_soc_card *card, int *link_index, int adr_index, int dai_index) { + struct mc_private *ctx = snd_soc_card_get_drvdata(card); struct device *dev = card->dev; const struct snd_soc_acpi_link_adr *adr_link_next; struct snd_soc_dai_link_component *codecs; + struct snd_soc_dai_link_component *cpus; struct sof_sdw_codec_info *codec_info; int cpu_dai_id[SDW_MAX_CPU_DAIS]; - int cpu_dai_num, cpu_dai_index; + int cpu_dai_num; unsigned int group_id; int codec_dlc_index = 0; int codec_index; @@ -1417,7 +1452,6 @@ static int create_sdw_dailink(struct snd_soc_card *card, int *link_index, if (codec_info->ignore_pch_dmic) *ignore_pch_dmic = true; - cpu_dai_index = *cpu_id; for_each_pcm_streams(stream) { struct snd_soc_dai_link_codec_ch_map *sdw_codec_ch_maps; char *name, *cpu_name; @@ -1455,6 +1489,10 @@ static int create_sdw_dailink(struct snd_soc_card *card, int *link_index, if (!name) return -ENOMEM; + cpus = devm_kcalloc(dev, cpu_dai_num, sizeof(*cpus), GFP_KERNEL); + if (!cpus) + return -ENOMEM; + /* * generate CPU DAI name base on the sdw link ID and * PIN ID with offset of 2 according to sdw dai driver. @@ -1462,17 +1500,11 @@ static int create_sdw_dailink(struct snd_soc_card *card, int *link_index, for (k = 0; k < cpu_dai_num; k++) { cpu_name = devm_kasprintf(dev, GFP_KERNEL, "SDW%d Pin%d", cpu_dai_id[k], - sdw_pin_index[cpu_dai_id[k]]++); + ctx->sdw_pin_index[cpu_dai_id[k]]++); if (!cpu_name) return -ENOMEM; - if (cpu_dai_index >= sdw_cpu_dai_num) { - dev_err(dev, "invalid cpu dai index %d\n", - cpu_dai_index); - return -EINVAL; - } - - cpus[cpu_dai_index++].dai_name = cpu_name; + cpus[k].dai_name = cpu_name; } /* @@ -1484,17 +1516,11 @@ static int create_sdw_dailink(struct snd_soc_card *card, int *link_index, return -EINVAL; } - if (*cpu_id >= sdw_cpu_dai_num) { - dev_err(dev, "invalid cpu dai index %d\n", *cpu_id); - return -EINVAL; - } - playback = (stream == SNDRV_PCM_STREAM_PLAYBACK); capture = (stream == SNDRV_PCM_STREAM_CAPTURE); - init_dai_link(dev, dai_links + *link_index, (*be_id)++, name, - playback, capture, - cpus + *cpu_id, cpu_dai_num, - codecs, codec_num, + + init_dai_link(dev, dai_links + *link_index, be_id, name, + playback, capture, cpus, cpu_dai_num, codecs, codec_num, NULL, &sdw_ops); /* @@ -1511,27 +1537,20 @@ static int create_sdw_dailink(struct snd_soc_card *card, int *link_index, dev_err(dev, "failed to init codec %d\n", codec_index); return ret; } - - *cpu_id += cpu_dai_num; } return 0; } -#define IDISP_CODEC_MASK 0x4 - static int sof_card_dai_links_create(struct snd_soc_card *card) { struct device *dev = card->dev; struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev); - int sdw_be_num = 0, ssp_num = 0, dmic_num = 0, hdmi_num = 0, bt_num = 0; + int sdw_be_num = 0, ssp_num = 0, dmic_num = 0, bt_num = 0; struct mc_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_dai_link_component *idisp_components; - struct snd_soc_dai_link_component *ssp_components; struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params; const struct snd_soc_acpi_link_adr *adr_link = mach_params->links; bool aggregation = !(sof_sdw_quirk & SOF_SDW_NO_AGGREGATION); - struct snd_soc_dai_link_component *cpus; struct snd_soc_codec_conf *codec_conf; bool append_dai_type = false; bool ignore_pch_dmic = false; @@ -1541,16 +1560,14 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) int ssp_codec_index, ssp_mask; struct snd_soc_dai_link *dai_links; int num_links, link_index = 0; - char *name, *cpu_name; - int total_cpu_dai_num; - int sdw_cpu_dai_num; + char *name, *cpu_dai_name; + char *codec_name, *codec_dai_name; int i, j, be_id = 0; int codec_index; - int cpu_id = 0; + int hdmi_num; int ret; - ret = get_dailink_info(dev, adr_link, &sdw_be_num, &sdw_cpu_dai_num, - &codec_conf_num); + ret = get_dailink_info(dev, adr_link, &sdw_be_num, &codec_conf_num); if (ret < 0) { dev_err(dev, "failed to get sdw link info %d\n", ret); return ret; @@ -1568,14 +1585,13 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) ssp_num = hweight_long(ssp_mask); } - if (mach_params->codec_mask & IDISP_CODEC_MASK) { - ctx->idisp_codec = true; + if (mach_params->codec_mask & IDISP_CODEC_MASK) + ctx->hdmi.idisp_codec = true; - if (sof_sdw_quirk & SOF_SDW_TGL_HDMI) - hdmi_num = SOF_TGL_HDMI_COUNT; - else - hdmi_num = SOF_PRE_TGL_HDMI_COUNT; - } + if (sof_sdw_quirk & SOF_SDW_TGL_HDMI) + hdmi_num = SOF_TGL_HDMI_COUNT; + else + hdmi_num = SOF_PRE_TGL_HDMI_COUNT; /* enable dmic01 & dmic16k */ if (sof_sdw_quirk & SOF_SDW_PCH_DMIC || mach_params->dmic_num) @@ -1585,7 +1601,8 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) bt_num = 1; dev_dbg(dev, "sdw %d, ssp %d, dmic %d, hdmi %d, bt: %d\n", - sdw_be_num, ssp_num, dmic_num, hdmi_num, bt_num); + sdw_be_num, ssp_num, dmic_num, + ctx->hdmi.idisp_codec ? hdmi_num : 0, bt_num); /* allocate BE dailinks */ num_links = sdw_be_num + ssp_num + dmic_num + hdmi_num + bt_num; @@ -1593,12 +1610,6 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) if (!dai_links) return -ENOMEM; - /* allocated CPU DAIs */ - total_cpu_dai_num = sdw_cpu_dai_num + ssp_num + dmic_num + hdmi_num + bt_num; - cpus = devm_kcalloc(dev, total_cpu_dai_num, sizeof(*cpus), GFP_KERNEL); - if (!cpus) - return -ENOMEM; - /* allocate codec conf, will be populated when dailinks are created */ codec_conf = devm_kcalloc(dev, codec_conf_num, sizeof(*codec_conf), GFP_KERNEL); @@ -1610,7 +1621,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) goto SSP; for (i = 0; i < SDW_MAX_LINKS; i++) - sdw_pin_index[i] = SDW_INTEL_BIDIR_PDI_BASE; + ctx->sdw_pin_index[i] = SDW_INTEL_BIDIR_PDI_BASE; for (; adr_link->num_adr; adr_link++) { /* @@ -1660,8 +1671,7 @@ out: for (j = 0; j < codec_info_list[codec_index].dai_num ; j++) { ret = create_sdw_dailink(card, &link_index, dai_links, - sdw_be_num, sdw_cpu_dai_num, cpus, - adr_link, &cpu_id, + sdw_be_num, adr_link, codec_conf, codec_conf_num, &be_id, &codec_conf_index, &ignore_pch_dmic, append_dai_type, i, j); @@ -1684,49 +1694,32 @@ SSP: for (i = 0, j = 0; ssp_mask; i++, ssp_mask >>= 1) { struct sof_sdw_codec_info *info; int playback, capture; - char *codec_name; if (!(ssp_mask & 0x1)) continue; - name = devm_kasprintf(dev, GFP_KERNEL, - "SSP%d-Codec", i); - if (!name) - return -ENOMEM; - - cpu_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", i); - if (!cpu_name) - return -ENOMEM; - - ssp_components = devm_kzalloc(dev, sizeof(*ssp_components), - GFP_KERNEL); - if (!ssp_components) - return -ENOMEM; - info = &codec_info_list[ssp_codec_index]; + + name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", i); + cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", i); codec_name = devm_kasprintf(dev, GFP_KERNEL, "i2c-%s:0%d", info->acpi_id, j++); - if (!codec_name) - return -ENOMEM; - - ssp_components->name = codec_name; - /* TODO: support multi codec dai on SSP when it is needed */ - ssp_components->dai_name = info->dais[0].dai_name; - cpus[cpu_id].dai_name = cpu_name; playback = info->dais[0].direction[SNDRV_PCM_STREAM_PLAYBACK]; capture = info->dais[0].direction[SNDRV_PCM_STREAM_CAPTURE]; - init_dai_link(dev, dai_links + link_index, be_id, name, - playback, capture, - cpus + cpu_id, 1, - ssp_components, 1, - NULL, info->ops); + + ret = init_simple_dai_link(dev, dai_links + link_index, &be_id, name, + playback, capture, cpu_dai_name, + codec_name, info->dais[0].dai_name, + NULL, info->ops); + if (ret) + return ret; ret = info->dais[0].init(card, NULL, dai_links + link_index, info, 0); if (ret < 0) return ret; - INC_ID(be_id, cpu_id, link_index); + link_index++; } DMIC: @@ -1736,64 +1729,50 @@ DMIC: dev_warn(dev, "Ignoring PCH DMIC\n"); goto HDMI; } - cpus[cpu_id].dai_name = "DMIC01 Pin"; - init_dai_link(dev, dai_links + link_index, be_id, "dmic01", - 0, 1, // DMIC only supports capture - cpus + cpu_id, 1, - dmic_component, 1, - sof_sdw_dmic_init, NULL); - INC_ID(be_id, cpu_id, link_index); - - cpus[cpu_id].dai_name = "DMIC16k Pin"; - init_dai_link(dev, dai_links + link_index, be_id, "dmic16k", - 0, 1, // DMIC only supports capture - cpus + cpu_id, 1, - dmic_component, 1, - /* don't call sof_sdw_dmic_init() twice */ - NULL, NULL); - INC_ID(be_id, cpu_id, link_index); + + ret = init_simple_dai_link(dev, dai_links + link_index, &be_id, "dmic01", + 0, 1, // DMIC only supports capture + "DMIC01 Pin", "dmic-codec", "dmic-hifi", + sof_sdw_dmic_init, NULL); + if (ret) + return ret; + + link_index++; + + ret = init_simple_dai_link(dev, dai_links + link_index, &be_id, "dmic16k", + 0, 1, // DMIC only supports capture + "DMIC16k Pin", "dmic-codec", "dmic-hifi", + /* don't call sof_sdw_dmic_init() twice */ + NULL, NULL); + if (ret) + return ret; + + link_index++; } HDMI: /* HDMI */ - if (hdmi_num > 0) { - idisp_components = devm_kcalloc(dev, hdmi_num, - sizeof(*idisp_components), - GFP_KERNEL); - if (!idisp_components) - return -ENOMEM; - } - for (i = 0; i < hdmi_num; i++) { - name = devm_kasprintf(dev, GFP_KERNEL, - "iDisp%d", i + 1); - if (!name) - return -ENOMEM; + name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d", i + 1); + cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d Pin", i + 1); - if (ctx->idisp_codec) { - idisp_components[i].name = "ehdaudio0D2"; - idisp_components[i].dai_name = devm_kasprintf(dev, - GFP_KERNEL, - "intel-hdmi-hifi%d", - i + 1); - if (!idisp_components[i].dai_name) - return -ENOMEM; + if (ctx->hdmi.idisp_codec) { + codec_name = "ehdaudio0D2"; + codec_dai_name = devm_kasprintf(dev, GFP_KERNEL, + "intel-hdmi-hifi%d", i + 1); } else { - idisp_components[i] = asoc_dummy_dlc; + codec_name = "snd-soc-dummy"; + codec_dai_name = "snd-soc-dummy-dai"; } - cpu_name = devm_kasprintf(dev, GFP_KERNEL, - "iDisp%d Pin", i + 1); - if (!cpu_name) - return -ENOMEM; + ret = init_simple_dai_link(dev, dai_links + link_index, &be_id, name, + 1, 0, // HDMI only supports playback + cpu_dai_name, codec_name, codec_dai_name, + i == 0 ? sof_sdw_hdmi_init : NULL, NULL); + if (ret) + return ret; - cpus[cpu_id].dai_name = cpu_name; - init_dai_link(dev, dai_links + link_index, be_id, name, - 1, 0, // HDMI only supports playback - cpus + cpu_id, 1, - idisp_components + i, 1, - sof_sdw_hdmi_init, NULL); - INC_ID(be_id, cpu_id, link_index); + link_index++; } if (sof_sdw_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) { @@ -1801,16 +1780,13 @@ HDMI: SOF_BT_OFFLOAD_SSP_SHIFT; name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port); - if (!name) - return -ENOMEM; - - cpu_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", port); - if (!cpu_name) - return -ENOMEM; + cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", port); - cpus[cpu_id].dai_name = cpu_name; - init_dai_link(dev, dai_links + link_index, be_id, name, 1, 1, - cpus + cpu_id, 1, &asoc_dummy_dlc, 1, NULL, NULL); + ret = init_simple_dai_link(dev, dai_links + link_index, &be_id, name, + 1, 1, cpu_dai_name, snd_soc_dummy_dlc.name, + snd_soc_dummy_dlc.dai_name, NULL, NULL); + if (ret) + return ret; } card->dai_link = dai_links; @@ -1837,7 +1813,7 @@ static int sof_sdw_card_late_probe(struct snd_soc_card *card) } } - if (ctx->idisp_codec) + if (ctx->hdmi.idisp_codec) ret = sof_sdw_hdmi_card_late_probe(card); return ret; @@ -1916,8 +1892,6 @@ static int mc_probe(struct platform_device *pdev) if (!ctx) return -ENOMEM; - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - snd_soc_card_set_drvdata(card, ctx); dmi_check_system(sof_sdw_quirk_table); diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h index 2f4fe6bc3d..e6b98523b4 100644 --- a/sound/soc/intel/boards/sof_sdw_common.h +++ b/sound/soc/intel/boards/sof_sdw_common.h @@ -12,6 +12,7 @@ #include <linux/bits.h> #include <linux/types.h> #include <sound/soc.h> +#include "sof_hdmi_common.h" #define MAX_NO_PROPS 2 #define MAX_HDMI_NUM 4 @@ -24,6 +25,8 @@ #define SDW_MAX_CPU_DAIS 16 #define SDW_INTEL_BIDIR_PDI_BASE 2 +#define SDW_MAX_LINKS 4 + /* 8 combinations with 4 links + unused group 0 */ #define SDW_MAX_GROUPS 9 @@ -92,11 +95,12 @@ struct sof_sdw_codec_info { }; struct mc_private { - struct list_head hdmi_pcm_list; - bool idisp_codec; struct snd_soc_jack sdw_headset; + struct sof_hdmi_private hdmi; struct device *headset_codec_dev; /* only one headset per card */ struct device *amp_dev1, *amp_dev2; + /* To store SDW Pin index for each SoundWire link */ + unsigned int sdw_pin_index[SDW_MAX_LINKS]; }; extern unsigned long sof_sdw_quirk; @@ -206,6 +210,19 @@ int sof_sdw_cs42l42_init(struct snd_soc_card *card, struct sof_sdw_codec_info *info, bool playback); +/* CS42L43 support */ +int sof_sdw_cs42l43_hs_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback); + +int sof_sdw_cs42l43_dmic_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback); + /* CS AMP support */ int sof_sdw_cs_amp_init(struct snd_soc_card *card, const struct snd_soc_acpi_link_adr *link, diff --git a/sound/soc/intel/boards/sof_sdw_cs42l42.c b/sound/soc/intel/boards/sof_sdw_cs42l42.c index ad130d9134..436f41086d 100644 --- a/sound/soc/intel/boards/sof_sdw_cs42l42.c +++ b/sound/soc/intel/boards/sof_sdw_cs42l42.c @@ -50,7 +50,7 @@ static int cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; struct mc_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_component *component = codec_dai->component; struct snd_soc_jack *jack; int ret; diff --git a/sound/soc/intel/boards/sof_sdw_cs42l43.c b/sound/soc/intel/boards/sof_sdw_cs42l43.c new file mode 100644 index 0000000000..360f11b72a --- /dev/null +++ b/sound/soc/intel/boards/sof_sdw_cs42l43.c @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Based on sof_sdw_rt5682.c +// Copyright (c) 2023 Intel Corporation + +/* + * sof_sdw_cs42l43 - Helpers to handle CS42L43 from generic machine driver + */ +#include <linux/device.h> +#include <linux/errno.h> +#include <linux/input.h> +#include <sound/jack.h> +#include <linux/soundwire/sdw.h> +#include <linux/soundwire/sdw_type.h> +#include <sound/cs42l43.h> +#include <sound/control.h> +#include <sound/soc.h> +#include <sound/soc-acpi.h> +#include <sound/soc-dapm.h> +#include "sof_sdw_common.h" + +static const struct snd_soc_dapm_widget cs42l43_hs_widgets[] = { + SND_SOC_DAPM_HP("Headphone", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), +}; + +static const struct snd_soc_dapm_route cs42l43_hs_map[] = { + { "Headphone", NULL, "cs42l43 AMP3_OUT" }, + { "Headphone", NULL, "cs42l43 AMP4_OUT" }, + { "cs42l43 ADC1_IN1_P", NULL, "Headset Mic" }, + { "cs42l43 ADC1_IN1_N", NULL, "Headset Mic" }, +}; + +static const struct snd_soc_dapm_widget cs42l43_dmic_widgets[] = { + SND_SOC_DAPM_MIC("DMIC", NULL), +}; + +static const struct snd_soc_dapm_route cs42l43_dmic_map[] = { + { "cs42l43 PDM1_DIN", NULL, "DMIC" }, + { "cs42l43 PDM2_DIN", NULL, "DMIC" }, +}; + +static struct snd_soc_jack_pin sof_jack_pins[] = { + { + .pin = "Headphone", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + +static int cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; + struct mc_private *ctx = snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_jack *jack = &ctx->sdw_headset; + struct snd_soc_card *card = rtd->card; + int ret; + + card->components = devm_kasprintf(card->dev, GFP_KERNEL, "%s hs:cs42l43", + card->components); + if (!card->components) + return -ENOMEM; + + ret = snd_soc_dapm_new_controls(&card->dapm, cs42l43_hs_widgets, + ARRAY_SIZE(cs42l43_hs_widgets)); + if (ret) { + dev_err(card->dev, "cs42l43 hs widgets addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, cs42l43_hs_map, + ARRAY_SIZE(cs42l43_hs_map)); + if (ret) { + dev_err(card->dev, "cs42l43 hs map addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_card_jack_new_pins(card, "Jack", + SND_JACK_MECHANICAL | SND_JACK_AVOUT | + SND_JACK_HEADSET | SND_JACK_LINEOUT | + SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3, + jack, sof_jack_pins, + ARRAY_SIZE(sof_jack_pins)); + if (ret) { + dev_err(card->dev, "Failed to create jack: %d\n", ret); + return ret; + } + + snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); + 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); + + ret = snd_soc_component_set_jack(component, jack, NULL); + if (ret) { + dev_err(card->dev, "Failed to register jack: %d\n", ret); + return ret; + } + + ret = snd_soc_component_set_sysclk(component, CS42L43_SYSCLK, CS42L43_SYSCLK_SDW, + 0, SND_SOC_CLOCK_IN); + if (ret) + dev_err(card->dev, "Failed to set sysclk: %d\n", ret); + + return ret; +} + +int sof_sdw_cs42l43_hs_init(struct snd_soc_card *card, const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, struct sof_sdw_codec_info *info, + bool playback) +{ + /* + * No need to test if (!playback) like other codecs as cs42l43 uses separated dai for + * playback and capture, and sof_sdw_cs42l43_init is only linked to the playback dai. + */ + dai_links->init = cs42l43_hs_rtd_init; + + return 0; +} + +static int cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + int ret; + + card->components = devm_kasprintf(card->dev, GFP_KERNEL, "%s mic:cs42l43-dmic", + card->components); + if (!card->components) + return -ENOMEM; + + ret = snd_soc_dapm_new_controls(&card->dapm, cs42l43_dmic_widgets, + ARRAY_SIZE(cs42l43_dmic_widgets)); + if (ret) { + dev_err(card->dev, "cs42l43 dmic widgets addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, cs42l43_dmic_map, + ARRAY_SIZE(cs42l43_dmic_map)); + if (ret) + dev_err(card->dev, "cs42l43 dmic map addition failed: %d\n", ret); + + return ret; +} + +int sof_sdw_cs42l43_dmic_init(struct snd_soc_card *card, const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, struct sof_sdw_codec_info *info, + bool playback) +{ + dai_links->init = cs42l43_dmic_rtd_init; + + return 0; +} diff --git a/sound/soc/intel/boards/sof_sdw_hdmi.c b/sound/soc/intel/boards/sof_sdw_hdmi.c index d47d8bf528..f34fabdf9d 100644 --- a/sound/soc/intel/boards/sof_sdw_hdmi.c +++ b/sound/soc/intel/boards/sof_sdw_hdmi.c @@ -15,47 +15,25 @@ #include "sof_sdw_common.h" #include "hda_dsp_common.h" -struct hdmi_pcm { - struct list_head head; - struct snd_soc_dai *codec_dai; - int device; -}; - int sof_sdw_hdmi_init(struct snd_soc_pcm_runtime *rtd) { struct mc_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); - struct hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); - /* dai_link id is 1:1 mapped to the PCM device */ - pcm->device = rtd->dai_link->id; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); + ctx->hdmi.hdmi_comp = dai->component; return 0; } -#define NAME_SIZE 32 int sof_sdw_hdmi_card_late_probe(struct snd_soc_card *card) { struct mc_private *ctx = snd_soc_card_get_drvdata(card); - struct hdmi_pcm *pcm; - struct snd_soc_component *component = NULL; - if (!ctx->idisp_codec) + if (!ctx->hdmi.idisp_codec) return 0; - if (list_empty(&ctx->hdmi_pcm_list)) + if (!ctx->hdmi.hdmi_comp) return -EINVAL; - pcm = list_first_entry(&ctx->hdmi_pcm_list, struct hdmi_pcm, - head); - component = pcm->codec_dai->component; - - return hda_dsp_hdmi_build_controls(card, component); + return hda_dsp_hdmi_build_controls(card, ctx->hdmi.hdmi_comp); } diff --git a/sound/soc/intel/boards/sof_sdw_maxim.c b/sound/soc/intel/boards/sof_sdw_maxim.c index 414c4d8dac..e36b8d8c70 100644 --- a/sound/soc/intel/boards/sof_sdw_maxim.c +++ b/sound/soc/intel/boards/sof_sdw_maxim.c @@ -64,7 +64,7 @@ static int spk_init(struct snd_soc_pcm_runtime *rtd) static int mx8373_enable_spk_pin(struct snd_pcm_substream *substream, bool enable) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; struct snd_soc_dai *cpu_dai; int ret; @@ -74,7 +74,7 @@ static int mx8373_enable_spk_pin(struct snd_pcm_substream *substream, bool enabl if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) return 0; - cpu_dai = asoc_rtd_to_cpu(rtd, 0); + cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); for_each_rtd_codec_dais(rtd, j, codec_dai) { struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cpu_dai->component); diff --git a/sound/soc/intel/boards/sof_sdw_rt5682.c b/sound/soc/intel/boards/sof_sdw_rt5682.c index 3a9be82115..7b7c9def39 100644 --- a/sound/soc/intel/boards/sof_sdw_rt5682.c +++ b/sound/soc/intel/boards/sof_sdw_rt5682.c @@ -49,7 +49,7 @@ static int rt5682_rtd_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; struct mc_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_component *component = codec_dai->component; struct snd_soc_jack *jack; int ret; diff --git a/sound/soc/intel/boards/sof_sdw_rt700.c b/sound/soc/intel/boards/sof_sdw_rt700.c index c93b1f5b94..a1714afe85 100644 --- a/sound/soc/intel/boards/sof_sdw_rt700.c +++ b/sound/soc/intel/boards/sof_sdw_rt700.c @@ -49,7 +49,7 @@ static int rt700_rtd_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; struct mc_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_component *component = codec_dai->component; struct snd_soc_jack *jack; int ret; diff --git a/sound/soc/intel/boards/sof_sdw_rt711.c b/sound/soc/intel/boards/sof_sdw_rt711.c index 2b05e2a707..38782fdfcf 100644 --- a/sound/soc/intel/boards/sof_sdw_rt711.c +++ b/sound/soc/intel/boards/sof_sdw_rt711.c @@ -73,7 +73,7 @@ static int rt711_rtd_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; struct mc_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_component *component = codec_dai->component; struct snd_soc_jack *jack; int ret; diff --git a/sound/soc/intel/boards/sof_sdw_rt712_sdca.c b/sound/soc/intel/boards/sof_sdw_rt712_sdca.c index 84c8025d24..3092029419 100644 --- a/sound/soc/intel/boards/sof_sdw_rt712_sdca.c +++ b/sound/soc/intel/boards/sof_sdw_rt712_sdca.c @@ -80,10 +80,12 @@ int sof_sdw_rt712_spk_init(struct snd_soc_card *card, static int rt712_sdca_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); + struct snd_soc_component *component = codec_dai->component; card->components = devm_kasprintf(card->dev, GFP_KERNEL, - "%s mic:rt712-sdca-dmic", - card->components); + "%s mic:%s", + card->components, component->name_prefix); if (!card->components) return -ENOMEM; diff --git a/sound/soc/intel/boards/sof_sdw_rt_amp.c b/sound/soc/intel/boards/sof_sdw_rt_amp.c index 26bf9e0dd3..436975b6bd 100644 --- a/sound/soc/intel/boards/sof_sdw_rt_amp.c +++ b/sound/soc/intel/boards/sof_sdw_rt_amp.c @@ -251,9 +251,9 @@ static int all_spk_init(struct snd_soc_pcm_runtime *rtd) static int rt1308_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_card *card = rtd->card; - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int clk_id, clk_freq, pll_out; int err; diff --git a/sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c b/sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c index 890517eb63..49a513399d 100644 --- a/sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c +++ b/sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c @@ -83,7 +83,7 @@ static int rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; struct mc_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_component *component = codec_dai->component; struct snd_soc_jack *jack; int ret; diff --git a/sound/soc/intel/boards/sof_ssp_amp.c b/sound/soc/intel/boards/sof_ssp_amp.c index 5aa16fd393..137ba64254 100644 --- a/sound/soc/intel/boards/sof_ssp_amp.c +++ b/sound/soc/intel/boards/sof_ssp_amp.c @@ -17,12 +17,10 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/sof.h> -#include "../../codecs/hdac_hdmi.h" -#include "hda_dsp_common.h" +#include "sof_board_helpers.h" #include "sof_realtek_common.h" #include "sof_cirrus_common.h" - -#define NAME_SIZE 32 +#include "sof_ssp_common.h" /* SSP port ID for speaker amplifier */ #define SOF_AMPLIFIER_SSP(quirk) ((quirk) & GENMASK(3, 0)) @@ -59,26 +57,9 @@ #define SOF_BT_OFFLOAD_SSP(quirk) \ (((quirk) << SOF_BT_OFFLOAD_SSP_SHIFT) & SOF_BT_OFFLOAD_SSP_MASK) -/* Speaker amplifiers */ -#define SOF_RT1308_SPEAKER_AMP_PRESENT BIT(21) -#define SOF_CS35L41_SPEAKER_AMP_PRESENT BIT(22) - /* Default: SSP2 */ static unsigned long sof_ssp_amp_quirk = SOF_AMPLIFIER_SSP(2); -struct sof_hdmi_pcm { - struct list_head head; - struct snd_soc_jack sof_hdmi; - struct snd_soc_dai *codec_dai; - int device; -}; - -struct sof_card_private { - struct list_head hdmi_pcm_list; - bool common_hdmi_codec_drv; - bool idisp_codec; -}; - static const struct dmi_system_id chromebook_platforms[] = { { .ident = "Google Chromebooks", @@ -89,66 +70,14 @@ static const struct dmi_system_id chromebook_platforms[] = { {}, }; -static const struct snd_soc_dapm_widget sof_ssp_amp_dapm_widgets[] = { - SND_SOC_DAPM_MIC("SoC DMIC", NULL), -}; - -static const struct snd_soc_dapm_route sof_ssp_amp_dapm_routes[] = { - /* digital mics */ - {"DMic", NULL, "SoC DMIC"}, -}; - static int sof_card_late_probe(struct snd_soc_card *card) { - struct sof_card_private *ctx = snd_soc_card_get_drvdata(card); - struct snd_soc_component *component = NULL; - char jack_name[NAME_SIZE]; - struct sof_hdmi_pcm *pcm; - int err; - - if (!(sof_ssp_amp_quirk & SOF_HDMI_PLAYBACK_PRESENT)) - return 0; - - /* HDMI is not supported by SOF on Baytrail/CherryTrail */ - if (!ctx->idisp_codec) - return 0; - - if (list_empty(&ctx->hdmi_pcm_list)) - return -EINVAL; - - if (ctx->common_hdmi_codec_drv) { - pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm, - head); - component = pcm->codec_dai->component; - return hda_dsp_hdmi_build_controls(card, component); - } - - list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { - component = pcm->codec_dai->component; - 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, &pcm->sof_hdmi); - - if (err) - return err; - - err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, - &pcm->sof_hdmi); - if (err < 0) - return err; - } - - return hdac_hdmi_jack_port_init(component, &card->dapm); + return sof_intel_board_card_late_probe(card); } static struct snd_soc_card sof_ssp_amp_card = { .name = "ssp_amp", .owner = THIS_MODULE, - .dapm_widgets = sof_ssp_amp_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(sof_ssp_amp_dapm_widgets), - .dapm_routes = sof_ssp_amp_dapm_routes, - .num_dapm_routes = ARRAY_SIZE(sof_ssp_amp_dapm_routes), .fully_routed = true, .late_probe = sof_card_late_probe, }; @@ -160,44 +89,25 @@ static struct snd_soc_dai_link_component platform_component[] = { } }; -static struct snd_soc_dai_link_component dmic_component[] = { - { - .name = "dmic-codec", - .dai_name = "dmic-hifi", - } -}; - -static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd) +/* BE ID defined in sof-tgl-rt1308-hdmi-ssp.m4 */ +#define HDMI_IN_BE_ID 0 +#define SPK_BE_ID 2 +#define DMIC01_BE_ID 3 +#define DMIC16K_BE_ID 4 +#define INTEL_HDMI_BE_ID 5 + +static struct snd_soc_dai_link * +sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec amp_type, + int ssp_codec, int dmic_be_num, int hdmi_num, + bool idisp_codec) { - struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); - struct sof_hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - /* dai_link id is 1:1 mapped to the PCM device */ - pcm->device = rtd->dai_link->id; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); - - return 0; -} - -#define IDISP_CODEC_MASK 0x4 - -static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, - int ssp_codec, - int dmic_be_num, - int hdmi_num, - bool idisp_codec) -{ - struct snd_soc_dai_link_component *idisp_components; struct snd_soc_dai_link_component *cpus; struct snd_soc_dai_link *links; - int i, id = 0; + int i; + int id = 0; + int ret; + bool fixed_be = false; + int be_id; links = devm_kcalloc(dev, sof_ssp_amp_card.num_links, sizeof(struct snd_soc_dai_link), GFP_KERNEL); @@ -211,6 +121,9 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, int num_of_hdmi_ssp = (sof_ssp_amp_quirk & SOF_NO_OF_HDMI_CAPTURE_SSP_MASK) >> SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT; + /* the topology supports HDMI-IN uses fixed BE ID for DAI links */ + fixed_be = true; + for (i = 1; i <= num_of_hdmi_ssp; i++) { int port = (i == 1 ? (sof_ssp_amp_quirk & SOF_HDMI_CAPTURE_1_SSP_MASK) >> SOF_HDMI_CAPTURE_1_SSP_SHIFT : @@ -225,8 +138,8 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-HDMI", port); if (!links[id].name) return NULL; - links[id].id = id; - links[id].codecs = &asoc_dummy_dlc; + links[id].id = fixed_be ? (HDMI_IN_BE_ID + i - 1) : id; + links[id].codecs = &snd_soc_dummy_dlc; links[id].num_codecs = 1; links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); @@ -238,104 +151,72 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, } /* codec SSP */ - links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_codec); - if (!links[id].name) - return NULL; + if (amp_type != CODEC_NONE) { + links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_codec); + if (!links[id].name) + return NULL; + + links[id].id = fixed_be ? SPK_BE_ID : id; + + switch (amp_type) { + case CODEC_CS35L41: + cs35l41_set_dai_link(&links[id]); + break; + case CODEC_RT1308: + sof_rt1308_dai_link(&links[id]); + break; + default: + dev_err(dev, "invalid amp type %d\n", amp_type); + return NULL; + } - links[id].id = id; - if (sof_ssp_amp_quirk & SOF_RT1308_SPEAKER_AMP_PRESENT) { - sof_rt1308_dai_link(&links[id]); - } else if (sof_ssp_amp_quirk & SOF_CS35L41_SPEAKER_AMP_PRESENT) { - cs35l41_set_dai_link(&links[id]); - } - links[id].platforms = platform_component; - links[id].num_platforms = ARRAY_SIZE(platform_component); - links[id].dpcm_playback = 1; - /* feedback from amplifier or firmware-generated echo reference */ - links[id].dpcm_capture = 1; - links[id].no_pcm = 1; - links[id].cpus = &cpus[id]; - links[id].num_cpus = 1; - links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_codec); - if (!links[id].cpus->dai_name) - return NULL; + links[id].platforms = platform_component; + links[id].num_platforms = ARRAY_SIZE(platform_component); + links[id].dpcm_playback = 1; + /* feedback from amplifier or firmware-generated echo reference */ + links[id].dpcm_capture = 1; + links[id].no_pcm = 1; + links[id].cpus = &cpus[id]; + links[id].num_cpus = 1; + links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_codec); + if (!links[id].cpus->dai_name) + return NULL; - id++; + id++; + } /* dmic */ if (dmic_be_num > 0) { /* at least we have dmic01 */ - links[id].name = "dmic01"; - links[id].cpus = &cpus[id]; - links[id].cpus->dai_name = "DMIC01 Pin"; - if (dmic_be_num > 1) { - /* set up 2 BE links at most */ - links[id + 1].name = "dmic16k"; - links[id + 1].cpus = &cpus[id + 1]; - links[id + 1].cpus->dai_name = "DMIC16k Pin"; - dmic_be_num = 2; - } + be_id = fixed_be ? DMIC01_BE_ID : id; + ret = sof_intel_board_set_dmic_link(dev, &links[id], be_id, + SOF_DMIC_01); + if (ret) + return NULL; + + id++; } - for (i = 0; i < dmic_be_num; i++) { - links[id].id = id; - links[id].num_cpus = 1; - links[id].codecs = dmic_component; - links[id].num_codecs = ARRAY_SIZE(dmic_component); - links[id].platforms = platform_component; - links[id].num_platforms = ARRAY_SIZE(platform_component); - links[id].ignore_suspend = 1; - links[id].dpcm_capture = 1; - links[id].no_pcm = 1; + if (dmic_be_num > 1) { + /* set up 2 BE links at most */ + be_id = fixed_be ? DMIC16K_BE_ID : id; + ret = sof_intel_board_set_dmic_link(dev, &links[id], be_id, + SOF_DMIC_16K); + if (ret) + return NULL; + id++; } /* HDMI playback */ - if (sof_ssp_amp_quirk & SOF_HDMI_PLAYBACK_PRESENT) { - /* HDMI */ - if (hdmi_num > 0) { - idisp_components = devm_kcalloc(dev, - hdmi_num, - sizeof(struct snd_soc_dai_link_component), - GFP_KERNEL); - if (!idisp_components) - goto devm_err; - } - for (i = 1; i <= hdmi_num; i++) { - links[id].name = devm_kasprintf(dev, GFP_KERNEL, - "iDisp%d", i); - if (!links[id].name) - goto devm_err; + for (i = 1; i <= hdmi_num; i++) { + be_id = fixed_be ? (INTEL_HDMI_BE_ID + i - 1) : id; + ret = sof_intel_board_set_intel_hdmi_link(dev, &links[id], be_id, + i, idisp_codec); + if (ret) + return NULL; - links[id].id = id; - links[id].cpus = &cpus[id]; - links[id].num_cpus = 1; - links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, - "iDisp%d Pin", i); - if (!links[id].cpus->dai_name) - goto devm_err; - - if (idisp_codec) { - idisp_components[i - 1].name = "ehdaudio0D2"; - idisp_components[i - 1].dai_name = devm_kasprintf(dev, - GFP_KERNEL, - "intel-hdmi-hifi%d", - i); - if (!idisp_components[i - 1].dai_name) - goto devm_err; - } else { - idisp_components[i - 1] = asoc_dummy_dlc; - } - - links[id].codecs = &idisp_components[i - 1]; - links[id].num_codecs = 1; - links[id].platforms = platform_component; - links[id].num_platforms = ARRAY_SIZE(platform_component); - links[id].init = sof_hdmi_init; - links[id].dpcm_playback = 1; - links[id].no_pcm = 1; - id++; - } + id++; } /* BT audio offload */ @@ -352,7 +233,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port); if (!links[id].name) goto devm_err; - links[id].codecs = &asoc_dummy_dlc; + links[id].codecs = &snd_soc_dummy_dlc; links[id].num_codecs = 1; links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); @@ -370,10 +251,9 @@ devm_err: static int sof_ssp_amp_probe(struct platform_device *pdev) { + struct snd_soc_acpi_mach *mach = pdev->dev.platform_data; struct snd_soc_dai_link *dai_links; - struct snd_soc_acpi_mach *mach; struct sof_card_private *ctx; - int dmic_be_num = 0, hdmi_num = 0; int ret, ssp_codec; ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); @@ -383,49 +263,66 @@ static int sof_ssp_amp_probe(struct platform_device *pdev) if (pdev->id_entry && pdev->id_entry->driver_data) sof_ssp_amp_quirk = (unsigned long)pdev->id_entry->driver_data; - mach = pdev->dev.platform_data; + ctx->amp_type = sof_ssp_detect_amp_type(&pdev->dev); if (dmi_check_system(chromebook_platforms) || mach->mach_params.dmic_num > 0) - dmic_be_num = 2; + ctx->dmic_be_num = 2; + else + ctx->dmic_be_num = 0; ssp_codec = sof_ssp_amp_quirk & SOF_AMPLIFIER_SSP_MASK; /* set number of dai links */ - sof_ssp_amp_card.num_links = 1 + dmic_be_num; + sof_ssp_amp_card.num_links = ctx->dmic_be_num; + + if (ctx->amp_type != CODEC_NONE) + sof_ssp_amp_card.num_links++; if (sof_ssp_amp_quirk & SOF_SSP_HDMI_CAPTURE_PRESENT) sof_ssp_amp_card.num_links += (sof_ssp_amp_quirk & SOF_NO_OF_HDMI_CAPTURE_SSP_MASK) >> SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT; if (sof_ssp_amp_quirk & SOF_HDMI_PLAYBACK_PRESENT) { - hdmi_num = (sof_ssp_amp_quirk & SOF_NO_OF_HDMI_PLAYBACK_MASK) >> + ctx->hdmi_num = (sof_ssp_amp_quirk & SOF_NO_OF_HDMI_PLAYBACK_MASK) >> SOF_NO_OF_HDMI_PLAYBACK_SHIFT; /* default number of HDMI DAI's */ - if (!hdmi_num) - hdmi_num = 3; + if (!ctx->hdmi_num) + ctx->hdmi_num = 3; if (mach->mach_params.codec_mask & IDISP_CODEC_MASK) - ctx->idisp_codec = true; + ctx->hdmi.idisp_codec = true; - sof_ssp_amp_card.num_links += hdmi_num; + sof_ssp_amp_card.num_links += ctx->hdmi_num; + } else { + ctx->hdmi_num = 0; } if (sof_ssp_amp_quirk & SOF_SSP_BT_OFFLOAD_PRESENT) sof_ssp_amp_card.num_links++; - dai_links = sof_card_dai_links_create(&pdev->dev, ssp_codec, dmic_be_num, hdmi_num, ctx->idisp_codec); + dai_links = sof_card_dai_links_create(&pdev->dev, ctx->amp_type, + ssp_codec, ctx->dmic_be_num, + ctx->hdmi_num, + ctx->hdmi.idisp_codec); if (!dai_links) return -ENOMEM; sof_ssp_amp_card.dai_link = dai_links; /* update codec_conf */ - if (sof_ssp_amp_quirk & SOF_CS35L41_SPEAKER_AMP_PRESENT) { + switch (ctx->amp_type) { + case CODEC_CS35L41: cs35l41_set_codec_conf(&sof_ssp_amp_card); + break; + case CODEC_NONE: + case CODEC_RT1308: + /* no codec conf required */ + break; + default: + dev_err(&pdev->dev, "invalid amp type %d\n", ctx->amp_type); + return -EINVAL; } - INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - sof_ssp_amp_card.dev = &pdev->dev; /* set platform name for each dailink */ @@ -434,8 +331,6 @@ static int sof_ssp_amp_probe(struct platform_device *pdev) if (ret) return ret; - ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv; - snd_soc_card_set_drvdata(&sof_ssp_amp_card, ctx); return devm_snd_soc_register_card(&pdev->dev, &sof_ssp_amp_card); @@ -451,8 +346,7 @@ static const struct platform_device_id board_ids[] = { SOF_NO_OF_HDMI_CAPTURE_SSP(2) | SOF_HDMI_CAPTURE_1_SSP(1) | SOF_HDMI_CAPTURE_2_SSP(5) | - SOF_SSP_HDMI_CAPTURE_PRESENT | - SOF_RT1308_SPEAKER_AMP_PRESENT), + SOF_SSP_HDMI_CAPTURE_PRESENT), }, { .name = "adl_cs35l41", @@ -460,8 +354,7 @@ static const struct platform_device_id board_ids[] = { SOF_NO_OF_HDMI_PLAYBACK(4) | SOF_HDMI_PLAYBACK_PRESENT | SOF_BT_OFFLOAD_SSP(2) | - SOF_SSP_BT_OFFLOAD_PRESENT | - SOF_CS35L41_SPEAKER_AMP_PRESENT), + SOF_SSP_BT_OFFLOAD_PRESENT), }, { .name = "adl_lt6911_hdmi_ssp", @@ -481,6 +374,15 @@ static const struct platform_device_id board_ids[] = { SOF_NO_OF_HDMI_PLAYBACK(3) | SOF_HDMI_PLAYBACK_PRESENT), }, + { + .name = "mtl_lt6911_hdmi_ssp", + .driver_data = (kernel_ulong_t)(SOF_NO_OF_HDMI_CAPTURE_SSP(2) | + SOF_HDMI_CAPTURE_1_SSP(0) | + SOF_HDMI_CAPTURE_2_SSP(2) | + SOF_SSP_HDMI_CAPTURE_PRESENT | + SOF_NO_OF_HDMI_PLAYBACK(3) | + SOF_HDMI_PLAYBACK_PRESENT), + }, { } }; MODULE_DEVICE_TABLE(platform, board_ids); @@ -499,6 +401,7 @@ MODULE_DESCRIPTION("ASoC Intel(R) SOF Amplifier Machine driver"); MODULE_AUTHOR("Balamurugan C <balamurugan.c@intel.com>"); MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); +MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS); MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON); MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_CIRRUS_COMMON); +MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_SSP_COMMON); diff --git a/sound/soc/intel/boards/sof_ssp_common.c b/sound/soc/intel/boards/sof_ssp_common.c new file mode 100644 index 0000000000..41a258e45a --- /dev/null +++ b/sound/soc/intel/boards/sof_ssp_common.c @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// Copyright(c) 2023 Intel Corporation. All rights reserved. + +#include <linux/device.h> +#include <sound/soc-acpi.h> +#include "sof_ssp_common.h" + +/* + * Codec probe function + */ +#define CODEC_MAP_ENTRY(n, h, t) \ + { \ + .name = n, \ + .acpi_hid = h, \ + .codec_type = t, \ + } + +struct codec_map { + const char *name; + const char *acpi_hid; + enum sof_ssp_codec codec_type; +}; + +static const struct codec_map codecs[] = { + /* Cirrus Logic */ + CODEC_MAP_ENTRY("CS42L42", CS42L42_ACPI_HID, CODEC_CS42L42), + + /* Dialog */ + CODEC_MAP_ENTRY("DA7219", DA7219_ACPI_HID, CODEC_DA7219), + + /* Everest */ + CODEC_MAP_ENTRY("ES8316", ES8316_ACPI_HID, CODEC_ES8316), + CODEC_MAP_ENTRY("ES8326", ES8326_ACPI_HID, CODEC_ES8326), + CODEC_MAP_ENTRY("ES8336", ES8336_ACPI_HID, CODEC_ES8336), + + /* Nuvoton */ + CODEC_MAP_ENTRY("NAU8825", NAU8825_ACPI_HID, CODEC_NAU8825), + + /* Realtek */ + CODEC_MAP_ENTRY("RT5650", RT5650_ACPI_HID, CODEC_RT5650), + CODEC_MAP_ENTRY("RT5682", RT5682_ACPI_HID, CODEC_RT5682), + CODEC_MAP_ENTRY("RT5682S", RT5682S_ACPI_HID, CODEC_RT5682S), +}; + +static const struct codec_map amps[] = { + /* Cirrus Logic */ + CODEC_MAP_ENTRY("CS35L41", CS35L41_ACPI_HID, CODEC_CS35L41), + + /* Maxim */ + CODEC_MAP_ENTRY("MAX98357A", MAX_98357A_ACPI_HID, CODEC_MAX98357A), + CODEC_MAP_ENTRY("MAX98360A", MAX_98360A_ACPI_HID, CODEC_MAX98360A), + CODEC_MAP_ENTRY("MAX98373", MAX_98373_ACPI_HID, CODEC_MAX98373), + CODEC_MAP_ENTRY("MAX98390", MAX_98390_ACPI_HID, CODEC_MAX98390), + + /* Nuvoton */ + CODEC_MAP_ENTRY("NAU8318", NAU8318_ACPI_HID, CODEC_NAU8318), + + /* Realtek */ + CODEC_MAP_ENTRY("RT1011", RT1011_ACPI_HID, CODEC_RT1011), + CODEC_MAP_ENTRY("RT1015", RT1015_ACPI_HID, CODEC_RT1015), + CODEC_MAP_ENTRY("RT1015P", RT1015P_ACPI_HID, CODEC_RT1015P), + CODEC_MAP_ENTRY("RT1019P", RT1019P_ACPI_HID, CODEC_RT1019P), + CODEC_MAP_ENTRY("RT1308", RT1308_ACPI_HID, CODEC_RT1308), +}; + +enum sof_ssp_codec sof_ssp_detect_codec_type(struct device *dev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(codecs); i++) { + if (!acpi_dev_present(codecs[i].acpi_hid, NULL, -1)) + continue; + + dev_dbg(dev, "codec %s found\n", codecs[i].name); + return codecs[i].codec_type; + } + + return CODEC_NONE; +} +EXPORT_SYMBOL_NS(sof_ssp_detect_codec_type, SND_SOC_INTEL_SOF_SSP_COMMON); + +enum sof_ssp_codec sof_ssp_detect_amp_type(struct device *dev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(amps); i++) { + if (!acpi_dev_present(amps[i].acpi_hid, NULL, -1)) + continue; + + dev_dbg(dev, "amp %s found\n", amps[i].name); + return amps[i].codec_type; + } + + return CODEC_NONE; +} +EXPORT_SYMBOL_NS(sof_ssp_detect_amp_type, SND_SOC_INTEL_SOF_SSP_COMMON); + +MODULE_DESCRIPTION("ASoC Intel SOF Common Machine Driver Helpers"); +MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/intel/boards/sof_ssp_common.h b/sound/soc/intel/boards/sof_ssp_common.h new file mode 100644 index 0000000000..e3fd6fb1db --- /dev/null +++ b/sound/soc/intel/boards/sof_ssp_common.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright(c) 2023 Intel Corporation. + */ + +#ifndef __SOF_SSP_COMMON_H +#define __SOF_SSP_COMMON_H + +/* Cirrus Logic */ +#define CS35L41_ACPI_HID "CSC3541" +#define CS42L42_ACPI_HID "10134242" + +/* Dialog */ +#define DA7219_ACPI_HID "DLGS7219" + +/* Everest */ +#define ES8316_ACPI_HID "ESSX8316" +#define ES8326_ACPI_HID "ESSX8326" +#define ES8336_ACPI_HID "ESSX8336" + +#define MAX_98357A_ACPI_HID "MX98357A" +#define MAX_98360A_ACPI_HID "MX98360A" +#define MAX_98373_ACPI_HID "MX98373" +#define MAX_98390_ACPI_HID "MX98390" + +/* Nuvoton */ +#define NAU8318_ACPI_HID "NVTN2012" +#define NAU8825_ACPI_HID "10508825" + +/* Realtek */ +#define RT1011_ACPI_HID "10EC1011" +#define RT1015_ACPI_HID "10EC1015" +#define RT1015P_ACPI_HID "RTL1015" +#define RT1019P_ACPI_HID "RTL1019" +#define RT1308_ACPI_HID "10EC1308" +#define RT5650_ACPI_HID "10EC5650" +#define RT5682_ACPI_HID "10EC5682" +#define RT5682S_ACPI_HID "RTL5682" + +enum sof_ssp_codec { + CODEC_NONE, + + /* headphone codec */ + CODEC_CS42L42, + CODEC_DA7219, + CODEC_ES8316, + CODEC_ES8326, + CODEC_ES8336, + CODEC_NAU8825, + CODEC_RT5650, + CODEC_RT5682, + CODEC_RT5682S, + + /* speaker amplifier */ + CODEC_CS35L41, + CODEC_MAX98357A, + CODEC_MAX98360A, + CODEC_MAX98373, + CODEC_MAX98390, + CODEC_NAU8318, + CODEC_RT1011, + CODEC_RT1015, + CODEC_RT1015P, + CODEC_RT1019P, + CODEC_RT1308, +}; + +enum sof_ssp_codec sof_ssp_detect_codec_type(struct device *dev); +enum sof_ssp_codec sof_ssp_detect_amp_type(struct device *dev); + +#endif /* __SOF_SSP_COMMON_H */ diff --git a/sound/soc/intel/boards/sof_wm8804.c b/sound/soc/intel/boards/sof_wm8804.c index 17224d26d9..4cb0d463bf 100644 --- a/sound/soc/intel/boards/sof_wm8804.c +++ b/sound/soc/intel/boards/sof_wm8804.c @@ -49,9 +49,9 @@ static const struct dmi_system_id sof_wm8804_quirk_table[] = { static int sof_wm8804_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_component *codec = codec_dai->component; const int sysclk = 27000000; /* This is fixed on this board */ int samplerate; diff --git a/sound/soc/intel/catpt/pcm.c b/sound/soc/intel/catpt/pcm.c index f1a5cb825f..3daf5eb37f 100644 --- a/sound/soc/intel/catpt/pcm.c +++ b/sound/soc/intel/catpt/pcm.c @@ -74,8 +74,8 @@ static struct catpt_stream_template *catpt_topology[] = { static struct catpt_stream_template * catpt_get_stream_template(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtm = asoc_substream_to_rtd(substream); - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtm, 0); + struct snd_soc_pcm_runtime *rtm = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtm, 0); enum catpt_stream_type type; type = cpu_dai->driver->id; @@ -593,7 +593,7 @@ static int catpt_component_pcm_construct(struct snd_soc_component *component, static int catpt_component_open(struct snd_soc_component *component, struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtm = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtm = snd_soc_substream_to_rtd(substream); if (!rtm->dai_link->no_pcm) snd_soc_set_runtime_hwparams(substream, &catpt_pcm_hardware); @@ -604,8 +604,8 @@ static snd_pcm_uframes_t catpt_component_pointer(struct snd_soc_component *component, struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtm = asoc_substream_to_rtd(substream); - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtm, 0); + struct snd_soc_pcm_runtime *rtm = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtm, 0); struct catpt_stream_runtime *stream; struct catpt_dev *cdev = dev_get_drvdata(component->dev); u32 pos; @@ -631,7 +631,7 @@ static const struct snd_soc_dai_ops catpt_fe_dai_ops = { static int catpt_dai_pcm_new(struct snd_soc_pcm_runtime *rtm, struct snd_soc_dai *dai) { - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtm, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtm, 0); struct catpt_ssp_device_format devfmt; struct catpt_dev *cdev = dev_get_drvdata(dai->dev); int ret; diff --git a/sound/soc/intel/common/Makefile b/sound/soc/intel/common/Makefile index 07aa37dd90..f7370e5b4e 100644 --- a/sound/soc/intel/common/Makefile +++ b/sound/soc/intel/common/Makefile @@ -10,6 +10,7 @@ snd-soc-acpi-intel-match-objs := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-m soc-acpi-intel-tgl-match.o soc-acpi-intel-ehl-match.o \ soc-acpi-intel-jsl-match.o soc-acpi-intel-adl-match.o \ soc-acpi-intel-rpl-match.o soc-acpi-intel-mtl-match.o \ + soc-acpi-intel-arl-match.o \ soc-acpi-intel-lnl-match.o \ soc-acpi-intel-hda-match.o \ soc-acpi-intel-sdw-mockup-match.o diff --git a/sound/soc/intel/common/soc-acpi-intel-adl-match.c b/sound/soc/intel/common/soc-acpi-intel-adl-match.c index 5103e75ac8..6e712ad954 100644 --- a/sound/soc/intel/common/soc-acpi-intel-adl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-adl-match.c @@ -492,6 +492,11 @@ static const struct snd_soc_acpi_codecs adl_nau8318_amp = { .codecs = {"NVTN2012"} }; +static struct snd_soc_acpi_codecs adl_rt5650_amp = { + .num_codecs = 1, + .codecs = {"10EC5650"} +}; + struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = { { .comp_ids = &adl_rt5682_rt5682s_hp, @@ -602,6 +607,20 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = { SND_SOC_ACPI_TPLG_INTEL_SSP_MSB | SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER, }, + { + .id = "10EC5650", + .drv_name = "adl_rt5650", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &adl_rt5650_amp, + .sof_tplg_filename = "sof-adl-rt5650.tplg", + }, + { + .id = "DLGS7219", + .drv_name = "adl_mx98360_da7219", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &adl_max98360a_amp, + .sof_tplg_filename = "sof-adl-max98360a-da7219.tplg", + }, /* place amp-only boards in the end of table */ { .id = "CSC3541", diff --git a/sound/soc/intel/common/soc-acpi-intel-arl-match.c b/sound/soc/intel/common/soc-acpi-intel-arl-match.c new file mode 100644 index 0000000000..e52797aae6 --- /dev/null +++ b/sound/soc/intel/common/soc-acpi-intel-arl-match.c @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * soc-apci-intel-arl-match.c - tables and support for ARL ACPI enumeration. + * + * Copyright (c) 2023 Intel Corporation. + */ + +#include <sound/soc-acpi.h> +#include <sound/soc-acpi-intel-match.h> + +static const struct snd_soc_acpi_endpoint single_endpoint = { + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, +}; + +static const struct snd_soc_acpi_adr_device rt711_0_adr[] = { + { + .adr = 0x000020025D071100ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt711" + } +}; + +static const struct snd_soc_acpi_link_adr arl_rvp[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt711_0_adr), + .adr_d = rt711_0_adr, + }, + {} +}; + +struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_machines[] = { + {}, +}; +EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_arl_machines); + +/* this table is used when there is no I2S codec present */ +struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_sdw_machines[] = { + { + .link_mask = 0x1, /* link0 required */ + .links = arl_rvp, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-arl-rt711.tplg", + }, + {}, +}; +EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_arl_sdw_machines); diff --git a/sound/soc/intel/common/soc-acpi-intel-jsl-match.c b/sound/soc/intel/common/soc-acpi-intel-jsl-match.c index f56bd7d656..342bbbb48c 100644 --- a/sound/soc/intel/common/soc-acpi-intel-jsl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-jsl-match.c @@ -14,7 +14,7 @@ static const struct snd_soc_acpi_codecs essx_83x6 = { .codecs = { "ESSX8316", "ESSX8326", "ESSX8336"}, }; -static const struct snd_soc_acpi_codecs jsl_7219_98373_codecs = { +static const struct snd_soc_acpi_codecs mx98373_spk = { .num_codecs = 1, .codecs = {"MX98373"} }; @@ -52,14 +52,16 @@ static const struct snd_soc_acpi_codecs rt5682_rt5682s_hp = { struct snd_soc_acpi_mach snd_soc_acpi_intel_jsl_machines[] = { { .id = "DLGS7219", - .drv_name = "sof_da7219_mx98373", - .sof_tplg_filename = "sof-jsl-da7219.tplg", + .drv_name = "jsl_mx98373_da7219", .machine_quirk = snd_soc_acpi_codec_list, - .quirk_data = &jsl_7219_98373_codecs, + .quirk_data = &mx98373_spk, + .sof_tplg_filename = "sof-jsl-da7219.tplg", }, { .id = "DLGS7219", - .drv_name = "sof_da7219_mx98360a", + .drv_name = "jsl_mx98360_da7219", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &mx98360a_spk, .sof_tplg_filename = "sof-jsl-da7219-mx98360a.tplg", }, { diff --git a/sound/soc/intel/common/soc-acpi-intel-mtl-match.c b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c index 92498d1d6c..9008b67682 100644 --- a/sound/soc/intel/common/soc-acpi-intel-mtl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c @@ -77,6 +77,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_machines[] = { SND_SOC_ACPI_TPLG_INTEL_SSP_MSB | SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER, }, + /* place amp-only boards in the end of table */ + { + .id = "INTC10B0", + .drv_name = "mtl_lt6911_hdmi_ssp", + .sof_tplg_filename = "sof-mtl-hdmi-ssp02.tplg", + }, {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_mtl_machines); @@ -117,6 +123,20 @@ static const struct snd_soc_acpi_endpoint rt712_endpoints[] = { }, }; +static const struct snd_soc_acpi_endpoint spk_2_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 2, + .group_id = 1, +}; + +static const struct snd_soc_acpi_endpoint spk_3_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 3, + .group_id = 1, +}; + static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = { { .adr = 0x000030025D071101ull, @@ -144,6 +164,24 @@ static const struct snd_soc_acpi_adr_device rt1712_3_single_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt713_0_single_adr[] = { + { + .adr = 0x000031025D071301ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt713" + } +}; + +static const struct snd_soc_acpi_adr_device rt1713_3_single_adr[] = { + { + .adr = 0x000331025D171301ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt713-dmic" + } +}; + static const struct snd_soc_acpi_adr_device mx8373_0_adr[] = { { .adr = 0x000023019F837300ull, @@ -186,6 +224,24 @@ static const struct snd_soc_acpi_adr_device rt1316_3_group1_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt1316_1_group2_adr[] = { + { + .adr = 0x000131025D131601ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "rt1316-1" + } +}; + +static const struct snd_soc_acpi_adr_device rt1316_2_group2_adr[] = { + { + .adr = 0x000230025D131601ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "rt1316-2" + } +}; + static const struct snd_soc_acpi_adr_device rt1318_1_group1_adr[] = { { .adr = 0x000130025D131801ull, @@ -236,6 +292,45 @@ static const struct snd_soc_acpi_link_adr mtl_712_only[] = { {} }; +static const struct snd_soc_acpi_adr_device cs42l43_0_adr[] = { + { + .adr = 0x00003001FA424301ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "cs42l43" + } +}; + +static const struct snd_soc_acpi_adr_device cs35l56_1_adr[] = { + { + .adr = 0x00013701FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "AMP8" + }, + { + .adr = 0x00013601FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_3_endpoint, + .name_prefix = "AMP7" + } +}; + +static const struct snd_soc_acpi_adr_device cs35l56_2_adr[] = { + { + .adr = 0x00023301FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "AMP1" + }, + { + .adr = 0x00023201FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_2_endpoint, + .name_prefix = "AMP2" + } +}; + static const struct snd_soc_acpi_link_adr rt5682_link2_max98373_link0[] = { /* Expected order: jack -> amp */ { @@ -303,6 +398,30 @@ static const struct snd_soc_acpi_link_adr mtl_sdw_rt1318_l12_rt714_l0[] = { {} }; +static const struct snd_soc_acpi_link_adr mtl_rt713_l0_rt1316_l12_rt1713_l3[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt713_0_single_adr), + .adr_d = rt713_0_single_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1316_1_group2_adr), + .adr_d = rt1316_1_group2_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt1316_2_group2_adr), + .adr_d = rt1316_2_group2_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt1713_3_single_adr), + .adr_d = rt1713_3_single_adr, + }, + {} +}; + static const struct snd_soc_acpi_adr_device mx8363_2_adr[] = { { .adr = 0x000230019F836300ull, @@ -342,6 +461,25 @@ static const struct snd_soc_acpi_link_adr cs42l42_link0_max98363_link2[] = { {} }; +static const struct snd_soc_acpi_link_adr mtl_cs42l43_cs35l56[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs42l43_0_adr), + .adr_d = cs42l43_0_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(cs35l56_1_adr), + .adr_d = cs35l56_1_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(cs35l56_2_adr), + .adr_d = cs35l56_2_adr, + }, + {} +}; + /* this table is used when there is no I2S codec present */ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = { /* mockup tests need to be first */ @@ -364,6 +502,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = { .sof_tplg_filename = "sof-mtl-rt715-rt711-rt1308-mono.tplg", }, { + .link_mask = GENMASK(3, 0), + .links = mtl_rt713_l0_rt1316_l12_rt1713_l3, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-mtl-rt713-l0-rt1316-l12-rt1713-l3.tplg", + }, + { .link_mask = BIT(3) | BIT(0), .links = mtl_712_only, .drv_name = "sof_sdw", @@ -376,6 +520,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = { .sof_tplg_filename = "sof-mtl-rt1318-l12-rt714-l0.tplg" }, { + .link_mask = GENMASK(2, 0), + .links = mtl_cs42l43_cs35l56, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-mtl-cs42l43-l0-cs35l56-l12.tplg", + }, + { .link_mask = GENMASK(3, 0), .links = mtl_3_in_1_sdca, .drv_name = "sof_sdw", diff --git a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c index 122673c1da..5b6f57e3a5 100644 --- a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c @@ -246,6 +246,25 @@ static const struct snd_soc_acpi_link_adr rpl_sdw_rt711_link2_rt1316_link01[] = {} }; +static const struct snd_soc_acpi_link_adr rpl_sdw_rt711_link0_rt1316_link12[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt711_sdca_0_adr), + .adr_d = rt711_sdca_0_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1316_1_group1_adr), + .adr_d = rt1316_1_group1_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt1316_2_group1_adr), + .adr_d = rt1316_2_group1_adr, + }, + {} +}; + static const struct snd_soc_acpi_link_adr rpl_sdw_rt711_link0_rt1318_link12_rt714_link3[] = { { .mask = BIT(0), @@ -390,6 +409,13 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_machines[] = { }, { .id = "10508825", + .drv_name = "rpl_mx98360a_8825", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &rpl_max98360a_amp, + .sof_tplg_filename = "sof-rpl-max98360a-nau8825.tplg", + }, + { + .id = "10508825", .drv_name = "rpl_nau8318_8825", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &rpl_nau8318_amp, @@ -403,6 +429,13 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_machines[] = { .sof_tplg_filename = "sof-rpl-rt1019-rt5682.tplg", }, { + .comp_ids = &rpl_rt5682_hp, + .drv_name = "rpl_rt5682_c1_h02", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &rpl_lt6911_hdmi, + .sof_tplg_filename = "sof-rpl-rt5682-ssp1-hdmi-ssp02.tplg", + }, + { .comp_ids = &rpl_essx_83x6, .drv_name = "rpl_es83x6_c1_h02", .machine_quirk = snd_soc_acpi_codec_list, @@ -453,6 +486,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_sdw_machines[] = { .sof_tplg_filename = "sof-rpl-rt711-l0-rt1318-l12-rt714-l3.tplg", }, { + .link_mask = 0x7, /* rt711 on link0 & two rt1316s on link1 and link2 */ + .links = rpl_sdw_rt711_link0_rt1316_link12, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-rpl-rt711-l0-rt1316-l12.tplg", + }, + { .link_mask = 0x7, /* rt711 on link0 & two rt1318s on link1 and link2 */ .links = rpl_sdw_rt711_link0_rt1318_link12, .drv_name = "sof_sdw", diff --git a/sound/soc/intel/keembay/kmb_platform.c b/sound/soc/intel/keembay/kmb_platform.c index 6b06b7b5ed..37ea2e1d2e 100644 --- a/sound/soc/intel/keembay/kmb_platform.c +++ b/sound/soc/intel/keembay/kmb_platform.c @@ -11,7 +11,6 @@ #include <linux/io.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <sound/dmaengine_pcm.h> #include <sound/pcm.h> #include <sound/pcm_params.h> @@ -252,10 +251,10 @@ static int kmb_pcm_open(struct snd_soc_component *component, struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct kmb_i2s_info *kmb_i2s; - kmb_i2s = snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); + kmb_i2s = snd_soc_dai_get_drvdata(snd_soc_rtd_to_cpu(rtd, 0)); snd_soc_set_runtime_hwparams(substream, &kmb_pcm_hardware); snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); runtime->private_data = kmb_i2s; @@ -820,7 +819,6 @@ static int kmb_plat_dai_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct snd_soc_dai_driver *kmb_i2s_dai; - const struct of_device_id *match; struct device *dev = &pdev->dev; struct kmb_i2s_info *kmb_i2s; struct resource *res; @@ -831,16 +829,7 @@ static int kmb_plat_dai_probe(struct platform_device *pdev) if (!kmb_i2s) return -ENOMEM; - kmb_i2s_dai = devm_kzalloc(dev, sizeof(*kmb_i2s_dai), GFP_KERNEL); - if (!kmb_i2s_dai) - return -ENOMEM; - - match = of_match_device(kmb_plat_of_match, &pdev->dev); - if (!match) { - dev_err(&pdev->dev, "Error: No device match found\n"); - return -ENODEV; - } - kmb_i2s_dai = (struct snd_soc_dai_driver *) match->data; + kmb_i2s_dai = (struct snd_soc_dai_driver *)device_get_match_data(&pdev->dev); /* Prepare the related clocks */ kmb_i2s->clk_apb = devm_clk_get(dev, "apb_clk"); diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index c602275fcf..174aae6e03 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c @@ -124,7 +124,6 @@ static void skl_set_suspend_active(struct snd_pcm_substream *substream, int skl_pcm_host_dma_prepare(struct device *dev, struct skl_pipe_params *params) { struct hdac_bus *bus = dev_get_drvdata(dev); - struct skl_dev *skl = bus_to_skl(bus); unsigned int format_val; struct hdac_stream *hstream; struct hdac_ext_stream *stream; @@ -149,18 +148,7 @@ int skl_pcm_host_dma_prepare(struct device *dev, struct skl_pipe_params *params) if (err < 0) return err; - /* - * The recommended SDxFMT programming sequence for BXT - * platforms is to couple the stream before writing the format - */ - if (HDA_CONTROLLER_IS_APL(skl->pci)) { - snd_hdac_ext_stream_decouple(bus, stream, false); - err = snd_hdac_stream_setup(hdac_stream(stream)); - snd_hdac_ext_stream_decouple(bus, stream, true); - } else { - err = snd_hdac_stream_setup(hdac_stream(stream)); - } - + err = snd_hdac_ext_host_stream_setup(stream, false); if (err < 0) return err; @@ -520,6 +508,9 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd, return ret; ret = skl_decoupled_trigger(substream, cmd); + if (ret < 0) + return ret; + if ((cmd == SNDRV_PCM_TRIGGER_SUSPEND) && !w->ignore_suspend) { /* save the dpib and lpib positions */ hstream->dpib = readl(bus->remap_addr + @@ -547,8 +538,8 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream, { struct hdac_bus *bus = dev_get_drvdata(dai->dev); struct hdac_ext_stream *link_dev; - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct skl_pipe_params p_params = {0}; struct hdac_ext_link *link; int stream_tag; @@ -635,7 +626,7 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct hdac_bus *bus = dev_get_drvdata(dai->dev); - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct hdac_ext_stream *link_dev = snd_soc_dai_get_dma_data(dai, substream); struct hdac_ext_link *link; @@ -645,7 +636,7 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream, link_dev->link_prepared = 0; - link = snd_hdac_ext_bus_get_hlink_by_name(bus, asoc_rtd_to_codec(rtd, 0)->component->name); + link = snd_hdac_ext_bus_get_hlink_by_name(bus, snd_soc_rtd_to_codec(rtd, 0)->component->name); if (!link) return -EINVAL; @@ -1072,10 +1063,10 @@ int skl_dai_load(struct snd_soc_component *cmp, int index, static int skl_platform_soc_open(struct snd_soc_component *component, struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai_link *dai_link = rtd->dai_link; - dev_dbg(asoc_rtd_to_cpu(rtd, 0)->dev, "In %s:%s\n", __func__, + dev_dbg(snd_soc_rtd_to_cpu(rtd, 0)->dev, "In %s:%s\n", __func__, dai_link->cpus->dai_name); snd_soc_set_runtime_hwparams(substream, &azx_pcm_hw); @@ -1219,8 +1210,8 @@ static snd_pcm_uframes_t skl_platform_soc_pointer( static u64 skl_adjust_codec_delay(struct snd_pcm_substream *substream, u64 nsec) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); u64 codec_frames, codec_nsecs; if (!codec_dai->driver->ops->delay) @@ -1274,7 +1265,7 @@ static int skl_platform_soc_get_time_info( static int skl_platform_soc_new(struct snd_soc_component *component, struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0); struct hdac_bus *bus = dev_get_drvdata(dai->dev); struct snd_pcm *pcm = rtd->pcm; unsigned int size; diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 77408a981b..1171251877 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -736,6 +736,7 @@ static int probe_codec(struct hdac_bus *bus, int addr) return PTR_ERR(codec); hda_codec->codec = codec; + hda_codec->dev_index = addr; dev_set_drvdata(&codec->core.dev, hda_codec); /* use legacy bus only for HDA codecs, idisp uses ext bus */ @@ -783,23 +784,6 @@ static void skl_codec_create(struct hdac_bus *bus) } } -static int skl_i915_init(struct hdac_bus *bus) -{ - int err; - - /* - * The HDMI codec is in GPU so we need to ensure that it is powered - * up and ready for probe - */ - err = snd_hdac_i915_init(bus); - if (err < 0) - return err; - - snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, true); - - return 0; -} - static void skl_probe_work(struct work_struct *work) { struct skl_dev *skl = container_of(work, struct skl_dev, probe_work); @@ -807,11 +791,8 @@ static void skl_probe_work(struct work_struct *work) struct hdac_ext_link *hlink; int err; - if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { - err = skl_i915_init(bus); - if (err < 0) - return; - } + if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) + snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, true); skl_init_pci(skl); skl_dum_set(bus); @@ -1075,10 +1056,17 @@ static int skl_probe(struct pci_dev *pci, goto out_dsp_free; } + if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { + err = snd_hdac_i915_init(bus); + if (err < 0) + goto out_dmic_unregister; + } schedule_work(&skl->probe_work); return 0; +out_dmic_unregister: + skl_dmic_device_unregister(skl); out_dsp_free: skl_free_dsp(skl); out_clk_free: |