2960 lines · c
1// SPDX-License-Identifier: GPL-2.02//3// mt6359.c -- mt6359 ALSA SoC audio codec driver4//5// Copyright (c) 2020 MediaTek Inc.6// Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>7 8#include <linux/delay.h>9#include <linux/kthread.h>10#include <linux/mfd/mt6397/core.h>11#include <linux/module.h>12#include <linux/of.h>13#include <linux/platform_device.h>14#include <linux/regulator/consumer.h>15#include <linux/sched.h>16#include <sound/soc.h>17#include <sound/tlv.h>18 19#include "mt6359.h"20 21static void mt6359_set_gpio_smt(struct mt6359_priv *priv)22{23 /* set gpio SMT mode */24 regmap_update_bits(priv->regmap, MT6359_SMT_CON1, 0x3ff0, 0x3ff0);25}26 27static void mt6359_set_gpio_driving(struct mt6359_priv *priv)28{29 /* 8:4mA(default), a:8mA, c:12mA, e:16mA */30 regmap_update_bits(priv->regmap, MT6359_DRV_CON2, 0xffff, 0x8888);31 regmap_update_bits(priv->regmap, MT6359_DRV_CON3, 0xffff, 0x8888);32 regmap_update_bits(priv->regmap, MT6359_DRV_CON4, 0x00ff, 0x88);33}34 35static void mt6359_set_playback_gpio(struct mt6359_priv *priv)36{37 /* set gpio mosi mode, clk / data mosi */38 regmap_write(priv->regmap, MT6359_GPIO_MODE2_CLR, 0x0ffe);39 regmap_write(priv->regmap, MT6359_GPIO_MODE2_SET, 0x0249);40 41 /* sync mosi */42 regmap_write(priv->regmap, MT6359_GPIO_MODE3_CLR, 0x6);43 regmap_write(priv->regmap, MT6359_GPIO_MODE3_SET, 0x1);44}45 46static void mt6359_reset_playback_gpio(struct mt6359_priv *priv)47{48 /* set pad_aud_*_mosi to GPIO mode and dir input49 * reason:50 * pad_aud_dat_mosi*, because the pin is used as boot strap51 * don't clean clk/sync, for mtkaif protocol 252 */53 regmap_write(priv->regmap, MT6359_GPIO_MODE2_CLR, 0x0ff8);54 regmap_update_bits(priv->regmap, MT6359_GPIO_DIR0, 0x7 << 9, 0x0);55}56 57static void mt6359_set_capture_gpio(struct mt6359_priv *priv)58{59 /* set gpio miso mode */60 regmap_write(priv->regmap, MT6359_GPIO_MODE3_CLR, 0x0e00);61 regmap_write(priv->regmap, MT6359_GPIO_MODE3_SET, 0x0200);62 63 regmap_write(priv->regmap, MT6359_GPIO_MODE4_CLR, 0x003f);64 regmap_write(priv->regmap, MT6359_GPIO_MODE4_SET, 0x0009);65}66 67static void mt6359_reset_capture_gpio(struct mt6359_priv *priv)68{69 /* set pad_aud_*_miso to GPIO mode and dir input70 * reason:71 * pad_aud_clk_miso, because when playback only the miso_clk72 * will also have 26m, so will have power leak73 * pad_aud_dat_miso*, because the pin is used as boot strap74 */75 regmap_write(priv->regmap, MT6359_GPIO_MODE3_CLR, 0x0e00);76 77 regmap_write(priv->regmap, MT6359_GPIO_MODE4_CLR, 0x003f);78 79 regmap_update_bits(priv->regmap, MT6359_GPIO_DIR0,80 0x7 << 13, 0x0);81 regmap_update_bits(priv->regmap, MT6359_GPIO_DIR1,82 0x3 << 0, 0x0);83}84 85/* use only when doing mtkaif calibraiton at the boot time */86static void mt6359_set_dcxo(struct mt6359_priv *priv, bool enable)87{88 regmap_update_bits(priv->regmap, MT6359_DCXO_CW12,89 0x1 << RG_XO_AUDIO_EN_M_SFT,90 (enable ? 1 : 0) << RG_XO_AUDIO_EN_M_SFT);91}92 93/* use only when doing mtkaif calibraiton at the boot time */94static void mt6359_set_clksq(struct mt6359_priv *priv, bool enable)95{96 /* Enable/disable CLKSQ 26MHz */97 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON23,98 RG_CLKSQ_EN_MASK_SFT,99 (enable ? 1 : 0) << RG_CLKSQ_EN_SFT);100}101 102/* use only when doing mtkaif calibraiton at the boot time */103static void mt6359_set_aud_global_bias(struct mt6359_priv *priv, bool enable)104{105 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON13,106 RG_AUDGLB_PWRDN_VA32_MASK_SFT,107 (enable ? 0 : 1) << RG_AUDGLB_PWRDN_VA32_SFT);108}109 110/* use only when doing mtkaif calibraiton at the boot time */111static void mt6359_set_topck(struct mt6359_priv *priv, bool enable)112{113 regmap_update_bits(priv->regmap, MT6359_AUD_TOP_CKPDN_CON0,114 0x0066, enable ? 0x0 : 0x66);115}116 117static void mt6359_set_decoder_clk(struct mt6359_priv *priv, bool enable)118{119 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON13,120 RG_RSTB_DECODER_VA32_MASK_SFT,121 (enable ? 1 : 0) << RG_RSTB_DECODER_VA32_SFT);122}123 124static void mt6359_mtkaif_tx_enable(struct mt6359_priv *priv)125{126 switch (priv->mtkaif_protocol) {127 case MT6359_MTKAIF_PROTOCOL_2_CLK_P2:128 /* MTKAIF TX format setting */129 regmap_update_bits(priv->regmap,130 MT6359_AFE_ADDA_MTKAIF_CFG0,131 0xffff, 0x0210);132 /* enable aud_pad TX fifos */133 regmap_update_bits(priv->regmap,134 MT6359_AFE_AUD_PAD_TOP,135 0xff00, 0x3800);136 regmap_update_bits(priv->regmap,137 MT6359_AFE_AUD_PAD_TOP,138 0xff00, 0x3900);139 break;140 case MT6359_MTKAIF_PROTOCOL_2:141 /* MTKAIF TX format setting */142 regmap_update_bits(priv->regmap,143 MT6359_AFE_ADDA_MTKAIF_CFG0,144 0xffff, 0x0210);145 /* enable aud_pad TX fifos */146 regmap_update_bits(priv->regmap,147 MT6359_AFE_AUD_PAD_TOP,148 0xff00, 0x3100);149 break;150 case MT6359_MTKAIF_PROTOCOL_1:151 default:152 /* MTKAIF TX format setting */153 regmap_update_bits(priv->regmap,154 MT6359_AFE_ADDA_MTKAIF_CFG0,155 0xffff, 0x0000);156 /* enable aud_pad TX fifos */157 regmap_update_bits(priv->regmap,158 MT6359_AFE_AUD_PAD_TOP,159 0xff00, 0x3100);160 break;161 }162}163 164static void mt6359_mtkaif_tx_disable(struct mt6359_priv *priv)165{166 /* disable aud_pad TX fifos */167 regmap_update_bits(priv->regmap, MT6359_AFE_AUD_PAD_TOP,168 0xff00, 0x3000);169}170 171void mt6359_set_mtkaif_protocol(struct snd_soc_component *cmpnt,172 int mtkaif_protocol)173{174 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);175 176 priv->mtkaif_protocol = mtkaif_protocol;177}178EXPORT_SYMBOL_GPL(mt6359_set_mtkaif_protocol);179 180void mt6359_mtkaif_calibration_enable(struct snd_soc_component *cmpnt)181{182 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);183 184 mt6359_set_playback_gpio(priv);185 mt6359_set_capture_gpio(priv);186 mt6359_mtkaif_tx_enable(priv);187 188 mt6359_set_dcxo(priv, true);189 mt6359_set_aud_global_bias(priv, true);190 mt6359_set_clksq(priv, true);191 mt6359_set_topck(priv, true);192 193 /* set dat_miso_loopback on */194 regmap_update_bits(priv->regmap, MT6359_AUDIO_DIG_CFG,195 RG_AUD_PAD_TOP_DAT_MISO2_LOOPBACK_MASK_SFT,196 1 << RG_AUD_PAD_TOP_DAT_MISO2_LOOPBACK_SFT);197 regmap_update_bits(priv->regmap, MT6359_AUDIO_DIG_CFG,198 RG_AUD_PAD_TOP_DAT_MISO_LOOPBACK_MASK_SFT,199 1 << RG_AUD_PAD_TOP_DAT_MISO_LOOPBACK_SFT);200 regmap_update_bits(priv->regmap, MT6359_AUDIO_DIG_CFG1,201 RG_AUD_PAD_TOP_DAT_MISO3_LOOPBACK_MASK_SFT,202 1 << RG_AUD_PAD_TOP_DAT_MISO3_LOOPBACK_SFT);203}204EXPORT_SYMBOL_GPL(mt6359_mtkaif_calibration_enable);205 206void mt6359_mtkaif_calibration_disable(struct snd_soc_component *cmpnt)207{208 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);209 210 /* set dat_miso_loopback off */211 regmap_update_bits(priv->regmap, MT6359_AUDIO_DIG_CFG,212 RG_AUD_PAD_TOP_DAT_MISO2_LOOPBACK_MASK_SFT,213 0 << RG_AUD_PAD_TOP_DAT_MISO2_LOOPBACK_SFT);214 regmap_update_bits(priv->regmap, MT6359_AUDIO_DIG_CFG,215 RG_AUD_PAD_TOP_DAT_MISO_LOOPBACK_MASK_SFT,216 0 << RG_AUD_PAD_TOP_DAT_MISO_LOOPBACK_SFT);217 regmap_update_bits(priv->regmap, MT6359_AUDIO_DIG_CFG1,218 RG_AUD_PAD_TOP_DAT_MISO3_LOOPBACK_MASK_SFT,219 0 << RG_AUD_PAD_TOP_DAT_MISO3_LOOPBACK_SFT);220 221 mt6359_set_topck(priv, false);222 mt6359_set_clksq(priv, false);223 mt6359_set_aud_global_bias(priv, false);224 mt6359_set_dcxo(priv, false);225 226 mt6359_mtkaif_tx_disable(priv);227 mt6359_reset_playback_gpio(priv);228 mt6359_reset_capture_gpio(priv);229}230EXPORT_SYMBOL_GPL(mt6359_mtkaif_calibration_disable);231 232void mt6359_set_mtkaif_calibration_phase(struct snd_soc_component *cmpnt,233 int phase_1, int phase_2, int phase_3)234{235 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);236 237 regmap_update_bits(priv->regmap, MT6359_AUDIO_DIG_CFG,238 RG_AUD_PAD_TOP_PHASE_MODE_MASK_SFT,239 phase_1 << RG_AUD_PAD_TOP_PHASE_MODE_SFT);240 regmap_update_bits(priv->regmap, MT6359_AUDIO_DIG_CFG,241 RG_AUD_PAD_TOP_PHASE_MODE2_MASK_SFT,242 phase_2 << RG_AUD_PAD_TOP_PHASE_MODE2_SFT);243 regmap_update_bits(priv->regmap, MT6359_AUDIO_DIG_CFG1,244 RG_AUD_PAD_TOP_PHASE_MODE3_MASK_SFT,245 phase_3 << RG_AUD_PAD_TOP_PHASE_MODE3_SFT);246}247EXPORT_SYMBOL_GPL(mt6359_set_mtkaif_calibration_phase);248 249static void zcd_disable(struct mt6359_priv *priv)250{251 regmap_write(priv->regmap, MT6359_ZCD_CON0, 0x0000);252}253 254static void hp_main_output_ramp(struct mt6359_priv *priv, bool up)255{256 int i, stage;257 int target = 7;258 259 /* Enable/Reduce HPL/R main output stage step by step */260 for (i = 0; i <= target; i++) {261 stage = up ? i : target - i;262 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON1,263 RG_HPLOUTSTGCTRL_VAUDP32_MASK_SFT,264 stage << RG_HPLOUTSTGCTRL_VAUDP32_SFT);265 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON1,266 RG_HPROUTSTGCTRL_VAUDP32_MASK_SFT,267 stage << RG_HPROUTSTGCTRL_VAUDP32_SFT);268 usleep_range(600, 650);269 }270}271 272static void hp_aux_feedback_loop_gain_ramp(struct mt6359_priv *priv, bool up)273{274 int i, stage;275 int target = 0xf;276 277 /* Enable/Reduce HP aux feedback loop gain step by step */278 for (i = 0; i <= target; i++) {279 stage = up ? i : target - i;280 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON9,281 0xf << 12, stage << 12);282 usleep_range(600, 650);283 }284}285 286static void hp_in_pair_current(struct mt6359_priv *priv, bool increase)287{288 int i, stage;289 int target = 0x3;290 291 /* Set input diff pair bias select (Hi-Fi mode) */292 if (priv->hp_hifi_mode) {293 /* Reduce HP aux feedback loop gain step by step */294 for (i = 0; i <= target; i++) {295 stage = increase ? i : target - i;296 regmap_update_bits(priv->regmap,297 MT6359_AUDDEC_ANA_CON10,298 0x3 << 3, stage << 3);299 usleep_range(100, 150);300 }301 }302}303 304static void hp_pull_down(struct mt6359_priv *priv, bool enable)305{306 int i;307 308 if (enable) {309 for (i = 0x0; i <= 0x7; i++) {310 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON2,311 RG_HPPSHORT2VCM_VAUDP32_MASK_SFT,312 i << RG_HPPSHORT2VCM_VAUDP32_SFT);313 usleep_range(100, 150);314 }315 } else {316 for (i = 0x7; i >= 0x0; i--) {317 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON2,318 RG_HPPSHORT2VCM_VAUDP32_MASK_SFT,319 i << RG_HPPSHORT2VCM_VAUDP32_SFT);320 usleep_range(100, 150);321 }322 }323}324 325static bool is_valid_hp_pga_idx(int reg_idx)326{327 return (reg_idx >= DL_GAIN_8DB && reg_idx <= DL_GAIN_N_22DB) ||328 reg_idx == DL_GAIN_N_40DB;329}330 331static void headset_volume_ramp(struct mt6359_priv *priv,332 int from, int to)333{334 int offset = 0, count = 1, reg_idx;335 336 if (!is_valid_hp_pga_idx(from) || !is_valid_hp_pga_idx(to)) {337 dev_warn(priv->dev, "%s(), volume index is not valid, from %d, to %d\n",338 __func__, from, to);339 return;340 }341 342 dev_dbg(priv->dev, "%s(), from %d, to %d\n", __func__, from, to);343 344 if (to > from)345 offset = to - from;346 else347 offset = from - to;348 349 while (offset > 0) {350 if (to > from)351 reg_idx = from + count;352 else353 reg_idx = from - count;354 355 if (is_valid_hp_pga_idx(reg_idx)) {356 regmap_update_bits(priv->regmap,357 MT6359_ZCD_CON2,358 DL_GAIN_REG_MASK,359 (reg_idx << 7) | reg_idx);360 usleep_range(600, 650);361 }362 offset--;363 count++;364 }365}366 367static int mt6359_put_volsw(struct snd_kcontrol *kcontrol,368 struct snd_ctl_elem_value *ucontrol)369{370 struct snd_soc_component *component =371 snd_soc_kcontrol_component(kcontrol);372 struct mt6359_priv *priv = snd_soc_component_get_drvdata(component);373 struct soc_mixer_control *mc =374 (struct soc_mixer_control *)kcontrol->private_value;375 unsigned int reg = 0;376 int index = ucontrol->value.integer.value[0];377 int orig_gain[2], new_gain[2];378 int ret;379 380 switch (mc->reg) {381 case MT6359_ZCD_CON2:382 orig_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL];383 orig_gain[1] = priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTR];384 break;385 case MT6359_ZCD_CON1:386 orig_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTL];387 orig_gain[1] = priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTR];388 break;389 case MT6359_ZCD_CON3:390 orig_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_HSOUTL];391 break;392 case MT6359_AUDENC_ANA_CON0:393 orig_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP1];394 break;395 case MT6359_AUDENC_ANA_CON1:396 orig_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP2];397 break;398 case MT6359_AUDENC_ANA_CON2:399 orig_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP3];400 break;401 default:402 return -EINVAL;403 }404 405 ret = snd_soc_put_volsw(kcontrol, ucontrol);406 if (ret < 0)407 return ret;408 409 switch (mc->reg) {410 case MT6359_ZCD_CON2:411 regmap_read(priv->regmap, MT6359_ZCD_CON2, ®);412 priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL] =413 (reg >> RG_AUDHPLGAIN_SFT) & RG_AUDHPLGAIN_MASK;414 priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTR] =415 (reg >> RG_AUDHPRGAIN_SFT) & RG_AUDHPRGAIN_MASK;416 new_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL];417 new_gain[1] = priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTR];418 break;419 case MT6359_ZCD_CON1:420 regmap_read(priv->regmap, MT6359_ZCD_CON1, ®);421 priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTL] =422 (reg >> RG_AUDLOLGAIN_SFT) & RG_AUDLOLGAIN_MASK;423 priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTR] =424 (reg >> RG_AUDLORGAIN_SFT) & RG_AUDLORGAIN_MASK;425 new_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTL];426 new_gain[1] = priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTR];427 break;428 case MT6359_ZCD_CON3:429 regmap_read(priv->regmap, MT6359_ZCD_CON3, ®);430 priv->ana_gain[AUDIO_ANALOG_VOLUME_HSOUTL] =431 (reg >> RG_AUDHSGAIN_SFT) & RG_AUDHSGAIN_MASK;432 new_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_HSOUTL];433 break;434 case MT6359_AUDENC_ANA_CON0:435 regmap_read(priv->regmap, MT6359_AUDENC_ANA_CON0, ®);436 priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP1] =437 (reg >> RG_AUDPREAMPLGAIN_SFT) & RG_AUDPREAMPLGAIN_MASK;438 new_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP1];439 break;440 case MT6359_AUDENC_ANA_CON1:441 regmap_read(priv->regmap, MT6359_AUDENC_ANA_CON1, ®);442 priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP2] =443 (reg >> RG_AUDPREAMPRGAIN_SFT) & RG_AUDPREAMPRGAIN_MASK;444 new_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP2];445 break;446 case MT6359_AUDENC_ANA_CON2:447 regmap_read(priv->regmap, MT6359_AUDENC_ANA_CON2, ®);448 priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP3] =449 (reg >> RG_AUDPREAMP3GAIN_SFT) & RG_AUDPREAMP3GAIN_MASK;450 new_gain[0] = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP3];451 break;452 }453 454 ret = 0;455 if (orig_gain[0] != new_gain[0]) {456 ret = 1;457 } else if (snd_soc_volsw_is_stereo(mc)) {458 if (orig_gain[1] != new_gain[1])459 ret = 1;460 }461 462 dev_dbg(priv->dev, "%s(), name %s, reg(0x%x) = 0x%x, set index = %x\n",463 __func__, kcontrol->id.name, mc->reg, reg, index);464 465 return ret;466}467 468static int mt6359_get_playback_volsw(struct snd_kcontrol *kcontrol,469 struct snd_ctl_elem_value *ucontrol)470{471 struct snd_soc_component *component =472 snd_soc_kcontrol_component(kcontrol);473 struct mt6359_priv *priv = snd_soc_component_get_drvdata(component);474 struct soc_mixer_control *mc =475 (struct soc_mixer_control *)kcontrol->private_value;476 477 switch (mc->reg) {478 case MT6359_ZCD_CON2:479 ucontrol->value.integer.value[0] =480 priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL];481 ucontrol->value.integer.value[1] =482 priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTR];483 break;484 case MT6359_ZCD_CON1:485 ucontrol->value.integer.value[0] =486 priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTL];487 ucontrol->value.integer.value[1] =488 priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTR];489 break;490 case MT6359_ZCD_CON3:491 ucontrol->value.integer.value[0] =492 priv->ana_gain[AUDIO_ANALOG_VOLUME_HSOUTL];493 break;494 default:495 return -EINVAL;496 }497 498 return 0;499}500 501/* MUX */502 503/* LOL MUX */504static const char * const lo_in_mux_map[] = {505 "Open", "Playback_L_DAC", "Playback", "Test Mode"506};507 508static SOC_ENUM_SINGLE_DECL(lo_in_mux_map_enum, SND_SOC_NOPM, 0, lo_in_mux_map);509 510static const struct snd_kcontrol_new lo_in_mux_control =511 SOC_DAPM_ENUM("LO Select", lo_in_mux_map_enum);512 513/*HP MUX */514static const char * const hp_in_mux_map[] = {515 "Open",516 "LoudSPK Playback",517 "Audio Playback",518 "Test Mode",519 "HP Impedance",520};521 522static SOC_ENUM_SINGLE_DECL(hp_in_mux_map_enum,523 SND_SOC_NOPM,524 0,525 hp_in_mux_map);526 527static const struct snd_kcontrol_new hp_in_mux_control =528 SOC_DAPM_ENUM("HP Select", hp_in_mux_map_enum);529 530/* RCV MUX */531static const char * const rcv_in_mux_map[] = {532 "Open", "Mute", "Voice Playback", "Test Mode"533};534 535static SOC_ENUM_SINGLE_DECL(rcv_in_mux_map_enum,536 SND_SOC_NOPM,537 0,538 rcv_in_mux_map);539 540static const struct snd_kcontrol_new rcv_in_mux_control =541 SOC_DAPM_ENUM("RCV Select", rcv_in_mux_map_enum);542 543/* DAC In MUX */544static const char * const dac_in_mux_map[] = {545 "Normal Path", "Sgen"546};547 548static int dac_in_mux_map_value[] = {549 0x0, 0x1,550};551 552static SOC_VALUE_ENUM_SINGLE_DECL(dac_in_mux_map_enum,553 MT6359_AFE_TOP_CON0,554 DL_SINE_ON_SFT,555 DL_SINE_ON_MASK,556 dac_in_mux_map,557 dac_in_mux_map_value);558 559static const struct snd_kcontrol_new dac_in_mux_control =560 SOC_DAPM_ENUM("DAC Select", dac_in_mux_map_enum);561 562/* AIF Out MUX */563static SOC_VALUE_ENUM_SINGLE_DECL(aif_out_mux_map_enum,564 MT6359_AFE_TOP_CON0,565 UL_SINE_ON_SFT,566 UL_SINE_ON_MASK,567 dac_in_mux_map,568 dac_in_mux_map_value);569 570static const struct snd_kcontrol_new aif_out_mux_control =571 SOC_DAPM_ENUM("AIF Out Select", aif_out_mux_map_enum);572 573static SOC_VALUE_ENUM_SINGLE_DECL(aif2_out_mux_map_enum,574 MT6359_AFE_TOP_CON0,575 ADDA6_UL_SINE_ON_SFT,576 ADDA6_UL_SINE_ON_MASK,577 dac_in_mux_map,578 dac_in_mux_map_value);579 580static const struct snd_kcontrol_new aif2_out_mux_control =581 SOC_DAPM_ENUM("AIF Out Select", aif2_out_mux_map_enum);582 583static const char * const ul_src_mux_map[] = {584 "AMIC",585 "DMIC",586};587 588static int ul_src_mux_map_value[] = {589 UL_SRC_MUX_AMIC,590 UL_SRC_MUX_DMIC,591};592 593static SOC_VALUE_ENUM_SINGLE_DECL(ul_src_mux_map_enum,594 MT6359_AFE_UL_SRC_CON0_L,595 UL_SDM_3_LEVEL_CTL_SFT,596 UL_SDM_3_LEVEL_CTL_MASK,597 ul_src_mux_map,598 ul_src_mux_map_value);599 600static const struct snd_kcontrol_new ul_src_mux_control =601 SOC_DAPM_ENUM("UL_SRC_MUX Select", ul_src_mux_map_enum);602 603static SOC_VALUE_ENUM_SINGLE_DECL(ul2_src_mux_map_enum,604 MT6359_AFE_ADDA6_UL_SRC_CON0_L,605 ADDA6_UL_SDM_3_LEVEL_CTL_SFT,606 ADDA6_UL_SDM_3_LEVEL_CTL_MASK,607 ul_src_mux_map,608 ul_src_mux_map_value);609 610static const struct snd_kcontrol_new ul2_src_mux_control =611 SOC_DAPM_ENUM("UL_SRC_MUX Select", ul2_src_mux_map_enum);612 613static const char * const miso_mux_map[] = {614 "UL1_CH1",615 "UL1_CH2",616 "UL2_CH1",617 "UL2_CH2",618};619 620static int miso_mux_map_value[] = {621 MISO_MUX_UL1_CH1,622 MISO_MUX_UL1_CH2,623 MISO_MUX_UL2_CH1,624 MISO_MUX_UL2_CH2,625};626 627static SOC_VALUE_ENUM_SINGLE_DECL(miso0_mux_map_enum,628 MT6359_AFE_MTKAIF_MUX_CFG,629 RG_ADDA_CH1_SEL_SFT,630 RG_ADDA_CH1_SEL_MASK,631 miso_mux_map,632 miso_mux_map_value);633 634static const struct snd_kcontrol_new miso0_mux_control =635 SOC_DAPM_ENUM("MISO_MUX Select", miso0_mux_map_enum);636 637static SOC_VALUE_ENUM_SINGLE_DECL(miso1_mux_map_enum,638 MT6359_AFE_MTKAIF_MUX_CFG,639 RG_ADDA_CH2_SEL_SFT,640 RG_ADDA_CH2_SEL_MASK,641 miso_mux_map,642 miso_mux_map_value);643 644static const struct snd_kcontrol_new miso1_mux_control =645 SOC_DAPM_ENUM("MISO_MUX Select", miso1_mux_map_enum);646 647static SOC_VALUE_ENUM_SINGLE_DECL(miso2_mux_map_enum,648 MT6359_AFE_MTKAIF_MUX_CFG,649 RG_ADDA6_CH1_SEL_SFT,650 RG_ADDA6_CH1_SEL_MASK,651 miso_mux_map,652 miso_mux_map_value);653 654static const struct snd_kcontrol_new miso2_mux_control =655 SOC_DAPM_ENUM("MISO_MUX Select", miso2_mux_map_enum);656 657static const char * const dmic_mux_map[] = {658 "DMIC_DATA0",659 "DMIC_DATA1_L",660 "DMIC_DATA1_L_1",661 "DMIC_DATA1_R",662};663 664static int dmic_mux_map_value[] = {665 DMIC_MUX_DMIC_DATA0,666 DMIC_MUX_DMIC_DATA1_L,667 DMIC_MUX_DMIC_DATA1_L_1,668 DMIC_MUX_DMIC_DATA1_R,669};670 671static SOC_VALUE_ENUM_SINGLE_DECL(dmic0_mux_map_enum,672 MT6359_AFE_MIC_ARRAY_CFG,673 RG_DMIC_ADC1_SOURCE_SEL_SFT,674 RG_DMIC_ADC1_SOURCE_SEL_MASK,675 dmic_mux_map,676 dmic_mux_map_value);677 678static const struct snd_kcontrol_new dmic0_mux_control =679 SOC_DAPM_ENUM("DMIC_MUX Select", dmic0_mux_map_enum);680 681/* ul1 ch2 use RG_DMIC_ADC3_SOURCE_SEL */682static SOC_VALUE_ENUM_SINGLE_DECL(dmic1_mux_map_enum,683 MT6359_AFE_MIC_ARRAY_CFG,684 RG_DMIC_ADC3_SOURCE_SEL_SFT,685 RG_DMIC_ADC3_SOURCE_SEL_MASK,686 dmic_mux_map,687 dmic_mux_map_value);688 689static const struct snd_kcontrol_new dmic1_mux_control =690 SOC_DAPM_ENUM("DMIC_MUX Select", dmic1_mux_map_enum);691 692/* ul2 ch1 use RG_DMIC_ADC2_SOURCE_SEL */693static SOC_VALUE_ENUM_SINGLE_DECL(dmic2_mux_map_enum,694 MT6359_AFE_MIC_ARRAY_CFG,695 RG_DMIC_ADC2_SOURCE_SEL_SFT,696 RG_DMIC_ADC2_SOURCE_SEL_MASK,697 dmic_mux_map,698 dmic_mux_map_value);699 700static const struct snd_kcontrol_new dmic2_mux_control =701 SOC_DAPM_ENUM("DMIC_MUX Select", dmic2_mux_map_enum);702 703/* ADC L MUX */704static const char * const adc_left_mux_map[] = {705 "Idle", "AIN0", "Left Preamplifier", "Idle_1"706};707 708static int adc_mux_map_value[] = {709 ADC_MUX_IDLE,710 ADC_MUX_AIN0,711 ADC_MUX_PREAMPLIFIER,712 ADC_MUX_IDLE1,713};714 715static SOC_VALUE_ENUM_SINGLE_DECL(adc_left_mux_map_enum,716 MT6359_AUDENC_ANA_CON0,717 RG_AUDADCLINPUTSEL_SFT,718 RG_AUDADCLINPUTSEL_MASK,719 adc_left_mux_map,720 adc_mux_map_value);721 722static const struct snd_kcontrol_new adc_left_mux_control =723 SOC_DAPM_ENUM("ADC L Select", adc_left_mux_map_enum);724 725/* ADC R MUX */726static const char * const adc_right_mux_map[] = {727 "Idle", "AIN0", "Right Preamplifier", "Idle_1"728};729 730static SOC_VALUE_ENUM_SINGLE_DECL(adc_right_mux_map_enum,731 MT6359_AUDENC_ANA_CON1,732 RG_AUDADCRINPUTSEL_SFT,733 RG_AUDADCRINPUTSEL_MASK,734 adc_right_mux_map,735 adc_mux_map_value);736 737static const struct snd_kcontrol_new adc_right_mux_control =738 SOC_DAPM_ENUM("ADC R Select", adc_right_mux_map_enum);739 740/* ADC 3 MUX */741static const char * const adc_3_mux_map[] = {742 "Idle", "AIN0", "Preamplifier", "Idle_1"743};744 745static SOC_VALUE_ENUM_SINGLE_DECL(adc_3_mux_map_enum,746 MT6359_AUDENC_ANA_CON2,747 RG_AUDADC3INPUTSEL_SFT,748 RG_AUDADC3INPUTSEL_MASK,749 adc_3_mux_map,750 adc_mux_map_value);751 752static const struct snd_kcontrol_new adc_3_mux_control =753 SOC_DAPM_ENUM("ADC 3 Select", adc_3_mux_map_enum);754 755static const char * const pga_l_mux_map[] = {756 "None", "AIN0", "AIN1"757};758 759static int pga_l_mux_map_value[] = {760 PGA_L_MUX_NONE,761 PGA_L_MUX_AIN0,762 PGA_L_MUX_AIN1763};764 765static SOC_VALUE_ENUM_SINGLE_DECL(pga_left_mux_map_enum,766 MT6359_AUDENC_ANA_CON0,767 RG_AUDPREAMPLINPUTSEL_SFT,768 RG_AUDPREAMPLINPUTSEL_MASK,769 pga_l_mux_map,770 pga_l_mux_map_value);771 772static const struct snd_kcontrol_new pga_left_mux_control =773 SOC_DAPM_ENUM("PGA L Select", pga_left_mux_map_enum);774 775static const char * const pga_r_mux_map[] = {776 "None", "AIN2", "AIN3", "AIN0"777};778 779static int pga_r_mux_map_value[] = {780 PGA_R_MUX_NONE,781 PGA_R_MUX_AIN2,782 PGA_R_MUX_AIN3,783 PGA_R_MUX_AIN0784};785 786static SOC_VALUE_ENUM_SINGLE_DECL(pga_right_mux_map_enum,787 MT6359_AUDENC_ANA_CON1,788 RG_AUDPREAMPRINPUTSEL_SFT,789 RG_AUDPREAMPRINPUTSEL_MASK,790 pga_r_mux_map,791 pga_r_mux_map_value);792 793static const struct snd_kcontrol_new pga_right_mux_control =794 SOC_DAPM_ENUM("PGA R Select", pga_right_mux_map_enum);795 796static const char * const pga_3_mux_map[] = {797 "None", "AIN3", "AIN2"798};799 800static int pga_3_mux_map_value[] = {801 PGA_3_MUX_NONE,802 PGA_3_MUX_AIN3,803 PGA_3_MUX_AIN2804};805 806static SOC_VALUE_ENUM_SINGLE_DECL(pga_3_mux_map_enum,807 MT6359_AUDENC_ANA_CON2,808 RG_AUDPREAMP3INPUTSEL_SFT,809 RG_AUDPREAMP3INPUTSEL_MASK,810 pga_3_mux_map,811 pga_3_mux_map_value);812 813static const struct snd_kcontrol_new pga_3_mux_control =814 SOC_DAPM_ENUM("PGA 3 Select", pga_3_mux_map_enum);815 816static int mt_sgen_event(struct snd_soc_dapm_widget *w,817 struct snd_kcontrol *kcontrol,818 int event)819{820 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);821 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);822 823 dev_dbg(priv->dev, "%s(), event = 0x%x\n", __func__, event);824 825 switch (event) {826 case SND_SOC_DAPM_PRE_PMU:827 /* sdm audio fifo clock power on */828 regmap_write(priv->regmap, MT6359_AFUNC_AUD_CON2, 0x0006);829 /* scrambler clock on enable */830 regmap_write(priv->regmap, MT6359_AFUNC_AUD_CON0, 0xcba1);831 /* sdm power on */832 regmap_write(priv->regmap, MT6359_AFUNC_AUD_CON2, 0x0003);833 /* sdm fifo enable */834 regmap_write(priv->regmap, MT6359_AFUNC_AUD_CON2, 0x000b);835 836 regmap_update_bits(priv->regmap, MT6359_AFE_SGEN_CFG0,837 0xff3f,838 0x0000);839 regmap_update_bits(priv->regmap, MT6359_AFE_SGEN_CFG1,840 0xffff,841 0x0001);842 break;843 case SND_SOC_DAPM_POST_PMD:844 /* DL scrambler disabling sequence */845 regmap_write(priv->regmap, MT6359_AFUNC_AUD_CON2, 0x0000);846 regmap_write(priv->regmap, MT6359_AFUNC_AUD_CON0, 0xcba0);847 break;848 default:849 break;850 }851 852 return 0;853}854 855static void mtk_hp_enable(struct mt6359_priv *priv)856{857 if (priv->hp_hifi_mode) {858 /* Set HP DR bias current optimization, 010: 6uA */859 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON11,860 DRBIAS_HP_MASK_SFT,861 DRBIAS_6UA << DRBIAS_HP_SFT);862 /* Set HP & ZCD bias current optimization */863 /* 01: ZCD: 4uA, HP/HS/LO: 5uA */864 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON12,865 IBIAS_ZCD_MASK_SFT,866 IBIAS_ZCD_4UA << IBIAS_ZCD_SFT);867 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON12,868 IBIAS_HP_MASK_SFT,869 IBIAS_5UA << IBIAS_HP_SFT);870 } else {871 /* Set HP DR bias current optimization, 001: 5uA */872 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON11,873 DRBIAS_HP_MASK_SFT,874 DRBIAS_5UA << DRBIAS_HP_SFT);875 /* Set HP & ZCD bias current optimization */876 /* 00: ZCD: 3uA, HP/HS/LO: 4uA */877 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON12,878 IBIAS_ZCD_MASK_SFT,879 IBIAS_ZCD_3UA << IBIAS_ZCD_SFT);880 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON12,881 IBIAS_HP_MASK_SFT,882 IBIAS_4UA << IBIAS_HP_SFT);883 }884 885 /* HP damp circuit enable */886 /* Enable HPRN/HPLN output 4K to VCM */887 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON10, 0x0087);888 889 /* HP Feedback Cap select 2'b00: 15pF */890 /* for >= 96KHz sampling rate: 2'b01: 10.5pF */891 if (priv->dl_rate[MT6359_AIF_1] >= 96000)892 regmap_update_bits(priv->regmap,893 MT6359_AUDDEC_ANA_CON4,894 RG_AUDHPHFCOMPBUFGAINSEL_VAUDP32_MASK_SFT,895 0x1 << RG_AUDHPHFCOMPBUFGAINSEL_VAUDP32_SFT);896 else897 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON4, 0x0000);898 899 /* Set HPP/N STB enhance circuits */900 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON2, 0xf133);901 902 /* Enable HP aux output stage */903 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON1, 0x000c);904 /* Enable HP aux feedback loop */905 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON1, 0x003c);906 /* Enable HP aux CMFB loop */907 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON9, 0x0c00);908 /* Enable HP driver bias circuits */909 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON0, 0x30c0);910 /* Enable HP driver core circuits */911 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON0, 0x30f0);912 /* Short HP main output to HP aux output stage */913 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON1, 0x00fc);914 915 /* Increase HP input pair current to HPM step by step */916 hp_in_pair_current(priv, true);917 918 /* Enable HP main CMFB loop */919 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON9, 0x0e00);920 /* Disable HP aux CMFB loop */921 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON9, 0x0200);922 923 /* Enable HP main output stage */924 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON1, 0x00ff);925 /* Enable HPR/L main output stage step by step */926 hp_main_output_ramp(priv, true);927 928 /* Reduce HP aux feedback loop gain */929 hp_aux_feedback_loop_gain_ramp(priv, true);930 /* Disable HP aux feedback loop */931 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON1, 0x77cf);932 933 /* apply volume setting */934 headset_volume_ramp(priv,935 DL_GAIN_N_22DB,936 priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL]);937 938 /* Disable HP aux output stage */939 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON1, 0x77c3);940 /* Unshort HP main output to HP aux output stage */941 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON1, 0x7703);942 usleep_range(100, 120);943 944 /* Enable AUD_CLK */945 mt6359_set_decoder_clk(priv, true);946 947 /* Enable Audio DAC */948 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON0, 0x30ff);949 if (priv->hp_hifi_mode) {950 /* Enable low-noise mode of DAC */951 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON9, 0xf201);952 } else {953 /* Disable low-noise mode of DAC */954 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON9, 0xf200);955 }956 usleep_range(100, 120);957 958 /* Switch HPL MUX to audio DAC */959 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON0, 0x32ff);960 /* Switch HPR MUX to audio DAC */961 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON0, 0x3aff);962 963 /* Disable Pull-down HPL/R to AVSS28_AUD */964 hp_pull_down(priv, false);965}966 967static void mtk_hp_disable(struct mt6359_priv *priv)968{969 /* Pull-down HPL/R to AVSS28_AUD */970 hp_pull_down(priv, true);971 972 /* HPR/HPL mux to open */973 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON0,974 0x0f00, 0x0000);975 976 /* Disable low-noise mode of DAC */977 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON9,978 0x0001, 0x0000);979 980 /* Disable Audio DAC */981 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON0,982 0x000f, 0x0000);983 984 /* Disable AUD_CLK */985 mt6359_set_decoder_clk(priv, false);986 987 /* Short HP main output to HP aux output stage */988 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON1, 0x77c3);989 /* Enable HP aux output stage */990 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON1, 0x77cf);991 992 /* decrease HPL/R gain to normal gain step by step */993 headset_volume_ramp(priv,994 priv->ana_gain[AUDIO_ANALOG_VOLUME_HPOUTL],995 DL_GAIN_N_22DB);996 997 /* Enable HP aux feedback loop */998 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON1, 0x77ff);999 1000 /* Reduce HP aux feedback loop gain */1001 hp_aux_feedback_loop_gain_ramp(priv, false);1002 1003 /* decrease HPR/L main output stage step by step */1004 hp_main_output_ramp(priv, false);1005 1006 /* Disable HP main output stage */1007 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON1, 0x3, 0x0);1008 1009 /* Enable HP aux CMFB loop */1010 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON9, 0x0e01);1011 1012 /* Disable HP main CMFB loop */1013 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON9, 0x0c01);1014 1015 /* Decrease HP input pair current to 2'b00 step by step */1016 hp_in_pair_current(priv, false);1017 1018 /* Unshort HP main output to HP aux output stage */1019 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON1,1020 0x3 << 6, 0x0);1021 1022 /* Disable HP driver core circuits */1023 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON0,1024 0x3 << 4, 0x0);1025 1026 /* Disable HP driver bias circuits */1027 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON0,1028 0x3 << 6, 0x0);1029 1030 /* Disable HP aux CMFB loop */1031 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON9, 0x201);1032 1033 /* Disable HP aux feedback loop */1034 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON1,1035 0x3 << 4, 0x0);1036 1037 /* Disable HP aux output stage */1038 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON1,1039 0x3 << 2, 0x0);1040}1041 1042static int mt_hp_event(struct snd_soc_dapm_widget *w,1043 struct snd_kcontrol *kcontrol,1044 int event)1045{1046 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1047 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1048 unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]);1049 int device = DEVICE_HP;1050 1051 dev_dbg(priv->dev, "%s(), event 0x%x, dev_counter[DEV_HP] %d, mux %u\n",1052 __func__, event, priv->dev_counter[device], mux);1053 1054 switch (event) {1055 case SND_SOC_DAPM_PRE_PMU:1056 priv->dev_counter[device]++;1057 if (mux == HP_MUX_HP)1058 mtk_hp_enable(priv);1059 break;1060 case SND_SOC_DAPM_PRE_PMD:1061 priv->dev_counter[device]--;1062 if (mux == HP_MUX_HP)1063 mtk_hp_disable(priv);1064 break;1065 default:1066 break;1067 }1068 1069 return 0;1070}1071 1072static int mt_rcv_event(struct snd_soc_dapm_widget *w,1073 struct snd_kcontrol *kcontrol,1074 int event)1075{1076 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1077 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1078 1079 dev_dbg(priv->dev, "%s(), event 0x%x, mux %u\n",1080 __func__, event, dapm_kcontrol_get_value(w->kcontrols[0]));1081 1082 switch (event) {1083 case SND_SOC_DAPM_PRE_PMU:1084 /* Disable handset short-circuit protection */1085 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON6, 0x0010);1086 1087 /* Set RCV DR bias current optimization, 010: 6uA */1088 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON11,1089 DRBIAS_HS_MASK_SFT,1090 DRBIAS_6UA << DRBIAS_HS_SFT);1091 /* Set RCV & ZCD bias current optimization */1092 /* 01: ZCD: 4uA, HP/HS/LO: 5uA */1093 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON12,1094 IBIAS_ZCD_MASK_SFT,1095 IBIAS_ZCD_4UA << IBIAS_ZCD_SFT);1096 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON12,1097 IBIAS_HS_MASK_SFT,1098 IBIAS_5UA << IBIAS_HS_SFT);1099 1100 /* Set HS STB enhance circuits */1101 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON6, 0x0090);1102 1103 /* Set HS output stage (3'b111 = 8x) */1104 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON10, 0x7000);1105 1106 /* Enable HS driver bias circuits */1107 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON6, 0x0092);1108 /* Enable HS driver core circuits */1109 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON6, 0x0093);1110 1111 /* Set HS gain to normal gain step by step */1112 regmap_write(priv->regmap, MT6359_ZCD_CON3,1113 priv->ana_gain[AUDIO_ANALOG_VOLUME_HSOUTL]);1114 1115 /* Enable AUD_CLK */1116 mt6359_set_decoder_clk(priv, true);1117 1118 /* Enable Audio DAC */1119 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON0, 0x0009);1120 /* Enable low-noise mode of DAC */1121 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON9, 0x0001);1122 /* Switch HS MUX to audio DAC */1123 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON6, 0x009b);1124 break;1125 case SND_SOC_DAPM_PRE_PMD:1126 /* HS mux to open */1127 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON6,1128 RG_AUDHSMUXINPUTSEL_VAUDP32_MASK_SFT,1129 RCV_MUX_OPEN);1130 1131 /* Disable Audio DAC */1132 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON0,1133 0x000f, 0x0000);1134 1135 /* Disable AUD_CLK */1136 mt6359_set_decoder_clk(priv, false);1137 1138 /* decrease HS gain to minimum gain step by step */1139 regmap_write(priv->regmap, MT6359_ZCD_CON3, DL_GAIN_N_40DB);1140 1141 /* Disable HS driver core circuits */1142 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON6,1143 RG_AUDHSPWRUP_VAUDP32_MASK_SFT, 0x0);1144 1145 /* Disable HS driver bias circuits */1146 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON6,1147 RG_AUDHSPWRUP_IBIAS_VAUDP32_MASK_SFT, 0x0);1148 break;1149 default:1150 break;1151 }1152 1153 return 0;1154}1155 1156static int mt_lo_event(struct snd_soc_dapm_widget *w,1157 struct snd_kcontrol *kcontrol,1158 int event)1159{1160 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1161 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1162 unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]);1163 1164 dev_dbg(priv->dev, "%s(), event 0x%x, mux %u\n",1165 __func__, event, mux);1166 1167 switch (event) {1168 case SND_SOC_DAPM_PRE_PMU:1169 /* Disable handset short-circuit protection */1170 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON7, 0x0010);1171 1172 /* Set LO DR bias current optimization, 010: 6uA */1173 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON11,1174 DRBIAS_LO_MASK_SFT,1175 DRBIAS_6UA << DRBIAS_LO_SFT);1176 /* Set LO & ZCD bias current optimization */1177 /* 01: ZCD: 4uA, HP/HS/LO: 5uA */1178 if (priv->dev_counter[DEVICE_HP] == 0)1179 regmap_update_bits(priv->regmap,1180 MT6359_AUDDEC_ANA_CON12,1181 IBIAS_ZCD_MASK_SFT,1182 IBIAS_ZCD_4UA << IBIAS_ZCD_SFT);1183 1184 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON12,1185 IBIAS_LO_MASK_SFT,1186 IBIAS_5UA << IBIAS_LO_SFT);1187 1188 /* Set LO STB enhance circuits */1189 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON7, 0x0110);1190 1191 /* Enable LO driver bias circuits */1192 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON7, 0x0112);1193 /* Enable LO driver core circuits */1194 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON7, 0x0113);1195 1196 /* Set LO gain to normal gain step by step */1197 regmap_write(priv->regmap, MT6359_ZCD_CON1,1198 priv->ana_gain[AUDIO_ANALOG_VOLUME_LINEOUTL]);1199 1200 /* Enable AUD_CLK */1201 mt6359_set_decoder_clk(priv, true);1202 1203 /* Switch LOL MUX to audio DAC */1204 if (mux == LO_MUX_L_DAC) {1205 if (priv->dev_counter[DEVICE_HP] > 0) {1206 dev_info(priv->dev, "%s(), can not enable DAC, hp count %d\n",1207 __func__, priv->dev_counter[DEVICE_HP]);1208 break;1209 }1210 /* Enable DACL and switch HP MUX to open*/1211 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON0, 0x3009);1212 /* Disable low-noise mode of DAC */1213 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON9, 0xf200);1214 usleep_range(100, 120);1215 /* Switch LOL MUX to DACL */1216 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON7, 0x0117);1217 } else if (mux == LO_MUX_3RD_DAC) {1218 /* Enable Audio DAC (3rd DAC) */1219 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON7, 0x3113);1220 /* Enable low-noise mode of DAC */1221 if (priv->dev_counter[DEVICE_HP] == 0)1222 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON9, 0x0001);1223 /* Switch LOL MUX to audio 3rd DAC */1224 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON7, 0x311b);1225 }1226 break;1227 case SND_SOC_DAPM_PRE_PMD:1228 /* Switch LOL MUX to open */1229 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON7,1230 RG_AUDLOLMUXINPUTSEL_VAUDP32_MASK_SFT,1231 LO_MUX_OPEN);1232 1233 /* Disable Audio DAC */1234 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON0,1235 0x000f, 0x0000);1236 1237 if (mux == LO_MUX_L_DAC) {1238 /* Disable HP driver core circuits */1239 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON0,1240 0x3 << 4, 0x0);1241 /* Disable HP driver bias circuits */1242 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON0,1243 0x3 << 6, 0x0);1244 }1245 1246 /* Disable AUD_CLK */1247 mt6359_set_decoder_clk(priv, false);1248 1249 /* decrease LO gain to minimum gain step by step */1250 regmap_write(priv->regmap, MT6359_ZCD_CON1, DL_GAIN_N_40DB);1251 1252 /* Disable LO driver core circuits */1253 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON7,1254 RG_AUDLOLPWRUP_VAUDP32_MASK_SFT, 0x0);1255 1256 /* Disable LO driver bias circuits */1257 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON7,1258 RG_AUDLOLPWRUP_IBIAS_VAUDP32_MASK_SFT, 0x0);1259 break;1260 default:1261 break;1262 }1263 1264 return 0;1265}1266 1267static int mt_adc_clk_gen_event(struct snd_soc_dapm_widget *w,1268 struct snd_kcontrol *kcontrol,1269 int event)1270{1271 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1272 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1273 1274 dev_dbg(priv->dev, "%s(), event 0x%x\n", __func__, event);1275 1276 switch (event) {1277 case SND_SOC_DAPM_POST_PMU:1278 /* ADC CLK from CLKGEN (6.5MHz) */1279 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON5,1280 RG_AUDADCCLKRSTB_MASK_SFT,1281 0x1 << RG_AUDADCCLKRSTB_SFT);1282 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON5,1283 RG_AUDADCCLKSOURCE_MASK_SFT, 0x0);1284 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON5,1285 RG_AUDADCCLKSEL_MASK_SFT, 0x0);1286 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON5,1287 RG_AUDADCCLKGENMODE_MASK_SFT,1288 0x1 << RG_AUDADCCLKGENMODE_SFT);1289 break;1290 case SND_SOC_DAPM_PRE_PMD:1291 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON5,1292 RG_AUDADCCLKSOURCE_MASK_SFT, 0x0);1293 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON5,1294 RG_AUDADCCLKSEL_MASK_SFT, 0x0);1295 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON5,1296 RG_AUDADCCLKGENMODE_MASK_SFT, 0x0);1297 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON5,1298 RG_AUDADCCLKRSTB_MASK_SFT, 0x0);1299 break;1300 default:1301 break;1302 }1303 1304 return 0;1305}1306 1307static int mt_dcc_clk_event(struct snd_soc_dapm_widget *w,1308 struct snd_kcontrol *kcontrol,1309 int event)1310{1311 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1312 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1313 1314 dev_dbg(priv->dev, "%s(), event 0x%x\n", __func__, event);1315 1316 switch (event) {1317 case SND_SOC_DAPM_PRE_PMU:1318 /* DCC 50k CLK (from 26M) */1319 /* MT6359_AFE_DCCLK_CFG0, bit 3 for dm ck swap */1320 regmap_update_bits(priv->regmap, MT6359_AFE_DCCLK_CFG0,1321 0xfff7, 0x2062);1322 regmap_update_bits(priv->regmap, MT6359_AFE_DCCLK_CFG0,1323 0xfff7, 0x2060);1324 regmap_update_bits(priv->regmap, MT6359_AFE_DCCLK_CFG0,1325 0xfff7, 0x2061);1326 1327 regmap_write(priv->regmap, MT6359_AFE_DCCLK_CFG1, 0x0100);1328 break;1329 case SND_SOC_DAPM_POST_PMD:1330 regmap_update_bits(priv->regmap, MT6359_AFE_DCCLK_CFG0,1331 0xfff7, 0x2060);1332 regmap_update_bits(priv->regmap, MT6359_AFE_DCCLK_CFG0,1333 0xfff7, 0x2062);1334 break;1335 default:1336 break;1337 }1338 1339 return 0;1340}1341 1342static int mt_mic_bias_0_event(struct snd_soc_dapm_widget *w,1343 struct snd_kcontrol *kcontrol,1344 int event)1345{1346 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1347 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1348 unsigned int mic_type = priv->mux_select[MUX_MIC_TYPE_0];1349 1350 dev_dbg(priv->dev, "%s(), event 0x%x, mic_type %d\n",1351 __func__, event, mic_type);1352 1353 switch (event) {1354 case SND_SOC_DAPM_PRE_PMU:1355 switch (mic_type) {1356 case MIC_TYPE_MUX_DCC_ECM_DIFF:1357 regmap_update_bits(priv->regmap,1358 MT6359_AUDENC_ANA_CON15,1359 0xff00, 0x7700);1360 break;1361 case MIC_TYPE_MUX_DCC_ECM_SINGLE:1362 regmap_update_bits(priv->regmap,1363 MT6359_AUDENC_ANA_CON15,1364 0xff00, 0x1100);1365 break;1366 default:1367 regmap_update_bits(priv->regmap,1368 MT6359_AUDENC_ANA_CON15,1369 0xff00, 0x0000);1370 break;1371 }1372 1373 /* DMIC enable */1374 regmap_write(priv->regmap,1375 MT6359_AUDENC_ANA_CON14, 0x0004);1376 /* MISBIAS0 = 1P9V */1377 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON15,1378 RG_AUDMICBIAS0VREF_MASK_SFT,1379 MIC_BIAS_1P9 << RG_AUDMICBIAS0VREF_SFT);1380 /* normal power select */1381 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON15,1382 RG_AUDMICBIAS0LOWPEN_MASK_SFT,1383 0 << RG_AUDMICBIAS0LOWPEN_SFT);1384 break;1385 case SND_SOC_DAPM_POST_PMD:1386 /* Disable MICBIAS0, MISBIAS0 = 1P7V */1387 regmap_write(priv->regmap, MT6359_AUDENC_ANA_CON15, 0x0000);1388 break;1389 default:1390 break;1391 }1392 1393 return 0;1394}1395 1396static int mt_mic_bias_1_event(struct snd_soc_dapm_widget *w,1397 struct snd_kcontrol *kcontrol,1398 int event)1399{1400 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1401 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1402 unsigned int mic_type = priv->mux_select[MUX_MIC_TYPE_1];1403 1404 dev_dbg(priv->dev, "%s(), event 0x%x, mic_type %d\n",1405 __func__, event, mic_type);1406 1407 switch (event) {1408 case SND_SOC_DAPM_PRE_PMU:1409 /* MISBIAS1 = 2P6V */1410 if (mic_type == MIC_TYPE_MUX_DCC_ECM_SINGLE)1411 regmap_write(priv->regmap,1412 MT6359_AUDENC_ANA_CON16, 0x0160);1413 else1414 regmap_write(priv->regmap,1415 MT6359_AUDENC_ANA_CON16, 0x0060);1416 1417 /* normal power select */1418 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON16,1419 RG_AUDMICBIAS1LOWPEN_MASK_SFT,1420 0 << RG_AUDMICBIAS1LOWPEN_SFT);1421 break;1422 default:1423 break;1424 }1425 1426 return 0;1427}1428 1429static int mt_mic_bias_2_event(struct snd_soc_dapm_widget *w,1430 struct snd_kcontrol *kcontrol,1431 int event)1432{1433 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1434 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1435 unsigned int mic_type = priv->mux_select[MUX_MIC_TYPE_2];1436 1437 dev_dbg(priv->dev, "%s(), event 0x%x, mic_type %d\n",1438 __func__, event, mic_type);1439 1440 switch (event) {1441 case SND_SOC_DAPM_PRE_PMU:1442 switch (mic_type) {1443 case MIC_TYPE_MUX_DCC_ECM_DIFF:1444 regmap_update_bits(priv->regmap,1445 MT6359_AUDENC_ANA_CON17,1446 0xff00, 0x7700);1447 break;1448 case MIC_TYPE_MUX_DCC_ECM_SINGLE:1449 regmap_update_bits(priv->regmap,1450 MT6359_AUDENC_ANA_CON17,1451 0xff00, 0x1100);1452 break;1453 default:1454 regmap_update_bits(priv->regmap,1455 MT6359_AUDENC_ANA_CON17,1456 0xff00, 0x0000);1457 break;1458 }1459 1460 /* MISBIAS2 = 1P9V */1461 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON17,1462 RG_AUDMICBIAS2VREF_MASK_SFT,1463 MIC_BIAS_1P9 << RG_AUDMICBIAS2VREF_SFT);1464 /* normal power select */1465 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON17,1466 RG_AUDMICBIAS2LOWPEN_MASK_SFT,1467 0 << RG_AUDMICBIAS2LOWPEN_SFT);1468 break;1469 case SND_SOC_DAPM_POST_PMD:1470 /* Disable MICBIAS2, MISBIAS0 = 1P7V */1471 regmap_write(priv->regmap, MT6359_AUDENC_ANA_CON17, 0x0000);1472 break;1473 default:1474 break;1475 }1476 1477 return 0;1478}1479 1480static int mt_mtkaif_tx_event(struct snd_soc_dapm_widget *w,1481 struct snd_kcontrol *kcontrol,1482 int event)1483{1484 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1485 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1486 1487 dev_dbg(priv->dev, "%s(), event = 0x%x\n", __func__, event);1488 1489 switch (event) {1490 case SND_SOC_DAPM_PRE_PMU:1491 mt6359_mtkaif_tx_enable(priv);1492 break;1493 case SND_SOC_DAPM_POST_PMD:1494 mt6359_mtkaif_tx_disable(priv);1495 break;1496 default:1497 break;1498 }1499 1500 return 0;1501}1502 1503static int mt_ul_src_dmic_event(struct snd_soc_dapm_widget *w,1504 struct snd_kcontrol *kcontrol,1505 int event)1506{1507 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1508 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1509 1510 dev_dbg(priv->dev, "%s(), event = 0x%x\n", __func__, event);1511 1512 switch (event) {1513 case SND_SOC_DAPM_PRE_PMU:1514 /* UL dmic setting */1515 if (priv->dmic_one_wire_mode)1516 regmap_write(priv->regmap, MT6359_AFE_UL_SRC_CON0_H,1517 0x0400);1518 else1519 regmap_write(priv->regmap, MT6359_AFE_UL_SRC_CON0_H,1520 0x0080);1521 /* default one wire, 3.25M */1522 regmap_update_bits(priv->regmap, MT6359_AFE_UL_SRC_CON0_L,1523 0xfffc, 0x0000);1524 break;1525 case SND_SOC_DAPM_POST_PMD:1526 regmap_write(priv->regmap,1527 MT6359_AFE_UL_SRC_CON0_H, 0x0000);1528 break;1529 default:1530 break;1531 }1532 1533 return 0;1534}1535 1536static int mt_ul_src_34_dmic_event(struct snd_soc_dapm_widget *w,1537 struct snd_kcontrol *kcontrol,1538 int event)1539{1540 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1541 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1542 1543 dev_dbg(priv->dev, "%s(), event = 0x%x\n", __func__, event);1544 1545 switch (event) {1546 case SND_SOC_DAPM_PRE_PMU:1547 /* default two wire, 3.25M */1548 regmap_write(priv->regmap,1549 MT6359_AFE_ADDA6_L_SRC_CON0_H, 0x0080);1550 regmap_update_bits(priv->regmap, MT6359_AFE_ADDA6_UL_SRC_CON0_L,1551 0xfffc, 0x0000);1552 break;1553 case SND_SOC_DAPM_POST_PMD:1554 regmap_write(priv->regmap,1555 MT6359_AFE_ADDA6_L_SRC_CON0_H, 0x0000);1556 break;1557 default:1558 break;1559 }1560 1561 return 0;1562}1563 1564static int mt_adc_l_event(struct snd_soc_dapm_widget *w,1565 struct snd_kcontrol *kcontrol,1566 int event)1567{1568 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1569 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1570 1571 dev_dbg(priv->dev, "%s(), event = 0x%x\n", __func__, event);1572 1573 switch (event) {1574 case SND_SOC_DAPM_POST_PMU:1575 usleep_range(100, 120);1576 /* Audio L preamplifier DCC precharge off */1577 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON0,1578 RG_AUDPREAMPLDCPRECHARGE_MASK_SFT,1579 0x0);1580 break;1581 default:1582 break;1583 }1584 1585 return 0;1586}1587 1588static int mt_adc_r_event(struct snd_soc_dapm_widget *w,1589 struct snd_kcontrol *kcontrol,1590 int event)1591{1592 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1593 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1594 1595 dev_dbg(priv->dev, "%s(), event = 0x%x\n", __func__, event);1596 1597 switch (event) {1598 case SND_SOC_DAPM_POST_PMU:1599 usleep_range(100, 120);1600 /* Audio R preamplifier DCC precharge off */1601 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON1,1602 RG_AUDPREAMPRDCPRECHARGE_MASK_SFT,1603 0x0);1604 break;1605 default:1606 break;1607 }1608 1609 return 0;1610}1611 1612static int mt_adc_3_event(struct snd_soc_dapm_widget *w,1613 struct snd_kcontrol *kcontrol,1614 int event)1615{1616 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1617 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1618 1619 dev_dbg(priv->dev, "%s(), event = 0x%x\n", __func__, event);1620 1621 switch (event) {1622 case SND_SOC_DAPM_POST_PMU:1623 usleep_range(100, 120);1624 /* Audio R preamplifier DCC precharge off */1625 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON2,1626 RG_AUDPREAMP3DCPRECHARGE_MASK_SFT,1627 0x0);1628 break;1629 default:1630 break;1631 }1632 1633 return 0;1634}1635 1636static int mt_pga_l_mux_event(struct snd_soc_dapm_widget *w,1637 struct snd_kcontrol *kcontrol,1638 int event)1639{1640 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1641 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1642 unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]);1643 1644 dev_dbg(priv->dev, "%s(), mux %d\n", __func__, mux);1645 priv->mux_select[MUX_PGA_L] = mux >> RG_AUDPREAMPLINPUTSEL_SFT;1646 return 0;1647}1648 1649static int mt_pga_r_mux_event(struct snd_soc_dapm_widget *w,1650 struct snd_kcontrol *kcontrol,1651 int event)1652{1653 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1654 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1655 unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]);1656 1657 dev_dbg(priv->dev, "%s(), mux %d\n", __func__, mux);1658 priv->mux_select[MUX_PGA_R] = mux >> RG_AUDPREAMPRINPUTSEL_SFT;1659 return 0;1660}1661 1662static int mt_pga_3_mux_event(struct snd_soc_dapm_widget *w,1663 struct snd_kcontrol *kcontrol,1664 int event)1665{1666 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1667 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1668 unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]);1669 1670 dev_dbg(priv->dev, "%s(), mux %d\n", __func__, mux);1671 priv->mux_select[MUX_PGA_3] = mux >> RG_AUDPREAMP3INPUTSEL_SFT;1672 return 0;1673}1674 1675static int mt_pga_l_event(struct snd_soc_dapm_widget *w,1676 struct snd_kcontrol *kcontrol,1677 int event)1678{1679 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1680 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1681 int mic_gain_l = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP1];1682 unsigned int mux_pga = priv->mux_select[MUX_PGA_L];1683 unsigned int mic_type;1684 1685 switch (mux_pga) {1686 case PGA_L_MUX_AIN0:1687 mic_type = priv->mux_select[MUX_MIC_TYPE_0];1688 break;1689 case PGA_L_MUX_AIN1:1690 mic_type = priv->mux_select[MUX_MIC_TYPE_1];1691 break;1692 default:1693 dev_err(priv->dev, "%s(), invalid pga mux %d\n",1694 __func__, mux_pga);1695 return -EINVAL;1696 }1697 1698 switch (event) {1699 case SND_SOC_DAPM_PRE_PMU:1700 if (IS_DCC_BASE(mic_type)) {1701 /* Audio L preamplifier DCC precharge */1702 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON0,1703 RG_AUDPREAMPLDCPRECHARGE_MASK_SFT,1704 0x1 << RG_AUDPREAMPLDCPRECHARGE_SFT);1705 }1706 break;1707 case SND_SOC_DAPM_POST_PMU:1708 /* set mic pga gain */1709 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON0,1710 RG_AUDPREAMPLGAIN_MASK_SFT,1711 mic_gain_l << RG_AUDPREAMPLGAIN_SFT);1712 1713 if (IS_DCC_BASE(mic_type)) {1714 /* L preamplifier DCCEN */1715 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON0,1716 RG_AUDPREAMPLDCCEN_MASK_SFT,1717 0x1 << RG_AUDPREAMPLDCCEN_SFT);1718 }1719 break;1720 case SND_SOC_DAPM_POST_PMD:1721 /* L preamplifier DCCEN */1722 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON0,1723 RG_AUDPREAMPLDCCEN_MASK_SFT,1724 0x0 << RG_AUDPREAMPLDCCEN_SFT);1725 break;1726 default:1727 break;1728 }1729 1730 return 0;1731}1732 1733static int mt_pga_r_event(struct snd_soc_dapm_widget *w,1734 struct snd_kcontrol *kcontrol,1735 int event)1736{1737 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1738 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1739 int mic_gain_r = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP2];1740 unsigned int mux_pga = priv->mux_select[MUX_PGA_R];1741 unsigned int mic_type;1742 1743 switch (mux_pga) {1744 case PGA_R_MUX_AIN0:1745 mic_type = priv->mux_select[MUX_MIC_TYPE_0];1746 break;1747 case PGA_R_MUX_AIN2:1748 case PGA_R_MUX_AIN3:1749 mic_type = priv->mux_select[MUX_MIC_TYPE_2];1750 break;1751 default:1752 dev_err(priv->dev, "%s(), invalid pga mux %d\n",1753 __func__, mux_pga);1754 return -EINVAL;1755 }1756 1757 switch (event) {1758 case SND_SOC_DAPM_PRE_PMU:1759 if (IS_DCC_BASE(mic_type)) {1760 /* Audio R preamplifier DCC precharge */1761 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON1,1762 RG_AUDPREAMPRDCPRECHARGE_MASK_SFT,1763 0x1 << RG_AUDPREAMPRDCPRECHARGE_SFT);1764 }1765 break;1766 case SND_SOC_DAPM_POST_PMU:1767 /* set mic pga gain */1768 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON1,1769 RG_AUDPREAMPRGAIN_MASK_SFT,1770 mic_gain_r << RG_AUDPREAMPRGAIN_SFT);1771 1772 if (IS_DCC_BASE(mic_type)) {1773 /* R preamplifier DCCEN */1774 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON1,1775 RG_AUDPREAMPRDCCEN_MASK_SFT,1776 0x1 << RG_AUDPREAMPRDCCEN_SFT);1777 }1778 break;1779 case SND_SOC_DAPM_POST_PMD:1780 /* R preamplifier DCCEN */1781 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON1,1782 RG_AUDPREAMPRDCCEN_MASK_SFT,1783 0x0 << RG_AUDPREAMPRDCCEN_SFT);1784 break;1785 default:1786 break;1787 }1788 1789 return 0;1790}1791 1792static int mt_pga_3_event(struct snd_soc_dapm_widget *w,1793 struct snd_kcontrol *kcontrol,1794 int event)1795{1796 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1797 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1798 int mic_gain_3 = priv->ana_gain[AUDIO_ANALOG_VOLUME_MICAMP3];1799 unsigned int mux_pga = priv->mux_select[MUX_PGA_3];1800 unsigned int mic_type;1801 1802 switch (mux_pga) {1803 case PGA_3_MUX_AIN2:1804 case PGA_3_MUX_AIN3:1805 mic_type = priv->mux_select[MUX_MIC_TYPE_2];1806 break;1807 default:1808 dev_err(priv->dev, "%s(), invalid pga mux %d\n",1809 __func__, mux_pga);1810 return -EINVAL;1811 }1812 1813 switch (event) {1814 case SND_SOC_DAPM_PRE_PMU:1815 if (IS_DCC_BASE(mic_type)) {1816 /* Audio 3 preamplifier DCC precharge */1817 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON2,1818 RG_AUDPREAMP3DCPRECHARGE_MASK_SFT,1819 0x1 << RG_AUDPREAMP3DCPRECHARGE_SFT);1820 }1821 break;1822 case SND_SOC_DAPM_POST_PMU:1823 /* set mic pga gain */1824 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON2,1825 RG_AUDPREAMP3GAIN_MASK_SFT,1826 mic_gain_3 << RG_AUDPREAMP3GAIN_SFT);1827 1828 if (IS_DCC_BASE(mic_type)) {1829 /* 3 preamplifier DCCEN */1830 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON2,1831 RG_AUDPREAMP3DCCEN_MASK_SFT,1832 0x1 << RG_AUDPREAMP3DCCEN_SFT);1833 }1834 break;1835 case SND_SOC_DAPM_POST_PMD:1836 /* 3 preamplifier DCCEN */1837 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON2,1838 RG_AUDPREAMP3DCCEN_MASK_SFT,1839 0x0 << RG_AUDPREAMP3DCCEN_SFT);1840 break;1841 default:1842 break;1843 }1844 1845 return 0;1846}1847 1848/* It is based on hw's control sequenece to add some delay when PMU/PMD */1849static int mt_delay_250_event(struct snd_soc_dapm_widget *w,1850 struct snd_kcontrol *kcontrol,1851 int event)1852{1853 switch (event) {1854 case SND_SOC_DAPM_POST_PMU:1855 case SND_SOC_DAPM_PRE_PMD:1856 usleep_range(250, 270);1857 break;1858 default:1859 break;1860 }1861 1862 return 0;1863}1864 1865static int mt_delay_100_event(struct snd_soc_dapm_widget *w,1866 struct snd_kcontrol *kcontrol,1867 int event)1868{1869 switch (event) {1870 case SND_SOC_DAPM_POST_PMU:1871 case SND_SOC_DAPM_PRE_PMD:1872 usleep_range(100, 120);1873 break;1874 default:1875 break;1876 }1877 1878 return 0;1879}1880 1881static int mt_hp_pull_down_event(struct snd_soc_dapm_widget *w,1882 struct snd_kcontrol *kcontrol,1883 int event)1884{1885 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1886 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1887 1888 switch (event) {1889 case SND_SOC_DAPM_PRE_PMU:1890 hp_pull_down(priv, true);1891 break;1892 case SND_SOC_DAPM_POST_PMD:1893 hp_pull_down(priv, false);1894 break;1895 default:1896 break;1897 }1898 1899 return 0;1900}1901 1902static int mt_hp_mute_event(struct snd_soc_dapm_widget *w,1903 struct snd_kcontrol *kcontrol,1904 int event)1905{1906 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1907 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1908 1909 switch (event) {1910 case SND_SOC_DAPM_PRE_PMU:1911 /* Set HPR/HPL gain to -22dB */1912 regmap_write(priv->regmap, MT6359_ZCD_CON2, DL_GAIN_N_22DB_REG);1913 break;1914 case SND_SOC_DAPM_POST_PMD:1915 /* Set HPL/HPR gain to mute */1916 regmap_write(priv->regmap, MT6359_ZCD_CON2, DL_GAIN_N_40DB_REG);1917 break;1918 default:1919 break;1920 }1921 1922 return 0;1923}1924 1925static int mt_hp_damp_event(struct snd_soc_dapm_widget *w,1926 struct snd_kcontrol *kcontrol,1927 int event)1928{1929 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1930 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1931 1932 switch (event) {1933 case SND_SOC_DAPM_POST_PMD:1934 /* Disable HP damping circuit & HPN 4K load */1935 /* reset CMFB PW level */1936 regmap_write(priv->regmap, MT6359_AUDDEC_ANA_CON10, 0x0000);1937 break;1938 default:1939 break;1940 }1941 1942 return 0;1943}1944 1945static int mt_esd_resist_event(struct snd_soc_dapm_widget *w,1946 struct snd_kcontrol *kcontrol,1947 int event)1948{1949 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1950 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1951 1952 switch (event) {1953 case SND_SOC_DAPM_PRE_PMU:1954 /* Reduce ESD resistance of AU_REFN */1955 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON2,1956 RG_AUDREFN_DERES_EN_VAUDP32_MASK_SFT,1957 0x1 << RG_AUDREFN_DERES_EN_VAUDP32_SFT);1958 usleep_range(250, 270);1959 break;1960 case SND_SOC_DAPM_POST_PMD:1961 /* Increase ESD resistance of AU_REFN */1962 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON2,1963 RG_AUDREFN_DERES_EN_VAUDP32_MASK_SFT, 0x0);1964 break;1965 default:1966 break;1967 }1968 1969 return 0;1970}1971 1972static int mt_sdm_event(struct snd_soc_dapm_widget *w,1973 struct snd_kcontrol *kcontrol,1974 int event)1975{1976 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);1977 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);1978 1979 switch (event) {1980 case SND_SOC_DAPM_PRE_PMU:1981 /* sdm audio fifo clock power on */1982 regmap_update_bits(priv->regmap, MT6359_AFUNC_AUD_CON2,1983 0xfffd, 0x0006);1984 /* scrambler clock on enable */1985 regmap_write(priv->regmap, MT6359_AFUNC_AUD_CON0, 0xcba1);1986 /* sdm power on */1987 regmap_update_bits(priv->regmap, MT6359_AFUNC_AUD_CON2,1988 0xfffd, 0x0003);1989 /* sdm fifo enable */1990 regmap_update_bits(priv->regmap, MT6359_AFUNC_AUD_CON2,1991 0xfffd, 0x000B);1992 break;1993 case SND_SOC_DAPM_POST_PMD:1994 /* DL scrambler disabling sequence */1995 regmap_update_bits(priv->regmap, MT6359_AFUNC_AUD_CON2,1996 0xfffd, 0x0000);1997 regmap_write(priv->regmap, MT6359_AFUNC_AUD_CON0, 0xcba0);1998 break;1999 default:2000 break;2001 }2002 2003 return 0;2004}2005 2006static int mt_sdm_3rd_event(struct snd_soc_dapm_widget *w,2007 struct snd_kcontrol *kcontrol,2008 int event)2009{2010 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);2011 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);2012 2013 switch (event) {2014 case SND_SOC_DAPM_PRE_PMU:2015 /* sdm audio fifo clock power on */2016 regmap_write(priv->regmap, MT6359_AFUNC_AUD_CON11, 0x0006);2017 /* scrambler clock on enable */2018 regmap_write(priv->regmap, MT6359_AFUNC_AUD_CON9, 0xcba1);2019 /* sdm power on */2020 regmap_write(priv->regmap, MT6359_AFUNC_AUD_CON11, 0x0003);2021 /* sdm fifo enable */2022 regmap_write(priv->regmap, MT6359_AFUNC_AUD_CON11, 0x000b);2023 break;2024 case SND_SOC_DAPM_POST_PMD:2025 /* DL scrambler disabling sequence */2026 regmap_write(priv->regmap, MT6359_AFUNC_AUD_CON11, 0x0000);2027 regmap_write(priv->regmap, MT6359_AFUNC_AUD_CON9, 0xcba0);2028 break;2029 default:2030 break;2031 }2032 2033 return 0;2034}2035 2036static int mt_ncp_event(struct snd_soc_dapm_widget *w,2037 struct snd_kcontrol *kcontrol,2038 int event)2039{2040 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);2041 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);2042 2043 switch (event) {2044 case SND_SOC_DAPM_PRE_PMU:2045 regmap_write(priv->regmap, MT6359_AFE_NCP_CFG0, 0xc800);2046 break;2047 default:2048 break;2049 }2050 2051 return 0;2052}2053 2054/* DAPM Widgets */2055static const struct snd_soc_dapm_widget mt6359_dapm_widgets[] = {2056 /* Global Supply*/2057 SND_SOC_DAPM_SUPPLY_S("CLK_BUF", SUPPLY_SEQ_CLK_BUF,2058 MT6359_DCXO_CW12,2059 RG_XO_AUDIO_EN_M_SFT, 0, NULL, 0),2060 SND_SOC_DAPM_SUPPLY_S("AUDGLB", SUPPLY_SEQ_AUD_GLB,2061 MT6359_AUDDEC_ANA_CON13,2062 RG_AUDGLB_PWRDN_VA32_SFT, 1, NULL, 0),2063 SND_SOC_DAPM_SUPPLY_S("CLKSQ Audio", SUPPLY_SEQ_CLKSQ,2064 MT6359_AUDENC_ANA_CON23,2065 RG_CLKSQ_EN_SFT, 0, NULL, SND_SOC_DAPM_PRE_PMU),2066 SND_SOC_DAPM_SUPPLY_S("AUDNCP_CK", SUPPLY_SEQ_TOP_CK,2067 MT6359_AUD_TOP_CKPDN_CON0,2068 RG_AUDNCP_CK_PDN_SFT, 1, NULL, 0),2069 SND_SOC_DAPM_SUPPLY_S("ZCD13M_CK", SUPPLY_SEQ_TOP_CK,2070 MT6359_AUD_TOP_CKPDN_CON0,2071 RG_ZCD13M_CK_PDN_SFT, 1, NULL, 0),2072 SND_SOC_DAPM_SUPPLY_S("AUD_CK", SUPPLY_SEQ_TOP_CK_LAST,2073 MT6359_AUD_TOP_CKPDN_CON0,2074 RG_AUD_CK_PDN_SFT, 1, mt_delay_250_event,2075 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),2076 SND_SOC_DAPM_SUPPLY_S("AUDIF_CK", SUPPLY_SEQ_TOP_CK,2077 MT6359_AUD_TOP_CKPDN_CON0,2078 RG_AUDIF_CK_PDN_SFT, 1, NULL, 0),2079 SND_SOC_DAPM_REGULATOR_SUPPLY("vaud18", 0, 0),2080 2081 /* Digital Clock */2082 SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_AFE_CTL", SUPPLY_SEQ_AUD_TOP_LAST,2083 MT6359_AUDIO_TOP_CON0,2084 PDN_AFE_CTL_SFT, 1,2085 mt_delay_250_event,2086 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),2087 SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_DAC_CTL", SUPPLY_SEQ_AUD_TOP,2088 MT6359_AUDIO_TOP_CON0,2089 PDN_DAC_CTL_SFT, 1, NULL, 0),2090 SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_ADC_CTL", SUPPLY_SEQ_AUD_TOP,2091 MT6359_AUDIO_TOP_CON0,2092 PDN_ADC_CTL_SFT, 1, NULL, 0),2093 SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_ADDA6_ADC_CTL", SUPPLY_SEQ_AUD_TOP,2094 MT6359_AUDIO_TOP_CON0,2095 PDN_ADDA6_ADC_CTL_SFT, 1, NULL, 0),2096 SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_I2S_DL", SUPPLY_SEQ_AUD_TOP,2097 MT6359_AUDIO_TOP_CON0,2098 PDN_I2S_DL_CTL_SFT, 1, NULL, 0),2099 SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_PWR_CLK", SUPPLY_SEQ_AUD_TOP,2100 MT6359_AUDIO_TOP_CON0,2101 PWR_CLK_DIS_CTL_SFT, 1, NULL, 0),2102 SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_PDN_AFE_TESTMODEL", SUPPLY_SEQ_AUD_TOP,2103 MT6359_AUDIO_TOP_CON0,2104 PDN_AFE_TESTMODEL_CTL_SFT, 1, NULL, 0),2105 SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_PDN_RESERVED", SUPPLY_SEQ_AUD_TOP,2106 MT6359_AUDIO_TOP_CON0,2107 PDN_RESERVED_SFT, 1, NULL, 0),2108 2109 SND_SOC_DAPM_SUPPLY_S("SDM", SUPPLY_SEQ_DL_SDM,2110 SND_SOC_NOPM, 0, 0,2111 mt_sdm_event,2112 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),2113 SND_SOC_DAPM_SUPPLY_S("SDM_3RD", SUPPLY_SEQ_DL_SDM,2114 SND_SOC_NOPM, 0, 0,2115 mt_sdm_3rd_event,2116 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),2117 2118 /* ch123 share SDM FIFO CLK */2119 SND_SOC_DAPM_SUPPLY_S("SDM_FIFO_CLK", SUPPLY_SEQ_DL_SDM_FIFO_CLK,2120 MT6359_AFUNC_AUD_CON2,2121 CCI_AFIFO_CLK_PWDB_SFT, 0,2122 NULL, 0),2123 2124 SND_SOC_DAPM_SUPPLY_S("NCP", SUPPLY_SEQ_DL_NCP,2125 MT6359_AFE_NCP_CFG0,2126 RG_NCP_ON_SFT, 0,2127 mt_ncp_event,2128 SND_SOC_DAPM_PRE_PMU),2129 2130 SND_SOC_DAPM_SUPPLY("DL Digital Clock", SND_SOC_NOPM,2131 0, 0, NULL, 0),2132 SND_SOC_DAPM_SUPPLY("DL Digital Clock CH_1_2", SND_SOC_NOPM,2133 0, 0, NULL, 0),2134 SND_SOC_DAPM_SUPPLY("DL Digital Clock CH_3", SND_SOC_NOPM,2135 0, 0, NULL, 0),2136 2137 /* AFE ON */2138 SND_SOC_DAPM_SUPPLY_S("AFE_ON", SUPPLY_SEQ_AFE,2139 MT6359_AFE_UL_DL_CON0, AFE_ON_SFT, 0,2140 NULL, 0),2141 2142 /* AIF Rx*/2143 SND_SOC_DAPM_AIF_IN("AIF_RX", "AIF1 Playback", 0,2144 SND_SOC_NOPM, 0, 0),2145 2146 SND_SOC_DAPM_AIF_IN("AIF2_RX", "AIF2 Playback", 0,2147 SND_SOC_NOPM, 0, 0),2148 2149 SND_SOC_DAPM_SUPPLY_S("AFE_DL_SRC", SUPPLY_SEQ_DL_SRC,2150 MT6359_AFE_DL_SRC2_CON0_L,2151 DL_2_SRC_ON_TMP_CTL_PRE_SFT, 0,2152 NULL, 0),2153 2154 /* DL Supply */2155 SND_SOC_DAPM_SUPPLY("DL Power Supply", SND_SOC_NOPM,2156 0, 0, NULL, 0),2157 2158 SND_SOC_DAPM_SUPPLY_S("ESD_RESIST", SUPPLY_SEQ_DL_ESD_RESIST,2159 SND_SOC_NOPM,2160 0, 0,2161 mt_esd_resist_event,2162 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),2163 SND_SOC_DAPM_SUPPLY_S("LDO", SUPPLY_SEQ_DL_LDO,2164 MT6359_AUDDEC_ANA_CON14,2165 RG_LCLDO_DEC_EN_VA32_SFT, 0,2166 NULL, 0),2167 SND_SOC_DAPM_SUPPLY_S("LDO_REMOTE", SUPPLY_SEQ_DL_LDO_REMOTE_SENSE,2168 MT6359_AUDDEC_ANA_CON14,2169 RG_LCLDO_DEC_REMOTE_SENSE_VA18_SFT, 0,2170 NULL, 0),2171 SND_SOC_DAPM_SUPPLY_S("NV_REGULATOR", SUPPLY_SEQ_DL_NV,2172 MT6359_AUDDEC_ANA_CON14,2173 RG_NVREG_EN_VAUDP32_SFT, 0,2174 mt_delay_100_event, SND_SOC_DAPM_POST_PMU),2175 SND_SOC_DAPM_SUPPLY_S("IBIST", SUPPLY_SEQ_DL_IBIST,2176 MT6359_AUDDEC_ANA_CON12,2177 RG_AUDIBIASPWRDN_VAUDP32_SFT, 1,2178 NULL, 0),2179 2180 /* DAC */2181 SND_SOC_DAPM_MUX("DAC In Mux", SND_SOC_NOPM, 0, 0, &dac_in_mux_control),2182 2183 SND_SOC_DAPM_DAC("DACL", NULL, SND_SOC_NOPM, 0, 0),2184 2185 SND_SOC_DAPM_DAC("DACR", NULL, SND_SOC_NOPM, 0, 0),2186 2187 SND_SOC_DAPM_DAC("DAC_3RD", NULL, SND_SOC_NOPM, 0, 0),2188 2189 /* Headphone */2190 SND_SOC_DAPM_MUX_E("HP Mux", SND_SOC_NOPM, 0, 0,2191 &hp_in_mux_control,2192 mt_hp_event,2193 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),2194 2195 SND_SOC_DAPM_SUPPLY("HP_Supply", SND_SOC_NOPM,2196 0, 0, NULL, 0),2197 SND_SOC_DAPM_SUPPLY_S("HP_PULL_DOWN", SUPPLY_SEQ_HP_PULL_DOWN,2198 SND_SOC_NOPM,2199 0, 0,2200 mt_hp_pull_down_event,2201 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),2202 SND_SOC_DAPM_SUPPLY_S("HP_MUTE", SUPPLY_SEQ_HP_MUTE,2203 SND_SOC_NOPM,2204 0, 0,2205 mt_hp_mute_event,2206 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),2207 SND_SOC_DAPM_SUPPLY_S("HP_DAMP", SUPPLY_SEQ_HP_DAMPING_OFF_RESET_CMFB,2208 SND_SOC_NOPM,2209 0, 0,2210 mt_hp_damp_event,2211 SND_SOC_DAPM_POST_PMD),2212 2213 /* Receiver */2214 SND_SOC_DAPM_MUX_E("RCV Mux", SND_SOC_NOPM, 0, 0,2215 &rcv_in_mux_control,2216 mt_rcv_event,2217 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),2218 2219 /* LOL */2220 SND_SOC_DAPM_MUX_E("LOL Mux", SND_SOC_NOPM, 0, 0,2221 &lo_in_mux_control,2222 mt_lo_event,2223 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),2224 2225 /* Outputs */2226 SND_SOC_DAPM_OUTPUT("Receiver"),2227 SND_SOC_DAPM_OUTPUT("Headphone L"),2228 SND_SOC_DAPM_OUTPUT("Headphone R"),2229 SND_SOC_DAPM_OUTPUT("Headphone L Ext Spk Amp"),2230 SND_SOC_DAPM_OUTPUT("Headphone R Ext Spk Amp"),2231 SND_SOC_DAPM_OUTPUT("LINEOUT L"),2232 2233 /* SGEN */2234 SND_SOC_DAPM_SUPPLY("SGEN DL Enable", MT6359_AFE_SGEN_CFG0,2235 SGEN_DAC_EN_CTL_SFT, 0, NULL, 0),2236 SND_SOC_DAPM_SUPPLY("SGEN MUTE", MT6359_AFE_SGEN_CFG0,2237 SGEN_MUTE_SW_CTL_SFT, 1,2238 mt_sgen_event,2239 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),2240 SND_SOC_DAPM_SUPPLY("SGEN DL SRC", MT6359_AFE_DL_SRC2_CON0_L,2241 DL_2_SRC_ON_TMP_CTL_PRE_SFT, 0, NULL, 0),2242 2243 SND_SOC_DAPM_INPUT("SGEN DL"),2244 2245 /* Uplinks */2246 SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0,2247 SND_SOC_NOPM, 0, 0),2248 SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0,2249 SND_SOC_NOPM, 0, 0),2250 2251 SND_SOC_DAPM_SUPPLY_S("ADC_CLKGEN", SUPPLY_SEQ_ADC_CLKGEN,2252 SND_SOC_NOPM, 0, 0,2253 mt_adc_clk_gen_event,2254 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),2255 2256 SND_SOC_DAPM_SUPPLY_S("DCC_CLK", SUPPLY_SEQ_DCC_CLK,2257 SND_SOC_NOPM, 0, 0,2258 mt_dcc_clk_event,2259 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),2260 2261 /* Uplinks MUX */2262 SND_SOC_DAPM_MUX("AIF Out Mux", SND_SOC_NOPM, 0, 0,2263 &aif_out_mux_control),2264 2265 SND_SOC_DAPM_MUX("AIF2 Out Mux", SND_SOC_NOPM, 0, 0,2266 &aif2_out_mux_control),2267 2268 SND_SOC_DAPM_SUPPLY("AIFTX_Supply", SND_SOC_NOPM, 0, 0, NULL, 0),2269 2270 SND_SOC_DAPM_SUPPLY_S("MTKAIF_TX", SUPPLY_SEQ_UL_MTKAIF,2271 SND_SOC_NOPM, 0, 0,2272 mt_mtkaif_tx_event,2273 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),2274 2275 SND_SOC_DAPM_SUPPLY_S("UL_SRC", SUPPLY_SEQ_UL_SRC,2276 MT6359_AFE_UL_SRC_CON0_L,2277 UL_SRC_ON_TMP_CTL_SFT, 0,2278 NULL, 0),2279 2280 SND_SOC_DAPM_SUPPLY_S("UL_SRC_DMIC", SUPPLY_SEQ_UL_SRC_DMIC,2281 SND_SOC_NOPM, 0, 0,2282 mt_ul_src_dmic_event,2283 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),2284 2285 SND_SOC_DAPM_SUPPLY_S("UL_SRC_34", SUPPLY_SEQ_UL_SRC,2286 MT6359_AFE_ADDA6_UL_SRC_CON0_L,2287 ADDA6_UL_SRC_ON_TMP_CTL_SFT, 0,2288 NULL, 0),2289 2290 SND_SOC_DAPM_SUPPLY_S("UL_SRC_34_DMIC", SUPPLY_SEQ_UL_SRC_DMIC,2291 SND_SOC_NOPM, 0, 0,2292 mt_ul_src_34_dmic_event,2293 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),2294 2295 SND_SOC_DAPM_MUX("MISO0_MUX", SND_SOC_NOPM, 0, 0, &miso0_mux_control),2296 SND_SOC_DAPM_MUX("MISO1_MUX", SND_SOC_NOPM, 0, 0, &miso1_mux_control),2297 SND_SOC_DAPM_MUX("MISO2_MUX", SND_SOC_NOPM, 0, 0, &miso2_mux_control),2298 2299 SND_SOC_DAPM_MUX("UL_SRC_MUX", SND_SOC_NOPM, 0, 0,2300 &ul_src_mux_control),2301 SND_SOC_DAPM_MUX("UL2_SRC_MUX", SND_SOC_NOPM, 0, 0,2302 &ul2_src_mux_control),2303 2304 SND_SOC_DAPM_MUX("DMIC0_MUX", SND_SOC_NOPM, 0, 0, &dmic0_mux_control),2305 SND_SOC_DAPM_MUX("DMIC1_MUX", SND_SOC_NOPM, 0, 0, &dmic1_mux_control),2306 SND_SOC_DAPM_MUX("DMIC2_MUX", SND_SOC_NOPM, 0, 0, &dmic2_mux_control),2307 2308 SND_SOC_DAPM_MUX_E("ADC_L_Mux", SND_SOC_NOPM, 0, 0,2309 &adc_left_mux_control, NULL, 0),2310 SND_SOC_DAPM_MUX_E("ADC_R_Mux", SND_SOC_NOPM, 0, 0,2311 &adc_right_mux_control, NULL, 0),2312 SND_SOC_DAPM_MUX_E("ADC_3_Mux", SND_SOC_NOPM, 0, 0,2313 &adc_3_mux_control, NULL, 0),2314 2315 SND_SOC_DAPM_ADC("ADC_L", NULL, SND_SOC_NOPM, 0, 0),2316 SND_SOC_DAPM_ADC("ADC_R", NULL, SND_SOC_NOPM, 0, 0),2317 SND_SOC_DAPM_ADC("ADC_3", NULL, SND_SOC_NOPM, 0, 0),2318 2319 SND_SOC_DAPM_SUPPLY_S("ADC_L_EN", SUPPLY_SEQ_UL_ADC,2320 MT6359_AUDENC_ANA_CON0,2321 RG_AUDADCLPWRUP_SFT, 0,2322 mt_adc_l_event,2323 SND_SOC_DAPM_POST_PMU),2324 SND_SOC_DAPM_SUPPLY_S("ADC_R_EN", SUPPLY_SEQ_UL_ADC,2325 MT6359_AUDENC_ANA_CON1,2326 RG_AUDADCRPWRUP_SFT, 0,2327 mt_adc_r_event,2328 SND_SOC_DAPM_POST_PMU),2329 SND_SOC_DAPM_SUPPLY_S("ADC_3_EN", SUPPLY_SEQ_UL_ADC,2330 MT6359_AUDENC_ANA_CON2,2331 RG_AUDADC3PWRUP_SFT, 0,2332 mt_adc_3_event,2333 SND_SOC_DAPM_POST_PMU),2334 2335 SND_SOC_DAPM_MUX_E("PGA_L_Mux", SND_SOC_NOPM, 0, 0,2336 &pga_left_mux_control,2337 mt_pga_l_mux_event,2338 SND_SOC_DAPM_WILL_PMU),2339 SND_SOC_DAPM_MUX_E("PGA_R_Mux", SND_SOC_NOPM, 0, 0,2340 &pga_right_mux_control,2341 mt_pga_r_mux_event,2342 SND_SOC_DAPM_WILL_PMU),2343 SND_SOC_DAPM_MUX_E("PGA_3_Mux", SND_SOC_NOPM, 0, 0,2344 &pga_3_mux_control,2345 mt_pga_3_mux_event,2346 SND_SOC_DAPM_WILL_PMU),2347 2348 SND_SOC_DAPM_PGA("PGA_L", SND_SOC_NOPM, 0, 0, NULL, 0),2349 SND_SOC_DAPM_PGA("PGA_R", SND_SOC_NOPM, 0, 0, NULL, 0),2350 SND_SOC_DAPM_PGA("PGA_3", SND_SOC_NOPM, 0, 0, NULL, 0),2351 2352 SND_SOC_DAPM_SUPPLY_S("PGA_L_EN", SUPPLY_SEQ_UL_PGA,2353 MT6359_AUDENC_ANA_CON0,2354 RG_AUDPREAMPLON_SFT, 0,2355 mt_pga_l_event,2356 SND_SOC_DAPM_PRE_PMU |2357 SND_SOC_DAPM_POST_PMU |2358 SND_SOC_DAPM_POST_PMD),2359 SND_SOC_DAPM_SUPPLY_S("PGA_R_EN", SUPPLY_SEQ_UL_PGA,2360 MT6359_AUDENC_ANA_CON1,2361 RG_AUDPREAMPRON_SFT, 0,2362 mt_pga_r_event,2363 SND_SOC_DAPM_PRE_PMU |2364 SND_SOC_DAPM_POST_PMU |2365 SND_SOC_DAPM_POST_PMD),2366 SND_SOC_DAPM_SUPPLY_S("PGA_3_EN", SUPPLY_SEQ_UL_PGA,2367 MT6359_AUDENC_ANA_CON2,2368 RG_AUDPREAMP3ON_SFT, 0,2369 mt_pga_3_event,2370 SND_SOC_DAPM_PRE_PMU |2371 SND_SOC_DAPM_POST_PMU |2372 SND_SOC_DAPM_POST_PMD),2373 2374 /* UL input */2375 SND_SOC_DAPM_INPUT("AIN0"),2376 SND_SOC_DAPM_INPUT("AIN1"),2377 SND_SOC_DAPM_INPUT("AIN2"),2378 SND_SOC_DAPM_INPUT("AIN3"),2379 2380 SND_SOC_DAPM_INPUT("AIN0_DMIC"),2381 SND_SOC_DAPM_INPUT("AIN2_DMIC"),2382 SND_SOC_DAPM_INPUT("AIN3_DMIC"),2383 2384 /* mic bias */2385 SND_SOC_DAPM_SUPPLY_S("MIC_BIAS_0", SUPPLY_SEQ_MIC_BIAS,2386 MT6359_AUDENC_ANA_CON15,2387 RG_AUDPWDBMICBIAS0_SFT, 0,2388 mt_mic_bias_0_event,2389 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),2390 SND_SOC_DAPM_SUPPLY_S("MIC_BIAS_1", SUPPLY_SEQ_MIC_BIAS,2391 MT6359_AUDENC_ANA_CON16,2392 RG_AUDPWDBMICBIAS1_SFT, 0,2393 mt_mic_bias_1_event,2394 SND_SOC_DAPM_PRE_PMU),2395 SND_SOC_DAPM_SUPPLY_S("MIC_BIAS_2", SUPPLY_SEQ_MIC_BIAS,2396 MT6359_AUDENC_ANA_CON17,2397 RG_AUDPWDBMICBIAS2_SFT, 0,2398 mt_mic_bias_2_event,2399 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),2400 2401 /* dmic */2402 SND_SOC_DAPM_SUPPLY_S("DMIC_0", SUPPLY_SEQ_DMIC,2403 MT6359_AUDENC_ANA_CON13,2404 RG_AUDDIGMICEN_SFT, 0,2405 NULL, 0),2406 SND_SOC_DAPM_SUPPLY_S("DMIC_1", SUPPLY_SEQ_DMIC,2407 MT6359_AUDENC_ANA_CON14,2408 RG_AUDDIGMIC1EN_SFT, 0,2409 NULL, 0),2410};2411 2412static int mt_dcc_clk_connect(struct snd_soc_dapm_widget *source,2413 struct snd_soc_dapm_widget *sink)2414{2415 struct snd_soc_dapm_widget *w = sink;2416 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);2417 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);2418 2419 if (IS_DCC_BASE(priv->mux_select[MUX_MIC_TYPE_0]) ||2420 IS_DCC_BASE(priv->mux_select[MUX_MIC_TYPE_1]) ||2421 IS_DCC_BASE(priv->mux_select[MUX_MIC_TYPE_2]))2422 return 1;2423 else2424 return 0;2425}2426 2427static const struct snd_soc_dapm_route mt6359_dapm_routes[] = {2428 /* Capture */2429 {"AIFTX_Supply", NULL, "CLK_BUF"},2430 {"AIFTX_Supply", NULL, "vaud18"},2431 {"AIFTX_Supply", NULL, "AUDGLB"},2432 {"AIFTX_Supply", NULL, "CLKSQ Audio"},2433 {"AIFTX_Supply", NULL, "AUD_CK"},2434 {"AIFTX_Supply", NULL, "AUDIF_CK"},2435 {"AIFTX_Supply", NULL, "AUDIO_TOP_AFE_CTL"},2436 {"AIFTX_Supply", NULL, "AUDIO_TOP_PWR_CLK"},2437 {"AIFTX_Supply", NULL, "AUDIO_TOP_PDN_RESERVED"},2438 {"AIFTX_Supply", NULL, "AUDIO_TOP_I2S_DL"},2439 /*2440 * *_ADC_CTL should enable only if UL_SRC in use,2441 * but dm ck may be needed even UL_SRC_x not in use2442 */2443 {"AIFTX_Supply", NULL, "AUDIO_TOP_ADC_CTL"},2444 {"AIFTX_Supply", NULL, "AUDIO_TOP_ADDA6_ADC_CTL"},2445 {"AIFTX_Supply", NULL, "AFE_ON"},2446 2447 /* ul ch 12 */2448 {"AIF1TX", NULL, "AIF Out Mux"},2449 {"AIF1TX", NULL, "AIFTX_Supply"},2450 {"AIF1TX", NULL, "MTKAIF_TX"},2451 2452 {"AIF2TX", NULL, "AIF2 Out Mux"},2453 {"AIF2TX", NULL, "AIFTX_Supply"},2454 {"AIF2TX", NULL, "MTKAIF_TX"},2455 2456 {"AIF Out Mux", "Normal Path", "MISO0_MUX"},2457 {"AIF Out Mux", "Normal Path", "MISO1_MUX"},2458 {"AIF2 Out Mux", "Normal Path", "MISO2_MUX"},2459 2460 {"MISO0_MUX", "UL1_CH1", "UL_SRC_MUX"},2461 {"MISO0_MUX", "UL1_CH2", "UL_SRC_MUX"},2462 {"MISO0_MUX", "UL2_CH1", "UL2_SRC_MUX"},2463 {"MISO0_MUX", "UL2_CH2", "UL2_SRC_MUX"},2464 2465 {"MISO1_MUX", "UL1_CH1", "UL_SRC_MUX"},2466 {"MISO1_MUX", "UL1_CH2", "UL_SRC_MUX"},2467 {"MISO1_MUX", "UL2_CH1", "UL2_SRC_MUX"},2468 {"MISO1_MUX", "UL2_CH2", "UL2_SRC_MUX"},2469 2470 {"MISO2_MUX", "UL1_CH1", "UL_SRC_MUX"},2471 {"MISO2_MUX", "UL1_CH2", "UL_SRC_MUX"},2472 {"MISO2_MUX", "UL2_CH1", "UL2_SRC_MUX"},2473 {"MISO2_MUX", "UL2_CH2", "UL2_SRC_MUX"},2474 2475 {"MISO0_MUX", NULL, "UL_SRC"},2476 {"MISO1_MUX", NULL, "UL_SRC"},2477 {"MISO2_MUX", NULL, "UL_SRC_34"},2478 2479 {"UL_SRC_MUX", "AMIC", "ADC_L"},2480 {"UL_SRC_MUX", "AMIC", "ADC_R"},2481 {"UL_SRC_MUX", "DMIC", "DMIC0_MUX"},2482 {"UL_SRC_MUX", "DMIC", "DMIC1_MUX"},2483 {"UL_SRC_MUX", NULL, "UL_SRC"},2484 2485 {"UL2_SRC_MUX", "AMIC", "ADC_3"},2486 {"UL2_SRC_MUX", "DMIC", "DMIC2_MUX"},2487 {"UL2_SRC_MUX", NULL, "UL_SRC_34"},2488 2489 {"DMIC0_MUX", "DMIC_DATA0", "AIN0_DMIC"},2490 {"DMIC0_MUX", "DMIC_DATA1_L", "AIN2_DMIC"},2491 {"DMIC0_MUX", "DMIC_DATA1_L_1", "AIN2_DMIC"},2492 {"DMIC0_MUX", "DMIC_DATA1_R", "AIN3_DMIC"},2493 {"DMIC1_MUX", "DMIC_DATA0", "AIN0_DMIC"},2494 {"DMIC1_MUX", "DMIC_DATA1_L", "AIN2_DMIC"},2495 {"DMIC1_MUX", "DMIC_DATA1_L_1", "AIN2_DMIC"},2496 {"DMIC1_MUX", "DMIC_DATA1_R", "AIN3_DMIC"},2497 {"DMIC2_MUX", "DMIC_DATA0", "AIN0_DMIC"},2498 {"DMIC2_MUX", "DMIC_DATA1_L", "AIN2_DMIC"},2499 {"DMIC2_MUX", "DMIC_DATA1_L_1", "AIN2_DMIC"},2500 {"DMIC2_MUX", "DMIC_DATA1_R", "AIN3_DMIC"},2501 2502 {"DMIC0_MUX", NULL, "UL_SRC_DMIC"},2503 {"DMIC1_MUX", NULL, "UL_SRC_DMIC"},2504 {"DMIC2_MUX", NULL, "UL_SRC_34_DMIC"},2505 2506 {"AIN0_DMIC", NULL, "DMIC_0"},2507 {"AIN2_DMIC", NULL, "DMIC_1"},2508 {"AIN3_DMIC", NULL, "DMIC_1"},2509 {"AIN0_DMIC", NULL, "MIC_BIAS_0"},2510 {"AIN2_DMIC", NULL, "MIC_BIAS_2"},2511 {"AIN3_DMIC", NULL, "MIC_BIAS_2"},2512 2513 /* adc */2514 {"ADC_L", NULL, "ADC_L_Mux"},2515 {"ADC_L", NULL, "ADC_CLKGEN"},2516 {"ADC_L", NULL, "ADC_L_EN"},2517 {"ADC_R", NULL, "ADC_R_Mux"},2518 {"ADC_R", NULL, "ADC_CLKGEN"},2519 {"ADC_R", NULL, "ADC_R_EN"},2520 /*2521 * amic fifo ch1/2 clk from ADC_L,2522 * enable ADC_L even use ADC_R only2523 */2524 {"ADC_R", NULL, "ADC_L_EN"},2525 {"ADC_3", NULL, "ADC_3_Mux"},2526 {"ADC_3", NULL, "ADC_CLKGEN"},2527 {"ADC_3", NULL, "ADC_3_EN"},2528 2529 {"ADC_L_Mux", "Left Preamplifier", "PGA_L"},2530 {"ADC_R_Mux", "Right Preamplifier", "PGA_R"},2531 {"ADC_3_Mux", "Preamplifier", "PGA_3"},2532 2533 {"PGA_L", NULL, "PGA_L_Mux"},2534 {"PGA_L", NULL, "PGA_L_EN"},2535 {"PGA_R", NULL, "PGA_R_Mux"},2536 {"PGA_R", NULL, "PGA_R_EN"},2537 {"PGA_3", NULL, "PGA_3_Mux"},2538 {"PGA_3", NULL, "PGA_3_EN"},2539 2540 {"PGA_L", NULL, "DCC_CLK", mt_dcc_clk_connect},2541 {"PGA_R", NULL, "DCC_CLK", mt_dcc_clk_connect},2542 {"PGA_3", NULL, "DCC_CLK", mt_dcc_clk_connect},2543 2544 {"PGA_L_Mux", "AIN0", "AIN0"},2545 {"PGA_L_Mux", "AIN1", "AIN1"},2546 2547 {"PGA_R_Mux", "AIN0", "AIN0"},2548 {"PGA_R_Mux", "AIN2", "AIN2"},2549 {"PGA_R_Mux", "AIN3", "AIN3"},2550 2551 {"PGA_3_Mux", "AIN2", "AIN2"},2552 {"PGA_3_Mux", "AIN3", "AIN3"},2553 2554 {"AIN0", NULL, "MIC_BIAS_0"},2555 {"AIN1", NULL, "MIC_BIAS_1"},2556 {"AIN2", NULL, "MIC_BIAS_0"},2557 {"AIN2", NULL, "MIC_BIAS_2"},2558 {"AIN3", NULL, "MIC_BIAS_2"},2559 2560 /* DL Supply */2561 {"DL Power Supply", NULL, "CLK_BUF"},2562 {"DL Power Supply", NULL, "vaud18"},2563 {"DL Power Supply", NULL, "AUDGLB"},2564 {"DL Power Supply", NULL, "CLKSQ Audio"},2565 {"DL Power Supply", NULL, "AUDNCP_CK"},2566 {"DL Power Supply", NULL, "ZCD13M_CK"},2567 {"DL Power Supply", NULL, "AUD_CK"},2568 {"DL Power Supply", NULL, "AUDIF_CK"},2569 {"DL Power Supply", NULL, "ESD_RESIST"},2570 {"DL Power Supply", NULL, "LDO"},2571 {"DL Power Supply", NULL, "LDO_REMOTE"},2572 {"DL Power Supply", NULL, "NV_REGULATOR"},2573 {"DL Power Supply", NULL, "IBIST"},2574 2575 /* DL Digital Supply */2576 {"DL Digital Clock", NULL, "AUDIO_TOP_AFE_CTL"},2577 {"DL Digital Clock", NULL, "AUDIO_TOP_DAC_CTL"},2578 {"DL Digital Clock", NULL, "AUDIO_TOP_PWR_CLK"},2579 {"DL Digital Clock", NULL, "AUDIO_TOP_PDN_RESERVED"},2580 {"DL Digital Clock", NULL, "SDM_FIFO_CLK"},2581 {"DL Digital Clock", NULL, "NCP"},2582 {"DL Digital Clock", NULL, "AFE_ON"},2583 {"DL Digital Clock", NULL, "AFE_DL_SRC"},2584 2585 {"DL Digital Clock CH_1_2", NULL, "DL Digital Clock"},2586 {"DL Digital Clock CH_1_2", NULL, "SDM"},2587 2588 {"DL Digital Clock CH_3", NULL, "DL Digital Clock"},2589 {"DL Digital Clock CH_3", NULL, "SDM_3RD"},2590 2591 {"AIF_RX", NULL, "DL Digital Clock CH_1_2"},2592 2593 {"AIF2_RX", NULL, "DL Digital Clock CH_3"},2594 2595 /* DL Path */2596 {"DAC In Mux", "Normal Path", "AIF_RX"},2597 {"DAC In Mux", "Sgen", "SGEN DL"},2598 {"SGEN DL", NULL, "SGEN DL SRC"},2599 {"SGEN DL", NULL, "SGEN MUTE"},2600 {"SGEN DL", NULL, "SGEN DL Enable"},2601 {"SGEN DL", NULL, "DL Digital Clock CH_1_2"},2602 {"SGEN DL", NULL, "DL Digital Clock CH_3"},2603 {"SGEN DL", NULL, "AUDIO_TOP_PDN_AFE_TESTMODEL"},2604 2605 {"DACL", NULL, "DAC In Mux"},2606 {"DACL", NULL, "DL Power Supply"},2607 2608 {"DACR", NULL, "DAC In Mux"},2609 {"DACR", NULL, "DL Power Supply"},2610 2611 /* DAC 3RD */2612 {"DAC In Mux", "Normal Path", "AIF2_RX"},2613 {"DAC_3RD", NULL, "DAC In Mux"},2614 {"DAC_3RD", NULL, "DL Power Supply"},2615 2616 /* Lineout Path */2617 {"LOL Mux", "Playback", "DAC_3RD"},2618 {"LOL Mux", "Playback_L_DAC", "DACL"},2619 {"LINEOUT L", NULL, "LOL Mux"},2620 2621 /* Headphone Path */2622 {"HP_Supply", NULL, "HP_PULL_DOWN"},2623 {"HP_Supply", NULL, "HP_MUTE"},2624 {"HP_Supply", NULL, "HP_DAMP"},2625 {"HP Mux", NULL, "HP_Supply"},2626 2627 {"HP Mux", "Audio Playback", "DACL"},2628 {"HP Mux", "Audio Playback", "DACR"},2629 {"HP Mux", "HP Impedance", "DACL"},2630 {"HP Mux", "HP Impedance", "DACR"},2631 {"HP Mux", "LoudSPK Playback", "DACL"},2632 {"HP Mux", "LoudSPK Playback", "DACR"},2633 2634 {"Headphone L", NULL, "HP Mux"},2635 {"Headphone R", NULL, "HP Mux"},2636 {"Headphone L Ext Spk Amp", NULL, "HP Mux"},2637 {"Headphone R Ext Spk Amp", NULL, "HP Mux"},2638 2639 /* Receiver Path */2640 {"RCV Mux", "Voice Playback", "DACL"},2641 {"Receiver", NULL, "RCV Mux"},2642};2643 2644static int mt6359_codec_dai_hw_params(struct snd_pcm_substream *substream,2645 struct snd_pcm_hw_params *params,2646 struct snd_soc_dai *dai)2647{2648 struct snd_soc_component *cmpnt = dai->component;2649 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);2650 unsigned int rate = params_rate(params);2651 int id = dai->id;2652 2653 dev_dbg(priv->dev, "%s(), id %d, substream->stream %d, rate %d, number %d\n",2654 __func__, id, substream->stream, rate, substream->number);2655 2656 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)2657 priv->dl_rate[id] = rate;2658 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)2659 priv->ul_rate[id] = rate;2660 2661 return 0;2662}2663 2664static int mt6359_codec_dai_startup(struct snd_pcm_substream *substream,2665 struct snd_soc_dai *dai)2666{2667 struct snd_soc_component *cmpnt = dai->component;2668 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);2669 2670 dev_dbg(priv->dev, "%s stream %d\n", __func__, substream->stream);2671 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)2672 mt6359_set_playback_gpio(priv);2673 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)2674 mt6359_set_capture_gpio(priv);2675 2676 return 0;2677}2678 2679static void mt6359_codec_dai_shutdown(struct snd_pcm_substream *substream,2680 struct snd_soc_dai *dai)2681{2682 struct snd_soc_component *cmpnt = dai->component;2683 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);2684 2685 dev_dbg(priv->dev, "%s stream %d\n", __func__, substream->stream);2686 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)2687 mt6359_reset_playback_gpio(priv);2688 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)2689 mt6359_reset_capture_gpio(priv);2690}2691 2692static const struct snd_soc_dai_ops mt6359_codec_dai_ops = {2693 .hw_params = mt6359_codec_dai_hw_params,2694 .startup = mt6359_codec_dai_startup,2695 .shutdown = mt6359_codec_dai_shutdown,2696};2697 2698#define MT6359_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE |\2699 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_U24_LE |\2700 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE)2701 2702static struct snd_soc_dai_driver mt6359_dai_driver[] = {2703 {2704 .id = MT6359_AIF_1,2705 .name = "mt6359-snd-codec-aif1",2706 .playback = {2707 .stream_name = "AIF1 Playback",2708 .channels_min = 1,2709 .channels_max = 2,2710 .rates = SNDRV_PCM_RATE_8000_48000 |2711 SNDRV_PCM_RATE_96000 |2712 SNDRV_PCM_RATE_192000,2713 .formats = MT6359_FORMATS,2714 },2715 .capture = {2716 .stream_name = "AIF1 Capture",2717 .channels_min = 1,2718 .channels_max = 2,2719 .rates = SNDRV_PCM_RATE_8000 |2720 SNDRV_PCM_RATE_16000 |2721 SNDRV_PCM_RATE_32000 |2722 SNDRV_PCM_RATE_48000 |2723 SNDRV_PCM_RATE_96000 |2724 SNDRV_PCM_RATE_192000,2725 .formats = MT6359_FORMATS,2726 },2727 .ops = &mt6359_codec_dai_ops,2728 },2729 {2730 .id = MT6359_AIF_2,2731 .name = "mt6359-snd-codec-aif2",2732 .playback = {2733 .stream_name = "AIF2 Playback",2734 .channels_min = 1,2735 .channels_max = 2,2736 .rates = SNDRV_PCM_RATE_8000_48000 |2737 SNDRV_PCM_RATE_96000 |2738 SNDRV_PCM_RATE_192000,2739 .formats = MT6359_FORMATS,2740 },2741 .capture = {2742 .stream_name = "AIF2 Capture",2743 .channels_min = 1,2744 .channels_max = 2,2745 .rates = SNDRV_PCM_RATE_8000 |2746 SNDRV_PCM_RATE_16000 |2747 SNDRV_PCM_RATE_32000 |2748 SNDRV_PCM_RATE_48000,2749 .formats = MT6359_FORMATS,2750 },2751 .ops = &mt6359_codec_dai_ops,2752 },2753};2754 2755static int mt6359_codec_init_reg(struct snd_soc_component *cmpnt)2756{2757 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);2758 2759 /* enable clk buf */2760 regmap_update_bits(priv->regmap, MT6359_DCXO_CW12,2761 0x1 << RG_XO_AUDIO_EN_M_SFT,2762 0x1 << RG_XO_AUDIO_EN_M_SFT);2763 2764 /* set those not controlled by dapm widget */2765 2766 /* audio clk source from internal dcxo */2767 regmap_update_bits(priv->regmap, MT6359_AUDENC_ANA_CON23,2768 RG_CLKSQ_IN_SEL_TEST_MASK_SFT,2769 0x0);2770 2771 /* Disable HeadphoneL/HeadphoneR short circuit protection */2772 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON0,2773 RG_AUDHPLSCDISABLE_VAUDP32_MASK_SFT,2774 0x1 << RG_AUDHPLSCDISABLE_VAUDP32_SFT);2775 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON0,2776 RG_AUDHPRSCDISABLE_VAUDP32_MASK_SFT,2777 0x1 << RG_AUDHPRSCDISABLE_VAUDP32_SFT);2778 /* Disable voice short circuit protection */2779 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON6,2780 RG_AUDHSSCDISABLE_VAUDP32_MASK_SFT,2781 0x1 << RG_AUDHSSCDISABLE_VAUDP32_SFT);2782 /* disable LO buffer left short circuit protection */2783 regmap_update_bits(priv->regmap, MT6359_AUDDEC_ANA_CON7,2784 RG_AUDLOLSCDISABLE_VAUDP32_MASK_SFT,2785 0x1 << RG_AUDLOLSCDISABLE_VAUDP32_SFT);2786 2787 /* set gpio */2788 mt6359_set_gpio_smt(priv);2789 mt6359_set_gpio_driving(priv);2790 mt6359_reset_playback_gpio(priv);2791 mt6359_reset_capture_gpio(priv);2792 2793 /* hp hifi mode, default normal mode */2794 priv->hp_hifi_mode = 0;2795 2796 /* Disable AUD_ZCD */2797 zcd_disable(priv);2798 2799 /* disable clk buf */2800 regmap_update_bits(priv->regmap, MT6359_DCXO_CW12,2801 0x1 << RG_XO_AUDIO_EN_M_SFT,2802 0x0 << RG_XO_AUDIO_EN_M_SFT);2803 2804 return 0;2805}2806 2807static int mt6359_codec_probe(struct snd_soc_component *cmpnt)2808{2809 struct mt6359_priv *priv = snd_soc_component_get_drvdata(cmpnt);2810 2811 snd_soc_component_init_regmap(cmpnt, priv->regmap);2812 2813 return mt6359_codec_init_reg(cmpnt);2814}2815 2816static void mt6359_codec_remove(struct snd_soc_component *cmpnt)2817{2818 cmpnt->regmap = NULL;2819}2820 2821static const DECLARE_TLV_DB_SCALE(playback_tlv, -1000, 100, 0);2822static const DECLARE_TLV_DB_SCALE(capture_tlv, 0, 600, 0);2823 2824static const struct snd_kcontrol_new mt6359_snd_controls[] = {2825 /* dl pga gain */2826 SOC_DOUBLE_EXT_TLV("Headset Volume",2827 MT6359_ZCD_CON2, 0, 7, 0x12, 0,2828 mt6359_get_playback_volsw, mt6359_put_volsw,2829 playback_tlv),2830 SOC_DOUBLE_EXT_TLV("Lineout Volume",2831 MT6359_ZCD_CON1, 0, 7, 0x12, 0,2832 mt6359_get_playback_volsw, mt6359_put_volsw,2833 playback_tlv),2834 SOC_SINGLE_EXT_TLV("Handset Volume",2835 MT6359_ZCD_CON3, 0, 0x12, 0,2836 mt6359_get_playback_volsw, mt6359_put_volsw,2837 playback_tlv),2838 2839 /* ul pga gain */2840 SOC_SINGLE_EXT_TLV("PGA1 Volume",2841 MT6359_AUDENC_ANA_CON0, RG_AUDPREAMPLGAIN_SFT, 4, 0,2842 snd_soc_get_volsw, mt6359_put_volsw, capture_tlv),2843 SOC_SINGLE_EXT_TLV("PGA2 Volume",2844 MT6359_AUDENC_ANA_CON1, RG_AUDPREAMPRGAIN_SFT, 4, 0,2845 snd_soc_get_volsw, mt6359_put_volsw, capture_tlv),2846 SOC_SINGLE_EXT_TLV("PGA3 Volume",2847 MT6359_AUDENC_ANA_CON2, RG_AUDPREAMP3GAIN_SFT, 4, 0,2848 snd_soc_get_volsw, mt6359_put_volsw, capture_tlv),2849};2850 2851static const struct snd_soc_component_driver mt6359_soc_component_driver = {2852 .name = CODEC_MT6359_NAME,2853 .probe = mt6359_codec_probe,2854 .remove = mt6359_codec_remove,2855 .controls = mt6359_snd_controls,2856 .num_controls = ARRAY_SIZE(mt6359_snd_controls),2857 .dapm_widgets = mt6359_dapm_widgets,2858 .num_dapm_widgets = ARRAY_SIZE(mt6359_dapm_widgets),2859 .dapm_routes = mt6359_dapm_routes,2860 .num_dapm_routes = ARRAY_SIZE(mt6359_dapm_routes),2861 .endianness = 1,2862};2863 2864static int mt6359_parse_dt(struct mt6359_priv *priv)2865{2866 int ret;2867 struct device *dev = priv->dev;2868 struct device_node *np;2869 2870 np = of_get_child_by_name(dev->parent->of_node, "mt6359codec");2871 if (!np)2872 return -EINVAL;2873 2874 ret = of_property_read_u32(np, "mediatek,dmic-mode",2875 &priv->dmic_one_wire_mode);2876 if (ret) {2877 dev_info(priv->dev,2878 "%s() failed to read dmic-mode, use default (0)\n",2879 __func__);2880 priv->dmic_one_wire_mode = 0;2881 }2882 2883 ret = of_property_read_u32(np, "mediatek,mic-type-0",2884 &priv->mux_select[MUX_MIC_TYPE_0]);2885 if (ret) {2886 dev_info(priv->dev,2887 "%s() failed to read mic-type-0, use default (%d)\n",2888 __func__, MIC_TYPE_MUX_IDLE);2889 priv->mux_select[MUX_MIC_TYPE_0] = MIC_TYPE_MUX_IDLE;2890 }2891 2892 ret = of_property_read_u32(np, "mediatek,mic-type-1",2893 &priv->mux_select[MUX_MIC_TYPE_1]);2894 if (ret) {2895 dev_info(priv->dev,2896 "%s() failed to read mic-type-1, use default (%d)\n",2897 __func__, MIC_TYPE_MUX_IDLE);2898 priv->mux_select[MUX_MIC_TYPE_1] = MIC_TYPE_MUX_IDLE;2899 }2900 2901 ret = of_property_read_u32(np, "mediatek,mic-type-2",2902 &priv->mux_select[MUX_MIC_TYPE_2]);2903 of_node_put(np);2904 if (ret) {2905 dev_info(priv->dev,2906 "%s() failed to read mic-type-2, use default (%d)\n",2907 __func__, MIC_TYPE_MUX_IDLE);2908 priv->mux_select[MUX_MIC_TYPE_2] = MIC_TYPE_MUX_IDLE;2909 }2910 2911 return 0;2912}2913 2914static int mt6359_platform_driver_probe(struct platform_device *pdev)2915{2916 struct mt6359_priv *priv;2917 int ret;2918 struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent);2919 2920 dev_dbg(&pdev->dev, "%s(), dev name %s\n",2921 __func__, dev_name(&pdev->dev));2922 2923 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);2924 if (!priv)2925 return -ENOMEM;2926 2927 priv->regmap = mt6397->regmap;2928 if (IS_ERR(priv->regmap))2929 return PTR_ERR(priv->regmap);2930 2931 dev_set_drvdata(&pdev->dev, priv);2932 priv->dev = &pdev->dev;2933 2934 ret = mt6359_parse_dt(priv);2935 if (ret) {2936 dev_warn(&pdev->dev, "%s() failed to parse dts\n", __func__);2937 return ret;2938 }2939 2940 return devm_snd_soc_register_component(&pdev->dev,2941 &mt6359_soc_component_driver,2942 mt6359_dai_driver,2943 ARRAY_SIZE(mt6359_dai_driver));2944}2945 2946static struct platform_driver mt6359_platform_driver = {2947 .driver = {2948 .name = "mt6359-sound",2949 },2950 .probe = mt6359_platform_driver_probe,2951};2952 2953module_platform_driver(mt6359_platform_driver)2954 2955/* Module information */2956MODULE_DESCRIPTION("MT6359 ALSA SoC codec driver");2957MODULE_AUTHOR("KaiChieh Chuang <kaichieh.chuang@mediatek.com>");2958MODULE_AUTHOR("Eason Yen <eason.yen@mediatek.com>");2959MODULE_LICENSE("GPL v2");2960