brintos

brintos / linux-shallow public Read only

0
0
Text · 107.2 KiB · 8aacd73 Raw
3304 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * da7218.c - DA7218 ALSA SoC Codec Driver4 *5 * Copyright (c) 2015 Dialog Semiconductor6 *7 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>8 */9 10#include <linux/clk.h>11#include <linux/i2c.h>12#include <linux/of.h>13#include <linux/regmap.h>14#include <linux/slab.h>15#include <linux/pm.h>16#include <linux/module.h>17#include <linux/delay.h>18#include <linux/regulator/consumer.h>19#include <sound/pcm.h>20#include <sound/pcm_params.h>21#include <sound/soc.h>22#include <sound/soc-dapm.h>23#include <sound/jack.h>24#include <sound/initval.h>25#include <sound/tlv.h>26#include <asm/div64.h>27 28#include <sound/da7218.h>29#include "da7218.h"30 31 32/*33 * TLVs and Enums34 */35 36/* Input TLVs */37static const DECLARE_TLV_DB_SCALE(da7218_mic_gain_tlv, -600, 600, 0);38static const DECLARE_TLV_DB_SCALE(da7218_mixin_gain_tlv, -450, 150, 0);39static const DECLARE_TLV_DB_SCALE(da7218_in_dig_gain_tlv, -8325, 75, 0);40static const DECLARE_TLV_DB_SCALE(da7218_ags_trigger_tlv, -9000, 600, 0);41static const DECLARE_TLV_DB_SCALE(da7218_ags_att_max_tlv, 0, 600, 0);42static const DECLARE_TLV_DB_SCALE(da7218_alc_threshold_tlv, -9450, 150, 0);43static const DECLARE_TLV_DB_SCALE(da7218_alc_gain_tlv, 0, 600, 0);44static const DECLARE_TLV_DB_SCALE(da7218_alc_ana_gain_tlv, 0, 600, 0);45 46/* Input/Output TLVs */47static const DECLARE_TLV_DB_SCALE(da7218_dmix_gain_tlv, -4200, 150, 0);48 49/* Output TLVs */50static const DECLARE_TLV_DB_SCALE(da7218_dgs_trigger_tlv, -9450, 150, 0);51static const DECLARE_TLV_DB_SCALE(da7218_dgs_anticlip_tlv, -4200, 600, 0);52static const DECLARE_TLV_DB_SCALE(da7218_dgs_signal_tlv, -9000, 600, 0);53static const DECLARE_TLV_DB_SCALE(da7218_out_eq_band_tlv, -1050, 150, 0);54static const DECLARE_TLV_DB_SCALE(da7218_out_dig_gain_tlv, -8325, 75, 0);55static const DECLARE_TLV_DB_SCALE(da7218_dac_ng_threshold_tlv, -10200, 600, 0);56static const DECLARE_TLV_DB_SCALE(da7218_mixout_gain_tlv, -100, 50, 0);57static const DECLARE_TLV_DB_SCALE(da7218_hp_gain_tlv, -5700, 150, 0);58 59/* Input Enums */60static const char * const da7218_alc_attack_rate_txt[] = {61	"7.33/fs", "14.66/fs", "29.32/fs", "58.64/fs", "117.3/fs", "234.6/fs",62	"469.1/fs", "938.2/fs", "1876/fs", "3753/fs", "7506/fs", "15012/fs",63	"30024/fs",64};65 66static const struct soc_enum da7218_alc_attack_rate =67	SOC_ENUM_SINGLE(DA7218_ALC_CTRL2, DA7218_ALC_ATTACK_SHIFT,68			DA7218_ALC_ATTACK_MAX, da7218_alc_attack_rate_txt);69 70static const char * const da7218_alc_release_rate_txt[] = {71	"28.66/fs", "57.33/fs", "114.6/fs", "229.3/fs", "458.6/fs", "917.1/fs",72	"1834/fs", "3668/fs", "7337/fs", "14674/fs", "29348/fs",73};74 75static const struct soc_enum da7218_alc_release_rate =76	SOC_ENUM_SINGLE(DA7218_ALC_CTRL2, DA7218_ALC_RELEASE_SHIFT,77			DA7218_ALC_RELEASE_MAX, da7218_alc_release_rate_txt);78 79static const char * const da7218_alc_hold_time_txt[] = {80	"62/fs", "124/fs", "248/fs", "496/fs", "992/fs", "1984/fs", "3968/fs",81	"7936/fs", "15872/fs", "31744/fs", "63488/fs", "126976/fs",82	"253952/fs", "507904/fs", "1015808/fs", "2031616/fs"83};84 85static const struct soc_enum da7218_alc_hold_time =86	SOC_ENUM_SINGLE(DA7218_ALC_CTRL3, DA7218_ALC_HOLD_SHIFT,87			DA7218_ALC_HOLD_MAX, da7218_alc_hold_time_txt);88 89static const char * const da7218_alc_anticlip_step_txt[] = {90	"0.034dB/fs", "0.068dB/fs", "0.136dB/fs", "0.272dB/fs",91};92 93static const struct soc_enum da7218_alc_anticlip_step =94	SOC_ENUM_SINGLE(DA7218_ALC_ANTICLIP_CTRL,95			DA7218_ALC_ANTICLIP_STEP_SHIFT,96			DA7218_ALC_ANTICLIP_STEP_MAX,97			da7218_alc_anticlip_step_txt);98 99static const char * const da7218_integ_rate_txt[] = {100	"1/4", "1/16", "1/256", "1/65536"101};102 103static const struct soc_enum da7218_integ_attack_rate =104	SOC_ENUM_SINGLE(DA7218_ENV_TRACK_CTRL, DA7218_INTEG_ATTACK_SHIFT,105			DA7218_INTEG_MAX, da7218_integ_rate_txt);106 107static const struct soc_enum da7218_integ_release_rate =108	SOC_ENUM_SINGLE(DA7218_ENV_TRACK_CTRL, DA7218_INTEG_RELEASE_SHIFT,109			DA7218_INTEG_MAX, da7218_integ_rate_txt);110 111/* Input/Output Enums */112static const char * const da7218_gain_ramp_rate_txt[] = {113	"Nominal Rate * 8", "Nominal Rate", "Nominal Rate / 8",114	"Nominal Rate / 16",115};116 117static const struct soc_enum da7218_gain_ramp_rate =118	SOC_ENUM_SINGLE(DA7218_GAIN_RAMP_CTRL, DA7218_GAIN_RAMP_RATE_SHIFT,119			DA7218_GAIN_RAMP_RATE_MAX, da7218_gain_ramp_rate_txt);120 121static const char * const da7218_hpf_mode_txt[] = {122	"Disabled", "Audio", "Voice",123};124 125static const unsigned int da7218_hpf_mode_val[] = {126	DA7218_HPF_DISABLED, DA7218_HPF_AUDIO_EN, DA7218_HPF_VOICE_EN,127};128 129static const struct soc_enum da7218_in1_hpf_mode =130	SOC_VALUE_ENUM_SINGLE(DA7218_IN_1_HPF_FILTER_CTRL,131			      DA7218_HPF_MODE_SHIFT, DA7218_HPF_MODE_MASK,132			      DA7218_HPF_MODE_MAX, da7218_hpf_mode_txt,133			      da7218_hpf_mode_val);134 135static const struct soc_enum da7218_in2_hpf_mode =136	SOC_VALUE_ENUM_SINGLE(DA7218_IN_2_HPF_FILTER_CTRL,137			      DA7218_HPF_MODE_SHIFT, DA7218_HPF_MODE_MASK,138			      DA7218_HPF_MODE_MAX, da7218_hpf_mode_txt,139			      da7218_hpf_mode_val);140 141static const struct soc_enum da7218_out1_hpf_mode =142	SOC_VALUE_ENUM_SINGLE(DA7218_OUT_1_HPF_FILTER_CTRL,143			      DA7218_HPF_MODE_SHIFT, DA7218_HPF_MODE_MASK,144			      DA7218_HPF_MODE_MAX, da7218_hpf_mode_txt,145			      da7218_hpf_mode_val);146 147static const char * const da7218_audio_hpf_corner_txt[] = {148	"2Hz", "4Hz", "8Hz", "16Hz",149};150 151static const struct soc_enum da7218_in1_audio_hpf_corner =152	SOC_ENUM_SINGLE(DA7218_IN_1_HPF_FILTER_CTRL,153			DA7218_IN_1_AUDIO_HPF_CORNER_SHIFT,154			DA7218_AUDIO_HPF_CORNER_MAX,155			da7218_audio_hpf_corner_txt);156 157static const struct soc_enum da7218_in2_audio_hpf_corner =158	SOC_ENUM_SINGLE(DA7218_IN_2_HPF_FILTER_CTRL,159			DA7218_IN_2_AUDIO_HPF_CORNER_SHIFT,160			DA7218_AUDIO_HPF_CORNER_MAX,161			da7218_audio_hpf_corner_txt);162 163static const struct soc_enum da7218_out1_audio_hpf_corner =164	SOC_ENUM_SINGLE(DA7218_OUT_1_HPF_FILTER_CTRL,165			DA7218_OUT_1_AUDIO_HPF_CORNER_SHIFT,166			DA7218_AUDIO_HPF_CORNER_MAX,167			da7218_audio_hpf_corner_txt);168 169static const char * const da7218_voice_hpf_corner_txt[] = {170	"2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz",171};172 173static const struct soc_enum da7218_in1_voice_hpf_corner =174	SOC_ENUM_SINGLE(DA7218_IN_1_HPF_FILTER_CTRL,175			DA7218_IN_1_VOICE_HPF_CORNER_SHIFT,176			DA7218_VOICE_HPF_CORNER_MAX,177			da7218_voice_hpf_corner_txt);178 179static const struct soc_enum da7218_in2_voice_hpf_corner =180	SOC_ENUM_SINGLE(DA7218_IN_2_HPF_FILTER_CTRL,181			DA7218_IN_2_VOICE_HPF_CORNER_SHIFT,182			DA7218_VOICE_HPF_CORNER_MAX,183			da7218_voice_hpf_corner_txt);184 185static const struct soc_enum da7218_out1_voice_hpf_corner =186	SOC_ENUM_SINGLE(DA7218_OUT_1_HPF_FILTER_CTRL,187			DA7218_OUT_1_VOICE_HPF_CORNER_SHIFT,188			DA7218_VOICE_HPF_CORNER_MAX,189			da7218_voice_hpf_corner_txt);190 191static const char * const da7218_tonegen_dtmf_key_txt[] = {192	"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D",193	"*", "#"194};195 196static const struct soc_enum da7218_tonegen_dtmf_key =197	SOC_ENUM_SINGLE(DA7218_TONE_GEN_CFG1, DA7218_DTMF_REG_SHIFT,198			DA7218_DTMF_REG_MAX, da7218_tonegen_dtmf_key_txt);199 200static const char * const da7218_tonegen_swg_sel_txt[] = {201	"Sum", "SWG1", "SWG2", "SWG1_1-Cos"202};203 204static const struct soc_enum da7218_tonegen_swg_sel =205	SOC_ENUM_SINGLE(DA7218_TONE_GEN_CFG2, DA7218_SWG_SEL_SHIFT,206			DA7218_SWG_SEL_MAX, da7218_tonegen_swg_sel_txt);207 208/* Output Enums */209static const char * const da7218_dgs_rise_coeff_txt[] = {210	"1/1", "1/16", "1/64", "1/256", "1/1024", "1/4096", "1/16384",211};212 213static const struct soc_enum da7218_dgs_rise_coeff =214	SOC_ENUM_SINGLE(DA7218_DGS_RISE_FALL, DA7218_DGS_RISE_COEFF_SHIFT,215			DA7218_DGS_RISE_COEFF_MAX, da7218_dgs_rise_coeff_txt);216 217static const char * const da7218_dgs_fall_coeff_txt[] = {218	"1/4", "1/16", "1/64", "1/256", "1/1024", "1/4096", "1/16384", "1/65536",219};220 221static const struct soc_enum da7218_dgs_fall_coeff =222	SOC_ENUM_SINGLE(DA7218_DGS_RISE_FALL, DA7218_DGS_FALL_COEFF_SHIFT,223			DA7218_DGS_FALL_COEFF_MAX, da7218_dgs_fall_coeff_txt);224 225static const char * const da7218_dac_ng_setup_time_txt[] = {226	"256 Samples", "512 Samples", "1024 Samples", "2048 Samples"227};228 229static const struct soc_enum da7218_dac_ng_setup_time =230	SOC_ENUM_SINGLE(DA7218_DAC_NG_SETUP_TIME,231			DA7218_DAC_NG_SETUP_TIME_SHIFT,232			DA7218_DAC_NG_SETUP_TIME_MAX,233			da7218_dac_ng_setup_time_txt);234 235static const char * const da7218_dac_ng_rampup_txt[] = {236	"0.22ms/dB", "0.0138ms/dB"237};238 239static const struct soc_enum da7218_dac_ng_rampup_rate =240	SOC_ENUM_SINGLE(DA7218_DAC_NG_SETUP_TIME,241			DA7218_DAC_NG_RAMPUP_RATE_SHIFT,242			DA7218_DAC_NG_RAMPUP_RATE_MAX,243			da7218_dac_ng_rampup_txt);244 245static const char * const da7218_dac_ng_rampdown_txt[] = {246	"0.88ms/dB", "14.08ms/dB"247};248 249static const struct soc_enum da7218_dac_ng_rampdown_rate =250	SOC_ENUM_SINGLE(DA7218_DAC_NG_SETUP_TIME,251			DA7218_DAC_NG_RAMPDN_RATE_SHIFT,252			DA7218_DAC_NG_RAMPDN_RATE_MAX,253			da7218_dac_ng_rampdown_txt);254 255static const char * const da7218_cp_mchange_txt[] = {256	"Largest Volume", "DAC Volume", "Signal Magnitude"257};258 259static const unsigned int da7218_cp_mchange_val[] = {260	DA7218_CP_MCHANGE_LARGEST_VOL, DA7218_CP_MCHANGE_DAC_VOL,261	DA7218_CP_MCHANGE_SIG_MAG262};263 264static const struct soc_enum da7218_cp_mchange =265	SOC_VALUE_ENUM_SINGLE(DA7218_CP_CTRL, DA7218_CP_MCHANGE_SHIFT,266			      DA7218_CP_MCHANGE_REL_MASK, DA7218_CP_MCHANGE_MAX,267			      da7218_cp_mchange_txt, da7218_cp_mchange_val);268 269static const char * const da7218_cp_fcontrol_txt[] = {270	"1MHz", "500KHz", "250KHz", "125KHz", "63KHz", "0KHz"271};272 273static const struct soc_enum da7218_cp_fcontrol =274	SOC_ENUM_SINGLE(DA7218_CP_DELAY, DA7218_CP_FCONTROL_SHIFT,275			DA7218_CP_FCONTROL_MAX, da7218_cp_fcontrol_txt);276 277static const char * const da7218_cp_tau_delay_txt[] = {278	"0ms", "2ms", "4ms", "16ms", "64ms", "128ms", "256ms", "512ms"279};280 281static const struct soc_enum da7218_cp_tau_delay =282	SOC_ENUM_SINGLE(DA7218_CP_DELAY, DA7218_CP_TAU_DELAY_SHIFT,283			DA7218_CP_TAU_DELAY_MAX, da7218_cp_tau_delay_txt);284 285/*286 * Control Functions287 */288 289/* ALC */290static void da7218_alc_calib(struct snd_soc_component *component)291{292	u8 mic_1_ctrl, mic_2_ctrl;293	u8 mixin_1_ctrl, mixin_2_ctrl;294	u8 in_1l_filt_ctrl, in_1r_filt_ctrl, in_2l_filt_ctrl, in_2r_filt_ctrl;295	u8 in_1_hpf_ctrl, in_2_hpf_ctrl;296	u8 calib_ctrl;297	int i = 0;298	bool calibrated = false;299 300	/* Save current state of MIC control registers */301	mic_1_ctrl = snd_soc_component_read(component, DA7218_MIC_1_CTRL);302	mic_2_ctrl = snd_soc_component_read(component, DA7218_MIC_2_CTRL);303 304	/* Save current state of input mixer control registers */305	mixin_1_ctrl = snd_soc_component_read(component, DA7218_MIXIN_1_CTRL);306	mixin_2_ctrl = snd_soc_component_read(component, DA7218_MIXIN_2_CTRL);307 308	/* Save current state of input filter control registers */309	in_1l_filt_ctrl = snd_soc_component_read(component, DA7218_IN_1L_FILTER_CTRL);310	in_1r_filt_ctrl = snd_soc_component_read(component, DA7218_IN_1R_FILTER_CTRL);311	in_2l_filt_ctrl = snd_soc_component_read(component, DA7218_IN_2L_FILTER_CTRL);312	in_2r_filt_ctrl = snd_soc_component_read(component, DA7218_IN_2R_FILTER_CTRL);313 314	/* Save current state of input HPF control registers */315	in_1_hpf_ctrl = snd_soc_component_read(component, DA7218_IN_1_HPF_FILTER_CTRL);316	in_2_hpf_ctrl = snd_soc_component_read(component, DA7218_IN_2_HPF_FILTER_CTRL);317 318	/* Enable then Mute MIC PGAs */319	snd_soc_component_update_bits(component, DA7218_MIC_1_CTRL, DA7218_MIC_1_AMP_EN_MASK,320			    DA7218_MIC_1_AMP_EN_MASK);321	snd_soc_component_update_bits(component, DA7218_MIC_2_CTRL, DA7218_MIC_2_AMP_EN_MASK,322			    DA7218_MIC_2_AMP_EN_MASK);323	snd_soc_component_update_bits(component, DA7218_MIC_1_CTRL,324			    DA7218_MIC_1_AMP_MUTE_EN_MASK,325			    DA7218_MIC_1_AMP_MUTE_EN_MASK);326	snd_soc_component_update_bits(component, DA7218_MIC_2_CTRL,327			    DA7218_MIC_2_AMP_MUTE_EN_MASK,328			    DA7218_MIC_2_AMP_MUTE_EN_MASK);329 330	/* Enable input mixers unmuted */331	snd_soc_component_update_bits(component, DA7218_MIXIN_1_CTRL,332			    DA7218_MIXIN_1_AMP_EN_MASK |333			    DA7218_MIXIN_1_AMP_MUTE_EN_MASK,334			    DA7218_MIXIN_1_AMP_EN_MASK);335	snd_soc_component_update_bits(component, DA7218_MIXIN_2_CTRL,336			    DA7218_MIXIN_2_AMP_EN_MASK |337			    DA7218_MIXIN_2_AMP_MUTE_EN_MASK,338			    DA7218_MIXIN_2_AMP_EN_MASK);339 340	/* Enable input filters unmuted */341	snd_soc_component_update_bits(component, DA7218_IN_1L_FILTER_CTRL,342			    DA7218_IN_1L_FILTER_EN_MASK |343			    DA7218_IN_1L_MUTE_EN_MASK,344			    DA7218_IN_1L_FILTER_EN_MASK);345	snd_soc_component_update_bits(component, DA7218_IN_1R_FILTER_CTRL,346			    DA7218_IN_1R_FILTER_EN_MASK |347			    DA7218_IN_1R_MUTE_EN_MASK,348			    DA7218_IN_1R_FILTER_EN_MASK);349	snd_soc_component_update_bits(component, DA7218_IN_2L_FILTER_CTRL,350			    DA7218_IN_2L_FILTER_EN_MASK |351			    DA7218_IN_2L_MUTE_EN_MASK,352			    DA7218_IN_2L_FILTER_EN_MASK);353	snd_soc_component_update_bits(component, DA7218_IN_2R_FILTER_CTRL,354			    DA7218_IN_2R_FILTER_EN_MASK |355			    DA7218_IN_2R_MUTE_EN_MASK,356			    DA7218_IN_2R_FILTER_EN_MASK);357 358	/*359	 * Make sure input HPFs voice mode is disabled, otherwise for sampling360	 * rates above 32KHz the ADC signals will be stopped and will cause361	 * calibration to lock up.362	 */363	snd_soc_component_update_bits(component, DA7218_IN_1_HPF_FILTER_CTRL,364			    DA7218_IN_1_VOICE_EN_MASK, 0);365	snd_soc_component_update_bits(component, DA7218_IN_2_HPF_FILTER_CTRL,366			    DA7218_IN_2_VOICE_EN_MASK, 0);367 368	/* Perform auto calibration */369	snd_soc_component_update_bits(component, DA7218_CALIB_CTRL, DA7218_CALIB_AUTO_EN_MASK,370			    DA7218_CALIB_AUTO_EN_MASK);371	do {372		calib_ctrl = snd_soc_component_read(component, DA7218_CALIB_CTRL);373		if (calib_ctrl & DA7218_CALIB_AUTO_EN_MASK) {374			++i;375			usleep_range(DA7218_ALC_CALIB_DELAY_MIN,376				     DA7218_ALC_CALIB_DELAY_MAX);377		} else {378			calibrated = true;379		}380 381	} while ((i < DA7218_ALC_CALIB_MAX_TRIES) && (!calibrated));382 383	/* If auto calibration fails, disable DC offset, hybrid ALC */384	if ((!calibrated) || (calib_ctrl & DA7218_CALIB_OVERFLOW_MASK)) {385		dev_warn(component->dev,386			 "ALC auto calibration failed - %s\n",387			 (calibrated) ? "overflow" : "timeout");388		snd_soc_component_update_bits(component, DA7218_CALIB_CTRL,389				    DA7218_CALIB_OFFSET_EN_MASK, 0);390		snd_soc_component_update_bits(component, DA7218_ALC_CTRL1,391				    DA7218_ALC_SYNC_MODE_MASK, 0);392 393	} else {394		/* Enable DC offset cancellation */395		snd_soc_component_update_bits(component, DA7218_CALIB_CTRL,396				    DA7218_CALIB_OFFSET_EN_MASK,397				    DA7218_CALIB_OFFSET_EN_MASK);398 399		/* Enable ALC hybrid mode */400		snd_soc_component_update_bits(component, DA7218_ALC_CTRL1,401				    DA7218_ALC_SYNC_MODE_MASK,402				    DA7218_ALC_SYNC_MODE_CH1 |403				    DA7218_ALC_SYNC_MODE_CH2);404	}405 406	/* Restore input HPF control registers to original states */407	snd_soc_component_write(component, DA7218_IN_1_HPF_FILTER_CTRL, in_1_hpf_ctrl);408	snd_soc_component_write(component, DA7218_IN_2_HPF_FILTER_CTRL, in_2_hpf_ctrl);409 410	/* Restore input filter control registers to original states */411	snd_soc_component_write(component, DA7218_IN_1L_FILTER_CTRL, in_1l_filt_ctrl);412	snd_soc_component_write(component, DA7218_IN_1R_FILTER_CTRL, in_1r_filt_ctrl);413	snd_soc_component_write(component, DA7218_IN_2L_FILTER_CTRL, in_2l_filt_ctrl);414	snd_soc_component_write(component, DA7218_IN_2R_FILTER_CTRL, in_2r_filt_ctrl);415 416	/* Restore input mixer control registers to original state */417	snd_soc_component_write(component, DA7218_MIXIN_1_CTRL, mixin_1_ctrl);418	snd_soc_component_write(component, DA7218_MIXIN_2_CTRL, mixin_2_ctrl);419 420	/* Restore MIC control registers to original states */421	snd_soc_component_write(component, DA7218_MIC_1_CTRL, mic_1_ctrl);422	snd_soc_component_write(component, DA7218_MIC_2_CTRL, mic_2_ctrl);423}424 425static int da7218_mixin_gain_put(struct snd_kcontrol *kcontrol,426				 struct snd_ctl_elem_value *ucontrol)427{428	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);429	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);430	int ret;431 432	ret = snd_soc_put_volsw(kcontrol, ucontrol);433 434	/*435	 * If ALC in operation and value of control has been updated,436	 * make sure calibrated offsets are updated.437	 */438	if ((ret == 1) && (da7218->alc_en))439		da7218_alc_calib(component);440 441	return ret;442}443 444static int da7218_alc_sw_put(struct snd_kcontrol *kcontrol,445			     struct snd_ctl_elem_value *ucontrol)446{447	struct soc_mixer_control *mc =448		(struct soc_mixer_control *) kcontrol->private_value;449	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);450	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);451	unsigned int lvalue = ucontrol->value.integer.value[0];452	unsigned int rvalue = ucontrol->value.integer.value[1];453	unsigned int lshift = mc->shift;454	unsigned int rshift = mc->rshift;455	unsigned int mask = (mc->max << lshift) | (mc->max << rshift);456 457	/* Force ALC offset calibration if enabling ALC */458	if ((lvalue || rvalue) && (!da7218->alc_en))459		da7218_alc_calib(component);460 461	/* Update bits to detail which channels are enabled/disabled */462	da7218->alc_en &= ~mask;463	da7218->alc_en |= (lvalue << lshift) | (rvalue << rshift);464 465	return snd_soc_put_volsw(kcontrol, ucontrol);466}467 468/* ToneGen */469static int da7218_tonegen_freq_get(struct snd_kcontrol *kcontrol,470				   struct snd_ctl_elem_value *ucontrol)471{472	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);473	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);474	struct soc_mixer_control *mixer_ctrl =475		(struct soc_mixer_control *) kcontrol->private_value;476	unsigned int reg = mixer_ctrl->reg;477	u16 val;478	int ret;479 480	/*481	 * Frequency value spans two 8-bit registers, lower then upper byte.482	 * Therefore we need to convert to host endianness here.483	 */484	ret = regmap_raw_read(da7218->regmap, reg, &val, 2);485	if (ret)486		return ret;487 488	ucontrol->value.integer.value[0] = le16_to_cpu(val);489 490	return 0;491}492 493static int da7218_tonegen_freq_put(struct snd_kcontrol *kcontrol,494				   struct snd_ctl_elem_value *ucontrol)495{496	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);497	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);498	struct soc_mixer_control *mixer_ctrl =499		(struct soc_mixer_control *) kcontrol->private_value;500	unsigned int reg = mixer_ctrl->reg;501	u16 val;502 503	/*504	 * Frequency value spans two 8-bit registers, lower then upper byte.505	 * Therefore we need to convert to little endian here to align with506	 * HW registers.507	 */508	val = cpu_to_le16(ucontrol->value.integer.value[0]);509 510	return regmap_raw_write(da7218->regmap, reg, &val, 2);511}512 513static int da7218_mic_lvl_det_sw_put(struct snd_kcontrol *kcontrol,514				     struct snd_ctl_elem_value *ucontrol)515{516	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);517	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);518	struct soc_mixer_control *mixer_ctrl =519		(struct soc_mixer_control *) kcontrol->private_value;520	unsigned int lvalue = ucontrol->value.integer.value[0];521	unsigned int rvalue = ucontrol->value.integer.value[1];522	unsigned int lshift = mixer_ctrl->shift;523	unsigned int rshift = mixer_ctrl->rshift;524	unsigned int mask = (mixer_ctrl->max << lshift) |525			    (mixer_ctrl->max << rshift);526	da7218->mic_lvl_det_en &= ~mask;527	da7218->mic_lvl_det_en |= (lvalue << lshift) | (rvalue << rshift);528 529	/*530	 * Here we only enable the feature on paths which are already531	 * powered. If a channel is enabled here for level detect, but that path532	 * isn't powered, then the channel will actually be enabled when we do533	 * power the path (IN_FILTER widget events). This handling avoids534	 * unwanted level detect events.535	 */536	return snd_soc_component_write(component, mixer_ctrl->reg,537			     (da7218->in_filt_en & da7218->mic_lvl_det_en));538}539 540static int da7218_mic_lvl_det_sw_get(struct snd_kcontrol *kcontrol,541				     struct snd_ctl_elem_value *ucontrol)542{543	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);544	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);545	struct soc_mixer_control *mixer_ctrl =546		(struct soc_mixer_control *) kcontrol->private_value;547	unsigned int lshift = mixer_ctrl->shift;548	unsigned int rshift = mixer_ctrl->rshift;549	unsigned int lmask = (mixer_ctrl->max << lshift);550	unsigned int rmask = (mixer_ctrl->max << rshift);551 552	ucontrol->value.integer.value[0] =553		(da7218->mic_lvl_det_en & lmask) >> lshift;554	ucontrol->value.integer.value[1] =555		(da7218->mic_lvl_det_en & rmask) >> rshift;556 557	return 0;558}559 560static int da7218_biquad_coeff_get(struct snd_kcontrol *kcontrol,561				   struct snd_ctl_elem_value *ucontrol)562{563	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);564	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);565	struct soc_bytes_ext *bytes_ext =566		(struct soc_bytes_ext *) kcontrol->private_value;567 568	/* Determine which BiQuads we're setting based on size of config data */569	switch (bytes_ext->max) {570	case DA7218_OUT_1_BIQ_5STAGE_CFG_SIZE:571		memcpy(ucontrol->value.bytes.data, da7218->biq_5stage_coeff,572		       bytes_ext->max);573		break;574	case DA7218_SIDETONE_BIQ_3STAGE_CFG_SIZE:575		memcpy(ucontrol->value.bytes.data, da7218->stbiq_3stage_coeff,576		       bytes_ext->max);577		break;578	default:579		return -EINVAL;580	}581 582	return 0;583}584 585static int da7218_biquad_coeff_put(struct snd_kcontrol *kcontrol,586				   struct snd_ctl_elem_value *ucontrol)587{588	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);589	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);590	struct soc_bytes_ext *bytes_ext =591		(struct soc_bytes_ext *) kcontrol->private_value;592	u8 reg, out_filt1l;593	u8 cfg[DA7218_BIQ_CFG_SIZE];594	int i;595 596	/*597	 * Determine which BiQuads we're setting based on size of config data,598	 * and stored the data for use by get function.599	 */600	switch (bytes_ext->max) {601	case DA7218_OUT_1_BIQ_5STAGE_CFG_SIZE:602		reg = DA7218_OUT_1_BIQ_5STAGE_DATA;603		memcpy(da7218->biq_5stage_coeff, ucontrol->value.bytes.data,604		       bytes_ext->max);605		break;606	case DA7218_SIDETONE_BIQ_3STAGE_CFG_SIZE:607		reg = DA7218_SIDETONE_BIQ_3STAGE_DATA;608		memcpy(da7218->stbiq_3stage_coeff, ucontrol->value.bytes.data,609		       bytes_ext->max);610		break;611	default:612		return -EINVAL;613	}614 615	/* Make sure at least out filter1 enabled to allow programming */616	out_filt1l = snd_soc_component_read(component, DA7218_OUT_1L_FILTER_CTRL);617	snd_soc_component_write(component, DA7218_OUT_1L_FILTER_CTRL,618		      out_filt1l | DA7218_OUT_1L_FILTER_EN_MASK);619 620	for (i = 0; i < bytes_ext->max; ++i) {621		cfg[DA7218_BIQ_CFG_DATA] = ucontrol->value.bytes.data[i];622		cfg[DA7218_BIQ_CFG_ADDR] = i;623		regmap_raw_write(da7218->regmap, reg, cfg, DA7218_BIQ_CFG_SIZE);624	}625 626	/* Restore filter to previous setting */627	snd_soc_component_write(component, DA7218_OUT_1L_FILTER_CTRL, out_filt1l);628 629	return 0;630}631 632 633/*634 * KControls635 */636 637static const struct snd_kcontrol_new da7218_snd_controls[] = {638	/* Mics */639	SOC_SINGLE_TLV("Mic1 Volume", DA7218_MIC_1_GAIN,640		       DA7218_MIC_1_AMP_GAIN_SHIFT, DA7218_MIC_AMP_GAIN_MAX,641		       DA7218_NO_INVERT, da7218_mic_gain_tlv),642	SOC_SINGLE("Mic1 Switch", DA7218_MIC_1_CTRL,643		   DA7218_MIC_1_AMP_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,644		   DA7218_INVERT),645	SOC_SINGLE_TLV("Mic2 Volume", DA7218_MIC_2_GAIN,646		       DA7218_MIC_2_AMP_GAIN_SHIFT, DA7218_MIC_AMP_GAIN_MAX,647		       DA7218_NO_INVERT, da7218_mic_gain_tlv),648	SOC_SINGLE("Mic2 Switch", DA7218_MIC_2_CTRL,649		   DA7218_MIC_2_AMP_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,650		   DA7218_INVERT),651 652	/* Mixer Input */653	SOC_SINGLE_EXT_TLV("Mixin1 Volume", DA7218_MIXIN_1_GAIN,654			   DA7218_MIXIN_1_AMP_GAIN_SHIFT,655			   DA7218_MIXIN_AMP_GAIN_MAX, DA7218_NO_INVERT,656			   snd_soc_get_volsw, da7218_mixin_gain_put,657			   da7218_mixin_gain_tlv),658	SOC_SINGLE("Mixin1 Switch", DA7218_MIXIN_1_CTRL,659		   DA7218_MIXIN_1_AMP_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,660		   DA7218_INVERT),661	SOC_SINGLE("Mixin1 Gain Ramp Switch", DA7218_MIXIN_1_CTRL,662		   DA7218_MIXIN_1_AMP_RAMP_EN_SHIFT, DA7218_SWITCH_EN_MAX,663		   DA7218_NO_INVERT),664	SOC_SINGLE("Mixin1 ZC Gain Switch", DA7218_MIXIN_1_CTRL,665		   DA7218_MIXIN_1_AMP_ZC_EN_SHIFT, DA7218_SWITCH_EN_MAX,666		   DA7218_NO_INVERT),667	SOC_SINGLE_EXT_TLV("Mixin2 Volume", DA7218_MIXIN_2_GAIN,668			   DA7218_MIXIN_2_AMP_GAIN_SHIFT,669			   DA7218_MIXIN_AMP_GAIN_MAX, DA7218_NO_INVERT,670			   snd_soc_get_volsw, da7218_mixin_gain_put,671			   da7218_mixin_gain_tlv),672	SOC_SINGLE("Mixin2 Switch", DA7218_MIXIN_2_CTRL,673		   DA7218_MIXIN_2_AMP_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,674		   DA7218_INVERT),675	SOC_SINGLE("Mixin2 Gain Ramp Switch", DA7218_MIXIN_2_CTRL,676		   DA7218_MIXIN_2_AMP_RAMP_EN_SHIFT, DA7218_SWITCH_EN_MAX,677		   DA7218_NO_INVERT),678	SOC_SINGLE("Mixin2 ZC Gain Switch", DA7218_MIXIN_2_CTRL,679		   DA7218_MIXIN_2_AMP_ZC_EN_SHIFT, DA7218_SWITCH_EN_MAX,680		   DA7218_NO_INVERT),681 682	/* ADCs */683	SOC_SINGLE("ADC1 AAF Switch", DA7218_ADC_1_CTRL,684		   DA7218_ADC_1_AAF_EN_SHIFT, DA7218_SWITCH_EN_MAX,685		   DA7218_NO_INVERT),686	SOC_SINGLE("ADC2 AAF Switch", DA7218_ADC_2_CTRL,687		   DA7218_ADC_2_AAF_EN_SHIFT, DA7218_SWITCH_EN_MAX,688		   DA7218_NO_INVERT),689	SOC_SINGLE("ADC LP Mode Switch", DA7218_ADC_MODE,690		   DA7218_ADC_LP_MODE_SHIFT, DA7218_SWITCH_EN_MAX,691		   DA7218_NO_INVERT),692 693	/* Input Filters */694	SOC_SINGLE_TLV("In Filter1L Volume", DA7218_IN_1L_GAIN,695		       DA7218_IN_1L_DIGITAL_GAIN_SHIFT,696		       DA7218_IN_DIGITAL_GAIN_MAX, DA7218_NO_INVERT,697		       da7218_in_dig_gain_tlv),698	SOC_SINGLE("In Filter1L Switch", DA7218_IN_1L_FILTER_CTRL,699		   DA7218_IN_1L_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,700		   DA7218_INVERT),701	SOC_SINGLE("In Filter1L Gain Ramp Switch", DA7218_IN_1L_FILTER_CTRL,702		   DA7218_IN_1L_RAMP_EN_SHIFT, DA7218_SWITCH_EN_MAX,703		   DA7218_NO_INVERT),704	SOC_SINGLE_TLV("In Filter1R Volume", DA7218_IN_1R_GAIN,705		       DA7218_IN_1R_DIGITAL_GAIN_SHIFT,706		       DA7218_IN_DIGITAL_GAIN_MAX, DA7218_NO_INVERT,707		       da7218_in_dig_gain_tlv),708	SOC_SINGLE("In Filter1R Switch", DA7218_IN_1R_FILTER_CTRL,709		   DA7218_IN_1R_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,710		   DA7218_INVERT),711	SOC_SINGLE("In Filter1R Gain Ramp Switch",712		   DA7218_IN_1R_FILTER_CTRL, DA7218_IN_1R_RAMP_EN_SHIFT,713		   DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),714	SOC_SINGLE_TLV("In Filter2L Volume", DA7218_IN_2L_GAIN,715		       DA7218_IN_2L_DIGITAL_GAIN_SHIFT,716		       DA7218_IN_DIGITAL_GAIN_MAX, DA7218_NO_INVERT,717		       da7218_in_dig_gain_tlv),718	SOC_SINGLE("In Filter2L Switch", DA7218_IN_2L_FILTER_CTRL,719		   DA7218_IN_2L_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,720		   DA7218_INVERT),721	SOC_SINGLE("In Filter2L Gain Ramp Switch", DA7218_IN_2L_FILTER_CTRL,722		   DA7218_IN_2L_RAMP_EN_SHIFT, DA7218_SWITCH_EN_MAX,723		   DA7218_NO_INVERT),724	SOC_SINGLE_TLV("In Filter2R Volume", DA7218_IN_2R_GAIN,725		       DA7218_IN_2R_DIGITAL_GAIN_SHIFT,726		       DA7218_IN_DIGITAL_GAIN_MAX, DA7218_NO_INVERT,727		       da7218_in_dig_gain_tlv),728	SOC_SINGLE("In Filter2R Switch", DA7218_IN_2R_FILTER_CTRL,729		   DA7218_IN_2R_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,730		   DA7218_INVERT),731	SOC_SINGLE("In Filter2R Gain Ramp Switch",732		   DA7218_IN_2R_FILTER_CTRL, DA7218_IN_2R_RAMP_EN_SHIFT,733		   DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),734 735	/* AGS */736	SOC_SINGLE_TLV("AGS Trigger", DA7218_AGS_TRIGGER,737		       DA7218_AGS_TRIGGER_SHIFT, DA7218_AGS_TRIGGER_MAX,738		       DA7218_INVERT, da7218_ags_trigger_tlv),739	SOC_SINGLE_TLV("AGS Max Attenuation", DA7218_AGS_ATT_MAX,740		       DA7218_AGS_ATT_MAX_SHIFT, DA7218_AGS_ATT_MAX_MAX,741		       DA7218_NO_INVERT, da7218_ags_att_max_tlv),742	SOC_SINGLE("AGS Anticlip Switch", DA7218_AGS_ANTICLIP_CTRL,743		   DA7218_AGS_ANTICLIP_EN_SHIFT, DA7218_SWITCH_EN_MAX,744		   DA7218_NO_INVERT),745	SOC_SINGLE("AGS Channel1 Switch", DA7218_AGS_ENABLE,746		   DA7218_AGS_ENABLE_CHAN1_SHIFT, DA7218_SWITCH_EN_MAX,747		   DA7218_NO_INVERT),748	SOC_SINGLE("AGS Channel2 Switch", DA7218_AGS_ENABLE,749		   DA7218_AGS_ENABLE_CHAN2_SHIFT, DA7218_SWITCH_EN_MAX,750		   DA7218_NO_INVERT),751 752	/* ALC */753	SOC_ENUM("ALC Attack Rate", da7218_alc_attack_rate),754	SOC_ENUM("ALC Release Rate", da7218_alc_release_rate),755	SOC_ENUM("ALC Hold Time", da7218_alc_hold_time),756	SOC_SINGLE_TLV("ALC Noise Threshold", DA7218_ALC_NOISE,757		       DA7218_ALC_NOISE_SHIFT, DA7218_ALC_THRESHOLD_MAX,758		       DA7218_INVERT, da7218_alc_threshold_tlv),759	SOC_SINGLE_TLV("ALC Min Threshold", DA7218_ALC_TARGET_MIN,760		       DA7218_ALC_THRESHOLD_MIN_SHIFT, DA7218_ALC_THRESHOLD_MAX,761		       DA7218_INVERT, da7218_alc_threshold_tlv),762	SOC_SINGLE_TLV("ALC Max Threshold", DA7218_ALC_TARGET_MAX,763		       DA7218_ALC_THRESHOLD_MAX_SHIFT, DA7218_ALC_THRESHOLD_MAX,764		       DA7218_INVERT, da7218_alc_threshold_tlv),765	SOC_SINGLE_TLV("ALC Max Attenuation", DA7218_ALC_GAIN_LIMITS,766		       DA7218_ALC_ATTEN_MAX_SHIFT, DA7218_ALC_ATTEN_GAIN_MAX,767		       DA7218_NO_INVERT, da7218_alc_gain_tlv),768	SOC_SINGLE_TLV("ALC Max Gain", DA7218_ALC_GAIN_LIMITS,769		       DA7218_ALC_GAIN_MAX_SHIFT, DA7218_ALC_ATTEN_GAIN_MAX,770		       DA7218_NO_INVERT, da7218_alc_gain_tlv),771	SOC_SINGLE_RANGE_TLV("ALC Min Analog Gain", DA7218_ALC_ANA_GAIN_LIMITS,772			     DA7218_ALC_ANA_GAIN_MIN_SHIFT,773			     DA7218_ALC_ANA_GAIN_MIN, DA7218_ALC_ANA_GAIN_MAX,774			     DA7218_NO_INVERT, da7218_alc_ana_gain_tlv),775	SOC_SINGLE_RANGE_TLV("ALC Max Analog Gain", DA7218_ALC_ANA_GAIN_LIMITS,776			     DA7218_ALC_ANA_GAIN_MAX_SHIFT,777			     DA7218_ALC_ANA_GAIN_MIN, DA7218_ALC_ANA_GAIN_MAX,778			     DA7218_NO_INVERT, da7218_alc_ana_gain_tlv),779	SOC_ENUM("ALC Anticlip Step", da7218_alc_anticlip_step),780	SOC_SINGLE("ALC Anticlip Switch", DA7218_ALC_ANTICLIP_CTRL,781		   DA7218_ALC_ANTICLIP_EN_SHIFT, DA7218_SWITCH_EN_MAX,782		   DA7218_NO_INVERT),783	SOC_DOUBLE_EXT("ALC Channel1 Switch", DA7218_ALC_CTRL1,784		       DA7218_ALC_CHAN1_L_EN_SHIFT, DA7218_ALC_CHAN1_R_EN_SHIFT,785		       DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT,786		       snd_soc_get_volsw, da7218_alc_sw_put),787	SOC_DOUBLE_EXT("ALC Channel2 Switch", DA7218_ALC_CTRL1,788		       DA7218_ALC_CHAN2_L_EN_SHIFT, DA7218_ALC_CHAN2_R_EN_SHIFT,789		       DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT,790		       snd_soc_get_volsw, da7218_alc_sw_put),791 792	/* Envelope Tracking */793	SOC_ENUM("Envelope Tracking Attack Rate", da7218_integ_attack_rate),794	SOC_ENUM("Envelope Tracking Release Rate", da7218_integ_release_rate),795 796	/* Input High-Pass Filters */797	SOC_ENUM("In Filter1 HPF Mode", da7218_in1_hpf_mode),798	SOC_ENUM("In Filter1 HPF Corner Audio", da7218_in1_audio_hpf_corner),799	SOC_ENUM("In Filter1 HPF Corner Voice", da7218_in1_voice_hpf_corner),800	SOC_ENUM("In Filter2 HPF Mode", da7218_in2_hpf_mode),801	SOC_ENUM("In Filter2 HPF Corner Audio", da7218_in2_audio_hpf_corner),802	SOC_ENUM("In Filter2 HPF Corner Voice", da7218_in2_voice_hpf_corner),803 804	/* Mic Level Detect */805	SOC_DOUBLE_EXT("Mic Level Detect Channel1 Switch", DA7218_LVL_DET_CTRL,806		       DA7218_LVL_DET_EN_CHAN1L_SHIFT,807		       DA7218_LVL_DET_EN_CHAN1R_SHIFT, DA7218_SWITCH_EN_MAX,808		       DA7218_NO_INVERT, da7218_mic_lvl_det_sw_get,809		       da7218_mic_lvl_det_sw_put),810	SOC_DOUBLE_EXT("Mic Level Detect Channel2 Switch", DA7218_LVL_DET_CTRL,811		       DA7218_LVL_DET_EN_CHAN2L_SHIFT,812		       DA7218_LVL_DET_EN_CHAN2R_SHIFT, DA7218_SWITCH_EN_MAX,813		       DA7218_NO_INVERT, da7218_mic_lvl_det_sw_get,814		       da7218_mic_lvl_det_sw_put),815	SOC_SINGLE("Mic Level Detect Level", DA7218_LVL_DET_LEVEL,816		   DA7218_LVL_DET_LEVEL_SHIFT, DA7218_LVL_DET_LEVEL_MAX,817		   DA7218_NO_INVERT),818 819	/* Digital Mixer (Input) */820	SOC_SINGLE_TLV("DMix In Filter1L Out1 DAIL Volume",821		       DA7218_DMIX_OUTDAI_1L_INFILT_1L_GAIN,822		       DA7218_OUTDAI_1L_INFILT_1L_GAIN_SHIFT,823		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,824		       da7218_dmix_gain_tlv),825	SOC_SINGLE_TLV("DMix In Filter1L Out1 DAIR Volume",826		       DA7218_DMIX_OUTDAI_1R_INFILT_1L_GAIN,827		       DA7218_OUTDAI_1R_INFILT_1L_GAIN_SHIFT,828		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,829		       da7218_dmix_gain_tlv),830	SOC_SINGLE_TLV("DMix In Filter1L Out2 DAIL Volume",831		       DA7218_DMIX_OUTDAI_2L_INFILT_1L_GAIN,832		       DA7218_OUTDAI_2L_INFILT_1L_GAIN_SHIFT,833		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,834		       da7218_dmix_gain_tlv),835	SOC_SINGLE_TLV("DMix In Filter1L Out2 DAIR Volume",836		       DA7218_DMIX_OUTDAI_2R_INFILT_1L_GAIN,837		       DA7218_OUTDAI_2R_INFILT_1L_GAIN_SHIFT,838		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,839		       da7218_dmix_gain_tlv),840 841	SOC_SINGLE_TLV("DMix In Filter1R Out1 DAIL Volume",842		       DA7218_DMIX_OUTDAI_1L_INFILT_1R_GAIN,843		       DA7218_OUTDAI_1L_INFILT_1R_GAIN_SHIFT,844		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,845		       da7218_dmix_gain_tlv),846	SOC_SINGLE_TLV("DMix In Filter1R Out1 DAIR Volume",847		       DA7218_DMIX_OUTDAI_1R_INFILT_1R_GAIN,848		       DA7218_OUTDAI_1R_INFILT_1R_GAIN_SHIFT,849		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,850		       da7218_dmix_gain_tlv),851	SOC_SINGLE_TLV("DMix In Filter1R Out2 DAIL Volume",852		       DA7218_DMIX_OUTDAI_2L_INFILT_1R_GAIN,853		       DA7218_OUTDAI_2L_INFILT_1R_GAIN_SHIFT,854		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,855		       da7218_dmix_gain_tlv),856	SOC_SINGLE_TLV("DMix In Filter1R Out2 DAIR Volume",857		       DA7218_DMIX_OUTDAI_2R_INFILT_1R_GAIN,858		       DA7218_OUTDAI_2R_INFILT_1R_GAIN_SHIFT,859		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,860		       da7218_dmix_gain_tlv),861 862	SOC_SINGLE_TLV("DMix In Filter2L Out1 DAIL Volume",863		       DA7218_DMIX_OUTDAI_1L_INFILT_2L_GAIN,864		       DA7218_OUTDAI_1L_INFILT_2L_GAIN_SHIFT,865		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,866		       da7218_dmix_gain_tlv),867	SOC_SINGLE_TLV("DMix In Filter2L Out1 DAIR Volume",868		       DA7218_DMIX_OUTDAI_1R_INFILT_2L_GAIN,869		       DA7218_OUTDAI_1R_INFILT_2L_GAIN_SHIFT,870		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,871		       da7218_dmix_gain_tlv),872	SOC_SINGLE_TLV("DMix In Filter2L Out2 DAIL Volume",873		       DA7218_DMIX_OUTDAI_2L_INFILT_2L_GAIN,874		       DA7218_OUTDAI_2L_INFILT_2L_GAIN_SHIFT,875		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,876		       da7218_dmix_gain_tlv),877	SOC_SINGLE_TLV("DMix In Filter2L Out2 DAIR Volume",878		       DA7218_DMIX_OUTDAI_2R_INFILT_2L_GAIN,879		       DA7218_OUTDAI_2R_INFILT_2L_GAIN_SHIFT,880		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,881		       da7218_dmix_gain_tlv),882 883	SOC_SINGLE_TLV("DMix In Filter2R Out1 DAIL Volume",884		       DA7218_DMIX_OUTDAI_1L_INFILT_2R_GAIN,885		       DA7218_OUTDAI_1L_INFILT_2R_GAIN_SHIFT,886		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,887		       da7218_dmix_gain_tlv),888	SOC_SINGLE_TLV("DMix In Filter2R Out1 DAIR Volume",889		       DA7218_DMIX_OUTDAI_1R_INFILT_2R_GAIN,890		       DA7218_OUTDAI_1R_INFILT_2R_GAIN_SHIFT,891		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,892		       da7218_dmix_gain_tlv),893	SOC_SINGLE_TLV("DMix In Filter2R Out2 DAIL Volume",894		       DA7218_DMIX_OUTDAI_2L_INFILT_2R_GAIN,895		       DA7218_OUTDAI_2L_INFILT_2R_GAIN_SHIFT,896		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,897		       da7218_dmix_gain_tlv),898	SOC_SINGLE_TLV("DMix In Filter2R Out2 DAIR Volume",899		       DA7218_DMIX_OUTDAI_2R_INFILT_2R_GAIN,900		       DA7218_OUTDAI_2R_INFILT_2R_GAIN_SHIFT,901		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,902		       da7218_dmix_gain_tlv),903 904	SOC_SINGLE_TLV("DMix ToneGen Out1 DAIL Volume",905		       DA7218_DMIX_OUTDAI_1L_TONEGEN_GAIN,906		       DA7218_OUTDAI_1L_TONEGEN_GAIN_SHIFT,907		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,908		       da7218_dmix_gain_tlv),909	SOC_SINGLE_TLV("DMix ToneGen Out1 DAIR Volume",910		       DA7218_DMIX_OUTDAI_1R_TONEGEN_GAIN,911		       DA7218_OUTDAI_1R_TONEGEN_GAIN_SHIFT,912		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,913		       da7218_dmix_gain_tlv),914	SOC_SINGLE_TLV("DMix ToneGen Out2 DAIL Volume",915		       DA7218_DMIX_OUTDAI_2L_TONEGEN_GAIN,916		       DA7218_OUTDAI_2L_TONEGEN_GAIN_SHIFT,917		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,918		       da7218_dmix_gain_tlv),919	SOC_SINGLE_TLV("DMix ToneGen Out2 DAIR Volume",920		       DA7218_DMIX_OUTDAI_2R_TONEGEN_GAIN,921		       DA7218_OUTDAI_2R_TONEGEN_GAIN_SHIFT,922		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,923		       da7218_dmix_gain_tlv),924 925	SOC_SINGLE_TLV("DMix In DAIL Out1 DAIL Volume",926		       DA7218_DMIX_OUTDAI_1L_INDAI_1L_GAIN,927		       DA7218_OUTDAI_1L_INDAI_1L_GAIN_SHIFT,928		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,929		       da7218_dmix_gain_tlv),930	SOC_SINGLE_TLV("DMix In DAIL Out1 DAIR Volume",931		       DA7218_DMIX_OUTDAI_1R_INDAI_1L_GAIN,932		       DA7218_OUTDAI_1R_INDAI_1L_GAIN_SHIFT,933		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,934		       da7218_dmix_gain_tlv),935	SOC_SINGLE_TLV("DMix In DAIL Out2 DAIL Volume",936		       DA7218_DMIX_OUTDAI_2L_INDAI_1L_GAIN,937		       DA7218_OUTDAI_2L_INDAI_1L_GAIN_SHIFT,938		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,939		       da7218_dmix_gain_tlv),940	SOC_SINGLE_TLV("DMix In DAIL Out2 DAIR Volume",941		       DA7218_DMIX_OUTDAI_2R_INDAI_1L_GAIN,942		       DA7218_OUTDAI_2R_INDAI_1L_GAIN_SHIFT,943		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,944		       da7218_dmix_gain_tlv),945 946	SOC_SINGLE_TLV("DMix In DAIR Out1 DAIL Volume",947		       DA7218_DMIX_OUTDAI_1L_INDAI_1R_GAIN,948		       DA7218_OUTDAI_1L_INDAI_1R_GAIN_SHIFT,949		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,950		       da7218_dmix_gain_tlv),951	SOC_SINGLE_TLV("DMix In DAIR Out1 DAIR Volume",952		       DA7218_DMIX_OUTDAI_1R_INDAI_1R_GAIN,953		       DA7218_OUTDAI_1R_INDAI_1R_GAIN_SHIFT,954		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,955		       da7218_dmix_gain_tlv),956	SOC_SINGLE_TLV("DMix In DAIR Out2 DAIL Volume",957		       DA7218_DMIX_OUTDAI_2L_INDAI_1R_GAIN,958		       DA7218_OUTDAI_2L_INDAI_1R_GAIN_SHIFT,959		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,960		       da7218_dmix_gain_tlv),961	SOC_SINGLE_TLV("DMix In DAIR Out2 DAIR Volume",962		       DA7218_DMIX_OUTDAI_2R_INDAI_1R_GAIN,963		       DA7218_OUTDAI_2R_INDAI_1R_GAIN_SHIFT,964		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,965		       da7218_dmix_gain_tlv),966 967	/* Digital Mixer (Output) */968	SOC_SINGLE_TLV("DMix In Filter1L Out FilterL Volume",969		       DA7218_DMIX_OUTFILT_1L_INFILT_1L_GAIN,970		       DA7218_OUTFILT_1L_INFILT_1L_GAIN_SHIFT,971		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,972		       da7218_dmix_gain_tlv),973	SOC_SINGLE_TLV("DMix In Filter1L Out FilterR Volume",974		       DA7218_DMIX_OUTFILT_1R_INFILT_1L_GAIN,975		       DA7218_OUTFILT_1R_INFILT_1L_GAIN_SHIFT,976		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,977		       da7218_dmix_gain_tlv),978 979	SOC_SINGLE_TLV("DMix In Filter1R Out FilterL Volume",980		       DA7218_DMIX_OUTFILT_1L_INFILT_1R_GAIN,981		       DA7218_OUTFILT_1L_INFILT_1R_GAIN_SHIFT,982		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,983		       da7218_dmix_gain_tlv),984	SOC_SINGLE_TLV("DMix In Filter1R Out FilterR Volume",985		       DA7218_DMIX_OUTFILT_1R_INFILT_1R_GAIN,986		       DA7218_OUTFILT_1R_INFILT_1R_GAIN_SHIFT,987		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,988		       da7218_dmix_gain_tlv),989 990	SOC_SINGLE_TLV("DMix In Filter2L Out FilterL Volume",991		       DA7218_DMIX_OUTFILT_1L_INFILT_2L_GAIN,992		       DA7218_OUTFILT_1L_INFILT_2L_GAIN_SHIFT,993		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,994		       da7218_dmix_gain_tlv),995	SOC_SINGLE_TLV("DMix In Filter2L Out FilterR Volume",996		       DA7218_DMIX_OUTFILT_1R_INFILT_2L_GAIN,997		       DA7218_OUTFILT_1R_INFILT_2L_GAIN_SHIFT,998		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,999		       da7218_dmix_gain_tlv),1000 1001	SOC_SINGLE_TLV("DMix In Filter2R Out FilterL Volume",1002		       DA7218_DMIX_OUTFILT_1L_INFILT_2R_GAIN,1003		       DA7218_OUTFILT_1L_INFILT_2R_GAIN_SHIFT,1004		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,1005		       da7218_dmix_gain_tlv),1006	SOC_SINGLE_TLV("DMix In Filter2R Out FilterR Volume",1007		       DA7218_DMIX_OUTFILT_1R_INFILT_2R_GAIN,1008		       DA7218_OUTFILT_1R_INFILT_2R_GAIN_SHIFT,1009		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,1010		       da7218_dmix_gain_tlv),1011 1012	SOC_SINGLE_TLV("DMix ToneGen Out FilterL Volume",1013		       DA7218_DMIX_OUTFILT_1L_TONEGEN_GAIN,1014		       DA7218_OUTFILT_1L_TONEGEN_GAIN_SHIFT,1015		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,1016		       da7218_dmix_gain_tlv),1017	SOC_SINGLE_TLV("DMix ToneGen Out FilterR Volume",1018		       DA7218_DMIX_OUTFILT_1R_TONEGEN_GAIN,1019		       DA7218_OUTFILT_1R_TONEGEN_GAIN_SHIFT,1020		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,1021		       da7218_dmix_gain_tlv),1022 1023	SOC_SINGLE_TLV("DMix In DAIL Out FilterL Volume",1024		       DA7218_DMIX_OUTFILT_1L_INDAI_1L_GAIN,1025		       DA7218_OUTFILT_1L_INDAI_1L_GAIN_SHIFT,1026		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,1027		       da7218_dmix_gain_tlv),1028	SOC_SINGLE_TLV("DMix In DAIL Out FilterR Volume",1029		       DA7218_DMIX_OUTFILT_1R_INDAI_1L_GAIN,1030		       DA7218_OUTFILT_1R_INDAI_1L_GAIN_SHIFT,1031		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,1032		       da7218_dmix_gain_tlv),1033 1034	SOC_SINGLE_TLV("DMix In DAIR Out FilterL Volume",1035		       DA7218_DMIX_OUTFILT_1L_INDAI_1R_GAIN,1036		       DA7218_OUTFILT_1L_INDAI_1R_GAIN_SHIFT,1037		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,1038		       da7218_dmix_gain_tlv),1039	SOC_SINGLE_TLV("DMix In DAIR Out FilterR Volume",1040		       DA7218_DMIX_OUTFILT_1R_INDAI_1R_GAIN,1041		       DA7218_OUTFILT_1R_INDAI_1R_GAIN_SHIFT,1042		       DA7218_DMIX_GAIN_MAX, DA7218_NO_INVERT,1043		       da7218_dmix_gain_tlv),1044 1045	/* Sidetone Filter */1046	SND_SOC_BYTES_EXT("Sidetone BiQuad Coefficients",1047			  DA7218_SIDETONE_BIQ_3STAGE_CFG_SIZE,1048			  da7218_biquad_coeff_get, da7218_biquad_coeff_put),1049	SOC_SINGLE_TLV("Sidetone Volume", DA7218_SIDETONE_GAIN,1050		       DA7218_SIDETONE_GAIN_SHIFT, DA7218_DMIX_GAIN_MAX,1051		       DA7218_NO_INVERT, da7218_dmix_gain_tlv),1052	SOC_SINGLE("Sidetone Switch", DA7218_SIDETONE_CTRL,1053		   DA7218_SIDETONE_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,1054		   DA7218_INVERT),1055 1056	/* Tone Generator */1057	SOC_ENUM("ToneGen DTMF Key", da7218_tonegen_dtmf_key),1058	SOC_SINGLE("ToneGen DTMF Switch", DA7218_TONE_GEN_CFG1,1059		   DA7218_DTMF_EN_SHIFT, DA7218_SWITCH_EN_MAX,1060		   DA7218_NO_INVERT),1061	SOC_ENUM("ToneGen Sinewave Gen Type", da7218_tonegen_swg_sel),1062	SOC_SINGLE_EXT("ToneGen Sinewave1 Freq", DA7218_TONE_GEN_FREQ1_L,1063		       DA7218_FREQ1_L_SHIFT, DA7218_FREQ_MAX, DA7218_NO_INVERT,1064		       da7218_tonegen_freq_get, da7218_tonegen_freq_put),1065	SOC_SINGLE_EXT("ToneGen Sinewave2 Freq", DA7218_TONE_GEN_FREQ2_L,1066		       DA7218_FREQ2_L_SHIFT, DA7218_FREQ_MAX, DA7218_NO_INVERT,1067		       da7218_tonegen_freq_get, da7218_tonegen_freq_put),1068	SOC_SINGLE("ToneGen On Time", DA7218_TONE_GEN_ON_PER,1069		   DA7218_BEEP_ON_PER_SHIFT, DA7218_BEEP_ON_OFF_MAX,1070		   DA7218_NO_INVERT),1071	SOC_SINGLE("ToneGen Off Time", DA7218_TONE_GEN_OFF_PER,1072		   DA7218_BEEP_OFF_PER_SHIFT, DA7218_BEEP_ON_OFF_MAX,1073		   DA7218_NO_INVERT),1074 1075	/* Gain ramping */1076	SOC_ENUM("Gain Ramp Rate", da7218_gain_ramp_rate),1077 1078	/* DGS */1079	SOC_SINGLE_TLV("DGS Trigger", DA7218_DGS_TRIGGER,1080		       DA7218_DGS_TRIGGER_LVL_SHIFT, DA7218_DGS_TRIGGER_MAX,1081		       DA7218_INVERT, da7218_dgs_trigger_tlv),1082	SOC_ENUM("DGS Rise Coefficient", da7218_dgs_rise_coeff),1083	SOC_ENUM("DGS Fall Coefficient", da7218_dgs_fall_coeff),1084	SOC_SINGLE("DGS Sync Delay", DA7218_DGS_SYNC_DELAY,1085		   DA7218_DGS_SYNC_DELAY_SHIFT, DA7218_DGS_SYNC_DELAY_MAX,1086		   DA7218_NO_INVERT),1087	SOC_SINGLE("DGS Fast SR Sync Delay", DA7218_DGS_SYNC_DELAY2,1088		   DA7218_DGS_SYNC_DELAY2_SHIFT, DA7218_DGS_SYNC_DELAY_MAX,1089		   DA7218_NO_INVERT),1090	SOC_SINGLE("DGS Voice Filter Sync Delay", DA7218_DGS_SYNC_DELAY3,1091		   DA7218_DGS_SYNC_DELAY3_SHIFT, DA7218_DGS_SYNC_DELAY3_MAX,1092		   DA7218_NO_INVERT),1093	SOC_SINGLE_TLV("DGS Anticlip Level", DA7218_DGS_LEVELS,1094		       DA7218_DGS_ANTICLIP_LVL_SHIFT,1095		       DA7218_DGS_ANTICLIP_LVL_MAX, DA7218_INVERT,1096		       da7218_dgs_anticlip_tlv),1097	SOC_SINGLE_TLV("DGS Signal Level", DA7218_DGS_LEVELS,1098		       DA7218_DGS_SIGNAL_LVL_SHIFT, DA7218_DGS_SIGNAL_LVL_MAX,1099		       DA7218_INVERT, da7218_dgs_signal_tlv),1100	SOC_SINGLE("DGS Gain Subrange Switch", DA7218_DGS_GAIN_CTRL,1101		   DA7218_DGS_SUBR_EN_SHIFT, DA7218_SWITCH_EN_MAX,1102		   DA7218_NO_INVERT),1103	SOC_SINGLE("DGS Gain Ramp Switch", DA7218_DGS_GAIN_CTRL,1104		   DA7218_DGS_RAMP_EN_SHIFT, DA7218_SWITCH_EN_MAX,1105		   DA7218_NO_INVERT),1106	SOC_SINGLE("DGS Gain Steps", DA7218_DGS_GAIN_CTRL,1107		   DA7218_DGS_STEPS_SHIFT, DA7218_DGS_STEPS_MAX,1108		   DA7218_NO_INVERT),1109	SOC_DOUBLE("DGS Switch", DA7218_DGS_ENABLE, DA7218_DGS_ENABLE_L_SHIFT,1110		   DA7218_DGS_ENABLE_R_SHIFT, DA7218_SWITCH_EN_MAX,1111		   DA7218_NO_INVERT),1112 1113	/* Output High-Pass Filter */1114	SOC_ENUM("Out Filter HPF Mode", da7218_out1_hpf_mode),1115	SOC_ENUM("Out Filter HPF Corner Audio", da7218_out1_audio_hpf_corner),1116	SOC_ENUM("Out Filter HPF Corner Voice", da7218_out1_voice_hpf_corner),1117 1118	/* 5-Band Equaliser */1119	SOC_SINGLE_TLV("Out EQ Band1 Volume", DA7218_OUT_1_EQ_12_FILTER_CTRL,1120		       DA7218_OUT_1_EQ_BAND1_SHIFT, DA7218_OUT_EQ_BAND_MAX,1121		       DA7218_NO_INVERT, da7218_out_eq_band_tlv),1122	SOC_SINGLE_TLV("Out EQ Band2 Volume", DA7218_OUT_1_EQ_12_FILTER_CTRL,1123		       DA7218_OUT_1_EQ_BAND2_SHIFT, DA7218_OUT_EQ_BAND_MAX,1124		       DA7218_NO_INVERT, da7218_out_eq_band_tlv),1125	SOC_SINGLE_TLV("Out EQ Band3 Volume", DA7218_OUT_1_EQ_34_FILTER_CTRL,1126		       DA7218_OUT_1_EQ_BAND3_SHIFT, DA7218_OUT_EQ_BAND_MAX,1127		       DA7218_NO_INVERT, da7218_out_eq_band_tlv),1128	SOC_SINGLE_TLV("Out EQ Band4 Volume", DA7218_OUT_1_EQ_34_FILTER_CTRL,1129		       DA7218_OUT_1_EQ_BAND4_SHIFT, DA7218_OUT_EQ_BAND_MAX,1130		       DA7218_NO_INVERT, da7218_out_eq_band_tlv),1131	SOC_SINGLE_TLV("Out EQ Band5 Volume", DA7218_OUT_1_EQ_5_FILTER_CTRL,1132		       DA7218_OUT_1_EQ_BAND5_SHIFT, DA7218_OUT_EQ_BAND_MAX,1133		       DA7218_NO_INVERT, da7218_out_eq_band_tlv),1134	SOC_SINGLE("Out EQ Switch", DA7218_OUT_1_EQ_5_FILTER_CTRL,1135		   DA7218_OUT_1_EQ_EN_SHIFT, DA7218_SWITCH_EN_MAX,1136		   DA7218_NO_INVERT),1137 1138	/* BiQuad Filters */1139	SND_SOC_BYTES_EXT("BiQuad Coefficients",1140			  DA7218_OUT_1_BIQ_5STAGE_CFG_SIZE,1141			  da7218_biquad_coeff_get, da7218_biquad_coeff_put),1142	SOC_SINGLE("BiQuad Filter Switch", DA7218_OUT_1_BIQ_5STAGE_CTRL,1143		   DA7218_OUT_1_BIQ_5STAGE_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,1144		   DA7218_INVERT),1145 1146	/* Output Filters */1147	SOC_DOUBLE_R_RANGE_TLV("Out Filter Volume", DA7218_OUT_1L_GAIN,1148			       DA7218_OUT_1R_GAIN,1149			       DA7218_OUT_1L_DIGITAL_GAIN_SHIFT,1150			       DA7218_OUT_DIGITAL_GAIN_MIN,1151			       DA7218_OUT_DIGITAL_GAIN_MAX, DA7218_NO_INVERT,1152			       da7218_out_dig_gain_tlv),1153	SOC_DOUBLE_R("Out Filter Switch", DA7218_OUT_1L_FILTER_CTRL,1154		     DA7218_OUT_1R_FILTER_CTRL, DA7218_OUT_1L_MUTE_EN_SHIFT,1155		     DA7218_SWITCH_EN_MAX, DA7218_INVERT),1156	SOC_DOUBLE_R("Out Filter Gain Subrange Switch",1157		     DA7218_OUT_1L_FILTER_CTRL, DA7218_OUT_1R_FILTER_CTRL,1158		     DA7218_OUT_1L_SUBRANGE_EN_SHIFT, DA7218_SWITCH_EN_MAX,1159		     DA7218_NO_INVERT),1160	SOC_DOUBLE_R("Out Filter Gain Ramp Switch", DA7218_OUT_1L_FILTER_CTRL,1161		     DA7218_OUT_1R_FILTER_CTRL, DA7218_OUT_1L_RAMP_EN_SHIFT,1162		     DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),1163 1164	/* Mixer Output */1165	SOC_DOUBLE_R_RANGE_TLV("Mixout Volume", DA7218_MIXOUT_L_GAIN,1166			       DA7218_MIXOUT_R_GAIN,1167			       DA7218_MIXOUT_L_AMP_GAIN_SHIFT,1168			       DA7218_MIXOUT_AMP_GAIN_MIN,1169			       DA7218_MIXOUT_AMP_GAIN_MAX, DA7218_NO_INVERT,1170			       da7218_mixout_gain_tlv),1171 1172	/* DAC Noise Gate */1173	SOC_ENUM("DAC NG Setup Time", da7218_dac_ng_setup_time),1174	SOC_ENUM("DAC NG Rampup Rate", da7218_dac_ng_rampup_rate),1175	SOC_ENUM("DAC NG Rampdown Rate", da7218_dac_ng_rampdown_rate),1176	SOC_SINGLE_TLV("DAC NG Off Threshold", DA7218_DAC_NG_OFF_THRESH,1177		       DA7218_DAC_NG_OFF_THRESHOLD_SHIFT,1178		       DA7218_DAC_NG_THRESHOLD_MAX, DA7218_NO_INVERT,1179		       da7218_dac_ng_threshold_tlv),1180	SOC_SINGLE_TLV("DAC NG On Threshold", DA7218_DAC_NG_ON_THRESH,1181		       DA7218_DAC_NG_ON_THRESHOLD_SHIFT,1182		       DA7218_DAC_NG_THRESHOLD_MAX, DA7218_NO_INVERT,1183		       da7218_dac_ng_threshold_tlv),1184	SOC_SINGLE("DAC NG Switch", DA7218_DAC_NG_CTRL, DA7218_DAC_NG_EN_SHIFT,1185		   DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),1186 1187	/* CP */1188	SOC_ENUM("Charge Pump Track Mode", da7218_cp_mchange),1189	SOC_ENUM("Charge Pump Frequency", da7218_cp_fcontrol),1190	SOC_ENUM("Charge Pump Decay Rate", da7218_cp_tau_delay),1191	SOC_SINGLE("Charge Pump Threshold", DA7218_CP_VOL_THRESHOLD1,1192		   DA7218_CP_THRESH_VDD2_SHIFT, DA7218_CP_THRESH_VDD2_MAX,1193		   DA7218_NO_INVERT),1194 1195	/* Headphones */1196	SOC_DOUBLE_R_RANGE_TLV("Headphone Volume", DA7218_HP_L_GAIN,1197			       DA7218_HP_R_GAIN, DA7218_HP_L_AMP_GAIN_SHIFT,1198			       DA7218_HP_AMP_GAIN_MIN, DA7218_HP_AMP_GAIN_MAX,1199			       DA7218_NO_INVERT, da7218_hp_gain_tlv),1200	SOC_DOUBLE_R("Headphone Switch", DA7218_HP_L_CTRL, DA7218_HP_R_CTRL,1201		     DA7218_HP_L_AMP_MUTE_EN_SHIFT, DA7218_SWITCH_EN_MAX,1202		     DA7218_INVERT),1203	SOC_DOUBLE_R("Headphone Gain Ramp Switch", DA7218_HP_L_CTRL,1204		     DA7218_HP_R_CTRL, DA7218_HP_L_AMP_RAMP_EN_SHIFT,1205		     DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),1206	SOC_DOUBLE_R("Headphone ZC Gain Switch", DA7218_HP_L_CTRL,1207		     DA7218_HP_R_CTRL, DA7218_HP_L_AMP_ZC_EN_SHIFT,1208		     DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),1209};1210 1211 1212/*1213 * DAPM Mux Controls1214 */1215 1216static const char * const da7218_mic_sel_text[] = { "Analog", "Digital" };1217 1218static const struct soc_enum da7218_mic1_sel =1219	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(da7218_mic_sel_text),1220			    da7218_mic_sel_text);1221 1222static const struct snd_kcontrol_new da7218_mic1_sel_mux =1223	SOC_DAPM_ENUM("Mic1 Mux", da7218_mic1_sel);1224 1225static const struct soc_enum da7218_mic2_sel =1226	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(da7218_mic_sel_text),1227			    da7218_mic_sel_text);1228 1229static const struct snd_kcontrol_new da7218_mic2_sel_mux =1230	SOC_DAPM_ENUM("Mic2 Mux", da7218_mic2_sel);1231 1232static const char * const da7218_sidetone_in_sel_txt[] = {1233	"In Filter1L", "In Filter1R", "In Filter2L", "In Filter2R"1234};1235 1236static const struct soc_enum da7218_sidetone_in_sel =1237	SOC_ENUM_SINGLE(DA7218_SIDETONE_IN_SELECT,1238			DA7218_SIDETONE_IN_SELECT_SHIFT,1239			DA7218_SIDETONE_IN_SELECT_MAX,1240			da7218_sidetone_in_sel_txt);1241 1242static const struct snd_kcontrol_new da7218_sidetone_in_sel_mux =1243	SOC_DAPM_ENUM("Sidetone Mux", da7218_sidetone_in_sel);1244 1245static const char * const da7218_out_filt_biq_sel_txt[] = {1246	"Bypass", "Enabled"1247};1248 1249static const struct soc_enum da7218_out_filtl_biq_sel =1250	SOC_ENUM_SINGLE(DA7218_OUT_1L_FILTER_CTRL,1251			DA7218_OUT_1L_BIQ_5STAGE_SEL_SHIFT,1252			DA7218_OUT_BIQ_5STAGE_SEL_MAX,1253			da7218_out_filt_biq_sel_txt);1254 1255static const struct snd_kcontrol_new da7218_out_filtl_biq_sel_mux =1256	SOC_DAPM_ENUM("Out FilterL BiQuad Mux", da7218_out_filtl_biq_sel);1257 1258static const struct soc_enum da7218_out_filtr_biq_sel =1259	SOC_ENUM_SINGLE(DA7218_OUT_1R_FILTER_CTRL,1260			DA7218_OUT_1R_BIQ_5STAGE_SEL_SHIFT,1261			DA7218_OUT_BIQ_5STAGE_SEL_MAX,1262			da7218_out_filt_biq_sel_txt);1263 1264static const struct snd_kcontrol_new da7218_out_filtr_biq_sel_mux =1265	SOC_DAPM_ENUM("Out FilterR BiQuad Mux", da7218_out_filtr_biq_sel);1266 1267 1268/*1269 * DAPM Mixer Controls1270 */1271 1272#define DA7218_DMIX_CTRLS(reg)						\1273	SOC_DAPM_SINGLE("In Filter1L Switch", reg,			\1274			DA7218_DMIX_SRC_INFILT1L,			\1275			DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),	\1276	SOC_DAPM_SINGLE("In Filter1R Switch", reg,			\1277			DA7218_DMIX_SRC_INFILT1R,			\1278			DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),	\1279	SOC_DAPM_SINGLE("In Filter2L Switch", reg,			\1280			DA7218_DMIX_SRC_INFILT2L,			\1281			DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),	\1282	SOC_DAPM_SINGLE("In Filter2R Switch", reg,			\1283			DA7218_DMIX_SRC_INFILT2R,			\1284			DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),	\1285	SOC_DAPM_SINGLE("ToneGen Switch", reg,				\1286			DA7218_DMIX_SRC_TONEGEN,			\1287			DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),	\1288	SOC_DAPM_SINGLE("DAIL Switch", reg, DA7218_DMIX_SRC_DAIL,	\1289			DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),	\1290	SOC_DAPM_SINGLE("DAIR Switch", reg, DA7218_DMIX_SRC_DAIR,	\1291			DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT)1292 1293static const struct snd_kcontrol_new da7218_out_dai1l_mix_controls[] = {1294	DA7218_DMIX_CTRLS(DA7218_DROUTING_OUTDAI_1L),1295};1296 1297static const struct snd_kcontrol_new da7218_out_dai1r_mix_controls[] = {1298	DA7218_DMIX_CTRLS(DA7218_DROUTING_OUTDAI_1R),1299};1300 1301static const struct snd_kcontrol_new da7218_out_dai2l_mix_controls[] = {1302	DA7218_DMIX_CTRLS(DA7218_DROUTING_OUTDAI_2L),1303};1304 1305static const struct snd_kcontrol_new da7218_out_dai2r_mix_controls[] = {1306	DA7218_DMIX_CTRLS(DA7218_DROUTING_OUTDAI_2R),1307};1308 1309static const struct snd_kcontrol_new da7218_out_filtl_mix_controls[] = {1310	DA7218_DMIX_CTRLS(DA7218_DROUTING_OUTFILT_1L),1311};1312 1313static const struct snd_kcontrol_new da7218_out_filtr_mix_controls[] = {1314	DA7218_DMIX_CTRLS(DA7218_DROUTING_OUTFILT_1R),1315};1316 1317#define DA7218_DMIX_ST_CTRLS(reg)					\1318	SOC_DAPM_SINGLE("Out FilterL Switch", reg,			\1319			DA7218_DMIX_ST_SRC_OUTFILT1L,			\1320			DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),	\1321	SOC_DAPM_SINGLE("Out FilterR Switch", reg,			\1322			DA7218_DMIX_ST_SRC_OUTFILT1R,			\1323			DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT),	\1324	SOC_DAPM_SINGLE("Sidetone Switch", reg,				\1325			DA7218_DMIX_ST_SRC_SIDETONE,			\1326			DA7218_SWITCH_EN_MAX, DA7218_NO_INVERT)		\1327 1328static const struct snd_kcontrol_new da7218_st_out_filtl_mix_controls[] = {1329	DA7218_DMIX_ST_CTRLS(DA7218_DROUTING_ST_OUTFILT_1L),1330};1331 1332static const struct snd_kcontrol_new da7218_st_out_filtr_mix_controls[] = {1333	DA7218_DMIX_ST_CTRLS(DA7218_DROUTING_ST_OUTFILT_1R),1334};1335 1336 1337/*1338 * DAPM Events1339 */1340 1341/*1342 * We keep track of which input filters are enabled. This is used in the logic1343 * for controlling the mic level detect feature.1344 */1345static int da7218_in_filter_event(struct snd_soc_dapm_widget *w,1346				  struct snd_kcontrol *kcontrol, int event)1347{1348	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);1349	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);1350	u8 mask;1351 1352	switch (w->reg) {1353	case DA7218_IN_1L_FILTER_CTRL:1354		mask = (1 << DA7218_LVL_DET_EN_CHAN1L_SHIFT);1355		break;1356	case DA7218_IN_1R_FILTER_CTRL:1357		mask = (1 << DA7218_LVL_DET_EN_CHAN1R_SHIFT);1358		break;1359	case DA7218_IN_2L_FILTER_CTRL:1360		mask = (1 << DA7218_LVL_DET_EN_CHAN2L_SHIFT);1361		break;1362	case DA7218_IN_2R_FILTER_CTRL:1363		mask = (1 << DA7218_LVL_DET_EN_CHAN2R_SHIFT);1364		break;1365	default:1366		return -EINVAL;1367	}1368 1369	switch (event) {1370	case SND_SOC_DAPM_POST_PMU:1371		da7218->in_filt_en |= mask;1372		/*1373		 * If we're enabling path for mic level detect, wait for path1374		 * to settle before enabling feature to avoid incorrect and1375		 * unwanted detect events.1376		 */1377		if (mask & da7218->mic_lvl_det_en)1378			msleep(DA7218_MIC_LVL_DET_DELAY);1379		break;1380	case SND_SOC_DAPM_PRE_PMD:1381		da7218->in_filt_en &= ~mask;1382		break;1383	default:1384		return -EINVAL;1385	}1386 1387	/* Enable configured level detection paths */1388	snd_soc_component_write(component, DA7218_LVL_DET_CTRL,1389		      (da7218->in_filt_en & da7218->mic_lvl_det_en));1390 1391	return 0;1392}1393 1394static int da7218_dai_event(struct snd_soc_dapm_widget *w,1395			    struct snd_kcontrol *kcontrol, int event)1396{1397	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);1398	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);1399	u8 pll_ctrl, pll_status, refosc_cal;1400	int i;1401	bool success;1402 1403	switch (event) {1404	case SND_SOC_DAPM_POST_PMU:1405		if (da7218->master)1406			/* Enable DAI clks for master mode */1407			snd_soc_component_update_bits(component, DA7218_DAI_CLK_MODE,1408					    DA7218_DAI_CLK_EN_MASK,1409					    DA7218_DAI_CLK_EN_MASK);1410 1411		/* Tune reference oscillator */1412		snd_soc_component_write(component, DA7218_PLL_REFOSC_CAL,1413			      DA7218_PLL_REFOSC_CAL_START_MASK);1414		snd_soc_component_write(component, DA7218_PLL_REFOSC_CAL,1415			      DA7218_PLL_REFOSC_CAL_START_MASK |1416			      DA7218_PLL_REFOSC_CAL_EN_MASK);1417 1418		/* Check tuning complete */1419		i = 0;1420		success = false;1421		do {1422			refosc_cal = snd_soc_component_read(component, DA7218_PLL_REFOSC_CAL);1423			if (!(refosc_cal & DA7218_PLL_REFOSC_CAL_START_MASK)) {1424				success = true;1425			} else {1426				++i;1427				usleep_range(DA7218_REF_OSC_CHECK_DELAY_MIN,1428					     DA7218_REF_OSC_CHECK_DELAY_MAX);1429			}1430		} while ((i < DA7218_REF_OSC_CHECK_TRIES) && (!success));1431 1432		if (!success)1433			dev_warn(component->dev,1434				 "Reference oscillator failed calibration\n");1435 1436		/* PC synchronised to DAI */1437		snd_soc_component_write(component, DA7218_PC_COUNT,1438			      DA7218_PC_RESYNC_AUTO_MASK);1439 1440		/* If SRM not enabled, we don't need to check status */1441		pll_ctrl = snd_soc_component_read(component, DA7218_PLL_CTRL);1442		if ((pll_ctrl & DA7218_PLL_MODE_MASK) != DA7218_PLL_MODE_SRM)1443			return 0;1444 1445		/* Check SRM has locked */1446		i = 0;1447		success = false;1448		do {1449			pll_status = snd_soc_component_read(component, DA7218_PLL_STATUS);1450			if (pll_status & DA7218_PLL_SRM_STATUS_SRM_LOCK) {1451				success = true;1452			} else {1453				++i;1454				msleep(DA7218_SRM_CHECK_DELAY);1455			}1456		} while ((i < DA7218_SRM_CHECK_TRIES) && (!success));1457 1458		if (!success)1459			dev_warn(component->dev, "SRM failed to lock\n");1460 1461		return 0;1462	case SND_SOC_DAPM_POST_PMD:1463		/* PC free-running */1464		snd_soc_component_write(component, DA7218_PC_COUNT, DA7218_PC_FREERUN_MASK);1465 1466		if (da7218->master)1467			/* Disable DAI clks for master mode */1468			snd_soc_component_update_bits(component, DA7218_DAI_CLK_MODE,1469					    DA7218_DAI_CLK_EN_MASK, 0);1470 1471		return 0;1472	default:1473		return -EINVAL;1474	}1475}1476 1477static int da7218_cp_event(struct snd_soc_dapm_widget *w,1478			   struct snd_kcontrol *kcontrol, int event)1479{1480	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);1481	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);1482 1483	/*1484	 * If this is DA7217 and we're using single supply for differential1485	 * output, we really don't want to touch the charge pump.1486	 */1487	if (da7218->hp_single_supply)1488		return 0;1489 1490	switch (event) {1491	case SND_SOC_DAPM_PRE_PMU:1492		snd_soc_component_update_bits(component, DA7218_CP_CTRL, DA7218_CP_EN_MASK,1493				    DA7218_CP_EN_MASK);1494		return 0;1495	case SND_SOC_DAPM_PRE_PMD:1496		snd_soc_component_update_bits(component, DA7218_CP_CTRL, DA7218_CP_EN_MASK,1497				    0);1498		return 0;1499	default:1500		return -EINVAL;1501	}1502}1503 1504static int da7218_hp_pga_event(struct snd_soc_dapm_widget *w,1505			       struct snd_kcontrol *kcontrol, int event)1506{1507	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);1508 1509	switch (event) {1510	case SND_SOC_DAPM_POST_PMU:1511		/* Enable headphone output */1512		snd_soc_component_update_bits(component, w->reg, DA7218_HP_AMP_OE_MASK,1513				    DA7218_HP_AMP_OE_MASK);1514		return 0;1515	case SND_SOC_DAPM_PRE_PMD:1516		/* Headphone output high impedance */1517		snd_soc_component_update_bits(component, w->reg, DA7218_HP_AMP_OE_MASK, 0);1518		return 0;1519	default:1520		return -EINVAL;1521	}1522}1523 1524 1525/*1526 * DAPM Widgets1527 */1528 1529static const struct snd_soc_dapm_widget da7218_dapm_widgets[] = {1530	/* Input Supplies */1531	SND_SOC_DAPM_SUPPLY("Mic Bias1", DA7218_MICBIAS_EN,1532			    DA7218_MICBIAS_1_EN_SHIFT, DA7218_NO_INVERT,1533			    NULL, 0),1534	SND_SOC_DAPM_SUPPLY("Mic Bias2", DA7218_MICBIAS_EN,1535			    DA7218_MICBIAS_2_EN_SHIFT, DA7218_NO_INVERT,1536			    NULL, 0),1537	SND_SOC_DAPM_SUPPLY("DMic1 Left", DA7218_DMIC_1_CTRL,1538			    DA7218_DMIC_1L_EN_SHIFT, DA7218_NO_INVERT,1539			    NULL, 0),1540	SND_SOC_DAPM_SUPPLY("DMic1 Right", DA7218_DMIC_1_CTRL,1541			    DA7218_DMIC_1R_EN_SHIFT, DA7218_NO_INVERT,1542			    NULL, 0),1543	SND_SOC_DAPM_SUPPLY("DMic2 Left", DA7218_DMIC_2_CTRL,1544			    DA7218_DMIC_2L_EN_SHIFT, DA7218_NO_INVERT,1545			    NULL, 0),1546	SND_SOC_DAPM_SUPPLY("DMic2 Right", DA7218_DMIC_2_CTRL,1547			    DA7218_DMIC_2R_EN_SHIFT, DA7218_NO_INVERT,1548			    NULL, 0),1549 1550	/* Inputs */1551	SND_SOC_DAPM_INPUT("MIC1"),1552	SND_SOC_DAPM_INPUT("MIC2"),1553	SND_SOC_DAPM_INPUT("DMIC1L"),1554	SND_SOC_DAPM_INPUT("DMIC1R"),1555	SND_SOC_DAPM_INPUT("DMIC2L"),1556	SND_SOC_DAPM_INPUT("DMIC2R"),1557 1558	/* Input Mixer Supplies */1559	SND_SOC_DAPM_SUPPLY("Mixin1 Supply", DA7218_MIXIN_1_CTRL,1560			    DA7218_MIXIN_1_MIX_SEL_SHIFT, DA7218_NO_INVERT,1561			    NULL, 0),1562	SND_SOC_DAPM_SUPPLY("Mixin2 Supply", DA7218_MIXIN_2_CTRL,1563			    DA7218_MIXIN_2_MIX_SEL_SHIFT, DA7218_NO_INVERT,1564			    NULL, 0),1565 1566	/* Input PGAs */1567	SND_SOC_DAPM_PGA("Mic1 PGA", DA7218_MIC_1_CTRL,1568			 DA7218_MIC_1_AMP_EN_SHIFT, DA7218_NO_INVERT,1569			 NULL, 0),1570	SND_SOC_DAPM_PGA("Mic2 PGA", DA7218_MIC_2_CTRL,1571			 DA7218_MIC_2_AMP_EN_SHIFT, DA7218_NO_INVERT,1572			 NULL, 0),1573	SND_SOC_DAPM_PGA("Mixin1 PGA", DA7218_MIXIN_1_CTRL,1574			 DA7218_MIXIN_1_AMP_EN_SHIFT, DA7218_NO_INVERT,1575			 NULL, 0),1576	SND_SOC_DAPM_PGA("Mixin2 PGA", DA7218_MIXIN_2_CTRL,1577			 DA7218_MIXIN_2_AMP_EN_SHIFT, DA7218_NO_INVERT,1578			 NULL, 0),1579 1580	/* Mic/DMic Muxes */1581	SND_SOC_DAPM_MUX("Mic1 Mux", SND_SOC_NOPM, 0, 0, &da7218_mic1_sel_mux),1582	SND_SOC_DAPM_MUX("Mic2 Mux", SND_SOC_NOPM, 0, 0, &da7218_mic2_sel_mux),1583 1584	/* Input Filters */1585	SND_SOC_DAPM_ADC_E("In Filter1L", NULL, DA7218_IN_1L_FILTER_CTRL,1586			   DA7218_IN_1L_FILTER_EN_SHIFT, DA7218_NO_INVERT,1587			   da7218_in_filter_event,1588			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),1589	SND_SOC_DAPM_ADC_E("In Filter1R", NULL, DA7218_IN_1R_FILTER_CTRL,1590			   DA7218_IN_1R_FILTER_EN_SHIFT, DA7218_NO_INVERT,1591			   da7218_in_filter_event,1592			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),1593	SND_SOC_DAPM_ADC_E("In Filter2L", NULL, DA7218_IN_2L_FILTER_CTRL,1594			   DA7218_IN_2L_FILTER_EN_SHIFT, DA7218_NO_INVERT,1595			   da7218_in_filter_event,1596			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),1597	SND_SOC_DAPM_ADC_E("In Filter2R", NULL, DA7218_IN_2R_FILTER_CTRL,1598			   DA7218_IN_2R_FILTER_EN_SHIFT, DA7218_NO_INVERT,1599			   da7218_in_filter_event,1600			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),1601 1602	/* Tone Generator */1603	SND_SOC_DAPM_SIGGEN("TONE"),1604	SND_SOC_DAPM_PGA("Tone Generator", DA7218_TONE_GEN_CFG1,1605			 DA7218_START_STOPN_SHIFT, DA7218_NO_INVERT, NULL, 0),1606 1607	/* Sidetone Input */1608	SND_SOC_DAPM_MUX("Sidetone Mux", SND_SOC_NOPM, 0, 0,1609			 &da7218_sidetone_in_sel_mux),1610	SND_SOC_DAPM_ADC("Sidetone Filter", NULL, DA7218_SIDETONE_CTRL,1611			 DA7218_SIDETONE_FILTER_EN_SHIFT, DA7218_NO_INVERT),1612 1613	/* Input Mixers */1614	SND_SOC_DAPM_MIXER("Mixer DAI1L", SND_SOC_NOPM, 0, 0,1615			   da7218_out_dai1l_mix_controls,1616			   ARRAY_SIZE(da7218_out_dai1l_mix_controls)),1617	SND_SOC_DAPM_MIXER("Mixer DAI1R", SND_SOC_NOPM, 0, 0,1618			   da7218_out_dai1r_mix_controls,1619			   ARRAY_SIZE(da7218_out_dai1r_mix_controls)),1620	SND_SOC_DAPM_MIXER("Mixer DAI2L", SND_SOC_NOPM, 0, 0,1621			   da7218_out_dai2l_mix_controls,1622			   ARRAY_SIZE(da7218_out_dai2l_mix_controls)),1623	SND_SOC_DAPM_MIXER("Mixer DAI2R", SND_SOC_NOPM, 0, 0,1624			   da7218_out_dai2r_mix_controls,1625			   ARRAY_SIZE(da7218_out_dai2r_mix_controls)),1626 1627	/* DAI Supply */1628	SND_SOC_DAPM_SUPPLY("DAI", DA7218_DAI_CTRL, DA7218_DAI_EN_SHIFT,1629			    DA7218_NO_INVERT, da7218_dai_event,1630			    SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),1631 1632	/* DAI */1633	SND_SOC_DAPM_AIF_OUT("DAIOUT", "Capture", 0, DA7218_DAI_TDM_CTRL,1634			     DA7218_DAI_OE_SHIFT, DA7218_NO_INVERT),1635	SND_SOC_DAPM_AIF_IN("DAIIN", "Playback", 0, SND_SOC_NOPM, 0, 0),1636 1637	/* Output Mixers */1638	SND_SOC_DAPM_MIXER("Mixer Out FilterL", SND_SOC_NOPM, 0, 0,1639			   da7218_out_filtl_mix_controls,1640			   ARRAY_SIZE(da7218_out_filtl_mix_controls)),1641	SND_SOC_DAPM_MIXER("Mixer Out FilterR", SND_SOC_NOPM, 0, 0,1642			   da7218_out_filtr_mix_controls,1643			   ARRAY_SIZE(da7218_out_filtr_mix_controls)),1644 1645	/* BiQuad Filters */1646	SND_SOC_DAPM_MUX("Out FilterL BiQuad Mux", SND_SOC_NOPM, 0, 0,1647			 &da7218_out_filtl_biq_sel_mux),1648	SND_SOC_DAPM_MUX("Out FilterR BiQuad Mux", SND_SOC_NOPM, 0, 0,1649			 &da7218_out_filtr_biq_sel_mux),1650	SND_SOC_DAPM_DAC("BiQuad Filter", NULL, DA7218_OUT_1_BIQ_5STAGE_CTRL,1651			 DA7218_OUT_1_BIQ_5STAGE_FILTER_EN_SHIFT,1652			 DA7218_NO_INVERT),1653 1654	/* Sidetone Mixers */1655	SND_SOC_DAPM_MIXER("ST Mixer Out FilterL", SND_SOC_NOPM, 0, 0,1656			   da7218_st_out_filtl_mix_controls,1657			   ARRAY_SIZE(da7218_st_out_filtl_mix_controls)),1658	SND_SOC_DAPM_MIXER("ST Mixer Out FilterR", SND_SOC_NOPM, 0, 0,1659			   da7218_st_out_filtr_mix_controls,1660			   ARRAY_SIZE(da7218_st_out_filtr_mix_controls)),1661 1662	/* Output Filters */1663	SND_SOC_DAPM_DAC("Out FilterL", NULL, DA7218_OUT_1L_FILTER_CTRL,1664			 DA7218_OUT_1L_FILTER_EN_SHIFT, DA7218_NO_INVERT),1665	SND_SOC_DAPM_DAC("Out FilterR", NULL, DA7218_OUT_1R_FILTER_CTRL,1666			 DA7218_IN_1R_FILTER_EN_SHIFT, DA7218_NO_INVERT),1667 1668	/* Output PGAs */1669	SND_SOC_DAPM_PGA("Mixout Left PGA", DA7218_MIXOUT_L_CTRL,1670			 DA7218_MIXOUT_L_AMP_EN_SHIFT, DA7218_NO_INVERT,1671			 NULL, 0),1672	SND_SOC_DAPM_PGA("Mixout Right PGA", DA7218_MIXOUT_R_CTRL,1673			 DA7218_MIXOUT_R_AMP_EN_SHIFT, DA7218_NO_INVERT,1674			 NULL, 0),1675	SND_SOC_DAPM_PGA_E("Headphone Left PGA", DA7218_HP_L_CTRL,1676			   DA7218_HP_L_AMP_EN_SHIFT, DA7218_NO_INVERT, NULL, 0,1677			   da7218_hp_pga_event,1678			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),1679	SND_SOC_DAPM_PGA_E("Headphone Right PGA", DA7218_HP_R_CTRL,1680			   DA7218_HP_R_AMP_EN_SHIFT, DA7218_NO_INVERT, NULL, 0,1681			   da7218_hp_pga_event,1682			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),1683 1684	/* Output Supplies */1685	SND_SOC_DAPM_SUPPLY("Charge Pump", SND_SOC_NOPM, 0, 0, da7218_cp_event,1686			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),1687 1688	/* Outputs */1689	SND_SOC_DAPM_OUTPUT("HPL"),1690	SND_SOC_DAPM_OUTPUT("HPR"),1691};1692 1693 1694/*1695 * DAPM Mixer Routes1696 */1697 1698#define DA7218_DMIX_ROUTES(name)				\1699	{name, "In Filter1L Switch", "In Filter1L"},		\1700	{name, "In Filter1R Switch", "In Filter1R"},		\1701	{name, "In Filter2L Switch", "In Filter2L"},		\1702	{name, "In Filter2R Switch", "In Filter2R"},		\1703	{name, "ToneGen Switch", "Tone Generator"},		\1704	{name, "DAIL Switch", "DAIIN"},				\1705	{name, "DAIR Switch", "DAIIN"}1706 1707#define DA7218_DMIX_ST_ROUTES(name)				\1708	{name, "Out FilterL Switch", "Out FilterL BiQuad Mux"},	\1709	{name, "Out FilterR Switch", "Out FilterR BiQuad Mux"},	\1710	{name, "Sidetone Switch", "Sidetone Filter"}1711 1712 1713/*1714 * DAPM audio route definition1715 */1716 1717static const struct snd_soc_dapm_route da7218_audio_map[] = {1718	/* Input paths */1719	{"MIC1", NULL, "Mic Bias1"},1720	{"MIC2", NULL, "Mic Bias2"},1721	{"DMIC1L", NULL, "Mic Bias1"},1722	{"DMIC1L", NULL, "DMic1 Left"},1723	{"DMIC1R", NULL, "Mic Bias1"},1724	{"DMIC1R", NULL, "DMic1 Right"},1725	{"DMIC2L", NULL, "Mic Bias2"},1726	{"DMIC2L", NULL, "DMic2 Left"},1727	{"DMIC2R", NULL, "Mic Bias2"},1728	{"DMIC2R", NULL, "DMic2 Right"},1729 1730	{"Mic1 PGA", NULL, "MIC1"},1731	{"Mic2 PGA", NULL, "MIC2"},1732 1733	{"Mixin1 PGA", NULL, "Mixin1 Supply"},1734	{"Mixin2 PGA", NULL, "Mixin2 Supply"},1735 1736	{"Mixin1 PGA", NULL, "Mic1 PGA"},1737	{"Mixin2 PGA", NULL, "Mic2 PGA"},1738 1739	{"Mic1 Mux", "Analog", "Mixin1 PGA"},1740	{"Mic1 Mux", "Digital", "DMIC1L"},1741	{"Mic1 Mux", "Digital", "DMIC1R"},1742	{"Mic2 Mux", "Analog", "Mixin2 PGA"},1743	{"Mic2 Mux", "Digital", "DMIC2L"},1744	{"Mic2 Mux", "Digital", "DMIC2R"},1745 1746	{"In Filter1L", NULL, "Mic1 Mux"},1747	{"In Filter1R", NULL, "Mic1 Mux"},1748	{"In Filter2L", NULL, "Mic2 Mux"},1749	{"In Filter2R", NULL, "Mic2 Mux"},1750 1751	{"Tone Generator", NULL, "TONE"},1752 1753	{"Sidetone Mux", "In Filter1L", "In Filter1L"},1754	{"Sidetone Mux", "In Filter1R", "In Filter1R"},1755	{"Sidetone Mux", "In Filter2L", "In Filter2L"},1756	{"Sidetone Mux", "In Filter2R", "In Filter2R"},1757	{"Sidetone Filter", NULL, "Sidetone Mux"},1758 1759	DA7218_DMIX_ROUTES("Mixer DAI1L"),1760	DA7218_DMIX_ROUTES("Mixer DAI1R"),1761	DA7218_DMIX_ROUTES("Mixer DAI2L"),1762	DA7218_DMIX_ROUTES("Mixer DAI2R"),1763 1764	{"DAIOUT", NULL, "Mixer DAI1L"},1765	{"DAIOUT", NULL, "Mixer DAI1R"},1766	{"DAIOUT", NULL, "Mixer DAI2L"},1767	{"DAIOUT", NULL, "Mixer DAI2R"},1768 1769	{"DAIOUT", NULL, "DAI"},1770 1771	/* Output paths */1772	{"DAIIN", NULL, "DAI"},1773 1774	DA7218_DMIX_ROUTES("Mixer Out FilterL"),1775	DA7218_DMIX_ROUTES("Mixer Out FilterR"),1776 1777	{"BiQuad Filter", NULL, "Mixer Out FilterL"},1778	{"BiQuad Filter", NULL, "Mixer Out FilterR"},1779 1780	{"Out FilterL BiQuad Mux", "Bypass", "Mixer Out FilterL"},1781	{"Out FilterL BiQuad Mux", "Enabled", "BiQuad Filter"},1782	{"Out FilterR BiQuad Mux", "Bypass", "Mixer Out FilterR"},1783	{"Out FilterR BiQuad Mux", "Enabled", "BiQuad Filter"},1784 1785	DA7218_DMIX_ST_ROUTES("ST Mixer Out FilterL"),1786	DA7218_DMIX_ST_ROUTES("ST Mixer Out FilterR"),1787 1788	{"Out FilterL", NULL, "ST Mixer Out FilterL"},1789	{"Out FilterR", NULL, "ST Mixer Out FilterR"},1790 1791	{"Mixout Left PGA", NULL, "Out FilterL"},1792	{"Mixout Right PGA", NULL, "Out FilterR"},1793 1794	{"Headphone Left PGA", NULL, "Mixout Left PGA"},1795	{"Headphone Right PGA", NULL, "Mixout Right PGA"},1796 1797	{"HPL", NULL, "Headphone Left PGA"},1798	{"HPR", NULL, "Headphone Right PGA"},1799 1800	{"HPL", NULL, "Charge Pump"},1801	{"HPR", NULL, "Charge Pump"},1802};1803 1804 1805/*1806 * DAI operations1807 */1808 1809static int da7218_set_dai_sysclk(struct snd_soc_dai *codec_dai,1810				 int clk_id, unsigned int freq, int dir)1811{1812	struct snd_soc_component *component = codec_dai->component;1813	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);1814	int ret;1815 1816	if (da7218->mclk_rate == freq)1817		return 0;1818 1819	if ((freq < 2000000) || (freq > 54000000)) {1820		dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",1821			freq);1822		return -EINVAL;1823	}1824 1825	switch (clk_id) {1826	case DA7218_CLKSRC_MCLK_SQR:1827		snd_soc_component_update_bits(component, DA7218_PLL_CTRL,1828				    DA7218_PLL_MCLK_SQR_EN_MASK,1829				    DA7218_PLL_MCLK_SQR_EN_MASK);1830		break;1831	case DA7218_CLKSRC_MCLK:1832		snd_soc_component_update_bits(component, DA7218_PLL_CTRL,1833				    DA7218_PLL_MCLK_SQR_EN_MASK, 0);1834		break;1835	default:1836		dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id);1837		return -EINVAL;1838	}1839 1840	if (da7218->mclk) {1841		freq = clk_round_rate(da7218->mclk, freq);1842		ret = clk_set_rate(da7218->mclk, freq);1843		if (ret) {1844			dev_err(codec_dai->dev, "Failed to set clock rate %d\n",1845				freq);1846			return ret;1847		}1848	}1849 1850	da7218->mclk_rate = freq;1851 1852	return 0;1853}1854 1855static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,1856			      int source, unsigned int fref, unsigned int fout)1857{1858	struct snd_soc_component *component = codec_dai->component;1859	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);1860 1861	u8 pll_ctrl, indiv_bits, indiv;1862	u8 pll_frac_top, pll_frac_bot, pll_integer;1863	u32 freq_ref;1864	u64 frac_div;1865 1866	/* Verify 2MHz - 54MHz MCLK provided, and set input divider */1867	if (da7218->mclk_rate < 2000000) {1868		dev_err(component->dev, "PLL input clock %d below valid range\n",1869			da7218->mclk_rate);1870		return -EINVAL;1871	} else if (da7218->mclk_rate <= 4500000) {1872		indiv_bits = DA7218_PLL_INDIV_2_TO_4_5_MHZ;1873		indiv = DA7218_PLL_INDIV_2_TO_4_5_MHZ_VAL;1874	} else if (da7218->mclk_rate <= 9000000) {1875		indiv_bits = DA7218_PLL_INDIV_4_5_TO_9_MHZ;1876		indiv = DA7218_PLL_INDIV_4_5_TO_9_MHZ_VAL;1877	} else if (da7218->mclk_rate <= 18000000) {1878		indiv_bits = DA7218_PLL_INDIV_9_TO_18_MHZ;1879		indiv = DA7218_PLL_INDIV_9_TO_18_MHZ_VAL;1880	} else if (da7218->mclk_rate <= 36000000) {1881		indiv_bits = DA7218_PLL_INDIV_18_TO_36_MHZ;1882		indiv = DA7218_PLL_INDIV_18_TO_36_MHZ_VAL;1883	} else if (da7218->mclk_rate <= 54000000) {1884		indiv_bits = DA7218_PLL_INDIV_36_TO_54_MHZ;1885		indiv = DA7218_PLL_INDIV_36_TO_54_MHZ_VAL;1886	} else {1887		dev_err(component->dev, "PLL input clock %d above valid range\n",1888			da7218->mclk_rate);1889		return -EINVAL;1890	}1891	freq_ref = (da7218->mclk_rate / indiv);1892	pll_ctrl = indiv_bits;1893 1894	/* Configure PLL */1895	switch (source) {1896	case DA7218_SYSCLK_MCLK:1897		pll_ctrl |= DA7218_PLL_MODE_BYPASS;1898		snd_soc_component_update_bits(component, DA7218_PLL_CTRL,1899				    DA7218_PLL_INDIV_MASK |1900				    DA7218_PLL_MODE_MASK, pll_ctrl);1901		return 0;1902	case DA7218_SYSCLK_PLL:1903		pll_ctrl |= DA7218_PLL_MODE_NORMAL;1904		break;1905	case DA7218_SYSCLK_PLL_SRM:1906		pll_ctrl |= DA7218_PLL_MODE_SRM;1907		break;1908	default:1909		dev_err(component->dev, "Invalid PLL config\n");1910		return -EINVAL;1911	}1912 1913	/* Calculate dividers for PLL */1914	pll_integer = fout / freq_ref;1915	frac_div = (u64)(fout % freq_ref) * 8192ULL;1916	do_div(frac_div, freq_ref);1917	pll_frac_top = (frac_div >> DA7218_BYTE_SHIFT) & DA7218_BYTE_MASK;1918	pll_frac_bot = (frac_div) & DA7218_BYTE_MASK;1919 1920	/* Write PLL config & dividers */1921	snd_soc_component_write(component, DA7218_PLL_FRAC_TOP, pll_frac_top);1922	snd_soc_component_write(component, DA7218_PLL_FRAC_BOT, pll_frac_bot);1923	snd_soc_component_write(component, DA7218_PLL_INTEGER, pll_integer);1924	snd_soc_component_update_bits(component, DA7218_PLL_CTRL,1925			    DA7218_PLL_MODE_MASK | DA7218_PLL_INDIV_MASK,1926			    pll_ctrl);1927 1928	return 0;1929}1930 1931static int da7218_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)1932{1933	struct snd_soc_component *component = codec_dai->component;1934	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);1935	u8 dai_clk_mode = 0, dai_ctrl = 0;1936 1937	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {1938	case SND_SOC_DAIFMT_CBM_CFM:1939		da7218->master = true;1940		break;1941	case SND_SOC_DAIFMT_CBS_CFS:1942		da7218->master = false;1943		break;1944	default:1945		return -EINVAL;1946	}1947 1948	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {1949	case SND_SOC_DAIFMT_I2S:1950	case SND_SOC_DAIFMT_LEFT_J:1951	case SND_SOC_DAIFMT_RIGHT_J:1952		switch (fmt & SND_SOC_DAIFMT_INV_MASK) {1953		case SND_SOC_DAIFMT_NB_NF:1954			break;1955		case SND_SOC_DAIFMT_NB_IF:1956			dai_clk_mode |= DA7218_DAI_WCLK_POL_INV;1957			break;1958		case SND_SOC_DAIFMT_IB_NF:1959			dai_clk_mode |= DA7218_DAI_CLK_POL_INV;1960			break;1961		case SND_SOC_DAIFMT_IB_IF:1962			dai_clk_mode |= DA7218_DAI_WCLK_POL_INV |1963					DA7218_DAI_CLK_POL_INV;1964			break;1965		default:1966			return -EINVAL;1967		}1968		break;1969	case SND_SOC_DAIFMT_DSP_B:1970		switch (fmt & SND_SOC_DAIFMT_INV_MASK) {1971		case SND_SOC_DAIFMT_NB_NF:1972			dai_clk_mode |= DA7218_DAI_CLK_POL_INV;1973			break;1974		case SND_SOC_DAIFMT_NB_IF:1975			dai_clk_mode |= DA7218_DAI_WCLK_POL_INV |1976					DA7218_DAI_CLK_POL_INV;1977			break;1978		case SND_SOC_DAIFMT_IB_NF:1979			break;1980		case SND_SOC_DAIFMT_IB_IF:1981			dai_clk_mode |= DA7218_DAI_WCLK_POL_INV;1982			break;1983		default:1984			return -EINVAL;1985		}1986		break;1987	default:1988		return -EINVAL;1989	}1990 1991	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {1992	case SND_SOC_DAIFMT_I2S:1993		dai_ctrl |= DA7218_DAI_FORMAT_I2S;1994		break;1995	case SND_SOC_DAIFMT_LEFT_J:1996		dai_ctrl |= DA7218_DAI_FORMAT_LEFT_J;1997		break;1998	case SND_SOC_DAIFMT_RIGHT_J:1999		dai_ctrl |= DA7218_DAI_FORMAT_RIGHT_J;2000		break;2001	case SND_SOC_DAIFMT_DSP_B:2002		dai_ctrl |= DA7218_DAI_FORMAT_DSP;2003		break;2004	default:2005		return -EINVAL;2006	}2007 2008	/* By default 64 BCLKs per WCLK is supported */2009	dai_clk_mode |= DA7218_DAI_BCLKS_PER_WCLK_64;2010 2011	snd_soc_component_write(component, DA7218_DAI_CLK_MODE, dai_clk_mode);2012	snd_soc_component_update_bits(component, DA7218_DAI_CTRL, DA7218_DAI_FORMAT_MASK,2013			    dai_ctrl);2014 2015	return 0;2016}2017 2018static int da7218_set_dai_tdm_slot(struct snd_soc_dai *dai,2019				   unsigned int tx_mask, unsigned int rx_mask,2020				   int slots, int slot_width)2021{2022	struct snd_soc_component *component = dai->component;2023	u8 dai_bclks_per_wclk;2024	u32 frame_size;2025 2026	/* No channels enabled so disable TDM, revert to 64-bit frames */2027	if (!tx_mask) {2028		snd_soc_component_update_bits(component, DA7218_DAI_TDM_CTRL,2029				    DA7218_DAI_TDM_CH_EN_MASK |2030				    DA7218_DAI_TDM_MODE_EN_MASK, 0);2031		snd_soc_component_update_bits(component, DA7218_DAI_CLK_MODE,2032				    DA7218_DAI_BCLKS_PER_WCLK_MASK,2033				    DA7218_DAI_BCLKS_PER_WCLK_64);2034		return 0;2035	}2036 2037	/* Check we have valid slots */2038	if (fls(tx_mask) > DA7218_DAI_TDM_MAX_SLOTS) {2039		dev_err(component->dev, "Invalid number of slots, max = %d\n",2040			DA7218_DAI_TDM_MAX_SLOTS);2041		return -EINVAL;2042	}2043 2044	/* Check we have a valid offset given (first 2 bytes of rx_mask) */2045	if (rx_mask >> DA7218_2BYTE_SHIFT) {2046		dev_err(component->dev, "Invalid slot offset, max = %d\n",2047			DA7218_2BYTE_MASK);2048		return -EINVAL;2049	}2050 2051	/* Calculate & validate frame size based on slot info provided. */2052	frame_size = slots * slot_width;2053	switch (frame_size) {2054	case 32:2055		dai_bclks_per_wclk = DA7218_DAI_BCLKS_PER_WCLK_32;2056		break;2057	case 64:2058		dai_bclks_per_wclk = DA7218_DAI_BCLKS_PER_WCLK_64;2059		break;2060	case 128:2061		dai_bclks_per_wclk = DA7218_DAI_BCLKS_PER_WCLK_128;2062		break;2063	case 256:2064		dai_bclks_per_wclk = DA7218_DAI_BCLKS_PER_WCLK_256;2065		break;2066	default:2067		dev_err(component->dev, "Invalid frame size\n");2068		return -EINVAL;2069	}2070 2071	snd_soc_component_update_bits(component, DA7218_DAI_CLK_MODE,2072			    DA7218_DAI_BCLKS_PER_WCLK_MASK,2073			    dai_bclks_per_wclk);2074	snd_soc_component_write(component, DA7218_DAI_OFFSET_LOWER,2075		      (rx_mask & DA7218_BYTE_MASK));2076	snd_soc_component_write(component, DA7218_DAI_OFFSET_UPPER,2077		      ((rx_mask >> DA7218_BYTE_SHIFT) & DA7218_BYTE_MASK));2078	snd_soc_component_update_bits(component, DA7218_DAI_TDM_CTRL,2079			    DA7218_DAI_TDM_CH_EN_MASK |2080			    DA7218_DAI_TDM_MODE_EN_MASK,2081			    (tx_mask << DA7218_DAI_TDM_CH_EN_SHIFT) |2082			    DA7218_DAI_TDM_MODE_EN_MASK);2083 2084	return 0;2085}2086 2087static int da7218_hw_params(struct snd_pcm_substream *substream,2088			    struct snd_pcm_hw_params *params,2089			    struct snd_soc_dai *dai)2090{2091	struct snd_soc_component *component = dai->component;2092	u8 dai_ctrl = 0, fs;2093	unsigned int channels;2094 2095	switch (params_width(params)) {2096	case 16:2097		dai_ctrl |= DA7218_DAI_WORD_LENGTH_S16_LE;2098		break;2099	case 20:2100		dai_ctrl |= DA7218_DAI_WORD_LENGTH_S20_LE;2101		break;2102	case 24:2103		dai_ctrl |= DA7218_DAI_WORD_LENGTH_S24_LE;2104		break;2105	case 32:2106		dai_ctrl |= DA7218_DAI_WORD_LENGTH_S32_LE;2107		break;2108	default:2109		return -EINVAL;2110	}2111 2112	channels = params_channels(params);2113	if ((channels < 1) || (channels > DA7218_DAI_CH_NUM_MAX)) {2114		dev_err(component->dev,2115			"Invalid number of channels, only 1 to %d supported\n",2116			DA7218_DAI_CH_NUM_MAX);2117		return -EINVAL;2118	}2119	dai_ctrl |= channels << DA7218_DAI_CH_NUM_SHIFT;2120 2121	switch (params_rate(params)) {2122	case 8000:2123		fs = DA7218_SR_8000;2124		break;2125	case 11025:2126		fs = DA7218_SR_11025;2127		break;2128	case 12000:2129		fs = DA7218_SR_12000;2130		break;2131	case 16000:2132		fs = DA7218_SR_16000;2133		break;2134	case 22050:2135		fs = DA7218_SR_22050;2136		break;2137	case 24000:2138		fs = DA7218_SR_24000;2139		break;2140	case 32000:2141		fs = DA7218_SR_32000;2142		break;2143	case 44100:2144		fs = DA7218_SR_44100;2145		break;2146	case 48000:2147		fs = DA7218_SR_48000;2148		break;2149	case 88200:2150		fs = DA7218_SR_88200;2151		break;2152	case 96000:2153		fs = DA7218_SR_96000;2154		break;2155	default:2156		return -EINVAL;2157	}2158 2159	snd_soc_component_update_bits(component, DA7218_DAI_CTRL,2160			    DA7218_DAI_WORD_LENGTH_MASK | DA7218_DAI_CH_NUM_MASK,2161			    dai_ctrl);2162	/* SRs tied for ADCs and DACs. */2163	snd_soc_component_write(component, DA7218_SR,2164		      (fs << DA7218_SR_DAC_SHIFT) | (fs << DA7218_SR_ADC_SHIFT));2165 2166	return 0;2167}2168 2169static const struct snd_soc_dai_ops da7218_dai_ops = {2170	.hw_params	= da7218_hw_params,2171	.set_sysclk	= da7218_set_dai_sysclk,2172	.set_pll	= da7218_set_dai_pll,2173	.set_fmt	= da7218_set_dai_fmt,2174	.set_tdm_slot	= da7218_set_dai_tdm_slot,2175};2176 2177#define DA7218_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\2178			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)2179 2180static struct snd_soc_dai_driver da7218_dai = {2181	.name = "da7218-hifi",2182	.playback = {2183		.stream_name = "Playback",2184		.channels_min = 1,2185		.channels_max = 4,	/* Only 2 channels of data */2186		.rates = SNDRV_PCM_RATE_8000_96000,2187		.formats = DA7218_FORMATS,2188	},2189	.capture = {2190		.stream_name = "Capture",2191		.channels_min = 1,2192		.channels_max = 4,2193		.rates = SNDRV_PCM_RATE_8000_96000,2194		.formats = DA7218_FORMATS,2195	},2196	.ops = &da7218_dai_ops,2197	.symmetric_rate = 1,2198	.symmetric_channels = 1,2199	.symmetric_sample_bits = 1,2200};2201 2202 2203/*2204 * HP Detect2205 */2206 2207int da7218_hpldet(struct snd_soc_component *component, struct snd_soc_jack *jack)2208{2209	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);2210 2211	if (da7218->dev_id == DA7217_DEV_ID)2212		return -EINVAL;2213 2214	da7218->jack = jack;2215	snd_soc_component_update_bits(component, DA7218_HPLDET_JACK,2216			    DA7218_HPLDET_JACK_EN_MASK,2217			    jack ? DA7218_HPLDET_JACK_EN_MASK : 0);2218 2219	return 0;2220}2221EXPORT_SYMBOL_GPL(da7218_hpldet);2222 2223static void da7218_micldet_irq(struct snd_soc_component *component)2224{2225	char *envp[] = {2226		"EVENT=MIC_LEVEL_DETECT",2227		NULL,2228	};2229 2230	kobject_uevent_env(&component->dev->kobj, KOBJ_CHANGE, envp);2231}2232 2233static void da7218_hpldet_irq(struct snd_soc_component *component)2234{2235	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);2236	u8 jack_status;2237	int report;2238 2239	jack_status = snd_soc_component_read(component, DA7218_EVENT_STATUS);2240 2241	if (jack_status & DA7218_HPLDET_JACK_STS_MASK)2242		report = SND_JACK_HEADPHONE;2243	else2244		report = 0;2245 2246	snd_soc_jack_report(da7218->jack, report, SND_JACK_HEADPHONE);2247}2248 2249/*2250 * IRQ2251 */2252 2253static irqreturn_t da7218_irq_thread(int irq, void *data)2254{2255	struct snd_soc_component *component = data;2256	u8 status;2257 2258	/* Read IRQ status reg */2259	status = snd_soc_component_read(component, DA7218_EVENT);2260	if (!status)2261		return IRQ_NONE;2262 2263	/* Mic level detect */2264	if (status & DA7218_LVL_DET_EVENT_MASK)2265		da7218_micldet_irq(component);2266 2267	/* HP detect */2268	if (status & DA7218_HPLDET_JACK_EVENT_MASK)2269		da7218_hpldet_irq(component);2270 2271	/* Clear interrupts */2272	snd_soc_component_write(component, DA7218_EVENT, status);2273 2274	return IRQ_HANDLED;2275}2276 2277/*2278 * DT2279 */2280 2281static const struct of_device_id da7218_of_match[] = {2282	{ .compatible = "dlg,da7217", .data = (void *) DA7217_DEV_ID },2283	{ .compatible = "dlg,da7218", .data = (void *) DA7218_DEV_ID },2284	{ }2285};2286MODULE_DEVICE_TABLE(of, da7218_of_match);2287 2288static enum da7218_micbias_voltage2289	da7218_of_micbias_lvl(struct snd_soc_component *component, u32 val)2290{2291	switch (val) {2292	case 1200:2293		return DA7218_MICBIAS_1_2V;2294	case 1600:2295		return DA7218_MICBIAS_1_6V;2296	case 1800:2297		return DA7218_MICBIAS_1_8V;2298	case 2000:2299		return DA7218_MICBIAS_2_0V;2300	case 2200:2301		return DA7218_MICBIAS_2_2V;2302	case 2400:2303		return DA7218_MICBIAS_2_4V;2304	case 2600:2305		return DA7218_MICBIAS_2_6V;2306	case 2800:2307		return DA7218_MICBIAS_2_8V;2308	case 3000:2309		return DA7218_MICBIAS_3_0V;2310	default:2311		dev_warn(component->dev, "Invalid micbias level");2312		return DA7218_MICBIAS_1_6V;2313	}2314}2315 2316static enum da7218_mic_amp_in_sel2317	da7218_of_mic_amp_in_sel(struct snd_soc_component *component, const char *str)2318{2319	if (!strcmp(str, "diff")) {2320		return DA7218_MIC_AMP_IN_SEL_DIFF;2321	} else if (!strcmp(str, "se_p")) {2322		return DA7218_MIC_AMP_IN_SEL_SE_P;2323	} else if (!strcmp(str, "se_n")) {2324		return DA7218_MIC_AMP_IN_SEL_SE_N;2325	} else {2326		dev_warn(component->dev, "Invalid mic input type selection");2327		return DA7218_MIC_AMP_IN_SEL_DIFF;2328	}2329}2330 2331static enum da7218_dmic_data_sel2332	da7218_of_dmic_data_sel(struct snd_soc_component *component, const char *str)2333{2334	if (!strcmp(str, "lrise_rfall")) {2335		return DA7218_DMIC_DATA_LRISE_RFALL;2336	} else if (!strcmp(str, "lfall_rrise")) {2337		return DA7218_DMIC_DATA_LFALL_RRISE;2338	} else {2339		dev_warn(component->dev, "Invalid DMIC data type selection");2340		return DA7218_DMIC_DATA_LRISE_RFALL;2341	}2342}2343 2344static enum da7218_dmic_samplephase2345	da7218_of_dmic_samplephase(struct snd_soc_component *component, const char *str)2346{2347	if (!strcmp(str, "on_clkedge")) {2348		return DA7218_DMIC_SAMPLE_ON_CLKEDGE;2349	} else if (!strcmp(str, "between_clkedge")) {2350		return DA7218_DMIC_SAMPLE_BETWEEN_CLKEDGE;2351	} else {2352		dev_warn(component->dev, "Invalid DMIC sample phase");2353		return DA7218_DMIC_SAMPLE_ON_CLKEDGE;2354	}2355}2356 2357static enum da7218_dmic_clk_rate2358	da7218_of_dmic_clkrate(struct snd_soc_component *component, u32 val)2359{2360	switch (val) {2361	case 1500000:2362		return DA7218_DMIC_CLK_1_5MHZ;2363	case 3000000:2364		return DA7218_DMIC_CLK_3_0MHZ;2365	default:2366		dev_warn(component->dev, "Invalid DMIC clock rate");2367		return DA7218_DMIC_CLK_3_0MHZ;2368	}2369}2370 2371static enum da7218_hpldet_jack_rate2372	da7218_of_jack_rate(struct snd_soc_component *component, u32 val)2373{2374	switch (val) {2375	case 5:2376		return DA7218_HPLDET_JACK_RATE_5US;2377	case 10:2378		return DA7218_HPLDET_JACK_RATE_10US;2379	case 20:2380		return DA7218_HPLDET_JACK_RATE_20US;2381	case 40:2382		return DA7218_HPLDET_JACK_RATE_40US;2383	case 80:2384		return DA7218_HPLDET_JACK_RATE_80US;2385	case 160:2386		return DA7218_HPLDET_JACK_RATE_160US;2387	case 320:2388		return DA7218_HPLDET_JACK_RATE_320US;2389	case 640:2390		return DA7218_HPLDET_JACK_RATE_640US;2391	default:2392		dev_warn(component->dev, "Invalid jack detect rate");2393		return DA7218_HPLDET_JACK_RATE_40US;2394	}2395}2396 2397static enum da7218_hpldet_jack_debounce2398	da7218_of_jack_debounce(struct snd_soc_component *component, u32 val)2399{2400	switch (val) {2401	case 0:2402		return DA7218_HPLDET_JACK_DEBOUNCE_OFF;2403	case 2:2404		return DA7218_HPLDET_JACK_DEBOUNCE_2;2405	case 3:2406		return DA7218_HPLDET_JACK_DEBOUNCE_3;2407	case 4:2408		return DA7218_HPLDET_JACK_DEBOUNCE_4;2409	default:2410		dev_warn(component->dev, "Invalid jack debounce");2411		return DA7218_HPLDET_JACK_DEBOUNCE_2;2412	}2413}2414 2415static enum da7218_hpldet_jack_thr2416	da7218_of_jack_thr(struct snd_soc_component *component, u32 val)2417{2418	switch (val) {2419	case 84:2420		return DA7218_HPLDET_JACK_THR_84PCT;2421	case 88:2422		return DA7218_HPLDET_JACK_THR_88PCT;2423	case 92:2424		return DA7218_HPLDET_JACK_THR_92PCT;2425	case 96:2426		return DA7218_HPLDET_JACK_THR_96PCT;2427	default:2428		dev_warn(component->dev, "Invalid jack threshold level");2429		return DA7218_HPLDET_JACK_THR_84PCT;2430	}2431}2432 2433static struct da7218_pdata *da7218_of_to_pdata(struct snd_soc_component *component)2434{2435	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);2436	struct device_node *np = component->dev->of_node;2437	struct device_node *hpldet_np;2438	struct da7218_pdata *pdata;2439	struct da7218_hpldet_pdata *hpldet_pdata;2440	const char *of_str;2441	u32 of_val32;2442 2443	pdata = devm_kzalloc(component->dev, sizeof(*pdata), GFP_KERNEL);2444	if (!pdata)2445		return NULL;2446 2447	if (of_property_read_u32(np, "dlg,micbias1-lvl-millivolt", &of_val32) >= 0)2448		pdata->micbias1_lvl = da7218_of_micbias_lvl(component, of_val32);2449	else2450		pdata->micbias1_lvl = DA7218_MICBIAS_1_6V;2451 2452	if (of_property_read_u32(np, "dlg,micbias2-lvl-millivolt", &of_val32) >= 0)2453		pdata->micbias2_lvl = da7218_of_micbias_lvl(component, of_val32);2454	else2455		pdata->micbias2_lvl = DA7218_MICBIAS_1_6V;2456 2457	if (!of_property_read_string(np, "dlg,mic1-amp-in-sel", &of_str))2458		pdata->mic1_amp_in_sel =2459			da7218_of_mic_amp_in_sel(component, of_str);2460	else2461		pdata->mic1_amp_in_sel = DA7218_MIC_AMP_IN_SEL_DIFF;2462 2463	if (!of_property_read_string(np, "dlg,mic2-amp-in-sel", &of_str))2464		pdata->mic2_amp_in_sel =2465			da7218_of_mic_amp_in_sel(component, of_str);2466	else2467		pdata->mic2_amp_in_sel = DA7218_MIC_AMP_IN_SEL_DIFF;2468 2469	if (!of_property_read_string(np, "dlg,dmic1-data-sel", &of_str))2470		pdata->dmic1_data_sel =	da7218_of_dmic_data_sel(component, of_str);2471	else2472		pdata->dmic1_data_sel =	DA7218_DMIC_DATA_LRISE_RFALL;2473 2474	if (!of_property_read_string(np, "dlg,dmic1-samplephase", &of_str))2475		pdata->dmic1_samplephase =2476			da7218_of_dmic_samplephase(component, of_str);2477	else2478		pdata->dmic1_samplephase = DA7218_DMIC_SAMPLE_ON_CLKEDGE;2479 2480	if (of_property_read_u32(np, "dlg,dmic1-clkrate-hz", &of_val32) >= 0)2481		pdata->dmic1_clk_rate = da7218_of_dmic_clkrate(component, of_val32);2482	else2483		pdata->dmic1_clk_rate = DA7218_DMIC_CLK_3_0MHZ;2484 2485	if (!of_property_read_string(np, "dlg,dmic2-data-sel", &of_str))2486		pdata->dmic2_data_sel = da7218_of_dmic_data_sel(component, of_str);2487	else2488		pdata->dmic2_data_sel =	DA7218_DMIC_DATA_LRISE_RFALL;2489 2490	if (!of_property_read_string(np, "dlg,dmic2-samplephase", &of_str))2491		pdata->dmic2_samplephase =2492			da7218_of_dmic_samplephase(component, of_str);2493	else2494		pdata->dmic2_samplephase = DA7218_DMIC_SAMPLE_ON_CLKEDGE;2495 2496	if (of_property_read_u32(np, "dlg,dmic2-clkrate-hz", &of_val32) >= 0)2497		pdata->dmic2_clk_rate = da7218_of_dmic_clkrate(component, of_val32);2498	else2499		pdata->dmic2_clk_rate = DA7218_DMIC_CLK_3_0MHZ;2500 2501	if (da7218->dev_id == DA7217_DEV_ID) {2502		if (of_property_read_bool(np, "dlg,hp-diff-single-supply"))2503			pdata->hp_diff_single_supply = true;2504	}2505 2506	if (da7218->dev_id == DA7218_DEV_ID) {2507		hpldet_np = of_get_child_by_name(np, "da7218_hpldet");2508		if (!hpldet_np)2509			return pdata;2510 2511		hpldet_pdata = devm_kzalloc(component->dev, sizeof(*hpldet_pdata),2512					    GFP_KERNEL);2513		if (!hpldet_pdata) {2514			of_node_put(hpldet_np);2515			return pdata;2516		}2517		pdata->hpldet_pdata = hpldet_pdata;2518 2519		if (of_property_read_u32(hpldet_np, "dlg,jack-rate-us",2520					 &of_val32) >= 0)2521			hpldet_pdata->jack_rate =2522				da7218_of_jack_rate(component, of_val32);2523		else2524			hpldet_pdata->jack_rate = DA7218_HPLDET_JACK_RATE_40US;2525 2526		if (of_property_read_u32(hpldet_np, "dlg,jack-debounce",2527					 &of_val32) >= 0)2528			hpldet_pdata->jack_debounce =2529				da7218_of_jack_debounce(component, of_val32);2530		else2531			hpldet_pdata->jack_debounce =2532				DA7218_HPLDET_JACK_DEBOUNCE_2;2533 2534		if (of_property_read_u32(hpldet_np, "dlg,jack-threshold-pct",2535					 &of_val32) >= 0)2536			hpldet_pdata->jack_thr =2537				da7218_of_jack_thr(component, of_val32);2538		else2539			hpldet_pdata->jack_thr = DA7218_HPLDET_JACK_THR_84PCT;2540 2541		if (of_property_read_bool(hpldet_np, "dlg,comp-inv"))2542			hpldet_pdata->comp_inv = true;2543 2544		if (of_property_read_bool(hpldet_np, "dlg,hyst"))2545			hpldet_pdata->hyst = true;2546 2547		if (of_property_read_bool(hpldet_np, "dlg,discharge"))2548			hpldet_pdata->discharge = true;2549 2550		of_node_put(hpldet_np);2551	}2552 2553	return pdata;2554}2555 2556 2557/*2558 * Codec driver functions2559 */2560 2561static int da7218_set_bias_level(struct snd_soc_component *component,2562				 enum snd_soc_bias_level level)2563{2564	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);2565	int ret;2566 2567	switch (level) {2568	case SND_SOC_BIAS_ON:2569		break;2570	case SND_SOC_BIAS_PREPARE:2571		/* Enable MCLK for transition to ON state */2572		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_STANDBY) {2573			if (da7218->mclk) {2574				ret = clk_prepare_enable(da7218->mclk);2575				if (ret) {2576					dev_err(component->dev, "Failed to enable mclk\n");2577					return ret;2578				}2579			}2580		}2581 2582		break;2583	case SND_SOC_BIAS_STANDBY:2584		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {2585			/* Master bias */2586			snd_soc_component_update_bits(component, DA7218_REFERENCES,2587					    DA7218_BIAS_EN_MASK,2588					    DA7218_BIAS_EN_MASK);2589 2590			/* Internal LDO */2591			snd_soc_component_update_bits(component, DA7218_LDO_CTRL,2592					    DA7218_LDO_EN_MASK,2593					    DA7218_LDO_EN_MASK);2594		} else {2595			/* Remove MCLK */2596			if (da7218->mclk)2597				clk_disable_unprepare(da7218->mclk);2598		}2599		break;2600	case SND_SOC_BIAS_OFF:2601		/* Only disable if jack detection disabled */2602		if (!da7218->jack) {2603			/* Internal LDO */2604			snd_soc_component_update_bits(component, DA7218_LDO_CTRL,2605					    DA7218_LDO_EN_MASK, 0);2606 2607			/* Master bias */2608			snd_soc_component_update_bits(component, DA7218_REFERENCES,2609					    DA7218_BIAS_EN_MASK, 0);2610		}2611		break;2612	}2613 2614	return 0;2615}2616 2617static const char *da7218_supply_names[DA7218_NUM_SUPPLIES] = {2618	[DA7218_SUPPLY_VDD] = "VDD",2619	[DA7218_SUPPLY_VDDMIC] = "VDDMIC",2620	[DA7218_SUPPLY_VDDIO] = "VDDIO",2621};2622 2623static int da7218_handle_supplies(struct snd_soc_component *component)2624{2625	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);2626	struct regulator *vddio;2627	u8 io_voltage_lvl = DA7218_IO_VOLTAGE_LEVEL_2_5V_3_6V;2628	int i, ret;2629 2630	/* Get required supplies */2631	for (i = 0; i < DA7218_NUM_SUPPLIES; ++i)2632		da7218->supplies[i].supply = da7218_supply_names[i];2633 2634	ret = devm_regulator_bulk_get(component->dev, DA7218_NUM_SUPPLIES,2635				      da7218->supplies);2636	if (ret) {2637		dev_err(component->dev, "Failed to get supplies\n");2638		return ret;2639	}2640 2641	/* Determine VDDIO voltage provided */2642	vddio = da7218->supplies[DA7218_SUPPLY_VDDIO].consumer;2643	ret = regulator_get_voltage(vddio);2644	if (ret < 1500000)2645		dev_warn(component->dev, "Invalid VDDIO voltage\n");2646	else if (ret < 2500000)2647		io_voltage_lvl = DA7218_IO_VOLTAGE_LEVEL_1_5V_2_5V;2648 2649	/* Enable main supplies */2650	ret = regulator_bulk_enable(DA7218_NUM_SUPPLIES, da7218->supplies);2651	if (ret) {2652		dev_err(component->dev, "Failed to enable supplies\n");2653		return ret;2654	}2655 2656	/* Ensure device in active mode */2657	snd_soc_component_write(component, DA7218_SYSTEM_ACTIVE, DA7218_SYSTEM_ACTIVE_MASK);2658 2659	/* Update IO voltage level range */2660	snd_soc_component_write(component, DA7218_IO_CTRL, io_voltage_lvl);2661 2662	return 0;2663}2664 2665static void da7218_handle_pdata(struct snd_soc_component *component)2666{2667	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);2668	struct da7218_pdata *pdata = da7218->pdata;2669 2670	if (pdata) {2671		u8 micbias_lvl = 0, dmic_cfg = 0;2672 2673		/* Mic Bias voltages */2674		switch (pdata->micbias1_lvl) {2675		case DA7218_MICBIAS_1_2V:2676			micbias_lvl |= DA7218_MICBIAS_1_LP_MODE_MASK;2677			break;2678		case DA7218_MICBIAS_1_6V:2679		case DA7218_MICBIAS_1_8V:2680		case DA7218_MICBIAS_2_0V:2681		case DA7218_MICBIAS_2_2V:2682		case DA7218_MICBIAS_2_4V:2683		case DA7218_MICBIAS_2_6V:2684		case DA7218_MICBIAS_2_8V:2685		case DA7218_MICBIAS_3_0V:2686			micbias_lvl |= (pdata->micbias1_lvl <<2687					DA7218_MICBIAS_1_LEVEL_SHIFT);2688			break;2689		}2690 2691		switch (pdata->micbias2_lvl) {2692		case DA7218_MICBIAS_1_2V:2693			micbias_lvl |= DA7218_MICBIAS_2_LP_MODE_MASK;2694			break;2695		case DA7218_MICBIAS_1_6V:2696		case DA7218_MICBIAS_1_8V:2697		case DA7218_MICBIAS_2_0V:2698		case DA7218_MICBIAS_2_2V:2699		case DA7218_MICBIAS_2_4V:2700		case DA7218_MICBIAS_2_6V:2701		case DA7218_MICBIAS_2_8V:2702		case DA7218_MICBIAS_3_0V:2703			micbias_lvl |= (pdata->micbias2_lvl <<2704					 DA7218_MICBIAS_2_LEVEL_SHIFT);2705			break;2706		}2707 2708		snd_soc_component_write(component, DA7218_MICBIAS_CTRL, micbias_lvl);2709 2710		/* Mic */2711		switch (pdata->mic1_amp_in_sel) {2712		case DA7218_MIC_AMP_IN_SEL_DIFF:2713		case DA7218_MIC_AMP_IN_SEL_SE_P:2714		case DA7218_MIC_AMP_IN_SEL_SE_N:2715			snd_soc_component_write(component, DA7218_MIC_1_SELECT,2716				      pdata->mic1_amp_in_sel);2717			break;2718		}2719 2720		switch (pdata->mic2_amp_in_sel) {2721		case DA7218_MIC_AMP_IN_SEL_DIFF:2722		case DA7218_MIC_AMP_IN_SEL_SE_P:2723		case DA7218_MIC_AMP_IN_SEL_SE_N:2724			snd_soc_component_write(component, DA7218_MIC_2_SELECT,2725				      pdata->mic2_amp_in_sel);2726			break;2727		}2728 2729		/* DMic */2730		switch (pdata->dmic1_data_sel) {2731		case DA7218_DMIC_DATA_LFALL_RRISE:2732		case DA7218_DMIC_DATA_LRISE_RFALL:2733			dmic_cfg |= (pdata->dmic1_data_sel <<2734				     DA7218_DMIC_1_DATA_SEL_SHIFT);2735			break;2736		}2737 2738		switch (pdata->dmic1_samplephase) {2739		case DA7218_DMIC_SAMPLE_ON_CLKEDGE:2740		case DA7218_DMIC_SAMPLE_BETWEEN_CLKEDGE:2741			dmic_cfg |= (pdata->dmic1_samplephase <<2742				     DA7218_DMIC_1_SAMPLEPHASE_SHIFT);2743			break;2744		}2745 2746		switch (pdata->dmic1_clk_rate) {2747		case DA7218_DMIC_CLK_3_0MHZ:2748		case DA7218_DMIC_CLK_1_5MHZ:2749			dmic_cfg |= (pdata->dmic1_clk_rate <<2750				     DA7218_DMIC_1_CLK_RATE_SHIFT);2751			break;2752		}2753 2754		snd_soc_component_update_bits(component, DA7218_DMIC_1_CTRL,2755				    DA7218_DMIC_1_DATA_SEL_MASK |2756				    DA7218_DMIC_1_SAMPLEPHASE_MASK |2757				    DA7218_DMIC_1_CLK_RATE_MASK, dmic_cfg);2758 2759		dmic_cfg = 0;2760		switch (pdata->dmic2_data_sel) {2761		case DA7218_DMIC_DATA_LFALL_RRISE:2762		case DA7218_DMIC_DATA_LRISE_RFALL:2763			dmic_cfg |= (pdata->dmic2_data_sel <<2764				     DA7218_DMIC_2_DATA_SEL_SHIFT);2765			break;2766		}2767 2768		switch (pdata->dmic2_samplephase) {2769		case DA7218_DMIC_SAMPLE_ON_CLKEDGE:2770		case DA7218_DMIC_SAMPLE_BETWEEN_CLKEDGE:2771			dmic_cfg |= (pdata->dmic2_samplephase <<2772				     DA7218_DMIC_2_SAMPLEPHASE_SHIFT);2773			break;2774		}2775 2776		switch (pdata->dmic2_clk_rate) {2777		case DA7218_DMIC_CLK_3_0MHZ:2778		case DA7218_DMIC_CLK_1_5MHZ:2779			dmic_cfg |= (pdata->dmic2_clk_rate <<2780				     DA7218_DMIC_2_CLK_RATE_SHIFT);2781			break;2782		}2783 2784		snd_soc_component_update_bits(component, DA7218_DMIC_2_CTRL,2785				    DA7218_DMIC_2_DATA_SEL_MASK |2786				    DA7218_DMIC_2_SAMPLEPHASE_MASK |2787				    DA7218_DMIC_2_CLK_RATE_MASK, dmic_cfg);2788 2789		/* DA7217 Specific */2790		if (da7218->dev_id == DA7217_DEV_ID) {2791			da7218->hp_single_supply =2792				pdata->hp_diff_single_supply;2793 2794			if (da7218->hp_single_supply) {2795				snd_soc_component_write(component, DA7218_HP_DIFF_UNLOCK,2796					      DA7218_HP_DIFF_UNLOCK_VAL);2797				snd_soc_component_update_bits(component, DA7218_HP_DIFF_CTRL,2798						    DA7218_HP_AMP_SINGLE_SUPPLY_EN_MASK,2799						    DA7218_HP_AMP_SINGLE_SUPPLY_EN_MASK);2800			}2801		}2802 2803		/* DA7218 Specific */2804		if ((da7218->dev_id == DA7218_DEV_ID) &&2805		    (pdata->hpldet_pdata)) {2806			struct da7218_hpldet_pdata *hpldet_pdata =2807				pdata->hpldet_pdata;2808			u8 hpldet_cfg = 0;2809 2810			switch (hpldet_pdata->jack_rate) {2811			case DA7218_HPLDET_JACK_RATE_5US:2812			case DA7218_HPLDET_JACK_RATE_10US:2813			case DA7218_HPLDET_JACK_RATE_20US:2814			case DA7218_HPLDET_JACK_RATE_40US:2815			case DA7218_HPLDET_JACK_RATE_80US:2816			case DA7218_HPLDET_JACK_RATE_160US:2817			case DA7218_HPLDET_JACK_RATE_320US:2818			case DA7218_HPLDET_JACK_RATE_640US:2819				hpldet_cfg |=2820					(hpldet_pdata->jack_rate <<2821					 DA7218_HPLDET_JACK_RATE_SHIFT);2822				break;2823			}2824 2825			switch (hpldet_pdata->jack_debounce) {2826			case DA7218_HPLDET_JACK_DEBOUNCE_OFF:2827			case DA7218_HPLDET_JACK_DEBOUNCE_2:2828			case DA7218_HPLDET_JACK_DEBOUNCE_3:2829			case DA7218_HPLDET_JACK_DEBOUNCE_4:2830				hpldet_cfg |=2831					(hpldet_pdata->jack_debounce <<2832					 DA7218_HPLDET_JACK_DEBOUNCE_SHIFT);2833				break;2834			}2835 2836			switch (hpldet_pdata->jack_thr) {2837			case DA7218_HPLDET_JACK_THR_84PCT:2838			case DA7218_HPLDET_JACK_THR_88PCT:2839			case DA7218_HPLDET_JACK_THR_92PCT:2840			case DA7218_HPLDET_JACK_THR_96PCT:2841				hpldet_cfg |=2842					(hpldet_pdata->jack_thr <<2843					 DA7218_HPLDET_JACK_THR_SHIFT);2844				break;2845			}2846			snd_soc_component_update_bits(component, DA7218_HPLDET_JACK,2847					    DA7218_HPLDET_JACK_RATE_MASK |2848					    DA7218_HPLDET_JACK_DEBOUNCE_MASK |2849					    DA7218_HPLDET_JACK_THR_MASK,2850					    hpldet_cfg);2851 2852			hpldet_cfg = 0;2853			if (hpldet_pdata->comp_inv)2854				hpldet_cfg |= DA7218_HPLDET_COMP_INV_MASK;2855 2856			if (hpldet_pdata->hyst)2857				hpldet_cfg |= DA7218_HPLDET_HYST_EN_MASK;2858 2859			if (hpldet_pdata->discharge)2860				hpldet_cfg |= DA7218_HPLDET_DISCHARGE_EN_MASK;2861 2862			snd_soc_component_write(component, DA7218_HPLDET_CTRL, hpldet_cfg);2863		}2864	}2865}2866 2867static int da7218_probe(struct snd_soc_component *component)2868{2869	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);2870	int ret;2871 2872	/* Regulator configuration */2873	ret = da7218_handle_supplies(component);2874	if (ret)2875		return ret;2876 2877	/* Handle DT/Platform data */2878	if (component->dev->of_node)2879		da7218->pdata = da7218_of_to_pdata(component);2880	else2881		da7218->pdata = dev_get_platdata(component->dev);2882 2883	da7218_handle_pdata(component);2884 2885	/* Check if MCLK provided, if not the clock is NULL */2886	da7218->mclk = devm_clk_get_optional(component->dev, "mclk");2887	if (IS_ERR(da7218->mclk)) {2888		ret = PTR_ERR(da7218->mclk);2889		goto err_disable_reg;2890	}2891 2892	/* Default PC to free-running */2893	snd_soc_component_write(component, DA7218_PC_COUNT, DA7218_PC_FREERUN_MASK);2894 2895	/*2896	 * Default Output Filter mixers to off otherwise DAPM will power2897	 * Mic to HP passthrough paths by default at startup.2898	 */2899	snd_soc_component_write(component, DA7218_DROUTING_OUTFILT_1L, 0);2900	snd_soc_component_write(component, DA7218_DROUTING_OUTFILT_1R, 0);2901 2902	/* Default CP to normal load, power mode */2903	snd_soc_component_update_bits(component, DA7218_CP_CTRL,2904			    DA7218_CP_SMALL_SWITCH_FREQ_EN_MASK, 0);2905 2906	/* Default gain ramping */2907	snd_soc_component_update_bits(component, DA7218_MIXIN_1_CTRL,2908			    DA7218_MIXIN_1_AMP_RAMP_EN_MASK,2909			    DA7218_MIXIN_1_AMP_RAMP_EN_MASK);2910	snd_soc_component_update_bits(component, DA7218_MIXIN_2_CTRL,2911			    DA7218_MIXIN_2_AMP_RAMP_EN_MASK,2912			    DA7218_MIXIN_2_AMP_RAMP_EN_MASK);2913	snd_soc_component_update_bits(component, DA7218_IN_1L_FILTER_CTRL,2914			    DA7218_IN_1L_RAMP_EN_MASK,2915			    DA7218_IN_1L_RAMP_EN_MASK);2916	snd_soc_component_update_bits(component, DA7218_IN_1R_FILTER_CTRL,2917			    DA7218_IN_1R_RAMP_EN_MASK,2918			    DA7218_IN_1R_RAMP_EN_MASK);2919	snd_soc_component_update_bits(component, DA7218_IN_2L_FILTER_CTRL,2920			    DA7218_IN_2L_RAMP_EN_MASK,2921			    DA7218_IN_2L_RAMP_EN_MASK);2922	snd_soc_component_update_bits(component, DA7218_IN_2R_FILTER_CTRL,2923			    DA7218_IN_2R_RAMP_EN_MASK,2924			    DA7218_IN_2R_RAMP_EN_MASK);2925	snd_soc_component_update_bits(component, DA7218_DGS_GAIN_CTRL,2926			    DA7218_DGS_RAMP_EN_MASK, DA7218_DGS_RAMP_EN_MASK);2927	snd_soc_component_update_bits(component, DA7218_OUT_1L_FILTER_CTRL,2928			    DA7218_OUT_1L_RAMP_EN_MASK,2929			    DA7218_OUT_1L_RAMP_EN_MASK);2930	snd_soc_component_update_bits(component, DA7218_OUT_1R_FILTER_CTRL,2931			    DA7218_OUT_1R_RAMP_EN_MASK,2932			    DA7218_OUT_1R_RAMP_EN_MASK);2933	snd_soc_component_update_bits(component, DA7218_HP_L_CTRL,2934			    DA7218_HP_L_AMP_RAMP_EN_MASK,2935			    DA7218_HP_L_AMP_RAMP_EN_MASK);2936	snd_soc_component_update_bits(component, DA7218_HP_R_CTRL,2937			    DA7218_HP_R_AMP_RAMP_EN_MASK,2938			    DA7218_HP_R_AMP_RAMP_EN_MASK);2939 2940	/* Default infinite tone gen, start/stop by Kcontrol */2941	snd_soc_component_write(component, DA7218_TONE_GEN_CYCLES, DA7218_BEEP_CYCLES_MASK);2942 2943	/* DA7217 specific config */2944	if (da7218->dev_id == DA7217_DEV_ID) {2945		snd_soc_component_update_bits(component, DA7218_HP_DIFF_CTRL,2946				    DA7218_HP_AMP_DIFF_MODE_EN_MASK,2947				    DA7218_HP_AMP_DIFF_MODE_EN_MASK);2948 2949		/* Only DA7218 supports HP detect, mask off for DA7217 */2950		snd_soc_component_write(component, DA7218_EVENT_MASK,2951			      DA7218_HPLDET_JACK_EVENT_IRQ_MSK_MASK);2952	}2953 2954	if (da7218->irq) {2955		ret = devm_request_threaded_irq(component->dev, da7218->irq, NULL,2956						da7218_irq_thread,2957						IRQF_TRIGGER_LOW | IRQF_ONESHOT,2958						"da7218", component);2959		if (ret != 0) {2960			dev_err(component->dev, "Failed to request IRQ %d: %d\n",2961				da7218->irq, ret);2962			goto err_disable_reg;2963		}2964 2965	}2966 2967	return 0;2968 2969err_disable_reg:2970	regulator_bulk_disable(DA7218_NUM_SUPPLIES, da7218->supplies);2971 2972	return ret;2973}2974 2975static void da7218_remove(struct snd_soc_component *component)2976{2977	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);2978 2979	regulator_bulk_disable(DA7218_NUM_SUPPLIES, da7218->supplies);2980}2981 2982#ifdef CONFIG_PM2983static int da7218_suspend(struct snd_soc_component *component)2984{2985	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);2986 2987	da7218_set_bias_level(component, SND_SOC_BIAS_OFF);2988 2989	/* Put device into standby mode if jack detection disabled */2990	if (!da7218->jack)2991		snd_soc_component_write(component, DA7218_SYSTEM_ACTIVE, 0);2992 2993	return 0;2994}2995 2996static int da7218_resume(struct snd_soc_component *component)2997{2998	struct da7218_priv *da7218 = snd_soc_component_get_drvdata(component);2999 3000	/* Put device into active mode if previously moved to standby */3001	if (!da7218->jack)3002		snd_soc_component_write(component, DA7218_SYSTEM_ACTIVE,3003			      DA7218_SYSTEM_ACTIVE_MASK);3004 3005	da7218_set_bias_level(component, SND_SOC_BIAS_STANDBY);3006 3007	return 0;3008}3009#else3010#define da7218_suspend NULL3011#define da7218_resume NULL3012#endif3013 3014static const struct snd_soc_component_driver soc_component_dev_da7218 = {3015	.probe			= da7218_probe,3016	.remove			= da7218_remove,3017	.suspend		= da7218_suspend,3018	.resume			= da7218_resume,3019	.set_bias_level		= da7218_set_bias_level,3020	.controls		= da7218_snd_controls,3021	.num_controls		= ARRAY_SIZE(da7218_snd_controls),3022	.dapm_widgets		= da7218_dapm_widgets,3023	.num_dapm_widgets	= ARRAY_SIZE(da7218_dapm_widgets),3024	.dapm_routes		= da7218_audio_map,3025	.num_dapm_routes	= ARRAY_SIZE(da7218_audio_map),3026	.idle_bias_on		= 1,3027	.use_pmdown_time	= 1,3028	.endianness		= 1,3029};3030 3031 3032/*3033 * Regmap configs3034 */3035 3036static struct reg_default da7218_reg_defaults[] = {3037	{ DA7218_SYSTEM_ACTIVE, 0x00 },3038	{ DA7218_CIF_CTRL, 0x00 },3039	{ DA7218_SPARE1, 0x00 },3040	{ DA7218_SR, 0xAA },3041	{ DA7218_PC_COUNT, 0x02 },3042	{ DA7218_GAIN_RAMP_CTRL, 0x00 },3043	{ DA7218_CIF_TIMEOUT_CTRL, 0x01 },3044	{ DA7218_SYSTEM_MODES_INPUT, 0x00 },3045	{ DA7218_SYSTEM_MODES_OUTPUT, 0x00 },3046	{ DA7218_IN_1L_FILTER_CTRL, 0x00 },3047	{ DA7218_IN_1R_FILTER_CTRL, 0x00 },3048	{ DA7218_IN_2L_FILTER_CTRL, 0x00 },3049	{ DA7218_IN_2R_FILTER_CTRL, 0x00 },3050	{ DA7218_OUT_1L_FILTER_CTRL, 0x40 },3051	{ DA7218_OUT_1R_FILTER_CTRL, 0x40 },3052	{ DA7218_OUT_1_HPF_FILTER_CTRL, 0x80 },3053	{ DA7218_OUT_1_EQ_12_FILTER_CTRL, 0x77 },3054	{ DA7218_OUT_1_EQ_34_FILTER_CTRL, 0x77 },3055	{ DA7218_OUT_1_EQ_5_FILTER_CTRL, 0x07 },3056	{ DA7218_OUT_1_BIQ_5STAGE_CTRL, 0x40 },3057	{ DA7218_OUT_1_BIQ_5STAGE_DATA, 0x00 },3058	{ DA7218_OUT_1_BIQ_5STAGE_ADDR, 0x00 },3059	{ DA7218_MIXIN_1_CTRL, 0x48 },3060	{ DA7218_MIXIN_1_GAIN, 0x03 },3061	{ DA7218_MIXIN_2_CTRL, 0x48 },3062	{ DA7218_MIXIN_2_GAIN, 0x03 },3063	{ DA7218_ALC_CTRL1, 0x00 },3064	{ DA7218_ALC_CTRL2, 0x00 },3065	{ DA7218_ALC_CTRL3, 0x00 },3066	{ DA7218_ALC_NOISE, 0x3F },3067	{ DA7218_ALC_TARGET_MIN, 0x3F },3068	{ DA7218_ALC_TARGET_MAX, 0x00 },3069	{ DA7218_ALC_GAIN_LIMITS, 0xFF },3070	{ DA7218_ALC_ANA_GAIN_LIMITS, 0x71 },3071	{ DA7218_ALC_ANTICLIP_CTRL, 0x00 },3072	{ DA7218_AGS_ENABLE, 0x00 },3073	{ DA7218_AGS_TRIGGER, 0x09 },3074	{ DA7218_AGS_ATT_MAX, 0x00 },3075	{ DA7218_AGS_TIMEOUT, 0x00 },3076	{ DA7218_AGS_ANTICLIP_CTRL, 0x00 },3077	{ DA7218_ENV_TRACK_CTRL, 0x00 },3078	{ DA7218_LVL_DET_CTRL, 0x00 },3079	{ DA7218_LVL_DET_LEVEL, 0x7F },3080	{ DA7218_DGS_TRIGGER, 0x24 },3081	{ DA7218_DGS_ENABLE, 0x00 },3082	{ DA7218_DGS_RISE_FALL, 0x50 },3083	{ DA7218_DGS_SYNC_DELAY, 0xA3 },3084	{ DA7218_DGS_SYNC_DELAY2, 0x31 },3085	{ DA7218_DGS_SYNC_DELAY3, 0x11 },3086	{ DA7218_DGS_LEVELS, 0x01 },3087	{ DA7218_DGS_GAIN_CTRL, 0x74 },3088	{ DA7218_DROUTING_OUTDAI_1L, 0x01 },3089	{ DA7218_DMIX_OUTDAI_1L_INFILT_1L_GAIN, 0x1C },3090	{ DA7218_DMIX_OUTDAI_1L_INFILT_1R_GAIN, 0x1C },3091	{ DA7218_DMIX_OUTDAI_1L_INFILT_2L_GAIN, 0x1C },3092	{ DA7218_DMIX_OUTDAI_1L_INFILT_2R_GAIN, 0x1C },3093	{ DA7218_DMIX_OUTDAI_1L_TONEGEN_GAIN, 0x1C },3094	{ DA7218_DMIX_OUTDAI_1L_INDAI_1L_GAIN, 0x1C },3095	{ DA7218_DMIX_OUTDAI_1L_INDAI_1R_GAIN, 0x1C },3096	{ DA7218_DROUTING_OUTDAI_1R, 0x04 },3097	{ DA7218_DMIX_OUTDAI_1R_INFILT_1L_GAIN, 0x1C },3098	{ DA7218_DMIX_OUTDAI_1R_INFILT_1R_GAIN, 0x1C },3099	{ DA7218_DMIX_OUTDAI_1R_INFILT_2L_GAIN, 0x1C },3100	{ DA7218_DMIX_OUTDAI_1R_INFILT_2R_GAIN, 0x1C },3101	{ DA7218_DMIX_OUTDAI_1R_TONEGEN_GAIN, 0x1C },3102	{ DA7218_DMIX_OUTDAI_1R_INDAI_1L_GAIN, 0x1C },3103	{ DA7218_DMIX_OUTDAI_1R_INDAI_1R_GAIN, 0x1C },3104	{ DA7218_DROUTING_OUTFILT_1L, 0x01 },3105	{ DA7218_DMIX_OUTFILT_1L_INFILT_1L_GAIN, 0x1C },3106	{ DA7218_DMIX_OUTFILT_1L_INFILT_1R_GAIN, 0x1C },3107	{ DA7218_DMIX_OUTFILT_1L_INFILT_2L_GAIN, 0x1C },3108	{ DA7218_DMIX_OUTFILT_1L_INFILT_2R_GAIN, 0x1C },3109	{ DA7218_DMIX_OUTFILT_1L_TONEGEN_GAIN, 0x1C },3110	{ DA7218_DMIX_OUTFILT_1L_INDAI_1L_GAIN, 0x1C },3111	{ DA7218_DMIX_OUTFILT_1L_INDAI_1R_GAIN, 0x1C },3112	{ DA7218_DROUTING_OUTFILT_1R, 0x04 },3113	{ DA7218_DMIX_OUTFILT_1R_INFILT_1L_GAIN, 0x1C },3114	{ DA7218_DMIX_OUTFILT_1R_INFILT_1R_GAIN, 0x1C },3115	{ DA7218_DMIX_OUTFILT_1R_INFILT_2L_GAIN, 0x1C },3116	{ DA7218_DMIX_OUTFILT_1R_INFILT_2R_GAIN, 0x1C },3117	{ DA7218_DMIX_OUTFILT_1R_TONEGEN_GAIN, 0x1C },3118	{ DA7218_DMIX_OUTFILT_1R_INDAI_1L_GAIN, 0x1C },3119	{ DA7218_DMIX_OUTFILT_1R_INDAI_1R_GAIN, 0x1C },3120	{ DA7218_DROUTING_OUTDAI_2L, 0x04 },3121	{ DA7218_DMIX_OUTDAI_2L_INFILT_1L_GAIN, 0x1C },3122	{ DA7218_DMIX_OUTDAI_2L_INFILT_1R_GAIN, 0x1C },3123	{ DA7218_DMIX_OUTDAI_2L_INFILT_2L_GAIN, 0x1C },3124	{ DA7218_DMIX_OUTDAI_2L_INFILT_2R_GAIN, 0x1C },3125	{ DA7218_DMIX_OUTDAI_2L_TONEGEN_GAIN, 0x1C },3126	{ DA7218_DMIX_OUTDAI_2L_INDAI_1L_GAIN, 0x1C },3127	{ DA7218_DMIX_OUTDAI_2L_INDAI_1R_GAIN, 0x1C },3128	{ DA7218_DROUTING_OUTDAI_2R, 0x08 },3129	{ DA7218_DMIX_OUTDAI_2R_INFILT_1L_GAIN, 0x1C },3130	{ DA7218_DMIX_OUTDAI_2R_INFILT_1R_GAIN, 0x1C },3131	{ DA7218_DMIX_OUTDAI_2R_INFILT_2L_GAIN, 0x1C },3132	{ DA7218_DMIX_OUTDAI_2R_INFILT_2R_GAIN, 0x1C },3133	{ DA7218_DMIX_OUTDAI_2R_TONEGEN_GAIN, 0x1C },3134	{ DA7218_DMIX_OUTDAI_2R_INDAI_1L_GAIN, 0x1C },3135	{ DA7218_DMIX_OUTDAI_2R_INDAI_1R_GAIN, 0x1C },3136	{ DA7218_DAI_CTRL, 0x28 },3137	{ DA7218_DAI_TDM_CTRL, 0x40 },3138	{ DA7218_DAI_OFFSET_LOWER, 0x00 },3139	{ DA7218_DAI_OFFSET_UPPER, 0x00 },3140	{ DA7218_DAI_CLK_MODE, 0x01 },3141	{ DA7218_PLL_CTRL, 0x04 },3142	{ DA7218_PLL_FRAC_TOP, 0x00 },3143	{ DA7218_PLL_FRAC_BOT, 0x00 },3144	{ DA7218_PLL_INTEGER, 0x20 },3145	{ DA7218_DAC_NG_CTRL, 0x00 },3146	{ DA7218_DAC_NG_SETUP_TIME, 0x00 },3147	{ DA7218_DAC_NG_OFF_THRESH, 0x00 },3148	{ DA7218_DAC_NG_ON_THRESH, 0x00 },3149	{ DA7218_TONE_GEN_CFG2, 0x00 },3150	{ DA7218_TONE_GEN_FREQ1_L, 0x55 },3151	{ DA7218_TONE_GEN_FREQ1_U, 0x15 },3152	{ DA7218_TONE_GEN_FREQ2_L, 0x00 },3153	{ DA7218_TONE_GEN_FREQ2_U, 0x40 },3154	{ DA7218_TONE_GEN_CYCLES, 0x00 },3155	{ DA7218_TONE_GEN_ON_PER, 0x02 },3156	{ DA7218_TONE_GEN_OFF_PER, 0x01 },3157	{ DA7218_CP_CTRL, 0x60 },3158	{ DA7218_CP_DELAY, 0x11 },3159	{ DA7218_CP_VOL_THRESHOLD1, 0x0E },3160	{ DA7218_MIC_1_CTRL, 0x40 },3161	{ DA7218_MIC_1_GAIN, 0x01 },3162	{ DA7218_MIC_1_SELECT, 0x00 },3163	{ DA7218_MIC_2_CTRL, 0x40 },3164	{ DA7218_MIC_2_GAIN, 0x01 },3165	{ DA7218_MIC_2_SELECT, 0x00 },3166	{ DA7218_IN_1_HPF_FILTER_CTRL, 0x80 },3167	{ DA7218_IN_2_HPF_FILTER_CTRL, 0x80 },3168	{ DA7218_ADC_1_CTRL, 0x07 },3169	{ DA7218_ADC_2_CTRL, 0x07 },3170	{ DA7218_MIXOUT_L_CTRL, 0x00 },3171	{ DA7218_MIXOUT_L_GAIN, 0x03 },3172	{ DA7218_MIXOUT_R_CTRL, 0x00 },3173	{ DA7218_MIXOUT_R_GAIN, 0x03 },3174	{ DA7218_HP_L_CTRL, 0x40 },3175	{ DA7218_HP_L_GAIN, 0x3B },3176	{ DA7218_HP_R_CTRL, 0x40 },3177	{ DA7218_HP_R_GAIN, 0x3B },3178	{ DA7218_HP_DIFF_CTRL, 0x00 },3179	{ DA7218_HP_DIFF_UNLOCK, 0xC3 },3180	{ DA7218_HPLDET_JACK, 0x0B },3181	{ DA7218_HPLDET_CTRL, 0x00 },3182	{ DA7218_REFERENCES, 0x08 },3183	{ DA7218_IO_CTRL, 0x00 },3184	{ DA7218_LDO_CTRL, 0x00 },3185	{ DA7218_SIDETONE_CTRL, 0x40 },3186	{ DA7218_SIDETONE_IN_SELECT, 0x00 },3187	{ DA7218_SIDETONE_GAIN, 0x1C },3188	{ DA7218_DROUTING_ST_OUTFILT_1L, 0x01 },3189	{ DA7218_DROUTING_ST_OUTFILT_1R, 0x02 },3190	{ DA7218_SIDETONE_BIQ_3STAGE_DATA, 0x00 },3191	{ DA7218_SIDETONE_BIQ_3STAGE_ADDR, 0x00 },3192	{ DA7218_EVENT_MASK, 0x00 },3193	{ DA7218_DMIC_1_CTRL, 0x00 },3194	{ DA7218_DMIC_2_CTRL, 0x00 },3195	{ DA7218_IN_1L_GAIN, 0x6F },3196	{ DA7218_IN_1R_GAIN, 0x6F },3197	{ DA7218_IN_2L_GAIN, 0x6F },3198	{ DA7218_IN_2R_GAIN, 0x6F },3199	{ DA7218_OUT_1L_GAIN, 0x6F },3200	{ DA7218_OUT_1R_GAIN, 0x6F },3201	{ DA7218_MICBIAS_CTRL, 0x00 },3202	{ DA7218_MICBIAS_EN, 0x00 },3203};3204 3205static bool da7218_volatile_register(struct device *dev, unsigned int reg)3206{3207	switch (reg) {3208	case DA7218_STATUS1:3209	case DA7218_SOFT_RESET:3210	case DA7218_SYSTEM_STATUS:3211	case DA7218_CALIB_CTRL:3212	case DA7218_CALIB_OFFSET_AUTO_M_1:3213	case DA7218_CALIB_OFFSET_AUTO_U_1:3214	case DA7218_CALIB_OFFSET_AUTO_M_2:3215	case DA7218_CALIB_OFFSET_AUTO_U_2:3216	case DA7218_PLL_STATUS:3217	case DA7218_PLL_REFOSC_CAL:3218	case DA7218_TONE_GEN_CFG1:3219	case DA7218_ADC_MODE:3220	case DA7218_HP_SNGL_CTRL:3221	case DA7218_HPLDET_TEST:3222	case DA7218_EVENT_STATUS:3223	case DA7218_EVENT:3224		return true;3225	default:3226		return false;3227	}3228}3229 3230static const struct regmap_config da7218_regmap_config = {3231	.reg_bits = 8,3232	.val_bits = 8,3233 3234	.max_register = DA7218_MICBIAS_EN,3235	.reg_defaults = da7218_reg_defaults,3236	.num_reg_defaults = ARRAY_SIZE(da7218_reg_defaults),3237	.volatile_reg = da7218_volatile_register,3238	.cache_type = REGCACHE_RBTREE,3239};3240 3241 3242/*3243 * I2C layer3244 */3245 3246static int da7218_i2c_probe(struct i2c_client *i2c)3247{3248	struct da7218_priv *da7218;3249	int ret;3250 3251	da7218 = devm_kzalloc(&i2c->dev, sizeof(*da7218), GFP_KERNEL);3252	if (!da7218)3253		return -ENOMEM;3254 3255	i2c_set_clientdata(i2c, da7218);3256 3257	da7218->dev_id = (uintptr_t)i2c_get_match_data(i2c);3258 3259	if ((da7218->dev_id != DA7217_DEV_ID) &&3260	    (da7218->dev_id != DA7218_DEV_ID)) {3261		dev_err(&i2c->dev, "Invalid device Id\n");3262		return -EINVAL;3263	}3264 3265	da7218->irq = i2c->irq;3266 3267	da7218->regmap = devm_regmap_init_i2c(i2c, &da7218_regmap_config);3268	if (IS_ERR(da7218->regmap)) {3269		ret = PTR_ERR(da7218->regmap);3270		dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);3271		return ret;3272	}3273 3274	ret = devm_snd_soc_register_component(&i2c->dev,3275			&soc_component_dev_da7218, &da7218_dai, 1);3276	if (ret < 0) {3277		dev_err(&i2c->dev, "Failed to register da7218 component: %d\n",3278			ret);3279	}3280	return ret;3281}3282 3283static const struct i2c_device_id da7218_i2c_id[] = {3284	{ "da7217", DA7217_DEV_ID },3285	{ "da7218", DA7218_DEV_ID },3286	{ }3287};3288MODULE_DEVICE_TABLE(i2c, da7218_i2c_id);3289 3290static struct i2c_driver da7218_i2c_driver = {3291	.driver = {3292		.name = "da7218",3293		.of_match_table = da7218_of_match,3294	},3295	.probe		= da7218_i2c_probe,3296	.id_table	= da7218_i2c_id,3297};3298 3299module_i2c_driver(da7218_i2c_driver);3300 3301MODULE_DESCRIPTION("ASoC DA7218 Codec driver");3302MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>");3303MODULE_LICENSE("GPL");3304