From b1a518fe4bb911c73d6f63d9deadf6928d630568 Mon Sep 17 00:00:00 2001 From: Venkata Prasad Potturu Date: Mon, 27 Feb 2023 16:22:04 +0530 Subject: ASOC: amd: acp: Add machine driver support for Maxim max98388 codec Add Max98388 codec support in machine driver as amp codec. Signed-off-by: Venkata Prasad Potturu --- sound/soc/amd/acp-config.c | 14 +++++ sound/soc/amd/acp/acp-mach-common.c | 101 ++++++++++++++++++++++++++++++++++++ sound/soc/amd/acp/acp-mach.h | 1 + sound/soc/amd/acp/acp-sof-mach.c | 19 ++++++- 4 files changed, 133 insertions(+), 2 deletions(-) diff --git a/sound/soc/amd/acp-config.c b/sound/soc/amd/acp-config.c index a1c4fd4ce9be..befd1ad20e4c 100644 --- a/sound/soc/amd/acp-config.c +++ b/sound/soc/amd/acp-config.c @@ -91,6 +91,11 @@ static struct snd_soc_acpi_codecs amp_cs35l41 = { .codecs = {"CLSA3541"} }; +static struct snd_soc_acpi_codecs amp_max98388 = { + .num_codecs = 1, + .codecs = {"ADS8388"} +}; + struct snd_soc_acpi_mach snd_soc_acpi_amd_sof_machines[] = { { .id = "10EC5682", @@ -156,6 +161,15 @@ struct snd_soc_acpi_mach snd_soc_acpi_amd_vgh_sof_machines[] = { .fw_filename = "sof-vgh.ri", .sof_tplg_filename = "sof-acp-vgh.tplg", }, + { + .id = "AMDI0010", + .drv_name = "nau8821-max", + .pdata = &acp_quirk_data, + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &_max98388, + .fw_filename = "sof-vangogh.ri", + .sof_tplg_filename = "sof-vgh-nau8821-cs35l41.tplg", + }, {}, }; EXPORT_SYMBOL(snd_soc_acpi_amd_vgh_sof_machines); diff --git a/sound/soc/amd/acp/acp-mach-common.c b/sound/soc/amd/acp/acp-mach-common.c index bc7bf76754ff..d96b0b3fcbaa 100644 --- a/sound/soc/amd/acp/acp-mach-common.c +++ b/sound/soc/amd/acp/acp-mach-common.c @@ -36,6 +36,8 @@ static struct snd_soc_jack vg_headset; #define DUAL_CHANNEL 2 #define FOUR_CHANNEL 4 +#define ACP5X_ADI_CODEC_DAI "max98388-aif1" + #define TDM_MODE_ENABLE 1 const struct dmi_system_id acp_quirk_table[] = { @@ -665,6 +667,97 @@ static const struct snd_soc_ops acp_card_maxim_ops = { .hw_params = acp_card_maxim_hw_params, }; +SND_SOC_DAILINK_DEF(max98388, + DAILINK_COMP_ARRAY(COMP_CODEC("i2c-ADS8388:00", "max98388-aif1"), + COMP_CODEC("i2c-ADS8388:01", "max98388-aif1"))); + +static const struct snd_soc_dapm_widget max98388_widgets[] = { + SND_SOC_DAPM_SPK("SPK", NULL), +}; + +static const struct snd_soc_dapm_route max98388_map[] = { + { "SPK", NULL, "Left BE_OUT" }, + { "SPK", NULL, "Right BE_OUT" }, +}; + +static struct snd_soc_codec_conf max98388_conf[] = { + { + .dlc = COMP_CODEC_CONF("i2c-ADS8388:00"), + .name_prefix = "Left", + }, + { + .dlc = COMP_CODEC_CONF("i2c-ADS8388:01"), + .name_prefix = "Right", + }, +}; + +static const unsigned int acp5x_max98388_format[] = {16}; + +static struct snd_pcm_hw_constraint_list constraints_sample_bits_max = { + .list = acp5x_max98388_format, + .count = ARRAY_SIZE(acp5x_max98388_format), +}; + +static int acp_card_max98388_startup(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + + runtime->hw.channels_max = DUAL_CHANNEL; + snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, + &constraints_channels); + snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, + &constraints_rates); + snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, + &constraints_sample_bits_max); + + return 0; +} + +static int acp_card_max98388_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + struct acp_card_drvdata *drvdata = card->drvdata; + int ret; + + if (drvdata->amp_codec_id != MAX98388) + return -EINVAL; + + ret = snd_soc_dapm_new_controls(&card->dapm, max98388_widgets, + ARRAY_SIZE(max98388_widgets)); + + if (ret) { + dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret); + /* Don't need to add routes if widget addition failed */ + return ret; + } + return snd_soc_dapm_add_routes(&rtd->card->dapm, max98388_map, + ARRAY_SIZE(max98388_map)); +} + +static int acp_max98388_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + struct snd_soc_dai *codec_dai = + snd_soc_card_get_codec_dai(card, + ACP5X_ADI_CODEC_DAI); + int ret; + + ret = snd_soc_dai_set_fmt(codec_dai, + SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF); + if (ret < 0) + return ret; + + return ret; +} + +static const struct snd_soc_ops acp_card_max98388_ops = { + .startup = acp_card_max98388_startup, + .hw_params = acp_max98388_hw_params, +}; + /* Declare nau8825 codec components */ SND_SOC_DAILINK_DEF(nau8825, DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10508825:00", "nau8825-hifi"))); @@ -1203,6 +1296,14 @@ int acp_sofdsp_dai_links_create(struct snd_soc_card *card) links[i].ops = &acp_card_maxim_ops; links[i].init = acp_card_maxim_init; } + if (drv_data->amp_codec_id == MAX98388) { + links[i].codecs = max98388; + links[i].num_codecs = ARRAY_SIZE(max98388); + links[i].ops = &acp_card_max98388_ops; + links[i].init = acp_card_max98388_init; + card->codec_conf = max98388_conf; + card->num_configs = ARRAY_SIZE(max98388_conf); + } if (drv_data->amp_codec_id == RT1019) { links[i].codecs = rt1019; links[i].num_codecs = ARRAY_SIZE(rt1019); diff --git a/sound/soc/amd/acp/acp-mach.h b/sound/soc/amd/acp/acp-mach.h index 1fd9bdb047a3..df6740c78f7e 100644 --- a/sound/soc/amd/acp/acp-mach.h +++ b/sound/soc/amd/acp/acp-mach.h @@ -43,6 +43,7 @@ enum codec_endpoints { NAU8825, NAU8821, CS35L41, + MAX98388, }; enum platform_end_point { diff --git a/sound/soc/amd/acp/acp-sof-mach.c b/sound/soc/amd/acp/acp-sof-mach.c index d6c465624acd..a9f44c8314ee 100644 --- a/sound/soc/amd/acp/acp-sof-mach.c +++ b/sound/soc/amd/acp/acp-sof-mach.c @@ -86,10 +86,21 @@ static struct acp_card_drvdata sof_rt5682s_hs_rt1019_data = { static struct acp_card_drvdata sof_nau8821_hs_cs35l41_data = { .hs_cpu_id = I2S_SP, .amp_cpu_id = I2S_HS, - .dmic_cpu_id = DMIC, + .dmic_cpu_id = NONE, .hs_codec_id = NAU8821, .amp_codec_id = CS35L41, - .dmic_codec_id = DMIC, + .dmic_codec_id = NONE, + .soc_mclk = true, + .tdm_mode = false, +}; + +static struct acp_card_drvdata sof_nau8821_max_data = { + .hs_cpu_id = I2S_SP, + .amp_cpu_id = I2S_HS, + .dmic_cpu_id = NONE, + .hs_codec_id = NAU8821, + .amp_codec_id = MAX98388, + .dmic_codec_id = NONE, .soc_mclk = true, .tdm_mode = false, }; @@ -181,6 +192,10 @@ static const struct platform_device_id board_ids[] = { .name = "nau8821-cs3", .driver_data = (kernel_ulong_t)&sof_nau8821_hs_cs35l41_data }, + { + .name = "nau8821-max", + .driver_data = (kernel_ulong_t)&sof_nau8821_max_data + }, { } }; static struct platform_driver acp_asoc_audio = { -- cgit 1.4.1