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