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