162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * da7218.c - DA7218 ALSA SoC Codec Driver 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2015 Dialog Semiconductor 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com> 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/clk.h> 1162306a36Sopenharmony_ci#include <linux/i2c.h> 1262306a36Sopenharmony_ci#include <linux/of_device.h> 1362306a36Sopenharmony_ci#include <linux/regmap.h> 1462306a36Sopenharmony_ci#include <linux/slab.h> 1562306a36Sopenharmony_ci#include <linux/pm.h> 1662306a36Sopenharmony_ci#include <linux/module.h> 1762306a36Sopenharmony_ci#include <linux/delay.h> 1862306a36Sopenharmony_ci#include <linux/regulator/consumer.h> 1962306a36Sopenharmony_ci#include <sound/pcm.h> 2062306a36Sopenharmony_ci#include <sound/pcm_params.h> 2162306a36Sopenharmony_ci#include <sound/soc.h> 2262306a36Sopenharmony_ci#include <sound/soc-dapm.h> 2362306a36Sopenharmony_ci#include <sound/jack.h> 2462306a36Sopenharmony_ci#include <sound/initval.h> 2562306a36Sopenharmony_ci#include <sound/tlv.h> 2662306a36Sopenharmony_ci#include <asm/div64.h> 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#include <sound/da7218.h> 2962306a36Sopenharmony_ci#include "da7218.h" 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci/* 3362306a36Sopenharmony_ci * TLVs and Enums 3462306a36Sopenharmony_ci */ 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci/* Input TLVs */ 3762306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(da7218_mic_gain_tlv, -600, 600, 0); 3862306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(da7218_mixin_gain_tlv, -450, 150, 0); 3962306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(da7218_in_dig_gain_tlv, -8325, 75, 0); 4062306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(da7218_ags_trigger_tlv, -9000, 600, 0); 4162306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(da7218_ags_att_max_tlv, 0, 600, 0); 4262306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(da7218_alc_threshold_tlv, -9450, 150, 0); 4362306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(da7218_alc_gain_tlv, 0, 600, 0); 4462306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(da7218_alc_ana_gain_tlv, 0, 600, 0); 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci/* Input/Output TLVs */ 4762306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(da7218_dmix_gain_tlv, -4200, 150, 0); 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci/* Output TLVs */ 5062306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(da7218_dgs_trigger_tlv, -9450, 150, 0); 5162306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(da7218_dgs_anticlip_tlv, -4200, 600, 0); 5262306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(da7218_dgs_signal_tlv, -9000, 600, 0); 5362306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(da7218_out_eq_band_tlv, -1050, 150, 0); 5462306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(da7218_out_dig_gain_tlv, -8325, 75, 0); 5562306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(da7218_dac_ng_threshold_tlv, -10200, 600, 0); 5662306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(da7218_mixout_gain_tlv, -100, 50, 0); 5762306a36Sopenharmony_cistatic const DECLARE_TLV_DB_SCALE(da7218_hp_gain_tlv, -5700, 150, 0); 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci/* Input Enums */ 6062306a36Sopenharmony_cistatic const char * const da7218_alc_attack_rate_txt[] = { 6162306a36Sopenharmony_ci "7.33/fs", "14.66/fs", "29.32/fs", "58.64/fs", "117.3/fs", "234.6/fs", 6262306a36Sopenharmony_ci "469.1/fs", "938.2/fs", "1876/fs", "3753/fs", "7506/fs", "15012/fs", 6362306a36Sopenharmony_ci "30024/fs", 6462306a36Sopenharmony_ci}; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_cistatic const struct soc_enum da7218_alc_attack_rate = 6762306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_ALC_CTRL2, DA7218_ALC_ATTACK_SHIFT, 6862306a36Sopenharmony_ci DA7218_ALC_ATTACK_MAX, da7218_alc_attack_rate_txt); 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_cistatic const char * const da7218_alc_release_rate_txt[] = { 7162306a36Sopenharmony_ci "28.66/fs", "57.33/fs", "114.6/fs", "229.3/fs", "458.6/fs", "917.1/fs", 7262306a36Sopenharmony_ci "1834/fs", "3668/fs", "7337/fs", "14674/fs", "29348/fs", 7362306a36Sopenharmony_ci}; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_cistatic const struct soc_enum da7218_alc_release_rate = 7662306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_ALC_CTRL2, DA7218_ALC_RELEASE_SHIFT, 7762306a36Sopenharmony_ci DA7218_ALC_RELEASE_MAX, da7218_alc_release_rate_txt); 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_cistatic const char * const da7218_alc_hold_time_txt[] = { 8062306a36Sopenharmony_ci "62/fs", "124/fs", "248/fs", "496/fs", "992/fs", "1984/fs", "3968/fs", 8162306a36Sopenharmony_ci "7936/fs", "15872/fs", "31744/fs", "63488/fs", "126976/fs", 8262306a36Sopenharmony_ci "253952/fs", "507904/fs", "1015808/fs", "2031616/fs" 8362306a36Sopenharmony_ci}; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_cistatic const struct soc_enum da7218_alc_hold_time = 8662306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_ALC_CTRL3, DA7218_ALC_HOLD_SHIFT, 8762306a36Sopenharmony_ci DA7218_ALC_HOLD_MAX, da7218_alc_hold_time_txt); 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_cistatic const char * const da7218_alc_anticlip_step_txt[] = { 9062306a36Sopenharmony_ci "0.034dB/fs", "0.068dB/fs", "0.136dB/fs", "0.272dB/fs", 9162306a36Sopenharmony_ci}; 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_cistatic const struct soc_enum da7218_alc_anticlip_step = 9462306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_ALC_ANTICLIP_CTRL, 9562306a36Sopenharmony_ci DA7218_ALC_ANTICLIP_STEP_SHIFT, 9662306a36Sopenharmony_ci DA7218_ALC_ANTICLIP_STEP_MAX, 9762306a36Sopenharmony_ci da7218_alc_anticlip_step_txt); 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_cistatic const char * const da7218_integ_rate_txt[] = { 10062306a36Sopenharmony_ci "1/4", "1/16", "1/256", "1/65536" 10162306a36Sopenharmony_ci}; 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_cistatic const struct soc_enum da7218_integ_attack_rate = 10462306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_ENV_TRACK_CTRL, DA7218_INTEG_ATTACK_SHIFT, 10562306a36Sopenharmony_ci DA7218_INTEG_MAX, da7218_integ_rate_txt); 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_cistatic const struct soc_enum da7218_integ_release_rate = 10862306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_ENV_TRACK_CTRL, DA7218_INTEG_RELEASE_SHIFT, 10962306a36Sopenharmony_ci DA7218_INTEG_MAX, da7218_integ_rate_txt); 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci/* Input/Output Enums */ 11262306a36Sopenharmony_cistatic const char * const da7218_gain_ramp_rate_txt[] = { 11362306a36Sopenharmony_ci "Nominal Rate * 8", "Nominal Rate", "Nominal Rate / 8", 11462306a36Sopenharmony_ci "Nominal Rate / 16", 11562306a36Sopenharmony_ci}; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_cistatic const struct soc_enum da7218_gain_ramp_rate = 11862306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_GAIN_RAMP_CTRL, DA7218_GAIN_RAMP_RATE_SHIFT, 11962306a36Sopenharmony_ci DA7218_GAIN_RAMP_RATE_MAX, da7218_gain_ramp_rate_txt); 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_cistatic const char * const da7218_hpf_mode_txt[] = { 12262306a36Sopenharmony_ci "Disabled", "Audio", "Voice", 12362306a36Sopenharmony_ci}; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_cistatic const unsigned int da7218_hpf_mode_val[] = { 12662306a36Sopenharmony_ci DA7218_HPF_DISABLED, DA7218_HPF_AUDIO_EN, DA7218_HPF_VOICE_EN, 12762306a36Sopenharmony_ci}; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_cistatic const struct soc_enum da7218_in1_hpf_mode = 13062306a36Sopenharmony_ci SOC_VALUE_ENUM_SINGLE(DA7218_IN_1_HPF_FILTER_CTRL, 13162306a36Sopenharmony_ci DA7218_HPF_MODE_SHIFT, DA7218_HPF_MODE_MASK, 13262306a36Sopenharmony_ci DA7218_HPF_MODE_MAX, da7218_hpf_mode_txt, 13362306a36Sopenharmony_ci da7218_hpf_mode_val); 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_cistatic const struct soc_enum da7218_in2_hpf_mode = 13662306a36Sopenharmony_ci SOC_VALUE_ENUM_SINGLE(DA7218_IN_2_HPF_FILTER_CTRL, 13762306a36Sopenharmony_ci DA7218_HPF_MODE_SHIFT, DA7218_HPF_MODE_MASK, 13862306a36Sopenharmony_ci DA7218_HPF_MODE_MAX, da7218_hpf_mode_txt, 13962306a36Sopenharmony_ci da7218_hpf_mode_val); 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_cistatic const struct soc_enum da7218_out1_hpf_mode = 14262306a36Sopenharmony_ci SOC_VALUE_ENUM_SINGLE(DA7218_OUT_1_HPF_FILTER_CTRL, 14362306a36Sopenharmony_ci DA7218_HPF_MODE_SHIFT, DA7218_HPF_MODE_MASK, 14462306a36Sopenharmony_ci DA7218_HPF_MODE_MAX, da7218_hpf_mode_txt, 14562306a36Sopenharmony_ci da7218_hpf_mode_val); 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_cistatic const char * const da7218_audio_hpf_corner_txt[] = { 14862306a36Sopenharmony_ci "2Hz", "4Hz", "8Hz", "16Hz", 14962306a36Sopenharmony_ci}; 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_cistatic const struct soc_enum da7218_in1_audio_hpf_corner = 15262306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_IN_1_HPF_FILTER_CTRL, 15362306a36Sopenharmony_ci DA7218_IN_1_AUDIO_HPF_CORNER_SHIFT, 15462306a36Sopenharmony_ci DA7218_AUDIO_HPF_CORNER_MAX, 15562306a36Sopenharmony_ci da7218_audio_hpf_corner_txt); 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_cistatic const struct soc_enum da7218_in2_audio_hpf_corner = 15862306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_IN_2_HPF_FILTER_CTRL, 15962306a36Sopenharmony_ci DA7218_IN_2_AUDIO_HPF_CORNER_SHIFT, 16062306a36Sopenharmony_ci DA7218_AUDIO_HPF_CORNER_MAX, 16162306a36Sopenharmony_ci da7218_audio_hpf_corner_txt); 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_cistatic const struct soc_enum da7218_out1_audio_hpf_corner = 16462306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_OUT_1_HPF_FILTER_CTRL, 16562306a36Sopenharmony_ci DA7218_OUT_1_AUDIO_HPF_CORNER_SHIFT, 16662306a36Sopenharmony_ci DA7218_AUDIO_HPF_CORNER_MAX, 16762306a36Sopenharmony_ci da7218_audio_hpf_corner_txt); 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_cistatic const char * const da7218_voice_hpf_corner_txt[] = { 17062306a36Sopenharmony_ci "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz", 17162306a36Sopenharmony_ci}; 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_cistatic const struct soc_enum da7218_in1_voice_hpf_corner = 17462306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_IN_1_HPF_FILTER_CTRL, 17562306a36Sopenharmony_ci DA7218_IN_1_VOICE_HPF_CORNER_SHIFT, 17662306a36Sopenharmony_ci DA7218_VOICE_HPF_CORNER_MAX, 17762306a36Sopenharmony_ci da7218_voice_hpf_corner_txt); 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_cistatic const struct soc_enum da7218_in2_voice_hpf_corner = 18062306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_IN_2_HPF_FILTER_CTRL, 18162306a36Sopenharmony_ci DA7218_IN_2_VOICE_HPF_CORNER_SHIFT, 18262306a36Sopenharmony_ci DA7218_VOICE_HPF_CORNER_MAX, 18362306a36Sopenharmony_ci da7218_voice_hpf_corner_txt); 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_cistatic const struct soc_enum da7218_out1_voice_hpf_corner = 18662306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_OUT_1_HPF_FILTER_CTRL, 18762306a36Sopenharmony_ci DA7218_OUT_1_VOICE_HPF_CORNER_SHIFT, 18862306a36Sopenharmony_ci DA7218_VOICE_HPF_CORNER_MAX, 18962306a36Sopenharmony_ci da7218_voice_hpf_corner_txt); 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_cistatic const char * const da7218_tonegen_dtmf_key_txt[] = { 19262306a36Sopenharmony_ci "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", 19362306a36Sopenharmony_ci "*", "#" 19462306a36Sopenharmony_ci}; 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_cistatic const struct soc_enum da7218_tonegen_dtmf_key = 19762306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_TONE_GEN_CFG1, DA7218_DTMF_REG_SHIFT, 19862306a36Sopenharmony_ci DA7218_DTMF_REG_MAX, da7218_tonegen_dtmf_key_txt); 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_cistatic const char * const da7218_tonegen_swg_sel_txt[] = { 20162306a36Sopenharmony_ci "Sum", "SWG1", "SWG2", "SWG1_1-Cos" 20262306a36Sopenharmony_ci}; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_cistatic const struct soc_enum da7218_tonegen_swg_sel = 20562306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_TONE_GEN_CFG2, DA7218_SWG_SEL_SHIFT, 20662306a36Sopenharmony_ci DA7218_SWG_SEL_MAX, da7218_tonegen_swg_sel_txt); 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci/* Output Enums */ 20962306a36Sopenharmony_cistatic const char * const da7218_dgs_rise_coeff_txt[] = { 21062306a36Sopenharmony_ci "1/1", "1/16", "1/64", "1/256", "1/1024", "1/4096", "1/16384", 21162306a36Sopenharmony_ci}; 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_cistatic const struct soc_enum da7218_dgs_rise_coeff = 21462306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_DGS_RISE_FALL, DA7218_DGS_RISE_COEFF_SHIFT, 21562306a36Sopenharmony_ci DA7218_DGS_RISE_COEFF_MAX, da7218_dgs_rise_coeff_txt); 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_cistatic const char * const da7218_dgs_fall_coeff_txt[] = { 21862306a36Sopenharmony_ci "1/4", "1/16", "1/64", "1/256", "1/1024", "1/4096", "1/16384", "1/65536", 21962306a36Sopenharmony_ci}; 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_cistatic const struct soc_enum da7218_dgs_fall_coeff = 22262306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_DGS_RISE_FALL, DA7218_DGS_FALL_COEFF_SHIFT, 22362306a36Sopenharmony_ci DA7218_DGS_FALL_COEFF_MAX, da7218_dgs_fall_coeff_txt); 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_cistatic const char * const da7218_dac_ng_setup_time_txt[] = { 22662306a36Sopenharmony_ci "256 Samples", "512 Samples", "1024 Samples", "2048 Samples" 22762306a36Sopenharmony_ci}; 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_cistatic const struct soc_enum da7218_dac_ng_setup_time = 23062306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_DAC_NG_SETUP_TIME, 23162306a36Sopenharmony_ci DA7218_DAC_NG_SETUP_TIME_SHIFT, 23262306a36Sopenharmony_ci DA7218_DAC_NG_SETUP_TIME_MAX, 23362306a36Sopenharmony_ci da7218_dac_ng_setup_time_txt); 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_cistatic const char * const da7218_dac_ng_rampup_txt[] = { 23662306a36Sopenharmony_ci "0.22ms/dB", "0.0138ms/dB" 23762306a36Sopenharmony_ci}; 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_cistatic const struct soc_enum da7218_dac_ng_rampup_rate = 24062306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_DAC_NG_SETUP_TIME, 24162306a36Sopenharmony_ci DA7218_DAC_NG_RAMPUP_RATE_SHIFT, 24262306a36Sopenharmony_ci DA7218_DAC_NG_RAMPUP_RATE_MAX, 24362306a36Sopenharmony_ci da7218_dac_ng_rampup_txt); 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_cistatic const char * const da7218_dac_ng_rampdown_txt[] = { 24662306a36Sopenharmony_ci "0.88ms/dB", "14.08ms/dB" 24762306a36Sopenharmony_ci}; 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_cistatic const struct soc_enum da7218_dac_ng_rampdown_rate = 25062306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_DAC_NG_SETUP_TIME, 25162306a36Sopenharmony_ci DA7218_DAC_NG_RAMPDN_RATE_SHIFT, 25262306a36Sopenharmony_ci DA7218_DAC_NG_RAMPDN_RATE_MAX, 25362306a36Sopenharmony_ci da7218_dac_ng_rampdown_txt); 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_cistatic const char * const da7218_cp_mchange_txt[] = { 25662306a36Sopenharmony_ci "Largest Volume", "DAC Volume", "Signal Magnitude" 25762306a36Sopenharmony_ci}; 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_cistatic const unsigned int da7218_cp_mchange_val[] = { 26062306a36Sopenharmony_ci DA7218_CP_MCHANGE_LARGEST_VOL, DA7218_CP_MCHANGE_DAC_VOL, 26162306a36Sopenharmony_ci DA7218_CP_MCHANGE_SIG_MAG 26262306a36Sopenharmony_ci}; 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_cistatic const struct soc_enum da7218_cp_mchange = 26562306a36Sopenharmony_ci SOC_VALUE_ENUM_SINGLE(DA7218_CP_CTRL, DA7218_CP_MCHANGE_SHIFT, 26662306a36Sopenharmony_ci DA7218_CP_MCHANGE_REL_MASK, DA7218_CP_MCHANGE_MAX, 26762306a36Sopenharmony_ci da7218_cp_mchange_txt, da7218_cp_mchange_val); 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_cistatic const char * const da7218_cp_fcontrol_txt[] = { 27062306a36Sopenharmony_ci "1MHz", "500KHz", "250KHz", "125KHz", "63KHz", "0KHz" 27162306a36Sopenharmony_ci}; 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_cistatic const struct soc_enum da7218_cp_fcontrol = 27462306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_CP_DELAY, DA7218_CP_FCONTROL_SHIFT, 27562306a36Sopenharmony_ci DA7218_CP_FCONTROL_MAX, da7218_cp_fcontrol_txt); 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_cistatic const char * const da7218_cp_tau_delay_txt[] = { 27862306a36Sopenharmony_ci "0ms", "2ms", "4ms", "16ms", "64ms", "128ms", "256ms", "512ms" 27962306a36Sopenharmony_ci}; 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_cistatic const struct soc_enum da7218_cp_tau_delay = 28262306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_CP_DELAY, DA7218_CP_TAU_DELAY_SHIFT, 28362306a36Sopenharmony_ci DA7218_CP_TAU_DELAY_MAX, da7218_cp_tau_delay_txt); 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci/* 28662306a36Sopenharmony_ci * Control Functions 28762306a36Sopenharmony_ci */ 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci/* ALC */ 29062306a36Sopenharmony_cistatic void da7218_alc_calib(struct snd_soc_component *component) 29162306a36Sopenharmony_ci{ 29262306a36Sopenharmony_ci u8 mic_1_ctrl, mic_2_ctrl; 29362306a36Sopenharmony_ci u8 mixin_1_ctrl, mixin_2_ctrl; 29462306a36Sopenharmony_ci u8 in_1l_filt_ctrl, in_1r_filt_ctrl, in_2l_filt_ctrl, in_2r_filt_ctrl; 29562306a36Sopenharmony_ci u8 in_1_hpf_ctrl, in_2_hpf_ctrl; 29662306a36Sopenharmony_ci u8 calib_ctrl; 29762306a36Sopenharmony_ci int i = 0; 29862306a36Sopenharmony_ci bool calibrated = false; 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci /* Save current state of MIC control registers */ 30162306a36Sopenharmony_ci mic_1_ctrl = snd_soc_component_read(component, DA7218_MIC_1_CTRL); 30262306a36Sopenharmony_ci mic_2_ctrl = snd_soc_component_read(component, DA7218_MIC_2_CTRL); 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci /* Save current state of input mixer control registers */ 30562306a36Sopenharmony_ci mixin_1_ctrl = snd_soc_component_read(component, DA7218_MIXIN_1_CTRL); 30662306a36Sopenharmony_ci mixin_2_ctrl = snd_soc_component_read(component, DA7218_MIXIN_2_CTRL); 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci /* Save current state of input filter control registers */ 30962306a36Sopenharmony_ci in_1l_filt_ctrl = snd_soc_component_read(component, DA7218_IN_1L_FILTER_CTRL); 31062306a36Sopenharmony_ci in_1r_filt_ctrl = snd_soc_component_read(component, DA7218_IN_1R_FILTER_CTRL); 31162306a36Sopenharmony_ci in_2l_filt_ctrl = snd_soc_component_read(component, DA7218_IN_2L_FILTER_CTRL); 31262306a36Sopenharmony_ci in_2r_filt_ctrl = snd_soc_component_read(component, DA7218_IN_2R_FILTER_CTRL); 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci /* Save current state of input HPF control registers */ 31562306a36Sopenharmony_ci in_1_hpf_ctrl = snd_soc_component_read(component, DA7218_IN_1_HPF_FILTER_CTRL); 31662306a36Sopenharmony_ci in_2_hpf_ctrl = snd_soc_component_read(component, DA7218_IN_2_HPF_FILTER_CTRL); 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci /* Enable then Mute MIC PGAs */ 31962306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_MIC_1_CTRL, DA7218_MIC_1_AMP_EN_MASK, 32062306a36Sopenharmony_ci DA7218_MIC_1_AMP_EN_MASK); 32162306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_MIC_2_CTRL, DA7218_MIC_2_AMP_EN_MASK, 32262306a36Sopenharmony_ci DA7218_MIC_2_AMP_EN_MASK); 32362306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_MIC_1_CTRL, 32462306a36Sopenharmony_ci DA7218_MIC_1_AMP_MUTE_EN_MASK, 32562306a36Sopenharmony_ci DA7218_MIC_1_AMP_MUTE_EN_MASK); 32662306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_MIC_2_CTRL, 32762306a36Sopenharmony_ci DA7218_MIC_2_AMP_MUTE_EN_MASK, 32862306a36Sopenharmony_ci DA7218_MIC_2_AMP_MUTE_EN_MASK); 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci /* Enable input mixers unmuted */ 33162306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_MIXIN_1_CTRL, 33262306a36Sopenharmony_ci DA7218_MIXIN_1_AMP_EN_MASK | 33362306a36Sopenharmony_ci DA7218_MIXIN_1_AMP_MUTE_EN_MASK, 33462306a36Sopenharmony_ci DA7218_MIXIN_1_AMP_EN_MASK); 33562306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_MIXIN_2_CTRL, 33662306a36Sopenharmony_ci DA7218_MIXIN_2_AMP_EN_MASK | 33762306a36Sopenharmony_ci DA7218_MIXIN_2_AMP_MUTE_EN_MASK, 33862306a36Sopenharmony_ci DA7218_MIXIN_2_AMP_EN_MASK); 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci /* Enable input filters unmuted */ 34162306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_IN_1L_FILTER_CTRL, 34262306a36Sopenharmony_ci DA7218_IN_1L_FILTER_EN_MASK | 34362306a36Sopenharmony_ci DA7218_IN_1L_MUTE_EN_MASK, 34462306a36Sopenharmony_ci DA7218_IN_1L_FILTER_EN_MASK); 34562306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_IN_1R_FILTER_CTRL, 34662306a36Sopenharmony_ci DA7218_IN_1R_FILTER_EN_MASK | 34762306a36Sopenharmony_ci DA7218_IN_1R_MUTE_EN_MASK, 34862306a36Sopenharmony_ci DA7218_IN_1R_FILTER_EN_MASK); 34962306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_IN_2L_FILTER_CTRL, 35062306a36Sopenharmony_ci DA7218_IN_2L_FILTER_EN_MASK | 35162306a36Sopenharmony_ci DA7218_IN_2L_MUTE_EN_MASK, 35262306a36Sopenharmony_ci DA7218_IN_2L_FILTER_EN_MASK); 35362306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_IN_2R_FILTER_CTRL, 35462306a36Sopenharmony_ci DA7218_IN_2R_FILTER_EN_MASK | 35562306a36Sopenharmony_ci DA7218_IN_2R_MUTE_EN_MASK, 35662306a36Sopenharmony_ci DA7218_IN_2R_FILTER_EN_MASK); 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci /* 35962306a36Sopenharmony_ci * Make sure input HPFs voice mode is disabled, otherwise for sampling 36062306a36Sopenharmony_ci * rates above 32KHz the ADC signals will be stopped and will cause 36162306a36Sopenharmony_ci * calibration to lock up. 36262306a36Sopenharmony_ci */ 36362306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_IN_1_HPF_FILTER_CTRL, 36462306a36Sopenharmony_ci DA7218_IN_1_VOICE_EN_MASK, 0); 36562306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_IN_2_HPF_FILTER_CTRL, 36662306a36Sopenharmony_ci DA7218_IN_2_VOICE_EN_MASK, 0); 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ci /* Perform auto calibration */ 36962306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_CALIB_CTRL, DA7218_CALIB_AUTO_EN_MASK, 37062306a36Sopenharmony_ci DA7218_CALIB_AUTO_EN_MASK); 37162306a36Sopenharmony_ci do { 37262306a36Sopenharmony_ci calib_ctrl = snd_soc_component_read(component, DA7218_CALIB_CTRL); 37362306a36Sopenharmony_ci if (calib_ctrl & DA7218_CALIB_AUTO_EN_MASK) { 37462306a36Sopenharmony_ci ++i; 37562306a36Sopenharmony_ci usleep_range(DA7218_ALC_CALIB_DELAY_MIN, 37662306a36Sopenharmony_ci DA7218_ALC_CALIB_DELAY_MAX); 37762306a36Sopenharmony_ci } else { 37862306a36Sopenharmony_ci calibrated = true; 37962306a36Sopenharmony_ci } 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci } while ((i < DA7218_ALC_CALIB_MAX_TRIES) && (!calibrated)); 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci /* If auto calibration fails, disable DC offset, hybrid ALC */ 38462306a36Sopenharmony_ci if ((!calibrated) || (calib_ctrl & DA7218_CALIB_OVERFLOW_MASK)) { 38562306a36Sopenharmony_ci dev_warn(component->dev, 38662306a36Sopenharmony_ci "ALC auto calibration failed - %s\n", 38762306a36Sopenharmony_ci (calibrated) ? "overflow" : "timeout"); 38862306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_CALIB_CTRL, 38962306a36Sopenharmony_ci DA7218_CALIB_OFFSET_EN_MASK, 0); 39062306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_ALC_CTRL1, 39162306a36Sopenharmony_ci DA7218_ALC_SYNC_MODE_MASK, 0); 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci } else { 39462306a36Sopenharmony_ci /* Enable DC offset cancellation */ 39562306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_CALIB_CTRL, 39662306a36Sopenharmony_ci DA7218_CALIB_OFFSET_EN_MASK, 39762306a36Sopenharmony_ci DA7218_CALIB_OFFSET_EN_MASK); 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_ci /* Enable ALC hybrid mode */ 40062306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_ALC_CTRL1, 40162306a36Sopenharmony_ci DA7218_ALC_SYNC_MODE_MASK, 40262306a36Sopenharmony_ci DA7218_ALC_SYNC_MODE_CH1 | 40362306a36Sopenharmony_ci DA7218_ALC_SYNC_MODE_CH2); 40462306a36Sopenharmony_ci } 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_ci /* Restore input HPF control registers to original states */ 40762306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_IN_1_HPF_FILTER_CTRL, in_1_hpf_ctrl); 40862306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_IN_2_HPF_FILTER_CTRL, in_2_hpf_ctrl); 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_ci /* Restore input filter control registers to original states */ 41162306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_IN_1L_FILTER_CTRL, in_1l_filt_ctrl); 41262306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_IN_1R_FILTER_CTRL, in_1r_filt_ctrl); 41362306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_IN_2L_FILTER_CTRL, in_2l_filt_ctrl); 41462306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_IN_2R_FILTER_CTRL, in_2r_filt_ctrl); 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_ci /* Restore input mixer control registers to original state */ 41762306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_MIXIN_1_CTRL, mixin_1_ctrl); 41862306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_MIXIN_2_CTRL, mixin_2_ctrl); 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ci /* Restore MIC control registers to original states */ 42162306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_MIC_1_CTRL, mic_1_ctrl); 42262306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_MIC_2_CTRL, mic_2_ctrl); 42362306a36Sopenharmony_ci} 42462306a36Sopenharmony_ci 42562306a36Sopenharmony_cistatic int da7218_mixin_gain_put(struct snd_kcontrol *kcontrol, 42662306a36Sopenharmony_ci struct snd_ctl_elem_value *ucontrol) 42762306a36Sopenharmony_ci{ 42862306a36Sopenharmony_ci struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 42962306a36Sopenharmony_ci struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component); 43062306a36Sopenharmony_ci int ret; 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_ci ret = snd_soc_put_volsw(kcontrol, ucontrol); 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_ci /* 43562306a36Sopenharmony_ci * If ALC in operation and value of control has been updated, 43662306a36Sopenharmony_ci * make sure calibrated offsets are updated. 43762306a36Sopenharmony_ci */ 43862306a36Sopenharmony_ci if ((ret == 1) && (da7218->alc_en)) 43962306a36Sopenharmony_ci da7218_alc_calib(component); 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci return ret; 44262306a36Sopenharmony_ci} 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_cistatic int da7218_alc_sw_put(struct snd_kcontrol *kcontrol, 44562306a36Sopenharmony_ci struct snd_ctl_elem_value *ucontrol) 44662306a36Sopenharmony_ci{ 44762306a36Sopenharmony_ci struct soc_mixer_control *mc = 44862306a36Sopenharmony_ci (struct soc_mixer_control *) kcontrol->private_value; 44962306a36Sopenharmony_ci struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 45062306a36Sopenharmony_ci struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component); 45162306a36Sopenharmony_ci unsigned int lvalue = ucontrol->value.integer.value[0]; 45262306a36Sopenharmony_ci unsigned int rvalue = ucontrol->value.integer.value[1]; 45362306a36Sopenharmony_ci unsigned int lshift = mc->shift; 45462306a36Sopenharmony_ci unsigned int rshift = mc->rshift; 45562306a36Sopenharmony_ci unsigned int mask = (mc->max << lshift) | (mc->max << rshift); 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_ci /* Force ALC offset calibration if enabling ALC */ 45862306a36Sopenharmony_ci if ((lvalue || rvalue) && (!da7218->alc_en)) 45962306a36Sopenharmony_ci da7218_alc_calib(component); 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci /* Update bits to detail which channels are enabled/disabled */ 46262306a36Sopenharmony_ci da7218->alc_en &= ~mask; 46362306a36Sopenharmony_ci da7218->alc_en |= (lvalue << lshift) | (rvalue << rshift); 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_ci return snd_soc_put_volsw(kcontrol, ucontrol); 46662306a36Sopenharmony_ci} 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_ci/* ToneGen */ 46962306a36Sopenharmony_cistatic int da7218_tonegen_freq_get(struct snd_kcontrol *kcontrol, 47062306a36Sopenharmony_ci struct snd_ctl_elem_value *ucontrol) 47162306a36Sopenharmony_ci{ 47262306a36Sopenharmony_ci struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 47362306a36Sopenharmony_ci struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component); 47462306a36Sopenharmony_ci struct soc_mixer_control *mixer_ctrl = 47562306a36Sopenharmony_ci (struct soc_mixer_control *) kcontrol->private_value; 47662306a36Sopenharmony_ci unsigned int reg = mixer_ctrl->reg; 47762306a36Sopenharmony_ci u16 val; 47862306a36Sopenharmony_ci int ret; 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_ci /* 48162306a36Sopenharmony_ci * Frequency value spans two 8-bit registers, lower then upper byte. 48262306a36Sopenharmony_ci * Therefore we need to convert to host endianness here. 48362306a36Sopenharmony_ci */ 48462306a36Sopenharmony_ci ret = regmap_raw_read(da7218->regmap, reg, &val, 2); 48562306a36Sopenharmony_ci if (ret) 48662306a36Sopenharmony_ci return ret; 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_ci ucontrol->value.integer.value[0] = le16_to_cpu(val); 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_ci return 0; 49162306a36Sopenharmony_ci} 49262306a36Sopenharmony_ci 49362306a36Sopenharmony_cistatic int da7218_tonegen_freq_put(struct snd_kcontrol *kcontrol, 49462306a36Sopenharmony_ci struct snd_ctl_elem_value *ucontrol) 49562306a36Sopenharmony_ci{ 49662306a36Sopenharmony_ci struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 49762306a36Sopenharmony_ci struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component); 49862306a36Sopenharmony_ci struct soc_mixer_control *mixer_ctrl = 49962306a36Sopenharmony_ci (struct soc_mixer_control *) kcontrol->private_value; 50062306a36Sopenharmony_ci unsigned int reg = mixer_ctrl->reg; 50162306a36Sopenharmony_ci u16 val; 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_ci /* 50462306a36Sopenharmony_ci * Frequency value spans two 8-bit registers, lower then upper byte. 50562306a36Sopenharmony_ci * Therefore we need to convert to little endian here to align with 50662306a36Sopenharmony_ci * HW registers. 50762306a36Sopenharmony_ci */ 50862306a36Sopenharmony_ci val = cpu_to_le16(ucontrol->value.integer.value[0]); 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_ci return regmap_raw_write(da7218->regmap, reg, &val, 2); 51162306a36Sopenharmony_ci} 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_cistatic int da7218_mic_lvl_det_sw_put(struct snd_kcontrol *kcontrol, 51462306a36Sopenharmony_ci struct snd_ctl_elem_value *ucontrol) 51562306a36Sopenharmony_ci{ 51662306a36Sopenharmony_ci struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 51762306a36Sopenharmony_ci struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component); 51862306a36Sopenharmony_ci struct soc_mixer_control *mixer_ctrl = 51962306a36Sopenharmony_ci (struct soc_mixer_control *) kcontrol->private_value; 52062306a36Sopenharmony_ci unsigned int lvalue = ucontrol->value.integer.value[0]; 52162306a36Sopenharmony_ci unsigned int rvalue = ucontrol->value.integer.value[1]; 52262306a36Sopenharmony_ci unsigned int lshift = mixer_ctrl->shift; 52362306a36Sopenharmony_ci unsigned int rshift = mixer_ctrl->rshift; 52462306a36Sopenharmony_ci unsigned int mask = (mixer_ctrl->max << lshift) | 52562306a36Sopenharmony_ci (mixer_ctrl->max << rshift); 52662306a36Sopenharmony_ci da7218->mic_lvl_det_en &= ~mask; 52762306a36Sopenharmony_ci da7218->mic_lvl_det_en |= (lvalue << lshift) | (rvalue << rshift); 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_ci /* 53062306a36Sopenharmony_ci * Here we only enable the feature on paths which are already 53162306a36Sopenharmony_ci * powered. If a channel is enabled here for level detect, but that path 53262306a36Sopenharmony_ci * isn't powered, then the channel will actually be enabled when we do 53362306a36Sopenharmony_ci * power the path (IN_FILTER widget events). This handling avoids 53462306a36Sopenharmony_ci * unwanted level detect events. 53562306a36Sopenharmony_ci */ 53662306a36Sopenharmony_ci return snd_soc_component_write(component, mixer_ctrl->reg, 53762306a36Sopenharmony_ci (da7218->in_filt_en & da7218->mic_lvl_det_en)); 53862306a36Sopenharmony_ci} 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_cistatic int da7218_mic_lvl_det_sw_get(struct snd_kcontrol *kcontrol, 54162306a36Sopenharmony_ci struct snd_ctl_elem_value *ucontrol) 54262306a36Sopenharmony_ci{ 54362306a36Sopenharmony_ci struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 54462306a36Sopenharmony_ci struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component); 54562306a36Sopenharmony_ci struct soc_mixer_control *mixer_ctrl = 54662306a36Sopenharmony_ci (struct soc_mixer_control *) kcontrol->private_value; 54762306a36Sopenharmony_ci unsigned int lshift = mixer_ctrl->shift; 54862306a36Sopenharmony_ci unsigned int rshift = mixer_ctrl->rshift; 54962306a36Sopenharmony_ci unsigned int lmask = (mixer_ctrl->max << lshift); 55062306a36Sopenharmony_ci unsigned int rmask = (mixer_ctrl->max << rshift); 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ci ucontrol->value.integer.value[0] = 55362306a36Sopenharmony_ci (da7218->mic_lvl_det_en & lmask) >> lshift; 55462306a36Sopenharmony_ci ucontrol->value.integer.value[1] = 55562306a36Sopenharmony_ci (da7218->mic_lvl_det_en & rmask) >> rshift; 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_ci return 0; 55862306a36Sopenharmony_ci} 55962306a36Sopenharmony_ci 56062306a36Sopenharmony_cistatic int da7218_biquad_coeff_get(struct snd_kcontrol *kcontrol, 56162306a36Sopenharmony_ci struct snd_ctl_elem_value *ucontrol) 56262306a36Sopenharmony_ci{ 56362306a36Sopenharmony_ci struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 56462306a36Sopenharmony_ci struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component); 56562306a36Sopenharmony_ci struct soc_bytes_ext *bytes_ext = 56662306a36Sopenharmony_ci (struct soc_bytes_ext *) kcontrol->private_value; 56762306a36Sopenharmony_ci 56862306a36Sopenharmony_ci /* Determine which BiQuads we're setting based on size of config data */ 56962306a36Sopenharmony_ci switch (bytes_ext->max) { 57062306a36Sopenharmony_ci case DA7218_OUT_1_BIQ_5STAGE_CFG_SIZE: 57162306a36Sopenharmony_ci memcpy(ucontrol->value.bytes.data, da7218->biq_5stage_coeff, 57262306a36Sopenharmony_ci bytes_ext->max); 57362306a36Sopenharmony_ci break; 57462306a36Sopenharmony_ci case DA7218_SIDETONE_BIQ_3STAGE_CFG_SIZE: 57562306a36Sopenharmony_ci memcpy(ucontrol->value.bytes.data, da7218->stbiq_3stage_coeff, 57662306a36Sopenharmony_ci bytes_ext->max); 57762306a36Sopenharmony_ci break; 57862306a36Sopenharmony_ci default: 57962306a36Sopenharmony_ci return -EINVAL; 58062306a36Sopenharmony_ci } 58162306a36Sopenharmony_ci 58262306a36Sopenharmony_ci return 0; 58362306a36Sopenharmony_ci} 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_cistatic int da7218_biquad_coeff_put(struct snd_kcontrol *kcontrol, 58662306a36Sopenharmony_ci struct snd_ctl_elem_value *ucontrol) 58762306a36Sopenharmony_ci{ 58862306a36Sopenharmony_ci struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 58962306a36Sopenharmony_ci struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component); 59062306a36Sopenharmony_ci struct soc_bytes_ext *bytes_ext = 59162306a36Sopenharmony_ci (struct soc_bytes_ext *) kcontrol->private_value; 59262306a36Sopenharmony_ci u8 reg, out_filt1l; 59362306a36Sopenharmony_ci u8 cfg[DA7218_BIQ_CFG_SIZE]; 59462306a36Sopenharmony_ci int i; 59562306a36Sopenharmony_ci 59662306a36Sopenharmony_ci /* 59762306a36Sopenharmony_ci * Determine which BiQuads we're setting based on size of config data, 59862306a36Sopenharmony_ci * and stored the data for use by get function. 59962306a36Sopenharmony_ci */ 60062306a36Sopenharmony_ci switch (bytes_ext->max) { 60162306a36Sopenharmony_ci case DA7218_OUT_1_BIQ_5STAGE_CFG_SIZE: 60262306a36Sopenharmony_ci reg = DA7218_OUT_1_BIQ_5STAGE_DATA; 60362306a36Sopenharmony_ci memcpy(da7218->biq_5stage_coeff, ucontrol->value.bytes.data, 60462306a36Sopenharmony_ci bytes_ext->max); 60562306a36Sopenharmony_ci break; 60662306a36Sopenharmony_ci case DA7218_SIDETONE_BIQ_3STAGE_CFG_SIZE: 60762306a36Sopenharmony_ci reg = DA7218_SIDETONE_BIQ_3STAGE_DATA; 60862306a36Sopenharmony_ci memcpy(da7218->stbiq_3stage_coeff, ucontrol->value.bytes.data, 60962306a36Sopenharmony_ci bytes_ext->max); 61062306a36Sopenharmony_ci break; 61162306a36Sopenharmony_ci default: 61262306a36Sopenharmony_ci return -EINVAL; 61362306a36Sopenharmony_ci } 61462306a36Sopenharmony_ci 61562306a36Sopenharmony_ci /* Make sure at least out filter1 enabled to allow programming */ 61662306a36Sopenharmony_ci out_filt1l = snd_soc_component_read(component, DA7218_OUT_1L_FILTER_CTRL); 61762306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_OUT_1L_FILTER_CTRL, 61862306a36Sopenharmony_ci out_filt1l | DA7218_OUT_1L_FILTER_EN_MASK); 61962306a36Sopenharmony_ci 62062306a36Sopenharmony_ci for (i = 0; i < bytes_ext->max; ++i) { 62162306a36Sopenharmony_ci cfg[DA7218_BIQ_CFG_DATA] = ucontrol->value.bytes.data[i]; 62262306a36Sopenharmony_ci cfg[DA7218_BIQ_CFG_ADDR] = i; 62362306a36Sopenharmony_ci regmap_raw_write(da7218->regmap, reg, cfg, DA7218_BIQ_CFG_SIZE); 62462306a36Sopenharmony_ci } 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_ci /* Restore filter to previous setting */ 62762306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_OUT_1L_FILTER_CTRL, out_filt1l); 62862306a36Sopenharmony_ci 62962306a36Sopenharmony_ci return 0; 63062306a36Sopenharmony_ci} 63162306a36Sopenharmony_ci 63262306a36Sopenharmony_ci 63362306a36Sopenharmony_ci/* 63462306a36Sopenharmony_ci * KControls 63562306a36Sopenharmony_ci */ 63662306a36Sopenharmony_ci 63762306a36Sopenharmony_cistatic const struct snd_kcontrol_new da7218_snd_controls[] = { 63862306a36Sopenharmony_ci /* Mics */ 63962306a36Sopenharmony_ci SOC_SINGLE_TLV("Mic1 Volume", DA7218_MIC_1_GAIN, 64062306a36Sopenharmony_ci DA7218_MIC_1_AMP_GAIN_SHIFT, DA7218_MIC_AMP_GAIN_MAX, 64162306a36Sopenharmony_ci DA7218_NO_INVERT, da7218_mic_gain_tlv), 64262306a36Sopenharmony_ci SOC_SINGLE("Mic1 Switch", DA7218_MIC_1_CTRL, 64362306a36Sopenharmony_ci DA7218_MIC_1_AMP_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX, 64462306a36Sopenharmony_ci DA7218_INVERT), 64562306a36Sopenharmony_ci SOC_SINGLE_TLV("Mic2 Volume", DA7218_MIC_2_GAIN, 64662306a36Sopenharmony_ci DA7218_MIC_2_AMP_GAIN_SHIFT, DA7218_MIC_AMP_GAIN_MAX, 64762306a36Sopenharmony_ci DA7218_NO_INVERT, da7218_mic_gain_tlv), 64862306a36Sopenharmony_ci SOC_SINGLE("Mic2 Switch", DA7218_MIC_2_CTRL, 64962306a36Sopenharmony_ci DA7218_MIC_2_AMP_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX, 65062306a36Sopenharmony_ci DA7218_INVERT), 65162306a36Sopenharmony_ci 65262306a36Sopenharmony_ci /* Mixer Input */ 65362306a36Sopenharmony_ci SOC_SINGLE_EXT_TLV("Mixin1 Volume", DA7218_MIXIN_1_GAIN, 65462306a36Sopenharmony_ci DA7218_MIXIN_1_AMP_GAIN_SHIFT, 65562306a36Sopenharmony_ci DA7218_MIXIN_AMP_GAIN_MAX, DA7218_NO_INVERT, 65662306a36Sopenharmony_ci snd_soc_get_volsw, da7218_mixin_gain_put, 65762306a36Sopenharmony_ci da7218_mixin_gain_tlv), 65862306a36Sopenharmony_ci SOC_SINGLE("Mixin1 Switch", DA7218_MIXIN_1_CTRL, 65962306a36Sopenharmony_ci DA7218_MIXIN_1_AMP_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX, 66062306a36Sopenharmony_ci DA7218_INVERT), 66162306a36Sopenharmony_ci SOC_SINGLE("Mixin1 Gain Ramp Switch", DA7218_MIXIN_1_CTRL, 66262306a36Sopenharmony_ci DA7218_MIXIN_1_AMP_RAMP_EN_SHIFT, DA7218_SWITCH_EN_MAX, 66362306a36Sopenharmony_ci DA7218_NO_INVERT), 66462306a36Sopenharmony_ci SOC_SINGLE("Mixin1 ZC Gain Switch", DA7218_MIXIN_1_CTRL, 66562306a36Sopenharmony_ci DA7218_MIXIN_1_AMP_ZC_EN_SHIFT, DA7218_SWITCH_EN_MAX, 66662306a36Sopenharmony_ci DA7218_NO_INVERT), 66762306a36Sopenharmony_ci SOC_SINGLE_EXT_TLV("Mixin2 Volume", DA7218_MIXIN_2_GAIN, 66862306a36Sopenharmony_ci DA7218_MIXIN_2_AMP_GAIN_SHIFT, 66962306a36Sopenharmony_ci DA7218_MIXIN_AMP_GAIN_MAX, DA7218_NO_INVERT, 67062306a36Sopenharmony_ci snd_soc_get_volsw, da7218_mixin_gain_put, 67162306a36Sopenharmony_ci da7218_mixin_gain_tlv), 67262306a36Sopenharmony_ci SOC_SINGLE("Mixin2 Switch", DA7218_MIXIN_2_CTRL, 67362306a36Sopenharmony_ci DA7218_MIXIN_2_AMP_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX, 67462306a36Sopenharmony_ci DA7218_INVERT), 67562306a36Sopenharmony_ci SOC_SINGLE("Mixin2 Gain Ramp Switch", DA7218_MIXIN_2_CTRL, 67662306a36Sopenharmony_ci DA7218_MIXIN_2_AMP_RAMP_EN_SHIFT, DA7218_SWITCH_EN_MAX, 67762306a36Sopenharmony_ci DA7218_NO_INVERT), 67862306a36Sopenharmony_ci SOC_SINGLE("Mixin2 ZC Gain Switch", DA7218_MIXIN_2_CTRL, 67962306a36Sopenharmony_ci DA7218_MIXIN_2_AMP_ZC_EN_SHIFT, DA7218_SWITCH_EN_MAX, 68062306a36Sopenharmony_ci DA7218_NO_INVERT), 68162306a36Sopenharmony_ci 68262306a36Sopenharmony_ci /* ADCs */ 68362306a36Sopenharmony_ci SOC_SINGLE("ADC1 AAF Switch", DA7218_ADC_1_CTRL, 68462306a36Sopenharmony_ci DA7218_ADC_1_AAF_EN_SHIFT, DA7218_SWITCH_EN_MAX, 68562306a36Sopenharmony_ci DA7218_NO_INVERT), 68662306a36Sopenharmony_ci SOC_SINGLE("ADC2 AAF Switch", DA7218_ADC_2_CTRL, 68762306a36Sopenharmony_ci DA7218_ADC_2_AAF_EN_SHIFT, DA7218_SWITCH_EN_MAX, 68862306a36Sopenharmony_ci DA7218_NO_INVERT), 68962306a36Sopenharmony_ci SOC_SINGLE("ADC LP Mode Switch", DA7218_ADC_MODE, 69062306a36Sopenharmony_ci DA7218_ADC_LP_MODE_SHIFT, DA7218_SWITCH_EN_MAX, 69162306a36Sopenharmony_ci DA7218_NO_INVERT), 69262306a36Sopenharmony_ci 69362306a36Sopenharmony_ci /* Input Filters */ 69462306a36Sopenharmony_ci SOC_SINGLE_TLV("In Filter1L Volume", DA7218_IN_1L_GAIN, 69562306a36Sopenharmony_ci DA7218_IN_1L_DIGITAL_GAIN_SHIFT, 69662306a36Sopenharmony_ci DA7218_IN_DIGITAL_GAIN_MAX, DA7218_NO_INVERT, 69762306a36Sopenharmony_ci da7218_in_dig_gain_tlv), 69862306a36Sopenharmony_ci SOC_SINGLE("In Filter1L Switch", DA7218_IN_1L_FILTER_CTRL, 69962306a36Sopenharmony_ci DA7218_IN_1L_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX, 70062306a36Sopenharmony_ci DA7218_INVERT), 70162306a36Sopenharmony_ci SOC_SINGLE("In Filter1L Gain Ramp Switch", DA7218_IN_1L_FILTER_CTRL, 70262306a36Sopenharmony_ci DA7218_IN_1L_RAMP_EN_SHIFT, DA7218_SWITCH_EN_MAX, 70362306a36Sopenharmony_ci DA7218_NO_INVERT), 70462306a36Sopenharmony_ci SOC_SINGLE_TLV("In Filter1R Volume", DA7218_IN_1R_GAIN, 70562306a36Sopenharmony_ci DA7218_IN_1R_DIGITAL_GAIN_SHIFT, 70662306a36Sopenharmony_ci DA7218_IN_DIGITAL_GAIN_MAX, DA7218_NO_INVERT, 70762306a36Sopenharmony_ci da7218_in_dig_gain_tlv), 70862306a36Sopenharmony_ci SOC_SINGLE("In Filter1R Switch", DA7218_IN_1R_FILTER_CTRL, 70962306a36Sopenharmony_ci DA7218_IN_1R_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX, 71062306a36Sopenharmony_ci DA7218_INVERT), 71162306a36Sopenharmony_ci SOC_SINGLE("In Filter1R Gain Ramp Switch", 71262306a36Sopenharmony_ci DA7218_IN_1R_FILTER_CTRL, DA7218_IN_1R_RAMP_EN_SHIFT, 71362306a36Sopenharmony_ci DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), 71462306a36Sopenharmony_ci SOC_SINGLE_TLV("In Filter2L Volume", DA7218_IN_2L_GAIN, 71562306a36Sopenharmony_ci DA7218_IN_2L_DIGITAL_GAIN_SHIFT, 71662306a36Sopenharmony_ci DA7218_IN_DIGITAL_GAIN_MAX, DA7218_NO_INVERT, 71762306a36Sopenharmony_ci da7218_in_dig_gain_tlv), 71862306a36Sopenharmony_ci SOC_SINGLE("In Filter2L Switch", DA7218_IN_2L_FILTER_CTRL, 71962306a36Sopenharmony_ci DA7218_IN_2L_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX, 72062306a36Sopenharmony_ci DA7218_INVERT), 72162306a36Sopenharmony_ci SOC_SINGLE("In Filter2L Gain Ramp Switch", DA7218_IN_2L_FILTER_CTRL, 72262306a36Sopenharmony_ci DA7218_IN_2L_RAMP_EN_SHIFT, DA7218_SWITCH_EN_MAX, 72362306a36Sopenharmony_ci DA7218_NO_INVERT), 72462306a36Sopenharmony_ci SOC_SINGLE_TLV("In Filter2R Volume", DA7218_IN_2R_GAIN, 72562306a36Sopenharmony_ci DA7218_IN_2R_DIGITAL_GAIN_SHIFT, 72662306a36Sopenharmony_ci DA7218_IN_DIGITAL_GAIN_MAX, DA7218_NO_INVERT, 72762306a36Sopenharmony_ci da7218_in_dig_gain_tlv), 72862306a36Sopenharmony_ci SOC_SINGLE("In Filter2R Switch", DA7218_IN_2R_FILTER_CTRL, 72962306a36Sopenharmony_ci DA7218_IN_2R_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX, 73062306a36Sopenharmony_ci DA7218_INVERT), 73162306a36Sopenharmony_ci SOC_SINGLE("In Filter2R Gain Ramp Switch", 73262306a36Sopenharmony_ci DA7218_IN_2R_FILTER_CTRL, DA7218_IN_2R_RAMP_EN_SHIFT, 73362306a36Sopenharmony_ci DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), 73462306a36Sopenharmony_ci 73562306a36Sopenharmony_ci /* AGS */ 73662306a36Sopenharmony_ci SOC_SINGLE_TLV("AGS Trigger", DA7218_AGS_TRIGGER, 73762306a36Sopenharmony_ci DA7218_AGS_TRIGGER_SHIFT, DA7218_AGS_TRIGGER_MAX, 73862306a36Sopenharmony_ci DA7218_INVERT, da7218_ags_trigger_tlv), 73962306a36Sopenharmony_ci SOC_SINGLE_TLV("AGS Max Attenuation", DA7218_AGS_ATT_MAX, 74062306a36Sopenharmony_ci DA7218_AGS_ATT_MAX_SHIFT, DA7218_AGS_ATT_MAX_MAX, 74162306a36Sopenharmony_ci DA7218_NO_INVERT, da7218_ags_att_max_tlv), 74262306a36Sopenharmony_ci SOC_SINGLE("AGS Anticlip Switch", DA7218_AGS_ANTICLIP_CTRL, 74362306a36Sopenharmony_ci DA7218_AGS_ANTICLIP_EN_SHIFT, DA7218_SWITCH_EN_MAX, 74462306a36Sopenharmony_ci DA7218_NO_INVERT), 74562306a36Sopenharmony_ci SOC_SINGLE("AGS Channel1 Switch", DA7218_AGS_ENABLE, 74662306a36Sopenharmony_ci DA7218_AGS_ENABLE_CHAN1_SHIFT, DA7218_SWITCH_EN_MAX, 74762306a36Sopenharmony_ci DA7218_NO_INVERT), 74862306a36Sopenharmony_ci SOC_SINGLE("AGS Channel2 Switch", DA7218_AGS_ENABLE, 74962306a36Sopenharmony_ci DA7218_AGS_ENABLE_CHAN2_SHIFT, DA7218_SWITCH_EN_MAX, 75062306a36Sopenharmony_ci DA7218_NO_INVERT), 75162306a36Sopenharmony_ci 75262306a36Sopenharmony_ci /* ALC */ 75362306a36Sopenharmony_ci SOC_ENUM("ALC Attack Rate", da7218_alc_attack_rate), 75462306a36Sopenharmony_ci SOC_ENUM("ALC Release Rate", da7218_alc_release_rate), 75562306a36Sopenharmony_ci SOC_ENUM("ALC Hold Time", da7218_alc_hold_time), 75662306a36Sopenharmony_ci SOC_SINGLE_TLV("ALC Noise Threshold", DA7218_ALC_NOISE, 75762306a36Sopenharmony_ci DA7218_ALC_NOISE_SHIFT, DA7218_ALC_THRESHOLD_MAX, 75862306a36Sopenharmony_ci DA7218_INVERT, da7218_alc_threshold_tlv), 75962306a36Sopenharmony_ci SOC_SINGLE_TLV("ALC Min Threshold", DA7218_ALC_TARGET_MIN, 76062306a36Sopenharmony_ci DA7218_ALC_THRESHOLD_MIN_SHIFT, DA7218_ALC_THRESHOLD_MAX, 76162306a36Sopenharmony_ci DA7218_INVERT, da7218_alc_threshold_tlv), 76262306a36Sopenharmony_ci SOC_SINGLE_TLV("ALC Max Threshold", DA7218_ALC_TARGET_MAX, 76362306a36Sopenharmony_ci DA7218_ALC_THRESHOLD_MAX_SHIFT, DA7218_ALC_THRESHOLD_MAX, 76462306a36Sopenharmony_ci DA7218_INVERT, da7218_alc_threshold_tlv), 76562306a36Sopenharmony_ci SOC_SINGLE_TLV("ALC Max Attenuation", DA7218_ALC_GAIN_LIMITS, 76662306a36Sopenharmony_ci DA7218_ALC_ATTEN_MAX_SHIFT, DA7218_ALC_ATTEN_GAIN_MAX, 76762306a36Sopenharmony_ci DA7218_NO_INVERT, da7218_alc_gain_tlv), 76862306a36Sopenharmony_ci SOC_SINGLE_TLV("ALC Max Gain", DA7218_ALC_GAIN_LIMITS, 76962306a36Sopenharmony_ci DA7218_ALC_GAIN_MAX_SHIFT, DA7218_ALC_ATTEN_GAIN_MAX, 77062306a36Sopenharmony_ci DA7218_NO_INVERT, da7218_alc_gain_tlv), 77162306a36Sopenharmony_ci SOC_SINGLE_RANGE_TLV("ALC Min Analog Gain", DA7218_ALC_ANA_GAIN_LIMITS, 77262306a36Sopenharmony_ci DA7218_ALC_ANA_GAIN_MIN_SHIFT, 77362306a36Sopenharmony_ci DA7218_ALC_ANA_GAIN_MIN, DA7218_ALC_ANA_GAIN_MAX, 77462306a36Sopenharmony_ci DA7218_NO_INVERT, da7218_alc_ana_gain_tlv), 77562306a36Sopenharmony_ci SOC_SINGLE_RANGE_TLV("ALC Max Analog Gain", DA7218_ALC_ANA_GAIN_LIMITS, 77662306a36Sopenharmony_ci DA7218_ALC_ANA_GAIN_MAX_SHIFT, 77762306a36Sopenharmony_ci DA7218_ALC_ANA_GAIN_MIN, DA7218_ALC_ANA_GAIN_MAX, 77862306a36Sopenharmony_ci DA7218_NO_INVERT, da7218_alc_ana_gain_tlv), 77962306a36Sopenharmony_ci SOC_ENUM("ALC Anticlip Step", da7218_alc_anticlip_step), 78062306a36Sopenharmony_ci SOC_SINGLE("ALC Anticlip Switch", DA7218_ALC_ANTICLIP_CTRL, 78162306a36Sopenharmony_ci DA7218_ALC_ANTICLIP_EN_SHIFT, DA7218_SWITCH_EN_MAX, 78262306a36Sopenharmony_ci DA7218_NO_INVERT), 78362306a36Sopenharmony_ci SOC_DOUBLE_EXT("ALC Channel1 Switch", DA7218_ALC_CTRL1, 78462306a36Sopenharmony_ci DA7218_ALC_CHAN1_L_EN_SHIFT, DA7218_ALC_CHAN1_R_EN_SHIFT, 78562306a36Sopenharmony_ci DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT, 78662306a36Sopenharmony_ci snd_soc_get_volsw, da7218_alc_sw_put), 78762306a36Sopenharmony_ci SOC_DOUBLE_EXT("ALC Channel2 Switch", DA7218_ALC_CTRL1, 78862306a36Sopenharmony_ci DA7218_ALC_CHAN2_L_EN_SHIFT, DA7218_ALC_CHAN2_R_EN_SHIFT, 78962306a36Sopenharmony_ci DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT, 79062306a36Sopenharmony_ci snd_soc_get_volsw, da7218_alc_sw_put), 79162306a36Sopenharmony_ci 79262306a36Sopenharmony_ci /* Envelope Tracking */ 79362306a36Sopenharmony_ci SOC_ENUM("Envelope Tracking Attack Rate", da7218_integ_attack_rate), 79462306a36Sopenharmony_ci SOC_ENUM("Envelope Tracking Release Rate", da7218_integ_release_rate), 79562306a36Sopenharmony_ci 79662306a36Sopenharmony_ci /* Input High-Pass Filters */ 79762306a36Sopenharmony_ci SOC_ENUM("In Filter1 HPF Mode", da7218_in1_hpf_mode), 79862306a36Sopenharmony_ci SOC_ENUM("In Filter1 HPF Corner Audio", da7218_in1_audio_hpf_corner), 79962306a36Sopenharmony_ci SOC_ENUM("In Filter1 HPF Corner Voice", da7218_in1_voice_hpf_corner), 80062306a36Sopenharmony_ci SOC_ENUM("In Filter2 HPF Mode", da7218_in2_hpf_mode), 80162306a36Sopenharmony_ci SOC_ENUM("In Filter2 HPF Corner Audio", da7218_in2_audio_hpf_corner), 80262306a36Sopenharmony_ci SOC_ENUM("In Filter2 HPF Corner Voice", da7218_in2_voice_hpf_corner), 80362306a36Sopenharmony_ci 80462306a36Sopenharmony_ci /* Mic Level Detect */ 80562306a36Sopenharmony_ci SOC_DOUBLE_EXT("Mic Level Detect Channel1 Switch", DA7218_LVL_DET_CTRL, 80662306a36Sopenharmony_ci DA7218_LVL_DET_EN_CHAN1L_SHIFT, 80762306a36Sopenharmony_ci DA7218_LVL_DET_EN_CHAN1R_SHIFT, DA7218_SWITCH_EN_MAX, 80862306a36Sopenharmony_ci DA7218_NO_INVERT, da7218_mic_lvl_det_sw_get, 80962306a36Sopenharmony_ci da7218_mic_lvl_det_sw_put), 81062306a36Sopenharmony_ci SOC_DOUBLE_EXT("Mic Level Detect Channel2 Switch", DA7218_LVL_DET_CTRL, 81162306a36Sopenharmony_ci DA7218_LVL_DET_EN_CHAN2L_SHIFT, 81262306a36Sopenharmony_ci DA7218_LVL_DET_EN_CHAN2R_SHIFT, DA7218_SWITCH_EN_MAX, 81362306a36Sopenharmony_ci DA7218_NO_INVERT, da7218_mic_lvl_det_sw_get, 81462306a36Sopenharmony_ci da7218_mic_lvl_det_sw_put), 81562306a36Sopenharmony_ci SOC_SINGLE("Mic Level Detect Level", DA7218_LVL_DET_LEVEL, 81662306a36Sopenharmony_ci DA7218_LVL_DET_LEVEL_SHIFT, DA7218_LVL_DET_LEVEL_MAX, 81762306a36Sopenharmony_ci DA7218_NO_INVERT), 81862306a36Sopenharmony_ci 81962306a36Sopenharmony_ci /* Digital Mixer (Input) */ 82062306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In Filter1L Out1 DAIL Volume", 82162306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_1L_INFILT_1L_GAIN, 82262306a36Sopenharmony_ci DA7218_OUTDAI_1L_INFILT_1L_GAIN_SHIFT, 82362306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 82462306a36Sopenharmony_ci da7218_dmix_gain_tlv), 82562306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In Filter1L Out1 DAIR Volume", 82662306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_1R_INFILT_1L_GAIN, 82762306a36Sopenharmony_ci DA7218_OUTDAI_1R_INFILT_1L_GAIN_SHIFT, 82862306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 82962306a36Sopenharmony_ci da7218_dmix_gain_tlv), 83062306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In Filter1L Out2 DAIL Volume", 83162306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_2L_INFILT_1L_GAIN, 83262306a36Sopenharmony_ci DA7218_OUTDAI_2L_INFILT_1L_GAIN_SHIFT, 83362306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 83462306a36Sopenharmony_ci da7218_dmix_gain_tlv), 83562306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In Filter1L Out2 DAIR Volume", 83662306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_2R_INFILT_1L_GAIN, 83762306a36Sopenharmony_ci DA7218_OUTDAI_2R_INFILT_1L_GAIN_SHIFT, 83862306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 83962306a36Sopenharmony_ci da7218_dmix_gain_tlv), 84062306a36Sopenharmony_ci 84162306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In Filter1R Out1 DAIL Volume", 84262306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_1L_INFILT_1R_GAIN, 84362306a36Sopenharmony_ci DA7218_OUTDAI_1L_INFILT_1R_GAIN_SHIFT, 84462306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 84562306a36Sopenharmony_ci da7218_dmix_gain_tlv), 84662306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In Filter1R Out1 DAIR Volume", 84762306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_1R_INFILT_1R_GAIN, 84862306a36Sopenharmony_ci DA7218_OUTDAI_1R_INFILT_1R_GAIN_SHIFT, 84962306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 85062306a36Sopenharmony_ci da7218_dmix_gain_tlv), 85162306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In Filter1R Out2 DAIL Volume", 85262306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_2L_INFILT_1R_GAIN, 85362306a36Sopenharmony_ci DA7218_OUTDAI_2L_INFILT_1R_GAIN_SHIFT, 85462306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 85562306a36Sopenharmony_ci da7218_dmix_gain_tlv), 85662306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In Filter1R Out2 DAIR Volume", 85762306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_2R_INFILT_1R_GAIN, 85862306a36Sopenharmony_ci DA7218_OUTDAI_2R_INFILT_1R_GAIN_SHIFT, 85962306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 86062306a36Sopenharmony_ci da7218_dmix_gain_tlv), 86162306a36Sopenharmony_ci 86262306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In Filter2L Out1 DAIL Volume", 86362306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_1L_INFILT_2L_GAIN, 86462306a36Sopenharmony_ci DA7218_OUTDAI_1L_INFILT_2L_GAIN_SHIFT, 86562306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 86662306a36Sopenharmony_ci da7218_dmix_gain_tlv), 86762306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In Filter2L Out1 DAIR Volume", 86862306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_1R_INFILT_2L_GAIN, 86962306a36Sopenharmony_ci DA7218_OUTDAI_1R_INFILT_2L_GAIN_SHIFT, 87062306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 87162306a36Sopenharmony_ci da7218_dmix_gain_tlv), 87262306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In Filter2L Out2 DAIL Volume", 87362306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_2L_INFILT_2L_GAIN, 87462306a36Sopenharmony_ci DA7218_OUTDAI_2L_INFILT_2L_GAIN_SHIFT, 87562306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 87662306a36Sopenharmony_ci da7218_dmix_gain_tlv), 87762306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In Filter2L Out2 DAIR Volume", 87862306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_2R_INFILT_2L_GAIN, 87962306a36Sopenharmony_ci DA7218_OUTDAI_2R_INFILT_2L_GAIN_SHIFT, 88062306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 88162306a36Sopenharmony_ci da7218_dmix_gain_tlv), 88262306a36Sopenharmony_ci 88362306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In Filter2R Out1 DAIL Volume", 88462306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_1L_INFILT_2R_GAIN, 88562306a36Sopenharmony_ci DA7218_OUTDAI_1L_INFILT_2R_GAIN_SHIFT, 88662306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 88762306a36Sopenharmony_ci da7218_dmix_gain_tlv), 88862306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In Filter2R Out1 DAIR Volume", 88962306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_1R_INFILT_2R_GAIN, 89062306a36Sopenharmony_ci DA7218_OUTDAI_1R_INFILT_2R_GAIN_SHIFT, 89162306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 89262306a36Sopenharmony_ci da7218_dmix_gain_tlv), 89362306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In Filter2R Out2 DAIL Volume", 89462306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_2L_INFILT_2R_GAIN, 89562306a36Sopenharmony_ci DA7218_OUTDAI_2L_INFILT_2R_GAIN_SHIFT, 89662306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 89762306a36Sopenharmony_ci da7218_dmix_gain_tlv), 89862306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In Filter2R Out2 DAIR Volume", 89962306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_2R_INFILT_2R_GAIN, 90062306a36Sopenharmony_ci DA7218_OUTDAI_2R_INFILT_2R_GAIN_SHIFT, 90162306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 90262306a36Sopenharmony_ci da7218_dmix_gain_tlv), 90362306a36Sopenharmony_ci 90462306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix ToneGen Out1 DAIL Volume", 90562306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_1L_TONEGEN_GAIN, 90662306a36Sopenharmony_ci DA7218_OUTDAI_1L_TONEGEN_GAIN_SHIFT, 90762306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 90862306a36Sopenharmony_ci da7218_dmix_gain_tlv), 90962306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix ToneGen Out1 DAIR Volume", 91062306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_1R_TONEGEN_GAIN, 91162306a36Sopenharmony_ci DA7218_OUTDAI_1R_TONEGEN_GAIN_SHIFT, 91262306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 91362306a36Sopenharmony_ci da7218_dmix_gain_tlv), 91462306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix ToneGen Out2 DAIL Volume", 91562306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_2L_TONEGEN_GAIN, 91662306a36Sopenharmony_ci DA7218_OUTDAI_2L_TONEGEN_GAIN_SHIFT, 91762306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 91862306a36Sopenharmony_ci da7218_dmix_gain_tlv), 91962306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix ToneGen Out2 DAIR Volume", 92062306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_2R_TONEGEN_GAIN, 92162306a36Sopenharmony_ci DA7218_OUTDAI_2R_TONEGEN_GAIN_SHIFT, 92262306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 92362306a36Sopenharmony_ci da7218_dmix_gain_tlv), 92462306a36Sopenharmony_ci 92562306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In DAIL Out1 DAIL Volume", 92662306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_1L_INDAI_1L_GAIN, 92762306a36Sopenharmony_ci DA7218_OUTDAI_1L_INDAI_1L_GAIN_SHIFT, 92862306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 92962306a36Sopenharmony_ci da7218_dmix_gain_tlv), 93062306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In DAIL Out1 DAIR Volume", 93162306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_1R_INDAI_1L_GAIN, 93262306a36Sopenharmony_ci DA7218_OUTDAI_1R_INDAI_1L_GAIN_SHIFT, 93362306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 93462306a36Sopenharmony_ci da7218_dmix_gain_tlv), 93562306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In DAIL Out2 DAIL Volume", 93662306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_2L_INDAI_1L_GAIN, 93762306a36Sopenharmony_ci DA7218_OUTDAI_2L_INDAI_1L_GAIN_SHIFT, 93862306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 93962306a36Sopenharmony_ci da7218_dmix_gain_tlv), 94062306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In DAIL Out2 DAIR Volume", 94162306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_2R_INDAI_1L_GAIN, 94262306a36Sopenharmony_ci DA7218_OUTDAI_2R_INDAI_1L_GAIN_SHIFT, 94362306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 94462306a36Sopenharmony_ci da7218_dmix_gain_tlv), 94562306a36Sopenharmony_ci 94662306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In DAIR Out1 DAIL Volume", 94762306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_1L_INDAI_1R_GAIN, 94862306a36Sopenharmony_ci DA7218_OUTDAI_1L_INDAI_1R_GAIN_SHIFT, 94962306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 95062306a36Sopenharmony_ci da7218_dmix_gain_tlv), 95162306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In DAIR Out1 DAIR Volume", 95262306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_1R_INDAI_1R_GAIN, 95362306a36Sopenharmony_ci DA7218_OUTDAI_1R_INDAI_1R_GAIN_SHIFT, 95462306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 95562306a36Sopenharmony_ci da7218_dmix_gain_tlv), 95662306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In DAIR Out2 DAIL Volume", 95762306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_2L_INDAI_1R_GAIN, 95862306a36Sopenharmony_ci DA7218_OUTDAI_2L_INDAI_1R_GAIN_SHIFT, 95962306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 96062306a36Sopenharmony_ci da7218_dmix_gain_tlv), 96162306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In DAIR Out2 DAIR Volume", 96262306a36Sopenharmony_ci DA7218_DMIX_OUTDAI_2R_INDAI_1R_GAIN, 96362306a36Sopenharmony_ci DA7218_OUTDAI_2R_INDAI_1R_GAIN_SHIFT, 96462306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 96562306a36Sopenharmony_ci da7218_dmix_gain_tlv), 96662306a36Sopenharmony_ci 96762306a36Sopenharmony_ci /* Digital Mixer (Output) */ 96862306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In Filter1L Out FilterL Volume", 96962306a36Sopenharmony_ci DA7218_DMIX_OUTFILT_1L_INFILT_1L_GAIN, 97062306a36Sopenharmony_ci DA7218_OUTFILT_1L_INFILT_1L_GAIN_SHIFT, 97162306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 97262306a36Sopenharmony_ci da7218_dmix_gain_tlv), 97362306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In Filter1L Out FilterR Volume", 97462306a36Sopenharmony_ci DA7218_DMIX_OUTFILT_1R_INFILT_1L_GAIN, 97562306a36Sopenharmony_ci DA7218_OUTFILT_1R_INFILT_1L_GAIN_SHIFT, 97662306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 97762306a36Sopenharmony_ci da7218_dmix_gain_tlv), 97862306a36Sopenharmony_ci 97962306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In Filter1R Out FilterL Volume", 98062306a36Sopenharmony_ci DA7218_DMIX_OUTFILT_1L_INFILT_1R_GAIN, 98162306a36Sopenharmony_ci DA7218_OUTFILT_1L_INFILT_1R_GAIN_SHIFT, 98262306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 98362306a36Sopenharmony_ci da7218_dmix_gain_tlv), 98462306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In Filter1R Out FilterR Volume", 98562306a36Sopenharmony_ci DA7218_DMIX_OUTFILT_1R_INFILT_1R_GAIN, 98662306a36Sopenharmony_ci DA7218_OUTFILT_1R_INFILT_1R_GAIN_SHIFT, 98762306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 98862306a36Sopenharmony_ci da7218_dmix_gain_tlv), 98962306a36Sopenharmony_ci 99062306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In Filter2L Out FilterL Volume", 99162306a36Sopenharmony_ci DA7218_DMIX_OUTFILT_1L_INFILT_2L_GAIN, 99262306a36Sopenharmony_ci DA7218_OUTFILT_1L_INFILT_2L_GAIN_SHIFT, 99362306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 99462306a36Sopenharmony_ci da7218_dmix_gain_tlv), 99562306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In Filter2L Out FilterR Volume", 99662306a36Sopenharmony_ci DA7218_DMIX_OUTFILT_1R_INFILT_2L_GAIN, 99762306a36Sopenharmony_ci DA7218_OUTFILT_1R_INFILT_2L_GAIN_SHIFT, 99862306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 99962306a36Sopenharmony_ci da7218_dmix_gain_tlv), 100062306a36Sopenharmony_ci 100162306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In Filter2R Out FilterL Volume", 100262306a36Sopenharmony_ci DA7218_DMIX_OUTFILT_1L_INFILT_2R_GAIN, 100362306a36Sopenharmony_ci DA7218_OUTFILT_1L_INFILT_2R_GAIN_SHIFT, 100462306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 100562306a36Sopenharmony_ci da7218_dmix_gain_tlv), 100662306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In Filter2R Out FilterR Volume", 100762306a36Sopenharmony_ci DA7218_DMIX_OUTFILT_1R_INFILT_2R_GAIN, 100862306a36Sopenharmony_ci DA7218_OUTFILT_1R_INFILT_2R_GAIN_SHIFT, 100962306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 101062306a36Sopenharmony_ci da7218_dmix_gain_tlv), 101162306a36Sopenharmony_ci 101262306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix ToneGen Out FilterL Volume", 101362306a36Sopenharmony_ci DA7218_DMIX_OUTFILT_1L_TONEGEN_GAIN, 101462306a36Sopenharmony_ci DA7218_OUTFILT_1L_TONEGEN_GAIN_SHIFT, 101562306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 101662306a36Sopenharmony_ci da7218_dmix_gain_tlv), 101762306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix ToneGen Out FilterR Volume", 101862306a36Sopenharmony_ci DA7218_DMIX_OUTFILT_1R_TONEGEN_GAIN, 101962306a36Sopenharmony_ci DA7218_OUTFILT_1R_TONEGEN_GAIN_SHIFT, 102062306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 102162306a36Sopenharmony_ci da7218_dmix_gain_tlv), 102262306a36Sopenharmony_ci 102362306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In DAIL Out FilterL Volume", 102462306a36Sopenharmony_ci DA7218_DMIX_OUTFILT_1L_INDAI_1L_GAIN, 102562306a36Sopenharmony_ci DA7218_OUTFILT_1L_INDAI_1L_GAIN_SHIFT, 102662306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 102762306a36Sopenharmony_ci da7218_dmix_gain_tlv), 102862306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In DAIL Out FilterR Volume", 102962306a36Sopenharmony_ci DA7218_DMIX_OUTFILT_1R_INDAI_1L_GAIN, 103062306a36Sopenharmony_ci DA7218_OUTFILT_1R_INDAI_1L_GAIN_SHIFT, 103162306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 103262306a36Sopenharmony_ci da7218_dmix_gain_tlv), 103362306a36Sopenharmony_ci 103462306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In DAIR Out FilterL Volume", 103562306a36Sopenharmony_ci DA7218_DMIX_OUTFILT_1L_INDAI_1R_GAIN, 103662306a36Sopenharmony_ci DA7218_OUTFILT_1L_INDAI_1R_GAIN_SHIFT, 103762306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 103862306a36Sopenharmony_ci da7218_dmix_gain_tlv), 103962306a36Sopenharmony_ci SOC_SINGLE_TLV("DMix In DAIR Out FilterR Volume", 104062306a36Sopenharmony_ci DA7218_DMIX_OUTFILT_1R_INDAI_1R_GAIN, 104162306a36Sopenharmony_ci DA7218_OUTFILT_1R_INDAI_1R_GAIN_SHIFT, 104262306a36Sopenharmony_ci DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT, 104362306a36Sopenharmony_ci da7218_dmix_gain_tlv), 104462306a36Sopenharmony_ci 104562306a36Sopenharmony_ci /* Sidetone Filter */ 104662306a36Sopenharmony_ci SND_SOC_BYTES_EXT("Sidetone BiQuad Coefficients", 104762306a36Sopenharmony_ci DA7218_SIDETONE_BIQ_3STAGE_CFG_SIZE, 104862306a36Sopenharmony_ci da7218_biquad_coeff_get, da7218_biquad_coeff_put), 104962306a36Sopenharmony_ci SOC_SINGLE_TLV("Sidetone Volume", DA7218_SIDETONE_GAIN, 105062306a36Sopenharmony_ci DA7218_SIDETONE_GAIN_SHIFT, DA7218_DMIX_GAIN_MAX, 105162306a36Sopenharmony_ci DA7218_NO_INVERT, da7218_dmix_gain_tlv), 105262306a36Sopenharmony_ci SOC_SINGLE("Sidetone Switch", DA7218_SIDETONE_CTRL, 105362306a36Sopenharmony_ci DA7218_SIDETONE_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX, 105462306a36Sopenharmony_ci DA7218_INVERT), 105562306a36Sopenharmony_ci 105662306a36Sopenharmony_ci /* Tone Generator */ 105762306a36Sopenharmony_ci SOC_ENUM("ToneGen DTMF Key", da7218_tonegen_dtmf_key), 105862306a36Sopenharmony_ci SOC_SINGLE("ToneGen DTMF Switch", DA7218_TONE_GEN_CFG1, 105962306a36Sopenharmony_ci DA7218_DTMF_EN_SHIFT, DA7218_SWITCH_EN_MAX, 106062306a36Sopenharmony_ci DA7218_NO_INVERT), 106162306a36Sopenharmony_ci SOC_ENUM("ToneGen Sinewave Gen Type", da7218_tonegen_swg_sel), 106262306a36Sopenharmony_ci SOC_SINGLE_EXT("ToneGen Sinewave1 Freq", DA7218_TONE_GEN_FREQ1_L, 106362306a36Sopenharmony_ci DA7218_FREQ1_L_SHIFT, DA7218_FREQ_MAX, DA7218_NO_INVERT, 106462306a36Sopenharmony_ci da7218_tonegen_freq_get, da7218_tonegen_freq_put), 106562306a36Sopenharmony_ci SOC_SINGLE_EXT("ToneGen Sinewave2 Freq", DA7218_TONE_GEN_FREQ2_L, 106662306a36Sopenharmony_ci DA7218_FREQ2_L_SHIFT, DA7218_FREQ_MAX, DA7218_NO_INVERT, 106762306a36Sopenharmony_ci da7218_tonegen_freq_get, da7218_tonegen_freq_put), 106862306a36Sopenharmony_ci SOC_SINGLE("ToneGen On Time", DA7218_TONE_GEN_ON_PER, 106962306a36Sopenharmony_ci DA7218_BEEP_ON_PER_SHIFT, DA7218_BEEP_ON_OFF_MAX, 107062306a36Sopenharmony_ci DA7218_NO_INVERT), 107162306a36Sopenharmony_ci SOC_SINGLE("ToneGen Off Time", DA7218_TONE_GEN_OFF_PER, 107262306a36Sopenharmony_ci DA7218_BEEP_OFF_PER_SHIFT, DA7218_BEEP_ON_OFF_MAX, 107362306a36Sopenharmony_ci DA7218_NO_INVERT), 107462306a36Sopenharmony_ci 107562306a36Sopenharmony_ci /* Gain ramping */ 107662306a36Sopenharmony_ci SOC_ENUM("Gain Ramp Rate", da7218_gain_ramp_rate), 107762306a36Sopenharmony_ci 107862306a36Sopenharmony_ci /* DGS */ 107962306a36Sopenharmony_ci SOC_SINGLE_TLV("DGS Trigger", DA7218_DGS_TRIGGER, 108062306a36Sopenharmony_ci DA7218_DGS_TRIGGER_LVL_SHIFT, DA7218_DGS_TRIGGER_MAX, 108162306a36Sopenharmony_ci DA7218_INVERT, da7218_dgs_trigger_tlv), 108262306a36Sopenharmony_ci SOC_ENUM("DGS Rise Coefficient", da7218_dgs_rise_coeff), 108362306a36Sopenharmony_ci SOC_ENUM("DGS Fall Coefficient", da7218_dgs_fall_coeff), 108462306a36Sopenharmony_ci SOC_SINGLE("DGS Sync Delay", DA7218_DGS_SYNC_DELAY, 108562306a36Sopenharmony_ci DA7218_DGS_SYNC_DELAY_SHIFT, DA7218_DGS_SYNC_DELAY_MAX, 108662306a36Sopenharmony_ci DA7218_NO_INVERT), 108762306a36Sopenharmony_ci SOC_SINGLE("DGS Fast SR Sync Delay", DA7218_DGS_SYNC_DELAY2, 108862306a36Sopenharmony_ci DA7218_DGS_SYNC_DELAY2_SHIFT, DA7218_DGS_SYNC_DELAY_MAX, 108962306a36Sopenharmony_ci DA7218_NO_INVERT), 109062306a36Sopenharmony_ci SOC_SINGLE("DGS Voice Filter Sync Delay", DA7218_DGS_SYNC_DELAY3, 109162306a36Sopenharmony_ci DA7218_DGS_SYNC_DELAY3_SHIFT, DA7218_DGS_SYNC_DELAY3_MAX, 109262306a36Sopenharmony_ci DA7218_NO_INVERT), 109362306a36Sopenharmony_ci SOC_SINGLE_TLV("DGS Anticlip Level", DA7218_DGS_LEVELS, 109462306a36Sopenharmony_ci DA7218_DGS_ANTICLIP_LVL_SHIFT, 109562306a36Sopenharmony_ci DA7218_DGS_ANTICLIP_LVL_MAX, DA7218_INVERT, 109662306a36Sopenharmony_ci da7218_dgs_anticlip_tlv), 109762306a36Sopenharmony_ci SOC_SINGLE_TLV("DGS Signal Level", DA7218_DGS_LEVELS, 109862306a36Sopenharmony_ci DA7218_DGS_SIGNAL_LVL_SHIFT, DA7218_DGS_SIGNAL_LVL_MAX, 109962306a36Sopenharmony_ci DA7218_INVERT, da7218_dgs_signal_tlv), 110062306a36Sopenharmony_ci SOC_SINGLE("DGS Gain Subrange Switch", DA7218_DGS_GAIN_CTRL, 110162306a36Sopenharmony_ci DA7218_DGS_SUBR_EN_SHIFT, DA7218_SWITCH_EN_MAX, 110262306a36Sopenharmony_ci DA7218_NO_INVERT), 110362306a36Sopenharmony_ci SOC_SINGLE("DGS Gain Ramp Switch", DA7218_DGS_GAIN_CTRL, 110462306a36Sopenharmony_ci DA7218_DGS_RAMP_EN_SHIFT, DA7218_SWITCH_EN_MAX, 110562306a36Sopenharmony_ci DA7218_NO_INVERT), 110662306a36Sopenharmony_ci SOC_SINGLE("DGS Gain Steps", DA7218_DGS_GAIN_CTRL, 110762306a36Sopenharmony_ci DA7218_DGS_STEPS_SHIFT, DA7218_DGS_STEPS_MAX, 110862306a36Sopenharmony_ci DA7218_NO_INVERT), 110962306a36Sopenharmony_ci SOC_DOUBLE("DGS Switch", DA7218_DGS_ENABLE, DA7218_DGS_ENABLE_L_SHIFT, 111062306a36Sopenharmony_ci DA7218_DGS_ENABLE_R_SHIFT, DA7218_SWITCH_EN_MAX, 111162306a36Sopenharmony_ci DA7218_NO_INVERT), 111262306a36Sopenharmony_ci 111362306a36Sopenharmony_ci /* Output High-Pass Filter */ 111462306a36Sopenharmony_ci SOC_ENUM("Out Filter HPF Mode", da7218_out1_hpf_mode), 111562306a36Sopenharmony_ci SOC_ENUM("Out Filter HPF Corner Audio", da7218_out1_audio_hpf_corner), 111662306a36Sopenharmony_ci SOC_ENUM("Out Filter HPF Corner Voice", da7218_out1_voice_hpf_corner), 111762306a36Sopenharmony_ci 111862306a36Sopenharmony_ci /* 5-Band Equaliser */ 111962306a36Sopenharmony_ci SOC_SINGLE_TLV("Out EQ Band1 Volume", DA7218_OUT_1_EQ_12_FILTER_CTRL, 112062306a36Sopenharmony_ci DA7218_OUT_1_EQ_BAND1_SHIFT, DA7218_OUT_EQ_BAND_MAX, 112162306a36Sopenharmony_ci DA7218_NO_INVERT, da7218_out_eq_band_tlv), 112262306a36Sopenharmony_ci SOC_SINGLE_TLV("Out EQ Band2 Volume", DA7218_OUT_1_EQ_12_FILTER_CTRL, 112362306a36Sopenharmony_ci DA7218_OUT_1_EQ_BAND2_SHIFT, DA7218_OUT_EQ_BAND_MAX, 112462306a36Sopenharmony_ci DA7218_NO_INVERT, da7218_out_eq_band_tlv), 112562306a36Sopenharmony_ci SOC_SINGLE_TLV("Out EQ Band3 Volume", DA7218_OUT_1_EQ_34_FILTER_CTRL, 112662306a36Sopenharmony_ci DA7218_OUT_1_EQ_BAND3_SHIFT, DA7218_OUT_EQ_BAND_MAX, 112762306a36Sopenharmony_ci DA7218_NO_INVERT, da7218_out_eq_band_tlv), 112862306a36Sopenharmony_ci SOC_SINGLE_TLV("Out EQ Band4 Volume", DA7218_OUT_1_EQ_34_FILTER_CTRL, 112962306a36Sopenharmony_ci DA7218_OUT_1_EQ_BAND4_SHIFT, DA7218_OUT_EQ_BAND_MAX, 113062306a36Sopenharmony_ci DA7218_NO_INVERT, da7218_out_eq_band_tlv), 113162306a36Sopenharmony_ci SOC_SINGLE_TLV("Out EQ Band5 Volume", DA7218_OUT_1_EQ_5_FILTER_CTRL, 113262306a36Sopenharmony_ci DA7218_OUT_1_EQ_BAND5_SHIFT, DA7218_OUT_EQ_BAND_MAX, 113362306a36Sopenharmony_ci DA7218_NO_INVERT, da7218_out_eq_band_tlv), 113462306a36Sopenharmony_ci SOC_SINGLE("Out EQ Switch", DA7218_OUT_1_EQ_5_FILTER_CTRL, 113562306a36Sopenharmony_ci DA7218_OUT_1_EQ_EN_SHIFT, DA7218_SWITCH_EN_MAX, 113662306a36Sopenharmony_ci DA7218_NO_INVERT), 113762306a36Sopenharmony_ci 113862306a36Sopenharmony_ci /* BiQuad Filters */ 113962306a36Sopenharmony_ci SND_SOC_BYTES_EXT("BiQuad Coefficients", 114062306a36Sopenharmony_ci DA7218_OUT_1_BIQ_5STAGE_CFG_SIZE, 114162306a36Sopenharmony_ci da7218_biquad_coeff_get, da7218_biquad_coeff_put), 114262306a36Sopenharmony_ci SOC_SINGLE("BiQuad Filter Switch", DA7218_OUT_1_BIQ_5STAGE_CTRL, 114362306a36Sopenharmony_ci DA7218_OUT_1_BIQ_5STAGE_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX, 114462306a36Sopenharmony_ci DA7218_INVERT), 114562306a36Sopenharmony_ci 114662306a36Sopenharmony_ci /* Output Filters */ 114762306a36Sopenharmony_ci SOC_DOUBLE_R_RANGE_TLV("Out Filter Volume", DA7218_OUT_1L_GAIN, 114862306a36Sopenharmony_ci DA7218_OUT_1R_GAIN, 114962306a36Sopenharmony_ci DA7218_OUT_1L_DIGITAL_GAIN_SHIFT, 115062306a36Sopenharmony_ci DA7218_OUT_DIGITAL_GAIN_MIN, 115162306a36Sopenharmony_ci DA7218_OUT_DIGITAL_GAIN_MAX, DA7218_NO_INVERT, 115262306a36Sopenharmony_ci da7218_out_dig_gain_tlv), 115362306a36Sopenharmony_ci SOC_DOUBLE_R("Out Filter Switch", DA7218_OUT_1L_FILTER_CTRL, 115462306a36Sopenharmony_ci DA7218_OUT_1R_FILTER_CTRL, DA7218_OUT_1L_MUTE_EN_SHIFT, 115562306a36Sopenharmony_ci DA7218_SWITCH_EN_MAX, DA7218_INVERT), 115662306a36Sopenharmony_ci SOC_DOUBLE_R("Out Filter Gain Subrange Switch", 115762306a36Sopenharmony_ci DA7218_OUT_1L_FILTER_CTRL, DA7218_OUT_1R_FILTER_CTRL, 115862306a36Sopenharmony_ci DA7218_OUT_1L_SUBRANGE_EN_SHIFT, DA7218_SWITCH_EN_MAX, 115962306a36Sopenharmony_ci DA7218_NO_INVERT), 116062306a36Sopenharmony_ci SOC_DOUBLE_R("Out Filter Gain Ramp Switch", DA7218_OUT_1L_FILTER_CTRL, 116162306a36Sopenharmony_ci DA7218_OUT_1R_FILTER_CTRL, DA7218_OUT_1L_RAMP_EN_SHIFT, 116262306a36Sopenharmony_ci DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), 116362306a36Sopenharmony_ci 116462306a36Sopenharmony_ci /* Mixer Output */ 116562306a36Sopenharmony_ci SOC_DOUBLE_R_RANGE_TLV("Mixout Volume", DA7218_MIXOUT_L_GAIN, 116662306a36Sopenharmony_ci DA7218_MIXOUT_R_GAIN, 116762306a36Sopenharmony_ci DA7218_MIXOUT_L_AMP_GAIN_SHIFT, 116862306a36Sopenharmony_ci DA7218_MIXOUT_AMP_GAIN_MIN, 116962306a36Sopenharmony_ci DA7218_MIXOUT_AMP_GAIN_MAX, DA7218_NO_INVERT, 117062306a36Sopenharmony_ci da7218_mixout_gain_tlv), 117162306a36Sopenharmony_ci 117262306a36Sopenharmony_ci /* DAC Noise Gate */ 117362306a36Sopenharmony_ci SOC_ENUM("DAC NG Setup Time", da7218_dac_ng_setup_time), 117462306a36Sopenharmony_ci SOC_ENUM("DAC NG Rampup Rate", da7218_dac_ng_rampup_rate), 117562306a36Sopenharmony_ci SOC_ENUM("DAC NG Rampdown Rate", da7218_dac_ng_rampdown_rate), 117662306a36Sopenharmony_ci SOC_SINGLE_TLV("DAC NG Off Threshold", DA7218_DAC_NG_OFF_THRESH, 117762306a36Sopenharmony_ci DA7218_DAC_NG_OFF_THRESHOLD_SHIFT, 117862306a36Sopenharmony_ci DA7218_DAC_NG_THRESHOLD_MAX, DA7218_NO_INVERT, 117962306a36Sopenharmony_ci da7218_dac_ng_threshold_tlv), 118062306a36Sopenharmony_ci SOC_SINGLE_TLV("DAC NG On Threshold", DA7218_DAC_NG_ON_THRESH, 118162306a36Sopenharmony_ci DA7218_DAC_NG_ON_THRESHOLD_SHIFT, 118262306a36Sopenharmony_ci DA7218_DAC_NG_THRESHOLD_MAX, DA7218_NO_INVERT, 118362306a36Sopenharmony_ci da7218_dac_ng_threshold_tlv), 118462306a36Sopenharmony_ci SOC_SINGLE("DAC NG Switch", DA7218_DAC_NG_CTRL, DA7218_DAC_NG_EN_SHIFT, 118562306a36Sopenharmony_ci DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), 118662306a36Sopenharmony_ci 118762306a36Sopenharmony_ci /* CP */ 118862306a36Sopenharmony_ci SOC_ENUM("Charge Pump Track Mode", da7218_cp_mchange), 118962306a36Sopenharmony_ci SOC_ENUM("Charge Pump Frequency", da7218_cp_fcontrol), 119062306a36Sopenharmony_ci SOC_ENUM("Charge Pump Decay Rate", da7218_cp_tau_delay), 119162306a36Sopenharmony_ci SOC_SINGLE("Charge Pump Threshold", DA7218_CP_VOL_THRESHOLD1, 119262306a36Sopenharmony_ci DA7218_CP_THRESH_VDD2_SHIFT, DA7218_CP_THRESH_VDD2_MAX, 119362306a36Sopenharmony_ci DA7218_NO_INVERT), 119462306a36Sopenharmony_ci 119562306a36Sopenharmony_ci /* Headphones */ 119662306a36Sopenharmony_ci SOC_DOUBLE_R_RANGE_TLV("Headphone Volume", DA7218_HP_L_GAIN, 119762306a36Sopenharmony_ci DA7218_HP_R_GAIN, DA7218_HP_L_AMP_GAIN_SHIFT, 119862306a36Sopenharmony_ci DA7218_HP_AMP_GAIN_MIN, DA7218_HP_AMP_GAIN_MAX, 119962306a36Sopenharmony_ci DA7218_NO_INVERT, da7218_hp_gain_tlv), 120062306a36Sopenharmony_ci SOC_DOUBLE_R("Headphone Switch", DA7218_HP_L_CTRL, DA7218_HP_R_CTRL, 120162306a36Sopenharmony_ci DA7218_HP_L_AMP_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX, 120262306a36Sopenharmony_ci DA7218_INVERT), 120362306a36Sopenharmony_ci SOC_DOUBLE_R("Headphone Gain Ramp Switch", DA7218_HP_L_CTRL, 120462306a36Sopenharmony_ci DA7218_HP_R_CTRL, DA7218_HP_L_AMP_RAMP_EN_SHIFT, 120562306a36Sopenharmony_ci DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), 120662306a36Sopenharmony_ci SOC_DOUBLE_R("Headphone ZC Gain Switch", DA7218_HP_L_CTRL, 120762306a36Sopenharmony_ci DA7218_HP_R_CTRL, DA7218_HP_L_AMP_ZC_EN_SHIFT, 120862306a36Sopenharmony_ci DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), 120962306a36Sopenharmony_ci}; 121062306a36Sopenharmony_ci 121162306a36Sopenharmony_ci 121262306a36Sopenharmony_ci/* 121362306a36Sopenharmony_ci * DAPM Mux Controls 121462306a36Sopenharmony_ci */ 121562306a36Sopenharmony_ci 121662306a36Sopenharmony_cistatic const char * const da7218_mic_sel_text[] = { "Analog", "Digital" }; 121762306a36Sopenharmony_ci 121862306a36Sopenharmony_cistatic const struct soc_enum da7218_mic1_sel = 121962306a36Sopenharmony_ci SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(da7218_mic_sel_text), 122062306a36Sopenharmony_ci da7218_mic_sel_text); 122162306a36Sopenharmony_ci 122262306a36Sopenharmony_cistatic const struct snd_kcontrol_new da7218_mic1_sel_mux = 122362306a36Sopenharmony_ci SOC_DAPM_ENUM("Mic1 Mux", da7218_mic1_sel); 122462306a36Sopenharmony_ci 122562306a36Sopenharmony_cistatic const struct soc_enum da7218_mic2_sel = 122662306a36Sopenharmony_ci SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(da7218_mic_sel_text), 122762306a36Sopenharmony_ci da7218_mic_sel_text); 122862306a36Sopenharmony_ci 122962306a36Sopenharmony_cistatic const struct snd_kcontrol_new da7218_mic2_sel_mux = 123062306a36Sopenharmony_ci SOC_DAPM_ENUM("Mic2 Mux", da7218_mic2_sel); 123162306a36Sopenharmony_ci 123262306a36Sopenharmony_cistatic const char * const da7218_sidetone_in_sel_txt[] = { 123362306a36Sopenharmony_ci "In Filter1L", "In Filter1R", "In Filter2L", "In Filter2R" 123462306a36Sopenharmony_ci}; 123562306a36Sopenharmony_ci 123662306a36Sopenharmony_cistatic const struct soc_enum da7218_sidetone_in_sel = 123762306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_SIDETONE_IN_SELECT, 123862306a36Sopenharmony_ci DA7218_SIDETONE_IN_SELECT_SHIFT, 123962306a36Sopenharmony_ci DA7218_SIDETONE_IN_SELECT_MAX, 124062306a36Sopenharmony_ci da7218_sidetone_in_sel_txt); 124162306a36Sopenharmony_ci 124262306a36Sopenharmony_cistatic const struct snd_kcontrol_new da7218_sidetone_in_sel_mux = 124362306a36Sopenharmony_ci SOC_DAPM_ENUM("Sidetone Mux", da7218_sidetone_in_sel); 124462306a36Sopenharmony_ci 124562306a36Sopenharmony_cistatic const char * const da7218_out_filt_biq_sel_txt[] = { 124662306a36Sopenharmony_ci "Bypass", "Enabled" 124762306a36Sopenharmony_ci}; 124862306a36Sopenharmony_ci 124962306a36Sopenharmony_cistatic const struct soc_enum da7218_out_filtl_biq_sel = 125062306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_OUT_1L_FILTER_CTRL, 125162306a36Sopenharmony_ci DA7218_OUT_1L_BIQ_5STAGE_SEL_SHIFT, 125262306a36Sopenharmony_ci DA7218_OUT_BIQ_5STAGE_SEL_MAX, 125362306a36Sopenharmony_ci da7218_out_filt_biq_sel_txt); 125462306a36Sopenharmony_ci 125562306a36Sopenharmony_cistatic const struct snd_kcontrol_new da7218_out_filtl_biq_sel_mux = 125662306a36Sopenharmony_ci SOC_DAPM_ENUM("Out FilterL BiQuad Mux", da7218_out_filtl_biq_sel); 125762306a36Sopenharmony_ci 125862306a36Sopenharmony_cistatic const struct soc_enum da7218_out_filtr_biq_sel = 125962306a36Sopenharmony_ci SOC_ENUM_SINGLE(DA7218_OUT_1R_FILTER_CTRL, 126062306a36Sopenharmony_ci DA7218_OUT_1R_BIQ_5STAGE_SEL_SHIFT, 126162306a36Sopenharmony_ci DA7218_OUT_BIQ_5STAGE_SEL_MAX, 126262306a36Sopenharmony_ci da7218_out_filt_biq_sel_txt); 126362306a36Sopenharmony_ci 126462306a36Sopenharmony_cistatic const struct snd_kcontrol_new da7218_out_filtr_biq_sel_mux = 126562306a36Sopenharmony_ci SOC_DAPM_ENUM("Out FilterR BiQuad Mux", da7218_out_filtr_biq_sel); 126662306a36Sopenharmony_ci 126762306a36Sopenharmony_ci 126862306a36Sopenharmony_ci/* 126962306a36Sopenharmony_ci * DAPM Mixer Controls 127062306a36Sopenharmony_ci */ 127162306a36Sopenharmony_ci 127262306a36Sopenharmony_ci#define DA7218_DMIX_CTRLS(reg) \ 127362306a36Sopenharmony_ci SOC_DAPM_SINGLE("In Filter1L Switch", reg, \ 127462306a36Sopenharmony_ci DA7218_DMIX_SRC_INFILT1L, \ 127562306a36Sopenharmony_ci DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), \ 127662306a36Sopenharmony_ci SOC_DAPM_SINGLE("In Filter1R Switch", reg, \ 127762306a36Sopenharmony_ci DA7218_DMIX_SRC_INFILT1R, \ 127862306a36Sopenharmony_ci DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), \ 127962306a36Sopenharmony_ci SOC_DAPM_SINGLE("In Filter2L Switch", reg, \ 128062306a36Sopenharmony_ci DA7218_DMIX_SRC_INFILT2L, \ 128162306a36Sopenharmony_ci DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), \ 128262306a36Sopenharmony_ci SOC_DAPM_SINGLE("In Filter2R Switch", reg, \ 128362306a36Sopenharmony_ci DA7218_DMIX_SRC_INFILT2R, \ 128462306a36Sopenharmony_ci DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), \ 128562306a36Sopenharmony_ci SOC_DAPM_SINGLE("ToneGen Switch", reg, \ 128662306a36Sopenharmony_ci DA7218_DMIX_SRC_TONEGEN, \ 128762306a36Sopenharmony_ci DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), \ 128862306a36Sopenharmony_ci SOC_DAPM_SINGLE("DAIL Switch", reg, DA7218_DMIX_SRC_DAIL, \ 128962306a36Sopenharmony_ci DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), \ 129062306a36Sopenharmony_ci SOC_DAPM_SINGLE("DAIR Switch", reg, DA7218_DMIX_SRC_DAIR, \ 129162306a36Sopenharmony_ci DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT) 129262306a36Sopenharmony_ci 129362306a36Sopenharmony_cistatic const struct snd_kcontrol_new da7218_out_dai1l_mix_controls[] = { 129462306a36Sopenharmony_ci DA7218_DMIX_CTRLS(DA7218_DROUTING_OUTDAI_1L), 129562306a36Sopenharmony_ci}; 129662306a36Sopenharmony_ci 129762306a36Sopenharmony_cistatic const struct snd_kcontrol_new da7218_out_dai1r_mix_controls[] = { 129862306a36Sopenharmony_ci DA7218_DMIX_CTRLS(DA7218_DROUTING_OUTDAI_1R), 129962306a36Sopenharmony_ci}; 130062306a36Sopenharmony_ci 130162306a36Sopenharmony_cistatic const struct snd_kcontrol_new da7218_out_dai2l_mix_controls[] = { 130262306a36Sopenharmony_ci DA7218_DMIX_CTRLS(DA7218_DROUTING_OUTDAI_2L), 130362306a36Sopenharmony_ci}; 130462306a36Sopenharmony_ci 130562306a36Sopenharmony_cistatic const struct snd_kcontrol_new da7218_out_dai2r_mix_controls[] = { 130662306a36Sopenharmony_ci DA7218_DMIX_CTRLS(DA7218_DROUTING_OUTDAI_2R), 130762306a36Sopenharmony_ci}; 130862306a36Sopenharmony_ci 130962306a36Sopenharmony_cistatic const struct snd_kcontrol_new da7218_out_filtl_mix_controls[] = { 131062306a36Sopenharmony_ci DA7218_DMIX_CTRLS(DA7218_DROUTING_OUTFILT_1L), 131162306a36Sopenharmony_ci}; 131262306a36Sopenharmony_ci 131362306a36Sopenharmony_cistatic const struct snd_kcontrol_new da7218_out_filtr_mix_controls[] = { 131462306a36Sopenharmony_ci DA7218_DMIX_CTRLS(DA7218_DROUTING_OUTFILT_1R), 131562306a36Sopenharmony_ci}; 131662306a36Sopenharmony_ci 131762306a36Sopenharmony_ci#define DA7218_DMIX_ST_CTRLS(reg) \ 131862306a36Sopenharmony_ci SOC_DAPM_SINGLE("Out FilterL Switch", reg, \ 131962306a36Sopenharmony_ci DA7218_DMIX_ST_SRC_OUTFILT1L, \ 132062306a36Sopenharmony_ci DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), \ 132162306a36Sopenharmony_ci SOC_DAPM_SINGLE("Out FilterR Switch", reg, \ 132262306a36Sopenharmony_ci DA7218_DMIX_ST_SRC_OUTFILT1R, \ 132362306a36Sopenharmony_ci DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT), \ 132462306a36Sopenharmony_ci SOC_DAPM_SINGLE("Sidetone Switch", reg, \ 132562306a36Sopenharmony_ci DA7218_DMIX_ST_SRC_SIDETONE, \ 132662306a36Sopenharmony_ci DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT) \ 132762306a36Sopenharmony_ci 132862306a36Sopenharmony_cistatic const struct snd_kcontrol_new da7218_st_out_filtl_mix_controls[] = { 132962306a36Sopenharmony_ci DA7218_DMIX_ST_CTRLS(DA7218_DROUTING_ST_OUTFILT_1L), 133062306a36Sopenharmony_ci}; 133162306a36Sopenharmony_ci 133262306a36Sopenharmony_cistatic const struct snd_kcontrol_new da7218_st_out_filtr_mix_controls[] = { 133362306a36Sopenharmony_ci DA7218_DMIX_ST_CTRLS(DA7218_DROUTING_ST_OUTFILT_1R), 133462306a36Sopenharmony_ci}; 133562306a36Sopenharmony_ci 133662306a36Sopenharmony_ci 133762306a36Sopenharmony_ci/* 133862306a36Sopenharmony_ci * DAPM Events 133962306a36Sopenharmony_ci */ 134062306a36Sopenharmony_ci 134162306a36Sopenharmony_ci/* 134262306a36Sopenharmony_ci * We keep track of which input filters are enabled. This is used in the logic 134362306a36Sopenharmony_ci * for controlling the mic level detect feature. 134462306a36Sopenharmony_ci */ 134562306a36Sopenharmony_cistatic int da7218_in_filter_event(struct snd_soc_dapm_widget *w, 134662306a36Sopenharmony_ci struct snd_kcontrol *kcontrol, int event) 134762306a36Sopenharmony_ci{ 134862306a36Sopenharmony_ci struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 134962306a36Sopenharmony_ci struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component); 135062306a36Sopenharmony_ci u8 mask; 135162306a36Sopenharmony_ci 135262306a36Sopenharmony_ci switch (w->reg) { 135362306a36Sopenharmony_ci case DA7218_IN_1L_FILTER_CTRL: 135462306a36Sopenharmony_ci mask = (1 << DA7218_LVL_DET_EN_CHAN1L_SHIFT); 135562306a36Sopenharmony_ci break; 135662306a36Sopenharmony_ci case DA7218_IN_1R_FILTER_CTRL: 135762306a36Sopenharmony_ci mask = (1 << DA7218_LVL_DET_EN_CHAN1R_SHIFT); 135862306a36Sopenharmony_ci break; 135962306a36Sopenharmony_ci case DA7218_IN_2L_FILTER_CTRL: 136062306a36Sopenharmony_ci mask = (1 << DA7218_LVL_DET_EN_CHAN2L_SHIFT); 136162306a36Sopenharmony_ci break; 136262306a36Sopenharmony_ci case DA7218_IN_2R_FILTER_CTRL: 136362306a36Sopenharmony_ci mask = (1 << DA7218_LVL_DET_EN_CHAN2R_SHIFT); 136462306a36Sopenharmony_ci break; 136562306a36Sopenharmony_ci default: 136662306a36Sopenharmony_ci return -EINVAL; 136762306a36Sopenharmony_ci } 136862306a36Sopenharmony_ci 136962306a36Sopenharmony_ci switch (event) { 137062306a36Sopenharmony_ci case SND_SOC_DAPM_POST_PMU: 137162306a36Sopenharmony_ci da7218->in_filt_en |= mask; 137262306a36Sopenharmony_ci /* 137362306a36Sopenharmony_ci * If we're enabling path for mic level detect, wait for path 137462306a36Sopenharmony_ci * to settle before enabling feature to avoid incorrect and 137562306a36Sopenharmony_ci * unwanted detect events. 137662306a36Sopenharmony_ci */ 137762306a36Sopenharmony_ci if (mask & da7218->mic_lvl_det_en) 137862306a36Sopenharmony_ci msleep(DA7218_MIC_LVL_DET_DELAY); 137962306a36Sopenharmony_ci break; 138062306a36Sopenharmony_ci case SND_SOC_DAPM_PRE_PMD: 138162306a36Sopenharmony_ci da7218->in_filt_en &= ~mask; 138262306a36Sopenharmony_ci break; 138362306a36Sopenharmony_ci default: 138462306a36Sopenharmony_ci return -EINVAL; 138562306a36Sopenharmony_ci } 138662306a36Sopenharmony_ci 138762306a36Sopenharmony_ci /* Enable configured level detection paths */ 138862306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_LVL_DET_CTRL, 138962306a36Sopenharmony_ci (da7218->in_filt_en & da7218->mic_lvl_det_en)); 139062306a36Sopenharmony_ci 139162306a36Sopenharmony_ci return 0; 139262306a36Sopenharmony_ci} 139362306a36Sopenharmony_ci 139462306a36Sopenharmony_cistatic int da7218_dai_event(struct snd_soc_dapm_widget *w, 139562306a36Sopenharmony_ci struct snd_kcontrol *kcontrol, int event) 139662306a36Sopenharmony_ci{ 139762306a36Sopenharmony_ci struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 139862306a36Sopenharmony_ci struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component); 139962306a36Sopenharmony_ci u8 pll_ctrl, pll_status, refosc_cal; 140062306a36Sopenharmony_ci int i; 140162306a36Sopenharmony_ci bool success; 140262306a36Sopenharmony_ci 140362306a36Sopenharmony_ci switch (event) { 140462306a36Sopenharmony_ci case SND_SOC_DAPM_POST_PMU: 140562306a36Sopenharmony_ci if (da7218->master) 140662306a36Sopenharmony_ci /* Enable DAI clks for master mode */ 140762306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_DAI_CLK_MODE, 140862306a36Sopenharmony_ci DA7218_DAI_CLK_EN_MASK, 140962306a36Sopenharmony_ci DA7218_DAI_CLK_EN_MASK); 141062306a36Sopenharmony_ci 141162306a36Sopenharmony_ci /* Tune reference oscillator */ 141262306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_PLL_REFOSC_CAL, 141362306a36Sopenharmony_ci DA7218_PLL_REFOSC_CAL_START_MASK); 141462306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_PLL_REFOSC_CAL, 141562306a36Sopenharmony_ci DA7218_PLL_REFOSC_CAL_START_MASK | 141662306a36Sopenharmony_ci DA7218_PLL_REFOSC_CAL_EN_MASK); 141762306a36Sopenharmony_ci 141862306a36Sopenharmony_ci /* Check tuning complete */ 141962306a36Sopenharmony_ci i = 0; 142062306a36Sopenharmony_ci success = false; 142162306a36Sopenharmony_ci do { 142262306a36Sopenharmony_ci refosc_cal = snd_soc_component_read(component, DA7218_PLL_REFOSC_CAL); 142362306a36Sopenharmony_ci if (!(refosc_cal & DA7218_PLL_REFOSC_CAL_START_MASK)) { 142462306a36Sopenharmony_ci success = true; 142562306a36Sopenharmony_ci } else { 142662306a36Sopenharmony_ci ++i; 142762306a36Sopenharmony_ci usleep_range(DA7218_REF_OSC_CHECK_DELAY_MIN, 142862306a36Sopenharmony_ci DA7218_REF_OSC_CHECK_DELAY_MAX); 142962306a36Sopenharmony_ci } 143062306a36Sopenharmony_ci } while ((i < DA7218_REF_OSC_CHECK_TRIES) && (!success)); 143162306a36Sopenharmony_ci 143262306a36Sopenharmony_ci if (!success) 143362306a36Sopenharmony_ci dev_warn(component->dev, 143462306a36Sopenharmony_ci "Reference oscillator failed calibration\n"); 143562306a36Sopenharmony_ci 143662306a36Sopenharmony_ci /* PC synchronised to DAI */ 143762306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_PC_COUNT, 143862306a36Sopenharmony_ci DA7218_PC_RESYNC_AUTO_MASK); 143962306a36Sopenharmony_ci 144062306a36Sopenharmony_ci /* If SRM not enabled, we don't need to check status */ 144162306a36Sopenharmony_ci pll_ctrl = snd_soc_component_read(component, DA7218_PLL_CTRL); 144262306a36Sopenharmony_ci if ((pll_ctrl & DA7218_PLL_MODE_MASK) != DA7218_PLL_MODE_SRM) 144362306a36Sopenharmony_ci return 0; 144462306a36Sopenharmony_ci 144562306a36Sopenharmony_ci /* Check SRM has locked */ 144662306a36Sopenharmony_ci i = 0; 144762306a36Sopenharmony_ci success = false; 144862306a36Sopenharmony_ci do { 144962306a36Sopenharmony_ci pll_status = snd_soc_component_read(component, DA7218_PLL_STATUS); 145062306a36Sopenharmony_ci if (pll_status & DA7218_PLL_SRM_STATUS_SRM_LOCK) { 145162306a36Sopenharmony_ci success = true; 145262306a36Sopenharmony_ci } else { 145362306a36Sopenharmony_ci ++i; 145462306a36Sopenharmony_ci msleep(DA7218_SRM_CHECK_DELAY); 145562306a36Sopenharmony_ci } 145662306a36Sopenharmony_ci } while ((i < DA7218_SRM_CHECK_TRIES) && (!success)); 145762306a36Sopenharmony_ci 145862306a36Sopenharmony_ci if (!success) 145962306a36Sopenharmony_ci dev_warn(component->dev, "SRM failed to lock\n"); 146062306a36Sopenharmony_ci 146162306a36Sopenharmony_ci return 0; 146262306a36Sopenharmony_ci case SND_SOC_DAPM_POST_PMD: 146362306a36Sopenharmony_ci /* PC free-running */ 146462306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_PC_COUNT, DA7218_PC_FREERUN_MASK); 146562306a36Sopenharmony_ci 146662306a36Sopenharmony_ci if (da7218->master) 146762306a36Sopenharmony_ci /* Disable DAI clks for master mode */ 146862306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_DAI_CLK_MODE, 146962306a36Sopenharmony_ci DA7218_DAI_CLK_EN_MASK, 0); 147062306a36Sopenharmony_ci 147162306a36Sopenharmony_ci return 0; 147262306a36Sopenharmony_ci default: 147362306a36Sopenharmony_ci return -EINVAL; 147462306a36Sopenharmony_ci } 147562306a36Sopenharmony_ci} 147662306a36Sopenharmony_ci 147762306a36Sopenharmony_cistatic int da7218_cp_event(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 da7218_priv *da7218 = snd_soc_component_get_drvdata(component); 148262306a36Sopenharmony_ci 148362306a36Sopenharmony_ci /* 148462306a36Sopenharmony_ci * If this is DA7217 and we're using single supply for differential 148562306a36Sopenharmony_ci * output, we really don't want to touch the charge pump. 148662306a36Sopenharmony_ci */ 148762306a36Sopenharmony_ci if (da7218->hp_single_supply) 148862306a36Sopenharmony_ci return 0; 148962306a36Sopenharmony_ci 149062306a36Sopenharmony_ci switch (event) { 149162306a36Sopenharmony_ci case SND_SOC_DAPM_PRE_PMU: 149262306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_CP_CTRL, DA7218_CP_EN_MASK, 149362306a36Sopenharmony_ci DA7218_CP_EN_MASK); 149462306a36Sopenharmony_ci return 0; 149562306a36Sopenharmony_ci case SND_SOC_DAPM_PRE_PMD: 149662306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_CP_CTRL, DA7218_CP_EN_MASK, 149762306a36Sopenharmony_ci 0); 149862306a36Sopenharmony_ci return 0; 149962306a36Sopenharmony_ci default: 150062306a36Sopenharmony_ci return -EINVAL; 150162306a36Sopenharmony_ci } 150262306a36Sopenharmony_ci} 150362306a36Sopenharmony_ci 150462306a36Sopenharmony_cistatic int da7218_hp_pga_event(struct snd_soc_dapm_widget *w, 150562306a36Sopenharmony_ci struct snd_kcontrol *kcontrol, int event) 150662306a36Sopenharmony_ci{ 150762306a36Sopenharmony_ci struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 150862306a36Sopenharmony_ci 150962306a36Sopenharmony_ci switch (event) { 151062306a36Sopenharmony_ci case SND_SOC_DAPM_POST_PMU: 151162306a36Sopenharmony_ci /* Enable headphone output */ 151262306a36Sopenharmony_ci snd_soc_component_update_bits(component, w->reg, DA7218_HP_AMP_OE_MASK, 151362306a36Sopenharmony_ci DA7218_HP_AMP_OE_MASK); 151462306a36Sopenharmony_ci return 0; 151562306a36Sopenharmony_ci case SND_SOC_DAPM_PRE_PMD: 151662306a36Sopenharmony_ci /* Headphone output high impedance */ 151762306a36Sopenharmony_ci snd_soc_component_update_bits(component, w->reg, DA7218_HP_AMP_OE_MASK, 0); 151862306a36Sopenharmony_ci return 0; 151962306a36Sopenharmony_ci default: 152062306a36Sopenharmony_ci return -EINVAL; 152162306a36Sopenharmony_ci } 152262306a36Sopenharmony_ci} 152362306a36Sopenharmony_ci 152462306a36Sopenharmony_ci 152562306a36Sopenharmony_ci/* 152662306a36Sopenharmony_ci * DAPM Widgets 152762306a36Sopenharmony_ci */ 152862306a36Sopenharmony_ci 152962306a36Sopenharmony_cistatic const struct snd_soc_dapm_widget da7218_dapm_widgets[] = { 153062306a36Sopenharmony_ci /* Input Supplies */ 153162306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("Mic Bias1", DA7218_MICBIAS_EN, 153262306a36Sopenharmony_ci DA7218_MICBIAS_1_EN_SHIFT, DA7218_NO_INVERT, 153362306a36Sopenharmony_ci NULL, 0), 153462306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("Mic Bias2", DA7218_MICBIAS_EN, 153562306a36Sopenharmony_ci DA7218_MICBIAS_2_EN_SHIFT, DA7218_NO_INVERT, 153662306a36Sopenharmony_ci NULL, 0), 153762306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("DMic1 Left", DA7218_DMIC_1_CTRL, 153862306a36Sopenharmony_ci DA7218_DMIC_1L_EN_SHIFT, DA7218_NO_INVERT, 153962306a36Sopenharmony_ci NULL, 0), 154062306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("DMic1 Right", DA7218_DMIC_1_CTRL, 154162306a36Sopenharmony_ci DA7218_DMIC_1R_EN_SHIFT, DA7218_NO_INVERT, 154262306a36Sopenharmony_ci NULL, 0), 154362306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("DMic2 Left", DA7218_DMIC_2_CTRL, 154462306a36Sopenharmony_ci DA7218_DMIC_2L_EN_SHIFT, DA7218_NO_INVERT, 154562306a36Sopenharmony_ci NULL, 0), 154662306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("DMic2 Right", DA7218_DMIC_2_CTRL, 154762306a36Sopenharmony_ci DA7218_DMIC_2R_EN_SHIFT, DA7218_NO_INVERT, 154862306a36Sopenharmony_ci NULL, 0), 154962306a36Sopenharmony_ci 155062306a36Sopenharmony_ci /* Inputs */ 155162306a36Sopenharmony_ci SND_SOC_DAPM_INPUT("MIC1"), 155262306a36Sopenharmony_ci SND_SOC_DAPM_INPUT("MIC2"), 155362306a36Sopenharmony_ci SND_SOC_DAPM_INPUT("DMIC1L"), 155462306a36Sopenharmony_ci SND_SOC_DAPM_INPUT("DMIC1R"), 155562306a36Sopenharmony_ci SND_SOC_DAPM_INPUT("DMIC2L"), 155662306a36Sopenharmony_ci SND_SOC_DAPM_INPUT("DMIC2R"), 155762306a36Sopenharmony_ci 155862306a36Sopenharmony_ci /* Input Mixer Supplies */ 155962306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("Mixin1 Supply", DA7218_MIXIN_1_CTRL, 156062306a36Sopenharmony_ci DA7218_MIXIN_1_MIX_SEL_SHIFT, DA7218_NO_INVERT, 156162306a36Sopenharmony_ci NULL, 0), 156262306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("Mixin2 Supply", DA7218_MIXIN_2_CTRL, 156362306a36Sopenharmony_ci DA7218_MIXIN_2_MIX_SEL_SHIFT, DA7218_NO_INVERT, 156462306a36Sopenharmony_ci NULL, 0), 156562306a36Sopenharmony_ci 156662306a36Sopenharmony_ci /* Input PGAs */ 156762306a36Sopenharmony_ci SND_SOC_DAPM_PGA("Mic1 PGA", DA7218_MIC_1_CTRL, 156862306a36Sopenharmony_ci DA7218_MIC_1_AMP_EN_SHIFT, DA7218_NO_INVERT, 156962306a36Sopenharmony_ci NULL, 0), 157062306a36Sopenharmony_ci SND_SOC_DAPM_PGA("Mic2 PGA", DA7218_MIC_2_CTRL, 157162306a36Sopenharmony_ci DA7218_MIC_2_AMP_EN_SHIFT, DA7218_NO_INVERT, 157262306a36Sopenharmony_ci NULL, 0), 157362306a36Sopenharmony_ci SND_SOC_DAPM_PGA("Mixin1 PGA", DA7218_MIXIN_1_CTRL, 157462306a36Sopenharmony_ci DA7218_MIXIN_1_AMP_EN_SHIFT, DA7218_NO_INVERT, 157562306a36Sopenharmony_ci NULL, 0), 157662306a36Sopenharmony_ci SND_SOC_DAPM_PGA("Mixin2 PGA", DA7218_MIXIN_2_CTRL, 157762306a36Sopenharmony_ci DA7218_MIXIN_2_AMP_EN_SHIFT, DA7218_NO_INVERT, 157862306a36Sopenharmony_ci NULL, 0), 157962306a36Sopenharmony_ci 158062306a36Sopenharmony_ci /* Mic/DMic Muxes */ 158162306a36Sopenharmony_ci SND_SOC_DAPM_MUX("Mic1 Mux", SND_SOC_NOPM, 0, 0, &da7218_mic1_sel_mux), 158262306a36Sopenharmony_ci SND_SOC_DAPM_MUX("Mic2 Mux", SND_SOC_NOPM, 0, 0, &da7218_mic2_sel_mux), 158362306a36Sopenharmony_ci 158462306a36Sopenharmony_ci /* Input Filters */ 158562306a36Sopenharmony_ci SND_SOC_DAPM_ADC_E("In Filter1L", NULL, DA7218_IN_1L_FILTER_CTRL, 158662306a36Sopenharmony_ci DA7218_IN_1L_FILTER_EN_SHIFT, DA7218_NO_INVERT, 158762306a36Sopenharmony_ci da7218_in_filter_event, 158862306a36Sopenharmony_ci SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 158962306a36Sopenharmony_ci SND_SOC_DAPM_ADC_E("In Filter1R", NULL, DA7218_IN_1R_FILTER_CTRL, 159062306a36Sopenharmony_ci DA7218_IN_1R_FILTER_EN_SHIFT, DA7218_NO_INVERT, 159162306a36Sopenharmony_ci da7218_in_filter_event, 159262306a36Sopenharmony_ci SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 159362306a36Sopenharmony_ci SND_SOC_DAPM_ADC_E("In Filter2L", NULL, DA7218_IN_2L_FILTER_CTRL, 159462306a36Sopenharmony_ci DA7218_IN_2L_FILTER_EN_SHIFT, DA7218_NO_INVERT, 159562306a36Sopenharmony_ci da7218_in_filter_event, 159662306a36Sopenharmony_ci SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 159762306a36Sopenharmony_ci SND_SOC_DAPM_ADC_E("In Filter2R", NULL, DA7218_IN_2R_FILTER_CTRL, 159862306a36Sopenharmony_ci DA7218_IN_2R_FILTER_EN_SHIFT, DA7218_NO_INVERT, 159962306a36Sopenharmony_ci da7218_in_filter_event, 160062306a36Sopenharmony_ci SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 160162306a36Sopenharmony_ci 160262306a36Sopenharmony_ci /* Tone Generator */ 160362306a36Sopenharmony_ci SND_SOC_DAPM_SIGGEN("TONE"), 160462306a36Sopenharmony_ci SND_SOC_DAPM_PGA("Tone Generator", DA7218_TONE_GEN_CFG1, 160562306a36Sopenharmony_ci DA7218_START_STOPN_SHIFT, DA7218_NO_INVERT, NULL, 0), 160662306a36Sopenharmony_ci 160762306a36Sopenharmony_ci /* Sidetone Input */ 160862306a36Sopenharmony_ci SND_SOC_DAPM_MUX("Sidetone Mux", SND_SOC_NOPM, 0, 0, 160962306a36Sopenharmony_ci &da7218_sidetone_in_sel_mux), 161062306a36Sopenharmony_ci SND_SOC_DAPM_ADC("Sidetone Filter", NULL, DA7218_SIDETONE_CTRL, 161162306a36Sopenharmony_ci DA7218_SIDETONE_FILTER_EN_SHIFT, DA7218_NO_INVERT), 161262306a36Sopenharmony_ci 161362306a36Sopenharmony_ci /* Input Mixers */ 161462306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("Mixer DAI1L", SND_SOC_NOPM, 0, 0, 161562306a36Sopenharmony_ci da7218_out_dai1l_mix_controls, 161662306a36Sopenharmony_ci ARRAY_SIZE(da7218_out_dai1l_mix_controls)), 161762306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("Mixer DAI1R", SND_SOC_NOPM, 0, 0, 161862306a36Sopenharmony_ci da7218_out_dai1r_mix_controls, 161962306a36Sopenharmony_ci ARRAY_SIZE(da7218_out_dai1r_mix_controls)), 162062306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("Mixer DAI2L", SND_SOC_NOPM, 0, 0, 162162306a36Sopenharmony_ci da7218_out_dai2l_mix_controls, 162262306a36Sopenharmony_ci ARRAY_SIZE(da7218_out_dai2l_mix_controls)), 162362306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("Mixer DAI2R", SND_SOC_NOPM, 0, 0, 162462306a36Sopenharmony_ci da7218_out_dai2r_mix_controls, 162562306a36Sopenharmony_ci ARRAY_SIZE(da7218_out_dai2r_mix_controls)), 162662306a36Sopenharmony_ci 162762306a36Sopenharmony_ci /* DAI Supply */ 162862306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("DAI", DA7218_DAI_CTRL, DA7218_DAI_EN_SHIFT, 162962306a36Sopenharmony_ci DA7218_NO_INVERT, da7218_dai_event, 163062306a36Sopenharmony_ci SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 163162306a36Sopenharmony_ci 163262306a36Sopenharmony_ci /* DAI */ 163362306a36Sopenharmony_ci SND_SOC_DAPM_AIF_OUT("DAIOUT", "Capture", 0, DA7218_DAI_TDM_CTRL, 163462306a36Sopenharmony_ci DA7218_DAI_OE_SHIFT, DA7218_NO_INVERT), 163562306a36Sopenharmony_ci SND_SOC_DAPM_AIF_IN("DAIIN", "Playback", 0, SND_SOC_NOPM, 0, 0), 163662306a36Sopenharmony_ci 163762306a36Sopenharmony_ci /* Output Mixers */ 163862306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("Mixer Out FilterL", SND_SOC_NOPM, 0, 0, 163962306a36Sopenharmony_ci da7218_out_filtl_mix_controls, 164062306a36Sopenharmony_ci ARRAY_SIZE(da7218_out_filtl_mix_controls)), 164162306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("Mixer Out FilterR", SND_SOC_NOPM, 0, 0, 164262306a36Sopenharmony_ci da7218_out_filtr_mix_controls, 164362306a36Sopenharmony_ci ARRAY_SIZE(da7218_out_filtr_mix_controls)), 164462306a36Sopenharmony_ci 164562306a36Sopenharmony_ci /* BiQuad Filters */ 164662306a36Sopenharmony_ci SND_SOC_DAPM_MUX("Out FilterL BiQuad Mux", SND_SOC_NOPM, 0, 0, 164762306a36Sopenharmony_ci &da7218_out_filtl_biq_sel_mux), 164862306a36Sopenharmony_ci SND_SOC_DAPM_MUX("Out FilterR BiQuad Mux", SND_SOC_NOPM, 0, 0, 164962306a36Sopenharmony_ci &da7218_out_filtr_biq_sel_mux), 165062306a36Sopenharmony_ci SND_SOC_DAPM_DAC("BiQuad Filter", NULL, DA7218_OUT_1_BIQ_5STAGE_CTRL, 165162306a36Sopenharmony_ci DA7218_OUT_1_BIQ_5STAGE_FILTER_EN_SHIFT, 165262306a36Sopenharmony_ci DA7218_NO_INVERT), 165362306a36Sopenharmony_ci 165462306a36Sopenharmony_ci /* Sidetone Mixers */ 165562306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("ST Mixer Out FilterL", SND_SOC_NOPM, 0, 0, 165662306a36Sopenharmony_ci da7218_st_out_filtl_mix_controls, 165762306a36Sopenharmony_ci ARRAY_SIZE(da7218_st_out_filtl_mix_controls)), 165862306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("ST Mixer Out FilterR", SND_SOC_NOPM, 0, 0, 165962306a36Sopenharmony_ci da7218_st_out_filtr_mix_controls, 166062306a36Sopenharmony_ci ARRAY_SIZE(da7218_st_out_filtr_mix_controls)), 166162306a36Sopenharmony_ci 166262306a36Sopenharmony_ci /* Output Filters */ 166362306a36Sopenharmony_ci SND_SOC_DAPM_DAC("Out FilterL", NULL, DA7218_OUT_1L_FILTER_CTRL, 166462306a36Sopenharmony_ci DA7218_OUT_1L_FILTER_EN_SHIFT, DA7218_NO_INVERT), 166562306a36Sopenharmony_ci SND_SOC_DAPM_DAC("Out FilterR", NULL, DA7218_OUT_1R_FILTER_CTRL, 166662306a36Sopenharmony_ci DA7218_IN_1R_FILTER_EN_SHIFT, DA7218_NO_INVERT), 166762306a36Sopenharmony_ci 166862306a36Sopenharmony_ci /* Output PGAs */ 166962306a36Sopenharmony_ci SND_SOC_DAPM_PGA("Mixout Left PGA", DA7218_MIXOUT_L_CTRL, 167062306a36Sopenharmony_ci DA7218_MIXOUT_L_AMP_EN_SHIFT, DA7218_NO_INVERT, 167162306a36Sopenharmony_ci NULL, 0), 167262306a36Sopenharmony_ci SND_SOC_DAPM_PGA("Mixout Right PGA", DA7218_MIXOUT_R_CTRL, 167362306a36Sopenharmony_ci DA7218_MIXOUT_R_AMP_EN_SHIFT, DA7218_NO_INVERT, 167462306a36Sopenharmony_ci NULL, 0), 167562306a36Sopenharmony_ci SND_SOC_DAPM_PGA_E("Headphone Left PGA", DA7218_HP_L_CTRL, 167662306a36Sopenharmony_ci DA7218_HP_L_AMP_EN_SHIFT, DA7218_NO_INVERT, NULL, 0, 167762306a36Sopenharmony_ci da7218_hp_pga_event, 167862306a36Sopenharmony_ci SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 167962306a36Sopenharmony_ci SND_SOC_DAPM_PGA_E("Headphone Right PGA", DA7218_HP_R_CTRL, 168062306a36Sopenharmony_ci DA7218_HP_R_AMP_EN_SHIFT, DA7218_NO_INVERT, NULL, 0, 168162306a36Sopenharmony_ci da7218_hp_pga_event, 168262306a36Sopenharmony_ci SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 168362306a36Sopenharmony_ci 168462306a36Sopenharmony_ci /* Output Supplies */ 168562306a36Sopenharmony_ci SND_SOC_DAPM_SUPPLY("Charge Pump", SND_SOC_NOPM, 0, 0, da7218_cp_event, 168662306a36Sopenharmony_ci SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), 168762306a36Sopenharmony_ci 168862306a36Sopenharmony_ci /* Outputs */ 168962306a36Sopenharmony_ci SND_SOC_DAPM_OUTPUT("HPL"), 169062306a36Sopenharmony_ci SND_SOC_DAPM_OUTPUT("HPR"), 169162306a36Sopenharmony_ci}; 169262306a36Sopenharmony_ci 169362306a36Sopenharmony_ci 169462306a36Sopenharmony_ci/* 169562306a36Sopenharmony_ci * DAPM Mixer Routes 169662306a36Sopenharmony_ci */ 169762306a36Sopenharmony_ci 169862306a36Sopenharmony_ci#define DA7218_DMIX_ROUTES(name) \ 169962306a36Sopenharmony_ci {name, "In Filter1L Switch", "In Filter1L"}, \ 170062306a36Sopenharmony_ci {name, "In Filter1R Switch", "In Filter1R"}, \ 170162306a36Sopenharmony_ci {name, "In Filter2L Switch", "In Filter2L"}, \ 170262306a36Sopenharmony_ci {name, "In Filter2R Switch", "In Filter2R"}, \ 170362306a36Sopenharmony_ci {name, "ToneGen Switch", "Tone Generator"}, \ 170462306a36Sopenharmony_ci {name, "DAIL Switch", "DAIIN"}, \ 170562306a36Sopenharmony_ci {name, "DAIR Switch", "DAIIN"} 170662306a36Sopenharmony_ci 170762306a36Sopenharmony_ci#define DA7218_DMIX_ST_ROUTES(name) \ 170862306a36Sopenharmony_ci {name, "Out FilterL Switch", "Out FilterL BiQuad Mux"}, \ 170962306a36Sopenharmony_ci {name, "Out FilterR Switch", "Out FilterR BiQuad Mux"}, \ 171062306a36Sopenharmony_ci {name, "Sidetone Switch", "Sidetone Filter"} 171162306a36Sopenharmony_ci 171262306a36Sopenharmony_ci 171362306a36Sopenharmony_ci/* 171462306a36Sopenharmony_ci * DAPM audio route definition 171562306a36Sopenharmony_ci */ 171662306a36Sopenharmony_ci 171762306a36Sopenharmony_cistatic const struct snd_soc_dapm_route da7218_audio_map[] = { 171862306a36Sopenharmony_ci /* Input paths */ 171962306a36Sopenharmony_ci {"MIC1", NULL, "Mic Bias1"}, 172062306a36Sopenharmony_ci {"MIC2", NULL, "Mic Bias2"}, 172162306a36Sopenharmony_ci {"DMIC1L", NULL, "Mic Bias1"}, 172262306a36Sopenharmony_ci {"DMIC1L", NULL, "DMic1 Left"}, 172362306a36Sopenharmony_ci {"DMIC1R", NULL, "Mic Bias1"}, 172462306a36Sopenharmony_ci {"DMIC1R", NULL, "DMic1 Right"}, 172562306a36Sopenharmony_ci {"DMIC2L", NULL, "Mic Bias2"}, 172662306a36Sopenharmony_ci {"DMIC2L", NULL, "DMic2 Left"}, 172762306a36Sopenharmony_ci {"DMIC2R", NULL, "Mic Bias2"}, 172862306a36Sopenharmony_ci {"DMIC2R", NULL, "DMic2 Right"}, 172962306a36Sopenharmony_ci 173062306a36Sopenharmony_ci {"Mic1 PGA", NULL, "MIC1"}, 173162306a36Sopenharmony_ci {"Mic2 PGA", NULL, "MIC2"}, 173262306a36Sopenharmony_ci 173362306a36Sopenharmony_ci {"Mixin1 PGA", NULL, "Mixin1 Supply"}, 173462306a36Sopenharmony_ci {"Mixin2 PGA", NULL, "Mixin2 Supply"}, 173562306a36Sopenharmony_ci 173662306a36Sopenharmony_ci {"Mixin1 PGA", NULL, "Mic1 PGA"}, 173762306a36Sopenharmony_ci {"Mixin2 PGA", NULL, "Mic2 PGA"}, 173862306a36Sopenharmony_ci 173962306a36Sopenharmony_ci {"Mic1 Mux", "Analog", "Mixin1 PGA"}, 174062306a36Sopenharmony_ci {"Mic1 Mux", "Digital", "DMIC1L"}, 174162306a36Sopenharmony_ci {"Mic1 Mux", "Digital", "DMIC1R"}, 174262306a36Sopenharmony_ci {"Mic2 Mux", "Analog", "Mixin2 PGA"}, 174362306a36Sopenharmony_ci {"Mic2 Mux", "Digital", "DMIC2L"}, 174462306a36Sopenharmony_ci {"Mic2 Mux", "Digital", "DMIC2R"}, 174562306a36Sopenharmony_ci 174662306a36Sopenharmony_ci {"In Filter1L", NULL, "Mic1 Mux"}, 174762306a36Sopenharmony_ci {"In Filter1R", NULL, "Mic1 Mux"}, 174862306a36Sopenharmony_ci {"In Filter2L", NULL, "Mic2 Mux"}, 174962306a36Sopenharmony_ci {"In Filter2R", NULL, "Mic2 Mux"}, 175062306a36Sopenharmony_ci 175162306a36Sopenharmony_ci {"Tone Generator", NULL, "TONE"}, 175262306a36Sopenharmony_ci 175362306a36Sopenharmony_ci {"Sidetone Mux", "In Filter1L", "In Filter1L"}, 175462306a36Sopenharmony_ci {"Sidetone Mux", "In Filter1R", "In Filter1R"}, 175562306a36Sopenharmony_ci {"Sidetone Mux", "In Filter2L", "In Filter2L"}, 175662306a36Sopenharmony_ci {"Sidetone Mux", "In Filter2R", "In Filter2R"}, 175762306a36Sopenharmony_ci {"Sidetone Filter", NULL, "Sidetone Mux"}, 175862306a36Sopenharmony_ci 175962306a36Sopenharmony_ci DA7218_DMIX_ROUTES("Mixer DAI1L"), 176062306a36Sopenharmony_ci DA7218_DMIX_ROUTES("Mixer DAI1R"), 176162306a36Sopenharmony_ci DA7218_DMIX_ROUTES("Mixer DAI2L"), 176262306a36Sopenharmony_ci DA7218_DMIX_ROUTES("Mixer DAI2R"), 176362306a36Sopenharmony_ci 176462306a36Sopenharmony_ci {"DAIOUT", NULL, "Mixer DAI1L"}, 176562306a36Sopenharmony_ci {"DAIOUT", NULL, "Mixer DAI1R"}, 176662306a36Sopenharmony_ci {"DAIOUT", NULL, "Mixer DAI2L"}, 176762306a36Sopenharmony_ci {"DAIOUT", NULL, "Mixer DAI2R"}, 176862306a36Sopenharmony_ci 176962306a36Sopenharmony_ci {"DAIOUT", NULL, "DAI"}, 177062306a36Sopenharmony_ci 177162306a36Sopenharmony_ci /* Output paths */ 177262306a36Sopenharmony_ci {"DAIIN", NULL, "DAI"}, 177362306a36Sopenharmony_ci 177462306a36Sopenharmony_ci DA7218_DMIX_ROUTES("Mixer Out FilterL"), 177562306a36Sopenharmony_ci DA7218_DMIX_ROUTES("Mixer Out FilterR"), 177662306a36Sopenharmony_ci 177762306a36Sopenharmony_ci {"BiQuad Filter", NULL, "Mixer Out FilterL"}, 177862306a36Sopenharmony_ci {"BiQuad Filter", NULL, "Mixer Out FilterR"}, 177962306a36Sopenharmony_ci 178062306a36Sopenharmony_ci {"Out FilterL BiQuad Mux", "Bypass", "Mixer Out FilterL"}, 178162306a36Sopenharmony_ci {"Out FilterL BiQuad Mux", "Enabled", "BiQuad Filter"}, 178262306a36Sopenharmony_ci {"Out FilterR BiQuad Mux", "Bypass", "Mixer Out FilterR"}, 178362306a36Sopenharmony_ci {"Out FilterR BiQuad Mux", "Enabled", "BiQuad Filter"}, 178462306a36Sopenharmony_ci 178562306a36Sopenharmony_ci DA7218_DMIX_ST_ROUTES("ST Mixer Out FilterL"), 178662306a36Sopenharmony_ci DA7218_DMIX_ST_ROUTES("ST Mixer Out FilterR"), 178762306a36Sopenharmony_ci 178862306a36Sopenharmony_ci {"Out FilterL", NULL, "ST Mixer Out FilterL"}, 178962306a36Sopenharmony_ci {"Out FilterR", NULL, "ST Mixer Out FilterR"}, 179062306a36Sopenharmony_ci 179162306a36Sopenharmony_ci {"Mixout Left PGA", NULL, "Out FilterL"}, 179262306a36Sopenharmony_ci {"Mixout Right PGA", NULL, "Out FilterR"}, 179362306a36Sopenharmony_ci 179462306a36Sopenharmony_ci {"Headphone Left PGA", NULL, "Mixout Left PGA"}, 179562306a36Sopenharmony_ci {"Headphone Right PGA", NULL, "Mixout Right PGA"}, 179662306a36Sopenharmony_ci 179762306a36Sopenharmony_ci {"HPL", NULL, "Headphone Left PGA"}, 179862306a36Sopenharmony_ci {"HPR", NULL, "Headphone Right PGA"}, 179962306a36Sopenharmony_ci 180062306a36Sopenharmony_ci {"HPL", NULL, "Charge Pump"}, 180162306a36Sopenharmony_ci {"HPR", NULL, "Charge Pump"}, 180262306a36Sopenharmony_ci}; 180362306a36Sopenharmony_ci 180462306a36Sopenharmony_ci 180562306a36Sopenharmony_ci/* 180662306a36Sopenharmony_ci * DAI operations 180762306a36Sopenharmony_ci */ 180862306a36Sopenharmony_ci 180962306a36Sopenharmony_cistatic int da7218_set_dai_sysclk(struct snd_soc_dai *codec_dai, 181062306a36Sopenharmony_ci int clk_id, unsigned int freq, int dir) 181162306a36Sopenharmony_ci{ 181262306a36Sopenharmony_ci struct snd_soc_component *component = codec_dai->component; 181362306a36Sopenharmony_ci struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component); 181462306a36Sopenharmony_ci int ret; 181562306a36Sopenharmony_ci 181662306a36Sopenharmony_ci if (da7218->mclk_rate == freq) 181762306a36Sopenharmony_ci return 0; 181862306a36Sopenharmony_ci 181962306a36Sopenharmony_ci if ((freq < 2000000) || (freq > 54000000)) { 182062306a36Sopenharmony_ci dev_err(codec_dai->dev, "Unsupported MCLK value %d\n", 182162306a36Sopenharmony_ci freq); 182262306a36Sopenharmony_ci return -EINVAL; 182362306a36Sopenharmony_ci } 182462306a36Sopenharmony_ci 182562306a36Sopenharmony_ci switch (clk_id) { 182662306a36Sopenharmony_ci case DA7218_CLKSRC_MCLK_SQR: 182762306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_PLL_CTRL, 182862306a36Sopenharmony_ci DA7218_PLL_MCLK_SQR_EN_MASK, 182962306a36Sopenharmony_ci DA7218_PLL_MCLK_SQR_EN_MASK); 183062306a36Sopenharmony_ci break; 183162306a36Sopenharmony_ci case DA7218_CLKSRC_MCLK: 183262306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_PLL_CTRL, 183362306a36Sopenharmony_ci DA7218_PLL_MCLK_SQR_EN_MASK, 0); 183462306a36Sopenharmony_ci break; 183562306a36Sopenharmony_ci default: 183662306a36Sopenharmony_ci dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id); 183762306a36Sopenharmony_ci return -EINVAL; 183862306a36Sopenharmony_ci } 183962306a36Sopenharmony_ci 184062306a36Sopenharmony_ci if (da7218->mclk) { 184162306a36Sopenharmony_ci freq = clk_round_rate(da7218->mclk, freq); 184262306a36Sopenharmony_ci ret = clk_set_rate(da7218->mclk, freq); 184362306a36Sopenharmony_ci if (ret) { 184462306a36Sopenharmony_ci dev_err(codec_dai->dev, "Failed to set clock rate %d\n", 184562306a36Sopenharmony_ci freq); 184662306a36Sopenharmony_ci return ret; 184762306a36Sopenharmony_ci } 184862306a36Sopenharmony_ci } 184962306a36Sopenharmony_ci 185062306a36Sopenharmony_ci da7218->mclk_rate = freq; 185162306a36Sopenharmony_ci 185262306a36Sopenharmony_ci return 0; 185362306a36Sopenharmony_ci} 185462306a36Sopenharmony_ci 185562306a36Sopenharmony_cistatic int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, 185662306a36Sopenharmony_ci int source, unsigned int fref, unsigned int fout) 185762306a36Sopenharmony_ci{ 185862306a36Sopenharmony_ci struct snd_soc_component *component = codec_dai->component; 185962306a36Sopenharmony_ci struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component); 186062306a36Sopenharmony_ci 186162306a36Sopenharmony_ci u8 pll_ctrl, indiv_bits, indiv; 186262306a36Sopenharmony_ci u8 pll_frac_top, pll_frac_bot, pll_integer; 186362306a36Sopenharmony_ci u32 freq_ref; 186462306a36Sopenharmony_ci u64 frac_div; 186562306a36Sopenharmony_ci 186662306a36Sopenharmony_ci /* Verify 2MHz - 54MHz MCLK provided, and set input divider */ 186762306a36Sopenharmony_ci if (da7218->mclk_rate < 2000000) { 186862306a36Sopenharmony_ci dev_err(component->dev, "PLL input clock %d below valid range\n", 186962306a36Sopenharmony_ci da7218->mclk_rate); 187062306a36Sopenharmony_ci return -EINVAL; 187162306a36Sopenharmony_ci } else if (da7218->mclk_rate <= 4500000) { 187262306a36Sopenharmony_ci indiv_bits = DA7218_PLL_INDIV_2_TO_4_5_MHZ; 187362306a36Sopenharmony_ci indiv = DA7218_PLL_INDIV_2_TO_4_5_MHZ_VAL; 187462306a36Sopenharmony_ci } else if (da7218->mclk_rate <= 9000000) { 187562306a36Sopenharmony_ci indiv_bits = DA7218_PLL_INDIV_4_5_TO_9_MHZ; 187662306a36Sopenharmony_ci indiv = DA7218_PLL_INDIV_4_5_TO_9_MHZ_VAL; 187762306a36Sopenharmony_ci } else if (da7218->mclk_rate <= 18000000) { 187862306a36Sopenharmony_ci indiv_bits = DA7218_PLL_INDIV_9_TO_18_MHZ; 187962306a36Sopenharmony_ci indiv = DA7218_PLL_INDIV_9_TO_18_MHZ_VAL; 188062306a36Sopenharmony_ci } else if (da7218->mclk_rate <= 36000000) { 188162306a36Sopenharmony_ci indiv_bits = DA7218_PLL_INDIV_18_TO_36_MHZ; 188262306a36Sopenharmony_ci indiv = DA7218_PLL_INDIV_18_TO_36_MHZ_VAL; 188362306a36Sopenharmony_ci } else if (da7218->mclk_rate <= 54000000) { 188462306a36Sopenharmony_ci indiv_bits = DA7218_PLL_INDIV_36_TO_54_MHZ; 188562306a36Sopenharmony_ci indiv = DA7218_PLL_INDIV_36_TO_54_MHZ_VAL; 188662306a36Sopenharmony_ci } else { 188762306a36Sopenharmony_ci dev_err(component->dev, "PLL input clock %d above valid range\n", 188862306a36Sopenharmony_ci da7218->mclk_rate); 188962306a36Sopenharmony_ci return -EINVAL; 189062306a36Sopenharmony_ci } 189162306a36Sopenharmony_ci freq_ref = (da7218->mclk_rate / indiv); 189262306a36Sopenharmony_ci pll_ctrl = indiv_bits; 189362306a36Sopenharmony_ci 189462306a36Sopenharmony_ci /* Configure PLL */ 189562306a36Sopenharmony_ci switch (source) { 189662306a36Sopenharmony_ci case DA7218_SYSCLK_MCLK: 189762306a36Sopenharmony_ci pll_ctrl |= DA7218_PLL_MODE_BYPASS; 189862306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_PLL_CTRL, 189962306a36Sopenharmony_ci DA7218_PLL_INDIV_MASK | 190062306a36Sopenharmony_ci DA7218_PLL_MODE_MASK, pll_ctrl); 190162306a36Sopenharmony_ci return 0; 190262306a36Sopenharmony_ci case DA7218_SYSCLK_PLL: 190362306a36Sopenharmony_ci pll_ctrl |= DA7218_PLL_MODE_NORMAL; 190462306a36Sopenharmony_ci break; 190562306a36Sopenharmony_ci case DA7218_SYSCLK_PLL_SRM: 190662306a36Sopenharmony_ci pll_ctrl |= DA7218_PLL_MODE_SRM; 190762306a36Sopenharmony_ci break; 190862306a36Sopenharmony_ci default: 190962306a36Sopenharmony_ci dev_err(component->dev, "Invalid PLL config\n"); 191062306a36Sopenharmony_ci return -EINVAL; 191162306a36Sopenharmony_ci } 191262306a36Sopenharmony_ci 191362306a36Sopenharmony_ci /* Calculate dividers for PLL */ 191462306a36Sopenharmony_ci pll_integer = fout / freq_ref; 191562306a36Sopenharmony_ci frac_div = (u64)(fout % freq_ref) * 8192ULL; 191662306a36Sopenharmony_ci do_div(frac_div, freq_ref); 191762306a36Sopenharmony_ci pll_frac_top = (frac_div >> DA7218_BYTE_SHIFT) & DA7218_BYTE_MASK; 191862306a36Sopenharmony_ci pll_frac_bot = (frac_div) & DA7218_BYTE_MASK; 191962306a36Sopenharmony_ci 192062306a36Sopenharmony_ci /* Write PLL config & dividers */ 192162306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_PLL_FRAC_TOP, pll_frac_top); 192262306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_PLL_FRAC_BOT, pll_frac_bot); 192362306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_PLL_INTEGER, pll_integer); 192462306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_PLL_CTRL, 192562306a36Sopenharmony_ci DA7218_PLL_MODE_MASK | DA7218_PLL_INDIV_MASK, 192662306a36Sopenharmony_ci pll_ctrl); 192762306a36Sopenharmony_ci 192862306a36Sopenharmony_ci return 0; 192962306a36Sopenharmony_ci} 193062306a36Sopenharmony_ci 193162306a36Sopenharmony_cistatic int da7218_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) 193262306a36Sopenharmony_ci{ 193362306a36Sopenharmony_ci struct snd_soc_component *component = codec_dai->component; 193462306a36Sopenharmony_ci struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component); 193562306a36Sopenharmony_ci u8 dai_clk_mode = 0, dai_ctrl = 0; 193662306a36Sopenharmony_ci 193762306a36Sopenharmony_ci switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 193862306a36Sopenharmony_ci case SND_SOC_DAIFMT_CBM_CFM: 193962306a36Sopenharmony_ci da7218->master = true; 194062306a36Sopenharmony_ci break; 194162306a36Sopenharmony_ci case SND_SOC_DAIFMT_CBS_CFS: 194262306a36Sopenharmony_ci da7218->master = false; 194362306a36Sopenharmony_ci break; 194462306a36Sopenharmony_ci default: 194562306a36Sopenharmony_ci return -EINVAL; 194662306a36Sopenharmony_ci } 194762306a36Sopenharmony_ci 194862306a36Sopenharmony_ci switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 194962306a36Sopenharmony_ci case SND_SOC_DAIFMT_I2S: 195062306a36Sopenharmony_ci case SND_SOC_DAIFMT_LEFT_J: 195162306a36Sopenharmony_ci case SND_SOC_DAIFMT_RIGHT_J: 195262306a36Sopenharmony_ci switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 195362306a36Sopenharmony_ci case SND_SOC_DAIFMT_NB_NF: 195462306a36Sopenharmony_ci break; 195562306a36Sopenharmony_ci case SND_SOC_DAIFMT_NB_IF: 195662306a36Sopenharmony_ci dai_clk_mode |= DA7218_DAI_WCLK_POL_INV; 195762306a36Sopenharmony_ci break; 195862306a36Sopenharmony_ci case SND_SOC_DAIFMT_IB_NF: 195962306a36Sopenharmony_ci dai_clk_mode |= DA7218_DAI_CLK_POL_INV; 196062306a36Sopenharmony_ci break; 196162306a36Sopenharmony_ci case SND_SOC_DAIFMT_IB_IF: 196262306a36Sopenharmony_ci dai_clk_mode |= DA7218_DAI_WCLK_POL_INV | 196362306a36Sopenharmony_ci DA7218_DAI_CLK_POL_INV; 196462306a36Sopenharmony_ci break; 196562306a36Sopenharmony_ci default: 196662306a36Sopenharmony_ci return -EINVAL; 196762306a36Sopenharmony_ci } 196862306a36Sopenharmony_ci break; 196962306a36Sopenharmony_ci case SND_SOC_DAIFMT_DSP_B: 197062306a36Sopenharmony_ci switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 197162306a36Sopenharmony_ci case SND_SOC_DAIFMT_NB_NF: 197262306a36Sopenharmony_ci dai_clk_mode |= DA7218_DAI_CLK_POL_INV; 197362306a36Sopenharmony_ci break; 197462306a36Sopenharmony_ci case SND_SOC_DAIFMT_NB_IF: 197562306a36Sopenharmony_ci dai_clk_mode |= DA7218_DAI_WCLK_POL_INV | 197662306a36Sopenharmony_ci DA7218_DAI_CLK_POL_INV; 197762306a36Sopenharmony_ci break; 197862306a36Sopenharmony_ci case SND_SOC_DAIFMT_IB_NF: 197962306a36Sopenharmony_ci break; 198062306a36Sopenharmony_ci case SND_SOC_DAIFMT_IB_IF: 198162306a36Sopenharmony_ci dai_clk_mode |= DA7218_DAI_WCLK_POL_INV; 198262306a36Sopenharmony_ci break; 198362306a36Sopenharmony_ci default: 198462306a36Sopenharmony_ci return -EINVAL; 198562306a36Sopenharmony_ci } 198662306a36Sopenharmony_ci break; 198762306a36Sopenharmony_ci default: 198862306a36Sopenharmony_ci return -EINVAL; 198962306a36Sopenharmony_ci } 199062306a36Sopenharmony_ci 199162306a36Sopenharmony_ci switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 199262306a36Sopenharmony_ci case SND_SOC_DAIFMT_I2S: 199362306a36Sopenharmony_ci dai_ctrl |= DA7218_DAI_FORMAT_I2S; 199462306a36Sopenharmony_ci break; 199562306a36Sopenharmony_ci case SND_SOC_DAIFMT_LEFT_J: 199662306a36Sopenharmony_ci dai_ctrl |= DA7218_DAI_FORMAT_LEFT_J; 199762306a36Sopenharmony_ci break; 199862306a36Sopenharmony_ci case SND_SOC_DAIFMT_RIGHT_J: 199962306a36Sopenharmony_ci dai_ctrl |= DA7218_DAI_FORMAT_RIGHT_J; 200062306a36Sopenharmony_ci break; 200162306a36Sopenharmony_ci case SND_SOC_DAIFMT_DSP_B: 200262306a36Sopenharmony_ci dai_ctrl |= DA7218_DAI_FORMAT_DSP; 200362306a36Sopenharmony_ci break; 200462306a36Sopenharmony_ci default: 200562306a36Sopenharmony_ci return -EINVAL; 200662306a36Sopenharmony_ci } 200762306a36Sopenharmony_ci 200862306a36Sopenharmony_ci /* By default 64 BCLKs per WCLK is supported */ 200962306a36Sopenharmony_ci dai_clk_mode |= DA7218_DAI_BCLKS_PER_WCLK_64; 201062306a36Sopenharmony_ci 201162306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_DAI_CLK_MODE, dai_clk_mode); 201262306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_DAI_CTRL, DA7218_DAI_FORMAT_MASK, 201362306a36Sopenharmony_ci dai_ctrl); 201462306a36Sopenharmony_ci 201562306a36Sopenharmony_ci return 0; 201662306a36Sopenharmony_ci} 201762306a36Sopenharmony_ci 201862306a36Sopenharmony_cistatic int da7218_set_dai_tdm_slot(struct snd_soc_dai *dai, 201962306a36Sopenharmony_ci unsigned int tx_mask, unsigned int rx_mask, 202062306a36Sopenharmony_ci int slots, int slot_width) 202162306a36Sopenharmony_ci{ 202262306a36Sopenharmony_ci struct snd_soc_component *component = dai->component; 202362306a36Sopenharmony_ci u8 dai_bclks_per_wclk; 202462306a36Sopenharmony_ci u32 frame_size; 202562306a36Sopenharmony_ci 202662306a36Sopenharmony_ci /* No channels enabled so disable TDM, revert to 64-bit frames */ 202762306a36Sopenharmony_ci if (!tx_mask) { 202862306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_DAI_TDM_CTRL, 202962306a36Sopenharmony_ci DA7218_DAI_TDM_CH_EN_MASK | 203062306a36Sopenharmony_ci DA7218_DAI_TDM_MODE_EN_MASK, 0); 203162306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_DAI_CLK_MODE, 203262306a36Sopenharmony_ci DA7218_DAI_BCLKS_PER_WCLK_MASK, 203362306a36Sopenharmony_ci DA7218_DAI_BCLKS_PER_WCLK_64); 203462306a36Sopenharmony_ci return 0; 203562306a36Sopenharmony_ci } 203662306a36Sopenharmony_ci 203762306a36Sopenharmony_ci /* Check we have valid slots */ 203862306a36Sopenharmony_ci if (fls(tx_mask) > DA7218_DAI_TDM_MAX_SLOTS) { 203962306a36Sopenharmony_ci dev_err(component->dev, "Invalid number of slots, max = %d\n", 204062306a36Sopenharmony_ci DA7218_DAI_TDM_MAX_SLOTS); 204162306a36Sopenharmony_ci return -EINVAL; 204262306a36Sopenharmony_ci } 204362306a36Sopenharmony_ci 204462306a36Sopenharmony_ci /* Check we have a valid offset given (first 2 bytes of rx_mask) */ 204562306a36Sopenharmony_ci if (rx_mask >> DA7218_2BYTE_SHIFT) { 204662306a36Sopenharmony_ci dev_err(component->dev, "Invalid slot offset, max = %d\n", 204762306a36Sopenharmony_ci DA7218_2BYTE_MASK); 204862306a36Sopenharmony_ci return -EINVAL; 204962306a36Sopenharmony_ci } 205062306a36Sopenharmony_ci 205162306a36Sopenharmony_ci /* Calculate & validate frame size based on slot info provided. */ 205262306a36Sopenharmony_ci frame_size = slots * slot_width; 205362306a36Sopenharmony_ci switch (frame_size) { 205462306a36Sopenharmony_ci case 32: 205562306a36Sopenharmony_ci dai_bclks_per_wclk = DA7218_DAI_BCLKS_PER_WCLK_32; 205662306a36Sopenharmony_ci break; 205762306a36Sopenharmony_ci case 64: 205862306a36Sopenharmony_ci dai_bclks_per_wclk = DA7218_DAI_BCLKS_PER_WCLK_64; 205962306a36Sopenharmony_ci break; 206062306a36Sopenharmony_ci case 128: 206162306a36Sopenharmony_ci dai_bclks_per_wclk = DA7218_DAI_BCLKS_PER_WCLK_128; 206262306a36Sopenharmony_ci break; 206362306a36Sopenharmony_ci case 256: 206462306a36Sopenharmony_ci dai_bclks_per_wclk = DA7218_DAI_BCLKS_PER_WCLK_256; 206562306a36Sopenharmony_ci break; 206662306a36Sopenharmony_ci default: 206762306a36Sopenharmony_ci dev_err(component->dev, "Invalid frame size\n"); 206862306a36Sopenharmony_ci return -EINVAL; 206962306a36Sopenharmony_ci } 207062306a36Sopenharmony_ci 207162306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_DAI_CLK_MODE, 207262306a36Sopenharmony_ci DA7218_DAI_BCLKS_PER_WCLK_MASK, 207362306a36Sopenharmony_ci dai_bclks_per_wclk); 207462306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_DAI_OFFSET_LOWER, 207562306a36Sopenharmony_ci (rx_mask & DA7218_BYTE_MASK)); 207662306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_DAI_OFFSET_UPPER, 207762306a36Sopenharmony_ci ((rx_mask >> DA7218_BYTE_SHIFT) & DA7218_BYTE_MASK)); 207862306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_DAI_TDM_CTRL, 207962306a36Sopenharmony_ci DA7218_DAI_TDM_CH_EN_MASK | 208062306a36Sopenharmony_ci DA7218_DAI_TDM_MODE_EN_MASK, 208162306a36Sopenharmony_ci (tx_mask << DA7218_DAI_TDM_CH_EN_SHIFT) | 208262306a36Sopenharmony_ci DA7218_DAI_TDM_MODE_EN_MASK); 208362306a36Sopenharmony_ci 208462306a36Sopenharmony_ci return 0; 208562306a36Sopenharmony_ci} 208662306a36Sopenharmony_ci 208762306a36Sopenharmony_cistatic int da7218_hw_params(struct snd_pcm_substream *substream, 208862306a36Sopenharmony_ci struct snd_pcm_hw_params *params, 208962306a36Sopenharmony_ci struct snd_soc_dai *dai) 209062306a36Sopenharmony_ci{ 209162306a36Sopenharmony_ci struct snd_soc_component *component = dai->component; 209262306a36Sopenharmony_ci u8 dai_ctrl = 0, fs; 209362306a36Sopenharmony_ci unsigned int channels; 209462306a36Sopenharmony_ci 209562306a36Sopenharmony_ci switch (params_width(params)) { 209662306a36Sopenharmony_ci case 16: 209762306a36Sopenharmony_ci dai_ctrl |= DA7218_DAI_WORD_LENGTH_S16_LE; 209862306a36Sopenharmony_ci break; 209962306a36Sopenharmony_ci case 20: 210062306a36Sopenharmony_ci dai_ctrl |= DA7218_DAI_WORD_LENGTH_S20_LE; 210162306a36Sopenharmony_ci break; 210262306a36Sopenharmony_ci case 24: 210362306a36Sopenharmony_ci dai_ctrl |= DA7218_DAI_WORD_LENGTH_S24_LE; 210462306a36Sopenharmony_ci break; 210562306a36Sopenharmony_ci case 32: 210662306a36Sopenharmony_ci dai_ctrl |= DA7218_DAI_WORD_LENGTH_S32_LE; 210762306a36Sopenharmony_ci break; 210862306a36Sopenharmony_ci default: 210962306a36Sopenharmony_ci return -EINVAL; 211062306a36Sopenharmony_ci } 211162306a36Sopenharmony_ci 211262306a36Sopenharmony_ci channels = params_channels(params); 211362306a36Sopenharmony_ci if ((channels < 1) || (channels > DA7218_DAI_CH_NUM_MAX)) { 211462306a36Sopenharmony_ci dev_err(component->dev, 211562306a36Sopenharmony_ci "Invalid number of channels, only 1 to %d supported\n", 211662306a36Sopenharmony_ci DA7218_DAI_CH_NUM_MAX); 211762306a36Sopenharmony_ci return -EINVAL; 211862306a36Sopenharmony_ci } 211962306a36Sopenharmony_ci dai_ctrl |= channels << DA7218_DAI_CH_NUM_SHIFT; 212062306a36Sopenharmony_ci 212162306a36Sopenharmony_ci switch (params_rate(params)) { 212262306a36Sopenharmony_ci case 8000: 212362306a36Sopenharmony_ci fs = DA7218_SR_8000; 212462306a36Sopenharmony_ci break; 212562306a36Sopenharmony_ci case 11025: 212662306a36Sopenharmony_ci fs = DA7218_SR_11025; 212762306a36Sopenharmony_ci break; 212862306a36Sopenharmony_ci case 12000: 212962306a36Sopenharmony_ci fs = DA7218_SR_12000; 213062306a36Sopenharmony_ci break; 213162306a36Sopenharmony_ci case 16000: 213262306a36Sopenharmony_ci fs = DA7218_SR_16000; 213362306a36Sopenharmony_ci break; 213462306a36Sopenharmony_ci case 22050: 213562306a36Sopenharmony_ci fs = DA7218_SR_22050; 213662306a36Sopenharmony_ci break; 213762306a36Sopenharmony_ci case 24000: 213862306a36Sopenharmony_ci fs = DA7218_SR_24000; 213962306a36Sopenharmony_ci break; 214062306a36Sopenharmony_ci case 32000: 214162306a36Sopenharmony_ci fs = DA7218_SR_32000; 214262306a36Sopenharmony_ci break; 214362306a36Sopenharmony_ci case 44100: 214462306a36Sopenharmony_ci fs = DA7218_SR_44100; 214562306a36Sopenharmony_ci break; 214662306a36Sopenharmony_ci case 48000: 214762306a36Sopenharmony_ci fs = DA7218_SR_48000; 214862306a36Sopenharmony_ci break; 214962306a36Sopenharmony_ci case 88200: 215062306a36Sopenharmony_ci fs = DA7218_SR_88200; 215162306a36Sopenharmony_ci break; 215262306a36Sopenharmony_ci case 96000: 215362306a36Sopenharmony_ci fs = DA7218_SR_96000; 215462306a36Sopenharmony_ci break; 215562306a36Sopenharmony_ci default: 215662306a36Sopenharmony_ci return -EINVAL; 215762306a36Sopenharmony_ci } 215862306a36Sopenharmony_ci 215962306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_DAI_CTRL, 216062306a36Sopenharmony_ci DA7218_DAI_WORD_LENGTH_MASK | DA7218_DAI_CH_NUM_MASK, 216162306a36Sopenharmony_ci dai_ctrl); 216262306a36Sopenharmony_ci /* SRs tied for ADCs and DACs. */ 216362306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_SR, 216462306a36Sopenharmony_ci (fs << DA7218_SR_DAC_SHIFT) | (fs << DA7218_SR_ADC_SHIFT)); 216562306a36Sopenharmony_ci 216662306a36Sopenharmony_ci return 0; 216762306a36Sopenharmony_ci} 216862306a36Sopenharmony_ci 216962306a36Sopenharmony_cistatic const struct snd_soc_dai_ops da7218_dai_ops = { 217062306a36Sopenharmony_ci .hw_params = da7218_hw_params, 217162306a36Sopenharmony_ci .set_sysclk = da7218_set_dai_sysclk, 217262306a36Sopenharmony_ci .set_pll = da7218_set_dai_pll, 217362306a36Sopenharmony_ci .set_fmt = da7218_set_dai_fmt, 217462306a36Sopenharmony_ci .set_tdm_slot = da7218_set_dai_tdm_slot, 217562306a36Sopenharmony_ci}; 217662306a36Sopenharmony_ci 217762306a36Sopenharmony_ci#define DA7218_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 217862306a36Sopenharmony_ci SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 217962306a36Sopenharmony_ci 218062306a36Sopenharmony_cistatic struct snd_soc_dai_driver da7218_dai = { 218162306a36Sopenharmony_ci .name = "da7218-hifi", 218262306a36Sopenharmony_ci .playback = { 218362306a36Sopenharmony_ci .stream_name = "Playback", 218462306a36Sopenharmony_ci .channels_min = 1, 218562306a36Sopenharmony_ci .channels_max = 4, /* Only 2 channels of data */ 218662306a36Sopenharmony_ci .rates = SNDRV_PCM_RATE_8000_96000, 218762306a36Sopenharmony_ci .formats = DA7218_FORMATS, 218862306a36Sopenharmony_ci }, 218962306a36Sopenharmony_ci .capture = { 219062306a36Sopenharmony_ci .stream_name = "Capture", 219162306a36Sopenharmony_ci .channels_min = 1, 219262306a36Sopenharmony_ci .channels_max = 4, 219362306a36Sopenharmony_ci .rates = SNDRV_PCM_RATE_8000_96000, 219462306a36Sopenharmony_ci .formats = DA7218_FORMATS, 219562306a36Sopenharmony_ci }, 219662306a36Sopenharmony_ci .ops = &da7218_dai_ops, 219762306a36Sopenharmony_ci .symmetric_rate = 1, 219862306a36Sopenharmony_ci .symmetric_channels = 1, 219962306a36Sopenharmony_ci .symmetric_sample_bits = 1, 220062306a36Sopenharmony_ci}; 220162306a36Sopenharmony_ci 220262306a36Sopenharmony_ci 220362306a36Sopenharmony_ci/* 220462306a36Sopenharmony_ci * HP Detect 220562306a36Sopenharmony_ci */ 220662306a36Sopenharmony_ci 220762306a36Sopenharmony_ciint da7218_hpldet(struct snd_soc_component *component, struct snd_soc_jack *jack) 220862306a36Sopenharmony_ci{ 220962306a36Sopenharmony_ci struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component); 221062306a36Sopenharmony_ci 221162306a36Sopenharmony_ci if (da7218->dev_id == DA7217_DEV_ID) 221262306a36Sopenharmony_ci return -EINVAL; 221362306a36Sopenharmony_ci 221462306a36Sopenharmony_ci da7218->jack = jack; 221562306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_HPLDET_JACK, 221662306a36Sopenharmony_ci DA7218_HPLDET_JACK_EN_MASK, 221762306a36Sopenharmony_ci jack ? DA7218_HPLDET_JACK_EN_MASK : 0); 221862306a36Sopenharmony_ci 221962306a36Sopenharmony_ci return 0; 222062306a36Sopenharmony_ci} 222162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(da7218_hpldet); 222262306a36Sopenharmony_ci 222362306a36Sopenharmony_cistatic void da7218_micldet_irq(struct snd_soc_component *component) 222462306a36Sopenharmony_ci{ 222562306a36Sopenharmony_ci char *envp[] = { 222662306a36Sopenharmony_ci "EVENT=MIC_LEVEL_DETECT", 222762306a36Sopenharmony_ci NULL, 222862306a36Sopenharmony_ci }; 222962306a36Sopenharmony_ci 223062306a36Sopenharmony_ci kobject_uevent_env(&component->dev->kobj, KOBJ_CHANGE, envp); 223162306a36Sopenharmony_ci} 223262306a36Sopenharmony_ci 223362306a36Sopenharmony_cistatic void da7218_hpldet_irq(struct snd_soc_component *component) 223462306a36Sopenharmony_ci{ 223562306a36Sopenharmony_ci struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component); 223662306a36Sopenharmony_ci u8 jack_status; 223762306a36Sopenharmony_ci int report; 223862306a36Sopenharmony_ci 223962306a36Sopenharmony_ci jack_status = snd_soc_component_read(component, DA7218_EVENT_STATUS); 224062306a36Sopenharmony_ci 224162306a36Sopenharmony_ci if (jack_status & DA7218_HPLDET_JACK_STS_MASK) 224262306a36Sopenharmony_ci report = SND_JACK_HEADPHONE; 224362306a36Sopenharmony_ci else 224462306a36Sopenharmony_ci report = 0; 224562306a36Sopenharmony_ci 224662306a36Sopenharmony_ci snd_soc_jack_report(da7218->jack, report, SND_JACK_HEADPHONE); 224762306a36Sopenharmony_ci} 224862306a36Sopenharmony_ci 224962306a36Sopenharmony_ci/* 225062306a36Sopenharmony_ci * IRQ 225162306a36Sopenharmony_ci */ 225262306a36Sopenharmony_ci 225362306a36Sopenharmony_cistatic irqreturn_t da7218_irq_thread(int irq, void *data) 225462306a36Sopenharmony_ci{ 225562306a36Sopenharmony_ci struct snd_soc_component *component = data; 225662306a36Sopenharmony_ci u8 status; 225762306a36Sopenharmony_ci 225862306a36Sopenharmony_ci /* Read IRQ status reg */ 225962306a36Sopenharmony_ci status = snd_soc_component_read(component, DA7218_EVENT); 226062306a36Sopenharmony_ci if (!status) 226162306a36Sopenharmony_ci return IRQ_NONE; 226262306a36Sopenharmony_ci 226362306a36Sopenharmony_ci /* Mic level detect */ 226462306a36Sopenharmony_ci if (status & DA7218_LVL_DET_EVENT_MASK) 226562306a36Sopenharmony_ci da7218_micldet_irq(component); 226662306a36Sopenharmony_ci 226762306a36Sopenharmony_ci /* HP detect */ 226862306a36Sopenharmony_ci if (status & DA7218_HPLDET_JACK_EVENT_MASK) 226962306a36Sopenharmony_ci da7218_hpldet_irq(component); 227062306a36Sopenharmony_ci 227162306a36Sopenharmony_ci /* Clear interrupts */ 227262306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_EVENT, status); 227362306a36Sopenharmony_ci 227462306a36Sopenharmony_ci return IRQ_HANDLED; 227562306a36Sopenharmony_ci} 227662306a36Sopenharmony_ci 227762306a36Sopenharmony_ci/* 227862306a36Sopenharmony_ci * DT 227962306a36Sopenharmony_ci */ 228062306a36Sopenharmony_ci 228162306a36Sopenharmony_cistatic const struct of_device_id da7218_of_match[] = { 228262306a36Sopenharmony_ci { .compatible = "dlg,da7217", .data = (void *) DA7217_DEV_ID }, 228362306a36Sopenharmony_ci { .compatible = "dlg,da7218", .data = (void *) DA7218_DEV_ID }, 228462306a36Sopenharmony_ci { } 228562306a36Sopenharmony_ci}; 228662306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, da7218_of_match); 228762306a36Sopenharmony_ci 228862306a36Sopenharmony_cistatic inline int da7218_of_get_id(struct device *dev) 228962306a36Sopenharmony_ci{ 229062306a36Sopenharmony_ci const struct of_device_id *id = of_match_device(da7218_of_match, dev); 229162306a36Sopenharmony_ci 229262306a36Sopenharmony_ci if (id) 229362306a36Sopenharmony_ci return (uintptr_t)id->data; 229462306a36Sopenharmony_ci else 229562306a36Sopenharmony_ci return -EINVAL; 229662306a36Sopenharmony_ci} 229762306a36Sopenharmony_ci 229862306a36Sopenharmony_cistatic enum da7218_micbias_voltage 229962306a36Sopenharmony_ci da7218_of_micbias_lvl(struct snd_soc_component *component, u32 val) 230062306a36Sopenharmony_ci{ 230162306a36Sopenharmony_ci switch (val) { 230262306a36Sopenharmony_ci case 1200: 230362306a36Sopenharmony_ci return DA7218_MICBIAS_1_2V; 230462306a36Sopenharmony_ci case 1600: 230562306a36Sopenharmony_ci return DA7218_MICBIAS_1_6V; 230662306a36Sopenharmony_ci case 1800: 230762306a36Sopenharmony_ci return DA7218_MICBIAS_1_8V; 230862306a36Sopenharmony_ci case 2000: 230962306a36Sopenharmony_ci return DA7218_MICBIAS_2_0V; 231062306a36Sopenharmony_ci case 2200: 231162306a36Sopenharmony_ci return DA7218_MICBIAS_2_2V; 231262306a36Sopenharmony_ci case 2400: 231362306a36Sopenharmony_ci return DA7218_MICBIAS_2_4V; 231462306a36Sopenharmony_ci case 2600: 231562306a36Sopenharmony_ci return DA7218_MICBIAS_2_6V; 231662306a36Sopenharmony_ci case 2800: 231762306a36Sopenharmony_ci return DA7218_MICBIAS_2_8V; 231862306a36Sopenharmony_ci case 3000: 231962306a36Sopenharmony_ci return DA7218_MICBIAS_3_0V; 232062306a36Sopenharmony_ci default: 232162306a36Sopenharmony_ci dev_warn(component->dev, "Invalid micbias level"); 232262306a36Sopenharmony_ci return DA7218_MICBIAS_1_6V; 232362306a36Sopenharmony_ci } 232462306a36Sopenharmony_ci} 232562306a36Sopenharmony_ci 232662306a36Sopenharmony_cistatic enum da7218_mic_amp_in_sel 232762306a36Sopenharmony_ci da7218_of_mic_amp_in_sel(struct snd_soc_component *component, const char *str) 232862306a36Sopenharmony_ci{ 232962306a36Sopenharmony_ci if (!strcmp(str, "diff")) { 233062306a36Sopenharmony_ci return DA7218_MIC_AMP_IN_SEL_DIFF; 233162306a36Sopenharmony_ci } else if (!strcmp(str, "se_p")) { 233262306a36Sopenharmony_ci return DA7218_MIC_AMP_IN_SEL_SE_P; 233362306a36Sopenharmony_ci } else if (!strcmp(str, "se_n")) { 233462306a36Sopenharmony_ci return DA7218_MIC_AMP_IN_SEL_SE_N; 233562306a36Sopenharmony_ci } else { 233662306a36Sopenharmony_ci dev_warn(component->dev, "Invalid mic input type selection"); 233762306a36Sopenharmony_ci return DA7218_MIC_AMP_IN_SEL_DIFF; 233862306a36Sopenharmony_ci } 233962306a36Sopenharmony_ci} 234062306a36Sopenharmony_ci 234162306a36Sopenharmony_cistatic enum da7218_dmic_data_sel 234262306a36Sopenharmony_ci da7218_of_dmic_data_sel(struct snd_soc_component *component, const char *str) 234362306a36Sopenharmony_ci{ 234462306a36Sopenharmony_ci if (!strcmp(str, "lrise_rfall")) { 234562306a36Sopenharmony_ci return DA7218_DMIC_DATA_LRISE_RFALL; 234662306a36Sopenharmony_ci } else if (!strcmp(str, "lfall_rrise")) { 234762306a36Sopenharmony_ci return DA7218_DMIC_DATA_LFALL_RRISE; 234862306a36Sopenharmony_ci } else { 234962306a36Sopenharmony_ci dev_warn(component->dev, "Invalid DMIC data type selection"); 235062306a36Sopenharmony_ci return DA7218_DMIC_DATA_LRISE_RFALL; 235162306a36Sopenharmony_ci } 235262306a36Sopenharmony_ci} 235362306a36Sopenharmony_ci 235462306a36Sopenharmony_cistatic enum da7218_dmic_samplephase 235562306a36Sopenharmony_ci da7218_of_dmic_samplephase(struct snd_soc_component *component, const char *str) 235662306a36Sopenharmony_ci{ 235762306a36Sopenharmony_ci if (!strcmp(str, "on_clkedge")) { 235862306a36Sopenharmony_ci return DA7218_DMIC_SAMPLE_ON_CLKEDGE; 235962306a36Sopenharmony_ci } else if (!strcmp(str, "between_clkedge")) { 236062306a36Sopenharmony_ci return DA7218_DMIC_SAMPLE_BETWEEN_CLKEDGE; 236162306a36Sopenharmony_ci } else { 236262306a36Sopenharmony_ci dev_warn(component->dev, "Invalid DMIC sample phase"); 236362306a36Sopenharmony_ci return DA7218_DMIC_SAMPLE_ON_CLKEDGE; 236462306a36Sopenharmony_ci } 236562306a36Sopenharmony_ci} 236662306a36Sopenharmony_ci 236762306a36Sopenharmony_cistatic enum da7218_dmic_clk_rate 236862306a36Sopenharmony_ci da7218_of_dmic_clkrate(struct snd_soc_component *component, u32 val) 236962306a36Sopenharmony_ci{ 237062306a36Sopenharmony_ci switch (val) { 237162306a36Sopenharmony_ci case 1500000: 237262306a36Sopenharmony_ci return DA7218_DMIC_CLK_1_5MHZ; 237362306a36Sopenharmony_ci case 3000000: 237462306a36Sopenharmony_ci return DA7218_DMIC_CLK_3_0MHZ; 237562306a36Sopenharmony_ci default: 237662306a36Sopenharmony_ci dev_warn(component->dev, "Invalid DMIC clock rate"); 237762306a36Sopenharmony_ci return DA7218_DMIC_CLK_3_0MHZ; 237862306a36Sopenharmony_ci } 237962306a36Sopenharmony_ci} 238062306a36Sopenharmony_ci 238162306a36Sopenharmony_cistatic enum da7218_hpldet_jack_rate 238262306a36Sopenharmony_ci da7218_of_jack_rate(struct snd_soc_component *component, u32 val) 238362306a36Sopenharmony_ci{ 238462306a36Sopenharmony_ci switch (val) { 238562306a36Sopenharmony_ci case 5: 238662306a36Sopenharmony_ci return DA7218_HPLDET_JACK_RATE_5US; 238762306a36Sopenharmony_ci case 10: 238862306a36Sopenharmony_ci return DA7218_HPLDET_JACK_RATE_10US; 238962306a36Sopenharmony_ci case 20: 239062306a36Sopenharmony_ci return DA7218_HPLDET_JACK_RATE_20US; 239162306a36Sopenharmony_ci case 40: 239262306a36Sopenharmony_ci return DA7218_HPLDET_JACK_RATE_40US; 239362306a36Sopenharmony_ci case 80: 239462306a36Sopenharmony_ci return DA7218_HPLDET_JACK_RATE_80US; 239562306a36Sopenharmony_ci case 160: 239662306a36Sopenharmony_ci return DA7218_HPLDET_JACK_RATE_160US; 239762306a36Sopenharmony_ci case 320: 239862306a36Sopenharmony_ci return DA7218_HPLDET_JACK_RATE_320US; 239962306a36Sopenharmony_ci case 640: 240062306a36Sopenharmony_ci return DA7218_HPLDET_JACK_RATE_640US; 240162306a36Sopenharmony_ci default: 240262306a36Sopenharmony_ci dev_warn(component->dev, "Invalid jack detect rate"); 240362306a36Sopenharmony_ci return DA7218_HPLDET_JACK_RATE_40US; 240462306a36Sopenharmony_ci } 240562306a36Sopenharmony_ci} 240662306a36Sopenharmony_ci 240762306a36Sopenharmony_cistatic enum da7218_hpldet_jack_debounce 240862306a36Sopenharmony_ci da7218_of_jack_debounce(struct snd_soc_component *component, u32 val) 240962306a36Sopenharmony_ci{ 241062306a36Sopenharmony_ci switch (val) { 241162306a36Sopenharmony_ci case 0: 241262306a36Sopenharmony_ci return DA7218_HPLDET_JACK_DEBOUNCE_OFF; 241362306a36Sopenharmony_ci case 2: 241462306a36Sopenharmony_ci return DA7218_HPLDET_JACK_DEBOUNCE_2; 241562306a36Sopenharmony_ci case 3: 241662306a36Sopenharmony_ci return DA7218_HPLDET_JACK_DEBOUNCE_3; 241762306a36Sopenharmony_ci case 4: 241862306a36Sopenharmony_ci return DA7218_HPLDET_JACK_DEBOUNCE_4; 241962306a36Sopenharmony_ci default: 242062306a36Sopenharmony_ci dev_warn(component->dev, "Invalid jack debounce"); 242162306a36Sopenharmony_ci return DA7218_HPLDET_JACK_DEBOUNCE_2; 242262306a36Sopenharmony_ci } 242362306a36Sopenharmony_ci} 242462306a36Sopenharmony_ci 242562306a36Sopenharmony_cistatic enum da7218_hpldet_jack_thr 242662306a36Sopenharmony_ci da7218_of_jack_thr(struct snd_soc_component *component, u32 val) 242762306a36Sopenharmony_ci{ 242862306a36Sopenharmony_ci switch (val) { 242962306a36Sopenharmony_ci case 84: 243062306a36Sopenharmony_ci return DA7218_HPLDET_JACK_THR_84PCT; 243162306a36Sopenharmony_ci case 88: 243262306a36Sopenharmony_ci return DA7218_HPLDET_JACK_THR_88PCT; 243362306a36Sopenharmony_ci case 92: 243462306a36Sopenharmony_ci return DA7218_HPLDET_JACK_THR_92PCT; 243562306a36Sopenharmony_ci case 96: 243662306a36Sopenharmony_ci return DA7218_HPLDET_JACK_THR_96PCT; 243762306a36Sopenharmony_ci default: 243862306a36Sopenharmony_ci dev_warn(component->dev, "Invalid jack threshold level"); 243962306a36Sopenharmony_ci return DA7218_HPLDET_JACK_THR_84PCT; 244062306a36Sopenharmony_ci } 244162306a36Sopenharmony_ci} 244262306a36Sopenharmony_ci 244362306a36Sopenharmony_cistatic struct da7218_pdata *da7218_of_to_pdata(struct snd_soc_component *component) 244462306a36Sopenharmony_ci{ 244562306a36Sopenharmony_ci struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component); 244662306a36Sopenharmony_ci struct device_node *np = component->dev->of_node; 244762306a36Sopenharmony_ci struct device_node *hpldet_np; 244862306a36Sopenharmony_ci struct da7218_pdata *pdata; 244962306a36Sopenharmony_ci struct da7218_hpldet_pdata *hpldet_pdata; 245062306a36Sopenharmony_ci const char *of_str; 245162306a36Sopenharmony_ci u32 of_val32; 245262306a36Sopenharmony_ci 245362306a36Sopenharmony_ci pdata = devm_kzalloc(component->dev, sizeof(*pdata), GFP_KERNEL); 245462306a36Sopenharmony_ci if (!pdata) 245562306a36Sopenharmony_ci return NULL; 245662306a36Sopenharmony_ci 245762306a36Sopenharmony_ci if (of_property_read_u32(np, "dlg,micbias1-lvl-millivolt", &of_val32) >= 0) 245862306a36Sopenharmony_ci pdata->micbias1_lvl = da7218_of_micbias_lvl(component, of_val32); 245962306a36Sopenharmony_ci else 246062306a36Sopenharmony_ci pdata->micbias1_lvl = DA7218_MICBIAS_1_6V; 246162306a36Sopenharmony_ci 246262306a36Sopenharmony_ci if (of_property_read_u32(np, "dlg,micbias2-lvl-millivolt", &of_val32) >= 0) 246362306a36Sopenharmony_ci pdata->micbias2_lvl = da7218_of_micbias_lvl(component, of_val32); 246462306a36Sopenharmony_ci else 246562306a36Sopenharmony_ci pdata->micbias2_lvl = DA7218_MICBIAS_1_6V; 246662306a36Sopenharmony_ci 246762306a36Sopenharmony_ci if (!of_property_read_string(np, "dlg,mic1-amp-in-sel", &of_str)) 246862306a36Sopenharmony_ci pdata->mic1_amp_in_sel = 246962306a36Sopenharmony_ci da7218_of_mic_amp_in_sel(component, of_str); 247062306a36Sopenharmony_ci else 247162306a36Sopenharmony_ci pdata->mic1_amp_in_sel = DA7218_MIC_AMP_IN_SEL_DIFF; 247262306a36Sopenharmony_ci 247362306a36Sopenharmony_ci if (!of_property_read_string(np, "dlg,mic2-amp-in-sel", &of_str)) 247462306a36Sopenharmony_ci pdata->mic2_amp_in_sel = 247562306a36Sopenharmony_ci da7218_of_mic_amp_in_sel(component, of_str); 247662306a36Sopenharmony_ci else 247762306a36Sopenharmony_ci pdata->mic2_amp_in_sel = DA7218_MIC_AMP_IN_SEL_DIFF; 247862306a36Sopenharmony_ci 247962306a36Sopenharmony_ci if (!of_property_read_string(np, "dlg,dmic1-data-sel", &of_str)) 248062306a36Sopenharmony_ci pdata->dmic1_data_sel = da7218_of_dmic_data_sel(component, of_str); 248162306a36Sopenharmony_ci else 248262306a36Sopenharmony_ci pdata->dmic1_data_sel = DA7218_DMIC_DATA_LRISE_RFALL; 248362306a36Sopenharmony_ci 248462306a36Sopenharmony_ci if (!of_property_read_string(np, "dlg,dmic1-samplephase", &of_str)) 248562306a36Sopenharmony_ci pdata->dmic1_samplephase = 248662306a36Sopenharmony_ci da7218_of_dmic_samplephase(component, of_str); 248762306a36Sopenharmony_ci else 248862306a36Sopenharmony_ci pdata->dmic1_samplephase = DA7218_DMIC_SAMPLE_ON_CLKEDGE; 248962306a36Sopenharmony_ci 249062306a36Sopenharmony_ci if (of_property_read_u32(np, "dlg,dmic1-clkrate-hz", &of_val32) >= 0) 249162306a36Sopenharmony_ci pdata->dmic1_clk_rate = da7218_of_dmic_clkrate(component, of_val32); 249262306a36Sopenharmony_ci else 249362306a36Sopenharmony_ci pdata->dmic1_clk_rate = DA7218_DMIC_CLK_3_0MHZ; 249462306a36Sopenharmony_ci 249562306a36Sopenharmony_ci if (!of_property_read_string(np, "dlg,dmic2-data-sel", &of_str)) 249662306a36Sopenharmony_ci pdata->dmic2_data_sel = da7218_of_dmic_data_sel(component, of_str); 249762306a36Sopenharmony_ci else 249862306a36Sopenharmony_ci pdata->dmic2_data_sel = DA7218_DMIC_DATA_LRISE_RFALL; 249962306a36Sopenharmony_ci 250062306a36Sopenharmony_ci if (!of_property_read_string(np, "dlg,dmic2-samplephase", &of_str)) 250162306a36Sopenharmony_ci pdata->dmic2_samplephase = 250262306a36Sopenharmony_ci da7218_of_dmic_samplephase(component, of_str); 250362306a36Sopenharmony_ci else 250462306a36Sopenharmony_ci pdata->dmic2_samplephase = DA7218_DMIC_SAMPLE_ON_CLKEDGE; 250562306a36Sopenharmony_ci 250662306a36Sopenharmony_ci if (of_property_read_u32(np, "dlg,dmic2-clkrate-hz", &of_val32) >= 0) 250762306a36Sopenharmony_ci pdata->dmic2_clk_rate = da7218_of_dmic_clkrate(component, of_val32); 250862306a36Sopenharmony_ci else 250962306a36Sopenharmony_ci pdata->dmic2_clk_rate = DA7218_DMIC_CLK_3_0MHZ; 251062306a36Sopenharmony_ci 251162306a36Sopenharmony_ci if (da7218->dev_id == DA7217_DEV_ID) { 251262306a36Sopenharmony_ci if (of_property_read_bool(np, "dlg,hp-diff-single-supply")) 251362306a36Sopenharmony_ci pdata->hp_diff_single_supply = true; 251462306a36Sopenharmony_ci } 251562306a36Sopenharmony_ci 251662306a36Sopenharmony_ci if (da7218->dev_id == DA7218_DEV_ID) { 251762306a36Sopenharmony_ci hpldet_np = of_get_child_by_name(np, "da7218_hpldet"); 251862306a36Sopenharmony_ci if (!hpldet_np) 251962306a36Sopenharmony_ci return pdata; 252062306a36Sopenharmony_ci 252162306a36Sopenharmony_ci hpldet_pdata = devm_kzalloc(component->dev, sizeof(*hpldet_pdata), 252262306a36Sopenharmony_ci GFP_KERNEL); 252362306a36Sopenharmony_ci if (!hpldet_pdata) { 252462306a36Sopenharmony_ci of_node_put(hpldet_np); 252562306a36Sopenharmony_ci return pdata; 252662306a36Sopenharmony_ci } 252762306a36Sopenharmony_ci pdata->hpldet_pdata = hpldet_pdata; 252862306a36Sopenharmony_ci 252962306a36Sopenharmony_ci if (of_property_read_u32(hpldet_np, "dlg,jack-rate-us", 253062306a36Sopenharmony_ci &of_val32) >= 0) 253162306a36Sopenharmony_ci hpldet_pdata->jack_rate = 253262306a36Sopenharmony_ci da7218_of_jack_rate(component, of_val32); 253362306a36Sopenharmony_ci else 253462306a36Sopenharmony_ci hpldet_pdata->jack_rate = DA7218_HPLDET_JACK_RATE_40US; 253562306a36Sopenharmony_ci 253662306a36Sopenharmony_ci if (of_property_read_u32(hpldet_np, "dlg,jack-debounce", 253762306a36Sopenharmony_ci &of_val32) >= 0) 253862306a36Sopenharmony_ci hpldet_pdata->jack_debounce = 253962306a36Sopenharmony_ci da7218_of_jack_debounce(component, of_val32); 254062306a36Sopenharmony_ci else 254162306a36Sopenharmony_ci hpldet_pdata->jack_debounce = 254262306a36Sopenharmony_ci DA7218_HPLDET_JACK_DEBOUNCE_2; 254362306a36Sopenharmony_ci 254462306a36Sopenharmony_ci if (of_property_read_u32(hpldet_np, "dlg,jack-threshold-pct", 254562306a36Sopenharmony_ci &of_val32) >= 0) 254662306a36Sopenharmony_ci hpldet_pdata->jack_thr = 254762306a36Sopenharmony_ci da7218_of_jack_thr(component, of_val32); 254862306a36Sopenharmony_ci else 254962306a36Sopenharmony_ci hpldet_pdata->jack_thr = DA7218_HPLDET_JACK_THR_84PCT; 255062306a36Sopenharmony_ci 255162306a36Sopenharmony_ci if (of_property_read_bool(hpldet_np, "dlg,comp-inv")) 255262306a36Sopenharmony_ci hpldet_pdata->comp_inv = true; 255362306a36Sopenharmony_ci 255462306a36Sopenharmony_ci if (of_property_read_bool(hpldet_np, "dlg,hyst")) 255562306a36Sopenharmony_ci hpldet_pdata->hyst = true; 255662306a36Sopenharmony_ci 255762306a36Sopenharmony_ci if (of_property_read_bool(hpldet_np, "dlg,discharge")) 255862306a36Sopenharmony_ci hpldet_pdata->discharge = true; 255962306a36Sopenharmony_ci 256062306a36Sopenharmony_ci of_node_put(hpldet_np); 256162306a36Sopenharmony_ci } 256262306a36Sopenharmony_ci 256362306a36Sopenharmony_ci return pdata; 256462306a36Sopenharmony_ci} 256562306a36Sopenharmony_ci 256662306a36Sopenharmony_ci 256762306a36Sopenharmony_ci/* 256862306a36Sopenharmony_ci * Codec driver functions 256962306a36Sopenharmony_ci */ 257062306a36Sopenharmony_ci 257162306a36Sopenharmony_cistatic int da7218_set_bias_level(struct snd_soc_component *component, 257262306a36Sopenharmony_ci enum snd_soc_bias_level level) 257362306a36Sopenharmony_ci{ 257462306a36Sopenharmony_ci struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component); 257562306a36Sopenharmony_ci int ret; 257662306a36Sopenharmony_ci 257762306a36Sopenharmony_ci switch (level) { 257862306a36Sopenharmony_ci case SND_SOC_BIAS_ON: 257962306a36Sopenharmony_ci break; 258062306a36Sopenharmony_ci case SND_SOC_BIAS_PREPARE: 258162306a36Sopenharmony_ci /* Enable MCLK for transition to ON state */ 258262306a36Sopenharmony_ci if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY) { 258362306a36Sopenharmony_ci if (da7218->mclk) { 258462306a36Sopenharmony_ci ret = clk_prepare_enable(da7218->mclk); 258562306a36Sopenharmony_ci if (ret) { 258662306a36Sopenharmony_ci dev_err(component->dev, "Failed to enable mclk\n"); 258762306a36Sopenharmony_ci return ret; 258862306a36Sopenharmony_ci } 258962306a36Sopenharmony_ci } 259062306a36Sopenharmony_ci } 259162306a36Sopenharmony_ci 259262306a36Sopenharmony_ci break; 259362306a36Sopenharmony_ci case SND_SOC_BIAS_STANDBY: 259462306a36Sopenharmony_ci if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { 259562306a36Sopenharmony_ci /* Master bias */ 259662306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_REFERENCES, 259762306a36Sopenharmony_ci DA7218_BIAS_EN_MASK, 259862306a36Sopenharmony_ci DA7218_BIAS_EN_MASK); 259962306a36Sopenharmony_ci 260062306a36Sopenharmony_ci /* Internal LDO */ 260162306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_LDO_CTRL, 260262306a36Sopenharmony_ci DA7218_LDO_EN_MASK, 260362306a36Sopenharmony_ci DA7218_LDO_EN_MASK); 260462306a36Sopenharmony_ci } else { 260562306a36Sopenharmony_ci /* Remove MCLK */ 260662306a36Sopenharmony_ci if (da7218->mclk) 260762306a36Sopenharmony_ci clk_disable_unprepare(da7218->mclk); 260862306a36Sopenharmony_ci } 260962306a36Sopenharmony_ci break; 261062306a36Sopenharmony_ci case SND_SOC_BIAS_OFF: 261162306a36Sopenharmony_ci /* Only disable if jack detection disabled */ 261262306a36Sopenharmony_ci if (!da7218->jack) { 261362306a36Sopenharmony_ci /* Internal LDO */ 261462306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_LDO_CTRL, 261562306a36Sopenharmony_ci DA7218_LDO_EN_MASK, 0); 261662306a36Sopenharmony_ci 261762306a36Sopenharmony_ci /* Master bias */ 261862306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_REFERENCES, 261962306a36Sopenharmony_ci DA7218_BIAS_EN_MASK, 0); 262062306a36Sopenharmony_ci } 262162306a36Sopenharmony_ci break; 262262306a36Sopenharmony_ci } 262362306a36Sopenharmony_ci 262462306a36Sopenharmony_ci return 0; 262562306a36Sopenharmony_ci} 262662306a36Sopenharmony_ci 262762306a36Sopenharmony_cistatic const char *da7218_supply_names[DA7218_NUM_SUPPLIES] = { 262862306a36Sopenharmony_ci [DA7218_SUPPLY_VDD] = "VDD", 262962306a36Sopenharmony_ci [DA7218_SUPPLY_VDDMIC] = "VDDMIC", 263062306a36Sopenharmony_ci [DA7218_SUPPLY_VDDIO] = "VDDIO", 263162306a36Sopenharmony_ci}; 263262306a36Sopenharmony_ci 263362306a36Sopenharmony_cistatic int da7218_handle_supplies(struct snd_soc_component *component) 263462306a36Sopenharmony_ci{ 263562306a36Sopenharmony_ci struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component); 263662306a36Sopenharmony_ci struct regulator *vddio; 263762306a36Sopenharmony_ci u8 io_voltage_lvl = DA7218_IO_VOLTAGE_LEVEL_2_5V_3_6V; 263862306a36Sopenharmony_ci int i, ret; 263962306a36Sopenharmony_ci 264062306a36Sopenharmony_ci /* Get required supplies */ 264162306a36Sopenharmony_ci for (i = 0; i < DA7218_NUM_SUPPLIES; ++i) 264262306a36Sopenharmony_ci da7218->supplies[i].supply = da7218_supply_names[i]; 264362306a36Sopenharmony_ci 264462306a36Sopenharmony_ci ret = devm_regulator_bulk_get(component->dev, DA7218_NUM_SUPPLIES, 264562306a36Sopenharmony_ci da7218->supplies); 264662306a36Sopenharmony_ci if (ret) { 264762306a36Sopenharmony_ci dev_err(component->dev, "Failed to get supplies\n"); 264862306a36Sopenharmony_ci return ret; 264962306a36Sopenharmony_ci } 265062306a36Sopenharmony_ci 265162306a36Sopenharmony_ci /* Determine VDDIO voltage provided */ 265262306a36Sopenharmony_ci vddio = da7218->supplies[DA7218_SUPPLY_VDDIO].consumer; 265362306a36Sopenharmony_ci ret = regulator_get_voltage(vddio); 265462306a36Sopenharmony_ci if (ret < 1500000) 265562306a36Sopenharmony_ci dev_warn(component->dev, "Invalid VDDIO voltage\n"); 265662306a36Sopenharmony_ci else if (ret < 2500000) 265762306a36Sopenharmony_ci io_voltage_lvl = DA7218_IO_VOLTAGE_LEVEL_1_5V_2_5V; 265862306a36Sopenharmony_ci 265962306a36Sopenharmony_ci /* Enable main supplies */ 266062306a36Sopenharmony_ci ret = regulator_bulk_enable(DA7218_NUM_SUPPLIES, da7218->supplies); 266162306a36Sopenharmony_ci if (ret) { 266262306a36Sopenharmony_ci dev_err(component->dev, "Failed to enable supplies\n"); 266362306a36Sopenharmony_ci return ret; 266462306a36Sopenharmony_ci } 266562306a36Sopenharmony_ci 266662306a36Sopenharmony_ci /* Ensure device in active mode */ 266762306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_SYSTEM_ACTIVE, DA7218_SYSTEM_ACTIVE_MASK); 266862306a36Sopenharmony_ci 266962306a36Sopenharmony_ci /* Update IO voltage level range */ 267062306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_IO_CTRL, io_voltage_lvl); 267162306a36Sopenharmony_ci 267262306a36Sopenharmony_ci return 0; 267362306a36Sopenharmony_ci} 267462306a36Sopenharmony_ci 267562306a36Sopenharmony_cistatic void da7218_handle_pdata(struct snd_soc_component *component) 267662306a36Sopenharmony_ci{ 267762306a36Sopenharmony_ci struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component); 267862306a36Sopenharmony_ci struct da7218_pdata *pdata = da7218->pdata; 267962306a36Sopenharmony_ci 268062306a36Sopenharmony_ci if (pdata) { 268162306a36Sopenharmony_ci u8 micbias_lvl = 0, dmic_cfg = 0; 268262306a36Sopenharmony_ci 268362306a36Sopenharmony_ci /* Mic Bias voltages */ 268462306a36Sopenharmony_ci switch (pdata->micbias1_lvl) { 268562306a36Sopenharmony_ci case DA7218_MICBIAS_1_2V: 268662306a36Sopenharmony_ci micbias_lvl |= DA7218_MICBIAS_1_LP_MODE_MASK; 268762306a36Sopenharmony_ci break; 268862306a36Sopenharmony_ci case DA7218_MICBIAS_1_6V: 268962306a36Sopenharmony_ci case DA7218_MICBIAS_1_8V: 269062306a36Sopenharmony_ci case DA7218_MICBIAS_2_0V: 269162306a36Sopenharmony_ci case DA7218_MICBIAS_2_2V: 269262306a36Sopenharmony_ci case DA7218_MICBIAS_2_4V: 269362306a36Sopenharmony_ci case DA7218_MICBIAS_2_6V: 269462306a36Sopenharmony_ci case DA7218_MICBIAS_2_8V: 269562306a36Sopenharmony_ci case DA7218_MICBIAS_3_0V: 269662306a36Sopenharmony_ci micbias_lvl |= (pdata->micbias1_lvl << 269762306a36Sopenharmony_ci DA7218_MICBIAS_1_LEVEL_SHIFT); 269862306a36Sopenharmony_ci break; 269962306a36Sopenharmony_ci } 270062306a36Sopenharmony_ci 270162306a36Sopenharmony_ci switch (pdata->micbias2_lvl) { 270262306a36Sopenharmony_ci case DA7218_MICBIAS_1_2V: 270362306a36Sopenharmony_ci micbias_lvl |= DA7218_MICBIAS_2_LP_MODE_MASK; 270462306a36Sopenharmony_ci break; 270562306a36Sopenharmony_ci case DA7218_MICBIAS_1_6V: 270662306a36Sopenharmony_ci case DA7218_MICBIAS_1_8V: 270762306a36Sopenharmony_ci case DA7218_MICBIAS_2_0V: 270862306a36Sopenharmony_ci case DA7218_MICBIAS_2_2V: 270962306a36Sopenharmony_ci case DA7218_MICBIAS_2_4V: 271062306a36Sopenharmony_ci case DA7218_MICBIAS_2_6V: 271162306a36Sopenharmony_ci case DA7218_MICBIAS_2_8V: 271262306a36Sopenharmony_ci case DA7218_MICBIAS_3_0V: 271362306a36Sopenharmony_ci micbias_lvl |= (pdata->micbias2_lvl << 271462306a36Sopenharmony_ci DA7218_MICBIAS_2_LEVEL_SHIFT); 271562306a36Sopenharmony_ci break; 271662306a36Sopenharmony_ci } 271762306a36Sopenharmony_ci 271862306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_MICBIAS_CTRL, micbias_lvl); 271962306a36Sopenharmony_ci 272062306a36Sopenharmony_ci /* Mic */ 272162306a36Sopenharmony_ci switch (pdata->mic1_amp_in_sel) { 272262306a36Sopenharmony_ci case DA7218_MIC_AMP_IN_SEL_DIFF: 272362306a36Sopenharmony_ci case DA7218_MIC_AMP_IN_SEL_SE_P: 272462306a36Sopenharmony_ci case DA7218_MIC_AMP_IN_SEL_SE_N: 272562306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_MIC_1_SELECT, 272662306a36Sopenharmony_ci pdata->mic1_amp_in_sel); 272762306a36Sopenharmony_ci break; 272862306a36Sopenharmony_ci } 272962306a36Sopenharmony_ci 273062306a36Sopenharmony_ci switch (pdata->mic2_amp_in_sel) { 273162306a36Sopenharmony_ci case DA7218_MIC_AMP_IN_SEL_DIFF: 273262306a36Sopenharmony_ci case DA7218_MIC_AMP_IN_SEL_SE_P: 273362306a36Sopenharmony_ci case DA7218_MIC_AMP_IN_SEL_SE_N: 273462306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_MIC_2_SELECT, 273562306a36Sopenharmony_ci pdata->mic2_amp_in_sel); 273662306a36Sopenharmony_ci break; 273762306a36Sopenharmony_ci } 273862306a36Sopenharmony_ci 273962306a36Sopenharmony_ci /* DMic */ 274062306a36Sopenharmony_ci switch (pdata->dmic1_data_sel) { 274162306a36Sopenharmony_ci case DA7218_DMIC_DATA_LFALL_RRISE: 274262306a36Sopenharmony_ci case DA7218_DMIC_DATA_LRISE_RFALL: 274362306a36Sopenharmony_ci dmic_cfg |= (pdata->dmic1_data_sel << 274462306a36Sopenharmony_ci DA7218_DMIC_1_DATA_SEL_SHIFT); 274562306a36Sopenharmony_ci break; 274662306a36Sopenharmony_ci } 274762306a36Sopenharmony_ci 274862306a36Sopenharmony_ci switch (pdata->dmic1_samplephase) { 274962306a36Sopenharmony_ci case DA7218_DMIC_SAMPLE_ON_CLKEDGE: 275062306a36Sopenharmony_ci case DA7218_DMIC_SAMPLE_BETWEEN_CLKEDGE: 275162306a36Sopenharmony_ci dmic_cfg |= (pdata->dmic1_samplephase << 275262306a36Sopenharmony_ci DA7218_DMIC_1_SAMPLEPHASE_SHIFT); 275362306a36Sopenharmony_ci break; 275462306a36Sopenharmony_ci } 275562306a36Sopenharmony_ci 275662306a36Sopenharmony_ci switch (pdata->dmic1_clk_rate) { 275762306a36Sopenharmony_ci case DA7218_DMIC_CLK_3_0MHZ: 275862306a36Sopenharmony_ci case DA7218_DMIC_CLK_1_5MHZ: 275962306a36Sopenharmony_ci dmic_cfg |= (pdata->dmic1_clk_rate << 276062306a36Sopenharmony_ci DA7218_DMIC_1_CLK_RATE_SHIFT); 276162306a36Sopenharmony_ci break; 276262306a36Sopenharmony_ci } 276362306a36Sopenharmony_ci 276462306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_DMIC_1_CTRL, 276562306a36Sopenharmony_ci DA7218_DMIC_1_DATA_SEL_MASK | 276662306a36Sopenharmony_ci DA7218_DMIC_1_SAMPLEPHASE_MASK | 276762306a36Sopenharmony_ci DA7218_DMIC_1_CLK_RATE_MASK, dmic_cfg); 276862306a36Sopenharmony_ci 276962306a36Sopenharmony_ci dmic_cfg = 0; 277062306a36Sopenharmony_ci switch (pdata->dmic2_data_sel) { 277162306a36Sopenharmony_ci case DA7218_DMIC_DATA_LFALL_RRISE: 277262306a36Sopenharmony_ci case DA7218_DMIC_DATA_LRISE_RFALL: 277362306a36Sopenharmony_ci dmic_cfg |= (pdata->dmic2_data_sel << 277462306a36Sopenharmony_ci DA7218_DMIC_2_DATA_SEL_SHIFT); 277562306a36Sopenharmony_ci break; 277662306a36Sopenharmony_ci } 277762306a36Sopenharmony_ci 277862306a36Sopenharmony_ci switch (pdata->dmic2_samplephase) { 277962306a36Sopenharmony_ci case DA7218_DMIC_SAMPLE_ON_CLKEDGE: 278062306a36Sopenharmony_ci case DA7218_DMIC_SAMPLE_BETWEEN_CLKEDGE: 278162306a36Sopenharmony_ci dmic_cfg |= (pdata->dmic2_samplephase << 278262306a36Sopenharmony_ci DA7218_DMIC_2_SAMPLEPHASE_SHIFT); 278362306a36Sopenharmony_ci break; 278462306a36Sopenharmony_ci } 278562306a36Sopenharmony_ci 278662306a36Sopenharmony_ci switch (pdata->dmic2_clk_rate) { 278762306a36Sopenharmony_ci case DA7218_DMIC_CLK_3_0MHZ: 278862306a36Sopenharmony_ci case DA7218_DMIC_CLK_1_5MHZ: 278962306a36Sopenharmony_ci dmic_cfg |= (pdata->dmic2_clk_rate << 279062306a36Sopenharmony_ci DA7218_DMIC_2_CLK_RATE_SHIFT); 279162306a36Sopenharmony_ci break; 279262306a36Sopenharmony_ci } 279362306a36Sopenharmony_ci 279462306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_DMIC_2_CTRL, 279562306a36Sopenharmony_ci DA7218_DMIC_2_DATA_SEL_MASK | 279662306a36Sopenharmony_ci DA7218_DMIC_2_SAMPLEPHASE_MASK | 279762306a36Sopenharmony_ci DA7218_DMIC_2_CLK_RATE_MASK, dmic_cfg); 279862306a36Sopenharmony_ci 279962306a36Sopenharmony_ci /* DA7217 Specific */ 280062306a36Sopenharmony_ci if (da7218->dev_id == DA7217_DEV_ID) { 280162306a36Sopenharmony_ci da7218->hp_single_supply = 280262306a36Sopenharmony_ci pdata->hp_diff_single_supply; 280362306a36Sopenharmony_ci 280462306a36Sopenharmony_ci if (da7218->hp_single_supply) { 280562306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_HP_DIFF_UNLOCK, 280662306a36Sopenharmony_ci DA7218_HP_DIFF_UNLOCK_VAL); 280762306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_HP_DIFF_CTRL, 280862306a36Sopenharmony_ci DA7218_HP_AMP_SINGLE_SUPPLY_EN_MASK, 280962306a36Sopenharmony_ci DA7218_HP_AMP_SINGLE_SUPPLY_EN_MASK); 281062306a36Sopenharmony_ci } 281162306a36Sopenharmony_ci } 281262306a36Sopenharmony_ci 281362306a36Sopenharmony_ci /* DA7218 Specific */ 281462306a36Sopenharmony_ci if ((da7218->dev_id == DA7218_DEV_ID) && 281562306a36Sopenharmony_ci (pdata->hpldet_pdata)) { 281662306a36Sopenharmony_ci struct da7218_hpldet_pdata *hpldet_pdata = 281762306a36Sopenharmony_ci pdata->hpldet_pdata; 281862306a36Sopenharmony_ci u8 hpldet_cfg = 0; 281962306a36Sopenharmony_ci 282062306a36Sopenharmony_ci switch (hpldet_pdata->jack_rate) { 282162306a36Sopenharmony_ci case DA7218_HPLDET_JACK_RATE_5US: 282262306a36Sopenharmony_ci case DA7218_HPLDET_JACK_RATE_10US: 282362306a36Sopenharmony_ci case DA7218_HPLDET_JACK_RATE_20US: 282462306a36Sopenharmony_ci case DA7218_HPLDET_JACK_RATE_40US: 282562306a36Sopenharmony_ci case DA7218_HPLDET_JACK_RATE_80US: 282662306a36Sopenharmony_ci case DA7218_HPLDET_JACK_RATE_160US: 282762306a36Sopenharmony_ci case DA7218_HPLDET_JACK_RATE_320US: 282862306a36Sopenharmony_ci case DA7218_HPLDET_JACK_RATE_640US: 282962306a36Sopenharmony_ci hpldet_cfg |= 283062306a36Sopenharmony_ci (hpldet_pdata->jack_rate << 283162306a36Sopenharmony_ci DA7218_HPLDET_JACK_RATE_SHIFT); 283262306a36Sopenharmony_ci break; 283362306a36Sopenharmony_ci } 283462306a36Sopenharmony_ci 283562306a36Sopenharmony_ci switch (hpldet_pdata->jack_debounce) { 283662306a36Sopenharmony_ci case DA7218_HPLDET_JACK_DEBOUNCE_OFF: 283762306a36Sopenharmony_ci case DA7218_HPLDET_JACK_DEBOUNCE_2: 283862306a36Sopenharmony_ci case DA7218_HPLDET_JACK_DEBOUNCE_3: 283962306a36Sopenharmony_ci case DA7218_HPLDET_JACK_DEBOUNCE_4: 284062306a36Sopenharmony_ci hpldet_cfg |= 284162306a36Sopenharmony_ci (hpldet_pdata->jack_debounce << 284262306a36Sopenharmony_ci DA7218_HPLDET_JACK_DEBOUNCE_SHIFT); 284362306a36Sopenharmony_ci break; 284462306a36Sopenharmony_ci } 284562306a36Sopenharmony_ci 284662306a36Sopenharmony_ci switch (hpldet_pdata->jack_thr) { 284762306a36Sopenharmony_ci case DA7218_HPLDET_JACK_THR_84PCT: 284862306a36Sopenharmony_ci case DA7218_HPLDET_JACK_THR_88PCT: 284962306a36Sopenharmony_ci case DA7218_HPLDET_JACK_THR_92PCT: 285062306a36Sopenharmony_ci case DA7218_HPLDET_JACK_THR_96PCT: 285162306a36Sopenharmony_ci hpldet_cfg |= 285262306a36Sopenharmony_ci (hpldet_pdata->jack_thr << 285362306a36Sopenharmony_ci DA7218_HPLDET_JACK_THR_SHIFT); 285462306a36Sopenharmony_ci break; 285562306a36Sopenharmony_ci } 285662306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_HPLDET_JACK, 285762306a36Sopenharmony_ci DA7218_HPLDET_JACK_RATE_MASK | 285862306a36Sopenharmony_ci DA7218_HPLDET_JACK_DEBOUNCE_MASK | 285962306a36Sopenharmony_ci DA7218_HPLDET_JACK_THR_MASK, 286062306a36Sopenharmony_ci hpldet_cfg); 286162306a36Sopenharmony_ci 286262306a36Sopenharmony_ci hpldet_cfg = 0; 286362306a36Sopenharmony_ci if (hpldet_pdata->comp_inv) 286462306a36Sopenharmony_ci hpldet_cfg |= DA7218_HPLDET_COMP_INV_MASK; 286562306a36Sopenharmony_ci 286662306a36Sopenharmony_ci if (hpldet_pdata->hyst) 286762306a36Sopenharmony_ci hpldet_cfg |= DA7218_HPLDET_HYST_EN_MASK; 286862306a36Sopenharmony_ci 286962306a36Sopenharmony_ci if (hpldet_pdata->discharge) 287062306a36Sopenharmony_ci hpldet_cfg |= DA7218_HPLDET_DISCHARGE_EN_MASK; 287162306a36Sopenharmony_ci 287262306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_HPLDET_CTRL, hpldet_cfg); 287362306a36Sopenharmony_ci } 287462306a36Sopenharmony_ci } 287562306a36Sopenharmony_ci} 287662306a36Sopenharmony_ci 287762306a36Sopenharmony_cistatic int da7218_probe(struct snd_soc_component *component) 287862306a36Sopenharmony_ci{ 287962306a36Sopenharmony_ci struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component); 288062306a36Sopenharmony_ci int ret; 288162306a36Sopenharmony_ci 288262306a36Sopenharmony_ci /* Regulator configuration */ 288362306a36Sopenharmony_ci ret = da7218_handle_supplies(component); 288462306a36Sopenharmony_ci if (ret) 288562306a36Sopenharmony_ci return ret; 288662306a36Sopenharmony_ci 288762306a36Sopenharmony_ci /* Handle DT/Platform data */ 288862306a36Sopenharmony_ci if (component->dev->of_node) 288962306a36Sopenharmony_ci da7218->pdata = da7218_of_to_pdata(component); 289062306a36Sopenharmony_ci else 289162306a36Sopenharmony_ci da7218->pdata = dev_get_platdata(component->dev); 289262306a36Sopenharmony_ci 289362306a36Sopenharmony_ci da7218_handle_pdata(component); 289462306a36Sopenharmony_ci 289562306a36Sopenharmony_ci /* Check if MCLK provided, if not the clock is NULL */ 289662306a36Sopenharmony_ci da7218->mclk = devm_clk_get_optional(component->dev, "mclk"); 289762306a36Sopenharmony_ci if (IS_ERR(da7218->mclk)) { 289862306a36Sopenharmony_ci ret = PTR_ERR(da7218->mclk); 289962306a36Sopenharmony_ci goto err_disable_reg; 290062306a36Sopenharmony_ci } 290162306a36Sopenharmony_ci 290262306a36Sopenharmony_ci /* Default PC to free-running */ 290362306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_PC_COUNT, DA7218_PC_FREERUN_MASK); 290462306a36Sopenharmony_ci 290562306a36Sopenharmony_ci /* 290662306a36Sopenharmony_ci * Default Output Filter mixers to off otherwise DAPM will power 290762306a36Sopenharmony_ci * Mic to HP passthrough paths by default at startup. 290862306a36Sopenharmony_ci */ 290962306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_DROUTING_OUTFILT_1L, 0); 291062306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_DROUTING_OUTFILT_1R, 0); 291162306a36Sopenharmony_ci 291262306a36Sopenharmony_ci /* Default CP to normal load, power mode */ 291362306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_CP_CTRL, 291462306a36Sopenharmony_ci DA7218_CP_SMALL_SWITCH_FREQ_EN_MASK, 0); 291562306a36Sopenharmony_ci 291662306a36Sopenharmony_ci /* Default gain ramping */ 291762306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_MIXIN_1_CTRL, 291862306a36Sopenharmony_ci DA7218_MIXIN_1_AMP_RAMP_EN_MASK, 291962306a36Sopenharmony_ci DA7218_MIXIN_1_AMP_RAMP_EN_MASK); 292062306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_MIXIN_2_CTRL, 292162306a36Sopenharmony_ci DA7218_MIXIN_2_AMP_RAMP_EN_MASK, 292262306a36Sopenharmony_ci DA7218_MIXIN_2_AMP_RAMP_EN_MASK); 292362306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_IN_1L_FILTER_CTRL, 292462306a36Sopenharmony_ci DA7218_IN_1L_RAMP_EN_MASK, 292562306a36Sopenharmony_ci DA7218_IN_1L_RAMP_EN_MASK); 292662306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_IN_1R_FILTER_CTRL, 292762306a36Sopenharmony_ci DA7218_IN_1R_RAMP_EN_MASK, 292862306a36Sopenharmony_ci DA7218_IN_1R_RAMP_EN_MASK); 292962306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_IN_2L_FILTER_CTRL, 293062306a36Sopenharmony_ci DA7218_IN_2L_RAMP_EN_MASK, 293162306a36Sopenharmony_ci DA7218_IN_2L_RAMP_EN_MASK); 293262306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_IN_2R_FILTER_CTRL, 293362306a36Sopenharmony_ci DA7218_IN_2R_RAMP_EN_MASK, 293462306a36Sopenharmony_ci DA7218_IN_2R_RAMP_EN_MASK); 293562306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_DGS_GAIN_CTRL, 293662306a36Sopenharmony_ci DA7218_DGS_RAMP_EN_MASK, DA7218_DGS_RAMP_EN_MASK); 293762306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_OUT_1L_FILTER_CTRL, 293862306a36Sopenharmony_ci DA7218_OUT_1L_RAMP_EN_MASK, 293962306a36Sopenharmony_ci DA7218_OUT_1L_RAMP_EN_MASK); 294062306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_OUT_1R_FILTER_CTRL, 294162306a36Sopenharmony_ci DA7218_OUT_1R_RAMP_EN_MASK, 294262306a36Sopenharmony_ci DA7218_OUT_1R_RAMP_EN_MASK); 294362306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_HP_L_CTRL, 294462306a36Sopenharmony_ci DA7218_HP_L_AMP_RAMP_EN_MASK, 294562306a36Sopenharmony_ci DA7218_HP_L_AMP_RAMP_EN_MASK); 294662306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_HP_R_CTRL, 294762306a36Sopenharmony_ci DA7218_HP_R_AMP_RAMP_EN_MASK, 294862306a36Sopenharmony_ci DA7218_HP_R_AMP_RAMP_EN_MASK); 294962306a36Sopenharmony_ci 295062306a36Sopenharmony_ci /* Default infinite tone gen, start/stop by Kcontrol */ 295162306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_TONE_GEN_CYCLES, DA7218_BEEP_CYCLES_MASK); 295262306a36Sopenharmony_ci 295362306a36Sopenharmony_ci /* DA7217 specific config */ 295462306a36Sopenharmony_ci if (da7218->dev_id == DA7217_DEV_ID) { 295562306a36Sopenharmony_ci snd_soc_component_update_bits(component, DA7218_HP_DIFF_CTRL, 295662306a36Sopenharmony_ci DA7218_HP_AMP_DIFF_MODE_EN_MASK, 295762306a36Sopenharmony_ci DA7218_HP_AMP_DIFF_MODE_EN_MASK); 295862306a36Sopenharmony_ci 295962306a36Sopenharmony_ci /* Only DA7218 supports HP detect, mask off for DA7217 */ 296062306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_EVENT_MASK, 296162306a36Sopenharmony_ci DA7218_HPLDET_JACK_EVENT_IRQ_MSK_MASK); 296262306a36Sopenharmony_ci } 296362306a36Sopenharmony_ci 296462306a36Sopenharmony_ci if (da7218->irq) { 296562306a36Sopenharmony_ci ret = devm_request_threaded_irq(component->dev, da7218->irq, NULL, 296662306a36Sopenharmony_ci da7218_irq_thread, 296762306a36Sopenharmony_ci IRQF_TRIGGER_LOW | IRQF_ONESHOT, 296862306a36Sopenharmony_ci "da7218", component); 296962306a36Sopenharmony_ci if (ret != 0) { 297062306a36Sopenharmony_ci dev_err(component->dev, "Failed to request IRQ %d: %d\n", 297162306a36Sopenharmony_ci da7218->irq, ret); 297262306a36Sopenharmony_ci goto err_disable_reg; 297362306a36Sopenharmony_ci } 297462306a36Sopenharmony_ci 297562306a36Sopenharmony_ci } 297662306a36Sopenharmony_ci 297762306a36Sopenharmony_ci return 0; 297862306a36Sopenharmony_ci 297962306a36Sopenharmony_cierr_disable_reg: 298062306a36Sopenharmony_ci regulator_bulk_disable(DA7218_NUM_SUPPLIES, da7218->supplies); 298162306a36Sopenharmony_ci 298262306a36Sopenharmony_ci return ret; 298362306a36Sopenharmony_ci} 298462306a36Sopenharmony_ci 298562306a36Sopenharmony_cistatic void da7218_remove(struct snd_soc_component *component) 298662306a36Sopenharmony_ci{ 298762306a36Sopenharmony_ci struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component); 298862306a36Sopenharmony_ci 298962306a36Sopenharmony_ci regulator_bulk_disable(DA7218_NUM_SUPPLIES, da7218->supplies); 299062306a36Sopenharmony_ci} 299162306a36Sopenharmony_ci 299262306a36Sopenharmony_ci#ifdef CONFIG_PM 299362306a36Sopenharmony_cistatic int da7218_suspend(struct snd_soc_component *component) 299462306a36Sopenharmony_ci{ 299562306a36Sopenharmony_ci struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component); 299662306a36Sopenharmony_ci 299762306a36Sopenharmony_ci da7218_set_bias_level(component, SND_SOC_BIAS_OFF); 299862306a36Sopenharmony_ci 299962306a36Sopenharmony_ci /* Put device into standby mode if jack detection disabled */ 300062306a36Sopenharmony_ci if (!da7218->jack) 300162306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_SYSTEM_ACTIVE, 0); 300262306a36Sopenharmony_ci 300362306a36Sopenharmony_ci return 0; 300462306a36Sopenharmony_ci} 300562306a36Sopenharmony_ci 300662306a36Sopenharmony_cistatic int da7218_resume(struct snd_soc_component *component) 300762306a36Sopenharmony_ci{ 300862306a36Sopenharmony_ci struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component); 300962306a36Sopenharmony_ci 301062306a36Sopenharmony_ci /* Put device into active mode if previously moved to standby */ 301162306a36Sopenharmony_ci if (!da7218->jack) 301262306a36Sopenharmony_ci snd_soc_component_write(component, DA7218_SYSTEM_ACTIVE, 301362306a36Sopenharmony_ci DA7218_SYSTEM_ACTIVE_MASK); 301462306a36Sopenharmony_ci 301562306a36Sopenharmony_ci da7218_set_bias_level(component, SND_SOC_BIAS_STANDBY); 301662306a36Sopenharmony_ci 301762306a36Sopenharmony_ci return 0; 301862306a36Sopenharmony_ci} 301962306a36Sopenharmony_ci#else 302062306a36Sopenharmony_ci#define da7218_suspend NULL 302162306a36Sopenharmony_ci#define da7218_resume NULL 302262306a36Sopenharmony_ci#endif 302362306a36Sopenharmony_ci 302462306a36Sopenharmony_cistatic const struct snd_soc_component_driver soc_component_dev_da7218 = { 302562306a36Sopenharmony_ci .probe = da7218_probe, 302662306a36Sopenharmony_ci .remove = da7218_remove, 302762306a36Sopenharmony_ci .suspend = da7218_suspend, 302862306a36Sopenharmony_ci .resume = da7218_resume, 302962306a36Sopenharmony_ci .set_bias_level = da7218_set_bias_level, 303062306a36Sopenharmony_ci .controls = da7218_snd_controls, 303162306a36Sopenharmony_ci .num_controls = ARRAY_SIZE(da7218_snd_controls), 303262306a36Sopenharmony_ci .dapm_widgets = da7218_dapm_widgets, 303362306a36Sopenharmony_ci .num_dapm_widgets = ARRAY_SIZE(da7218_dapm_widgets), 303462306a36Sopenharmony_ci .dapm_routes = da7218_audio_map, 303562306a36Sopenharmony_ci .num_dapm_routes = ARRAY_SIZE(da7218_audio_map), 303662306a36Sopenharmony_ci .idle_bias_on = 1, 303762306a36Sopenharmony_ci .use_pmdown_time = 1, 303862306a36Sopenharmony_ci .endianness = 1, 303962306a36Sopenharmony_ci}; 304062306a36Sopenharmony_ci 304162306a36Sopenharmony_ci 304262306a36Sopenharmony_ci/* 304362306a36Sopenharmony_ci * Regmap configs 304462306a36Sopenharmony_ci */ 304562306a36Sopenharmony_ci 304662306a36Sopenharmony_cistatic struct reg_default da7218_reg_defaults[] = { 304762306a36Sopenharmony_ci { DA7218_SYSTEM_ACTIVE, 0x00 }, 304862306a36Sopenharmony_ci { DA7218_CIF_CTRL, 0x00 }, 304962306a36Sopenharmony_ci { DA7218_SPARE1, 0x00 }, 305062306a36Sopenharmony_ci { DA7218_SR, 0xAA }, 305162306a36Sopenharmony_ci { DA7218_PC_COUNT, 0x02 }, 305262306a36Sopenharmony_ci { DA7218_GAIN_RAMP_CTRL, 0x00 }, 305362306a36Sopenharmony_ci { DA7218_CIF_TIMEOUT_CTRL, 0x01 }, 305462306a36Sopenharmony_ci { DA7218_SYSTEM_MODES_INPUT, 0x00 }, 305562306a36Sopenharmony_ci { DA7218_SYSTEM_MODES_OUTPUT, 0x00 }, 305662306a36Sopenharmony_ci { DA7218_IN_1L_FILTER_CTRL, 0x00 }, 305762306a36Sopenharmony_ci { DA7218_IN_1R_FILTER_CTRL, 0x00 }, 305862306a36Sopenharmony_ci { DA7218_IN_2L_FILTER_CTRL, 0x00 }, 305962306a36Sopenharmony_ci { DA7218_IN_2R_FILTER_CTRL, 0x00 }, 306062306a36Sopenharmony_ci { DA7218_OUT_1L_FILTER_CTRL, 0x40 }, 306162306a36Sopenharmony_ci { DA7218_OUT_1R_FILTER_CTRL, 0x40 }, 306262306a36Sopenharmony_ci { DA7218_OUT_1_HPF_FILTER_CTRL, 0x80 }, 306362306a36Sopenharmony_ci { DA7218_OUT_1_EQ_12_FILTER_CTRL, 0x77 }, 306462306a36Sopenharmony_ci { DA7218_OUT_1_EQ_34_FILTER_CTRL, 0x77 }, 306562306a36Sopenharmony_ci { DA7218_OUT_1_EQ_5_FILTER_CTRL, 0x07 }, 306662306a36Sopenharmony_ci { DA7218_OUT_1_BIQ_5STAGE_CTRL, 0x40 }, 306762306a36Sopenharmony_ci { DA7218_OUT_1_BIQ_5STAGE_DATA, 0x00 }, 306862306a36Sopenharmony_ci { DA7218_OUT_1_BIQ_5STAGE_ADDR, 0x00 }, 306962306a36Sopenharmony_ci { DA7218_MIXIN_1_CTRL, 0x48 }, 307062306a36Sopenharmony_ci { DA7218_MIXIN_1_GAIN, 0x03 }, 307162306a36Sopenharmony_ci { DA7218_MIXIN_2_CTRL, 0x48 }, 307262306a36Sopenharmony_ci { DA7218_MIXIN_2_GAIN, 0x03 }, 307362306a36Sopenharmony_ci { DA7218_ALC_CTRL1, 0x00 }, 307462306a36Sopenharmony_ci { DA7218_ALC_CTRL2, 0x00 }, 307562306a36Sopenharmony_ci { DA7218_ALC_CTRL3, 0x00 }, 307662306a36Sopenharmony_ci { DA7218_ALC_NOISE, 0x3F }, 307762306a36Sopenharmony_ci { DA7218_ALC_TARGET_MIN, 0x3F }, 307862306a36Sopenharmony_ci { DA7218_ALC_TARGET_MAX, 0x00 }, 307962306a36Sopenharmony_ci { DA7218_ALC_GAIN_LIMITS, 0xFF }, 308062306a36Sopenharmony_ci { DA7218_ALC_ANA_GAIN_LIMITS, 0x71 }, 308162306a36Sopenharmony_ci { DA7218_ALC_ANTICLIP_CTRL, 0x00 }, 308262306a36Sopenharmony_ci { DA7218_AGS_ENABLE, 0x00 }, 308362306a36Sopenharmony_ci { DA7218_AGS_TRIGGER, 0x09 }, 308462306a36Sopenharmony_ci { DA7218_AGS_ATT_MAX, 0x00 }, 308562306a36Sopenharmony_ci { DA7218_AGS_TIMEOUT, 0x00 }, 308662306a36Sopenharmony_ci { DA7218_AGS_ANTICLIP_CTRL, 0x00 }, 308762306a36Sopenharmony_ci { DA7218_ENV_TRACK_CTRL, 0x00 }, 308862306a36Sopenharmony_ci { DA7218_LVL_DET_CTRL, 0x00 }, 308962306a36Sopenharmony_ci { DA7218_LVL_DET_LEVEL, 0x7F }, 309062306a36Sopenharmony_ci { DA7218_DGS_TRIGGER, 0x24 }, 309162306a36Sopenharmony_ci { DA7218_DGS_ENABLE, 0x00 }, 309262306a36Sopenharmony_ci { DA7218_DGS_RISE_FALL, 0x50 }, 309362306a36Sopenharmony_ci { DA7218_DGS_SYNC_DELAY, 0xA3 }, 309462306a36Sopenharmony_ci { DA7218_DGS_SYNC_DELAY2, 0x31 }, 309562306a36Sopenharmony_ci { DA7218_DGS_SYNC_DELAY3, 0x11 }, 309662306a36Sopenharmony_ci { DA7218_DGS_LEVELS, 0x01 }, 309762306a36Sopenharmony_ci { DA7218_DGS_GAIN_CTRL, 0x74 }, 309862306a36Sopenharmony_ci { DA7218_DROUTING_OUTDAI_1L, 0x01 }, 309962306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_1L_INFILT_1L_GAIN, 0x1C }, 310062306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_1L_INFILT_1R_GAIN, 0x1C }, 310162306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_1L_INFILT_2L_GAIN, 0x1C }, 310262306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_1L_INFILT_2R_GAIN, 0x1C }, 310362306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_1L_TONEGEN_GAIN, 0x1C }, 310462306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_1L_INDAI_1L_GAIN, 0x1C }, 310562306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_1L_INDAI_1R_GAIN, 0x1C }, 310662306a36Sopenharmony_ci { DA7218_DROUTING_OUTDAI_1R, 0x04 }, 310762306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_1R_INFILT_1L_GAIN, 0x1C }, 310862306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_1R_INFILT_1R_GAIN, 0x1C }, 310962306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_1R_INFILT_2L_GAIN, 0x1C }, 311062306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_1R_INFILT_2R_GAIN, 0x1C }, 311162306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_1R_TONEGEN_GAIN, 0x1C }, 311262306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_1R_INDAI_1L_GAIN, 0x1C }, 311362306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_1R_INDAI_1R_GAIN, 0x1C }, 311462306a36Sopenharmony_ci { DA7218_DROUTING_OUTFILT_1L, 0x01 }, 311562306a36Sopenharmony_ci { DA7218_DMIX_OUTFILT_1L_INFILT_1L_GAIN, 0x1C }, 311662306a36Sopenharmony_ci { DA7218_DMIX_OUTFILT_1L_INFILT_1R_GAIN, 0x1C }, 311762306a36Sopenharmony_ci { DA7218_DMIX_OUTFILT_1L_INFILT_2L_GAIN, 0x1C }, 311862306a36Sopenharmony_ci { DA7218_DMIX_OUTFILT_1L_INFILT_2R_GAIN, 0x1C }, 311962306a36Sopenharmony_ci { DA7218_DMIX_OUTFILT_1L_TONEGEN_GAIN, 0x1C }, 312062306a36Sopenharmony_ci { DA7218_DMIX_OUTFILT_1L_INDAI_1L_GAIN, 0x1C }, 312162306a36Sopenharmony_ci { DA7218_DMIX_OUTFILT_1L_INDAI_1R_GAIN, 0x1C }, 312262306a36Sopenharmony_ci { DA7218_DROUTING_OUTFILT_1R, 0x04 }, 312362306a36Sopenharmony_ci { DA7218_DMIX_OUTFILT_1R_INFILT_1L_GAIN, 0x1C }, 312462306a36Sopenharmony_ci { DA7218_DMIX_OUTFILT_1R_INFILT_1R_GAIN, 0x1C }, 312562306a36Sopenharmony_ci { DA7218_DMIX_OUTFILT_1R_INFILT_2L_GAIN, 0x1C }, 312662306a36Sopenharmony_ci { DA7218_DMIX_OUTFILT_1R_INFILT_2R_GAIN, 0x1C }, 312762306a36Sopenharmony_ci { DA7218_DMIX_OUTFILT_1R_TONEGEN_GAIN, 0x1C }, 312862306a36Sopenharmony_ci { DA7218_DMIX_OUTFILT_1R_INDAI_1L_GAIN, 0x1C }, 312962306a36Sopenharmony_ci { DA7218_DMIX_OUTFILT_1R_INDAI_1R_GAIN, 0x1C }, 313062306a36Sopenharmony_ci { DA7218_DROUTING_OUTDAI_2L, 0x04 }, 313162306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_2L_INFILT_1L_GAIN, 0x1C }, 313262306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_2L_INFILT_1R_GAIN, 0x1C }, 313362306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_2L_INFILT_2L_GAIN, 0x1C }, 313462306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_2L_INFILT_2R_GAIN, 0x1C }, 313562306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_2L_TONEGEN_GAIN, 0x1C }, 313662306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_2L_INDAI_1L_GAIN, 0x1C }, 313762306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_2L_INDAI_1R_GAIN, 0x1C }, 313862306a36Sopenharmony_ci { DA7218_DROUTING_OUTDAI_2R, 0x08 }, 313962306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_2R_INFILT_1L_GAIN, 0x1C }, 314062306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_2R_INFILT_1R_GAIN, 0x1C }, 314162306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_2R_INFILT_2L_GAIN, 0x1C }, 314262306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_2R_INFILT_2R_GAIN, 0x1C }, 314362306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_2R_TONEGEN_GAIN, 0x1C }, 314462306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_2R_INDAI_1L_GAIN, 0x1C }, 314562306a36Sopenharmony_ci { DA7218_DMIX_OUTDAI_2R_INDAI_1R_GAIN, 0x1C }, 314662306a36Sopenharmony_ci { DA7218_DAI_CTRL, 0x28 }, 314762306a36Sopenharmony_ci { DA7218_DAI_TDM_CTRL, 0x40 }, 314862306a36Sopenharmony_ci { DA7218_DAI_OFFSET_LOWER, 0x00 }, 314962306a36Sopenharmony_ci { DA7218_DAI_OFFSET_UPPER, 0x00 }, 315062306a36Sopenharmony_ci { DA7218_DAI_CLK_MODE, 0x01 }, 315162306a36Sopenharmony_ci { DA7218_PLL_CTRL, 0x04 }, 315262306a36Sopenharmony_ci { DA7218_PLL_FRAC_TOP, 0x00 }, 315362306a36Sopenharmony_ci { DA7218_PLL_FRAC_BOT, 0x00 }, 315462306a36Sopenharmony_ci { DA7218_PLL_INTEGER, 0x20 }, 315562306a36Sopenharmony_ci { DA7218_DAC_NG_CTRL, 0x00 }, 315662306a36Sopenharmony_ci { DA7218_DAC_NG_SETUP_TIME, 0x00 }, 315762306a36Sopenharmony_ci { DA7218_DAC_NG_OFF_THRESH, 0x00 }, 315862306a36Sopenharmony_ci { DA7218_DAC_NG_ON_THRESH, 0x00 }, 315962306a36Sopenharmony_ci { DA7218_TONE_GEN_CFG2, 0x00 }, 316062306a36Sopenharmony_ci { DA7218_TONE_GEN_FREQ1_L, 0x55 }, 316162306a36Sopenharmony_ci { DA7218_TONE_GEN_FREQ1_U, 0x15 }, 316262306a36Sopenharmony_ci { DA7218_TONE_GEN_FREQ2_L, 0x00 }, 316362306a36Sopenharmony_ci { DA7218_TONE_GEN_FREQ2_U, 0x40 }, 316462306a36Sopenharmony_ci { DA7218_TONE_GEN_CYCLES, 0x00 }, 316562306a36Sopenharmony_ci { DA7218_TONE_GEN_ON_PER, 0x02 }, 316662306a36Sopenharmony_ci { DA7218_TONE_GEN_OFF_PER, 0x01 }, 316762306a36Sopenharmony_ci { DA7218_CP_CTRL, 0x60 }, 316862306a36Sopenharmony_ci { DA7218_CP_DELAY, 0x11 }, 316962306a36Sopenharmony_ci { DA7218_CP_VOL_THRESHOLD1, 0x0E }, 317062306a36Sopenharmony_ci { DA7218_MIC_1_CTRL, 0x40 }, 317162306a36Sopenharmony_ci { DA7218_MIC_1_GAIN, 0x01 }, 317262306a36Sopenharmony_ci { DA7218_MIC_1_SELECT, 0x00 }, 317362306a36Sopenharmony_ci { DA7218_MIC_2_CTRL, 0x40 }, 317462306a36Sopenharmony_ci { DA7218_MIC_2_GAIN, 0x01 }, 317562306a36Sopenharmony_ci { DA7218_MIC_2_SELECT, 0x00 }, 317662306a36Sopenharmony_ci { DA7218_IN_1_HPF_FILTER_CTRL, 0x80 }, 317762306a36Sopenharmony_ci { DA7218_IN_2_HPF_FILTER_CTRL, 0x80 }, 317862306a36Sopenharmony_ci { DA7218_ADC_1_CTRL, 0x07 }, 317962306a36Sopenharmony_ci { DA7218_ADC_2_CTRL, 0x07 }, 318062306a36Sopenharmony_ci { DA7218_MIXOUT_L_CTRL, 0x00 }, 318162306a36Sopenharmony_ci { DA7218_MIXOUT_L_GAIN, 0x03 }, 318262306a36Sopenharmony_ci { DA7218_MIXOUT_R_CTRL, 0x00 }, 318362306a36Sopenharmony_ci { DA7218_MIXOUT_R_GAIN, 0x03 }, 318462306a36Sopenharmony_ci { DA7218_HP_L_CTRL, 0x40 }, 318562306a36Sopenharmony_ci { DA7218_HP_L_GAIN, 0x3B }, 318662306a36Sopenharmony_ci { DA7218_HP_R_CTRL, 0x40 }, 318762306a36Sopenharmony_ci { DA7218_HP_R_GAIN, 0x3B }, 318862306a36Sopenharmony_ci { DA7218_HP_DIFF_CTRL, 0x00 }, 318962306a36Sopenharmony_ci { DA7218_HP_DIFF_UNLOCK, 0xC3 }, 319062306a36Sopenharmony_ci { DA7218_HPLDET_JACK, 0x0B }, 319162306a36Sopenharmony_ci { DA7218_HPLDET_CTRL, 0x00 }, 319262306a36Sopenharmony_ci { DA7218_REFERENCES, 0x08 }, 319362306a36Sopenharmony_ci { DA7218_IO_CTRL, 0x00 }, 319462306a36Sopenharmony_ci { DA7218_LDO_CTRL, 0x00 }, 319562306a36Sopenharmony_ci { DA7218_SIDETONE_CTRL, 0x40 }, 319662306a36Sopenharmony_ci { DA7218_SIDETONE_IN_SELECT, 0x00 }, 319762306a36Sopenharmony_ci { DA7218_SIDETONE_GAIN, 0x1C }, 319862306a36Sopenharmony_ci { DA7218_DROUTING_ST_OUTFILT_1L, 0x01 }, 319962306a36Sopenharmony_ci { DA7218_DROUTING_ST_OUTFILT_1R, 0x02 }, 320062306a36Sopenharmony_ci { DA7218_SIDETONE_BIQ_3STAGE_DATA, 0x00 }, 320162306a36Sopenharmony_ci { DA7218_SIDETONE_BIQ_3STAGE_ADDR, 0x00 }, 320262306a36Sopenharmony_ci { DA7218_EVENT_MASK, 0x00 }, 320362306a36Sopenharmony_ci { DA7218_DMIC_1_CTRL, 0x00 }, 320462306a36Sopenharmony_ci { DA7218_DMIC_2_CTRL, 0x00 }, 320562306a36Sopenharmony_ci { DA7218_IN_1L_GAIN, 0x6F }, 320662306a36Sopenharmony_ci { DA7218_IN_1R_GAIN, 0x6F }, 320762306a36Sopenharmony_ci { DA7218_IN_2L_GAIN, 0x6F }, 320862306a36Sopenharmony_ci { DA7218_IN_2R_GAIN, 0x6F }, 320962306a36Sopenharmony_ci { DA7218_OUT_1L_GAIN, 0x6F }, 321062306a36Sopenharmony_ci { DA7218_OUT_1R_GAIN, 0x6F }, 321162306a36Sopenharmony_ci { DA7218_MICBIAS_CTRL, 0x00 }, 321262306a36Sopenharmony_ci { DA7218_MICBIAS_EN, 0x00 }, 321362306a36Sopenharmony_ci}; 321462306a36Sopenharmony_ci 321562306a36Sopenharmony_cistatic bool da7218_volatile_register(struct device *dev, unsigned int reg) 321662306a36Sopenharmony_ci{ 321762306a36Sopenharmony_ci switch (reg) { 321862306a36Sopenharmony_ci case DA7218_STATUS1: 321962306a36Sopenharmony_ci case DA7218_SOFT_RESET: 322062306a36Sopenharmony_ci case DA7218_SYSTEM_STATUS: 322162306a36Sopenharmony_ci case DA7218_CALIB_CTRL: 322262306a36Sopenharmony_ci case DA7218_CALIB_OFFSET_AUTO_M_1: 322362306a36Sopenharmony_ci case DA7218_CALIB_OFFSET_AUTO_U_1: 322462306a36Sopenharmony_ci case DA7218_CALIB_OFFSET_AUTO_M_2: 322562306a36Sopenharmony_ci case DA7218_CALIB_OFFSET_AUTO_U_2: 322662306a36Sopenharmony_ci case DA7218_PLL_STATUS: 322762306a36Sopenharmony_ci case DA7218_PLL_REFOSC_CAL: 322862306a36Sopenharmony_ci case DA7218_TONE_GEN_CFG1: 322962306a36Sopenharmony_ci case DA7218_ADC_MODE: 323062306a36Sopenharmony_ci case DA7218_HP_SNGL_CTRL: 323162306a36Sopenharmony_ci case DA7218_HPLDET_TEST: 323262306a36Sopenharmony_ci case DA7218_EVENT_STATUS: 323362306a36Sopenharmony_ci case DA7218_EVENT: 323462306a36Sopenharmony_ci return true; 323562306a36Sopenharmony_ci default: 323662306a36Sopenharmony_ci return false; 323762306a36Sopenharmony_ci } 323862306a36Sopenharmony_ci} 323962306a36Sopenharmony_ci 324062306a36Sopenharmony_cistatic const struct regmap_config da7218_regmap_config = { 324162306a36Sopenharmony_ci .reg_bits = 8, 324262306a36Sopenharmony_ci .val_bits = 8, 324362306a36Sopenharmony_ci 324462306a36Sopenharmony_ci .max_register = DA7218_MICBIAS_EN, 324562306a36Sopenharmony_ci .reg_defaults = da7218_reg_defaults, 324662306a36Sopenharmony_ci .num_reg_defaults = ARRAY_SIZE(da7218_reg_defaults), 324762306a36Sopenharmony_ci .volatile_reg = da7218_volatile_register, 324862306a36Sopenharmony_ci .cache_type = REGCACHE_RBTREE, 324962306a36Sopenharmony_ci}; 325062306a36Sopenharmony_ci 325162306a36Sopenharmony_ci 325262306a36Sopenharmony_ci/* 325362306a36Sopenharmony_ci * I2C layer 325462306a36Sopenharmony_ci */ 325562306a36Sopenharmony_ci 325662306a36Sopenharmony_cistatic const struct i2c_device_id da7218_i2c_id[]; 325762306a36Sopenharmony_ci 325862306a36Sopenharmony_cistatic inline int da7218_i2c_get_id(struct i2c_client *i2c) 325962306a36Sopenharmony_ci{ 326062306a36Sopenharmony_ci const struct i2c_device_id *id = i2c_match_id(da7218_i2c_id, i2c); 326162306a36Sopenharmony_ci 326262306a36Sopenharmony_ci if (id) 326362306a36Sopenharmony_ci return (uintptr_t)id->driver_data; 326462306a36Sopenharmony_ci else 326562306a36Sopenharmony_ci return -EINVAL; 326662306a36Sopenharmony_ci} 326762306a36Sopenharmony_ci 326862306a36Sopenharmony_cistatic int da7218_i2c_probe(struct i2c_client *i2c) 326962306a36Sopenharmony_ci{ 327062306a36Sopenharmony_ci struct da7218_priv *da7218; 327162306a36Sopenharmony_ci int ret; 327262306a36Sopenharmony_ci 327362306a36Sopenharmony_ci da7218 = devm_kzalloc(&i2c->dev, sizeof(*da7218), GFP_KERNEL); 327462306a36Sopenharmony_ci if (!da7218) 327562306a36Sopenharmony_ci return -ENOMEM; 327662306a36Sopenharmony_ci 327762306a36Sopenharmony_ci i2c_set_clientdata(i2c, da7218); 327862306a36Sopenharmony_ci 327962306a36Sopenharmony_ci if (i2c->dev.of_node) 328062306a36Sopenharmony_ci da7218->dev_id = da7218_of_get_id(&i2c->dev); 328162306a36Sopenharmony_ci else 328262306a36Sopenharmony_ci da7218->dev_id = da7218_i2c_get_id(i2c); 328362306a36Sopenharmony_ci 328462306a36Sopenharmony_ci if ((da7218->dev_id != DA7217_DEV_ID) && 328562306a36Sopenharmony_ci (da7218->dev_id != DA7218_DEV_ID)) { 328662306a36Sopenharmony_ci dev_err(&i2c->dev, "Invalid device Id\n"); 328762306a36Sopenharmony_ci return -EINVAL; 328862306a36Sopenharmony_ci } 328962306a36Sopenharmony_ci 329062306a36Sopenharmony_ci da7218->irq = i2c->irq; 329162306a36Sopenharmony_ci 329262306a36Sopenharmony_ci da7218->regmap = devm_regmap_init_i2c(i2c, &da7218_regmap_config); 329362306a36Sopenharmony_ci if (IS_ERR(da7218->regmap)) { 329462306a36Sopenharmony_ci ret = PTR_ERR(da7218->regmap); 329562306a36Sopenharmony_ci dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); 329662306a36Sopenharmony_ci return ret; 329762306a36Sopenharmony_ci } 329862306a36Sopenharmony_ci 329962306a36Sopenharmony_ci ret = devm_snd_soc_register_component(&i2c->dev, 330062306a36Sopenharmony_ci &soc_component_dev_da7218, &da7218_dai, 1); 330162306a36Sopenharmony_ci if (ret < 0) { 330262306a36Sopenharmony_ci dev_err(&i2c->dev, "Failed to register da7218 component: %d\n", 330362306a36Sopenharmony_ci ret); 330462306a36Sopenharmony_ci } 330562306a36Sopenharmony_ci return ret; 330662306a36Sopenharmony_ci} 330762306a36Sopenharmony_ci 330862306a36Sopenharmony_cistatic const struct i2c_device_id da7218_i2c_id[] = { 330962306a36Sopenharmony_ci { "da7217", DA7217_DEV_ID }, 331062306a36Sopenharmony_ci { "da7218", DA7218_DEV_ID }, 331162306a36Sopenharmony_ci { } 331262306a36Sopenharmony_ci}; 331362306a36Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, da7218_i2c_id); 331462306a36Sopenharmony_ci 331562306a36Sopenharmony_cistatic struct i2c_driver da7218_i2c_driver = { 331662306a36Sopenharmony_ci .driver = { 331762306a36Sopenharmony_ci .name = "da7218", 331862306a36Sopenharmony_ci .of_match_table = da7218_of_match, 331962306a36Sopenharmony_ci }, 332062306a36Sopenharmony_ci .probe = da7218_i2c_probe, 332162306a36Sopenharmony_ci .id_table = da7218_i2c_id, 332262306a36Sopenharmony_ci}; 332362306a36Sopenharmony_ci 332462306a36Sopenharmony_cimodule_i2c_driver(da7218_i2c_driver); 332562306a36Sopenharmony_ci 332662306a36Sopenharmony_ciMODULE_DESCRIPTION("ASoC DA7218 Codec driver"); 332762306a36Sopenharmony_ciMODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>"); 332862306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 3329