Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/sound/soc/codecs/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 62 kB image not shown  

Quelle  mt6357.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/*
 * MT6357 ALSA SoC audio codec driver
 *
 * Copyright (c) 2024 Baylibre
 * Author: Nicolas Belin <nbelin@baylibre.com>
 */


#include <linux/dma-mapping.h>
#include <sound/soc.h>
#include <sound/tlv.h>
#include <linux/mfd/mt6397/core.h>
#include <linux/regulator/consumer.h>

#include "mt6357.h"

static void set_playback_gpio(struct mt6357_priv *priv, bool enable)
{
 regmap_write(priv->regmap, MT6357_GPIO_MODE2_CLR, MT6357_GPIO_MODE2_CLEAR_ALL);
 if (enable) {
  /* set gpio mosi mode */
  regmap_write(priv->regmap, MT6357_GPIO_MODE2_SET,
        MT6357_GPIO8_MODE_SET_AUD_CLK_MOSI |
        MT6357_GPIO9_MODE_SET_AUD_DAT_MOSI0 |
        MT6357_GPIO10_MODE_SET_AUD_DAT_MOSI1 |
        MT6357_GPIO11_MODE_SET_AUD_SYNC_MOSI);
 } else {
  /* pad_aud_*_mosi are GPIO mode after clear and set them to dir input
 * reason:
 * pad_aud_dat_mosi*, because the pin is used as boot strap
 */

  regmap_update_bits(priv->regmap, MT6357_GPIO_DIR0,
       MT6357_GPIO8_DIR_MASK |
       MT6357_GPIO9_DIR_MASK |
       MT6357_GPIO10_DIR_MASK |
       MT6357_GPIO11_DIR_MASK,
       MT6357_GPIO8_DIR_INPUT |
       MT6357_GPIO9_DIR_INPUT |
       MT6357_GPIO10_DIR_INPUT |
       MT6357_GPIO11_DIR_INPUT);
 }
}

static void set_capture_gpio(struct mt6357_priv *priv, bool enable)
{
 regmap_write(priv->regmap, MT6357_GPIO_MODE3_CLR, MT6357_GPIO_MODE3_CLEAR_ALL);
 if (enable) {
  /* set gpio miso mode */
  regmap_write(priv->regmap, MT6357_GPIO_MODE3_SET,
        MT6357_GPIO12_MODE_SET_AUD_CLK_MISO |
        MT6357_GPIO13_MODE_SET_AUD_DAT_MISO0 |
        MT6357_GPIO14_MODE_SET_AUD_DAT_MISO1 |
        MT6357_GPIO15_MODE_SET_AUD_SYNC_MISO);
 } else {
  /* pad_aud_*_mosi are GPIO mode after clear and set them to dir input
 * reason:
 * pad_aud_clk_miso, because when playback only the miso_clk
 * will also have 26m, so will have power leak
 * pad_aud_dat_miso*, because the pin is used as boot strap
 */

  regmap_update_bits(priv->regmap, MT6357_GPIO_DIR0,
       MT6357_GPIO12_DIR_MASK |
       MT6357_GPIO13_DIR_MASK |
       MT6357_GPIO14_DIR_MASK |
       MT6357_GPIO15_DIR_MASK,
       MT6357_GPIO12_DIR_INPUT |
       MT6357_GPIO13_DIR_INPUT |
       MT6357_GPIO14_DIR_INPUT |
       MT6357_GPIO15_DIR_INPUT);
 }
}

static void hp_main_output_ramp(struct mt6357_priv *priv, bool up)
{
 int i, stage;

 /* Enable/Reduce HPL/R main output stage step by step */
 for (i = 0; i <= MT6357_HPLOUT_STG_CTRL_VAUDP15_MAX; i++) {
  stage = up ? i : MT6357_HPLOUT_STG_CTRL_VAUDP15_MAX - i;
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
       MT6357_HPLOUT_STG_CTRL_VAUDP15_MASK,
       stage << MT6357_HPLOUT_STG_CTRL_VAUDP15_SFT);
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
       MT6357_HPROUT_STG_CTRL_VAUDP15_MASK,
       stage << MT6357_HPROUT_STG_CTRL_VAUDP15_SFT);
  usleep_range(600, 700);
 }
}

static void hp_aux_feedback_loop_gain_ramp(struct mt6357_priv *priv, bool up)
{
 int i, stage;

 /* Reduce HP aux feedback loop gain step by step */
 for (i = 0; i <= MT6357_HP_AUX_LOOP_GAIN_MAX; i++) {
  stage = up ? i : MT6357_HP_AUX_LOOP_GAIN_MAX - i;
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6,
       MT6357_HP_AUX_LOOP_GAIN_MASK,
       stage << MT6357_HP_AUX_LOOP_GAIN_SFT);
  usleep_range(600, 700);
 }
}

static void hp_pull_down(struct mt6357_priv *priv, bool enable)
{
 if (enable)
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON2,
       MT6357_HPP_SHORT_2VCM_VAUDP15_MASK,
       MT6357_HPP_SHORT_2VCM_VAUDP15_ENABLE);
 else
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON2,
       MT6357_HPP_SHORT_2VCM_VAUDP15_MASK,
       MT6357_HPP_SHORT_2VCM_VAUDP15_DISABLE);
}

static bool is_valid_hp_pga_idx(int reg_idx)
{
 return (reg_idx >= DL_GAIN_8DB && reg_idx <= DL_GAIN_N_12DB) || reg_idx == DL_GAIN_N_40DB;
}

static void volume_ramp(struct mt6357_priv *priv, int lfrom, int lto,
   int rfrom, int rto, unsigned int reg_addr)
{
 int lcount, rcount, sleep = 0;

 if (!is_valid_hp_pga_idx(lfrom) || !is_valid_hp_pga_idx(lto))
  pr_debug("%s(), invalid left volume index, from %d, to %d\n",
    __func__, lfrom, lto);

 if (!is_valid_hp_pga_idx(rfrom) || !is_valid_hp_pga_idx(rto))
  pr_debug("%s(), invalid right volume index, from %d, to %d\n",
    __func__, rfrom, rto);

 if (lto > lfrom)
  lcount = 1;
 else
  lcount = -1;

 if (rto > rfrom)
  rcount = 1;
 else
  rcount = -1;

 while ((lto != lfrom) || (rto != rfrom)) {
  if (lto != lfrom) {
   lfrom += lcount;
   if (is_valid_hp_pga_idx(lfrom)) {
    regmap_update_bits(priv->regmap, reg_addr,
         MT6357_DL_GAIN_REG_LEFT_MASK,
         lfrom << MT6357_DL_GAIN_REG_LEFT_SHIFT);
    sleep = 1;
   }
  }
  if (rto != rfrom) {
   rfrom += rcount;
   if (is_valid_hp_pga_idx(rfrom)) {
    regmap_update_bits(priv->regmap, reg_addr,
         MT6357_DL_GAIN_REG_RIGHT_MASK,
         rfrom << MT6357_DL_GAIN_REG_RIGHT_SHIFT);
    sleep = 1;
   }
  }
  if (sleep)
   usleep_range(200, 300);
 }
}

static void lo_volume_ramp(struct mt6357_priv *priv, int lfrom, int lto, int rfrom, int rto)
{
 volume_ramp(priv, lfrom, lto, rfrom, rto, MT6357_ZCD_CON1);
}

static void hp_volume_ramp(struct mt6357_priv *priv, int lfrom, int lto, int rfrom, int rto)
{
 volume_ramp(priv, lfrom, lto, rfrom, rto, MT6357_ZCD_CON2);
}

static void hs_volume_ramp(struct mt6357_priv *priv, int from, int to)
{
 volume_ramp(priv, from, to, 0, 0, MT6357_ZCD_CON3);
}

/* Volume and channel swap controls */
static const DECLARE_TLV_DB_SCALE(playback_tlv, -1000, 100, 0);
static const DECLARE_TLV_DB_SCALE(capture_tlv, 0, 600, 0);
static const DECLARE_TLV_DB_SCALE(hp_degain_tlv, -1200, 1200, 0);

static const struct snd_kcontrol_new mt6357_controls[] = {
 /* dl pga gain */
 SOC_DOUBLE_TLV("Headphone Volume",
         MT6357_ZCD_CON2, MT6357_AUD_HPL_GAIN_SFT,
         MT6357_AUD_HPR_GAIN_SFT, MT6357_AUD_HP_GAIN_MAX,
         1, playback_tlv),
 SOC_SINGLE_TLV("Headphone Vin Volume",
         MT6357_AUDDEC_ANA_CON7, MT6357_HP_IVBUF_DEGAIN_SFT,
         MT6357_HP_IVBUF_DEGAIN_MAX, 1, hp_degain_tlv),
 SOC_DOUBLE_TLV("Lineout Volume",
         MT6357_ZCD_CON1, MT6357_AUD_LOL_GAIN_SFT,
         MT6357_AUD_LOR_GAIN_SFT, MT6357_AUD_LO_GAIN_MAX,
         1, playback_tlv),
 SOC_SINGLE_TLV("Handset Volume",
         MT6357_ZCD_CON3, MT6357_AUD_HS_GAIN_SFT,
         MT6357_AUD_HS_GAIN_MAX, 1, playback_tlv),
 /* ul pga gain */
 SOC_DOUBLE_R_TLV("Mic Volume",
    MT6357_AUDENC_ANA_CON0, MT6357_AUDENC_ANA_CON1,
    MT6357_AUDPREAMPLGAIN_SFT, MT6357_AUDPREAMPLGAIN_MAX,
    0, capture_tlv),
};

/* Uplink controls */

enum {
 MIC_TYPE_MUX_IDLE,
 MIC_TYPE_MUX_ACC,
 MIC_TYPE_MUX_DMIC,
 MIC_TYPE_MUX_DCC,
 MIC_TYPE_MUX_DCC_ECM_DIFF,
 MIC_TYPE_MUX_DCC_ECM_SINGLE,
 MIC_TYPE_MUX_LPBK,
 MIC_TYPE_MUX_SGEN,
};

#define IS_DCC_BASE(type) ((type) == MIC_TYPE_MUX_DCC || \
   (type) == MIC_TYPE_MUX_DCC_ECM_DIFF || \
   (type) == MIC_TYPE_MUX_DCC_ECM_SINGLE)

static const char * const mic_type_mux_map[] = {
 "Idle",
 "ACC",
 "DMIC",
 "DCC",
 "DCC_ECM_DIFF",
 "DCC_ECM_SINGLE",
 "Loopback",
 "Sine Generator",
};

static SOC_ENUM_SINGLE_DECL(mic_type_mux_map_enum, SND_SOC_NOPM,
       0, mic_type_mux_map);

static const struct snd_kcontrol_new mic_type_mux_control =
 SOC_DAPM_ENUM("Mic Type Select", mic_type_mux_map_enum);

static const char * const pga_mux_map[] = {
 "None""AIN0""AIN1""AIN2"
};

static SOC_ENUM_SINGLE_DECL(pga_left_mux_map_enum,
       MT6357_AUDENC_ANA_CON0,
       MT6357_AUDPREAMPLINPUTSEL_SFT,
       pga_mux_map);

static const struct snd_kcontrol_new pga_left_mux_control =
 SOC_DAPM_ENUM("PGA L Select", pga_left_mux_map_enum);

static SOC_ENUM_SINGLE_DECL(pga_right_mux_map_enum,
       MT6357_AUDENC_ANA_CON1,
       MT6357_AUDPREAMPRINPUTSEL_SFT,
       pga_mux_map);

static const struct snd_kcontrol_new pga_right_mux_control =
 SOC_DAPM_ENUM("PGA R Select", pga_right_mux_map_enum);

/* Downlink controls */
static const char * const hslo_mux_map[] = {
 "Open""DACR""Playback""Test mode"
};

static SOC_ENUM_SINGLE_DECL(lo_mux_map_enum,
       MT6357_AUDDEC_ANA_CON4,
       MT6357_AUD_LOL_MUX_INPUT_VAUDP15_SFT,
       hslo_mux_map);

static const struct snd_kcontrol_new lo_mux_control =
 SOC_DAPM_ENUM("Line out source", lo_mux_map_enum);

static SOC_ENUM_SINGLE_DECL(hs_mux_map_enum,
       MT6357_AUDDEC_ANA_CON3,
       MT6357_AUD_HS_MUX_INPUT_VAUDP15_SFT,
       hslo_mux_map);

static const struct snd_kcontrol_new hs_mux_control =
 SOC_DAPM_ENUM("Handset source", hs_mux_map_enum);

static const char * const hplr_mux_map[] = {
 "Open""Line Out""DAC""Handset"
};

static SOC_ENUM_SINGLE_DECL(hpr_mux_map_enum,
       MT6357_AUDDEC_ANA_CON0,
       MT6357_AUD_HPR_MUX_INPUT_VAUDP15_SFT,
       hplr_mux_map);

static const struct snd_kcontrol_new hpr_mux_control =
 SOC_DAPM_ENUM("Headphone Right source", hpr_mux_map_enum);

static SOC_ENUM_SINGLE_DECL(hpl_mux_map_enum,
       MT6357_AUDDEC_ANA_CON0,
       MT6357_AUD_HPL_MUX_INPUT_VAUDP15_SFT,
       hplr_mux_map);

static const struct snd_kcontrol_new hpl_mux_control =
 SOC_DAPM_ENUM("Headphone Left source", hpl_mux_map_enum);

static const char * const dac_mux_map[] = {
 "Normal Path""Sine Generator"
};

static SOC_ENUM_SINGLE_DECL(dac_mux_map_enum,
       MT6357_AFE_TOP_CON0,
       MT6357_DL_SINE_ON_SFT,
       dac_mux_map);

static const struct snd_kcontrol_new dac_mux_control =
 SOC_DAPM_ENUM("DAC Select", dac_mux_map_enum);

static int mt6357_set_dmic(struct mt6357_priv *priv, bool enable)
{
 if (enable) {
  /* DMIC enable */
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON7,
       MT6357_AUDDIGMICBIAS_MASK | MT6357_AUDDIGMICEN_MASK,
       MT6357_AUDDIGMICBIAS_DEFAULT_VALUE | MT6357_AUDDIGMICEN_ENABLE);
  /* enable aud_pad TX fifos */
  regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP,
       MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK,
       MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_ENABLE);
  /* UL dmic setting: dual mode */
  regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_H,
       MT6357_C_TWO_DIGITAL_MIC_CTL_MASK,
       MT6357_C_TWO_DIGITAL_MIC_ENABLE);
  /* UL turn on SDM 3 level mode */
  regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L,
       MT6357_UL_SDM_3_LEVEL_CTL_MASK,
       MT6357_UL_SDM_3_LEVEL_SELECT);
  /* UL turn on */
  regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L,
       MT6357_UL_SRC_ON_TMP_CTL_MASK,
       MT6357_UL_SRC_ENABLE);
  /* Wait to avoid any pop noises */
  msleep(100);
 } else {
  /* UL turn off */
  regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L,
       MT6357_UL_SRC_ON_TMP_CTL_MASK,
       MT6357_UL_SRC_DISABLE);
  /* UL turn on SDM 3 level mode */
  regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L,
       MT6357_UL_SDM_3_LEVEL_CTL_MASK,
       MT6357_UL_SDM_3_LEVEL_DESELECT);
  /* disable aud_pad TX fifos */
  regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP,
       MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK,
       MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_DISABLE);
  /* UL dmic setting: dual mode */
  regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_H,
       MT6357_C_TWO_DIGITAL_MIC_CTL_MASK,
       MT6357_C_TWO_DIGITAL_MIC_DISABLE);
  /* DMIC disable */
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON7,
       MT6357_AUDDIGMICBIAS_MASK | MT6357_AUDDIGMICEN_MASK,
       MT6357_AUDDIGMICBIAS_OFF | MT6357_AUDDIGMICEN_DISABLE);
 }
 return 0;
}

static int mt6357_set_amic(struct mt6357_priv *priv, bool enable, unsigned int mic_type)
{
 if (enable) {
  if (IS_DCC_BASE(mic_type)) {
   regmap_update_bits(priv->regmap, MT6357_AFE_DCCLK_CFG0,
        MT6357_DCCLK_DIV_MASK, MT6357_DCCLK_DIV_RUN_VALUE);
   regmap_update_bits(priv->regmap, MT6357_AFE_DCCLK_CFG0,
        MT6357_DCCLK_PDN_MASK, MT6357_DCCLK_OUTPUT);
   regmap_update_bits(priv->regmap, MT6357_AFE_DCCLK_CFG0,
        MT6357_DCCLK_GEN_ON_MASK, MT6357_DCCLK_GEN_ON);
   regmap_update_bits(priv->regmap, MT6357_AFE_DCCLK_CFG1,
        MT6357_DCCLK_RESYNC_BYPASS_MASK,
        MT6357_DCCLK_RESYNC_BYPASS);

   /* mic bias 0: set the correct DC couple*/
   switch (mic_type) {
   case MIC_TYPE_MUX_DCC_ECM_DIFF:
    regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON8,
         MT6357_AUD_MICBIAS0_DC_MASK,
         MT6357_AUD_MICBIAS0_DC_ENABLE_ALL);
    break;
   case MIC_TYPE_MUX_DCC_ECM_SINGLE:
    regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON8,
         MT6357_AUD_MICBIAS0_DC_MASK,
         MT6357_AUD_MICBIAS0_DC_ENABLE_P1);
    break;
   default:
    regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON8,
         MT6357_AUD_MICBIAS0_DC_MASK,
         MT6357_AUD_MICBIAS0_DC_DISABLE_ALL);
    break;
   }

   /* mic bias 1: set the correct DC couple */
   if (mic_type == MIC_TYPE_MUX_DCC_ECM_SINGLE)
    regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON9,
         MT6357_AUD_MICBIAS1_DCSW1P_EN_MASK,
         MT6357_AUD_MICBIAS1_DCSW1P_ENABLE);

   /* Audio L/R preamplifier DCC precharge */
   regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
        MT6357_AUDPREAMPLDCPRECHARGE_MASK,
        MT6357_AUDPREAMPLDCPRECHARGE_ENABLE);
   regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
        MT6357_AUDPREAMPRDCPRECHARGE_MASK,
        MT6357_AUDPREAMPRDCPRECHARGE_ENABLE);
   /* L preamplifier DCCEN */
   regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
        MT6357_AUDPREAMPLDCCEN_MASK,
        MT6357_AUDPREAMPLDCCEN_DC);
   /* R preamplifier DCCEN */
   regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
        MT6357_AUDPREAMPRDCCEN_MASK,
        MT6357_AUDPREAMPRDCCEN_DC);
  } else {
   /* Audio L preamplifier DCC precharge disable */
   regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
        MT6357_AUDPREAMPLDCPRECHARGE_MASK,
        MT6357_AUDPREAMPLDCPRECHARGE_DISABLE);
   /* L preamplifier ACC */
   regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
        MT6357_AUDPREAMPLDCCEN_MASK,
        MT6357_AUDPREAMPLDCCEN_AC);
   /* Audio R preamplifier DCC precharge disable */
   regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
        MT6357_AUDPREAMPRDCPRECHARGE_MASK,
        MT6357_AUDPREAMPRDCPRECHARGE_DISABLE);
   /* R preamplifier ACC */
   regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
        MT6357_AUDPREAMPRDCCEN_MASK,
        MT6357_AUDPREAMPRDCCEN_AC);
  }
 } else {
  /* disable any Mic Bias 0 DC couple */
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON8,
       MT6357_AUD_MICBIAS0_DC_MASK,
       MT6357_AUD_MICBIAS0_DC_DISABLE_ALL);
  /* disable any Mic Bias 1 DC couple */
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON9,
       MT6357_AUD_MICBIAS1_DCSW1P_EN_MASK,
       MT6357_AUD_MICBIAS1_DCSW1P_DISABLE);
  if (IS_DCC_BASE(mic_type)) {
   regmap_update_bits(priv->regmap, MT6357_AFE_DCCLK_CFG0,
        MT6357_DCCLK_GEN_ON_MASK, MT6357_DCCLK_GEN_OFF);
   regmap_update_bits(priv->regmap, MT6357_AFE_DCCLK_CFG0,
        MT6357_DCCLK_PDN_MASK, MT6357_DCCLK_PDN);
   regmap_update_bits(priv->regmap, MT6357_AFE_DCCLK_CFG0,
        MT6357_DCCLK_DIV_MASK, MT6357_DCCLK_DIV_STOP_VALUE);
  }
 }

 return 0;
}

static int mt6357_set_loopback(struct mt6357_priv *priv, bool enable)
{
 if (enable) {
  /* enable aud_pad TX fifos */
  regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP,
       MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK,
       MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_ENABLE);
  /* enable aud_pad lpk TX fifos */
  regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP,
       MT6357_AUD_PAD_TX_FIFO_LPBK_MASK,
       MT6357_AUD_PAD_TX_FIFO_LPBK_ENABLE);
  /* Set UL Part: enable new lpbk 2 */
  regmap_update_bits(priv->regmap, MT6357_AFE_ADDA_MTKAIF_CFG0,
       MT6357_ADDA_MTKAIF_LPBK_CTL_MASK,
       MT6357_ADDA_MTKAIF_LPBK_ENABLE);
  /* UL turn on */
  regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L,
       MT6357_UL_SRC_ON_TMP_CTL_MASK,
       MT6357_UL_SRC_ENABLE);
 } else {
  /* UL turn off */
  regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L,
       MT6357_UL_SRC_ON_TMP_CTL_MASK,
       MT6357_UL_SRC_DISABLE);
  /* disable new lpbk 2 */
  regmap_update_bits(priv->regmap, MT6357_AFE_ADDA_MTKAIF_CFG0,
       MT6357_ADDA_MTKAIF_LPBK_CTL_MASK,
       MT6357_ADDA_MTKAIF_LPBK_DISABLE);
  /* disable aud_pad lpbk TX fifos */
  regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP,
       MT6357_AUD_PAD_TX_FIFO_LPBK_MASK,
       MT6357_AUD_PAD_TX_FIFO_LPBK_DISABLE);
  /* disable aud_pad TX fifos */
  regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP,
       MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK,
       MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_DISABLE);
 }

 return 0;
}

static int mt6357_set_ul_sine_gen(struct mt6357_priv *priv, bool enable)
{
 if (enable) {
  /* enable aud_pad TX fifos */
  regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP,
       MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK,
       MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_ENABLE);
  /* UL turn on */
  regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L,
       MT6357_UL_SRC_ON_TMP_CTL_MASK,
       MT6357_UL_SRC_ENABLE);
 } else {
  /* UL turn off */
  regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L,
       MT6357_UL_SRC_ON_TMP_CTL_MASK,
       MT6357_UL_SRC_DISABLE);
  /* disable aud_pad TX fifos */
  regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP,
       MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK,
       MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_DISABLE);
 }

 return 0;
}

static int mt_aif_out_event(struct snd_soc_dapm_widget *w,
       struct snd_kcontrol *kcontrol,
       int event)
{
 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);

 switch (event) {
 case SND_SOC_DAPM_PRE_PMU:
  set_capture_gpio(priv, true);
  break;
 case SND_SOC_DAPM_POST_PMD:
  set_capture_gpio(priv, false);
  break;
 default:
  break;
 }

 return 0;
}

static int mt_adc_supply_event(struct snd_soc_dapm_widget *w,
          struct snd_kcontrol *kcontrol,
          int event)
{
 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);

 switch (event) {
 case SND_SOC_DAPM_PRE_PMU:
  /* Enable audio ADC CLKGEN  */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON11,
       MT6357_RSTB_ENCODER_VA28_MASK, MT6357_RSTB_ENCODER_VA28_ENABLE);
  /* Enable  LCLDO_ENC 2P8V */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON12,
       MT6357_LCLDO_ENC_EN_VA28_MASK, MT6357_LCLDO_ENC_EN_VA28_ENABLE);
  /* LCLDO_ENC remote sense */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON12,
       MT6357_VA28REFGEN_EN_VA28_MASK |
       MT6357_LCLDO_ENC_REMOTE_SENSE_VA28_MASK,
       MT6357_VA28REFGEN_EN_VA28_ENABLE |
       MT6357_LCLDO_ENC_REMOTE_SENSE_VA28_ENABLE);
  break;
 case SND_SOC_DAPM_POST_PMD:
  /* LCLDO_ENC remote sense off */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON12,
       MT6357_VA28REFGEN_EN_VA28_MASK |
       MT6357_LCLDO_ENC_REMOTE_SENSE_VA28_MASK,
       MT6357_VA28REFGEN_EN_VA28_DISABLE |
       MT6357_LCLDO_ENC_REMOTE_SENSE_VA28_DISABLE);
  /* disable LCLDO_ENC 2P8V */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON12,
       MT6357_LCLDO_ENC_EN_VA28_MASK,
       MT6357_LCLDO_ENC_EN_VA28_DISABLE);
  /* disable audio ADC CLKGEN  */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON11,
       MT6357_RSTB_ENCODER_VA28_MASK,
       MT6357_RSTB_ENCODER_VA28_DISABLE);
  break;
 default:
  break;
 }

 return 0;
}

static int mt_mic_type_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol,
        int event)
{
 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);
 unsigned int mic_type = dapm_kcontrol_get_value(w->kcontrols[0]);

 switch (event) {
 case SND_SOC_DAPM_PRE_PMU:
  switch (mic_type) {
  case MIC_TYPE_MUX_DMIC:
   mt6357_set_dmic(priv, true);
   break;
  case MIC_TYPE_MUX_LPBK:
   mt6357_set_loopback(priv, true);
   break;
  case MIC_TYPE_MUX_SGEN:
   mt6357_set_ul_sine_gen(priv, true);
   break;
  default:
   mt6357_set_amic(priv, true, mic_type);
   break;
  }
  break;
 case SND_SOC_DAPM_POST_PMD:
  switch (mic_type) {
  case MIC_TYPE_MUX_DMIC:
   mt6357_set_dmic(priv, false);
   break;
  case MIC_TYPE_MUX_LPBK:
   mt6357_set_loopback(priv, false);
   break;
  case MIC_TYPE_MUX_SGEN:
   mt6357_set_ul_sine_gen(priv, false);
   break;
  default:
   mt6357_set_amic(priv, false, mic_type);
   break;
  }
  break;
 default:
  break;
 }

 return 0;
}

static int mt_pga_left_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol,
        int event)
{
 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);

 switch (event) {
 case SND_SOC_DAPM_POST_PMU:
  /* L preamplifier enable */
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
       MT6357_AUDPREAMPLON_MASK,
       MT6357_AUDPREAMPLON_ENABLE);
  /* L ADC input sel : L PGA. Enable audio L ADC */
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
       MT6357_AUDADCLINPUTSEL_MASK,
       MT6357_AUDADCLINPUTSEL_PREAMPLIFIER);
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
       MT6357_AUDADCLPWRUP_MASK,
       MT6357_AUDADCLPWRUP);
  /* Audio L preamplifier DCC precharge off */
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
       MT6357_AUDPREAMPLDCPRECHARGE_MASK,
       MT6357_AUDPREAMPLDCPRECHARGE_DISABLE);
  break;
 case SND_SOC_DAPM_PRE_PMD:
  /* Audio L ADC input sel : off, disable audio L ADC */
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
       MT6357_AUDADCLPWRUP_MASK,
       MT6357_AUDADCLPWRDOWN);
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
       MT6357_AUDADCLINPUTSEL_MASK,
       MT6357_AUDADCLINPUTSEL_IDLE);
  /* L preamplifier ACC */
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
       MT6357_AUDPREAMPLDCCEN_MASK,
       MT6357_AUDPREAMPLDCCEN_AC);
  /* L preamplifier disable */
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
       MT6357_AUDPREAMPLON_MASK,
       MT6357_AUDPREAMPLON_DISABLE);
  /* disable Audio L preamplifier DCC precharge */
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
       MT6357_AUDPREAMPLDCPRECHARGE_MASK,
       MT6357_AUDPREAMPLDCPRECHARGE_DISABLE);
  break;
 default:
  break;
 }

 return 0;
}

static int mt_pga_right_event(struct snd_soc_dapm_widget *w,
         struct snd_kcontrol *kcontrol,
         int event)
{
 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);

 switch (event) {
 case SND_SOC_DAPM_POST_PMU:
  /* R preamplifier enable */
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
       MT6357_AUDPREAMPRON_MASK, MT6357_AUDPREAMPRON_ENABLE);
  /* R ADC input sel : R PGA. Enable audio R ADC */
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
       MT6357_AUDADCRINPUTSEL_MASK,
       MT6357_AUDADCRINPUTSEL_PREAMPLIFIER);
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
       MT6357_AUDADCRPWRUP_MASK, MT6357_AUDADCRPWRUP);
  /* Audio R preamplifier DCC precharge off */
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
       MT6357_AUDPREAMPRDCPRECHARGE_MASK,
       MT6357_AUDPREAMPRDCPRECHARGE_DISABLE);
  break;
 case SND_SOC_DAPM_PRE_PMD:
  /* Audio R ADC input sel : off, disable audio R ADC */
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
       MT6357_AUDADCRPWRUP_MASK, MT6357_AUDADCRPWRDOWN);
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
       MT6357_AUDADCRINPUTSEL_MASK, MT6357_AUDADCRINPUTSEL_IDLE);
  /* R preamplifier ACC */
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
       MT6357_AUDPREAMPRDCCEN_MASK, MT6357_AUDPREAMPRDCCEN_AC);
  /* R preamplifier disable */
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
       MT6357_AUDPREAMPRON_MASK, MT6357_AUDPREAMPRON_DISABLE);
  /* disable Audio R preamplifier DCC precharge */
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
       MT6357_AUDPREAMPRDCPRECHARGE_MASK,
       MT6357_AUDPREAMPRDCPRECHARGE_DISABLE);
  break;
 default:
  break;
 }

 return 0;
}

static int adc_enable_event(struct snd_soc_dapm_widget *w,
       struct snd_kcontrol *kcontrol,
       int event)
{
 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);
 int lgain, rgain;

 switch (event) {
 case SND_SOC_DAPM_PRE_PMU:
  regmap_read(priv->regmap, MT6357_AUDENC_ANA_CON0, &lgain);
  regmap_read(priv->regmap, MT6357_AUDENC_ANA_CON1, &rgain);
  /* L PGA 0 dB gain */
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
       MT6357_AUDPREAMPLGAIN_MASK,
       UL_GAIN_0DB << MT6357_AUDPREAMPLGAIN_SFT);
  /* R PGA 0 dB gain */
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
       MT6357_AUDPREAMPRGAIN_MASK,
       UL_GAIN_0DB << MT6357_AUDPREAMPRGAIN_SFT);
  /* enable aud_pad TX fifos */
  regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP,
       MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK,
       MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_ENABLE);
  /* UL turn on */
  regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L,
       MT6357_UL_SRC_ON_TMP_CTL_MASK, MT6357_UL_SRC_ENABLE);
  /* Wait to avoid any pop noises */
  msleep(100);
  /* set the mic gains to the stored values */
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON0,
       MT6357_AUDPREAMPLGAIN_MASK, lgain);
  regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON1,
       MT6357_AUDPREAMPRGAIN_MASK, rgain);
  break;
 case SND_SOC_DAPM_POST_PMD:
  /* UL turn off */
  regmap_update_bits(priv->regmap, MT6357_AFE_UL_SRC_CON0_L,
       MT6357_UL_SRC_ON_TMP_CTL_MASK, MT6357_UL_SRC_DISABLE);
  /* disable aud_pad TX fifos */
  regmap_update_bits(priv->regmap, MT6357_AFE_AUD_PAD_TOP,
       MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_MASK,
       MT6357_AUD_PAD_TX_FIFO_NORMAL_PATH_DISABLE);
  break;
 default:
  break;
 }

 return 0;
}

static void configure_downlinks(struct mt6357_priv *priv, bool enable)
{
 if (enable) {
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ELR_0,
       MT6357_AUD_HP_TRIM_EN_VAUDP15_MASK,
       MT6357_AUD_HP_TRIM_EN_VAUDP15_ENABLE);
  /* Disable headphone short-circuit protection */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0,
       MT6357_AUD_HPR_SC_VAUDP15_MASK | MT6357_AUD_HPL_SC_VAUDP15_MASK,
       MT6357_AUD_HPR_SC_VAUDP15_DISABLE |
       MT6357_AUD_HPL_SC_VAUDP15_DISABLE);
  /* Disable handset short-circuit protection */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3,
       MT6357_AUD_HS_SC_VAUDP15_MASK,
       MT6357_AUD_HS_SC_VAUDP15_DISABLE);
  /* Disable lineout short-circuit protection */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4,
       MT6357_AUD_LOL_SC_VAUDP15_MASK,
       MT6357_AUD_LOL_SC_VAUDP15_DISABLE);
  /* Reduce ESD resistance of AU_REFN */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON2,
       MT6357_AUD_REFN_DERES_VAUDP15_MASK,
       MT6357_AUD_REFN_DERES_VAUDP15_ENABLE);
  /* Turn on DA_600K_NCP_VA18 */
  regmap_write(priv->regmap, MT6357_AUDNCP_CLKDIV_CON1, MT6357_DIVCKS_ON);
  /* Set NCP clock as 604kHz // 26MHz/43 = 604KHz */
  regmap_write(priv->regmap, MT6357_AUDNCP_CLKDIV_CON2, 0x002c);
  /* Toggle DIVCKS_CHG */
  regmap_write(priv->regmap, MT6357_AUDNCP_CLKDIV_CON0, MT6357_DIVCKS_CHG);
  /* Set NCP soft start mode as default mode: 150us */
  regmap_write(priv->regmap, MT6357_AUDNCP_CLKDIV_CON4,
        MT6357_DIVCKS_PWD_NCP_ST_150US);
  /* Enable NCP */
  regmap_write(priv->regmap, MT6357_AUDNCP_CLKDIV_CON3,
        MT6357_DIVCKS_PWD_NCP_ENABLE);
  usleep_range(250, 270);
  /* Enable cap-less LDOs (1.5V) */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON12,
       MT6357_VA33REFGEN_EN_VA18_MASK |
       MT6357_LCLDO_REMOTE_SENSE_VA18_MASK |
       MT6357_LCLDO_EN_VA18_MASK |
       MT6357_HCLDO_REMOTE_SENSE_VA18_MASK |
       MT6357_HCLDO_EN_VA18_MASK,
       MT6357_VA33REFGEN_EN_VA18_ENABLE |
       MT6357_LCLDO_REMOTE_SENSE_VA18_ENABLE |
       MT6357_LCLDO_EN_VA18_ENABLE |
       MT6357_HCLDO_REMOTE_SENSE_VA18_ENABLE |
       MT6357_HCLDO_EN_VA18_ENABLE);
  /* Enable NV regulator (-1.2V) */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON13,
       MT6357_NVREG_EN_VAUDP15_MASK, MT6357_NVREG_EN_VAUDP15_ENABLE);
  usleep_range(100, 120);
  /* Enable IBIST */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON10,
       MT6357_AUD_IBIAS_PWRDN_VAUDP15_MASK,
       MT6357_AUD_IBIAS_PWRDN_VAUDP15_ENABLE);
  /* Enable AUD_CLK */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON11,
       MT6357_RSTB_DECODER_VA28_MASK,
       MT6357_RSTB_DECODER_VA28_ENABLE);
  /* Enable low-noise mode of DAC */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6,
       MT6357_DAC_LOW_NOISE_MODE_MASK,
       MT6357_DAC_LOW_NOISE_MODE_ENABLE);
  usleep_range(100, 120);
 } else {
  /* Disable low-noise mode of DAC */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6,
       MT6357_DAC_LOW_NOISE_MODE_MASK,
       MT6357_DAC_LOW_NOISE_MODE_DISABLE);
  /* Disable AUD_CLK */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON11,
       MT6357_RSTB_DECODER_VA28_MASK,
       MT6357_RSTB_DECODER_VA28_DISABLE);
  /* Enable linout short-circuit protection */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4,
       MT6357_AUD_LOL_SC_VAUDP15_MASK,
       MT6357_AUD_LOL_SC_VAUDP15_ENABLE);
  /* Enable handset short-circuit protection */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3,
       MT6357_AUD_HS_SC_VAUDP15_MASK,
       MT6357_AUD_HS_SC_VAUDP15_ENABLE);
  /* Enable headphone short-circuit protection */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0,
       MT6357_AUD_HPR_SC_VAUDP15_MASK |
       MT6357_AUD_HPL_SC_VAUDP15_MASK,
       MT6357_AUD_HPR_SC_VAUDP15_ENABLE |
       MT6357_AUD_HPL_SC_VAUDP15_ENABLE);
  /* Disable IBIST */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON10,
       MT6357_AUD_IBIAS_PWRDN_VAUDP15_MASK,
       MT6357_AUD_IBIAS_PWRDN_VAUDP15_DISABLE);
  /* Disable NV regulator (-1.2V) */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON13,
       MT6357_NVREG_EN_VAUDP15_MASK,
       MT6357_NVREG_EN_VAUDP15_DISABLE);
  /* Disable cap-less LDOs (1.5V) */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON12,
       MT6357_VA33REFGEN_EN_VA18_MASK |
       MT6357_LCLDO_REMOTE_SENSE_VA18_MASK |
       MT6357_LCLDO_EN_VA18_MASK |
       MT6357_HCLDO_REMOTE_SENSE_VA18_MASK |
       MT6357_HCLDO_EN_VA18_MASK,
       MT6357_VA33REFGEN_EN_VA18_DISABLE |
       MT6357_LCLDO_REMOTE_SENSE_VA18_DISABLE |
       MT6357_LCLDO_EN_VA18_DISABLE |
       MT6357_HCLDO_REMOTE_SENSE_VA18_DISABLE |
       MT6357_HCLDO_EN_VA18_DISABLE);
  /* Disable NCP */
  regmap_update_bits(priv->regmap, MT6357_AUDNCP_CLKDIV_CON3,
       MT6357_DIVCKS_PWD_NCP_MASK, MT6357_DIVCKS_PWD_NCP_DISABLE);
 }
}

static int mt_audio_in_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol,
        int event)
{
 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);

 switch (event) {
 case SND_SOC_DAPM_PRE_PMU:
  set_playback_gpio(priv, true);

  /* Pull-down HPL/R to AVSS28_AUD */
  if (priv->pull_down_needed)
   hp_pull_down(priv, true);

  /* Disable HP main CMFB Switch */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6,
       MT6357_HPRL_MAIN_CMFB_LOOP_MASK,
       MT6357_HPRL_MAIN_CMFB_LOOP_DISABLE);
  /* Audio system digital clock power down release */
  regmap_write(priv->regmap, MT6357_AFUNC_AUD_CON2,
        MT6357_CCI_AUDIO_FIFO_DISABLE |
        MT6357_CCI_ACD_MODE_NORMAL_PATH |
        MT6357_CCI_AFIFO_CLK_PWDB_ON |
        MT6357_CCI_ACD_FUNC_RSTB_RESET);
  /* sdm audio fifo clock power on */
  regmap_write(priv->regmap, MT6357_AFUNC_AUD_CON0,
        MT6357_CCI_AUD_ANACK_INVERT |
        (4 << MT6357_CCI_AUDIO_FIFO_WPTR_SFT) |
        MT6357_CCI_SCRAMBLER_CG_ENABLE |
        MT6357_CCI_RAND_ENABLE |
        MT6357_CCI_SPLT_SCRMB_CLK_ON |
        MT6357_CCI_SPLT_SCRMB_ON |
        MT6357_CCI_ZERO_PADDING_DISABLE |
        MT6357_CCI_SCRAMBLER_ENABLE);
  /* scrambler clock on enable */
  regmap_write(priv->regmap, MT6357_AFUNC_AUD_CON2,
        MT6357_CCI_AUDIO_FIFO_DISABLE |
        MT6357_CCI_ACD_MODE_TEST_PATH |
        MT6357_CCI_AFIFO_CLK_PWDB_ON |
        MT6357_CCI_ACD_FUNC_RSTB_RELEASE);
  /* sdm power on */
  regmap_write(priv->regmap, MT6357_AFUNC_AUD_CON2,
        MT6357_CCI_AUDIO_FIFO_ENABLE |
        MT6357_CCI_ACD_MODE_TEST_PATH |
        MT6357_CCI_AFIFO_CLK_PWDB_ON |
        MT6357_CCI_ACD_FUNC_RSTB_RELEASE);

  configure_downlinks(priv, true);
  break;
 case SND_SOC_DAPM_POST_PMD:
  configure_downlinks(priv, false);
  /* DL scrambler disabling sequence */
  regmap_write(priv->regmap, MT6357_AFUNC_AUD_CON2,
        MT6357_CCI_AUDIO_FIFO_DISABLE |
        MT6357_CCI_ACD_MODE_TEST_PATH |
        MT6357_CCI_AFIFO_CLK_PWDB_DOWN |
        MT6357_CCI_ACD_FUNC_RSTB_RESET);
  regmap_write(priv->regmap, MT6357_AFUNC_AUD_CON0,
        MT6357_CCI_AUD_ANACK_INVERT |
        (4 << MT6357_CCI_AUDIO_FIFO_WPTR_SFT) |
        MT6357_CCI_SCRAMBLER_CG_ENABLE |
        MT6357_CCI_RAND_ENABLE |
        MT6357_CCI_SPLT_SCRMB_CLK_ON |
        MT6357_CCI_SPLT_SCRMB_ON |
        MT6357_CCI_ZERO_PADDING_DISABLE |
        MT6357_CCI_SCRAMBLER_DISABLE);

  set_playback_gpio(priv, false);

  /* disable Pull-down HPL/R to AVSS28_AUD */
  if (priv->pull_down_needed)
   hp_pull_down(priv, false);
  break;
 default:
  break;
 }

 return 0;
}

static int mt_delay_250_event(struct snd_soc_dapm_widget *w,
         struct snd_kcontrol *kcontrol,
         int event)
{
 switch (event) {
 case SND_SOC_DAPM_POST_PMU:
  usleep_range(250, 270);
  break;
 case SND_SOC_DAPM_PRE_PMD:
  usleep_range(250, 270);
  break;
 default:
  break;
 }

 return 0;
}

static int lo_mux_event(struct snd_soc_dapm_widget *w,
   struct snd_kcontrol *kcontrol,
   int event)
{
 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);
 int lgain, rgain;

 /* Get current gain value */
 regmap_read(priv->regmap, MT6357_ZCD_CON1, &lgain);
 rgain = (lgain & MT6357_AUD_LOR_GAIN_MASK) >> MT6357_AUD_LOR_GAIN_SFT;
 lgain = lgain & MT6357_AUD_LOL_GAIN_MASK;
 switch (event) {
 case SND_SOC_DAPM_POST_PMU:
  /* Set -40dB before enable HS to avoid POP noise */
  regmap_update_bits(priv->regmap, MT6357_ZCD_CON1,
       MT6357_AUD_LOL_GAIN_MASK |
       MT6357_AUD_LOR_GAIN_MASK,
       MT6357_DL_GAIN_N_40DB_REG);
  /* Set LO STB enhance circuits */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4,
       MT6357_AUD_LOLOUT_STB_ENH_VAUDP15_MASK,
       MT6357_AUD_LOLOUT_STB_ENH_VAUDP15_ENABLE);
  /* Enable LO driver bias circuits */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4,
       MT6357_AUD_LOL_PWRUP_BIAS_VAUDP15_MASK,
       MT6357_AUD_LOL_PWRUP_BIAS_VAUDP15_ENABLE);
  /* Enable LO driver core circuits */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4,
       MT6357_AUD_LOL_PWRUP_VAUDP15_MASK,
       MT6357_AUD_LOL_PWRUP_VAUDP15_ENABLE);
  /* Set LOL gain to normal gain step by step */
  lo_volume_ramp(priv, DL_GAIN_N_40DB, lgain,
          DL_GAIN_N_40DB, rgain);
  break;
 case SND_SOC_DAPM_PRE_PMD:
  /* decrease LOL gain to minimum gain step by step */

  lo_volume_ramp(priv, lgain, DL_GAIN_N_40DB,
          rgain, DL_GAIN_N_40DB);
  /* Disable LO driver core circuits */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4,
       MT6357_AUD_LOL_PWRUP_VAUDP15_MASK,
       MT6357_AUD_LOL_PWRUP_VAUDP15_DISABLE);
  /* Disable LO driver bias circuits */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4,
       MT6357_AUD_LOL_PWRUP_BIAS_VAUDP15_MASK,
       MT6357_AUD_LOL_PWRUP_BIAS_VAUDP15_DISABLE);
  /* Clear LO STB enhance circuits */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4,
       MT6357_AUD_LOLOUT_STB_ENH_VAUDP15_MASK,
       MT6357_AUD_LOLOUT_STB_ENH_VAUDP15_DISABLE);
  /* Save the gain value into the register*/
  regmap_update_bits(priv->regmap, MT6357_ZCD_CON1,
       MT6357_AUD_LOL_GAIN_MASK |
       MT6357_AUD_LOR_GAIN_MASK,
       lgain << MT6357_AUD_LOL_GAIN_SFT |
       rgain << MT6357_AUD_LOR_GAIN_SFT);

  break;
 default:
  break;
 }

 return 0;
}

static int hs_mux_event(struct snd_soc_dapm_widget *w,
   struct snd_kcontrol *kcontrol,
   int event)
{
 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);
 int gain; /* HS register has only one gain slot */

 /* Get current gain value */
 regmap_read(priv->regmap, MT6357_ZCD_CON3, &gain);
 switch (event) {
 case SND_SOC_DAPM_POST_PMU:
  /* Set -40dB before enable HS to avoid POP noise */
  regmap_update_bits(priv->regmap, MT6357_ZCD_CON3,
       MT6357_AUD_HS_GAIN_MASK,
       DL_GAIN_N_40DB);

  /* Set HS STB enhance circuits */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3,
       MT6357_AUD_HSOUT_STB_ENH_VAUDP15_MASK,
       MT6357_AUD_HSOUT_STB_ENH_VAUDP15_ENABLE);
  /* Enable HS driver bias circuits */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3,
       MT6357_AUD_HS_PWRUP_BIAS_VAUDP15_MASK,
       MT6357_AUD_HS_PWRUP_BIAS_VAUDP15_ENABLE);
  /* Enable HS driver core circuits */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3,
       MT6357_AUD_HS_PWRUP_VAUDP15_MASK,
       MT6357_AUD_HS_PWRUP_VAUDP15_ENABLE);
  /* Set HS gain to normal gain step by step */
  hs_volume_ramp(priv, DL_GAIN_N_40DB, gain);
  break;
 case SND_SOC_DAPM_PRE_PMD:
  /* decrease HS gain to minimum gain step by step */
  hs_volume_ramp(priv,  gain, DL_GAIN_N_40DB);
  /* Disable HS driver core circuits */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3,
       MT6357_AUD_HS_PWRUP_VAUDP15_MASK,
       MT6357_AUD_HS_PWRUP_VAUDP15_DISABLE);
  /* Disable HS driver bias circuits */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3,
       MT6357_AUD_HS_PWRUP_BIAS_VAUDP15_MASK,
       MT6357_AUD_HS_PWRUP_BIAS_VAUDP15_ENABLE);
  /* Clear HS STB enhance circuits */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3,
       MT6357_AUD_HSOUT_STB_ENH_VAUDP15_MASK,
       MT6357_AUD_HSOUT_STB_ENH_VAUDP15_DISABLE);
  /* Save the gain value into the register*/
  regmap_update_bits(priv->regmap, MT6357_ZCD_CON3,
       MT6357_AUD_HS_GAIN_MASK, gain);
  break;
 default:
  break;
 }

 return 0;
}

static int hp_main_mux_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *kcontrol,
        int event)
{
 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);
 int lgain, rgain;

 /* Get current gain value */
 regmap_read(priv->regmap, MT6357_ZCD_CON2, &lgain);
 rgain = (lgain & MT6357_AUD_HPR_GAIN_MASK) >> MT6357_AUD_HPR_GAIN_SFT;
 lgain = lgain & MT6357_AUD_HPL_GAIN_MASK;
 switch (event) {
 case SND_SOC_DAPM_POST_PMU:
  priv->hp_channel_number++;
  if (priv->hp_channel_number > 1)
   break;
  /* Set -40dB before enable HS to avoid POP noise */
  regmap_update_bits(priv->regmap, MT6357_ZCD_CON2,
       MT6357_AUD_HPL_GAIN_MASK |
       MT6357_AUD_HPR_GAIN_MASK,
       MT6357_DL_GAIN_N_40DB_REG);
  /* Set HPP/N STB enhance circuits */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON2,
       MT6357_HPROUT_STB_ENH_VAUDP15_MASK |
       MT6357_HPLOUT_STB_ENH_VAUDP15_MASK,
       MT6357_HPROUT_STB_ENH_VAUDP15_N470_P250 |
       MT6357_HPLOUT_STB_ENH_VAUDP15_N470_P250);
  /* Enable HP aux output stage */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
       MT6357_HPROUT_AUX_PWRUP_VAUDP15_MASK |
       MT6357_HPLOUT_AUX_PWRUP_VAUDP15_MASK,
       MT6357_HPROUT_AUX_PWRUP_VAUDP15_ENABLE |
       MT6357_HPLOUT_AUX_PWRUP_VAUDP15_ENABLE);
  /* Enable HP aux feedback loop */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
       MT6357_HPR_AUX_FBRSW_VAUDP15_MASK |
       MT6357_HPL_AUX_FBRSW_VAUDP15_MASK,
       MT6357_HPR_AUX_FBRSW_VAUDP15_ENABLE |
       MT6357_HPL_AUX_FBRSW_VAUDP15_ENABLE);
  /* Enable HP aux CMFB loop */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6,
       MT6357_HP_CMFB_RST_MASK |
       MT6357_HPL_AUX_CMFB_LOOP_MASK |
       MT6357_HPR_AUX_CMFB_LOOP_MASK,
       MT6357_HP_CMFB_RST_NORMAL |
       MT6357_HPL_AUX_CMFB_LOOP_ENABLE |
       MT6357_HPR_AUX_CMFB_LOOP_ENABLE);
  /* Enable HP driver bias circuits */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0,
       MT6357_AUD_HPR_BIAS_VAUDP15_MASK |
       MT6357_AUD_HPL_BIAS_VAUDP15_MASK,
       MT6357_AUD_HPR_BIAS_VAUDP15_ENABLE |
       MT6357_AUD_HPL_BIAS_VAUDP15_ENABLE);
  /* Enable HP driver core circuits */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0,
       MT6357_AUD_HPR_PWRUP_VAUDP15_MASK |
       MT6357_AUD_HPL_PWRUP_VAUDP15_MASK,
       MT6357_AUD_HPR_PWRUP_VAUDP15_ENABLE |
       MT6357_AUD_HPL_PWRUP_VAUDP15_ENABLE);
  /* Short HP main output to HP aux output stage */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
       MT6357_HPR_SHORT2HPR_AUX_VAUDP15_MASK |
       MT6357_HPL_SHORT2HPR_AUX_VAUDP15_MASK,
       MT6357_HPR_SHORT2HPR_AUX_VAUDP15_ENABLE |
       MT6357_HPL_SHORT2HPR_AUX_VAUDP15_ENABLE);
  /* Enable HP main CMFB loop */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6,
       MT6357_HPRL_MAIN_CMFB_LOOP_MASK,
       MT6357_HPRL_MAIN_CMFB_LOOP_ENABLE);
  /* Disable HP aux CMFB loop */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6,
       MT6357_HPR_AUX_CMFB_LOOP_MASK |
       MT6357_HPL_AUX_CMFB_LOOP_MASK,
       MT6357_HPR_AUX_CMFB_LOOP_DISABLE |
       MT6357_HPL_AUX_CMFB_LOOP_DISABLE);
  /* Enable HP main output stage */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
       MT6357_HPROUT_PWRUP_VAUDP15_MASK |
       MT6357_HPLOUT_PWRUP_VAUDP15_MASK,
       MT6357_HPROUT_PWRUP_VAUDP15_ENABLE |
       MT6357_HPLOUT_PWRUP_VAUDP15_ENABLE);
  /* Enable HPR/L main output stage step by step */
  hp_main_output_ramp(priv, true);
  usleep_range(1000, 1200);
  /* Reduce HP aux feedback loop gain */
  hp_aux_feedback_loop_gain_ramp(priv, true);
  /* Disable HP aux feedback loop */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
       MT6357_HPR_AUX_FBRSW_VAUDP15_MASK |
       MT6357_HPL_AUX_FBRSW_VAUDP15_MASK,
       MT6357_HPR_AUX_FBRSW_VAUDP15_DISABLE |
       MT6357_HPL_AUX_FBRSW_VAUDP15_DISABLE);
  /* apply volume setting */
  hp_volume_ramp(priv, DL_GAIN_N_40DB, lgain,
          DL_GAIN_N_40DB, rgain);
  /* Disable HP aux output stage */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
       MT6357_HPROUT_AUX_PWRUP_VAUDP15_MASK |
       MT6357_HPLOUT_AUX_PWRUP_VAUDP15_MASK,
       MT6357_HPROUT_AUX_PWRUP_VAUDP15_DISABLE |
       MT6357_HPLOUT_AUX_PWRUP_VAUDP15_DISABLE);
  /* Unshort HP main output to HP aux output stage */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
       MT6357_HPR_SHORT2HPR_AUX_VAUDP15_MASK |
       MT6357_HPL_SHORT2HPR_AUX_VAUDP15_MASK,
       MT6357_HPR_SHORT2HPR_AUX_VAUDP15_DISABLE |
       MT6357_HPL_SHORT2HPR_AUX_VAUDP15_DISABLE);
  usleep_range(100, 120);
  break;
 case SND_SOC_DAPM_PRE_PMD:
  priv->hp_channel_number--;
  if (priv->hp_channel_number > 0)
   break;
  /* Short HP main output to HP aux output stage */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
       MT6357_HPR_SHORT2HPR_AUX_VAUDP15_MASK |
       MT6357_HPL_SHORT2HPR_AUX_VAUDP15_MASK,
       MT6357_HPR_SHORT2HPR_AUX_VAUDP15_ENABLE |
       MT6357_HPL_SHORT2HPR_AUX_VAUDP15_ENABLE);
  /* Enable HP aux output stage */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
       MT6357_HPROUT_AUX_PWRUP_VAUDP15_MASK |
       MT6357_HPLOUT_AUX_PWRUP_VAUDP15_MASK,
       MT6357_HPROUT_AUX_PWRUP_VAUDP15_ENABLE |
       MT6357_HPLOUT_AUX_PWRUP_VAUDP15_ENABLE);
  /* decrease HPL/R gain to normal gain step by step */
  hp_volume_ramp(priv, lgain, DL_GAIN_N_40DB,
          rgain, DL_GAIN_N_40DB);
  /* Enable HP aux feedback loop */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
       MT6357_HPR_AUX_FBRSW_VAUDP15_MASK |
       MT6357_HPL_AUX_FBRSW_VAUDP15_MASK,
       MT6357_HPR_AUX_FBRSW_VAUDP15_ENABLE |
       MT6357_HPL_AUX_FBRSW_VAUDP15_ENABLE);
  /* Reduce HP aux feedback loop gain */
  hp_aux_feedback_loop_gain_ramp(priv, false);
  /* decrease HPR/L main output stage step by step */
  hp_main_output_ramp(priv, false);
  /* Disable HP main output stage */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
       MT6357_HPROUT_PWRUP_VAUDP15_MASK |
       MT6357_HPLOUT_PWRUP_VAUDP15_MASK,
       MT6357_HPROUT_PWRUP_VAUDP15_DISABLE |
       MT6357_HPLOUT_PWRUP_VAUDP15_DISABLE);
  /* Enable HP aux CMFB loop */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6,
       MT6357_HP_CMFB_RST_MASK |
       MT6357_HPL_AUX_CMFB_LOOP_MASK |
       MT6357_HPR_AUX_CMFB_LOOP_MASK,
       MT6357_HP_CMFB_RST_RESET |
       MT6357_HPL_AUX_CMFB_LOOP_ENABLE |
       MT6357_HPR_AUX_CMFB_LOOP_ENABLE);
  /* Disable HP main CMFB loop */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6,
       MT6357_HPRL_MAIN_CMFB_LOOP_MASK,
       MT6357_HPRL_MAIN_CMFB_LOOP_DISABLE);
  /* Unshort HP main output to HP aux output stage */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
       MT6357_HPR_SHORT2HPR_AUX_VAUDP15_MASK |
       MT6357_HPL_SHORT2HPR_AUX_VAUDP15_MASK,
       MT6357_HPR_SHORT2HPR_AUX_VAUDP15_DISABLE |
       MT6357_HPL_SHORT2HPR_AUX_VAUDP15_DISABLE);
  /* Disable HP driver core circuits */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0,
       MT6357_AUD_HPR_PWRUP_VAUDP15_MASK |
       MT6357_AUD_HPL_PWRUP_VAUDP15_MASK,
       MT6357_AUD_HPR_PWRUP_VAUDP15_DISABLE |
       MT6357_AUD_HPL_PWRUP_VAUDP15_DISABLE);
  /* Disable HP driver bias circuits */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0,
       MT6357_AUD_HPR_BIAS_VAUDP15_MASK |
       MT6357_AUD_HPL_BIAS_VAUDP15_MASK,
       MT6357_AUD_HPR_BIAS_VAUDP15_DISABLE |
       MT6357_AUD_HPL_BIAS_VAUDP15_DISABLE);
  /* Disable HP aux CMFB loop,
 * Enable HP main CMFB for HP off state
 */

  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON6,
       MT6357_HPRL_MAIN_CMFB_LOOP_MASK |
       MT6357_HPR_AUX_CMFB_LOOP_MASK |
       MT6357_HPL_AUX_CMFB_LOOP_MASK,
       MT6357_HPRL_MAIN_CMFB_LOOP_ENABLE |
       MT6357_HPR_AUX_CMFB_LOOP_DISABLE |
       MT6357_HPL_AUX_CMFB_LOOP_DISABLE);
  /* Disable HP aux feedback loop */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
       MT6357_HPR_AUX_FBRSW_VAUDP15_MASK |
       MT6357_HPL_AUX_FBRSW_VAUDP15_MASK,
       MT6357_HPR_AUX_FBRSW_VAUDP15_DISABLE |
       MT6357_HPL_AUX_FBRSW_VAUDP15_DISABLE);
  /* Disable HP aux output stage */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON1,
       MT6357_HPROUT_AUX_PWRUP_VAUDP15_MASK |
       MT6357_HPLOUT_AUX_PWRUP_VAUDP15_MASK,
       MT6357_HPROUT_AUX_PWRUP_VAUDP15_DISABLE |
       MT6357_HPLOUT_AUX_PWRUP_VAUDP15_DISABLE);
  /* Save the gain value into the register*/
  regmap_update_bits(priv->regmap, MT6357_ZCD_CON2,
       MT6357_AUD_HPL_GAIN_MASK |
       MT6357_AUD_HPR_GAIN_MASK,
       lgain << MT6357_AUD_HPL_GAIN_SFT |
       rgain << MT6357_AUD_HPR_GAIN_SFT);
  break;
 default:
  break;
 }

 return 0;
}

static int right_dac_event(struct snd_soc_dapm_widget *w,
      struct snd_kcontrol *kcontrol,
      int event)
{
 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);

 switch (event) {
 case SND_SOC_DAPM_PRE_PMU:
  /* Enable Audio DAC and control audio bias gen */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0,
       MT6357_AUD_DACR_PWRUP_VA28_MASK |
       MT6357_AUD_DACR_PWRUP_VAUDP15_MASK,
       MT6357_AUD_DACR_PWRUP_VA28_ENABLE |
       MT6357_AUD_DACR_PWRUP_VAUDP15_ENABLE);
  break;
 case SND_SOC_DAPM_POST_PMU:
  /* disable Pull-down HPL/R to AVSS28_AUD */
  if (priv->pull_down_needed)
   hp_pull_down(priv, false);
  break;
 case SND_SOC_DAPM_PRE_PMD:
  /* Pull-down HPL/R to AVSS28_AUD */
  if (priv->pull_down_needed)
   hp_pull_down(priv, true);
  /* Disable Audio DAC and control audio bias gen  */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0,
       MT6357_AUD_DACR_PWRUP_VA28_MASK |
       MT6357_AUD_DACR_PWRUP_VAUDP15_MASK,
       MT6357_AUD_DACR_PWRUP_VA28_DISABLE |
       MT6357_AUD_DACR_PWRUP_VAUDP15_DISABLE);
  break;
 default:
  break;
 }

 return 0;
}

static int left_dac_event(struct snd_soc_dapm_widget *w,
     struct snd_kcontrol *kcontrol,
     int event)
{
 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 struct mt6357_priv *priv = snd_soc_component_get_drvdata(cmpnt);

 switch (event) {
 case SND_SOC_DAPM_PRE_PMU:
  /* Enable Audio DAC and control audio bias gen  */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0,
       MT6357_AUD_DACL_PWRUP_VA28_MASK |
       MT6357_AUD_DACL_PWRUP_VAUDP15_MASK,
       MT6357_AUD_DACL_PWRUP_VA28_ENABLE |
       MT6357_AUD_DACL_PWRUP_VAUDP15_ENABLE);
  break;
 case SND_SOC_DAPM_POST_PMU:
  /* disable Pull-down HPL/R to AVSS28_AUD */
  if (priv->pull_down_needed)
   hp_pull_down(priv, false);
  break;
 case SND_SOC_DAPM_PRE_PMD:
  /* Pull-down HPL/R to AVSS28_AUD */
  if (priv->pull_down_needed)
   hp_pull_down(priv, true);
  /* Disable Audio DAC and control audio bias gen  */
  regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0,
       MT6357_AUD_DACL_PWRUP_VA28_MASK |
       MT6357_AUD_DACL_PWRUP_VAUDP15_MASK,
       MT6357_AUD_DACL_PWRUP_VA28_DISABLE |
       MT6357_AUD_DACL_PWRUP_VAUDP15_DISABLE);
  break;
 default:
  break;
 }

 return 0;
}

/* Supply widgets subsequence */
enum {
 /* common */
 SUPPLY_SEQ_CLK_BUF,
 SUPPLY_SEQ_AUD_GLB,
 SUPPLY_SEQ_CLKSQ,
 SUPPLY_SEQ_VOW_AUD_LPW,
 SUPPLY_SEQ_AUD_VOW,
 SUPPLY_SEQ_VOW_CLK,
 SUPPLY_SEQ_VOW_LDO,
 SUPPLY_SEQ_TOP_CK,
 SUPPLY_SEQ_TOP_CK_LAST,
 SUPPLY_SEQ_AUD_TOP,
 SUPPLY_SEQ_AUD_TOP_LAST,
 SUPPLY_SEQ_AFE,
 /* capture */
 SUPPLY_SEQ_ADC_SUPPLY,
};

/* DAPM Widgets */
static const struct snd_soc_dapm_widget mt6357_dapm_widgets[] = {
 /* Analog Clocks */
 SND_SOC_DAPM_SUPPLY_S("CLK_BUF", SUPPLY_SEQ_CLK_BUF,
         MT6357_DCXO_CW14,
         MT6357_XO_AUDIO_EN_M_SFT, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY_S("AUDGLB", SUPPLY_SEQ_AUD_GLB,
         MT6357_AUDDEC_ANA_CON11,
         MT6357_AUDGLB_PWRDN_VA28_SFT, 1, NULL, 0),
 SND_SOC_DAPM_SUPPLY_S("CLKSQ Audio", SUPPLY_SEQ_CLKSQ,
         MT6357_AUDENC_ANA_CON6,
         MT6357_CLKSQ_EN_SFT, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY_S("AUDNCP_CK", SUPPLY_SEQ_TOP_CK,
         MT6357_AUD_TOP_CKPDN_CON0,
         MT6357_AUDNCP_CK_PDN_SFT, 1, NULL, 0),
 SND_SOC_DAPM_SUPPLY_S("ZCD13M_CK", SUPPLY_SEQ_TOP_CK,
         MT6357_AUD_TOP_CKPDN_CON0,
         MT6357_ZCD13M_CK_PDN_SFT, 1, NULL, 0),
 SND_SOC_DAPM_SUPPLY_S("AUD_CK", SUPPLY_SEQ_TOP_CK_LAST,
         MT6357_AUD_TOP_CKPDN_CON0,
         MT6357_AUD_CK_PDN_SFT, 1,
         mt_delay_250_event,
         SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 SND_SOC_DAPM_SUPPLY_S("AUDIF_CK", SUPPLY_SEQ_TOP_CK,
         MT6357_AUD_TOP_CKPDN_CON0,
         MT6357_AUDIF_CK_PDN_SFT, 1, NULL, 0),

 /* Digital Clocks */
 SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_AFE_CTL", SUPPLY_SEQ_AUD_TOP_LAST,
         MT6357_AUDIO_TOP_CON0,
         MT6357_PDN_AFE_CTL_SFT, 1,
         mt_delay_250_event,
         SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_DAC_CTL", SUPPLY_SEQ_AUD_TOP,
         MT6357_AUDIO_TOP_CON0,
         MT6357_PDN_DAC_CTL_SFT, 1, NULL, 0),
 SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_ADC_CTL", SUPPLY_SEQ_AUD_TOP,
         MT6357_AUDIO_TOP_CON0,
         MT6357_PDN_ADC_CTL_SFT, 1, NULL, 0),
 SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_I2S_DL", SUPPLY_SEQ_AUD_TOP,
         MT6357_AUDIO_TOP_CON0,
         MT6357_PDN_I2S_DL_CTL_SFT, 1, NULL, 0),
 SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_PWR_CLK", SUPPLY_SEQ_AUD_TOP,
         MT6357_AUDIO_TOP_CON0,
         MT6357_PWR_CLK_DIS_CTL_SFT, 1, NULL, 0),
 SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_PDN_AFE_TESTMODEL", SUPPLY_SEQ_AUD_TOP,
         MT6357_AUDIO_TOP_CON0,
         MT6357_PDN_AFE_TESTMODEL_CTL_SFT, 1, NULL, 0),
 SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_PDN_RESERVED", SUPPLY_SEQ_AUD_TOP,
         MT6357_AUDIO_TOP_CON0,
         MT6357_PDN_RESERVED_SFT, 1, NULL, 0),
 SND_SOC_DAPM_SUPPLY_S("AUDIO_TOP_LPBK", SUPPLY_SEQ_AUD_TOP,
         MT6357_AUDIO_TOP_CON0,
         MT6357_PDN_LPBK_CTL_SFT, 1, NULL, 0),

 /* General */
 SND_SOC_DAPM_SUPPLY_S("AFE_ON", SUPPLY_SEQ_AFE,
         MT6357_AFE_UL_DL_CON0,
         MT6357_AFE_ON_SFT, 0, NULL, 0),

 /* Uplinks */
 SND_SOC_DAPM_AIF_OUT_E("AIF1TX""MT6357 Capture", 0,
          SND_SOC_NOPM, 0, 0,
          mt_aif_out_event,
          SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 SND_SOC_DAPM_SUPPLY_S("ADC Supply", SUPPLY_SEQ_ADC_SUPPLY,
         SND_SOC_NOPM, 0, 0,
         mt_adc_supply_event,
         SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 SND_SOC_DAPM_ADC_E("ADC", NULL, SND_SOC_NOPM, 0, 0, adc_enable_event,
      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 SND_SOC_DAPM_MUX_E("PGA L Mux", SND_SOC_NOPM, 0, 0,
      &pga_left_mux_control,
      mt_pga_left_event,
      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 SND_SOC_DAPM_MUX_E("PGA R Mux", SND_SOC_NOPM, 0, 0,
      &pga_right_mux_control,
      mt_pga_right_event,
      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 SND_SOC_DAPM_PGA("PGA L", SND_SOC_NOPM, 0, 0, NULL, 0),
 SND_SOC_DAPM_PGA("PGA R", SND_SOC_NOPM, 0, 0, NULL, 0),
 SND_SOC_DAPM_MUX_E("Mic Type Mux", SND_SOC_NOPM, 0, 0,
      &mic_type_mux_control,
      mt_mic_type_event,
      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 SND_SOC_DAPM_SUPPLY("MICBIAS0", MT6357_AUDENC_ANA_CON8,
       MT6357_AUD_MICBIAS0_PWD_SFT, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY("MICBIAS1", MT6357_AUDENC_ANA_CON9,
       MT6357_AUD_MICBIAS1_PWD_SFT, 0, NULL, 0),

 /* UL inputs */
 SND_SOC_DAPM_INPUT("AIN0"),
 SND_SOC_DAPM_INPUT("AIN1"),
 SND_SOC_DAPM_INPUT("AIN2"),
 SND_SOC_DAPM_INPUT("LPBK"),
 SND_SOC_DAPM_INPUT("SGEN UL"),

 /* Downlinks */
 SND_SOC_DAPM_AIF_IN_E("AIF_RX""MT6357 Playback", 0,
         SND_SOC_NOPM, 0, 0,
         mt_audio_in_event,
         SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 SND_SOC_DAPM_INPUT("SGEN DL"),
 SND_SOC_DAPM_MUX("DAC Mux", SND_SOC_NOPM, 0, 0, &dac_mux_control),

 SND_SOC_DAPM_DAC_E("DACR", NULL, SND_SOC_NOPM, 0, 0, right_dac_event,
      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 SND_SOC_DAPM_DAC_E("DACL", NULL, SND_SOC_NOPM, 0, 0, left_dac_event,
      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),

 SND_SOC_DAPM_SUPPLY("DL Digital Supply", SND_SOC_NOPM, 0, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY("DL Analog Supply", SND_SOC_NOPM, 0, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY("DL SRC", MT6357_AFE_DL_SRC2_CON0_L,
       MT6357_DL_2_SRC_ON_TMP_CTL_PRE_SFT, 0, NULL, 0),

 SND_SOC_DAPM_MUX_E("Line Out Source", SND_SOC_NOPM, 0, 0, &lo_mux_control,
      lo_mux_event,
      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),

 SND_SOC_DAPM_MUX_E("Handset Source", SND_SOC_NOPM, 0, 0, &hs_mux_control,
      hs_mux_event,
      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),

 SND_SOC_DAPM_MUX_E("Headphone Right Source", SND_SOC_NOPM, 0, 0, &hpr_mux_control,
      hp_main_mux_event,
      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),

 SND_SOC_DAPM_MUX_E("Headphone Left Source", SND_SOC_NOPM, 0, 0, &hpl_mux_control,
      hp_main_mux_event,
      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 /* DL outputs */
 SND_SOC_DAPM_OUTPUT("Headphones"),
 SND_SOC_DAPM_OUTPUT("Hansdet"),
 SND_SOC_DAPM_OUTPUT("Line out"),

 /* Sine generator */
 SND_SOC_DAPM_SUPPLY("SGEN UL Enable",
       MT6357_AFE_TOP_CON0, MT6357_UL_SINE_ON_SFT, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY("SGEN Enable",
       MT6357_AFE_SGEN_CFG0,
       MT6357_SGEN_DAC_EN_CTL_SFT, 0, mt_audio_in_event,
       SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 SND_SOC_DAPM_SUPPLY("SGEN MUTE",
       MT6357_AFE_SGEN_CFG0,
       MT6357_SGEN_MUTE_SW_CTL_SFT, 1, NULL, 0)
};

static const struct snd_soc_dapm_route mt6357_dapm_routes[] = {
 /* Capture */
 {"AIF1TX", NULL, "Mic Type Mux"},
 {"AIF1TX", NULL, "CLK_BUF"},
 {"AIF1TX", NULL, "AUDGLB"},
 {"AIF1TX", NULL, "CLKSQ Audio"},
 {"AIF1TX", NULL, "AUD_CK"},
 {"AIF1TX", NULL, "AUDIF_CK"},

 {"AIF1TX", NULL, "AUDIO_TOP_AFE_CTL"},
 {"AIF1TX", NULL, "AUDIO_TOP_ADC_CTL"},
 {"AIF1TX", NULL, "AUDIO_TOP_PWR_CLK"},
 {"AIF1TX", NULL, "AUDIO_TOP_PDN_RESERVED"},
 {"AIF1TX", NULL, "AUDIO_TOP_I2S_DL"},
 {"AIF1TX", NULL, "AFE_ON"},

 {"Mic Type Mux""ACC""ADC"},
 {"Mic Type Mux""DCC""ADC"},
 {"Mic Type Mux""DCC_ECM_DIFF""ADC"},
 {"Mic Type Mux""DCC_ECM_SINGLE""ADC"},
 {"Mic Type Mux""DMIC""AIN0"},
 {"Mic Type Mux""DMIC""AIN2"},
 {"Mic Type Mux""Loopback""LPBK"},
 {"Mic Type Mux""Sine Generator""SGEN UL"},

 {"SGEN UL", NULL, "AUDIO_TOP_PDN_AFE_TESTMODEL"},
 {"SGEN UL", NULL, "SGEN UL Enable"},
 {"SGEN UL", NULL, "SGEN MUTE"},
 {"SGEN UL", NULL, "SGEN Enable"},

 {"ADC", NULL, "PGA L Mux"},
 {"ADC", NULL, "PGA R Mux"},
 {"ADC", NULL, "ADC Supply"},

 {"PGA L Mux""AIN0""AIN0"},
 {"PGA L Mux""AIN1""AIN1"},
 {"PGA L Mux""AIN2""AIN2"},

 {"PGA R Mux""AIN0""AIN0"},
 {"PGA R Mux""AIN1""AIN1"},
 {"PGA R Mux""AIN2""AIN2"},

 {"AIN0", NULL, "MICBIAS0"},
 {"AIN1", NULL, "MICBIAS1"},
 {"AIN2", NULL, "MICBIAS0"},
 {"LPBK", NULL, "AUDIO_TOP_LPBK"},

 /* Playback */
 {"DAC Mux""Normal Path""AIF_RX"},
 {"DAC Mux""Sine Generator""SGEN DL"},

 {"AIF_RX", NULL, "DL SRC"},

 {"SGEN DL", NULL, "DL SRC"},
 {"SGEN DL", NULL, "SGEN MUTE"},
 {"SGEN DL", NULL, "SGEN Enable"},
 {"SGEN DL", NULL, "DL Digital Supply"},
 {"SGEN DL", NULL, "AUDIO_TOP_PDN_AFE_TESTMODEL"},

 {"DACL", NULL, "DAC Mux"},
 {"DACR", NULL, "DAC Mux"},

 {"DL Analog Supply", NULL, "CLK_BUF"},
 {"DL Analog Supply", NULL, "AUDGLB"},
 {"DL Analog Supply", NULL, "CLKSQ Audio"},
 {"DL Analog Supply", NULL, "AUDNCP_CK"},
 {"DL Analog Supply", NULL, "ZCD13M_CK"},
 {"DL Analog Supply", NULL, "AUD_CK"},
 {"DL Analog Supply", NULL, "AUDIF_CK"},

 {"DL Digital Supply", NULL, "AUDIO_TOP_AFE_CTL"},
 {"DL Digital Supply", NULL, "AUDIO_TOP_DAC_CTL"},
 {"DL Digital Supply", NULL, "AUDIO_TOP_PWR_CLK"},
 {"DL Digital Supply", NULL, "AFE_ON"},

 {"DACR", NULL, "DL Digital Supply"},
 {"DACR", NULL, "DL Analog Supply"},
 {"DACL", NULL, "DL Digital Supply"},
 {"DACL", NULL, "DL Analog Supply"},

 {"Line Out Source""DACR""DACR"},
 {"Line Out Source""Playback""DACL"},
 {"Line Out Source""Test mode""DACL"},

 {"Handset Source""DACR""DACR"},
 {"Handset Source""Playback""DACL"},
 {"Handset Source""Test mode""DACL"},

 {"Headphone Right Source""DAC""DACR"},
 {"Headphone Right Source""Line Out""Line Out Source"},
 {"Headphone Right Source""Handset""Handset Source"},

 {"Headphone Left Source""DAC""DACL"},
 {"Headphone Left Source""Line Out""Line Out Source"},
 {"Headphone Left Source""Handset""Handset Source"},

 {"Line out", NULL, "Line Out Source"},
 {"Hansdet", NULL, "Handset Source"},

 {"Headphones", NULL, "Headphone Right Source"},
 {"Headphones", NULL, "Headphone Left Source"},
};

static struct snd_soc_dai_driver mtk_6357_dai_codecs[] = {
 {
  .name = "mt6357-snd-codec-aif1",
  .playback = {
   .stream_name = "MT6357 Playback",
   .channels_min = 1,
   .channels_max = 2,
   .rates = SNDRV_PCM_RATE_8000_192000,
   .formats = MT6357_SND_SOC_ADV_MT_FMTS,
   },
  .capture = {
   .stream_name = "MT6357 Capture",
   .channels_min = 1,
   .channels_max = 2,
   .rates = MT6357_SOC_HIGH_USE_RATE,
   .formats = MT6357_SND_SOC_ADV_MT_FMTS,
   },
 },
};

static int mt6357_codec_probe(struct snd_soc_component *codec)
{
 struct mt6357_priv *priv = snd_soc_component_get_drvdata(codec);

 snd_soc_component_init_regmap(codec, priv->regmap);

 /* Enable audio part */
 regmap_update_bits(priv->regmap, MT6357_DCXO_CW14,
      MT6357_XO_AUDIO_EN_M_MASK, MT6357_XO_AUDIO_EN_M_ENABLE);
 /* Disable HeadphoneL/HeadphoneR short circuit protection */
 regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON0,
      MT6357_AUD_HPR_SC_VAUDP15_MASK |
      MT6357_AUD_HPL_SC_VAUDP15_MASK,
      MT6357_AUD_HPR_SC_VAUDP15_DISABLE |
      MT6357_AUD_HPL_SC_VAUDP15_DISABLE);
 /* Disable voice short circuit protection */
 regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON3,
      MT6357_AUD_HS_SC_VAUDP15_MASK,
      MT6357_AUD_HS_SC_VAUDP15_DISABLE);
 /* disable LO buffer left short circuit protection */
 regmap_update_bits(priv->regmap, MT6357_AUDDEC_ANA_CON4,
      MT6357_AUD_LOL_SC_VAUDP15_MASK,
      MT6357_AUD_LOL_SC_VAUDP15_DISABLE);
 /* set gpio */
 set_playback_gpio(priv, false);
 set_capture_gpio(priv, false);
 /* Disable audio part */
 regmap_update_bits(priv->regmap, MT6357_DCXO_CW14,
      MT6357_XO_AUDIO_EN_M_MASK,
      MT6357_XO_AUDIO_EN_M_DISABLE);

 return 0;
}

static const struct snd_soc_component_driver mt6357_soc_component_driver = {
 .probe = mt6357_codec_probe,
 .read = snd_soc_component_read,
 .write = snd_soc_component_write,
 .controls = mt6357_controls,
 .num_controls = ARRAY_SIZE(mt6357_controls),
 .dapm_widgets = mt6357_dapm_widgets,
 .num_dapm_widgets = ARRAY_SIZE(mt6357_dapm_widgets),
 .dapm_routes = mt6357_dapm_routes,
 .num_dapm_routes = ARRAY_SIZE(mt6357_dapm_routes),
};

static const u32 micbias_values[] = {
 1700000, 1800000, 1900000, 2000000,
 2100000, 2500000, 2600000, 2700000
};

static u32 mt6357_get_micbias_idx(struct device_node *np, const char *micbias)
{
 int err;
 u32 idx, val;

 err = of_property_read_u32(np, micbias,  &val);
 if (err)
  return 0;

 for (idx = 0; idx < ARRAY_SIZE(micbias_values); idx++) {
  if (val == micbias_values[idx])
   return idx;
 }
 return 0;
}

static int mt6357_parse_dt(struct mt6357_priv *priv)
{
 u32 micbias_voltage_index = 0;
 struct device_node *np = priv->dev->parent->of_node;

 if (!np)
  return -EINVAL;

 priv->pull_down_needed = false;
 if (of_property_read_bool(np, "mediatek,hp-pull-down"))
  priv->pull_down_needed = true;

 micbias_voltage_index = mt6357_get_micbias_idx(np, "mediatek,micbias0-microvolt");
 regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON8,
      MT6357_AUD_MICBIAS0_VREF_MASK,
      micbias_voltage_index << MT6357_AUD_MICBIAS0_VREF_SFT);

 micbias_voltage_index = mt6357_get_micbias_idx(np, "mediatek,micbias1-microvolt");
 regmap_update_bits(priv->regmap, MT6357_AUDENC_ANA_CON9,
      MT6357_AUD_MICBIAS1_VREF_MASK,
      micbias_voltage_index << MT6357_AUD_MICBIAS1_VREF_SFT);

 return 0;
}

static int mt6357_platform_driver_probe(struct platform_device *pdev)
{
 struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent);
 struct mt6357_priv *priv;
 int ret;

 ret = devm_regulator_get_enable(&pdev->dev, "vaud28");
 if (ret)
  return dev_err_probe(&pdev->dev, ret, "Failed to enable vaud28 regulator\n");

 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
 if (!priv)
  return -ENOMEM;

 dev_set_drvdata(&pdev->dev, priv);
 priv->dev = &pdev->dev;

 priv->regmap = mt6397->regmap;
 if (IS_ERR(priv->regmap))
  return PTR_ERR(priv->regmap);

 ret = mt6357_parse_dt(priv);
 if (ret)
  return dev_err_probe(&pdev->dev, ret, "Failed to parse dts\n");

 pdev->dev.coherent_dma_mask = DMA_BIT_MASK(64);
 if (!pdev->dev.dma_mask)
  pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;

 return devm_snd_soc_register_component(&pdev->dev,
            &mt6357_soc_component_driver,
            mtk_6357_dai_codecs,
            ARRAY_SIZE(mtk_6357_dai_codecs));
}

static const struct platform_device_id mt6357_platform_ids[] = {
 {"mt6357-sound", 0},
 { /* sentinel */ },
};
MODULE_DEVICE_TABLE(platform, mt6357_platform_ids);

static struct platform_driver mt6357_platform_driver = {
 .driver = {
  .name = "mt6357-sound",
  .probe_type = PROBE_PREFER_ASYNCHRONOUS,
 },
 .probe = mt6357_platform_driver_probe,
 .id_table = mt6357_platform_ids,
};

module_platform_driver(mt6357_platform_driver)

MODULE_DESCRIPTION("MT6357 ALSA SoC codec driver");
MODULE_AUTHOR("Nicolas Belin ");
MODULE_LICENSE("GPL");

Messung V0.5
C=91 H=98 G=94

¤ Dauer der Verarbeitung: 0.22 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.