162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci//
362306a36Sopenharmony_ci// CS42L43 CODEC driver
462306a36Sopenharmony_ci//
562306a36Sopenharmony_ci// Copyright (C) 2022-2023 Cirrus Logic, Inc. and
662306a36Sopenharmony_ci//                         Cirrus Logic International Semiconductor Ltd.
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <linux/bitops.h>
962306a36Sopenharmony_ci#include <linux/err.h>
1062306a36Sopenharmony_ci#include <linux/errno.h>
1162306a36Sopenharmony_ci#include <linux/gcd.h>
1262306a36Sopenharmony_ci#include <linux/irq.h>
1362306a36Sopenharmony_ci#include <linux/jiffies.h>
1462306a36Sopenharmony_ci#include <linux/mfd/cs42l43.h>
1562306a36Sopenharmony_ci#include <linux/mfd/cs42l43-regs.h>
1662306a36Sopenharmony_ci#include <linux/module.h>
1762306a36Sopenharmony_ci#include <linux/pm_runtime.h>
1862306a36Sopenharmony_ci#include <linux/string.h>
1962306a36Sopenharmony_ci#include <sound/control.h>
2062306a36Sopenharmony_ci#include <sound/pcm.h>
2162306a36Sopenharmony_ci#include <sound/pcm_params.h>
2262306a36Sopenharmony_ci#include <sound/soc-component.h>
2362306a36Sopenharmony_ci#include <sound/soc-dapm.h>
2462306a36Sopenharmony_ci#include <sound/soc-dai.h>
2562306a36Sopenharmony_ci#include <sound/soc.h>
2662306a36Sopenharmony_ci#include <sound/tlv.h>
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci#include "cs42l43.h"
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci#define CS42L43_DECL_MUX(name, reg) \
3162306a36Sopenharmony_cistatic SOC_VALUE_ENUM_SINGLE_DECL(cs42l43_##name##_enum, reg, \
3262306a36Sopenharmony_ci				  0, CS42L43_MIXER_SRC_MASK, \
3362306a36Sopenharmony_ci				  cs42l43_mixer_texts, cs42l43_mixer_values); \
3462306a36Sopenharmony_cistatic const struct snd_kcontrol_new cs42l43_##name##_mux = \
3562306a36Sopenharmony_ci		SOC_DAPM_ENUM("Route", cs42l43_##name##_enum)
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci#define CS42L43_DECL_MIXER(name, reg) \
3862306a36Sopenharmony_ci	CS42L43_DECL_MUX(name##_in1, reg); \
3962306a36Sopenharmony_ci	CS42L43_DECL_MUX(name##_in2, reg + 0x4); \
4062306a36Sopenharmony_ci	CS42L43_DECL_MUX(name##_in3, reg + 0x8); \
4162306a36Sopenharmony_ci	CS42L43_DECL_MUX(name##_in4, reg + 0xC)
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci#define CS42L43_DAPM_MUX(name_str, name) \
4462306a36Sopenharmony_ci	SND_SOC_DAPM_MUX(name_str " Input", SND_SOC_NOPM, 0, 0, &cs42l43_##name##_mux)
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci#define CS42L43_DAPM_MIXER(name_str, name) \
4762306a36Sopenharmony_ci	SND_SOC_DAPM_MUX(name_str " Input 1", SND_SOC_NOPM, 0, 0, &cs42l43_##name##_in1_mux), \
4862306a36Sopenharmony_ci	SND_SOC_DAPM_MUX(name_str " Input 2", SND_SOC_NOPM, 0, 0, &cs42l43_##name##_in2_mux), \
4962306a36Sopenharmony_ci	SND_SOC_DAPM_MUX(name_str " Input 3", SND_SOC_NOPM, 0, 0, &cs42l43_##name##_in3_mux), \
5062306a36Sopenharmony_ci	SND_SOC_DAPM_MUX(name_str " Input 4", SND_SOC_NOPM, 0, 0, &cs42l43_##name##_in4_mux), \
5162306a36Sopenharmony_ci	SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci#define CS42L43_BASE_ROUTES(name_str) \
5462306a36Sopenharmony_ci	{ name_str,		"Tone Generator 1",	"Tone 1" }, \
5562306a36Sopenharmony_ci	{ name_str,		"Tone Generator 2",	"Tone 2" }, \
5662306a36Sopenharmony_ci	{ name_str,		"Decimator 1",		"Decimator 1" }, \
5762306a36Sopenharmony_ci	{ name_str,		"Decimator 2",		"Decimator 2" }, \
5862306a36Sopenharmony_ci	{ name_str,		"Decimator 3",		"Decimator 3" }, \
5962306a36Sopenharmony_ci	{ name_str,		"Decimator 4",		"Decimator 4" }, \
6062306a36Sopenharmony_ci	{ name_str,		"ASPRX1",		"ASPRX1" }, \
6162306a36Sopenharmony_ci	{ name_str,		"ASPRX2",		"ASPRX2" }, \
6262306a36Sopenharmony_ci	{ name_str,		"ASPRX3",		"ASPRX3" }, \
6362306a36Sopenharmony_ci	{ name_str,		"ASPRX4",		"ASPRX4" }, \
6462306a36Sopenharmony_ci	{ name_str,		"ASPRX5",		"ASPRX5" }, \
6562306a36Sopenharmony_ci	{ name_str,		"ASPRX6",		"ASPRX6" }, \
6662306a36Sopenharmony_ci	{ name_str,		"DP5RX1",		"DP5RX1" }, \
6762306a36Sopenharmony_ci	{ name_str,		"DP5RX2",		"DP5RX2" }, \
6862306a36Sopenharmony_ci	{ name_str,		"DP6RX1",		"DP6RX1" }, \
6962306a36Sopenharmony_ci	{ name_str,		"DP6RX2",		"DP6RX2" }, \
7062306a36Sopenharmony_ci	{ name_str,		"DP7RX1",		"DP7RX1" }, \
7162306a36Sopenharmony_ci	{ name_str,		"DP7RX2",		"DP7RX2" }, \
7262306a36Sopenharmony_ci	{ name_str,		"ASRC INT1",		"ASRC_INT1" }, \
7362306a36Sopenharmony_ci	{ name_str,		"ASRC INT2",		"ASRC_INT2" }, \
7462306a36Sopenharmony_ci	{ name_str,		"ASRC INT3",		"ASRC_INT3" }, \
7562306a36Sopenharmony_ci	{ name_str,		"ASRC INT4",		"ASRC_INT4" }, \
7662306a36Sopenharmony_ci	{ name_str,		"ASRC DEC1",		"ASRC_DEC1" }, \
7762306a36Sopenharmony_ci	{ name_str,		"ASRC DEC2",		"ASRC_DEC2" }, \
7862306a36Sopenharmony_ci	{ name_str,		"ASRC DEC3",		"ASRC_DEC3" }, \
7962306a36Sopenharmony_ci	{ name_str,		"ASRC DEC4",		"ASRC_DEC4" }, \
8062306a36Sopenharmony_ci	{ name_str,		"ISRC1 INT1",		"ISRC1INT1" }, \
8162306a36Sopenharmony_ci	{ name_str,		"ISRC1 INT2",		"ISRC1INT2" }, \
8262306a36Sopenharmony_ci	{ name_str,		"ISRC1 DEC1",		"ISRC1DEC1" }, \
8362306a36Sopenharmony_ci	{ name_str,		"ISRC1 DEC2",		"ISRC1DEC2" }, \
8462306a36Sopenharmony_ci	{ name_str,		"ISRC2 INT1",		"ISRC2INT1" }, \
8562306a36Sopenharmony_ci	{ name_str,		"ISRC2 INT2",		"ISRC2INT2" }, \
8662306a36Sopenharmony_ci	{ name_str,		"ISRC2 DEC1",		"ISRC2DEC1" }, \
8762306a36Sopenharmony_ci	{ name_str,		"ISRC2 DEC2",		"ISRC2DEC2" }, \
8862306a36Sopenharmony_ci	{ name_str,		"EQ1",			"EQ" }, \
8962306a36Sopenharmony_ci	{ name_str,		"EQ2",			"EQ" }
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci#define CS42L43_MUX_ROUTES(name_str, widget) \
9262306a36Sopenharmony_ci	{ widget,		NULL,			name_str " Input" }, \
9362306a36Sopenharmony_ci	{ name_str " Input",	NULL,			"Mixer Core" }, \
9462306a36Sopenharmony_ci	CS42L43_BASE_ROUTES(name_str " Input")
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci#define CS42L43_MIXER_ROUTES(name_str, widget) \
9762306a36Sopenharmony_ci	{ name_str " Mixer",	NULL,			name_str " Input 1" }, \
9862306a36Sopenharmony_ci	{ name_str " Mixer",	NULL,			name_str " Input 2" }, \
9962306a36Sopenharmony_ci	{ name_str " Mixer",	NULL,			name_str " Input 3" }, \
10062306a36Sopenharmony_ci	{ name_str " Mixer",	NULL,			name_str " Input 4" }, \
10162306a36Sopenharmony_ci	{ widget,		NULL,			name_str " Mixer" }, \
10262306a36Sopenharmony_ci	{ name_str " Mixer",	NULL,			"Mixer Core" }, \
10362306a36Sopenharmony_ci	CS42L43_BASE_ROUTES(name_str " Input 1"), \
10462306a36Sopenharmony_ci	CS42L43_BASE_ROUTES(name_str " Input 2"), \
10562306a36Sopenharmony_ci	CS42L43_BASE_ROUTES(name_str " Input 3"), \
10662306a36Sopenharmony_ci	CS42L43_BASE_ROUTES(name_str " Input 4")
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci#define CS42L43_MIXER_VOLUMES(name_str, base) \
10962306a36Sopenharmony_ci	SOC_SINGLE_RANGE_TLV(name_str " Input 1 Volume", base, \
11062306a36Sopenharmony_ci			     CS42L43_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
11162306a36Sopenharmony_ci			     cs42l43_mixer_tlv), \
11262306a36Sopenharmony_ci	SOC_SINGLE_RANGE_TLV(name_str " Input 2 Volume", base + 4, \
11362306a36Sopenharmony_ci			     CS42L43_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
11462306a36Sopenharmony_ci			     cs42l43_mixer_tlv), \
11562306a36Sopenharmony_ci	SOC_SINGLE_RANGE_TLV(name_str " Input 3 Volume", base + 8, \
11662306a36Sopenharmony_ci			     CS42L43_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
11762306a36Sopenharmony_ci			     cs42l43_mixer_tlv), \
11862306a36Sopenharmony_ci	SOC_SINGLE_RANGE_TLV(name_str " Input 4 Volume", base + 12, \
11962306a36Sopenharmony_ci			     CS42L43_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
12062306a36Sopenharmony_ci			     cs42l43_mixer_tlv)
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci#define CS42L43_IRQ_ERROR(name) \
12362306a36Sopenharmony_cistatic irqreturn_t cs42l43_##name(int irq, void *data) \
12462306a36Sopenharmony_ci{ \
12562306a36Sopenharmony_ci	struct cs42l43_codec *priv = data; \
12662306a36Sopenharmony_ci	dev_err(priv->dev, "Error " #name " IRQ\n"); \
12762306a36Sopenharmony_ci	return IRQ_HANDLED; \
12862306a36Sopenharmony_ci}
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ciCS42L43_IRQ_ERROR(pll_lost_lock)
13162306a36Sopenharmony_ciCS42L43_IRQ_ERROR(spkr_clock_stop)
13262306a36Sopenharmony_ciCS42L43_IRQ_ERROR(spkl_clock_stop)
13362306a36Sopenharmony_ciCS42L43_IRQ_ERROR(spkr_brown_out)
13462306a36Sopenharmony_ciCS42L43_IRQ_ERROR(spkl_brown_out)
13562306a36Sopenharmony_ciCS42L43_IRQ_ERROR(spkr_therm_shutdown)
13662306a36Sopenharmony_ciCS42L43_IRQ_ERROR(spkl_therm_shutdown)
13762306a36Sopenharmony_ciCS42L43_IRQ_ERROR(spkr_therm_warm)
13862306a36Sopenharmony_ciCS42L43_IRQ_ERROR(spkl_therm_warm)
13962306a36Sopenharmony_ciCS42L43_IRQ_ERROR(spkr_sc_detect)
14062306a36Sopenharmony_ciCS42L43_IRQ_ERROR(spkl_sc_detect)
14162306a36Sopenharmony_ciCS42L43_IRQ_ERROR(hp_ilimit)
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci#define CS42L43_IRQ_COMPLETE(name) \
14462306a36Sopenharmony_cistatic irqreturn_t cs42l43_##name(int irq, void *data) \
14562306a36Sopenharmony_ci{ \
14662306a36Sopenharmony_ci	struct cs42l43_codec *priv = data; \
14762306a36Sopenharmony_ci	dev_dbg(priv->dev, #name " completed\n"); \
14862306a36Sopenharmony_ci	complete(&priv->name); \
14962306a36Sopenharmony_ci	return IRQ_HANDLED; \
15062306a36Sopenharmony_ci}
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ciCS42L43_IRQ_COMPLETE(pll_ready)
15362306a36Sopenharmony_ciCS42L43_IRQ_COMPLETE(hp_startup)
15462306a36Sopenharmony_ciCS42L43_IRQ_COMPLETE(hp_shutdown)
15562306a36Sopenharmony_ciCS42L43_IRQ_COMPLETE(type_detect)
15662306a36Sopenharmony_ciCS42L43_IRQ_COMPLETE(spkr_shutdown)
15762306a36Sopenharmony_ciCS42L43_IRQ_COMPLETE(spkl_shutdown)
15862306a36Sopenharmony_ciCS42L43_IRQ_COMPLETE(spkr_startup)
15962306a36Sopenharmony_ciCS42L43_IRQ_COMPLETE(spkl_startup)
16062306a36Sopenharmony_ciCS42L43_IRQ_COMPLETE(load_detect)
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_cistatic irqreturn_t cs42l43_mic_shutter(int irq, void *data)
16362306a36Sopenharmony_ci{
16462306a36Sopenharmony_ci	struct cs42l43_codec *priv = data;
16562306a36Sopenharmony_ci	const char * const controls[] = {
16662306a36Sopenharmony_ci		"Decimator 1 Switch",
16762306a36Sopenharmony_ci		"Decimator 2 Switch",
16862306a36Sopenharmony_ci		"Decimator 3 Switch",
16962306a36Sopenharmony_ci		"Decimator 4 Switch",
17062306a36Sopenharmony_ci	};
17162306a36Sopenharmony_ci	int i, ret;
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci	dev_dbg(priv->dev, "Microphone shutter changed\n");
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci	if (!priv->component)
17662306a36Sopenharmony_ci		return IRQ_NONE;
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(controls); i++) {
17962306a36Sopenharmony_ci		ret = snd_soc_component_notify_control(priv->component,
18062306a36Sopenharmony_ci						       controls[i]);
18162306a36Sopenharmony_ci		if (ret)
18262306a36Sopenharmony_ci			return IRQ_NONE;
18362306a36Sopenharmony_ci	}
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci	return IRQ_HANDLED;
18662306a36Sopenharmony_ci}
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_cistatic irqreturn_t cs42l43_spk_shutter(int irq, void *data)
18962306a36Sopenharmony_ci{
19062306a36Sopenharmony_ci	struct cs42l43_codec *priv = data;
19162306a36Sopenharmony_ci	int ret;
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci	dev_dbg(priv->dev, "Speaker shutter changed\n");
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci	if (!priv->component)
19662306a36Sopenharmony_ci		return IRQ_NONE;
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci	ret = snd_soc_component_notify_control(priv->component,
19962306a36Sopenharmony_ci					       "Speaker Digital Switch");
20062306a36Sopenharmony_ci	if (ret)
20162306a36Sopenharmony_ci		return IRQ_NONE;
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci	return IRQ_HANDLED;
20462306a36Sopenharmony_ci}
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_cistatic const unsigned int cs42l43_sample_rates[] = {
20762306a36Sopenharmony_ci	8000, 16000, 24000, 32000, 44100, 48000, 96000, 192000,
20862306a36Sopenharmony_ci};
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci#define CS42L43_CONSUMER_RATE_MASK 0xFF
21162306a36Sopenharmony_ci#define CS42L43_PROVIDER_RATE_MASK 0xEF // 44.1k only supported as consumer
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_cistatic const struct snd_pcm_hw_constraint_list cs42l43_constraint = {
21462306a36Sopenharmony_ci	.count		= ARRAY_SIZE(cs42l43_sample_rates),
21562306a36Sopenharmony_ci	.list		= cs42l43_sample_rates,
21662306a36Sopenharmony_ci};
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_cistatic int cs42l43_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
21962306a36Sopenharmony_ci{
22062306a36Sopenharmony_ci	struct snd_soc_component *component = dai->component;
22162306a36Sopenharmony_ci	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
22262306a36Sopenharmony_ci	struct cs42l43 *cs42l43 = priv->core;
22362306a36Sopenharmony_ci	int provider = !!regmap_test_bits(cs42l43->regmap, CS42L43_ASP_CLK_CONFIG2,
22462306a36Sopenharmony_ci					  CS42L43_ASP_MASTER_MODE_MASK);
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci	if (provider)
22762306a36Sopenharmony_ci		priv->constraint.mask = CS42L43_PROVIDER_RATE_MASK;
22862306a36Sopenharmony_ci	else
22962306a36Sopenharmony_ci		priv->constraint.mask = CS42L43_CONSUMER_RATE_MASK;
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci	return snd_pcm_hw_constraint_list(substream->runtime, 0,
23262306a36Sopenharmony_ci					  SNDRV_PCM_HW_PARAM_RATE,
23362306a36Sopenharmony_ci					  &priv->constraint);
23462306a36Sopenharmony_ci}
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_cistatic int cs42l43_convert_sample_rate(unsigned int rate)
23762306a36Sopenharmony_ci{
23862306a36Sopenharmony_ci	switch (rate) {
23962306a36Sopenharmony_ci	case 8000:
24062306a36Sopenharmony_ci		return 0x11;
24162306a36Sopenharmony_ci	case 16000:
24262306a36Sopenharmony_ci		return 0x12;
24362306a36Sopenharmony_ci	case 24000:
24462306a36Sopenharmony_ci		return 0x02;
24562306a36Sopenharmony_ci	case 32000:
24662306a36Sopenharmony_ci		return 0x13;
24762306a36Sopenharmony_ci	case 44100:
24862306a36Sopenharmony_ci		return 0x0B;
24962306a36Sopenharmony_ci	case 48000:
25062306a36Sopenharmony_ci		return 0x03;
25162306a36Sopenharmony_ci	case 96000:
25262306a36Sopenharmony_ci		return 0x04;
25362306a36Sopenharmony_ci	case 192000:
25462306a36Sopenharmony_ci		return 0x05;
25562306a36Sopenharmony_ci	default:
25662306a36Sopenharmony_ci		return -EINVAL;
25762306a36Sopenharmony_ci	}
25862306a36Sopenharmony_ci}
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_cistatic int cs42l43_set_sample_rate(struct snd_pcm_substream *substream,
26162306a36Sopenharmony_ci				   struct snd_pcm_hw_params *params,
26262306a36Sopenharmony_ci				   struct snd_soc_dai *dai)
26362306a36Sopenharmony_ci{
26462306a36Sopenharmony_ci	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(dai->component);
26562306a36Sopenharmony_ci	struct cs42l43 *cs42l43 = priv->core;
26662306a36Sopenharmony_ci	int ret;
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci	ret = cs42l43_convert_sample_rate(params_rate(params));
26962306a36Sopenharmony_ci	if (ret < 0) {
27062306a36Sopenharmony_ci		dev_err(priv->dev, "Failed to convert sample rate: %d\n", ret);
27162306a36Sopenharmony_ci		return ret;
27262306a36Sopenharmony_ci	}
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ci	//FIXME: For now lets just set sample rate 1, this needs expanded in the future
27562306a36Sopenharmony_ci	regmap_update_bits(cs42l43->regmap, CS42L43_SAMPLE_RATE1,
27662306a36Sopenharmony_ci			   CS42L43_SAMPLE_RATE_MASK, ret);
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_ci	return 0;
27962306a36Sopenharmony_ci}
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_cistatic int cs42l43_asp_hw_params(struct snd_pcm_substream *substream,
28262306a36Sopenharmony_ci				 struct snd_pcm_hw_params *params,
28362306a36Sopenharmony_ci				 struct snd_soc_dai *dai)
28462306a36Sopenharmony_ci{
28562306a36Sopenharmony_ci	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(dai->component);
28662306a36Sopenharmony_ci	struct cs42l43 *cs42l43 = priv->core;
28762306a36Sopenharmony_ci	int dsp_mode = !!regmap_test_bits(cs42l43->regmap, CS42L43_ASP_CTRL,
28862306a36Sopenharmony_ci					  CS42L43_ASP_FSYNC_MODE_MASK);
28962306a36Sopenharmony_ci	int provider = !!regmap_test_bits(cs42l43->regmap, CS42L43_ASP_CLK_CONFIG2,
29062306a36Sopenharmony_ci					  CS42L43_ASP_MASTER_MODE_MASK);
29162306a36Sopenharmony_ci	int n_chans = params_channels(params);
29262306a36Sopenharmony_ci	int data_width = params_width(params);
29362306a36Sopenharmony_ci	int n_slots = n_chans;
29462306a36Sopenharmony_ci	int slot_width = data_width;
29562306a36Sopenharmony_ci	int frame, bclk_target, i;
29662306a36Sopenharmony_ci	unsigned int reg;
29762306a36Sopenharmony_ci	int *slots;
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci	if (priv->n_slots) {
30062306a36Sopenharmony_ci		n_slots = priv->n_slots;
30162306a36Sopenharmony_ci		slot_width = priv->slot_width;
30262306a36Sopenharmony_ci	}
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ci	if (!dsp_mode && (n_slots & 0x1)) {
30562306a36Sopenharmony_ci		dev_dbg(priv->dev, "Forcing balanced channels on ASP\n");
30662306a36Sopenharmony_ci		n_slots++;
30762306a36Sopenharmony_ci	}
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ci	frame = n_slots * slot_width;
31062306a36Sopenharmony_ci	bclk_target = params_rate(params) * frame;
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci	if (provider) {
31362306a36Sopenharmony_ci		unsigned int gcd_nm = gcd(bclk_target, CS42L43_INTERNAL_SYSCLK);
31462306a36Sopenharmony_ci		int n = bclk_target / gcd_nm;
31562306a36Sopenharmony_ci		int m = CS42L43_INTERNAL_SYSCLK / gcd_nm;
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ci		if (n > (CS42L43_ASP_BCLK_N_MASK >> CS42L43_ASP_BCLK_N_SHIFT) ||
31862306a36Sopenharmony_ci		    m > CS42L43_ASP_BCLK_M_MASK) {
31962306a36Sopenharmony_ci			dev_err(priv->dev, "Can't produce %dHz bclk\n", bclk_target);
32062306a36Sopenharmony_ci			return -EINVAL;
32162306a36Sopenharmony_ci		}
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_ci		dev_dbg(priv->dev, "bclk %d/%d = %dHz, with %dx%d frame\n",
32462306a36Sopenharmony_ci			n, m, bclk_target, n_slots, slot_width);
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_ci		regmap_update_bits(cs42l43->regmap, CS42L43_ASP_CLK_CONFIG1,
32762306a36Sopenharmony_ci				   CS42L43_ASP_BCLK_N_MASK | CS42L43_ASP_BCLK_M_MASK,
32862306a36Sopenharmony_ci				   n << CS42L43_ASP_BCLK_N_SHIFT |
32962306a36Sopenharmony_ci				   m << CS42L43_ASP_BCLK_M_SHIFT);
33062306a36Sopenharmony_ci		regmap_update_bits(cs42l43->regmap, CS42L43_ASP_FSYNC_CTRL1,
33162306a36Sopenharmony_ci				   CS42L43_ASP_FSYNC_M_MASK, frame);
33262306a36Sopenharmony_ci	}
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci	regmap_update_bits(cs42l43->regmap, CS42L43_ASP_FSYNC_CTRL4,
33562306a36Sopenharmony_ci			   CS42L43_ASP_NUM_BCLKS_PER_FSYNC_MASK,
33662306a36Sopenharmony_ci			   frame << CS42L43_ASP_NUM_BCLKS_PER_FSYNC_SHIFT);
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_ci	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
33962306a36Sopenharmony_ci		reg = CS42L43_ASP_TX_CH1_CTRL;
34062306a36Sopenharmony_ci		slots = priv->tx_slots;
34162306a36Sopenharmony_ci	} else {
34262306a36Sopenharmony_ci		reg = CS42L43_ASP_RX_CH1_CTRL;
34362306a36Sopenharmony_ci		slots = priv->rx_slots;
34462306a36Sopenharmony_ci	}
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_ci	for (i = 0; i < n_chans; i++, reg += 4) {
34762306a36Sopenharmony_ci		int slot_phase = dsp_mode | (i & CS42L43_ASP_CH_SLOT_PHASE_MASK);
34862306a36Sopenharmony_ci		int slot_pos;
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_ci		if (dsp_mode)
35162306a36Sopenharmony_ci			slot_pos = slots[i] * slot_width;
35262306a36Sopenharmony_ci		else
35362306a36Sopenharmony_ci			slot_pos = (slots[i] / 2) * slot_width;
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_ci		dev_dbg(priv->dev, "Configure channel %d at slot %d (%d,%d)\n",
35662306a36Sopenharmony_ci			i, slots[i], slot_pos, slot_phase);
35762306a36Sopenharmony_ci
35862306a36Sopenharmony_ci		regmap_update_bits(cs42l43->regmap, reg,
35962306a36Sopenharmony_ci				   CS42L43_ASP_CH_WIDTH_MASK |
36062306a36Sopenharmony_ci				   CS42L43_ASP_CH_SLOT_MASK |
36162306a36Sopenharmony_ci				   CS42L43_ASP_CH_SLOT_PHASE_MASK,
36262306a36Sopenharmony_ci				   ((data_width - 1) << CS42L43_ASP_CH_WIDTH_SHIFT) |
36362306a36Sopenharmony_ci				   (slot_pos << CS42L43_ASP_CH_SLOT_SHIFT) |
36462306a36Sopenharmony_ci				   slot_phase);
36562306a36Sopenharmony_ci	}
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ci	return cs42l43_set_sample_rate(substream, params, dai);
36862306a36Sopenharmony_ci}
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_cistatic int cs42l43_asp_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
37162306a36Sopenharmony_ci{
37262306a36Sopenharmony_ci	struct snd_soc_component *component = dai->component;
37362306a36Sopenharmony_ci	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
37462306a36Sopenharmony_ci	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
37562306a36Sopenharmony_ci	struct cs42l43 *cs42l43 = priv->core;
37662306a36Sopenharmony_ci	int provider = regmap_test_bits(cs42l43->regmap, CS42L43_ASP_CLK_CONFIG2,
37762306a36Sopenharmony_ci					CS42L43_ASP_MASTER_MODE_MASK);
37862306a36Sopenharmony_ci	struct snd_soc_dapm_route routes[] = {
37962306a36Sopenharmony_ci		{ "BCLK", NULL, "FSYNC" },
38062306a36Sopenharmony_ci	};
38162306a36Sopenharmony_ci	unsigned int asp_ctrl = 0;
38262306a36Sopenharmony_ci	unsigned int data_ctrl = 0;
38362306a36Sopenharmony_ci	unsigned int fsync_ctrl = 0;
38462306a36Sopenharmony_ci	unsigned int clk_config = 0;
38562306a36Sopenharmony_ci
38662306a36Sopenharmony_ci	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
38762306a36Sopenharmony_ci	case SND_SOC_DAIFMT_DSP_A:
38862306a36Sopenharmony_ci		data_ctrl |= 2 << CS42L43_ASP_FSYNC_FRAME_START_DLY_SHIFT;
38962306a36Sopenharmony_ci		fallthrough;
39062306a36Sopenharmony_ci	case SND_SOC_DAIFMT_DSP_B:
39162306a36Sopenharmony_ci		asp_ctrl |= CS42L43_ASP_FSYNC_MODE_MASK;
39262306a36Sopenharmony_ci		data_ctrl |= CS42L43_ASP_FSYNC_FRAME_START_PHASE_MASK;
39362306a36Sopenharmony_ci		break;
39462306a36Sopenharmony_ci	case SND_SOC_DAIFMT_I2S:
39562306a36Sopenharmony_ci		data_ctrl |= 2 << CS42L43_ASP_FSYNC_FRAME_START_DLY_SHIFT;
39662306a36Sopenharmony_ci		break;
39762306a36Sopenharmony_ci	case SND_SOC_DAIFMT_LEFT_J:
39862306a36Sopenharmony_ci		data_ctrl |= CS42L43_ASP_FSYNC_FRAME_START_PHASE_MASK;
39962306a36Sopenharmony_ci		break;
40062306a36Sopenharmony_ci	default:
40162306a36Sopenharmony_ci		dev_err(priv->dev, "Unsupported DAI format 0x%x\n",
40262306a36Sopenharmony_ci			fmt & SND_SOC_DAIFMT_FORMAT_MASK);
40362306a36Sopenharmony_ci		return -EINVAL;
40462306a36Sopenharmony_ci	}
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ci	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
40762306a36Sopenharmony_ci	case SND_SOC_DAIFMT_CBC_CFC:
40862306a36Sopenharmony_ci		if (provider)
40962306a36Sopenharmony_ci			snd_soc_dapm_del_routes(dapm, routes, ARRAY_SIZE(routes));
41062306a36Sopenharmony_ci		break;
41162306a36Sopenharmony_ci	case SND_SOC_DAIFMT_CBP_CFP:
41262306a36Sopenharmony_ci		if (!provider)
41362306a36Sopenharmony_ci			snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
41462306a36Sopenharmony_ci		clk_config |= CS42L43_ASP_MASTER_MODE_MASK;
41562306a36Sopenharmony_ci		break;
41662306a36Sopenharmony_ci	default:
41762306a36Sopenharmony_ci		dev_err(priv->dev, "Unsupported ASP mode 0x%x\n",
41862306a36Sopenharmony_ci			fmt & SND_SOC_DAIFMT_MASTER_MASK);
41962306a36Sopenharmony_ci		return -EINVAL;
42062306a36Sopenharmony_ci	}
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
42362306a36Sopenharmony_ci	case SND_SOC_DAIFMT_NB_NF:
42462306a36Sopenharmony_ci		clk_config |= CS42L43_ASP_BCLK_INV_MASK; /* Yes BCLK_INV = NB */
42562306a36Sopenharmony_ci		break;
42662306a36Sopenharmony_ci	case SND_SOC_DAIFMT_IB_NF:
42762306a36Sopenharmony_ci		break;
42862306a36Sopenharmony_ci	case SND_SOC_DAIFMT_NB_IF:
42962306a36Sopenharmony_ci		clk_config |= CS42L43_ASP_BCLK_INV_MASK;
43062306a36Sopenharmony_ci		fsync_ctrl |= CS42L43_ASP_FSYNC_IN_INV_MASK |
43162306a36Sopenharmony_ci			      CS42L43_ASP_FSYNC_OUT_INV_MASK;
43262306a36Sopenharmony_ci		break;
43362306a36Sopenharmony_ci	case SND_SOC_DAIFMT_IB_IF:
43462306a36Sopenharmony_ci		fsync_ctrl |= CS42L43_ASP_FSYNC_IN_INV_MASK |
43562306a36Sopenharmony_ci			      CS42L43_ASP_FSYNC_OUT_INV_MASK;
43662306a36Sopenharmony_ci		break;
43762306a36Sopenharmony_ci	default:
43862306a36Sopenharmony_ci		dev_err(priv->dev, "Unsupported invert mode 0x%x\n",
43962306a36Sopenharmony_ci			fmt & SND_SOC_DAIFMT_INV_MASK);
44062306a36Sopenharmony_ci		return -EINVAL;
44162306a36Sopenharmony_ci	}
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ci	regmap_update_bits(cs42l43->regmap, CS42L43_ASP_CTRL,
44462306a36Sopenharmony_ci			   CS42L43_ASP_FSYNC_MODE_MASK,
44562306a36Sopenharmony_ci			   asp_ctrl);
44662306a36Sopenharmony_ci	regmap_update_bits(cs42l43->regmap, CS42L43_ASP_DATA_CTRL,
44762306a36Sopenharmony_ci			   CS42L43_ASP_FSYNC_FRAME_START_DLY_MASK |
44862306a36Sopenharmony_ci			   CS42L43_ASP_FSYNC_FRAME_START_PHASE_MASK,
44962306a36Sopenharmony_ci			   data_ctrl);
45062306a36Sopenharmony_ci	regmap_update_bits(cs42l43->regmap, CS42L43_ASP_CLK_CONFIG2,
45162306a36Sopenharmony_ci			   CS42L43_ASP_MASTER_MODE_MASK |
45262306a36Sopenharmony_ci			   CS42L43_ASP_BCLK_INV_MASK,
45362306a36Sopenharmony_ci			   clk_config);
45462306a36Sopenharmony_ci	regmap_update_bits(cs42l43->regmap, CS42L43_ASP_FSYNC_CTRL3,
45562306a36Sopenharmony_ci			   CS42L43_ASP_FSYNC_IN_INV_MASK |
45662306a36Sopenharmony_ci			   CS42L43_ASP_FSYNC_OUT_INV_MASK,
45762306a36Sopenharmony_ci			   fsync_ctrl);
45862306a36Sopenharmony_ci
45962306a36Sopenharmony_ci	return 0;
46062306a36Sopenharmony_ci}
46162306a36Sopenharmony_ci
46262306a36Sopenharmony_cistatic void cs42l43_mask_to_slots(struct cs42l43_codec *priv, unsigned int mask, int *slots)
46362306a36Sopenharmony_ci{
46462306a36Sopenharmony_ci	int i;
46562306a36Sopenharmony_ci
46662306a36Sopenharmony_ci	for (i = 0; i < CS42L43_ASP_MAX_CHANNELS; ++i) {
46762306a36Sopenharmony_ci		int slot = ffs(mask) - 1;
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_ci		if (slot < 0)
47062306a36Sopenharmony_ci			return;
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ci		slots[i] = slot;
47362306a36Sopenharmony_ci
47462306a36Sopenharmony_ci		mask &= ~(1 << slot);
47562306a36Sopenharmony_ci	}
47662306a36Sopenharmony_ci
47762306a36Sopenharmony_ci	if (mask)
47862306a36Sopenharmony_ci		dev_warn(priv->dev, "Too many channels in TDM mask\n");
47962306a36Sopenharmony_ci}
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_cistatic int cs42l43_asp_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
48262306a36Sopenharmony_ci				    unsigned int rx_mask, int slots, int slot_width)
48362306a36Sopenharmony_ci{
48462306a36Sopenharmony_ci	struct snd_soc_component *component = dai->component;
48562306a36Sopenharmony_ci	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_ci	priv->n_slots = slots;
48862306a36Sopenharmony_ci	priv->slot_width = slot_width;
48962306a36Sopenharmony_ci
49062306a36Sopenharmony_ci	if (!slots) {
49162306a36Sopenharmony_ci		tx_mask = CS42L43_DEFAULT_SLOTS;
49262306a36Sopenharmony_ci		rx_mask = CS42L43_DEFAULT_SLOTS;
49362306a36Sopenharmony_ci	}
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ci	cs42l43_mask_to_slots(priv, tx_mask, priv->tx_slots);
49662306a36Sopenharmony_ci	cs42l43_mask_to_slots(priv, rx_mask, priv->rx_slots);
49762306a36Sopenharmony_ci
49862306a36Sopenharmony_ci	return 0;
49962306a36Sopenharmony_ci}
50062306a36Sopenharmony_ci
50162306a36Sopenharmony_cistatic const struct snd_soc_dai_ops cs42l43_asp_ops = {
50262306a36Sopenharmony_ci	.startup	= cs42l43_startup,
50362306a36Sopenharmony_ci	.hw_params	= cs42l43_asp_hw_params,
50462306a36Sopenharmony_ci	.set_fmt	= cs42l43_asp_set_fmt,
50562306a36Sopenharmony_ci	.set_tdm_slot	= cs42l43_asp_set_tdm_slot,
50662306a36Sopenharmony_ci};
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_cistatic int cs42l43_sdw_hw_params(struct snd_pcm_substream *substream,
50962306a36Sopenharmony_ci				 struct snd_pcm_hw_params *params,
51062306a36Sopenharmony_ci				 struct snd_soc_dai *dai)
51162306a36Sopenharmony_ci{
51262306a36Sopenharmony_ci	int ret;
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_ci	ret = cs42l43_sdw_add_peripheral(substream, params, dai);
51562306a36Sopenharmony_ci	if (ret)
51662306a36Sopenharmony_ci		return ret;
51762306a36Sopenharmony_ci
51862306a36Sopenharmony_ci	return cs42l43_set_sample_rate(substream, params, dai);
51962306a36Sopenharmony_ci};
52062306a36Sopenharmony_ci
52162306a36Sopenharmony_cistatic const struct snd_soc_dai_ops cs42l43_sdw_ops = {
52262306a36Sopenharmony_ci	.startup	= cs42l43_startup,
52362306a36Sopenharmony_ci	.set_stream	= cs42l43_sdw_set_stream,
52462306a36Sopenharmony_ci	.hw_params	= cs42l43_sdw_hw_params,
52562306a36Sopenharmony_ci	.hw_free	= cs42l43_sdw_remove_peripheral,
52662306a36Sopenharmony_ci};
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_ci#define CS42L43_ASP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
52962306a36Sopenharmony_ci			     SNDRV_PCM_FMTBIT_S32_LE)
53062306a36Sopenharmony_ci#define CS42L43_SDW_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
53162306a36Sopenharmony_ci
53262306a36Sopenharmony_cistatic struct snd_soc_dai_driver cs42l43_dais[] = {
53362306a36Sopenharmony_ci	{
53462306a36Sopenharmony_ci		.name			= "cs42l43-asp",
53562306a36Sopenharmony_ci		.ops			= &cs42l43_asp_ops,
53662306a36Sopenharmony_ci		.symmetric_rate		= 1,
53762306a36Sopenharmony_ci		.capture = {
53862306a36Sopenharmony_ci			.stream_name	= "ASP Capture",
53962306a36Sopenharmony_ci			.channels_min	= 1,
54062306a36Sopenharmony_ci			.channels_max	= CS42L43_ASP_MAX_CHANNELS,
54162306a36Sopenharmony_ci			.rates		= SNDRV_PCM_RATE_KNOT,
54262306a36Sopenharmony_ci			.formats	= CS42L43_ASP_FORMATS,
54362306a36Sopenharmony_ci		},
54462306a36Sopenharmony_ci		.playback = {
54562306a36Sopenharmony_ci			.stream_name	= "ASP Playback",
54662306a36Sopenharmony_ci			.channels_min	= 1,
54762306a36Sopenharmony_ci			.channels_max	= CS42L43_ASP_MAX_CHANNELS,
54862306a36Sopenharmony_ci			.rates		= SNDRV_PCM_RATE_KNOT,
54962306a36Sopenharmony_ci			.formats	= CS42L43_ASP_FORMATS,
55062306a36Sopenharmony_ci		},
55162306a36Sopenharmony_ci	},
55262306a36Sopenharmony_ci	{
55362306a36Sopenharmony_ci		.name			= "cs42l43-dp1",
55462306a36Sopenharmony_ci		.id			= 1,
55562306a36Sopenharmony_ci		.ops			= &cs42l43_sdw_ops,
55662306a36Sopenharmony_ci		.capture = {
55762306a36Sopenharmony_ci			.stream_name	= "DP1 Capture",
55862306a36Sopenharmony_ci			.channels_min	= 1,
55962306a36Sopenharmony_ci			.channels_max	= 4,
56062306a36Sopenharmony_ci			.rates		= SNDRV_PCM_RATE_KNOT,
56162306a36Sopenharmony_ci			.formats	= CS42L43_SDW_FORMATS,
56262306a36Sopenharmony_ci		},
56362306a36Sopenharmony_ci	},
56462306a36Sopenharmony_ci	{
56562306a36Sopenharmony_ci		.name			= "cs42l43-dp2",
56662306a36Sopenharmony_ci		.id			= 2,
56762306a36Sopenharmony_ci		.ops			= &cs42l43_sdw_ops,
56862306a36Sopenharmony_ci		.capture = {
56962306a36Sopenharmony_ci			.stream_name	= "DP2 Capture",
57062306a36Sopenharmony_ci			.channels_min	= 1,
57162306a36Sopenharmony_ci			.channels_max	= 2,
57262306a36Sopenharmony_ci			.rates		= SNDRV_PCM_RATE_KNOT,
57362306a36Sopenharmony_ci			.formats	= CS42L43_SDW_FORMATS,
57462306a36Sopenharmony_ci		},
57562306a36Sopenharmony_ci	},
57662306a36Sopenharmony_ci	{
57762306a36Sopenharmony_ci		.name			= "cs42l43-dp3",
57862306a36Sopenharmony_ci		.id			= 3,
57962306a36Sopenharmony_ci		.ops			= &cs42l43_sdw_ops,
58062306a36Sopenharmony_ci		.capture = {
58162306a36Sopenharmony_ci			.stream_name	= "DP3 Capture",
58262306a36Sopenharmony_ci			.channels_min	= 1,
58362306a36Sopenharmony_ci			.channels_max	= 2,
58462306a36Sopenharmony_ci			.rates		= SNDRV_PCM_RATE_KNOT,
58562306a36Sopenharmony_ci			.formats	= CS42L43_SDW_FORMATS,
58662306a36Sopenharmony_ci		},
58762306a36Sopenharmony_ci	},
58862306a36Sopenharmony_ci	{
58962306a36Sopenharmony_ci		.name			= "cs42l43-dp4",
59062306a36Sopenharmony_ci		.id			= 4,
59162306a36Sopenharmony_ci		.ops			= &cs42l43_sdw_ops,
59262306a36Sopenharmony_ci		.capture = {
59362306a36Sopenharmony_ci			.stream_name	= "DP4 Capture",
59462306a36Sopenharmony_ci			.channels_min	= 1,
59562306a36Sopenharmony_ci			.channels_max	= 2,
59662306a36Sopenharmony_ci			.rates		= SNDRV_PCM_RATE_KNOT,
59762306a36Sopenharmony_ci			.formats	= CS42L43_SDW_FORMATS,
59862306a36Sopenharmony_ci		},
59962306a36Sopenharmony_ci	},
60062306a36Sopenharmony_ci	{
60162306a36Sopenharmony_ci		.name			= "cs42l43-dp5",
60262306a36Sopenharmony_ci		.id			= 5,
60362306a36Sopenharmony_ci		.ops			= &cs42l43_sdw_ops,
60462306a36Sopenharmony_ci		.playback = {
60562306a36Sopenharmony_ci			.stream_name	= "DP5 Playback",
60662306a36Sopenharmony_ci			.channels_min	= 1,
60762306a36Sopenharmony_ci			.channels_max	= 2,
60862306a36Sopenharmony_ci			.rates		= SNDRV_PCM_RATE_KNOT,
60962306a36Sopenharmony_ci			.formats	= CS42L43_SDW_FORMATS,
61062306a36Sopenharmony_ci		},
61162306a36Sopenharmony_ci	},
61262306a36Sopenharmony_ci	{
61362306a36Sopenharmony_ci		.name			= "cs42l43-dp6",
61462306a36Sopenharmony_ci		.id			= 6,
61562306a36Sopenharmony_ci		.ops			= &cs42l43_sdw_ops,
61662306a36Sopenharmony_ci		.playback = {
61762306a36Sopenharmony_ci			.stream_name	= "DP6 Playback",
61862306a36Sopenharmony_ci			.channels_min	= 1,
61962306a36Sopenharmony_ci			.channels_max	= 2,
62062306a36Sopenharmony_ci			.rates		= SNDRV_PCM_RATE_KNOT,
62162306a36Sopenharmony_ci			.formats	= CS42L43_SDW_FORMATS,
62262306a36Sopenharmony_ci		},
62362306a36Sopenharmony_ci	},
62462306a36Sopenharmony_ci	{
62562306a36Sopenharmony_ci		.name			= "cs42l43-dp7",
62662306a36Sopenharmony_ci		.id			= 7,
62762306a36Sopenharmony_ci		.ops			= &cs42l43_sdw_ops,
62862306a36Sopenharmony_ci		.playback = {
62962306a36Sopenharmony_ci			.stream_name	= "DP7 Playback",
63062306a36Sopenharmony_ci			.channels_min	= 1,
63162306a36Sopenharmony_ci			.channels_max	= 2,
63262306a36Sopenharmony_ci			.rates		= SNDRV_PCM_RATE_KNOT,
63362306a36Sopenharmony_ci			.formats	= CS42L43_SDW_FORMATS,
63462306a36Sopenharmony_ci		},
63562306a36Sopenharmony_ci	},
63662306a36Sopenharmony_ci};
63762306a36Sopenharmony_ci
63862306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(cs42l43_mixer_tlv, -3200, 100, 0);
63962306a36Sopenharmony_ci
64062306a36Sopenharmony_cistatic const char * const cs42l43_ramp_text[] = {
64162306a36Sopenharmony_ci	"0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",
64262306a36Sopenharmony_ci	"15ms/6dB", "30ms/6dB",
64362306a36Sopenharmony_ci};
64462306a36Sopenharmony_ci
64562306a36Sopenharmony_cistatic const char * const cs42l43_adc1_input_text[] = { "IN1", "IN2" };
64662306a36Sopenharmony_ci
64762306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(cs42l43_adc1_input, CS42L43_ADC_B_CTRL1,
64862306a36Sopenharmony_ci			    CS42L43_ADC_AIN_SEL_SHIFT,
64962306a36Sopenharmony_ci			    cs42l43_adc1_input_text);
65062306a36Sopenharmony_ci
65162306a36Sopenharmony_cistatic const struct snd_kcontrol_new cs42l43_adc1_input_ctl =
65262306a36Sopenharmony_ci	SOC_DAPM_ENUM("ADC1 Input", cs42l43_adc1_input);
65362306a36Sopenharmony_ci
65462306a36Sopenharmony_cistatic const char * const cs42l43_dec_mode_text[] = { "ADC", "PDM" };
65562306a36Sopenharmony_ci
65662306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_VIRT_DECL(cs42l43_dec1_mode, cs42l43_dec_mode_text);
65762306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_VIRT_DECL(cs42l43_dec2_mode, cs42l43_dec_mode_text);
65862306a36Sopenharmony_ci
65962306a36Sopenharmony_cistatic const struct snd_kcontrol_new cs42l43_dec_mode_ctl[] = {
66062306a36Sopenharmony_ci	SOC_DAPM_ENUM("Decimator 1 Mode", cs42l43_dec1_mode),
66162306a36Sopenharmony_ci	SOC_DAPM_ENUM("Decimator 2 Mode", cs42l43_dec2_mode),
66262306a36Sopenharmony_ci};
66362306a36Sopenharmony_ci
66462306a36Sopenharmony_cistatic const char * const cs42l43_pdm_clk_text[] = {
66562306a36Sopenharmony_ci	"3.072MHz", "1.536MHz", "768kHz",
66662306a36Sopenharmony_ci};
66762306a36Sopenharmony_ci
66862306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(cs42l43_pdm1_clk, CS42L43_PDM_CONTROL,
66962306a36Sopenharmony_ci			    CS42L43_PDM1_CLK_DIV_SHIFT, cs42l43_pdm_clk_text);
67062306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(cs42l43_pdm2_clk, CS42L43_PDM_CONTROL,
67162306a36Sopenharmony_ci			    CS42L43_PDM2_CLK_DIV_SHIFT, cs42l43_pdm_clk_text);
67262306a36Sopenharmony_ci
67362306a36Sopenharmony_cistatic DECLARE_TLV_DB_SCALE(cs42l43_adc_tlv, -600, 600, 0);
67462306a36Sopenharmony_cistatic DECLARE_TLV_DB_SCALE(cs42l43_dec_tlv, -6400, 50, 0);
67562306a36Sopenharmony_ci
67662306a36Sopenharmony_cistatic const char * const cs42l43_wnf_corner_text[] = {
67762306a36Sopenharmony_ci	"160Hz", "180Hz", "200Hz", "220Hz", "240Hz", "260Hz", "280Hz", "300Hz",
67862306a36Sopenharmony_ci};
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(cs42l43_dec1_wnf_corner, CS42L43_DECIM_HPF_WNF_CTRL1,
68162306a36Sopenharmony_ci			    CS42L43_DECIM_WNF_CF_SHIFT, cs42l43_wnf_corner_text);
68262306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(cs42l43_dec2_wnf_corner, CS42L43_DECIM_HPF_WNF_CTRL2,
68362306a36Sopenharmony_ci			    CS42L43_DECIM_WNF_CF_SHIFT, cs42l43_wnf_corner_text);
68462306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(cs42l43_dec3_wnf_corner, CS42L43_DECIM_HPF_WNF_CTRL3,
68562306a36Sopenharmony_ci			    CS42L43_DECIM_WNF_CF_SHIFT, cs42l43_wnf_corner_text);
68662306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(cs42l43_dec4_wnf_corner, CS42L43_DECIM_HPF_WNF_CTRL4,
68762306a36Sopenharmony_ci			    CS42L43_DECIM_WNF_CF_SHIFT, cs42l43_wnf_corner_text);
68862306a36Sopenharmony_ci
68962306a36Sopenharmony_cistatic const char * const cs42l43_hpf_corner_text[] = {
69062306a36Sopenharmony_ci	"3Hz", "12Hz", "48Hz", "96Hz",
69162306a36Sopenharmony_ci};
69262306a36Sopenharmony_ci
69362306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(cs42l43_dec1_hpf_corner, CS42L43_DECIM_HPF_WNF_CTRL1,
69462306a36Sopenharmony_ci			    CS42L43_DECIM_HPF_CF_SHIFT, cs42l43_hpf_corner_text);
69562306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(cs42l43_dec2_hpf_corner, CS42L43_DECIM_HPF_WNF_CTRL2,
69662306a36Sopenharmony_ci			    CS42L43_DECIM_HPF_CF_SHIFT, cs42l43_hpf_corner_text);
69762306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(cs42l43_dec3_hpf_corner, CS42L43_DECIM_HPF_WNF_CTRL3,
69862306a36Sopenharmony_ci			    CS42L43_DECIM_HPF_CF_SHIFT, cs42l43_hpf_corner_text);
69962306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(cs42l43_dec4_hpf_corner, CS42L43_DECIM_HPF_WNF_CTRL4,
70062306a36Sopenharmony_ci			    CS42L43_DECIM_HPF_CF_SHIFT, cs42l43_hpf_corner_text);
70162306a36Sopenharmony_ci
70262306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(cs42l43_dec1_ramp_up, CS42L43_DECIM_VOL_CTRL_CH1_CH2,
70362306a36Sopenharmony_ci			    CS42L43_DECIM1_VI_RAMP_SHIFT, cs42l43_ramp_text);
70462306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(cs42l43_dec1_ramp_down, CS42L43_DECIM_VOL_CTRL_CH1_CH2,
70562306a36Sopenharmony_ci			    CS42L43_DECIM1_VD_RAMP_SHIFT, cs42l43_ramp_text);
70662306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(cs42l43_dec2_ramp_up, CS42L43_DECIM_VOL_CTRL_CH1_CH2,
70762306a36Sopenharmony_ci			    CS42L43_DECIM2_VI_RAMP_SHIFT, cs42l43_ramp_text);
70862306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(cs42l43_dec2_ramp_down, CS42L43_DECIM_VOL_CTRL_CH1_CH2,
70962306a36Sopenharmony_ci			    CS42L43_DECIM2_VD_RAMP_SHIFT, cs42l43_ramp_text);
71062306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(cs42l43_dec3_ramp_up, CS42L43_DECIM_VOL_CTRL_CH3_CH4,
71162306a36Sopenharmony_ci			    CS42L43_DECIM3_VI_RAMP_SHIFT, cs42l43_ramp_text);
71262306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(cs42l43_dec3_ramp_down, CS42L43_DECIM_VOL_CTRL_CH3_CH4,
71362306a36Sopenharmony_ci			    CS42L43_DECIM3_VD_RAMP_SHIFT, cs42l43_ramp_text);
71462306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(cs42l43_dec4_ramp_up, CS42L43_DECIM_VOL_CTRL_CH3_CH4,
71562306a36Sopenharmony_ci			    CS42L43_DECIM4_VI_RAMP_SHIFT, cs42l43_ramp_text);
71662306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(cs42l43_dec4_ramp_down, CS42L43_DECIM_VOL_CTRL_CH3_CH4,
71762306a36Sopenharmony_ci			    CS42L43_DECIM4_VD_RAMP_SHIFT, cs42l43_ramp_text);
71862306a36Sopenharmony_ci
71962306a36Sopenharmony_cistatic DECLARE_TLV_DB_SCALE(cs42l43_speaker_tlv, -6400, 50, 0);
72062306a36Sopenharmony_ci
72162306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(cs42l43_speaker_ramp_up, CS42L43_AMP1_2_VOL_RAMP,
72262306a36Sopenharmony_ci			    CS42L43_AMP1_2_VI_RAMP_SHIFT, cs42l43_ramp_text);
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(cs42l43_speaker_ramp_down, CS42L43_AMP1_2_VOL_RAMP,
72562306a36Sopenharmony_ci			    CS42L43_AMP1_2_VD_RAMP_SHIFT, cs42l43_ramp_text);
72662306a36Sopenharmony_ci
72762306a36Sopenharmony_cistatic DECLARE_TLV_DB_SCALE(cs42l43_headphone_tlv, -11450, 50, 1);
72862306a36Sopenharmony_ci
72962306a36Sopenharmony_cistatic const char * const cs42l43_headphone_ramp_text[] = {
73062306a36Sopenharmony_ci	"1", "2", "4", "6", "8", "11", "12", "16", "22", "24", "33", "36", "44",
73162306a36Sopenharmony_ci	"48", "66", "72",
73262306a36Sopenharmony_ci};
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(cs42l43_headphone_ramp, CS42L43_PGAVOL,
73562306a36Sopenharmony_ci			    CS42L43_HP_PATH_VOL_RAMP_SHIFT,
73662306a36Sopenharmony_ci			    cs42l43_headphone_ramp_text);
73762306a36Sopenharmony_ci
73862306a36Sopenharmony_cistatic const char * const cs42l43_tone_freq_text[] = {
73962306a36Sopenharmony_ci	"1kHz", "2kHz", "4kHz", "6kHz", "8kHz",
74062306a36Sopenharmony_ci};
74162306a36Sopenharmony_ci
74262306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(cs42l43_tone1_freq, CS42L43_TONE_CH1_CTRL,
74362306a36Sopenharmony_ci			    CS42L43_TONE_FREQ_SHIFT, cs42l43_tone_freq_text);
74462306a36Sopenharmony_ci
74562306a36Sopenharmony_cistatic SOC_ENUM_SINGLE_DECL(cs42l43_tone2_freq, CS42L43_TONE_CH2_CTRL,
74662306a36Sopenharmony_ci			    CS42L43_TONE_FREQ_SHIFT, cs42l43_tone_freq_text);
74762306a36Sopenharmony_ci
74862306a36Sopenharmony_cistatic const char * const cs42l43_mixer_texts[] = {
74962306a36Sopenharmony_ci	"None",
75062306a36Sopenharmony_ci	"Tone Generator 1", "Tone Generator 2",
75162306a36Sopenharmony_ci	"Decimator 1", "Decimator 2", "Decimator 3", "Decimator 4",
75262306a36Sopenharmony_ci	"ASPRX1", "ASPRX2", "ASPRX3", "ASPRX4", "ASPRX5", "ASPRX6",
75362306a36Sopenharmony_ci	"DP5RX1", "DP5RX2", "DP6RX1", "DP6RX2", "DP7RX1", "DP7RX2",
75462306a36Sopenharmony_ci	"ASRC INT1", "ASRC INT2", "ASRC INT3", "ASRC INT4",
75562306a36Sopenharmony_ci	"ASRC DEC1", "ASRC DEC2", "ASRC DEC3", "ASRC DEC4",
75662306a36Sopenharmony_ci	"ISRC1 INT1", "ISRC1 INT2",
75762306a36Sopenharmony_ci	"ISRC1 DEC1", "ISRC1 DEC2",
75862306a36Sopenharmony_ci	"ISRC2 INT1", "ISRC2 INT2",
75962306a36Sopenharmony_ci	"ISRC2 DEC1", "ISRC2 DEC2",
76062306a36Sopenharmony_ci	"EQ1", "EQ2",
76162306a36Sopenharmony_ci};
76262306a36Sopenharmony_ci
76362306a36Sopenharmony_cistatic const unsigned int cs42l43_mixer_values[] = {
76462306a36Sopenharmony_ci	0x00, // None
76562306a36Sopenharmony_ci	0x04, 0x05, // Tone Generator 1, 2
76662306a36Sopenharmony_ci	0x10, 0x11, 0x12, 0x13, // Decimator 1, 2, 3, 4
76762306a36Sopenharmony_ci	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, // ASPRX1,2,3,4,5,6
76862306a36Sopenharmony_ci	0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, // DP5, 6, 7RX1, 2
76962306a36Sopenharmony_ci	0x40, 0x41, 0x42, 0x43, // ASRC INT1, 2, 3, 4
77062306a36Sopenharmony_ci	0x44, 0x45, 0x46, 0x47, // ASRC DEC1, 2, 3, 4
77162306a36Sopenharmony_ci	0x50, 0x51, // ISRC1 INT1, 2
77262306a36Sopenharmony_ci	0x52, 0x53, // ISRC1 DEC1, 2
77362306a36Sopenharmony_ci	0x54, 0x55, // ISRC2 INT1, 2
77462306a36Sopenharmony_ci	0x56, 0x57, // ISRC2 DEC1, 2
77562306a36Sopenharmony_ci	0x58, 0x59, // EQ1, 2
77662306a36Sopenharmony_ci};
77762306a36Sopenharmony_ci
77862306a36Sopenharmony_ciCS42L43_DECL_MUX(asptx1, CS42L43_ASPTX1_INPUT);
77962306a36Sopenharmony_ciCS42L43_DECL_MUX(asptx2, CS42L43_ASPTX2_INPUT);
78062306a36Sopenharmony_ciCS42L43_DECL_MUX(asptx3, CS42L43_ASPTX3_INPUT);
78162306a36Sopenharmony_ciCS42L43_DECL_MUX(asptx4, CS42L43_ASPTX4_INPUT);
78262306a36Sopenharmony_ciCS42L43_DECL_MUX(asptx5, CS42L43_ASPTX5_INPUT);
78362306a36Sopenharmony_ciCS42L43_DECL_MUX(asptx6, CS42L43_ASPTX6_INPUT);
78462306a36Sopenharmony_ci
78562306a36Sopenharmony_ciCS42L43_DECL_MUX(dp1tx1, CS42L43_SWIRE_DP1_CH1_INPUT);
78662306a36Sopenharmony_ciCS42L43_DECL_MUX(dp1tx2, CS42L43_SWIRE_DP1_CH2_INPUT);
78762306a36Sopenharmony_ciCS42L43_DECL_MUX(dp1tx3, CS42L43_SWIRE_DP1_CH3_INPUT);
78862306a36Sopenharmony_ciCS42L43_DECL_MUX(dp1tx4, CS42L43_SWIRE_DP1_CH4_INPUT);
78962306a36Sopenharmony_ciCS42L43_DECL_MUX(dp2tx1, CS42L43_SWIRE_DP2_CH1_INPUT);
79062306a36Sopenharmony_ciCS42L43_DECL_MUX(dp2tx2, CS42L43_SWIRE_DP2_CH2_INPUT);
79162306a36Sopenharmony_ciCS42L43_DECL_MUX(dp3tx1, CS42L43_SWIRE_DP3_CH1_INPUT);
79262306a36Sopenharmony_ciCS42L43_DECL_MUX(dp3tx2, CS42L43_SWIRE_DP3_CH2_INPUT);
79362306a36Sopenharmony_ciCS42L43_DECL_MUX(dp4tx1, CS42L43_SWIRE_DP4_CH1_INPUT);
79462306a36Sopenharmony_ciCS42L43_DECL_MUX(dp4tx2, CS42L43_SWIRE_DP4_CH2_INPUT);
79562306a36Sopenharmony_ci
79662306a36Sopenharmony_ciCS42L43_DECL_MUX(asrcint1, CS42L43_ASRC_INT1_INPUT1);
79762306a36Sopenharmony_ciCS42L43_DECL_MUX(asrcint2, CS42L43_ASRC_INT2_INPUT1);
79862306a36Sopenharmony_ciCS42L43_DECL_MUX(asrcint3, CS42L43_ASRC_INT3_INPUT1);
79962306a36Sopenharmony_ciCS42L43_DECL_MUX(asrcint4, CS42L43_ASRC_INT4_INPUT1);
80062306a36Sopenharmony_ciCS42L43_DECL_MUX(asrcdec1, CS42L43_ASRC_DEC1_INPUT1);
80162306a36Sopenharmony_ciCS42L43_DECL_MUX(asrcdec2, CS42L43_ASRC_DEC2_INPUT1);
80262306a36Sopenharmony_ciCS42L43_DECL_MUX(asrcdec3, CS42L43_ASRC_DEC3_INPUT1);
80362306a36Sopenharmony_ciCS42L43_DECL_MUX(asrcdec4, CS42L43_ASRC_DEC4_INPUT1);
80462306a36Sopenharmony_ci
80562306a36Sopenharmony_ciCS42L43_DECL_MUX(isrc1int1, CS42L43_ISRC1INT1_INPUT1);
80662306a36Sopenharmony_ciCS42L43_DECL_MUX(isrc1int2, CS42L43_ISRC1INT2_INPUT1);
80762306a36Sopenharmony_ciCS42L43_DECL_MUX(isrc1dec1, CS42L43_ISRC1DEC1_INPUT1);
80862306a36Sopenharmony_ciCS42L43_DECL_MUX(isrc1dec2, CS42L43_ISRC1DEC2_INPUT1);
80962306a36Sopenharmony_ciCS42L43_DECL_MUX(isrc2int1, CS42L43_ISRC2INT1_INPUT1);
81062306a36Sopenharmony_ciCS42L43_DECL_MUX(isrc2int2, CS42L43_ISRC2INT2_INPUT1);
81162306a36Sopenharmony_ciCS42L43_DECL_MUX(isrc2dec1, CS42L43_ISRC2DEC1_INPUT1);
81262306a36Sopenharmony_ciCS42L43_DECL_MUX(isrc2dec2, CS42L43_ISRC2DEC2_INPUT1);
81362306a36Sopenharmony_ci
81462306a36Sopenharmony_ciCS42L43_DECL_MUX(spdif1, CS42L43_SPDIF1_INPUT1);
81562306a36Sopenharmony_ciCS42L43_DECL_MUX(spdif2, CS42L43_SPDIF2_INPUT1);
81662306a36Sopenharmony_ci
81762306a36Sopenharmony_ciCS42L43_DECL_MIXER(eq1, CS42L43_EQ1MIX_INPUT1);
81862306a36Sopenharmony_ciCS42L43_DECL_MIXER(eq2, CS42L43_EQ2MIX_INPUT1);
81962306a36Sopenharmony_ci
82062306a36Sopenharmony_ciCS42L43_DECL_MIXER(amp1, CS42L43_AMP1MIX_INPUT1);
82162306a36Sopenharmony_ciCS42L43_DECL_MIXER(amp2, CS42L43_AMP2MIX_INPUT1);
82262306a36Sopenharmony_ci
82362306a36Sopenharmony_ciCS42L43_DECL_MIXER(amp3, CS42L43_AMP3MIX_INPUT1);
82462306a36Sopenharmony_ciCS42L43_DECL_MIXER(amp4, CS42L43_AMP4MIX_INPUT1);
82562306a36Sopenharmony_ci
82662306a36Sopenharmony_cistatic int cs42l43_dapm_get_volsw(struct snd_kcontrol *kcontrol,
82762306a36Sopenharmony_ci				  struct snd_ctl_elem_value *ucontrol)
82862306a36Sopenharmony_ci{
82962306a36Sopenharmony_ci	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
83062306a36Sopenharmony_ci	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
83162306a36Sopenharmony_ci	int ret;
83262306a36Sopenharmony_ci
83362306a36Sopenharmony_ci	snd_soc_dapm_mutex_lock(dapm);
83462306a36Sopenharmony_ci	ret = snd_soc_get_volsw(kcontrol, ucontrol);
83562306a36Sopenharmony_ci	snd_soc_dapm_mutex_unlock(dapm);
83662306a36Sopenharmony_ci
83762306a36Sopenharmony_ci	return ret;
83862306a36Sopenharmony_ci}
83962306a36Sopenharmony_ci
84062306a36Sopenharmony_cistatic int cs42l43_dapm_put_volsw(struct snd_kcontrol *kcontrol,
84162306a36Sopenharmony_ci				  struct snd_ctl_elem_value *ucontrol)
84262306a36Sopenharmony_ci{
84362306a36Sopenharmony_ci	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
84462306a36Sopenharmony_ci	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
84562306a36Sopenharmony_ci	int ret;
84662306a36Sopenharmony_ci
84762306a36Sopenharmony_ci	snd_soc_dapm_mutex_lock(dapm);
84862306a36Sopenharmony_ci	ret = snd_soc_put_volsw(kcontrol, ucontrol);
84962306a36Sopenharmony_ci	snd_soc_dapm_mutex_unlock(dapm);
85062306a36Sopenharmony_ci
85162306a36Sopenharmony_ci	return ret;
85262306a36Sopenharmony_ci}
85362306a36Sopenharmony_ci
85462306a36Sopenharmony_cistatic int cs42l43_dapm_get_enum(struct snd_kcontrol *kcontrol,
85562306a36Sopenharmony_ci				 struct snd_ctl_elem_value *ucontrol)
85662306a36Sopenharmony_ci{
85762306a36Sopenharmony_ci	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
85862306a36Sopenharmony_ci	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
85962306a36Sopenharmony_ci	int ret;
86062306a36Sopenharmony_ci
86162306a36Sopenharmony_ci	snd_soc_dapm_mutex_lock(dapm);
86262306a36Sopenharmony_ci	ret = snd_soc_get_enum_double(kcontrol, ucontrol);
86362306a36Sopenharmony_ci	snd_soc_dapm_mutex_unlock(dapm);
86462306a36Sopenharmony_ci
86562306a36Sopenharmony_ci	return ret;
86662306a36Sopenharmony_ci}
86762306a36Sopenharmony_ci
86862306a36Sopenharmony_cistatic int cs42l43_dapm_put_enum(struct snd_kcontrol *kcontrol,
86962306a36Sopenharmony_ci				 struct snd_ctl_elem_value *ucontrol)
87062306a36Sopenharmony_ci{
87162306a36Sopenharmony_ci	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
87262306a36Sopenharmony_ci	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
87362306a36Sopenharmony_ci	int ret;
87462306a36Sopenharmony_ci
87562306a36Sopenharmony_ci	snd_soc_dapm_mutex_lock(dapm);
87662306a36Sopenharmony_ci	ret = snd_soc_put_enum_double(kcontrol, ucontrol);
87762306a36Sopenharmony_ci	snd_soc_dapm_mutex_unlock(dapm);
87862306a36Sopenharmony_ci
87962306a36Sopenharmony_ci	return ret;
88062306a36Sopenharmony_ci}
88162306a36Sopenharmony_ci
88262306a36Sopenharmony_cistatic int cs42l43_eq_get(struct snd_kcontrol *kcontrol,
88362306a36Sopenharmony_ci			  struct snd_ctl_elem_value *ucontrol)
88462306a36Sopenharmony_ci{
88562306a36Sopenharmony_ci	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
88662306a36Sopenharmony_ci	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
88762306a36Sopenharmony_ci
88862306a36Sopenharmony_ci	memcpy(ucontrol->value.integer.value, priv->eq_coeffs, sizeof(priv->eq_coeffs));
88962306a36Sopenharmony_ci
89062306a36Sopenharmony_ci	return 0;
89162306a36Sopenharmony_ci}
89262306a36Sopenharmony_ci
89362306a36Sopenharmony_cistatic int cs42l43_eq_put(struct snd_kcontrol *kcontrol,
89462306a36Sopenharmony_ci			  struct snd_ctl_elem_value *ucontrol)
89562306a36Sopenharmony_ci{
89662306a36Sopenharmony_ci	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
89762306a36Sopenharmony_ci	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
89862306a36Sopenharmony_ci	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
89962306a36Sopenharmony_ci
90062306a36Sopenharmony_ci	snd_soc_dapm_mutex_lock(dapm);
90162306a36Sopenharmony_ci
90262306a36Sopenharmony_ci	memcpy(priv->eq_coeffs, ucontrol->value.integer.value, sizeof(priv->eq_coeffs));
90362306a36Sopenharmony_ci
90462306a36Sopenharmony_ci	snd_soc_dapm_mutex_unlock(dapm);
90562306a36Sopenharmony_ci
90662306a36Sopenharmony_ci	return 0;
90762306a36Sopenharmony_ci}
90862306a36Sopenharmony_ci
90962306a36Sopenharmony_cistatic void cs42l43_spk_vu_sync(struct cs42l43_codec *priv)
91062306a36Sopenharmony_ci{
91162306a36Sopenharmony_ci	struct cs42l43 *cs42l43 = priv->core;
91262306a36Sopenharmony_ci
91362306a36Sopenharmony_ci	mutex_lock(&priv->spk_vu_lock);
91462306a36Sopenharmony_ci
91562306a36Sopenharmony_ci	regmap_update_bits(cs42l43->regmap, CS42L43_INTP_VOLUME_CTRL1,
91662306a36Sopenharmony_ci			   CS42L43_AMP1_2_VU_MASK, CS42L43_AMP1_2_VU_MASK);
91762306a36Sopenharmony_ci	regmap_update_bits(cs42l43->regmap, CS42L43_INTP_VOLUME_CTRL1,
91862306a36Sopenharmony_ci			   CS42L43_AMP1_2_VU_MASK, 0);
91962306a36Sopenharmony_ci
92062306a36Sopenharmony_ci	mutex_unlock(&priv->spk_vu_lock);
92162306a36Sopenharmony_ci}
92262306a36Sopenharmony_ci
92362306a36Sopenharmony_cistatic int cs42l43_shutter_get(struct cs42l43_codec *priv, unsigned int shift)
92462306a36Sopenharmony_ci{
92562306a36Sopenharmony_ci	struct cs42l43 *cs42l43 = priv->core;
92662306a36Sopenharmony_ci	unsigned int val;
92762306a36Sopenharmony_ci	int ret;
92862306a36Sopenharmony_ci
92962306a36Sopenharmony_ci	ret = pm_runtime_resume_and_get(priv->dev);
93062306a36Sopenharmony_ci	if (ret) {
93162306a36Sopenharmony_ci		dev_err(priv->dev, "Failed to resume for shutters: %d\n", ret);
93262306a36Sopenharmony_ci		return ret;
93362306a36Sopenharmony_ci	}
93462306a36Sopenharmony_ci
93562306a36Sopenharmony_ci	/*
93662306a36Sopenharmony_ci	 * SHUTTER_CONTROL is a mix of volatile and non-volatile bits, so must
93762306a36Sopenharmony_ci	 * be cached for the non-volatiles, so drop it from the cache here so
93862306a36Sopenharmony_ci	 * we force a read.
93962306a36Sopenharmony_ci	 */
94062306a36Sopenharmony_ci	ret = regcache_drop_region(cs42l43->regmap, CS42L43_SHUTTER_CONTROL,
94162306a36Sopenharmony_ci				   CS42L43_SHUTTER_CONTROL);
94262306a36Sopenharmony_ci	if (ret) {
94362306a36Sopenharmony_ci		dev_err(priv->dev, "Failed to drop shutter from cache: %d\n", ret);
94462306a36Sopenharmony_ci		goto error;
94562306a36Sopenharmony_ci	}
94662306a36Sopenharmony_ci
94762306a36Sopenharmony_ci	ret = regmap_read(cs42l43->regmap, CS42L43_SHUTTER_CONTROL, &val);
94862306a36Sopenharmony_ci	if (ret) {
94962306a36Sopenharmony_ci		dev_err(priv->dev, "Failed to check shutter status: %d\n", ret);
95062306a36Sopenharmony_ci		goto error;
95162306a36Sopenharmony_ci	}
95262306a36Sopenharmony_ci
95362306a36Sopenharmony_ci	ret = !(val & BIT(shift));
95462306a36Sopenharmony_ci
95562306a36Sopenharmony_ci	dev_dbg(priv->dev, "%s shutter is %s\n",
95662306a36Sopenharmony_ci		BIT(shift) == CS42L43_STATUS_MIC_SHUTTER_MUTE_MASK ? "Mic" : "Speaker",
95762306a36Sopenharmony_ci		ret ? "open" : "closed");
95862306a36Sopenharmony_ci
95962306a36Sopenharmony_cierror:
96062306a36Sopenharmony_ci	pm_runtime_mark_last_busy(priv->dev);
96162306a36Sopenharmony_ci	pm_runtime_put_autosuspend(priv->dev);
96262306a36Sopenharmony_ci
96362306a36Sopenharmony_ci	return ret;
96462306a36Sopenharmony_ci}
96562306a36Sopenharmony_ci
96662306a36Sopenharmony_cistatic int cs42l43_decim_get(struct snd_kcontrol *kcontrol,
96762306a36Sopenharmony_ci			     struct snd_ctl_elem_value *ucontrol)
96862306a36Sopenharmony_ci{
96962306a36Sopenharmony_ci	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
97062306a36Sopenharmony_ci	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
97162306a36Sopenharmony_ci	int ret;
97262306a36Sopenharmony_ci
97362306a36Sopenharmony_ci	ret = cs42l43_shutter_get(priv, CS42L43_STATUS_MIC_SHUTTER_MUTE_SHIFT);
97462306a36Sopenharmony_ci	if (ret < 0)
97562306a36Sopenharmony_ci		return ret;
97662306a36Sopenharmony_ci	else if (!ret)
97762306a36Sopenharmony_ci		ucontrol->value.integer.value[0] = ret;
97862306a36Sopenharmony_ci	else
97962306a36Sopenharmony_ci		ret = cs42l43_dapm_get_volsw(kcontrol, ucontrol);
98062306a36Sopenharmony_ci
98162306a36Sopenharmony_ci	return ret;
98262306a36Sopenharmony_ci}
98362306a36Sopenharmony_ci
98462306a36Sopenharmony_cistatic int cs42l43_spk_get(struct snd_kcontrol *kcontrol,
98562306a36Sopenharmony_ci			   struct snd_ctl_elem_value *ucontrol)
98662306a36Sopenharmony_ci{
98762306a36Sopenharmony_ci	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
98862306a36Sopenharmony_ci	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
98962306a36Sopenharmony_ci	int ret;
99062306a36Sopenharmony_ci
99162306a36Sopenharmony_ci	ret = cs42l43_shutter_get(priv, CS42L43_STATUS_SPK_SHUTTER_MUTE_SHIFT);
99262306a36Sopenharmony_ci	if (ret < 0)
99362306a36Sopenharmony_ci		return ret;
99462306a36Sopenharmony_ci	else if (!ret)
99562306a36Sopenharmony_ci		ucontrol->value.integer.value[0] = ret;
99662306a36Sopenharmony_ci	else
99762306a36Sopenharmony_ci		ret = snd_soc_get_volsw(kcontrol, ucontrol);
99862306a36Sopenharmony_ci
99962306a36Sopenharmony_ci	return ret;
100062306a36Sopenharmony_ci}
100162306a36Sopenharmony_ci
100262306a36Sopenharmony_cistatic int cs42l43_spk_put(struct snd_kcontrol *kcontrol,
100362306a36Sopenharmony_ci			   struct snd_ctl_elem_value *ucontrol)
100462306a36Sopenharmony_ci{
100562306a36Sopenharmony_ci	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
100662306a36Sopenharmony_ci	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
100762306a36Sopenharmony_ci	int ret;
100862306a36Sopenharmony_ci
100962306a36Sopenharmony_ci	ret = snd_soc_put_volsw(kcontrol, ucontrol);
101062306a36Sopenharmony_ci	if (ret > 0)
101162306a36Sopenharmony_ci		cs42l43_spk_vu_sync(priv);
101262306a36Sopenharmony_ci
101362306a36Sopenharmony_ci	return ret;
101462306a36Sopenharmony_ci}
101562306a36Sopenharmony_ci
101662306a36Sopenharmony_cistatic const struct snd_kcontrol_new cs42l43_controls[] = {
101762306a36Sopenharmony_ci	SOC_ENUM_EXT("Jack Override", cs42l43_jack_enum,
101862306a36Sopenharmony_ci		     cs42l43_jack_get, cs42l43_jack_put),
101962306a36Sopenharmony_ci
102062306a36Sopenharmony_ci	SOC_DOUBLE_R_SX_TLV("ADC Volume", CS42L43_ADC_B_CTRL1, CS42L43_ADC_B_CTRL2,
102162306a36Sopenharmony_ci			    CS42L43_ADC_PGA_GAIN_SHIFT,
102262306a36Sopenharmony_ci			    0xF, 5, cs42l43_adc_tlv),
102362306a36Sopenharmony_ci
102462306a36Sopenharmony_ci	SOC_DOUBLE("PDM1 Invert Switch", CS42L43_DMIC_PDM_CTRL,
102562306a36Sopenharmony_ci		   CS42L43_PDM1L_INV_SHIFT, CS42L43_PDM1R_INV_SHIFT, 1, 0),
102662306a36Sopenharmony_ci	SOC_DOUBLE("PDM2 Invert Switch", CS42L43_DMIC_PDM_CTRL,
102762306a36Sopenharmony_ci		   CS42L43_PDM2L_INV_SHIFT, CS42L43_PDM2R_INV_SHIFT, 1, 0),
102862306a36Sopenharmony_ci	SOC_ENUM("PDM1 Clock", cs42l43_pdm1_clk),
102962306a36Sopenharmony_ci	SOC_ENUM("PDM2 Clock", cs42l43_pdm2_clk),
103062306a36Sopenharmony_ci
103162306a36Sopenharmony_ci	SOC_SINGLE("Decimator 1 WNF Switch", CS42L43_DECIM_HPF_WNF_CTRL1,
103262306a36Sopenharmony_ci		   CS42L43_DECIM_WNF_EN_SHIFT, 1, 0),
103362306a36Sopenharmony_ci	SOC_SINGLE("Decimator 2 WNF Switch", CS42L43_DECIM_HPF_WNF_CTRL2,
103462306a36Sopenharmony_ci		   CS42L43_DECIM_WNF_EN_SHIFT, 1, 0),
103562306a36Sopenharmony_ci	SOC_SINGLE("Decimator 3 WNF Switch", CS42L43_DECIM_HPF_WNF_CTRL3,
103662306a36Sopenharmony_ci		   CS42L43_DECIM_WNF_EN_SHIFT, 1, 0),
103762306a36Sopenharmony_ci	SOC_SINGLE("Decimator 4 WNF Switch", CS42L43_DECIM_HPF_WNF_CTRL4,
103862306a36Sopenharmony_ci		   CS42L43_DECIM_WNF_EN_SHIFT, 1, 0),
103962306a36Sopenharmony_ci
104062306a36Sopenharmony_ci	SOC_ENUM("Decimator 1 WNF Corner Frequency", cs42l43_dec1_wnf_corner),
104162306a36Sopenharmony_ci	SOC_ENUM("Decimator 2 WNF Corner Frequency", cs42l43_dec2_wnf_corner),
104262306a36Sopenharmony_ci	SOC_ENUM("Decimator 3 WNF Corner Frequency", cs42l43_dec3_wnf_corner),
104362306a36Sopenharmony_ci	SOC_ENUM("Decimator 4 WNF Corner Frequency", cs42l43_dec4_wnf_corner),
104462306a36Sopenharmony_ci
104562306a36Sopenharmony_ci	SOC_SINGLE("Decimator 1 HPF Switch", CS42L43_DECIM_HPF_WNF_CTRL1,
104662306a36Sopenharmony_ci		   CS42L43_DECIM_HPF_EN_SHIFT, 1, 0),
104762306a36Sopenharmony_ci	SOC_SINGLE("Decimator 2 HPF Switch", CS42L43_DECIM_HPF_WNF_CTRL2,
104862306a36Sopenharmony_ci		   CS42L43_DECIM_HPF_EN_SHIFT, 1, 0),
104962306a36Sopenharmony_ci	SOC_SINGLE("Decimator 3 HPF Switch", CS42L43_DECIM_HPF_WNF_CTRL3,
105062306a36Sopenharmony_ci		   CS42L43_DECIM_HPF_EN_SHIFT, 1, 0),
105162306a36Sopenharmony_ci	SOC_SINGLE("Decimator 4 HPF Switch", CS42L43_DECIM_HPF_WNF_CTRL4,
105262306a36Sopenharmony_ci		   CS42L43_DECIM_HPF_EN_SHIFT, 1, 0),
105362306a36Sopenharmony_ci
105462306a36Sopenharmony_ci	SOC_ENUM("Decimator 1 HPF Corner Frequency", cs42l43_dec1_hpf_corner),
105562306a36Sopenharmony_ci	SOC_ENUM("Decimator 2 HPF Corner Frequency", cs42l43_dec2_hpf_corner),
105662306a36Sopenharmony_ci	SOC_ENUM("Decimator 3 HPF Corner Frequency", cs42l43_dec3_hpf_corner),
105762306a36Sopenharmony_ci	SOC_ENUM("Decimator 4 HPF Corner Frequency", cs42l43_dec4_hpf_corner),
105862306a36Sopenharmony_ci
105962306a36Sopenharmony_ci	SOC_SINGLE_TLV("Decimator 1 Volume", CS42L43_DECIM_VOL_CTRL_CH1_CH2,
106062306a36Sopenharmony_ci		       CS42L43_DECIM1_VOL_SHIFT, 0xBF, 0, cs42l43_dec_tlv),
106162306a36Sopenharmony_ci	SOC_SINGLE_EXT("Decimator 1 Switch", CS42L43_DECIM_VOL_CTRL_CH1_CH2,
106262306a36Sopenharmony_ci		       CS42L43_DECIM1_MUTE_SHIFT, 1, 1,
106362306a36Sopenharmony_ci		       cs42l43_decim_get, cs42l43_dapm_put_volsw),
106462306a36Sopenharmony_ci	SOC_SINGLE_TLV("Decimator 2 Volume", CS42L43_DECIM_VOL_CTRL_CH1_CH2,
106562306a36Sopenharmony_ci		       CS42L43_DECIM2_VOL_SHIFT, 0xBF, 0, cs42l43_dec_tlv),
106662306a36Sopenharmony_ci	SOC_SINGLE_EXT("Decimator 2 Switch", CS42L43_DECIM_VOL_CTRL_CH1_CH2,
106762306a36Sopenharmony_ci		       CS42L43_DECIM2_MUTE_SHIFT, 1, 1,
106862306a36Sopenharmony_ci		       cs42l43_decim_get, cs42l43_dapm_put_volsw),
106962306a36Sopenharmony_ci	SOC_SINGLE_TLV("Decimator 3 Volume", CS42L43_DECIM_VOL_CTRL_CH3_CH4,
107062306a36Sopenharmony_ci		       CS42L43_DECIM3_VOL_SHIFT, 0xBF, 0, cs42l43_dec_tlv),
107162306a36Sopenharmony_ci	SOC_SINGLE_EXT("Decimator 3 Switch", CS42L43_DECIM_VOL_CTRL_CH3_CH4,
107262306a36Sopenharmony_ci		       CS42L43_DECIM3_MUTE_SHIFT, 1, 1,
107362306a36Sopenharmony_ci		       cs42l43_decim_get, cs42l43_dapm_put_volsw),
107462306a36Sopenharmony_ci	SOC_SINGLE_TLV("Decimator 4 Volume", CS42L43_DECIM_VOL_CTRL_CH3_CH4,
107562306a36Sopenharmony_ci		       CS42L43_DECIM4_VOL_SHIFT, 0xBF, 0, cs42l43_dec_tlv),
107662306a36Sopenharmony_ci	SOC_SINGLE_EXT("Decimator 4 Switch", CS42L43_DECIM_VOL_CTRL_CH3_CH4,
107762306a36Sopenharmony_ci		       CS42L43_DECIM4_MUTE_SHIFT, 1, 1,
107862306a36Sopenharmony_ci		       cs42l43_decim_get, cs42l43_dapm_put_volsw),
107962306a36Sopenharmony_ci
108062306a36Sopenharmony_ci	SOC_ENUM_EXT("Decimator 1 Ramp Up", cs42l43_dec1_ramp_up,
108162306a36Sopenharmony_ci		     cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
108262306a36Sopenharmony_ci	SOC_ENUM_EXT("Decimator 1 Ramp Down", cs42l43_dec1_ramp_down,
108362306a36Sopenharmony_ci		     cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
108462306a36Sopenharmony_ci	SOC_ENUM_EXT("Decimator 2 Ramp Up", cs42l43_dec2_ramp_up,
108562306a36Sopenharmony_ci		     cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
108662306a36Sopenharmony_ci	SOC_ENUM_EXT("Decimator 2 Ramp Down", cs42l43_dec2_ramp_down,
108762306a36Sopenharmony_ci		     cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
108862306a36Sopenharmony_ci	SOC_ENUM_EXT("Decimator 3 Ramp Up", cs42l43_dec3_ramp_up,
108962306a36Sopenharmony_ci		     cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
109062306a36Sopenharmony_ci	SOC_ENUM_EXT("Decimator 3 Ramp Down", cs42l43_dec3_ramp_down,
109162306a36Sopenharmony_ci		     cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
109262306a36Sopenharmony_ci	SOC_ENUM_EXT("Decimator 4 Ramp Up", cs42l43_dec4_ramp_up,
109362306a36Sopenharmony_ci		     cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
109462306a36Sopenharmony_ci	SOC_ENUM_EXT("Decimator 4 Ramp Down", cs42l43_dec4_ramp_down,
109562306a36Sopenharmony_ci		     cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),
109662306a36Sopenharmony_ci
109762306a36Sopenharmony_ci	SOC_DOUBLE_R_EXT("Speaker Digital Switch",
109862306a36Sopenharmony_ci			 CS42L43_INTP_VOLUME_CTRL1, CS42L43_INTP_VOLUME_CTRL2,
109962306a36Sopenharmony_ci			 CS42L43_AMP_MUTE_SHIFT, 1, 1,
110062306a36Sopenharmony_ci			 cs42l43_spk_get, cs42l43_spk_put),
110162306a36Sopenharmony_ci
110262306a36Sopenharmony_ci	SOC_DOUBLE_R_EXT_TLV("Speaker Digital Volume",
110362306a36Sopenharmony_ci			     CS42L43_INTP_VOLUME_CTRL1, CS42L43_INTP_VOLUME_CTRL2,
110462306a36Sopenharmony_ci			     CS42L43_AMP_VOL_SHIFT,
110562306a36Sopenharmony_ci			     0xBF, 0, snd_soc_get_volsw, cs42l43_spk_put,
110662306a36Sopenharmony_ci			     cs42l43_speaker_tlv),
110762306a36Sopenharmony_ci
110862306a36Sopenharmony_ci	SOC_ENUM("Speaker Ramp Up", cs42l43_speaker_ramp_up),
110962306a36Sopenharmony_ci	SOC_ENUM("Speaker Ramp Down", cs42l43_speaker_ramp_down),
111062306a36Sopenharmony_ci
111162306a36Sopenharmony_ci	CS42L43_MIXER_VOLUMES("Speaker L", CS42L43_AMP1MIX_INPUT1),
111262306a36Sopenharmony_ci	CS42L43_MIXER_VOLUMES("Speaker R", CS42L43_AMP2MIX_INPUT1),
111362306a36Sopenharmony_ci
111462306a36Sopenharmony_ci	SOC_DOUBLE_SX_TLV("Headphone Digital Volume", CS42L43_HPPATHVOL,
111562306a36Sopenharmony_ci			  CS42L43_AMP3_PATH_VOL_SHIFT, CS42L43_AMP4_PATH_VOL_SHIFT,
111662306a36Sopenharmony_ci			  0x11B, 229, cs42l43_headphone_tlv),
111762306a36Sopenharmony_ci
111862306a36Sopenharmony_ci	SOC_DOUBLE("Headphone Invert Switch", CS42L43_DACCNFG1,
111962306a36Sopenharmony_ci		   CS42L43_AMP3_INV_SHIFT, CS42L43_AMP4_INV_SHIFT, 1, 0),
112062306a36Sopenharmony_ci
112162306a36Sopenharmony_ci	SOC_SINGLE("Headphone Zero Cross Switch", CS42L43_PGAVOL,
112262306a36Sopenharmony_ci		   CS42L43_HP_PATH_VOL_ZC_SHIFT, 1, 0),
112362306a36Sopenharmony_ci	SOC_SINGLE("Headphone Ramp Switch", CS42L43_PGAVOL,
112462306a36Sopenharmony_ci		   CS42L43_HP_PATH_VOL_SFT_SHIFT, 1, 0),
112562306a36Sopenharmony_ci	SOC_ENUM("Headphone Ramp Rate", cs42l43_headphone_ramp),
112662306a36Sopenharmony_ci
112762306a36Sopenharmony_ci	CS42L43_MIXER_VOLUMES("Headphone L", CS42L43_AMP3MIX_INPUT1),
112862306a36Sopenharmony_ci	CS42L43_MIXER_VOLUMES("Headphone R", CS42L43_AMP4MIX_INPUT1),
112962306a36Sopenharmony_ci
113062306a36Sopenharmony_ci	SOC_ENUM("Tone 1 Frequency", cs42l43_tone1_freq),
113162306a36Sopenharmony_ci	SOC_ENUM("Tone 2 Frequency", cs42l43_tone2_freq),
113262306a36Sopenharmony_ci
113362306a36Sopenharmony_ci	SOC_DOUBLE_EXT("EQ Switch",
113462306a36Sopenharmony_ci		       CS42L43_MUTE_EQ_IN0, CS42L43_MUTE_EQ_CH1_SHIFT,
113562306a36Sopenharmony_ci		       CS42L43_MUTE_EQ_CH2_SHIFT, 1, 1,
113662306a36Sopenharmony_ci		       cs42l43_dapm_get_volsw, cs42l43_dapm_put_volsw),
113762306a36Sopenharmony_ci
113862306a36Sopenharmony_ci	SND_SOC_BYTES_E("EQ Coefficients", 0, CS42L43_N_EQ_COEFFS,
113962306a36Sopenharmony_ci			cs42l43_eq_get, cs42l43_eq_put),
114062306a36Sopenharmony_ci
114162306a36Sopenharmony_ci	CS42L43_MIXER_VOLUMES("EQ1", CS42L43_EQ1MIX_INPUT1),
114262306a36Sopenharmony_ci	CS42L43_MIXER_VOLUMES("EQ2", CS42L43_EQ2MIX_INPUT1),
114362306a36Sopenharmony_ci};
114462306a36Sopenharmony_ci
114562306a36Sopenharmony_cistatic int cs42l43_eq_ev(struct snd_soc_dapm_widget *w,
114662306a36Sopenharmony_ci			 struct snd_kcontrol *kcontrol, int event)
114762306a36Sopenharmony_ci{
114862306a36Sopenharmony_ci	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
114962306a36Sopenharmony_ci	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
115062306a36Sopenharmony_ci	struct cs42l43 *cs42l43 = priv->core;
115162306a36Sopenharmony_ci	unsigned int val;
115262306a36Sopenharmony_ci	int i, ret;
115362306a36Sopenharmony_ci
115462306a36Sopenharmony_ci	switch (event) {
115562306a36Sopenharmony_ci	case SND_SOC_DAPM_PRE_PMU:
115662306a36Sopenharmony_ci		regmap_update_bits(cs42l43->regmap, CS42L43_MUTE_EQ_IN0,
115762306a36Sopenharmony_ci				   CS42L43_MUTE_EQ_CH1_MASK | CS42L43_MUTE_EQ_CH2_MASK,
115862306a36Sopenharmony_ci				   CS42L43_MUTE_EQ_CH1_MASK | CS42L43_MUTE_EQ_CH2_MASK);
115962306a36Sopenharmony_ci
116062306a36Sopenharmony_ci		regmap_update_bits(cs42l43->regmap, CS42L43_COEFF_RD_WR0,
116162306a36Sopenharmony_ci				   CS42L43_WRITE_MODE_MASK, CS42L43_WRITE_MODE_MASK);
116262306a36Sopenharmony_ci
116362306a36Sopenharmony_ci		for (i = 0; i < CS42L43_N_EQ_COEFFS; i++)
116462306a36Sopenharmony_ci			regmap_write(cs42l43->regmap, CS42L43_COEFF_DATA_IN0,
116562306a36Sopenharmony_ci				     priv->eq_coeffs[i]);
116662306a36Sopenharmony_ci
116762306a36Sopenharmony_ci		regmap_update_bits(cs42l43->regmap, CS42L43_COEFF_RD_WR0,
116862306a36Sopenharmony_ci				   CS42L43_WRITE_MODE_MASK, 0);
116962306a36Sopenharmony_ci
117062306a36Sopenharmony_ci		return 0;
117162306a36Sopenharmony_ci	case SND_SOC_DAPM_POST_PMU:
117262306a36Sopenharmony_ci		ret = regmap_read_poll_timeout(cs42l43->regmap, CS42L43_INIT_DONE0,
117362306a36Sopenharmony_ci					       val, (val & CS42L43_INITIALIZE_DONE_MASK),
117462306a36Sopenharmony_ci					       2000, 10000);
117562306a36Sopenharmony_ci		if (ret)
117662306a36Sopenharmony_ci			dev_err(priv->dev, "Failed to start EQs: %d\n", ret);
117762306a36Sopenharmony_ci
117862306a36Sopenharmony_ci		regmap_update_bits(cs42l43->regmap, CS42L43_MUTE_EQ_IN0,
117962306a36Sopenharmony_ci				   CS42L43_MUTE_EQ_CH1_MASK | CS42L43_MUTE_EQ_CH2_MASK, 0);
118062306a36Sopenharmony_ci		return ret;
118162306a36Sopenharmony_ci	default:
118262306a36Sopenharmony_ci		return 0;
118362306a36Sopenharmony_ci	}
118462306a36Sopenharmony_ci}
118562306a36Sopenharmony_ci
118662306a36Sopenharmony_cistruct cs42l43_pll_config {
118762306a36Sopenharmony_ci	unsigned int freq;
118862306a36Sopenharmony_ci
118962306a36Sopenharmony_ci	unsigned int div;
119062306a36Sopenharmony_ci	unsigned int mode;
119162306a36Sopenharmony_ci	unsigned int cal;
119262306a36Sopenharmony_ci};
119362306a36Sopenharmony_ci
119462306a36Sopenharmony_cistatic const struct cs42l43_pll_config cs42l43_pll_configs[] = {
119562306a36Sopenharmony_ci	{ 2400000, 0x50000000, 0x1, 0xA4 },
119662306a36Sopenharmony_ci	{ 3000000, 0x40000000, 0x1, 0x83 },
119762306a36Sopenharmony_ci	{ 3072000, 0x40000000, 0x3, 0x80 },
119862306a36Sopenharmony_ci};
119962306a36Sopenharmony_ci
120062306a36Sopenharmony_cistatic int cs42l43_set_pll(struct cs42l43_codec *priv, unsigned int src,
120162306a36Sopenharmony_ci			   unsigned int freq)
120262306a36Sopenharmony_ci{
120362306a36Sopenharmony_ci	struct cs42l43 *cs42l43 = priv->core;
120462306a36Sopenharmony_ci
120562306a36Sopenharmony_ci	lockdep_assert_held(&cs42l43->pll_lock);
120662306a36Sopenharmony_ci
120762306a36Sopenharmony_ci	if (priv->refclk_src == src && priv->refclk_freq == freq)
120862306a36Sopenharmony_ci		return 0;
120962306a36Sopenharmony_ci
121062306a36Sopenharmony_ci	if (regmap_test_bits(cs42l43->regmap, CS42L43_CTRL_REG, CS42L43_PLL_EN_MASK)) {
121162306a36Sopenharmony_ci		dev_err(priv->dev, "PLL active, can't change configuration\n");
121262306a36Sopenharmony_ci		return -EBUSY;
121362306a36Sopenharmony_ci	}
121462306a36Sopenharmony_ci
121562306a36Sopenharmony_ci	switch (src) {
121662306a36Sopenharmony_ci	case CS42L43_SYSCLK_MCLK:
121762306a36Sopenharmony_ci	case CS42L43_SYSCLK_SDW:
121862306a36Sopenharmony_ci		dev_dbg(priv->dev, "Source PLL from %s at %uHz\n",
121962306a36Sopenharmony_ci			src ? "SoundWire" : "MCLK", freq);
122062306a36Sopenharmony_ci
122162306a36Sopenharmony_ci		priv->refclk_src = src;
122262306a36Sopenharmony_ci		priv->refclk_freq = freq;
122362306a36Sopenharmony_ci
122462306a36Sopenharmony_ci		return 0;
122562306a36Sopenharmony_ci	default:
122662306a36Sopenharmony_ci		dev_err(priv->dev, "Invalid PLL source: 0x%x\n", src);
122762306a36Sopenharmony_ci		return -EINVAL;
122862306a36Sopenharmony_ci	}
122962306a36Sopenharmony_ci}
123062306a36Sopenharmony_ci
123162306a36Sopenharmony_cistatic int cs42l43_enable_pll(struct cs42l43_codec *priv)
123262306a36Sopenharmony_ci{
123362306a36Sopenharmony_ci	static const struct reg_sequence enable_seq[] = {
123462306a36Sopenharmony_ci		{ CS42L43_OSC_DIV_SEL, 0x0, },
123562306a36Sopenharmony_ci		{ CS42L43_MCLK_SRC_SEL, CS42L43_OSC_PLL_MCLK_SEL_MASK, 5, },
123662306a36Sopenharmony_ci	};
123762306a36Sopenharmony_ci	struct cs42l43 *cs42l43 = priv->core;
123862306a36Sopenharmony_ci	const struct cs42l43_pll_config *config = NULL;
123962306a36Sopenharmony_ci	unsigned int div = 0;
124062306a36Sopenharmony_ci	unsigned int freq = priv->refclk_freq;
124162306a36Sopenharmony_ci	unsigned long time_left;
124262306a36Sopenharmony_ci
124362306a36Sopenharmony_ci	lockdep_assert_held(&cs42l43->pll_lock);
124462306a36Sopenharmony_ci
124562306a36Sopenharmony_ci	if (priv->refclk_src == CS42L43_SYSCLK_SDW) {
124662306a36Sopenharmony_ci		if (!freq)
124762306a36Sopenharmony_ci			freq = cs42l43->sdw_freq;
124862306a36Sopenharmony_ci		else if (!cs42l43->sdw_freq)
124962306a36Sopenharmony_ci			cs42l43->sdw_freq = freq;
125062306a36Sopenharmony_ci	}
125162306a36Sopenharmony_ci
125262306a36Sopenharmony_ci	dev_dbg(priv->dev, "Enabling PLL at %uHz\n", freq);
125362306a36Sopenharmony_ci
125462306a36Sopenharmony_ci	while (freq > cs42l43_pll_configs[ARRAY_SIZE(cs42l43_pll_configs) - 1].freq) {
125562306a36Sopenharmony_ci		div++;
125662306a36Sopenharmony_ci		freq /= 2;
125762306a36Sopenharmony_ci	}
125862306a36Sopenharmony_ci
125962306a36Sopenharmony_ci	if (div <= CS42L43_PLL_REFCLK_DIV_MASK) {
126062306a36Sopenharmony_ci		int i;
126162306a36Sopenharmony_ci
126262306a36Sopenharmony_ci		for (i = 0; i < ARRAY_SIZE(cs42l43_pll_configs); i++) {
126362306a36Sopenharmony_ci			if (freq == cs42l43_pll_configs[i].freq) {
126462306a36Sopenharmony_ci				config = &cs42l43_pll_configs[i];
126562306a36Sopenharmony_ci				break;
126662306a36Sopenharmony_ci			}
126762306a36Sopenharmony_ci		}
126862306a36Sopenharmony_ci	}
126962306a36Sopenharmony_ci
127062306a36Sopenharmony_ci	if (!config) {
127162306a36Sopenharmony_ci		dev_err(priv->dev, "No suitable PLL config: 0x%x, %uHz\n", div, freq);
127262306a36Sopenharmony_ci		return -EINVAL;
127362306a36Sopenharmony_ci	}
127462306a36Sopenharmony_ci
127562306a36Sopenharmony_ci	regmap_update_bits(cs42l43->regmap, CS42L43_PLL_CONTROL,
127662306a36Sopenharmony_ci			   CS42L43_PLL_REFCLK_DIV_MASK | CS42L43_PLL_REFCLK_SRC_MASK,
127762306a36Sopenharmony_ci			   div << CS42L43_PLL_REFCLK_DIV_SHIFT |
127862306a36Sopenharmony_ci			   priv->refclk_src << CS42L43_PLL_REFCLK_SRC_SHIFT);
127962306a36Sopenharmony_ci	regmap_write(cs42l43->regmap, CS42L43_FDIV_FRAC, config->div);
128062306a36Sopenharmony_ci	regmap_update_bits(cs42l43->regmap, CS42L43_CTRL_REG,
128162306a36Sopenharmony_ci			   CS42L43_PLL_MODE_BYPASS_500_MASK |
128262306a36Sopenharmony_ci			   CS42L43_PLL_MODE_BYPASS_1029_MASK,
128362306a36Sopenharmony_ci			   config->mode << CS42L43_PLL_MODE_BYPASS_1029_SHIFT);
128462306a36Sopenharmony_ci	regmap_update_bits(cs42l43->regmap, CS42L43_CAL_RATIO,
128562306a36Sopenharmony_ci			   CS42L43_PLL_CAL_RATIO_MASK, config->cal);
128662306a36Sopenharmony_ci	regmap_update_bits(cs42l43->regmap, CS42L43_PLL_CONTROL,
128762306a36Sopenharmony_ci			   CS42L43_PLL_REFCLK_EN_MASK, CS42L43_PLL_REFCLK_EN_MASK);
128862306a36Sopenharmony_ci
128962306a36Sopenharmony_ci	reinit_completion(&priv->pll_ready);
129062306a36Sopenharmony_ci
129162306a36Sopenharmony_ci	regmap_update_bits(cs42l43->regmap, CS42L43_CTRL_REG,
129262306a36Sopenharmony_ci			   CS42L43_PLL_EN_MASK, CS42L43_PLL_EN_MASK);
129362306a36Sopenharmony_ci
129462306a36Sopenharmony_ci	time_left = wait_for_completion_timeout(&priv->pll_ready,
129562306a36Sopenharmony_ci						msecs_to_jiffies(CS42L43_PLL_TIMEOUT_MS));
129662306a36Sopenharmony_ci	if (!time_left) {
129762306a36Sopenharmony_ci		regmap_update_bits(cs42l43->regmap, CS42L43_CTRL_REG,
129862306a36Sopenharmony_ci				   CS42L43_PLL_EN_MASK, 0);
129962306a36Sopenharmony_ci		regmap_update_bits(cs42l43->regmap, CS42L43_PLL_CONTROL,
130062306a36Sopenharmony_ci				   CS42L43_PLL_REFCLK_EN_MASK, 0);
130162306a36Sopenharmony_ci
130262306a36Sopenharmony_ci		dev_err(priv->dev, "Timeout out waiting for PLL\n");
130362306a36Sopenharmony_ci		return -ETIMEDOUT;
130462306a36Sopenharmony_ci	}
130562306a36Sopenharmony_ci
130662306a36Sopenharmony_ci	if (priv->refclk_src == CS42L43_SYSCLK_SDW)
130762306a36Sopenharmony_ci		cs42l43->sdw_pll_active = true;
130862306a36Sopenharmony_ci
130962306a36Sopenharmony_ci	dev_dbg(priv->dev, "PLL locked in %ums\n", 200 - jiffies_to_msecs(time_left));
131062306a36Sopenharmony_ci
131162306a36Sopenharmony_ci	/*
131262306a36Sopenharmony_ci	 * Reads are not allowed over Soundwire without OSC_DIV2_EN or the PLL,
131362306a36Sopenharmony_ci	 * but you can not change to PLL with OSC_DIV2_EN set. So ensure the whole
131462306a36Sopenharmony_ci	 * change over happens under the regmap lock to prevent any reads.
131562306a36Sopenharmony_ci	 */
131662306a36Sopenharmony_ci	regmap_multi_reg_write(cs42l43->regmap, enable_seq, ARRAY_SIZE(enable_seq));
131762306a36Sopenharmony_ci
131862306a36Sopenharmony_ci	return 0;
131962306a36Sopenharmony_ci}
132062306a36Sopenharmony_ci
132162306a36Sopenharmony_cistatic int cs42l43_disable_pll(struct cs42l43_codec *priv)
132262306a36Sopenharmony_ci{
132362306a36Sopenharmony_ci	static const struct reg_sequence disable_seq[] = {
132462306a36Sopenharmony_ci		{ CS42L43_MCLK_SRC_SEL, 0x0, 5, },
132562306a36Sopenharmony_ci		{ CS42L43_OSC_DIV_SEL, CS42L43_OSC_DIV2_EN_MASK, },
132662306a36Sopenharmony_ci	};
132762306a36Sopenharmony_ci	struct cs42l43 *cs42l43 = priv->core;
132862306a36Sopenharmony_ci
132962306a36Sopenharmony_ci	dev_dbg(priv->dev, "Disabling PLL\n");
133062306a36Sopenharmony_ci
133162306a36Sopenharmony_ci	lockdep_assert_held(&cs42l43->pll_lock);
133262306a36Sopenharmony_ci
133362306a36Sopenharmony_ci	regmap_multi_reg_write(cs42l43->regmap, disable_seq, ARRAY_SIZE(disable_seq));
133462306a36Sopenharmony_ci	regmap_update_bits(cs42l43->regmap, CS42L43_CTRL_REG, CS42L43_PLL_EN_MASK, 0);
133562306a36Sopenharmony_ci	regmap_update_bits(cs42l43->regmap, CS42L43_PLL_CONTROL,
133662306a36Sopenharmony_ci			   CS42L43_PLL_REFCLK_EN_MASK, 0);
133762306a36Sopenharmony_ci
133862306a36Sopenharmony_ci	cs42l43->sdw_pll_active = false;
133962306a36Sopenharmony_ci
134062306a36Sopenharmony_ci	return 0;
134162306a36Sopenharmony_ci}
134262306a36Sopenharmony_ci
134362306a36Sopenharmony_cistatic int cs42l43_pll_ev(struct snd_soc_dapm_widget *w,
134462306a36Sopenharmony_ci			  struct snd_kcontrol *kcontrol, int event)
134562306a36Sopenharmony_ci{
134662306a36Sopenharmony_ci	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
134762306a36Sopenharmony_ci	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
134862306a36Sopenharmony_ci	struct cs42l43 *cs42l43 = priv->core;
134962306a36Sopenharmony_ci	int ret;
135062306a36Sopenharmony_ci
135162306a36Sopenharmony_ci	mutex_lock(&cs42l43->pll_lock);
135262306a36Sopenharmony_ci
135362306a36Sopenharmony_ci	switch (event) {
135462306a36Sopenharmony_ci	case SND_SOC_DAPM_PRE_PMU:
135562306a36Sopenharmony_ci		if (priv->refclk_src == CS42L43_SYSCLK_MCLK) {
135662306a36Sopenharmony_ci			ret = clk_prepare_enable(priv->mclk);
135762306a36Sopenharmony_ci			if (ret) {
135862306a36Sopenharmony_ci				dev_err(priv->dev, "Failed to enable MCLK: %d\n", ret);
135962306a36Sopenharmony_ci				break;
136062306a36Sopenharmony_ci			}
136162306a36Sopenharmony_ci		}
136262306a36Sopenharmony_ci
136362306a36Sopenharmony_ci		ret = cs42l43_enable_pll(priv);
136462306a36Sopenharmony_ci		break;
136562306a36Sopenharmony_ci	case SND_SOC_DAPM_POST_PMD:
136662306a36Sopenharmony_ci		ret = cs42l43_disable_pll(priv);
136762306a36Sopenharmony_ci
136862306a36Sopenharmony_ci		if (priv->refclk_src == CS42L43_SYSCLK_MCLK)
136962306a36Sopenharmony_ci			clk_disable_unprepare(priv->mclk);
137062306a36Sopenharmony_ci		break;
137162306a36Sopenharmony_ci	default:
137262306a36Sopenharmony_ci		ret = 0;
137362306a36Sopenharmony_ci		break;
137462306a36Sopenharmony_ci	}
137562306a36Sopenharmony_ci
137662306a36Sopenharmony_ci	mutex_unlock(&cs42l43->pll_lock);
137762306a36Sopenharmony_ci
137862306a36Sopenharmony_ci	return ret;
137962306a36Sopenharmony_ci}
138062306a36Sopenharmony_ci
138162306a36Sopenharmony_cistatic int cs42l43_dapm_wait_completion(struct completion *pmu, struct completion *pmd,
138262306a36Sopenharmony_ci					int event, int timeout_ms)
138362306a36Sopenharmony_ci{
138462306a36Sopenharmony_ci	unsigned long time_left;
138562306a36Sopenharmony_ci
138662306a36Sopenharmony_ci	switch (event) {
138762306a36Sopenharmony_ci	case SND_SOC_DAPM_PRE_PMU:
138862306a36Sopenharmony_ci		reinit_completion(pmu);
138962306a36Sopenharmony_ci		return 0;
139062306a36Sopenharmony_ci	case SND_SOC_DAPM_PRE_PMD:
139162306a36Sopenharmony_ci		reinit_completion(pmd);
139262306a36Sopenharmony_ci		return 0;
139362306a36Sopenharmony_ci	case SND_SOC_DAPM_POST_PMU:
139462306a36Sopenharmony_ci		time_left = wait_for_completion_timeout(pmu, msecs_to_jiffies(timeout_ms));
139562306a36Sopenharmony_ci		break;
139662306a36Sopenharmony_ci	case SND_SOC_DAPM_POST_PMD:
139762306a36Sopenharmony_ci		time_left = wait_for_completion_timeout(pmd, msecs_to_jiffies(timeout_ms));
139862306a36Sopenharmony_ci		break;
139962306a36Sopenharmony_ci	default:
140062306a36Sopenharmony_ci		return 0;
140162306a36Sopenharmony_ci	}
140262306a36Sopenharmony_ci
140362306a36Sopenharmony_ci	if (!time_left)
140462306a36Sopenharmony_ci		return -ETIMEDOUT;
140562306a36Sopenharmony_ci	else
140662306a36Sopenharmony_ci		return 0;
140762306a36Sopenharmony_ci}
140862306a36Sopenharmony_ci
140962306a36Sopenharmony_cistatic int cs42l43_spkr_ev(struct snd_soc_dapm_widget *w,
141062306a36Sopenharmony_ci			   struct snd_kcontrol *kcontrol, int event)
141162306a36Sopenharmony_ci{
141262306a36Sopenharmony_ci	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
141362306a36Sopenharmony_ci	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
141462306a36Sopenharmony_ci
141562306a36Sopenharmony_ci	return cs42l43_dapm_wait_completion(&priv->spkr_startup,
141662306a36Sopenharmony_ci					    &priv->spkr_shutdown, event,
141762306a36Sopenharmony_ci					    CS42L43_SPK_TIMEOUT_MS);
141862306a36Sopenharmony_ci}
141962306a36Sopenharmony_ci
142062306a36Sopenharmony_cistatic int cs42l43_spkl_ev(struct snd_soc_dapm_widget *w,
142162306a36Sopenharmony_ci			   struct snd_kcontrol *kcontrol, int event)
142262306a36Sopenharmony_ci{
142362306a36Sopenharmony_ci	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
142462306a36Sopenharmony_ci	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
142562306a36Sopenharmony_ci
142662306a36Sopenharmony_ci	return cs42l43_dapm_wait_completion(&priv->spkl_startup,
142762306a36Sopenharmony_ci					    &priv->spkl_shutdown, event,
142862306a36Sopenharmony_ci					    CS42L43_SPK_TIMEOUT_MS);
142962306a36Sopenharmony_ci}
143062306a36Sopenharmony_ci
143162306a36Sopenharmony_cistatic int cs42l43_hp_ev(struct snd_soc_dapm_widget *w,
143262306a36Sopenharmony_ci			 struct snd_kcontrol *kcontrol, int event)
143362306a36Sopenharmony_ci{
143462306a36Sopenharmony_ci	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
143562306a36Sopenharmony_ci	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
143662306a36Sopenharmony_ci	struct cs42l43 *cs42l43 = priv->core;
143762306a36Sopenharmony_ci	unsigned int mask = 1 << w->shift;
143862306a36Sopenharmony_ci	unsigned int val = 0;
143962306a36Sopenharmony_ci	int ret;
144062306a36Sopenharmony_ci
144162306a36Sopenharmony_ci	switch (event) {
144262306a36Sopenharmony_ci	case SND_SOC_DAPM_PRE_PMU:
144362306a36Sopenharmony_ci		val = mask;
144462306a36Sopenharmony_ci		fallthrough;
144562306a36Sopenharmony_ci	case SND_SOC_DAPM_PRE_PMD:
144662306a36Sopenharmony_ci		priv->hp_ena &= ~mask;
144762306a36Sopenharmony_ci		priv->hp_ena |= val;
144862306a36Sopenharmony_ci
144962306a36Sopenharmony_ci		ret = cs42l43_dapm_wait_completion(&priv->hp_startup,
145062306a36Sopenharmony_ci						   &priv->hp_shutdown, event,
145162306a36Sopenharmony_ci						   CS42L43_HP_TIMEOUT_MS);
145262306a36Sopenharmony_ci		if (ret)
145362306a36Sopenharmony_ci			return ret;
145462306a36Sopenharmony_ci
145562306a36Sopenharmony_ci		if (!priv->load_detect_running)
145662306a36Sopenharmony_ci			regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN8,
145762306a36Sopenharmony_ci					   mask, val);
145862306a36Sopenharmony_ci		break;
145962306a36Sopenharmony_ci	case SND_SOC_DAPM_POST_PMU:
146062306a36Sopenharmony_ci	case SND_SOC_DAPM_POST_PMD:
146162306a36Sopenharmony_ci		if (priv->load_detect_running)
146262306a36Sopenharmony_ci			break;
146362306a36Sopenharmony_ci
146462306a36Sopenharmony_ci		ret = cs42l43_dapm_wait_completion(&priv->hp_startup,
146562306a36Sopenharmony_ci						   &priv->hp_shutdown, event,
146662306a36Sopenharmony_ci						   CS42L43_HP_TIMEOUT_MS);
146762306a36Sopenharmony_ci		if (ret)
146862306a36Sopenharmony_ci			return ret;
146962306a36Sopenharmony_ci		break;
147062306a36Sopenharmony_ci	default:
147162306a36Sopenharmony_ci		break;
147262306a36Sopenharmony_ci	}
147362306a36Sopenharmony_ci
147462306a36Sopenharmony_ci	return 0;
147562306a36Sopenharmony_ci}
147662306a36Sopenharmony_ci
147762306a36Sopenharmony_cistatic int cs42l43_mic_ev(struct snd_soc_dapm_widget *w,
147862306a36Sopenharmony_ci			  struct snd_kcontrol *kcontrol, int event)
147962306a36Sopenharmony_ci{
148062306a36Sopenharmony_ci	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
148162306a36Sopenharmony_ci	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
148262306a36Sopenharmony_ci	struct cs42l43 *cs42l43 = priv->core;
148362306a36Sopenharmony_ci	unsigned int reg, ramp, mute;
148462306a36Sopenharmony_ci	unsigned int *val;
148562306a36Sopenharmony_ci	int ret;
148662306a36Sopenharmony_ci
148762306a36Sopenharmony_ci	switch (w->shift) {
148862306a36Sopenharmony_ci	case CS42L43_ADC1_EN_SHIFT:
148962306a36Sopenharmony_ci	case CS42L43_PDM1_DIN_L_EN_SHIFT:
149062306a36Sopenharmony_ci		reg = CS42L43_DECIM_VOL_CTRL_CH1_CH2;
149162306a36Sopenharmony_ci		ramp = CS42L43_DECIM1_VD_RAMP_MASK;
149262306a36Sopenharmony_ci		mute = CS42L43_DECIM1_MUTE_MASK;
149362306a36Sopenharmony_ci		val = &priv->decim_cache[0];
149462306a36Sopenharmony_ci		break;
149562306a36Sopenharmony_ci	case CS42L43_ADC2_EN_SHIFT:
149662306a36Sopenharmony_ci	case CS42L43_PDM1_DIN_R_EN_SHIFT:
149762306a36Sopenharmony_ci		reg = CS42L43_DECIM_VOL_CTRL_CH1_CH2;
149862306a36Sopenharmony_ci		ramp = CS42L43_DECIM2_VD_RAMP_MASK;
149962306a36Sopenharmony_ci		mute = CS42L43_DECIM2_MUTE_MASK;
150062306a36Sopenharmony_ci		val = &priv->decim_cache[1];
150162306a36Sopenharmony_ci		break;
150262306a36Sopenharmony_ci	case CS42L43_PDM2_DIN_L_EN_SHIFT:
150362306a36Sopenharmony_ci		reg = CS42L43_DECIM_VOL_CTRL_CH3_CH4;
150462306a36Sopenharmony_ci		ramp  = CS42L43_DECIM3_VD_RAMP_MASK;
150562306a36Sopenharmony_ci		mute = CS42L43_DECIM3_MUTE_MASK;
150662306a36Sopenharmony_ci		val = &priv->decim_cache[2];
150762306a36Sopenharmony_ci		break;
150862306a36Sopenharmony_ci	case CS42L43_PDM2_DIN_R_EN_SHIFT:
150962306a36Sopenharmony_ci		reg = CS42L43_DECIM_VOL_CTRL_CH3_CH4;
151062306a36Sopenharmony_ci		ramp = CS42L43_DECIM4_VD_RAMP_MASK;
151162306a36Sopenharmony_ci		mute = CS42L43_DECIM4_MUTE_MASK;
151262306a36Sopenharmony_ci		val = &priv->decim_cache[3];
151362306a36Sopenharmony_ci		break;
151462306a36Sopenharmony_ci	default:
151562306a36Sopenharmony_ci		dev_err(priv->dev, "Invalid microphone shift: %d\n", w->shift);
151662306a36Sopenharmony_ci		return -EINVAL;
151762306a36Sopenharmony_ci	}
151862306a36Sopenharmony_ci
151962306a36Sopenharmony_ci	switch (event) {
152062306a36Sopenharmony_ci	case SND_SOC_DAPM_PRE_PMU:
152162306a36Sopenharmony_ci		ret = regmap_read(cs42l43->regmap, reg, val);
152262306a36Sopenharmony_ci		if (ret) {
152362306a36Sopenharmony_ci			dev_err(priv->dev,
152462306a36Sopenharmony_ci				"Failed to cache decimator settings: %d\n",
152562306a36Sopenharmony_ci				ret);
152662306a36Sopenharmony_ci			return ret;
152762306a36Sopenharmony_ci		}
152862306a36Sopenharmony_ci
152962306a36Sopenharmony_ci		regmap_update_bits(cs42l43->regmap, reg, mute | ramp, mute);
153062306a36Sopenharmony_ci		break;
153162306a36Sopenharmony_ci	case SND_SOC_DAPM_POST_PMU:
153262306a36Sopenharmony_ci		regmap_update_bits(cs42l43->regmap, reg, mute | ramp, *val);
153362306a36Sopenharmony_ci		break;
153462306a36Sopenharmony_ci	default:
153562306a36Sopenharmony_ci		break;
153662306a36Sopenharmony_ci	}
153762306a36Sopenharmony_ci
153862306a36Sopenharmony_ci	return 0;
153962306a36Sopenharmony_ci}
154062306a36Sopenharmony_ci
154162306a36Sopenharmony_cistatic int cs42l43_adc_ev(struct snd_soc_dapm_widget *w,
154262306a36Sopenharmony_ci			  struct snd_kcontrol *kcontrol, int event)
154362306a36Sopenharmony_ci{
154462306a36Sopenharmony_ci	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
154562306a36Sopenharmony_ci	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
154662306a36Sopenharmony_ci	struct cs42l43 *cs42l43 = priv->core;
154762306a36Sopenharmony_ci	unsigned int mask = 1 << w->shift;
154862306a36Sopenharmony_ci	unsigned int val = 0;
154962306a36Sopenharmony_ci	int ret;
155062306a36Sopenharmony_ci
155162306a36Sopenharmony_ci	ret = cs42l43_mic_ev(w, kcontrol, event);
155262306a36Sopenharmony_ci	if (ret)
155362306a36Sopenharmony_ci		return ret;
155462306a36Sopenharmony_ci
155562306a36Sopenharmony_ci	switch (event) {
155662306a36Sopenharmony_ci	case SND_SOC_DAPM_PRE_PMU:
155762306a36Sopenharmony_ci		val = mask;
155862306a36Sopenharmony_ci		fallthrough;
155962306a36Sopenharmony_ci	case SND_SOC_DAPM_PRE_PMD:
156062306a36Sopenharmony_ci		priv->adc_ena &= ~mask;
156162306a36Sopenharmony_ci		priv->adc_ena |= val;
156262306a36Sopenharmony_ci
156362306a36Sopenharmony_ci		if (!priv->load_detect_running)
156462306a36Sopenharmony_ci			regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN3,
156562306a36Sopenharmony_ci					   mask, val);
156662306a36Sopenharmony_ci		fallthrough;
156762306a36Sopenharmony_ci	default:
156862306a36Sopenharmony_ci		return 0;
156962306a36Sopenharmony_ci	}
157062306a36Sopenharmony_ci}
157162306a36Sopenharmony_ci
157262306a36Sopenharmony_cistatic const struct snd_soc_dapm_widget cs42l43_widgets[] = {
157362306a36Sopenharmony_ci	SND_SOC_DAPM_SUPPLY("PLL", SND_SOC_NOPM, 0, 0, cs42l43_pll_ev,
157462306a36Sopenharmony_ci			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
157562306a36Sopenharmony_ci
157662306a36Sopenharmony_ci	SND_SOC_DAPM_INPUT("ADC1_IN1_P"),
157762306a36Sopenharmony_ci	SND_SOC_DAPM_INPUT("ADC1_IN1_N"),
157862306a36Sopenharmony_ci	SND_SOC_DAPM_INPUT("ADC1_IN2_P"),
157962306a36Sopenharmony_ci	SND_SOC_DAPM_INPUT("ADC1_IN2_N"),
158062306a36Sopenharmony_ci	SND_SOC_DAPM_INPUT("ADC2_IN_P"),
158162306a36Sopenharmony_ci	SND_SOC_DAPM_INPUT("ADC2_IN_N"),
158262306a36Sopenharmony_ci
158362306a36Sopenharmony_ci	SND_SOC_DAPM_INPUT("PDM1_DIN"),
158462306a36Sopenharmony_ci	SND_SOC_DAPM_INPUT("PDM2_DIN"),
158562306a36Sopenharmony_ci
158662306a36Sopenharmony_ci	SND_SOC_DAPM_MUX("ADC1 Input", SND_SOC_NOPM, 0, 0, &cs42l43_adc1_input_ctl),
158762306a36Sopenharmony_ci
158862306a36Sopenharmony_ci	SND_SOC_DAPM_PGA_E("ADC1", SND_SOC_NOPM, CS42L43_ADC1_EN_SHIFT, 0, NULL, 0,
158962306a36Sopenharmony_ci			   cs42l43_adc_ev, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
159062306a36Sopenharmony_ci			   SND_SOC_DAPM_PRE_PMD),
159162306a36Sopenharmony_ci	SND_SOC_DAPM_PGA_E("ADC2", SND_SOC_NOPM, CS42L43_ADC2_EN_SHIFT, 0, NULL, 0,
159262306a36Sopenharmony_ci			   cs42l43_adc_ev, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
159362306a36Sopenharmony_ci			   SND_SOC_DAPM_PRE_PMD),
159462306a36Sopenharmony_ci
159562306a36Sopenharmony_ci	SND_SOC_DAPM_PGA_E("PDM1L", CS42L43_BLOCK_EN3, CS42L43_PDM1_DIN_L_EN_SHIFT,
159662306a36Sopenharmony_ci			   0, NULL, 0, cs42l43_mic_ev,
159762306a36Sopenharmony_ci			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
159862306a36Sopenharmony_ci	SND_SOC_DAPM_PGA_E("PDM1R", CS42L43_BLOCK_EN3, CS42L43_PDM1_DIN_R_EN_SHIFT,
159962306a36Sopenharmony_ci			   0, NULL, 0, cs42l43_mic_ev,
160062306a36Sopenharmony_ci			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
160162306a36Sopenharmony_ci	SND_SOC_DAPM_PGA_E("PDM2L", CS42L43_BLOCK_EN3, CS42L43_PDM2_DIN_L_EN_SHIFT,
160262306a36Sopenharmony_ci			   0, NULL, 0, cs42l43_mic_ev,
160362306a36Sopenharmony_ci			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
160462306a36Sopenharmony_ci	SND_SOC_DAPM_PGA_E("PDM2R", CS42L43_BLOCK_EN3, CS42L43_PDM2_DIN_R_EN_SHIFT,
160562306a36Sopenharmony_ci			   0, NULL, 0, cs42l43_mic_ev,
160662306a36Sopenharmony_ci			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
160762306a36Sopenharmony_ci
160862306a36Sopenharmony_ci	SND_SOC_DAPM_MUX("Decimator 1 Mode", SND_SOC_NOPM, 0, 0,
160962306a36Sopenharmony_ci			 &cs42l43_dec_mode_ctl[0]),
161062306a36Sopenharmony_ci	SND_SOC_DAPM_MUX("Decimator 2 Mode", SND_SOC_NOPM, 0, 0,
161162306a36Sopenharmony_ci			 &cs42l43_dec_mode_ctl[1]),
161262306a36Sopenharmony_ci
161362306a36Sopenharmony_ci	SND_SOC_DAPM_PGA("Decimator 1", SND_SOC_NOPM, 0, 0, NULL, 0),
161462306a36Sopenharmony_ci	SND_SOC_DAPM_PGA("Decimator 2", SND_SOC_NOPM, 0, 0, NULL, 0),
161562306a36Sopenharmony_ci	SND_SOC_DAPM_PGA("Decimator 3", SND_SOC_NOPM, 0, 0, NULL, 0),
161662306a36Sopenharmony_ci	SND_SOC_DAPM_PGA("Decimator 4", SND_SOC_NOPM, 0, 0, NULL, 0),
161762306a36Sopenharmony_ci
161862306a36Sopenharmony_ci	SND_SOC_DAPM_SUPPLY_S("FSYNC", 0, CS42L43_ASP_CTRL, CS42L43_ASP_FSYNC_EN_SHIFT,
161962306a36Sopenharmony_ci			      0, NULL, 0),
162062306a36Sopenharmony_ci	SND_SOC_DAPM_SUPPLY_S("BCLK", 1, CS42L43_ASP_CTRL, CS42L43_ASP_BCLK_EN_SHIFT,
162162306a36Sopenharmony_ci			      0, NULL, 0),
162262306a36Sopenharmony_ci
162362306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_OUT("ASPTX1", NULL, 0,
162462306a36Sopenharmony_ci			     CS42L43_ASP_TX_EN, CS42L43_ASP_TX_CH1_EN_SHIFT, 0),
162562306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_OUT("ASPTX2", NULL, 1,
162662306a36Sopenharmony_ci			     CS42L43_ASP_TX_EN, CS42L43_ASP_TX_CH2_EN_SHIFT, 0),
162762306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_OUT("ASPTX3", NULL, 2,
162862306a36Sopenharmony_ci			     CS42L43_ASP_TX_EN, CS42L43_ASP_TX_CH3_EN_SHIFT, 0),
162962306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_OUT("ASPTX4", NULL, 3,
163062306a36Sopenharmony_ci			     CS42L43_ASP_TX_EN, CS42L43_ASP_TX_CH4_EN_SHIFT, 0),
163162306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_OUT("ASPTX5", NULL, 4,
163262306a36Sopenharmony_ci			     CS42L43_ASP_TX_EN, CS42L43_ASP_TX_CH5_EN_SHIFT, 0),
163362306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_OUT("ASPTX6", NULL, 5,
163462306a36Sopenharmony_ci			     CS42L43_ASP_TX_EN, CS42L43_ASP_TX_CH6_EN_SHIFT, 0),
163562306a36Sopenharmony_ci
163662306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_IN("ASPRX1", NULL, 0,
163762306a36Sopenharmony_ci			    CS42L43_ASP_RX_EN, CS42L43_ASP_RX_CH1_EN_SHIFT, 0),
163862306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_IN("ASPRX2", NULL, 1,
163962306a36Sopenharmony_ci			    CS42L43_ASP_RX_EN, CS42L43_ASP_RX_CH2_EN_SHIFT, 0),
164062306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_IN("ASPRX3", NULL, 2,
164162306a36Sopenharmony_ci			    CS42L43_ASP_RX_EN, CS42L43_ASP_RX_CH3_EN_SHIFT, 0),
164262306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_IN("ASPRX4", NULL, 3,
164362306a36Sopenharmony_ci			    CS42L43_ASP_RX_EN, CS42L43_ASP_RX_CH4_EN_SHIFT, 0),
164462306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_IN("ASPRX5", NULL, 4,
164562306a36Sopenharmony_ci			    CS42L43_ASP_RX_EN, CS42L43_ASP_RX_CH5_EN_SHIFT, 0),
164662306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_IN("ASPRX6", NULL, 5,
164762306a36Sopenharmony_ci			    CS42L43_ASP_RX_EN, CS42L43_ASP_RX_CH6_EN_SHIFT, 0),
164862306a36Sopenharmony_ci
164962306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_OUT("DP1TX1", NULL, 0, SND_SOC_NOPM, 0, 0),
165062306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_OUT("DP1TX2", NULL, 1, SND_SOC_NOPM, 0, 0),
165162306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_OUT("DP1TX3", NULL, 2, SND_SOC_NOPM, 0, 0),
165262306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_OUT("DP1TX4", NULL, 3, SND_SOC_NOPM, 0, 0),
165362306a36Sopenharmony_ci
165462306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_OUT("DP2TX1", NULL, 0, SND_SOC_NOPM, 0, 0),
165562306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_OUT("DP2TX2", NULL, 1, SND_SOC_NOPM, 0, 0),
165662306a36Sopenharmony_ci
165762306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_OUT("DP3TX1", NULL, 0, SND_SOC_NOPM, 0, 0),
165862306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_OUT("DP3TX2", NULL, 1, SND_SOC_NOPM, 0, 0),
165962306a36Sopenharmony_ci
166062306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_OUT("DP4TX1", NULL, 0, SND_SOC_NOPM, 0, 0),
166162306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_OUT("DP4TX2", NULL, 1, SND_SOC_NOPM, 0, 0),
166262306a36Sopenharmony_ci
166362306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_IN("DP5RX1", NULL, 0, SND_SOC_NOPM, 0, 0),
166462306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_IN("DP5RX2", NULL, 1, SND_SOC_NOPM, 0, 0),
166562306a36Sopenharmony_ci
166662306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_IN("DP6RX1", NULL, 0, SND_SOC_NOPM, 0, 0),
166762306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_IN("DP6RX2", NULL, 1, SND_SOC_NOPM, 0, 0),
166862306a36Sopenharmony_ci
166962306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_IN("DP7RX1", NULL, 0, SND_SOC_NOPM, 0, 0),
167062306a36Sopenharmony_ci	SND_SOC_DAPM_AIF_IN("DP7RX2", NULL, 1, SND_SOC_NOPM, 0, 0),
167162306a36Sopenharmony_ci
167262306a36Sopenharmony_ci	SND_SOC_DAPM_REGULATOR_SUPPLY("vdd-amp", 0, 0),
167362306a36Sopenharmony_ci
167462306a36Sopenharmony_ci	SND_SOC_DAPM_PGA_E("AMP1", CS42L43_BLOCK_EN10, CS42L43_AMP1_EN_SHIFT, 0, NULL, 0,
167562306a36Sopenharmony_ci			   cs42l43_spkl_ev, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
167662306a36Sopenharmony_ci			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
167762306a36Sopenharmony_ci	SND_SOC_DAPM_PGA_E("AMP2", CS42L43_BLOCK_EN10, CS42L43_AMP2_EN_SHIFT, 0, NULL, 0,
167862306a36Sopenharmony_ci			   cs42l43_spkr_ev, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
167962306a36Sopenharmony_ci			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
168062306a36Sopenharmony_ci
168162306a36Sopenharmony_ci	SND_SOC_DAPM_OUTPUT("AMP1_OUT_P"),
168262306a36Sopenharmony_ci	SND_SOC_DAPM_OUTPUT("AMP1_OUT_N"),
168362306a36Sopenharmony_ci	SND_SOC_DAPM_OUTPUT("AMP2_OUT_P"),
168462306a36Sopenharmony_ci	SND_SOC_DAPM_OUTPUT("AMP2_OUT_N"),
168562306a36Sopenharmony_ci
168662306a36Sopenharmony_ci	SND_SOC_DAPM_PGA("SPDIF", CS42L43_BLOCK_EN11, CS42L43_SPDIF_EN_SHIFT,
168762306a36Sopenharmony_ci			 0, NULL, 0),
168862306a36Sopenharmony_ci	SND_SOC_DAPM_OUTPUT("SPDIF_TX"),
168962306a36Sopenharmony_ci
169062306a36Sopenharmony_ci	SND_SOC_DAPM_PGA_E("HP", SND_SOC_NOPM, CS42L43_HP_EN_SHIFT, 0, NULL, 0,
169162306a36Sopenharmony_ci			   cs42l43_hp_ev, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
169262306a36Sopenharmony_ci			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
169362306a36Sopenharmony_ci	SND_SOC_DAPM_OUTPUT("AMP3_OUT"),
169462306a36Sopenharmony_ci	SND_SOC_DAPM_OUTPUT("AMP4_OUT"),
169562306a36Sopenharmony_ci
169662306a36Sopenharmony_ci	SND_SOC_DAPM_SIGGEN("Tone"),
169762306a36Sopenharmony_ci	SND_SOC_DAPM_SUPPLY("Tone Generator", CS42L43_BLOCK_EN9, CS42L43_TONE_EN_SHIFT,
169862306a36Sopenharmony_ci			    0, NULL, 0),
169962306a36Sopenharmony_ci	SND_SOC_DAPM_REG(snd_soc_dapm_pga, "Tone 1", CS42L43_TONE_CH1_CTRL,
170062306a36Sopenharmony_ci			 CS42L43_TONE_SEL_SHIFT, CS42L43_TONE_SEL_MASK, 0xA, 0),
170162306a36Sopenharmony_ci	SND_SOC_DAPM_REG(snd_soc_dapm_pga, "Tone 2", CS42L43_TONE_CH2_CTRL,
170262306a36Sopenharmony_ci			 CS42L43_TONE_SEL_SHIFT, CS42L43_TONE_SEL_MASK, 0xA, 0),
170362306a36Sopenharmony_ci
170462306a36Sopenharmony_ci	SND_SOC_DAPM_SUPPLY("ISRC1", CS42L43_BLOCK_EN5, CS42L43_ISRC1_BANK_EN_SHIFT,
170562306a36Sopenharmony_ci			    0, NULL, 0),
170662306a36Sopenharmony_ci	SND_SOC_DAPM_SUPPLY("ISRC2", CS42L43_BLOCK_EN5, CS42L43_ISRC2_BANK_EN_SHIFT,
170762306a36Sopenharmony_ci			    0, NULL, 0),
170862306a36Sopenharmony_ci
170962306a36Sopenharmony_ci	SND_SOC_DAPM_PGA("ISRC1INT2", CS42L43_ISRC1_CTRL,
171062306a36Sopenharmony_ci			 CS42L43_ISRC_INT2_EN_SHIFT, 0, NULL, 0),
171162306a36Sopenharmony_ci	SND_SOC_DAPM_PGA("ISRC1INT1", CS42L43_ISRC1_CTRL,
171262306a36Sopenharmony_ci			 CS42L43_ISRC_INT1_EN_SHIFT, 0, NULL, 0),
171362306a36Sopenharmony_ci	SND_SOC_DAPM_PGA("ISRC1DEC2", CS42L43_ISRC1_CTRL,
171462306a36Sopenharmony_ci			 CS42L43_ISRC_DEC2_EN_SHIFT, 0, NULL, 0),
171562306a36Sopenharmony_ci	SND_SOC_DAPM_PGA("ISRC1DEC1", CS42L43_ISRC1_CTRL,
171662306a36Sopenharmony_ci			 CS42L43_ISRC_DEC1_EN_SHIFT, 0, NULL, 0),
171762306a36Sopenharmony_ci
171862306a36Sopenharmony_ci	SND_SOC_DAPM_PGA("ISRC2INT2", CS42L43_ISRC2_CTRL,
171962306a36Sopenharmony_ci			 CS42L43_ISRC_INT2_EN_SHIFT, 0, NULL, 0),
172062306a36Sopenharmony_ci	SND_SOC_DAPM_PGA("ISRC2INT1", CS42L43_ISRC2_CTRL,
172162306a36Sopenharmony_ci			 CS42L43_ISRC_INT1_EN_SHIFT, 0, NULL, 0),
172262306a36Sopenharmony_ci	SND_SOC_DAPM_PGA("ISRC2DEC2", CS42L43_ISRC2_CTRL,
172362306a36Sopenharmony_ci			 CS42L43_ISRC_DEC2_EN_SHIFT, 0, NULL, 0),
172462306a36Sopenharmony_ci	SND_SOC_DAPM_PGA("ISRC2DEC1", CS42L43_ISRC2_CTRL,
172562306a36Sopenharmony_ci			 CS42L43_ISRC_DEC1_EN_SHIFT, 0, NULL, 0),
172662306a36Sopenharmony_ci
172762306a36Sopenharmony_ci	SND_SOC_DAPM_SUPPLY("ASRC_INT", CS42L43_BLOCK_EN4,
172862306a36Sopenharmony_ci			    CS42L43_ASRC_INT_BANK_EN_SHIFT, 0, NULL, 0),
172962306a36Sopenharmony_ci	SND_SOC_DAPM_SUPPLY("ASRC_DEC", CS42L43_BLOCK_EN4,
173062306a36Sopenharmony_ci			    CS42L43_ASRC_DEC_BANK_EN_SHIFT, 0, NULL, 0),
173162306a36Sopenharmony_ci
173262306a36Sopenharmony_ci	SND_SOC_DAPM_PGA("ASRC_INT1", CS42L43_ASRC_INT_ENABLES,
173362306a36Sopenharmony_ci			 CS42L43_ASRC_INT1_EN_SHIFT, 0, NULL, 0),
173462306a36Sopenharmony_ci	SND_SOC_DAPM_PGA("ASRC_INT2", CS42L43_ASRC_INT_ENABLES,
173562306a36Sopenharmony_ci			 CS42L43_ASRC_INT2_EN_SHIFT, 0, NULL, 0),
173662306a36Sopenharmony_ci	SND_SOC_DAPM_PGA("ASRC_INT3", CS42L43_ASRC_INT_ENABLES,
173762306a36Sopenharmony_ci			 CS42L43_ASRC_INT3_EN_SHIFT, 0, NULL, 0),
173862306a36Sopenharmony_ci	SND_SOC_DAPM_PGA("ASRC_INT4", CS42L43_ASRC_INT_ENABLES,
173962306a36Sopenharmony_ci			 CS42L43_ASRC_INT4_EN_SHIFT, 0, NULL, 0),
174062306a36Sopenharmony_ci	SND_SOC_DAPM_PGA("ASRC_DEC1", CS42L43_ASRC_DEC_ENABLES,
174162306a36Sopenharmony_ci			 CS42L43_ASRC_DEC1_EN_SHIFT, 0, NULL, 0),
174262306a36Sopenharmony_ci	SND_SOC_DAPM_PGA("ASRC_DEC2", CS42L43_ASRC_DEC_ENABLES,
174362306a36Sopenharmony_ci			 CS42L43_ASRC_DEC2_EN_SHIFT, 0, NULL, 0),
174462306a36Sopenharmony_ci	SND_SOC_DAPM_PGA("ASRC_DEC3", CS42L43_ASRC_DEC_ENABLES,
174562306a36Sopenharmony_ci			 CS42L43_ASRC_DEC3_EN_SHIFT, 0, NULL, 0),
174662306a36Sopenharmony_ci	SND_SOC_DAPM_PGA("ASRC_DEC4", CS42L43_ASRC_DEC_ENABLES,
174762306a36Sopenharmony_ci			 CS42L43_ASRC_DEC4_EN_SHIFT, 0, NULL, 0),
174862306a36Sopenharmony_ci
174962306a36Sopenharmony_ci	SND_SOC_DAPM_SUPPLY("EQ Clock", CS42L43_BLOCK_EN7, CS42L43_EQ_EN_SHIFT,
175062306a36Sopenharmony_ci			    0, NULL, 0),
175162306a36Sopenharmony_ci	SND_SOC_DAPM_PGA_E("EQ", CS42L43_START_EQZ0, CS42L43_START_FILTER_SHIFT,
175262306a36Sopenharmony_ci			   0, NULL, 0, cs42l43_eq_ev,
175362306a36Sopenharmony_ci			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
175462306a36Sopenharmony_ci
175562306a36Sopenharmony_ci	SND_SOC_DAPM_SUPPLY("Mixer Core", CS42L43_BLOCK_EN6, CS42L43_MIXER_EN_SHIFT,
175662306a36Sopenharmony_ci			    0, NULL, 0),
175762306a36Sopenharmony_ci	CS42L43_DAPM_MUX("ASPTX1", asptx1),
175862306a36Sopenharmony_ci	CS42L43_DAPM_MUX("ASPTX2", asptx2),
175962306a36Sopenharmony_ci	CS42L43_DAPM_MUX("ASPTX3", asptx3),
176062306a36Sopenharmony_ci	CS42L43_DAPM_MUX("ASPTX4", asptx4),
176162306a36Sopenharmony_ci	CS42L43_DAPM_MUX("ASPTX5", asptx5),
176262306a36Sopenharmony_ci	CS42L43_DAPM_MUX("ASPTX6", asptx6),
176362306a36Sopenharmony_ci
176462306a36Sopenharmony_ci	CS42L43_DAPM_MUX("DP1TX1", dp1tx1),
176562306a36Sopenharmony_ci	CS42L43_DAPM_MUX("DP1TX2", dp1tx2),
176662306a36Sopenharmony_ci	CS42L43_DAPM_MUX("DP1TX3", dp1tx3),
176762306a36Sopenharmony_ci	CS42L43_DAPM_MUX("DP1TX4", dp1tx4),
176862306a36Sopenharmony_ci	CS42L43_DAPM_MUX("DP2TX1", dp2tx1),
176962306a36Sopenharmony_ci	CS42L43_DAPM_MUX("DP2TX2", dp2tx2),
177062306a36Sopenharmony_ci	CS42L43_DAPM_MUX("DP3TX1", dp3tx1),
177162306a36Sopenharmony_ci	CS42L43_DAPM_MUX("DP3TX2", dp3tx2),
177262306a36Sopenharmony_ci	CS42L43_DAPM_MUX("DP4TX1", dp4tx1),
177362306a36Sopenharmony_ci	CS42L43_DAPM_MUX("DP4TX2", dp4tx2),
177462306a36Sopenharmony_ci
177562306a36Sopenharmony_ci	CS42L43_DAPM_MUX("ASRC INT1", asrcint1),
177662306a36Sopenharmony_ci	CS42L43_DAPM_MUX("ASRC INT2", asrcint2),
177762306a36Sopenharmony_ci	CS42L43_DAPM_MUX("ASRC INT3", asrcint3),
177862306a36Sopenharmony_ci	CS42L43_DAPM_MUX("ASRC INT4", asrcint4),
177962306a36Sopenharmony_ci	CS42L43_DAPM_MUX("ASRC DEC1", asrcdec1),
178062306a36Sopenharmony_ci	CS42L43_DAPM_MUX("ASRC DEC2", asrcdec2),
178162306a36Sopenharmony_ci	CS42L43_DAPM_MUX("ASRC DEC3", asrcdec3),
178262306a36Sopenharmony_ci	CS42L43_DAPM_MUX("ASRC DEC4", asrcdec4),
178362306a36Sopenharmony_ci
178462306a36Sopenharmony_ci	CS42L43_DAPM_MUX("ISRC1INT1", isrc1int1),
178562306a36Sopenharmony_ci	CS42L43_DAPM_MUX("ISRC1INT2", isrc1int2),
178662306a36Sopenharmony_ci	CS42L43_DAPM_MUX("ISRC1DEC1", isrc1dec1),
178762306a36Sopenharmony_ci	CS42L43_DAPM_MUX("ISRC1DEC2", isrc1dec2),
178862306a36Sopenharmony_ci	CS42L43_DAPM_MUX("ISRC2INT1", isrc2int1),
178962306a36Sopenharmony_ci	CS42L43_DAPM_MUX("ISRC2INT2", isrc2int2),
179062306a36Sopenharmony_ci	CS42L43_DAPM_MUX("ISRC2DEC1", isrc2dec1),
179162306a36Sopenharmony_ci	CS42L43_DAPM_MUX("ISRC2DEC2", isrc2dec2),
179262306a36Sopenharmony_ci
179362306a36Sopenharmony_ci	CS42L43_DAPM_MUX("SPDIF1", spdif1),
179462306a36Sopenharmony_ci	CS42L43_DAPM_MUX("SPDIF2", spdif2),
179562306a36Sopenharmony_ci
179662306a36Sopenharmony_ci	CS42L43_DAPM_MIXER("EQ1", eq1),
179762306a36Sopenharmony_ci	CS42L43_DAPM_MIXER("EQ2", eq2),
179862306a36Sopenharmony_ci
179962306a36Sopenharmony_ci	CS42L43_DAPM_MIXER("Speaker L", amp1),
180062306a36Sopenharmony_ci	CS42L43_DAPM_MIXER("Speaker R", amp2),
180162306a36Sopenharmony_ci
180262306a36Sopenharmony_ci	CS42L43_DAPM_MIXER("Headphone L", amp3),
180362306a36Sopenharmony_ci	CS42L43_DAPM_MIXER("Headphone R", amp4),
180462306a36Sopenharmony_ci};
180562306a36Sopenharmony_ci
180662306a36Sopenharmony_cistatic const struct snd_soc_dapm_route cs42l43_routes[] = {
180762306a36Sopenharmony_ci	{ "ADC1_IN1_P",		NULL,	"PLL" },
180862306a36Sopenharmony_ci	{ "ADC1_IN1_N",		NULL,	"PLL" },
180962306a36Sopenharmony_ci	{ "ADC1_IN2_P",		NULL,	"PLL" },
181062306a36Sopenharmony_ci	{ "ADC1_IN2_N",		NULL,	"PLL" },
181162306a36Sopenharmony_ci	{ "ADC2_IN_P",		NULL,	"PLL" },
181262306a36Sopenharmony_ci	{ "ADC2_IN_N",		NULL,	"PLL" },
181362306a36Sopenharmony_ci	{ "PDM1_DIN",		NULL,	"PLL" },
181462306a36Sopenharmony_ci	{ "PDM2_DIN",		NULL,	"PLL" },
181562306a36Sopenharmony_ci	{ "AMP1_OUT_P",		NULL,	"PLL" },
181662306a36Sopenharmony_ci	{ "AMP1_OUT_N",		NULL,	"PLL" },
181762306a36Sopenharmony_ci	{ "AMP2_OUT_P",		NULL,	"PLL" },
181862306a36Sopenharmony_ci	{ "AMP2_OUT_N",		NULL,	"PLL" },
181962306a36Sopenharmony_ci	{ "SPDIF_TX",		NULL,	"PLL" },
182062306a36Sopenharmony_ci	{ "HP",			NULL,	"PLL" },
182162306a36Sopenharmony_ci	{ "AMP3_OUT",		NULL,	"PLL" },
182262306a36Sopenharmony_ci	{ "AMP4_OUT",		NULL,	"PLL" },
182362306a36Sopenharmony_ci	{ "Tone 1",		NULL,	"PLL" },
182462306a36Sopenharmony_ci	{ "Tone 2",		NULL,	"PLL" },
182562306a36Sopenharmony_ci	{ "ASP Playback",	NULL,	"PLL" },
182662306a36Sopenharmony_ci	{ "ASP Capture",	NULL,	"PLL" },
182762306a36Sopenharmony_ci	{ "DP1 Capture",	NULL,	"PLL" },
182862306a36Sopenharmony_ci	{ "DP2 Capture",	NULL,	"PLL" },
182962306a36Sopenharmony_ci	{ "DP3 Capture",	NULL,	"PLL" },
183062306a36Sopenharmony_ci	{ "DP4 Capture",	NULL,	"PLL" },
183162306a36Sopenharmony_ci	{ "DP5 Playback",	NULL,	"PLL" },
183262306a36Sopenharmony_ci	{ "DP6 Playback",	NULL,	"PLL" },
183362306a36Sopenharmony_ci	{ "DP7 Playback",	NULL,	"PLL" },
183462306a36Sopenharmony_ci
183562306a36Sopenharmony_ci	{ "ADC1 Input",		"IN1",	"ADC1_IN1_P" },
183662306a36Sopenharmony_ci	{ "ADC1 Input",		"IN1",	"ADC1_IN1_N" },
183762306a36Sopenharmony_ci	{ "ADC1 Input",		"IN2",	"ADC1_IN2_P" },
183862306a36Sopenharmony_ci	{ "ADC1 Input",		"IN2",	"ADC1_IN2_N" },
183962306a36Sopenharmony_ci
184062306a36Sopenharmony_ci	{ "ADC1",		NULL,	"ADC1 Input" },
184162306a36Sopenharmony_ci	{ "ADC2",		NULL,	"ADC2_IN_P" },
184262306a36Sopenharmony_ci	{ "ADC2",		NULL,	"ADC2_IN_N" },
184362306a36Sopenharmony_ci
184462306a36Sopenharmony_ci	{ "PDM1L",		NULL,	"PDM1_DIN" },
184562306a36Sopenharmony_ci	{ "PDM1R",		NULL,	"PDM1_DIN" },
184662306a36Sopenharmony_ci	{ "PDM2L",		NULL,	"PDM2_DIN" },
184762306a36Sopenharmony_ci	{ "PDM2R",		NULL,	"PDM2_DIN" },
184862306a36Sopenharmony_ci
184962306a36Sopenharmony_ci	{ "Decimator 1 Mode",	"PDM",	"PDM1L" },
185062306a36Sopenharmony_ci	{ "Decimator 1 Mode",	"ADC",	"ADC1" },
185162306a36Sopenharmony_ci	{ "Decimator 2 Mode",	"PDM",	"PDM1R" },
185262306a36Sopenharmony_ci	{ "Decimator 2 Mode",	"ADC",	"ADC2" },
185362306a36Sopenharmony_ci
185462306a36Sopenharmony_ci	{ "Decimator 1",	NULL,	"Decimator 1 Mode" },
185562306a36Sopenharmony_ci	{ "Decimator 2",	NULL,	"Decimator 2 Mode" },
185662306a36Sopenharmony_ci	{ "Decimator 3",	NULL,	"PDM2L" },
185762306a36Sopenharmony_ci	{ "Decimator 4",	NULL,	"PDM2R" },
185862306a36Sopenharmony_ci
185962306a36Sopenharmony_ci	{ "ASP Capture",	NULL,	"ASPTX1" },
186062306a36Sopenharmony_ci	{ "ASP Capture",	NULL,	"ASPTX2" },
186162306a36Sopenharmony_ci	{ "ASP Capture",	NULL,	"ASPTX3" },
186262306a36Sopenharmony_ci	{ "ASP Capture",	NULL,	"ASPTX4" },
186362306a36Sopenharmony_ci	{ "ASP Capture",	NULL,	"ASPTX5" },
186462306a36Sopenharmony_ci	{ "ASP Capture",	NULL,	"ASPTX6" },
186562306a36Sopenharmony_ci	{ "ASPTX1",		NULL,	"BCLK" },
186662306a36Sopenharmony_ci	{ "ASPTX2",		NULL,	"BCLK" },
186762306a36Sopenharmony_ci	{ "ASPTX3",		NULL,	"BCLK" },
186862306a36Sopenharmony_ci	{ "ASPTX4",		NULL,	"BCLK" },
186962306a36Sopenharmony_ci	{ "ASPTX5",		NULL,	"BCLK" },
187062306a36Sopenharmony_ci	{ "ASPTX6",		NULL,	"BCLK" },
187162306a36Sopenharmony_ci
187262306a36Sopenharmony_ci	{ "ASPRX1",		NULL,	"ASP Playback" },
187362306a36Sopenharmony_ci	{ "ASPRX2",		NULL,	"ASP Playback" },
187462306a36Sopenharmony_ci	{ "ASPRX3",		NULL,	"ASP Playback" },
187562306a36Sopenharmony_ci	{ "ASPRX4",		NULL,	"ASP Playback" },
187662306a36Sopenharmony_ci	{ "ASPRX5",		NULL,	"ASP Playback" },
187762306a36Sopenharmony_ci	{ "ASPRX6",		NULL,	"ASP Playback" },
187862306a36Sopenharmony_ci	{ "ASPRX1",		NULL,	"BCLK" },
187962306a36Sopenharmony_ci	{ "ASPRX2",		NULL,	"BCLK" },
188062306a36Sopenharmony_ci	{ "ASPRX3",		NULL,	"BCLK" },
188162306a36Sopenharmony_ci	{ "ASPRX4",		NULL,	"BCLK" },
188262306a36Sopenharmony_ci	{ "ASPRX5",		NULL,	"BCLK" },
188362306a36Sopenharmony_ci	{ "ASPRX6",		NULL,	"BCLK" },
188462306a36Sopenharmony_ci
188562306a36Sopenharmony_ci	{ "DP1 Capture",	NULL, "DP1TX1" },
188662306a36Sopenharmony_ci	{ "DP1 Capture",	NULL, "DP1TX2" },
188762306a36Sopenharmony_ci	{ "DP1 Capture",	NULL, "DP1TX3" },
188862306a36Sopenharmony_ci	{ "DP1 Capture",	NULL, "DP1TX4" },
188962306a36Sopenharmony_ci
189062306a36Sopenharmony_ci	{ "DP2 Capture",	NULL, "DP2TX1" },
189162306a36Sopenharmony_ci	{ "DP2 Capture",	NULL, "DP2TX2" },
189262306a36Sopenharmony_ci
189362306a36Sopenharmony_ci	{ "DP3 Capture",	NULL, "DP3TX1" },
189462306a36Sopenharmony_ci	{ "DP3 Capture",	NULL, "DP3TX2" },
189562306a36Sopenharmony_ci
189662306a36Sopenharmony_ci	{ "DP4 Capture",	NULL, "DP4TX1" },
189762306a36Sopenharmony_ci	{ "DP4 Capture",	NULL, "DP4TX2" },
189862306a36Sopenharmony_ci
189962306a36Sopenharmony_ci	{ "DP5RX1",		NULL, "DP5 Playback" },
190062306a36Sopenharmony_ci	{ "DP5RX2",		NULL, "DP5 Playback" },
190162306a36Sopenharmony_ci
190262306a36Sopenharmony_ci	{ "DP6RX1",		NULL, "DP6 Playback" },
190362306a36Sopenharmony_ci	{ "DP6RX2",		NULL, "DP6 Playback" },
190462306a36Sopenharmony_ci
190562306a36Sopenharmony_ci	{ "DP7RX1",		NULL, "DP7 Playback" },
190662306a36Sopenharmony_ci	{ "DP7RX2",		NULL, "DP7 Playback" },
190762306a36Sopenharmony_ci
190862306a36Sopenharmony_ci	{ "AMP1",		NULL,	"vdd-amp" },
190962306a36Sopenharmony_ci	{ "AMP2",		NULL,	"vdd-amp" },
191062306a36Sopenharmony_ci
191162306a36Sopenharmony_ci	{ "AMP1_OUT_P",		NULL,	"AMP1" },
191262306a36Sopenharmony_ci	{ "AMP1_OUT_N",		NULL,	"AMP1" },
191362306a36Sopenharmony_ci	{ "AMP2_OUT_P",		NULL,	"AMP2" },
191462306a36Sopenharmony_ci	{ "AMP2_OUT_N",		NULL,	"AMP2" },
191562306a36Sopenharmony_ci
191662306a36Sopenharmony_ci	{ "SPDIF_TX",		NULL,	"SPDIF" },
191762306a36Sopenharmony_ci
191862306a36Sopenharmony_ci	{ "AMP3_OUT",		NULL,	"HP" },
191962306a36Sopenharmony_ci	{ "AMP4_OUT",		NULL,	"HP" },
192062306a36Sopenharmony_ci
192162306a36Sopenharmony_ci	{ "Tone 1",		NULL,	"Tone" },
192262306a36Sopenharmony_ci	{ "Tone 1",		NULL,	"Tone Generator" },
192362306a36Sopenharmony_ci	{ "Tone 2",		NULL,	"Tone" },
192462306a36Sopenharmony_ci	{ "Tone 2",		NULL,	"Tone Generator" },
192562306a36Sopenharmony_ci
192662306a36Sopenharmony_ci	{ "ISRC1INT2",		NULL,	"ISRC1" },
192762306a36Sopenharmony_ci	{ "ISRC1INT1",		NULL,	"ISRC1" },
192862306a36Sopenharmony_ci	{ "ISRC1DEC2",		NULL,	"ISRC1" },
192962306a36Sopenharmony_ci	{ "ISRC1DEC1",		NULL,	"ISRC1" },
193062306a36Sopenharmony_ci
193162306a36Sopenharmony_ci	{ "ISRC2INT2",		NULL,	"ISRC2" },
193262306a36Sopenharmony_ci	{ "ISRC2INT1",		NULL,	"ISRC2" },
193362306a36Sopenharmony_ci	{ "ISRC2DEC2",		NULL,	"ISRC2" },
193462306a36Sopenharmony_ci	{ "ISRC2DEC1",		NULL,	"ISRC2" },
193562306a36Sopenharmony_ci
193662306a36Sopenharmony_ci	{ "ASRC_INT1",		NULL,	"ASRC_INT" },
193762306a36Sopenharmony_ci	{ "ASRC_INT2",		NULL,	"ASRC_INT" },
193862306a36Sopenharmony_ci	{ "ASRC_INT3",		NULL,	"ASRC_INT" },
193962306a36Sopenharmony_ci	{ "ASRC_INT4",		NULL,	"ASRC_INT" },
194062306a36Sopenharmony_ci	{ "ASRC_DEC1",		NULL,	"ASRC_DEC" },
194162306a36Sopenharmony_ci	{ "ASRC_DEC2",		NULL,	"ASRC_DEC" },
194262306a36Sopenharmony_ci	{ "ASRC_DEC3",		NULL,	"ASRC_DEC" },
194362306a36Sopenharmony_ci	{ "ASRC_DEC4",		NULL,	"ASRC_DEC" },
194462306a36Sopenharmony_ci
194562306a36Sopenharmony_ci	{ "EQ",			NULL,	"EQ Clock" },
194662306a36Sopenharmony_ci
194762306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("ASPTX1", "ASPTX1"),
194862306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("ASPTX2", "ASPTX2"),
194962306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("ASPTX3", "ASPTX3"),
195062306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("ASPTX4", "ASPTX4"),
195162306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("ASPTX5", "ASPTX5"),
195262306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("ASPTX6", "ASPTX6"),
195362306a36Sopenharmony_ci
195462306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("DP1TX1", "DP1TX1"),
195562306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("DP1TX2", "DP1TX2"),
195662306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("DP1TX3", "DP1TX3"),
195762306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("DP1TX4", "DP1TX4"),
195862306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("DP2TX1", "DP2TX1"),
195962306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("DP2TX2", "DP2TX2"),
196062306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("DP3TX1", "DP3TX1"),
196162306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("DP3TX2", "DP3TX2"),
196262306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("DP4TX1", "DP4TX1"),
196362306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("DP4TX2", "DP4TX2"),
196462306a36Sopenharmony_ci
196562306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("ASRC INT1", "ASRC_INT1"),
196662306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("ASRC INT2", "ASRC_INT2"),
196762306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("ASRC INT3", "ASRC_INT3"),
196862306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("ASRC INT4", "ASRC_INT4"),
196962306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("ASRC DEC1", "ASRC_DEC1"),
197062306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("ASRC DEC2", "ASRC_DEC2"),
197162306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("ASRC DEC3", "ASRC_DEC3"),
197262306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("ASRC DEC4", "ASRC_DEC4"),
197362306a36Sopenharmony_ci
197462306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("ISRC1INT1", "ISRC1INT1"),
197562306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("ISRC1INT2", "ISRC1INT2"),
197662306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("ISRC1DEC1", "ISRC1DEC1"),
197762306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("ISRC1DEC2", "ISRC1DEC2"),
197862306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("ISRC2INT1", "ISRC2INT1"),
197962306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("ISRC2INT2", "ISRC2INT2"),
198062306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("ISRC2DEC1", "ISRC2DEC1"),
198162306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("ISRC2DEC2", "ISRC2DEC2"),
198262306a36Sopenharmony_ci
198362306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("SPDIF1", "SPDIF"),
198462306a36Sopenharmony_ci	CS42L43_MUX_ROUTES("SPDIF2", "SPDIF"),
198562306a36Sopenharmony_ci
198662306a36Sopenharmony_ci	CS42L43_MIXER_ROUTES("EQ1", "EQ"),
198762306a36Sopenharmony_ci	CS42L43_MIXER_ROUTES("EQ2", "EQ"),
198862306a36Sopenharmony_ci
198962306a36Sopenharmony_ci	CS42L43_MIXER_ROUTES("Speaker L", "AMP1"),
199062306a36Sopenharmony_ci	CS42L43_MIXER_ROUTES("Speaker R", "AMP2"),
199162306a36Sopenharmony_ci
199262306a36Sopenharmony_ci	CS42L43_MIXER_ROUTES("Headphone L", "HP"),
199362306a36Sopenharmony_ci	CS42L43_MIXER_ROUTES("Headphone R", "HP"),
199462306a36Sopenharmony_ci};
199562306a36Sopenharmony_ci
199662306a36Sopenharmony_cistatic int cs42l43_set_sysclk(struct snd_soc_component *component, int clk_id,
199762306a36Sopenharmony_ci			      int src, unsigned int freq, int dir)
199862306a36Sopenharmony_ci{
199962306a36Sopenharmony_ci	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
200062306a36Sopenharmony_ci	struct cs42l43 *cs42l43 = priv->core;
200162306a36Sopenharmony_ci	int ret;
200262306a36Sopenharmony_ci
200362306a36Sopenharmony_ci	mutex_lock(&cs42l43->pll_lock);
200462306a36Sopenharmony_ci	ret = cs42l43_set_pll(priv, src, freq);
200562306a36Sopenharmony_ci	mutex_unlock(&cs42l43->pll_lock);
200662306a36Sopenharmony_ci
200762306a36Sopenharmony_ci	return ret;
200862306a36Sopenharmony_ci}
200962306a36Sopenharmony_ci
201062306a36Sopenharmony_cistatic int cs42l43_component_probe(struct snd_soc_component *component)
201162306a36Sopenharmony_ci{
201262306a36Sopenharmony_ci	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);
201362306a36Sopenharmony_ci	struct cs42l43 *cs42l43 = priv->core;
201462306a36Sopenharmony_ci
201562306a36Sopenharmony_ci	snd_soc_component_init_regmap(component, cs42l43->regmap);
201662306a36Sopenharmony_ci
201762306a36Sopenharmony_ci	cs42l43_mask_to_slots(priv, CS42L43_DEFAULT_SLOTS, priv->tx_slots);
201862306a36Sopenharmony_ci	cs42l43_mask_to_slots(priv, CS42L43_DEFAULT_SLOTS, priv->rx_slots);
201962306a36Sopenharmony_ci
202062306a36Sopenharmony_ci	priv->component = component;
202162306a36Sopenharmony_ci	priv->constraint = cs42l43_constraint;
202262306a36Sopenharmony_ci
202362306a36Sopenharmony_ci	return 0;
202462306a36Sopenharmony_ci}
202562306a36Sopenharmony_ci
202662306a36Sopenharmony_cistatic const struct snd_soc_component_driver cs42l43_component_drv = {
202762306a36Sopenharmony_ci	.name			= "cs42l43-codec",
202862306a36Sopenharmony_ci
202962306a36Sopenharmony_ci	.probe			= cs42l43_component_probe,
203062306a36Sopenharmony_ci	.set_sysclk		= cs42l43_set_sysclk,
203162306a36Sopenharmony_ci	.set_jack		= cs42l43_set_jack,
203262306a36Sopenharmony_ci
203362306a36Sopenharmony_ci	.endianness		= 1,
203462306a36Sopenharmony_ci
203562306a36Sopenharmony_ci	.controls		= cs42l43_controls,
203662306a36Sopenharmony_ci	.num_controls		= ARRAY_SIZE(cs42l43_controls),
203762306a36Sopenharmony_ci	.dapm_widgets		= cs42l43_widgets,
203862306a36Sopenharmony_ci	.num_dapm_widgets	= ARRAY_SIZE(cs42l43_widgets),
203962306a36Sopenharmony_ci	.dapm_routes		= cs42l43_routes,
204062306a36Sopenharmony_ci	.num_dapm_routes	= ARRAY_SIZE(cs42l43_routes),
204162306a36Sopenharmony_ci};
204262306a36Sopenharmony_ci
204362306a36Sopenharmony_cistruct cs42l43_irq {
204462306a36Sopenharmony_ci	unsigned int irq;
204562306a36Sopenharmony_ci	const char *name;
204662306a36Sopenharmony_ci	irq_handler_t handler;
204762306a36Sopenharmony_ci};
204862306a36Sopenharmony_ci
204962306a36Sopenharmony_cistatic const struct cs42l43_irq cs42l43_irqs[] = {
205062306a36Sopenharmony_ci	{ CS42L43_PLL_LOST_LOCK, "pll lost lock", cs42l43_pll_lost_lock },
205162306a36Sopenharmony_ci	{ CS42L43_PLL_READY, "pll ready", cs42l43_pll_ready },
205262306a36Sopenharmony_ci	{ CS42L43_HP_STARTUP_DONE, "hp startup", cs42l43_hp_startup },
205362306a36Sopenharmony_ci	{ CS42L43_HP_SHUTDOWN_DONE, "hp shutdown", cs42l43_hp_shutdown },
205462306a36Sopenharmony_ci	{ CS42L43_HSDET_DONE, "type detect", cs42l43_type_detect },
205562306a36Sopenharmony_ci	{ CS42L43_TIPSENSE_UNPLUG_PDET, "tip sense unplug", cs42l43_tip_sense },
205662306a36Sopenharmony_ci	{ CS42L43_TIPSENSE_PLUG_PDET, "tip sense plug", cs42l43_tip_sense },
205762306a36Sopenharmony_ci	{ CS42L43_DC_DETECT1_TRUE, "button press", cs42l43_button_press },
205862306a36Sopenharmony_ci	{ CS42L43_DC_DETECT1_FALSE, "button release", cs42l43_button_release },
205962306a36Sopenharmony_ci	{ CS42L43_HSBIAS_CLAMPED, "hsbias detect clamp", cs42l43_bias_detect_clamp },
206062306a36Sopenharmony_ci	{ CS42L43_AMP2_CLK_STOP_FAULT, "spkr clock stop", cs42l43_spkr_clock_stop },
206162306a36Sopenharmony_ci	{ CS42L43_AMP1_CLK_STOP_FAULT, "spkl clock stop", cs42l43_spkl_clock_stop },
206262306a36Sopenharmony_ci	{ CS42L43_AMP2_VDDSPK_FAULT, "spkr brown out", cs42l43_spkr_brown_out },
206362306a36Sopenharmony_ci	{ CS42L43_AMP1_VDDSPK_FAULT, "spkl brown out", cs42l43_spkl_brown_out },
206462306a36Sopenharmony_ci	{ CS42L43_AMP2_SHUTDOWN_DONE, "spkr shutdown", cs42l43_spkr_shutdown },
206562306a36Sopenharmony_ci	{ CS42L43_AMP1_SHUTDOWN_DONE, "spkl shutdown", cs42l43_spkl_shutdown },
206662306a36Sopenharmony_ci	{ CS42L43_AMP2_STARTUP_DONE, "spkr startup", cs42l43_spkr_startup },
206762306a36Sopenharmony_ci	{ CS42L43_AMP1_STARTUP_DONE, "spkl startup", cs42l43_spkl_startup },
206862306a36Sopenharmony_ci	{ CS42L43_AMP2_THERM_SHDN, "spkr thermal shutdown", cs42l43_spkr_therm_shutdown },
206962306a36Sopenharmony_ci	{ CS42L43_AMP1_THERM_SHDN, "spkl thermal shutdown", cs42l43_spkl_therm_shutdown },
207062306a36Sopenharmony_ci	{ CS42L43_AMP2_THERM_WARN, "spkr thermal warning", cs42l43_spkr_therm_warm },
207162306a36Sopenharmony_ci	{ CS42L43_AMP1_THERM_WARN, "spkl thermal warning", cs42l43_spkl_therm_warm },
207262306a36Sopenharmony_ci	{ CS42L43_AMP2_SCDET, "spkr short circuit", cs42l43_spkr_sc_detect },
207362306a36Sopenharmony_ci	{ CS42L43_AMP1_SCDET, "spkl short circuit", cs42l43_spkl_sc_detect },
207462306a36Sopenharmony_ci	{ CS42L43_HP_ILIMIT, "hp ilimit", cs42l43_hp_ilimit },
207562306a36Sopenharmony_ci	{ CS42L43_HP_LOADDET_DONE, "load detect done", cs42l43_load_detect },
207662306a36Sopenharmony_ci};
207762306a36Sopenharmony_ci
207862306a36Sopenharmony_cistatic int cs42l43_request_irq(struct cs42l43_codec *priv,
207962306a36Sopenharmony_ci			       struct irq_domain *dom, const char * const name,
208062306a36Sopenharmony_ci			       unsigned int irq, irq_handler_t handler,
208162306a36Sopenharmony_ci			       unsigned long flags)
208262306a36Sopenharmony_ci{
208362306a36Sopenharmony_ci	int ret;
208462306a36Sopenharmony_ci
208562306a36Sopenharmony_ci	ret = irq_create_mapping(dom, irq);
208662306a36Sopenharmony_ci	if (ret < 0)
208762306a36Sopenharmony_ci		return dev_err_probe(priv->dev, ret, "Failed to map IRQ %s\n", name);
208862306a36Sopenharmony_ci
208962306a36Sopenharmony_ci	dev_dbg(priv->dev, "Request IRQ %d for %s\n", ret, name);
209062306a36Sopenharmony_ci
209162306a36Sopenharmony_ci	ret = devm_request_threaded_irq(priv->dev, ret, NULL, handler,
209262306a36Sopenharmony_ci					IRQF_ONESHOT | flags, name, priv);
209362306a36Sopenharmony_ci	if (ret)
209462306a36Sopenharmony_ci		return dev_err_probe(priv->dev, ret, "Failed to request IRQ %s\n", name);
209562306a36Sopenharmony_ci
209662306a36Sopenharmony_ci	return 0;
209762306a36Sopenharmony_ci}
209862306a36Sopenharmony_ci
209962306a36Sopenharmony_cistatic int cs42l43_shutter_irq(struct cs42l43_codec *priv,
210062306a36Sopenharmony_ci			       struct irq_domain *dom, unsigned int shutter,
210162306a36Sopenharmony_ci			       const char * const open_name,
210262306a36Sopenharmony_ci			       const char * const close_name,
210362306a36Sopenharmony_ci			       irq_handler_t handler)
210462306a36Sopenharmony_ci{
210562306a36Sopenharmony_ci	unsigned int open_irq, close_irq;
210662306a36Sopenharmony_ci	int ret;
210762306a36Sopenharmony_ci
210862306a36Sopenharmony_ci	switch (shutter) {
210962306a36Sopenharmony_ci	case 0x1:
211062306a36Sopenharmony_ci		dev_warn(priv->dev, "Manual shutters, notifications not available\n");
211162306a36Sopenharmony_ci		return 0;
211262306a36Sopenharmony_ci	case 0x2:
211362306a36Sopenharmony_ci		open_irq = CS42L43_GPIO1_RISE;
211462306a36Sopenharmony_ci		close_irq = CS42L43_GPIO1_FALL;
211562306a36Sopenharmony_ci		break;
211662306a36Sopenharmony_ci	case 0x4:
211762306a36Sopenharmony_ci		open_irq = CS42L43_GPIO2_RISE;
211862306a36Sopenharmony_ci		close_irq = CS42L43_GPIO2_FALL;
211962306a36Sopenharmony_ci		break;
212062306a36Sopenharmony_ci	case 0x8:
212162306a36Sopenharmony_ci		open_irq = CS42L43_GPIO3_RISE;
212262306a36Sopenharmony_ci		close_irq = CS42L43_GPIO3_FALL;
212362306a36Sopenharmony_ci		break;
212462306a36Sopenharmony_ci	default:
212562306a36Sopenharmony_ci		return 0;
212662306a36Sopenharmony_ci	}
212762306a36Sopenharmony_ci
212862306a36Sopenharmony_ci	ret = cs42l43_request_irq(priv, dom, close_name, close_irq, handler, IRQF_SHARED);
212962306a36Sopenharmony_ci	if (ret)
213062306a36Sopenharmony_ci		return ret;
213162306a36Sopenharmony_ci
213262306a36Sopenharmony_ci	return cs42l43_request_irq(priv, dom, open_name, open_irq, handler, IRQF_SHARED);
213362306a36Sopenharmony_ci}
213462306a36Sopenharmony_ci
213562306a36Sopenharmony_cistatic int cs42l43_codec_probe(struct platform_device *pdev)
213662306a36Sopenharmony_ci{
213762306a36Sopenharmony_ci	struct cs42l43 *cs42l43 = dev_get_drvdata(pdev->dev.parent);
213862306a36Sopenharmony_ci	struct cs42l43_codec *priv;
213962306a36Sopenharmony_ci	struct irq_domain *dom;
214062306a36Sopenharmony_ci	unsigned int val;
214162306a36Sopenharmony_ci	int i, ret;
214262306a36Sopenharmony_ci
214362306a36Sopenharmony_ci	dom = irq_find_matching_fwnode(dev_fwnode(cs42l43->dev), DOMAIN_BUS_ANY);
214462306a36Sopenharmony_ci	if (!dom)
214562306a36Sopenharmony_ci		return -EPROBE_DEFER;
214662306a36Sopenharmony_ci
214762306a36Sopenharmony_ci	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
214862306a36Sopenharmony_ci	if (!priv)
214962306a36Sopenharmony_ci		return -ENOMEM;
215062306a36Sopenharmony_ci
215162306a36Sopenharmony_ci	priv->dev = &pdev->dev;
215262306a36Sopenharmony_ci	priv->core = cs42l43;
215362306a36Sopenharmony_ci
215462306a36Sopenharmony_ci	platform_set_drvdata(pdev, priv);
215562306a36Sopenharmony_ci
215662306a36Sopenharmony_ci	mutex_init(&priv->jack_lock);
215762306a36Sopenharmony_ci	mutex_init(&priv->spk_vu_lock);
215862306a36Sopenharmony_ci
215962306a36Sopenharmony_ci	init_completion(&priv->hp_startup);
216062306a36Sopenharmony_ci	init_completion(&priv->hp_shutdown);
216162306a36Sopenharmony_ci	init_completion(&priv->spkr_shutdown);
216262306a36Sopenharmony_ci	init_completion(&priv->spkl_shutdown);
216362306a36Sopenharmony_ci	init_completion(&priv->spkr_startup);
216462306a36Sopenharmony_ci	init_completion(&priv->spkl_startup);
216562306a36Sopenharmony_ci	init_completion(&priv->pll_ready);
216662306a36Sopenharmony_ci	init_completion(&priv->type_detect);
216762306a36Sopenharmony_ci	init_completion(&priv->load_detect);
216862306a36Sopenharmony_ci
216962306a36Sopenharmony_ci	INIT_DELAYED_WORK(&priv->tip_sense_work, cs42l43_tip_sense_work);
217062306a36Sopenharmony_ci	INIT_DELAYED_WORK(&priv->bias_sense_timeout, cs42l43_bias_sense_timeout);
217162306a36Sopenharmony_ci	INIT_DELAYED_WORK(&priv->button_press_work, cs42l43_button_press_work);
217262306a36Sopenharmony_ci	INIT_WORK(&priv->button_release_work, cs42l43_button_release_work);
217362306a36Sopenharmony_ci
217462306a36Sopenharmony_ci	pm_runtime_set_autosuspend_delay(priv->dev, 100);
217562306a36Sopenharmony_ci	pm_runtime_use_autosuspend(priv->dev);
217662306a36Sopenharmony_ci	pm_runtime_set_active(priv->dev);
217762306a36Sopenharmony_ci	pm_runtime_get_noresume(priv->dev);
217862306a36Sopenharmony_ci
217962306a36Sopenharmony_ci	ret = devm_pm_runtime_enable(priv->dev);
218062306a36Sopenharmony_ci	if (ret)
218162306a36Sopenharmony_ci		goto err_pm;
218262306a36Sopenharmony_ci
218362306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(cs42l43_irqs); i++) {
218462306a36Sopenharmony_ci		ret = cs42l43_request_irq(priv, dom, cs42l43_irqs[i].name,
218562306a36Sopenharmony_ci					  cs42l43_irqs[i].irq,
218662306a36Sopenharmony_ci					  cs42l43_irqs[i].handler, 0);
218762306a36Sopenharmony_ci		if (ret)
218862306a36Sopenharmony_ci			goto err_pm;
218962306a36Sopenharmony_ci	}
219062306a36Sopenharmony_ci
219162306a36Sopenharmony_ci	ret = regmap_read(cs42l43->regmap, CS42L43_SHUTTER_CONTROL, &val);
219262306a36Sopenharmony_ci	if (ret) {
219362306a36Sopenharmony_ci		dev_err(priv->dev, "Failed to check shutter source: %d\n", ret);
219462306a36Sopenharmony_ci		goto err_pm;
219562306a36Sopenharmony_ci	}
219662306a36Sopenharmony_ci
219762306a36Sopenharmony_ci	ret = cs42l43_shutter_irq(priv, dom, val & CS42L43_MIC_SHUTTER_CFG_MASK,
219862306a36Sopenharmony_ci				  "mic shutter open", "mic shutter close",
219962306a36Sopenharmony_ci				  cs42l43_mic_shutter);
220062306a36Sopenharmony_ci	if (ret)
220162306a36Sopenharmony_ci		goto err_pm;
220262306a36Sopenharmony_ci
220362306a36Sopenharmony_ci	ret = cs42l43_shutter_irq(priv, dom, (val & CS42L43_SPK_SHUTTER_CFG_MASK) >>
220462306a36Sopenharmony_ci				  CS42L43_SPK_SHUTTER_CFG_SHIFT,
220562306a36Sopenharmony_ci				  "spk shutter open", "spk shutter close",
220662306a36Sopenharmony_ci				  cs42l43_spk_shutter);
220762306a36Sopenharmony_ci	if (ret)
220862306a36Sopenharmony_ci		goto err_pm;
220962306a36Sopenharmony_ci
221062306a36Sopenharmony_ci	// Don't use devm as we need to get against the MFD device
221162306a36Sopenharmony_ci	priv->mclk = clk_get_optional(cs42l43->dev, "mclk");
221262306a36Sopenharmony_ci	if (IS_ERR(priv->mclk)) {
221362306a36Sopenharmony_ci		ret = PTR_ERR(priv->mclk);
221462306a36Sopenharmony_ci		dev_err_probe(priv->dev, ret, "Failed to get mclk\n");
221562306a36Sopenharmony_ci		goto err_pm;
221662306a36Sopenharmony_ci	}
221762306a36Sopenharmony_ci
221862306a36Sopenharmony_ci	ret = devm_snd_soc_register_component(priv->dev, &cs42l43_component_drv,
221962306a36Sopenharmony_ci					      cs42l43_dais, ARRAY_SIZE(cs42l43_dais));
222062306a36Sopenharmony_ci	if (ret) {
222162306a36Sopenharmony_ci		dev_err_probe(priv->dev, ret, "Failed to register component\n");
222262306a36Sopenharmony_ci		goto err_clk;
222362306a36Sopenharmony_ci	}
222462306a36Sopenharmony_ci
222562306a36Sopenharmony_ci	pm_runtime_mark_last_busy(priv->dev);
222662306a36Sopenharmony_ci	pm_runtime_put_autosuspend(priv->dev);
222762306a36Sopenharmony_ci
222862306a36Sopenharmony_ci	return 0;
222962306a36Sopenharmony_ci
223062306a36Sopenharmony_cierr_clk:
223162306a36Sopenharmony_ci	clk_put(priv->mclk);
223262306a36Sopenharmony_cierr_pm:
223362306a36Sopenharmony_ci	pm_runtime_put_sync(priv->dev);
223462306a36Sopenharmony_ci
223562306a36Sopenharmony_ci	return ret;
223662306a36Sopenharmony_ci}
223762306a36Sopenharmony_ci
223862306a36Sopenharmony_cistatic int cs42l43_codec_remove(struct platform_device *pdev)
223962306a36Sopenharmony_ci{
224062306a36Sopenharmony_ci	struct cs42l43_codec *priv = platform_get_drvdata(pdev);
224162306a36Sopenharmony_ci
224262306a36Sopenharmony_ci	clk_put(priv->mclk);
224362306a36Sopenharmony_ci
224462306a36Sopenharmony_ci	return 0;
224562306a36Sopenharmony_ci}
224662306a36Sopenharmony_ci
224762306a36Sopenharmony_cistatic int cs42l43_codec_runtime_resume(struct device *dev)
224862306a36Sopenharmony_ci{
224962306a36Sopenharmony_ci	struct cs42l43_codec *priv = dev_get_drvdata(dev);
225062306a36Sopenharmony_ci
225162306a36Sopenharmony_ci	dev_dbg(priv->dev, "Runtime resume\n");
225262306a36Sopenharmony_ci
225362306a36Sopenharmony_ci	// Toggle the speaker volume update incase the speaker volume was synced
225462306a36Sopenharmony_ci	cs42l43_spk_vu_sync(priv);
225562306a36Sopenharmony_ci
225662306a36Sopenharmony_ci	return 0;
225762306a36Sopenharmony_ci}
225862306a36Sopenharmony_ci
225962306a36Sopenharmony_ciDEFINE_RUNTIME_DEV_PM_OPS(cs42l43_codec_pm_ops, NULL,
226062306a36Sopenharmony_ci			  cs42l43_codec_runtime_resume, NULL);
226162306a36Sopenharmony_ci
226262306a36Sopenharmony_cistatic const struct platform_device_id cs42l43_codec_id_table[] = {
226362306a36Sopenharmony_ci	{ "cs42l43-codec", },
226462306a36Sopenharmony_ci	{}
226562306a36Sopenharmony_ci};
226662306a36Sopenharmony_ciMODULE_DEVICE_TABLE(platform, cs42l43_codec_id_table);
226762306a36Sopenharmony_ci
226862306a36Sopenharmony_cistatic struct platform_driver cs42l43_codec_driver = {
226962306a36Sopenharmony_ci	.driver = {
227062306a36Sopenharmony_ci		.name	= "cs42l43-codec",
227162306a36Sopenharmony_ci		.pm	= &cs42l43_codec_pm_ops,
227262306a36Sopenharmony_ci	},
227362306a36Sopenharmony_ci
227462306a36Sopenharmony_ci	.probe		= cs42l43_codec_probe,
227562306a36Sopenharmony_ci	.remove		= cs42l43_codec_remove,
227662306a36Sopenharmony_ci	.id_table	= cs42l43_codec_id_table,
227762306a36Sopenharmony_ci};
227862306a36Sopenharmony_cimodule_platform_driver(cs42l43_codec_driver);
227962306a36Sopenharmony_ci
228062306a36Sopenharmony_ciMODULE_IMPORT_NS(SND_SOC_CS42L43);
228162306a36Sopenharmony_ci
228262306a36Sopenharmony_ciMODULE_DESCRIPTION("CS42L43 CODEC Driver");
228362306a36Sopenharmony_ciMODULE_AUTHOR("Charles Keepax <ckeepax@opensource.cirrus.com>");
228462306a36Sopenharmony_ciMODULE_LICENSE("GPL");
2285