From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on sa.local.altlinux.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.1 From: nickel@altlinux.org To: devel-kernel@lists.altlinux.org Date: Wed, 5 Apr 2023 19:59:40 +0300 Message-Id: <20230405165943.267637-2-nickel@altlinux.org> X-Mailer: git-send-email 2.33.7 In-Reply-To: <20230405165943.267637-1-nickel@altlinux.org> References: <20230405165943.267637-1-nickel@altlinux.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Cc: Vasiliy Kovalev Subject: [d-kernel] [PATCH 1/4] ASoC: AMD: add ACP machine driver for ES8336 X-BeenThere: devel-kernel@lists.altlinux.org X-Mailman-Version: 2.1.12 Precedence: list Reply-To: ALT Linux kernel packages development List-Id: ALT Linux kernel packages development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 05 Apr 2023 17:00:10 -0000 Archived-At: List-Archive: List-Post: From: Vasiliy Kovalev Backport from 6.1.3 Based on commit 6976fc0fea0dcc5a367580cd7edf94574601837e from fork of Marian Postevca aka @codepayne Link: https://github.com/thesofproject/linux/issues/3249#issuecomment-1378025039 Link: https://github.com/codepayne/linux-sound-huawei/issues/5 fix conflict use pci-acp driver for ES8336 codec (kovalev) For a family of machines whose pci revision ID is 0x1 (renoir), working with the es8336 codec is only available through the snd-pci-acp3x driver (raven). Now we will use a specific driver if there is an acpi device detected as "ESSX8336" in the machine. Signed-off-by: Vasiliy Kovalev Signed-off-by: Nikolai Kostrigin --- config | 1 + sound/soc/amd/Kconfig | 13 ++ sound/soc/amd/Makefile | 2 + sound/soc/amd/acp3x-es8336.c | 395 ++++++++++++++++++++++++++++++++ sound/soc/amd/raven/pci-acp3x.c | 7 +- sound/soc/codecs/es8316.c | 85 +++++-- 6 files changed, 476 insertions(+), 27 deletions(-) create mode 100644 sound/soc/amd/acp3x-es8336.c diff --git a/config b/config index 7a9be2c8203ff..61e6930c3b532 100644 --- a/config +++ b/config @@ -6833,6 +6833,7 @@ CONFIG_SND_SOC_AMD_CZ_DA7219MX98357_MACH=m CONFIG_SND_SOC_AMD_CZ_RT5645_MACH=m CONFIG_SND_SOC_AMD_ST_ES8336_MACH=m CONFIG_SND_SOC_AMD_ACP3x=m +CONFIG_SND_SOC_AMD_ACP3x_ES8336_MACH=m CONFIG_SND_SOC_AMD_RV_RT5682_MACH=m CONFIG_SND_SOC_AMD_RENOIR=m CONFIG_SND_SOC_AMD_RENOIR_MACH=m diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig index 150786279257d..605e332cb6f30 100644 --- a/sound/soc/amd/Kconfig +++ b/sound/soc/amd/Kconfig @@ -41,6 +41,19 @@ config SND_SOC_AMD_ACP3x help This option enables ACP v3.x I2S support on AMD platform +config SND_SOC_AMD_ACP3x_ES8336_MACH + tristate "AMD ACP3x support for ES8336" + select SND_SOC_ACPI if ACPI + select SND_SOC_ES8316 + depends on ACPI + depends on I2C + depends on SND_SOC_AMD_ACP3x + help + This option enables machine driver for ACP3x platform + using es8336 codec. + Say m if you have such a device. + If unsure select "N". + config SND_SOC_AMD_RV_RT5682_MACH tristate "AMD RV support for RT5682" select CLK_FIXED_FCH diff --git a/sound/soc/amd/Makefile b/sound/soc/amd/Makefile index 82e1cf864a409..959b3439b03dc 100644 --- a/sound/soc/amd/Makefile +++ b/sound/soc/amd/Makefile @@ -5,6 +5,7 @@ snd-soc-acp-rt5645-mach-objs := acp-rt5645.o snd-soc-acp-es8336-mach-objs := acp-es8336.o snd-soc-acp-rt5682-mach-objs := acp3x-rt5682-max9836.o snd-acp-config-objs := acp-config.o +snd-soc-acp3x-es8336-mach-objs := acp3x-es8336.o obj-$(CONFIG_SND_SOC_AMD_ACP) += acp_audio_dma.o obj-$(CONFIG_SND_SOC_AMD_CZ_DA7219MX98357_MACH) += snd-soc-acp-da7219mx98357-mach.o @@ -19,3 +20,4 @@ obj-$(CONFIG_SND_SOC_AMD_ACP_COMMON) += acp/ obj-$(CONFIG_SND_AMD_ACP_CONFIG) += snd-acp-config.o obj-$(CONFIG_SND_SOC_AMD_RPL_ACP6x) += rpl/ obj-$(CONFIG_SND_SOC_AMD_PS) += ps/ +obj-$(CONFIG_SND_SOC_AMD_ACP3x_ES8336_MACH) += snd-soc-acp3x-es8336-mach.o diff --git a/sound/soc/amd/acp3x-es8336.c b/sound/soc/amd/acp3x-es8336.c new file mode 100644 index 0000000000000..fd23afa50eb52 --- /dev/null +++ b/sound/soc/amd/acp3x-es8336.c @@ -0,0 +1,395 @@ +// SPDX-License-Identifier: GPL-2.0+ +// +// Machine driver for AMD ACP Audio engine using DA7219 & MAX98357 codec. +// +//Copyright 2016 Advanced Micro Devices, Inc. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "raven/acp3x.h" + +#define DRV_NAME "amd-acp3x-essx8336" +#define SND_CARD_NAME DRV_NAME +#define DUAL_CHANNEL 2 + +struct acp3x_es8336_private { + /* struct acp3x_platform_info machine must always be + * the first entry in the structure, + * the acp3x-i2s driver casts the card private data to + * struct acp3x_platform_info + */ + struct acp3x_platform_info machine; + struct device *codec_dev; + struct gpio_desc *gpio_speakers; + bool speaker_en; +}; + +static const unsigned int channels[] = { + DUAL_CHANNEL, +}; + +static const unsigned int rates[] = { + 48000 +}; + +static const struct snd_pcm_hw_constraint_list constraints_rates = { + .count = ARRAY_SIZE(rates), + .list = rates, + .mask = 0, +}; + +static const struct snd_pcm_hw_constraint_list constraints_channels = { + .count = ARRAY_SIZE(channels), + .list = channels, + .mask = 0, +}; +#define ES8336_MCLK_FREQ (48000 * 1000) + +static int acp3x_es8336_codec_startup(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime; + struct snd_soc_pcm_runtime *rtd; + struct acp3x_platform_info *machine; + struct acp3x_es8336_private *priv; + struct snd_soc_dai *codec_dai; + int ret; + + runtime = substream->runtime; + rtd = asoc_substream_to_rtd(substream); + priv = snd_soc_card_get_drvdata(rtd->card); + machine = &priv->machine; + codec_dai = asoc_rtd_to_codec(rtd, 0); + + ret = snd_soc_dai_set_sysclk(codec_dai, 0, ES8336_MCLK_FREQ, SND_SOC_CLOCK_OUT); + if (ret < 0) { + dev_err(rtd->dev, "can't set codec sysclk: %d\n", ret); + return ret; + } + + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBP_CFP); + if (ret < 0) { + dev_err(rtd->dev, "failed to set DAI fmt: %d\n", ret); + return ret; + } + /* Report to userspace ALSA that we don't support suspending and resuming pcm streams, + * this means that during suspends and resumes of the PC, pulseaudio will not try to resume + * the substream, but will drop the connection and establish a new one. + * This is needed because sometimes after resume pulseaudio is unable to resume the stream + * and no sound can be heard. As a workaround for this issue, pulseaudio needs to be restarted. + */ + runtime->hw.info &= ~(SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME); + + 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); + runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE; + machine->play_i2s_instance = I2S_SP_INSTANCE; + + return 0; +} + +static int acp3x_es8336_speaker_power_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event); + +static struct snd_soc_jack es8336_jack; + +static struct snd_soc_jack_pin es8336_jack_pins[] = { + { + .pin = "Headphone", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + +static const struct snd_soc_dapm_widget acp3x_es8336_widgets[] = { + SND_SOC_DAPM_SPK("Speaker", NULL), + SND_SOC_DAPM_HP("Headphone", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("Internal Mic", NULL), + + SND_SOC_DAPM_SUPPLY("Speaker Power", SND_SOC_NOPM, 0, 0, + acp3x_es8336_speaker_power_event, + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), +}; + +static const struct snd_soc_dapm_route acp3x_es8336_audio_map[] = { + {"Headphone", NULL, "HPOL"}, + {"Headphone", NULL, "HPOR"}, + + /* + * There is no separate speaker output instead the speakers are muxed to + * the HP outputs. The mux is controlled Speaker and/or headphone switch. + */ + {"Speaker", NULL, "HPOL"}, + {"Speaker", NULL, "HPOR"}, + {"MIC1", NULL, "Headset Mic"}, + {"Speaker", NULL, "Speaker Power"}, +}; + + +static const struct snd_kcontrol_new acp3x_es8336_controls[] = { + SOC_DAPM_PIN_SWITCH("Speaker"), + SOC_DAPM_PIN_SWITCH("Headphone"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), +}; + +static const struct acpi_gpio_params enable_gpio0 = { 0, 0, true }; + +static const struct acpi_gpio_mapping acpi_speakers_enable_gpio0[] = { + { "speakers-enable-gpios", &enable_gpio0, 1, ACPI_GPIO_QUIRK_ONLY_GPIOIO }, + { } +}; + +static int acp3x_es8336_speaker_power_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct acp3x_es8336_private *priv = snd_soc_card_get_drvdata(w->dapm->card); + + if (priv->speaker_en == !SND_SOC_DAPM_EVENT_ON(event)) + return 0; + + priv->speaker_en = !SND_SOC_DAPM_EVENT_ON(event); + + if (SND_SOC_DAPM_EVENT_ON(event)) + msleep(70); + + gpiod_set_value_cansleep(priv->gpio_speakers, priv->speaker_en); + + return 0; +} + +static int acp3x_es8336_init(struct snd_soc_pcm_runtime *runtime) +{ + struct snd_soc_component *codec = asoc_rtd_to_codec(runtime, 0)->component; + struct snd_soc_card *card = runtime->card; + struct acp3x_es8336_private *priv = snd_soc_card_get_drvdata(card); + int ret; + + ret = snd_soc_card_jack_new_pins(card, "Headset", + SND_JACK_HEADSET | SND_JACK_BTN_0, + &es8336_jack, es8336_jack_pins, + ARRAY_SIZE(es8336_jack_pins)); + if (ret) { + dev_err(card->dev, "jack creation failed %d\n", ret); + return ret; + } + + snd_jack_set_key(es8336_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); + + snd_soc_component_set_jack(codec, &es8336_jack, NULL); + + ret = devm_acpi_dev_add_driver_gpios(codec->dev, acpi_speakers_enable_gpio0); + if (ret) + dev_warn(codec->dev, "failed to add speaker gpio\n"); + + priv->codec_dev = codec->dev; + priv->gpio_speakers = gpiod_get_optional(codec->dev, "speakers-enable", GPIOD_OUT_LOW); + if (IS_ERR(priv->gpio_speakers)) { + dev_err(codec->dev, "could not get speakers-enable GPIO\n"); + return PTR_ERR(priv->gpio_speakers); + } + + return 0; +} + +static struct snd_soc_ops acp3x_es8336_ops = { + .startup = acp3x_es8336_codec_startup, +}; + + +SND_SOC_DAILINK_DEF(acp3x_i2s, + DAILINK_COMP_ARRAY(COMP_CPU("acp3x_i2s_playcap.0"))); +SND_SOC_DAILINK_DEF(codec, + DAILINK_COMP_ARRAY(COMP_CODEC("i2c-ESSX8336:00", "ES8316 HiFi"))); +SND_SOC_DAILINK_DEF(platform, + DAILINK_COMP_ARRAY(COMP_PLATFORM("acp3x_rv_i2s_dma.0"))); + +static struct snd_soc_dai_link acp3x_dai_es8336[] = { + { + .name = "amd-acp3x-es8336-dai", + .stream_name = "ES8336 HiFi Play", + .stop_dma_first = 1, + .dpcm_capture = 1, + .dpcm_playback = 1, + .init = acp3x_es8336_init, + .ops = &acp3x_es8336_ops, + SND_SOC_DAILINK_REG(acp3x_i2s, codec, platform), + }, +}; + +static struct snd_soc_card acp3x_es8336 = { + .name = SND_CARD_NAME, + .owner = THIS_MODULE, + .dai_link = acp3x_dai_es8336, + .num_links = ARRAY_SIZE(acp3x_dai_es8336), + .dapm_widgets = acp3x_es8336_widgets, + .num_dapm_widgets = ARRAY_SIZE(acp3x_es8336_widgets), + .dapm_routes = acp3x_es8336_audio_map, + .num_dapm_routes = ARRAY_SIZE(acp3x_es8336_audio_map), + .controls = acp3x_es8336_controls, + .num_controls = ARRAY_SIZE(acp3x_es8336_controls), +}; + +static const struct dmi_system_id acp3x_es8336_dmi_table[] = { + { + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "HUAWEI"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "KLVL-WXXW"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "M1010"), + }, + .driver_data = &acp3x_es8336, + }, + { + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "HUAWEI"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "KLVL-WXX9"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "M1010"), + }, + .driver_data = &acp3x_es8336, + }, + { + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "HUAWEI"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "BOM-WXX9"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "M1010"), + }, + .driver_data = &acp3x_es8336, + }, + { + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "HUAWEI"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HVY-WXX9"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "M1040"), + }, + .driver_data = &acp3x_es8336, + }, + {} +}; + +static int acp3x_probe(struct platform_device *pdev) +{ + int ret = -ENODEV; + struct device *dev = &pdev->dev; + const struct dmi_system_id *dmi_id; + + dmi_id = dmi_first_match(acp3x_es8336_dmi_table); + if (dmi_id && dmi_id->driver_data) { + struct acp3x_es8336_private *priv; + struct snd_soc_card *card; + + dev_info(dev, "matched DMI table with this system, trying to register sound card\n"); + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) { + dev_err(dev, "can't alloc priv structure\n"); + return -ENOMEM; + } + + card = (struct snd_soc_card *)dmi_id->driver_data; + + card->dev = &pdev->dev; + platform_set_drvdata(pdev, card); + snd_soc_card_set_drvdata(card, priv); + ret = devm_snd_soc_register_card(&pdev->dev, card); + if (ret) { + dev_err(dev, "failed to register sound card, ret = %d\n", ret); + return dev_err_probe(&pdev->dev, ret, + "devm_snd_soc_register_card(%s) failed\n", + card->name); + } else { + dev_info(dev, "successfully registered the sound card\n"); + } + } + return ret; +} + +static int acp3x_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct acp3x_es8336_private *priv = snd_soc_card_get_drvdata(card); + struct device *dev = &pdev->dev; + + gpiod_put(priv->gpio_speakers); + + dev_info(dev, "removing sound card\n"); + return 0; +} + +static const struct acpi_device_id acp3x_audio_acpi_match[] = { + {"ESSX8336", 0}, + {}, +}; +MODULE_DEVICE_TABLE(acpi, acp3x_audio_acpi_match); + +static struct platform_driver acp3x_audio = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + }, + .probe = acp3x_probe, + .remove = acp3x_remove, +}; + +static struct platform_device *acp3x_es8336_snd_device; + +static int __init acp3x_es8336_module_init(void) +{ + int ret = -ENODEV; + + msleep(5000); + ret = platform_driver_register(&acp3x_audio); + if (ret < 0) { + printk(KERN_ERR DRV_NAME": can't register platform driver\n"); + return ret; + } + + acp3x_es8336_snd_device = platform_device_register_simple(DRV_NAME, 0, NULL, 0); + if (IS_ERR(acp3x_es8336_snd_device)) { + printk(KERN_ERR DRV_NAME": couldn't register platform device\n"); + platform_driver_unregister(&acp3x_audio); + return PTR_ERR(acp3x_es8336_snd_device); + } + + if (!platform_get_drvdata(acp3x_es8336_snd_device)) { + platform_device_unregister(acp3x_es8336_snd_device); + platform_driver_unregister(&acp3x_audio); + return -ENODEV; + } + printk(KERN_INFO DRV_NAME": platform device registered successfully\n"); + + return ret; +} +module_init(acp3x_es8336_module_init); + +static void __exit acp3x_es8336_module_exit(void) +{ + printk(KERN_INFO DRV_NAME": module unloading\n"); + platform_device_unregister(acp3x_es8336_snd_device); + platform_driver_unregister(&acp3x_audio); +} +module_exit(acp3x_es8336_module_exit); + +MODULE_AUTHOR("posteuca@mutex.one"); +MODULE_DESCRIPTION("ACP3x rev 1 ES8336 audio support"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/amd/raven/pci-acp3x.c b/sound/soc/amd/raven/pci-acp3x.c index a013a607b3d47..312a16c0e624f 100644 --- a/sound/soc/amd/raven/pci-acp3x.c +++ b/sound/soc/amd/raven/pci-acp3x.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "acp3x.h" @@ -133,8 +134,10 @@ static int snd_acp3x_probe(struct pci_dev *pci, int ret, i; u32 addr, val; - /* Raven device detection */ - if (pci->revision != 0x00) + /* Raven and lucienne device detection */ + if (acpi_dev_get_first_match_dev("ESSX8336", NULL, -1)) + dev_info(&pci->dev, "use pci-acp for ES8336 codec\n"); + else if (pci->revision != 0x00) return -ENODEV; if (pci_enable_device(pci)) { diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c index 056c3082fe02c..20a47573409a9 100644 --- a/sound/soc/codecs/es8316.c +++ b/sound/soc/codecs/es8316.c @@ -27,9 +27,9 @@ * MCLK/LRCK ratios, but we also add ratio 400, which is commonly used on * Intel Cherry Trail platforms (19.2MHz MCLK, 48kHz LRCK). */ -#define NR_SUPPORTED_MCLK_LRCK_RATIOS 6 +#define NR_SUPPORTED_MCLK_LRCK_RATIOS 7 static const unsigned int supported_mclk_lrck_ratios[] = { - 256, 384, 400, 512, 768, 1024 + 256, 384, 400, 512, 768, 1000, 1024 }; struct es8316_priv { @@ -465,10 +465,12 @@ static int es8316_pcm_hw_params(struct snd_pcm_substream *substream, u8 bclk_divider; u16 lrck_divider; int i; + int mclk_div = 1; + unsigned int ratio; /* Validate supported sample rates that are autodetected from MCLK */ for (i = 0; i < NR_SUPPORTED_MCLK_LRCK_RATIOS; i++) { - const unsigned int ratio = supported_mclk_lrck_ratios[i]; + ratio = supported_mclk_lrck_ratios[i]; if (es8316->sysclk % ratio != 0) continue; @@ -477,7 +479,13 @@ static int es8316_pcm_hw_params(struct snd_pcm_substream *substream, } if (i == NR_SUPPORTED_MCLK_LRCK_RATIOS) return -EINVAL; - lrck_divider = es8316->sysclk / params_rate(params); + + if (ratio == 1000) { + snd_soc_component_update_bits(component, 0x01, 0x80, 0x80); + mclk_div = 2; + } + + lrck_divider = es8316->sysclk / params_rate(params) / mclk_div; bclk_divider = lrck_divider / 4; switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: @@ -500,6 +508,15 @@ static int es8316_pcm_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } + static u8 only_one = 0; + if (!only_one) { + only_one = 1; + if (mclk_div == 2) + dev_info(component->dev, "Activating MCLK div by 2\n"); + + dev_info(component->dev, "Using lrck div = %d, bclk div = %d, wordlen = %d\n", lrck_divider, bclk_divider, wordlen); + } + snd_soc_component_update_bits(component, ES8316_SERDATA_DAC, ES8316_SERDATA2_LEN_MASK, wordlen); snd_soc_component_update_bits(component, ES8316_SERDATA_ADC, @@ -520,7 +537,7 @@ static int es8316_mute(struct snd_soc_dai *dai, int mute, int direction) } #define ES8316_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ - SNDRV_PCM_FMTBIT_S24_LE) + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) static const struct snd_soc_dai_ops es8316_ops = { .startup = es8316_pcm_startup, @@ -717,6 +734,41 @@ static int es8316_set_jack(struct snd_soc_component *component, return 0; } +#ifdef CONFIG_PM + +static int es8316_suspend(struct snd_soc_component *component) +{ + struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); + regcache_cache_only(es8316->regmap, true); + + return 0; +} + +static int es8316_resume(struct snd_soc_component *component) +{ + struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); + + regcache_cache_only(es8316->regmap, false); + /* Reset codec and enable current state machine */ + snd_soc_component_write(component, ES8316_RESET, 0x3f); + usleep_range(5000, 5500); + snd_soc_component_write(component, ES8316_RESET, ES8316_RESET_CSM_ON); + msleep(30); + + snd_soc_component_write(component, ES8316_SYS_VMIDSEL, 0xff); + + snd_soc_component_write(component, ES8316_CLKMGR_ADCOSR, 0x32); + + regcache_mark_dirty(es8316->regmap); + regcache_sync(es8316->regmap); + + return 0; +} +#else +#define es8316_suspend NULL +#define es8316_resume NULL +#endif + static int es8316_probe(struct snd_soc_component *component) { struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); @@ -767,26 +819,6 @@ static void es8316_remove(struct snd_soc_component *component) clk_disable_unprepare(es8316->mclk); } -static int es8316_resume(struct snd_soc_component *component) -{ - struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); - - regcache_cache_only(es8316->regmap, false); - regcache_sync(es8316->regmap); - - return 0; -} - -static int es8316_suspend(struct snd_soc_component *component) -{ - struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component); - - regcache_cache_only(es8316->regmap, true); - regcache_mark_dirty(es8316->regmap); - - return 0; -} - static const struct snd_soc_component_driver soc_component_dev_es8316 = { .probe = es8316_probe, .remove = es8316_remove, @@ -805,6 +837,9 @@ static const struct snd_soc_component_driver soc_component_dev_es8316 = { static const struct regmap_range es8316_volatile_ranges[] = { regmap_reg_range(ES8316_GPIO_FLAG, ES8316_GPIO_FLAG), + regmap_reg_range(ES8316_RESET, ES8316_RESET), + regmap_reg_range(ES8316_SYS_VMIDSEL,ES8316_SYS_VMIDSEL), + regmap_reg_range(ES8316_CLKMGR_ADCOSR,ES8316_CLKMGR_ADCOSR), }; static const struct regmap_access_table es8316_volatile_table = { -- 2.33.5