Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  mt8188-afe-clk.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/*
 * mt8188-afe-clk.c  --  MediaTek 8188 afe clock ctrl
 *
 * Copyright (c) 2022 MediaTek Inc.
 * Author: Bicycle Tsai <bicycle.tsai@mediatek.com>
 *         Trevor Wu <trevor.wu@mediatek.com>
 *         Chun-Chia Chiu <chun-chia.chiu@mediatek.com>
 */


#include <linux/clk.h>

#include "mt8188-afe-common.h"
#include "mt8188-afe-clk.h"
#include "mt8188-audsys-clk.h"
#include "mt8188-reg.h"

static const char *aud_clks[MT8188_CLK_NUM] = {
 /* xtal */
 [MT8188_CLK_XTAL_26M] = "clk26m",

 /* pll */
 [MT8188_CLK_APMIXED_APLL1] = "apll1",
 [MT8188_CLK_APMIXED_APLL2] = "apll2",

 /* divider */
 [MT8188_CLK_TOP_APLL1_D4] = "apll1_d4",
 [MT8188_CLK_TOP_APLL2_D4] = "apll2_d4",
 [MT8188_CLK_TOP_APLL12_DIV0] = "apll12_div0",
 [MT8188_CLK_TOP_APLL12_DIV1] = "apll12_div1",
 [MT8188_CLK_TOP_APLL12_DIV2] = "apll12_div2",
 [MT8188_CLK_TOP_APLL12_DIV3] = "apll12_div3",
 [MT8188_CLK_TOP_APLL12_DIV4] = "apll12_div4",
 [MT8188_CLK_TOP_APLL12_DIV9] = "apll12_div9",

 /* mux */
 [MT8188_CLK_TOP_A1SYS_HP_SEL] = "top_a1sys_hp",
 [MT8188_CLK_TOP_A2SYS_SEL] = "top_a2sys",
 [MT8188_CLK_TOP_AUD_IEC_SEL] = "top_aud_iec",
 [MT8188_CLK_TOP_AUD_INTBUS_SEL] = "top_aud_intbus",
 [MT8188_CLK_TOP_AUDIO_H_SEL] = "top_audio_h",
 [MT8188_CLK_TOP_AUDIO_LOCAL_BUS_SEL] = "top_audio_local_bus",
 [MT8188_CLK_TOP_DPTX_M_SEL] = "top_dptx",
 [MT8188_CLK_TOP_I2SO1_M_SEL] = "top_i2so1",
 [MT8188_CLK_TOP_I2SO2_M_SEL] = "top_i2so2",
 [MT8188_CLK_TOP_I2SI1_M_SEL] = "top_i2si1",
 [MT8188_CLK_TOP_I2SI2_M_SEL] = "top_i2si2",

 /* clock gate */
 [MT8188_CLK_ADSP_AUDIO_26M] = "adsp_audio_26m",
 /* afe clock gate */
 [MT8188_CLK_AUD_AFE] = "aud_afe",
 [MT8188_CLK_AUD_APLL1_TUNER] = "aud_apll1_tuner",
 [MT8188_CLK_AUD_APLL2_TUNER] = "aud_apll2_tuner",
 [MT8188_CLK_AUD_APLL] = "aud_apll",
 [MT8188_CLK_AUD_APLL2] = "aud_apll2",
 [MT8188_CLK_AUD_DAC] = "aud_dac",
 [MT8188_CLK_AUD_ADC] = "aud_adc",
 [MT8188_CLK_AUD_DAC_HIRES] = "aud_dac_hires",
 [MT8188_CLK_AUD_A1SYS_HP] = "aud_a1sys_hp",
 [MT8188_CLK_AUD_AFE_DMIC1] = "aud_afe_dmic1",
 [MT8188_CLK_AUD_AFE_DMIC2] = "aud_afe_dmic2",
 [MT8188_CLK_AUD_AFE_DMIC3] = "aud_afe_dmic3",
 [MT8188_CLK_AUD_AFE_DMIC4] = "aud_afe_dmic4",
 [MT8188_CLK_AUD_ADC_HIRES] = "aud_adc_hires",
 [MT8188_CLK_AUD_DMIC_HIRES1] = "aud_dmic_hires1",
 [MT8188_CLK_AUD_DMIC_HIRES2] = "aud_dmic_hires2",
 [MT8188_CLK_AUD_DMIC_HIRES3] = "aud_dmic_hires3",
 [MT8188_CLK_AUD_DMIC_HIRES4] = "aud_dmic_hires4",
 [MT8188_CLK_AUD_I2SIN] = "aud_i2sin",
 [MT8188_CLK_AUD_TDM_IN] = "aud_tdm_in",
 [MT8188_CLK_AUD_I2S_OUT] = "aud_i2s_out",
 [MT8188_CLK_AUD_TDM_OUT] = "aud_tdm_out",
 [MT8188_CLK_AUD_HDMI_OUT] = "aud_hdmi_out",
 [MT8188_CLK_AUD_ASRC11] = "aud_asrc11",
 [MT8188_CLK_AUD_ASRC12] = "aud_asrc12",
 [MT8188_CLK_AUD_A1SYS] = "aud_a1sys",
 [MT8188_CLK_AUD_A2SYS] = "aud_a2sys",
 [MT8188_CLK_AUD_PCMIF] = "aud_pcmif",
 [MT8188_CLK_AUD_MEMIF_UL1] = "aud_memif_ul1",
 [MT8188_CLK_AUD_MEMIF_UL2] = "aud_memif_ul2",
 [MT8188_CLK_AUD_MEMIF_UL3] = "aud_memif_ul3",
 [MT8188_CLK_AUD_MEMIF_UL4] = "aud_memif_ul4",
 [MT8188_CLK_AUD_MEMIF_UL5] = "aud_memif_ul5",
 [MT8188_CLK_AUD_MEMIF_UL6] = "aud_memif_ul6",
 [MT8188_CLK_AUD_MEMIF_UL8] = "aud_memif_ul8",
 [MT8188_CLK_AUD_MEMIF_UL9] = "aud_memif_ul9",
 [MT8188_CLK_AUD_MEMIF_UL10] = "aud_memif_ul10",
 [MT8188_CLK_AUD_MEMIF_DL2] = "aud_memif_dl2",
 [MT8188_CLK_AUD_MEMIF_DL3] = "aud_memif_dl3",
 [MT8188_CLK_AUD_MEMIF_DL6] = "aud_memif_dl6",
 [MT8188_CLK_AUD_MEMIF_DL7] = "aud_memif_dl7",
 [MT8188_CLK_AUD_MEMIF_DL8] = "aud_memif_dl8",
 [MT8188_CLK_AUD_MEMIF_DL10] = "aud_memif_dl10",
 [MT8188_CLK_AUD_MEMIF_DL11] = "aud_memif_dl11",
};

struct mt8188_afe_tuner_cfg {
 unsigned int id;
 int apll_div_reg;
 unsigned int apll_div_shift;
 unsigned int apll_div_maskbit;
 unsigned int apll_div_default;
 int ref_ck_sel_reg;
 unsigned int ref_ck_sel_shift;
 unsigned int ref_ck_sel_maskbit;
 unsigned int ref_ck_sel_default;
 int tuner_en_reg;
 unsigned int tuner_en_shift;
 unsigned int tuner_en_maskbit;
 int upper_bound_reg;
 unsigned int upper_bound_shift;
 unsigned int upper_bound_maskbit;
 unsigned int upper_bound_default;
 spinlock_t ctrl_lock; /* lock for apll tuner ctrl*/
 int ref_cnt;
};

static struct mt8188_afe_tuner_cfg
 mt8188_afe_tuner_cfgs[MT8188_AUD_PLL_NUM] = {
 [MT8188_AUD_PLL1] = {
  .id = MT8188_AUD_PLL1,
  .apll_div_reg = AFE_APLL_TUNER_CFG,
  .apll_div_shift = 4,
  .apll_div_maskbit = 0xf,
  .apll_div_default = 0x7,
  .ref_ck_sel_reg = AFE_APLL_TUNER_CFG,
  .ref_ck_sel_shift = 1,
  .ref_ck_sel_maskbit = 0x3,
  .ref_ck_sel_default = 0x2,
  .tuner_en_reg = AFE_APLL_TUNER_CFG,
  .tuner_en_shift = 0,
  .tuner_en_maskbit = 0x1,
  .upper_bound_reg = AFE_APLL_TUNER_CFG,
  .upper_bound_shift = 8,
  .upper_bound_maskbit = 0xff,
  .upper_bound_default = 0x3,
 },
 [MT8188_AUD_PLL2] = {
  .id = MT8188_AUD_PLL2,
  .apll_div_reg = AFE_APLL_TUNER_CFG1,
  .apll_div_shift = 4,
  .apll_div_maskbit = 0xf,
  .apll_div_default = 0x7,
  .ref_ck_sel_reg = AFE_APLL_TUNER_CFG1,
  .ref_ck_sel_shift = 1,
  .ref_ck_sel_maskbit = 0x3,
  .ref_ck_sel_default = 0x1,
  .tuner_en_reg = AFE_APLL_TUNER_CFG1,
  .tuner_en_shift = 0,
  .tuner_en_maskbit = 0x1,
  .upper_bound_reg = AFE_APLL_TUNER_CFG1,
  .upper_bound_shift = 8,
  .upper_bound_maskbit = 0xff,
  .upper_bound_default = 0x3,
 },
 [MT8188_AUD_PLL3] = {
  .id = MT8188_AUD_PLL3,
  .apll_div_reg = AFE_EARC_APLL_TUNER_CFG,
  .apll_div_shift = 4,
  .apll_div_maskbit = 0x3f,
  .apll_div_default = 0x3,
  .ref_ck_sel_reg = AFE_EARC_APLL_TUNER_CFG,
  .ref_ck_sel_shift = 24,
  .ref_ck_sel_maskbit = 0x3,
  .ref_ck_sel_default = 0x0,
  .tuner_en_reg = AFE_EARC_APLL_TUNER_CFG,
  .tuner_en_shift = 0,
  .tuner_en_maskbit = 0x1,
  .upper_bound_reg = AFE_EARC_APLL_TUNER_CFG,
  .upper_bound_shift = 12,
  .upper_bound_maskbit = 0xff,
  .upper_bound_default = 0x4,
 },
 [MT8188_AUD_PLL4] = {
  .id = MT8188_AUD_PLL4,
  .apll_div_reg = AFE_SPDIFIN_APLL_TUNER_CFG,
  .apll_div_shift = 4,
  .apll_div_maskbit = 0x3f,
  .apll_div_default = 0x7,
  .ref_ck_sel_reg = AFE_SPDIFIN_APLL_TUNER_CFG1,
  .ref_ck_sel_shift = 8,
  .ref_ck_sel_maskbit = 0x1,
  .ref_ck_sel_default = 0,
  .tuner_en_reg = AFE_SPDIFIN_APLL_TUNER_CFG,
  .tuner_en_shift = 0,
  .tuner_en_maskbit = 0x1,
  .upper_bound_reg = AFE_SPDIFIN_APLL_TUNER_CFG,
  .upper_bound_shift = 12,
  .upper_bound_maskbit = 0xff,
  .upper_bound_default = 0x4,
 },
 [MT8188_AUD_PLL5] = {
  .id = MT8188_AUD_PLL5,
  .apll_div_reg = AFE_LINEIN_APLL_TUNER_CFG,
  .apll_div_shift = 4,
  .apll_div_maskbit = 0x3f,
  .apll_div_default = 0x3,
  .ref_ck_sel_reg = AFE_LINEIN_APLL_TUNER_CFG,
  .ref_ck_sel_shift = 24,
  .ref_ck_sel_maskbit = 0x1,
  .ref_ck_sel_default = 0,
  .tuner_en_reg = AFE_LINEIN_APLL_TUNER_CFG,
  .tuner_en_shift = 0,
  .tuner_en_maskbit = 0x1,
  .upper_bound_reg = AFE_LINEIN_APLL_TUNER_CFG,
  .upper_bound_shift = 12,
  .upper_bound_maskbit = 0xff,
  .upper_bound_default = 0x4,
 },
};

static struct mt8188_afe_tuner_cfg *mt8188_afe_found_apll_tuner(unsigned int id)
{
 if (id >= MT8188_AUD_PLL_NUM)
  return NULL;

 return &mt8188_afe_tuner_cfgs[id];
}

static int mt8188_afe_init_apll_tuner(unsigned int id)
{
 struct mt8188_afe_tuner_cfg *cfg = mt8188_afe_found_apll_tuner(id);

 if (!cfg)
  return -EINVAL;

 cfg->ref_cnt = 0;
 spin_lock_init(&cfg->ctrl_lock);

 return 0;
}

static int mt8188_afe_setup_apll_tuner(struct mtk_base_afe *afe, unsigned int id)
{
 const struct mt8188_afe_tuner_cfg *cfg = mt8188_afe_found_apll_tuner(id);

 if (!cfg)
  return -EINVAL;

 regmap_update_bits(afe->regmap,
      cfg->apll_div_reg,
      cfg->apll_div_maskbit << cfg->apll_div_shift,
      cfg->apll_div_default << cfg->apll_div_shift);

 regmap_update_bits(afe->regmap,
      cfg->ref_ck_sel_reg,
      cfg->ref_ck_sel_maskbit << cfg->ref_ck_sel_shift,
      cfg->ref_ck_sel_default << cfg->ref_ck_sel_shift);

 regmap_update_bits(afe->regmap,
      cfg->upper_bound_reg,
      cfg->upper_bound_maskbit << cfg->upper_bound_shift,
      cfg->upper_bound_default << cfg->upper_bound_shift);

 return 0;
}

static int mt8188_afe_enable_tuner_clk(struct mtk_base_afe *afe,
           unsigned int id)
{
 struct mt8188_afe_private *afe_priv = afe->platform_priv;

 switch (id) {
 case MT8188_AUD_PLL1:
  mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_APLL]);
  mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_APLL1_TUNER]);
  break;
 case MT8188_AUD_PLL2:
  mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_APLL2]);
  mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_APLL2_TUNER]);
  break;
 default:
  return -EINVAL;
 }

 return 0;
}

static int mt8188_afe_disable_tuner_clk(struct mtk_base_afe *afe,
     unsigned int id)
{
 struct mt8188_afe_private *afe_priv = afe->platform_priv;

 switch (id) {
 case MT8188_AUD_PLL1:
  mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_APLL1_TUNER]);
  mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_APLL]);
  break;
 case MT8188_AUD_PLL2:
  mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_APLL2_TUNER]);
  mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_APLL2]);
  break;
 default:
  return -EINVAL;
 }

 return 0;
}

static int mt8188_afe_enable_apll_tuner(struct mtk_base_afe *afe, unsigned int id)
{
 struct mt8188_afe_tuner_cfg *cfg = mt8188_afe_found_apll_tuner(id);
 unsigned long flags;
 int ret;

 if (!cfg)
  return -EINVAL;

 ret = mt8188_afe_setup_apll_tuner(afe, id);
 if (ret)
  return ret;

 ret = mt8188_afe_enable_tuner_clk(afe, id);
 if (ret)
  return ret;

 spin_lock_irqsave(&cfg->ctrl_lock, flags);

 cfg->ref_cnt++;
 if (cfg->ref_cnt == 1)
  regmap_update_bits(afe->regmap,
       cfg->tuner_en_reg,
       cfg->tuner_en_maskbit << cfg->tuner_en_shift,
       BIT(cfg->tuner_en_shift));

 spin_unlock_irqrestore(&cfg->ctrl_lock, flags);

 return 0;
}

static int mt8188_afe_disable_apll_tuner(struct mtk_base_afe *afe, unsigned int id)
{
 struct mt8188_afe_tuner_cfg *cfg = mt8188_afe_found_apll_tuner(id);
 unsigned long flags;
 int ret;

 if (!cfg)
  return -EINVAL;

 spin_lock_irqsave(&cfg->ctrl_lock, flags);

 cfg->ref_cnt--;
 if (cfg->ref_cnt == 0)
  regmap_update_bits(afe->regmap,
       cfg->tuner_en_reg,
       cfg->tuner_en_maskbit << cfg->tuner_en_shift,
       0 << cfg->tuner_en_shift);
 else if (cfg->ref_cnt < 0)
  cfg->ref_cnt = 0;

 spin_unlock_irqrestore(&cfg->ctrl_lock, flags);

 ret = mt8188_afe_disable_tuner_clk(afe, id);
 if (ret)
  return ret;

 return 0;
}

int mt8188_afe_get_mclk_source_clk_id(int sel)
{
 switch (sel) {
 case MT8188_MCK_SEL_26M:
  return MT8188_CLK_XTAL_26M;
 case MT8188_MCK_SEL_APLL1:
  return MT8188_CLK_APMIXED_APLL1;
 case MT8188_MCK_SEL_APLL2:
  return MT8188_CLK_APMIXED_APLL2;
 default:
  return -EINVAL;
 }
}

int mt8188_afe_get_mclk_source_rate(struct mtk_base_afe *afe, int apll)
{
 struct mt8188_afe_private *afe_priv = afe->platform_priv;
 int clk_id = mt8188_afe_get_mclk_source_clk_id(apll);

 if (clk_id < 0) {
  dev_dbg(afe->dev, "invalid clk id\n");
  return 0;
 }

 return clk_get_rate(afe_priv->clk[clk_id]);
}

int mt8188_afe_get_default_mclk_source_by_rate(int rate)
{
 return ((rate % 8000) == 0) ?
  MT8188_MCK_SEL_APLL1 : MT8188_MCK_SEL_APLL2;
}

int mt8188_get_apll_by_rate(struct mtk_base_afe *afe, int rate)
{
 return ((rate % 8000) == 0) ? MT8188_AUD_PLL1 : MT8188_AUD_PLL2;
}

int mt8188_get_apll_by_name(struct mtk_base_afe *afe, const char *name)
{
 if (strcmp(name, APLL1_W_NAME) == 0)
  return MT8188_AUD_PLL1;

 return MT8188_AUD_PLL2;
}

int mt8188_afe_init_clock(struct mtk_base_afe *afe)
{
 struct mt8188_afe_private *afe_priv = afe->platform_priv;
 int i, ret;

 ret = mt8188_audsys_clk_register(afe);
 if (ret) {
  dev_err(afe->dev, "register audsys clk fail %d\n", ret);
  return ret;
 }

 afe_priv->clk =
  devm_kcalloc(afe->dev, MT8188_CLK_NUM, sizeof(*afe_priv->clk),
        GFP_KERNEL);
 if (!afe_priv->clk)
  return -ENOMEM;

 for (i = 0; i < MT8188_CLK_NUM; i++) {
  afe_priv->clk[i] = devm_clk_get(afe->dev, aud_clks[i]);
  if (IS_ERR(afe_priv->clk[i])) {
   dev_err(afe->dev, "%s(), devm_clk_get %s fail, ret %ld\n",
    __func__, aud_clks[i],
    PTR_ERR(afe_priv->clk[i]));
   return PTR_ERR(afe_priv->clk[i]);
  }
 }

 /* initial tuner */
 for (i = 0; i < MT8188_AUD_PLL_NUM; i++) {
  ret = mt8188_afe_init_apll_tuner(i);
  if (ret) {
   dev_info(afe->dev, "%s(), init apll_tuner%d failed",
     __func__, (i + 1));
   return -EINVAL;
  }
 }

 return 0;
}

int mt8188_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk)
{
 int ret;

 if (clk) {
  ret = clk_prepare_enable(clk);
  if (ret) {
   dev_dbg(afe->dev, "%s(), failed to enable clk\n",
    __func__);
   return ret;
  }
 } else {
  dev_dbg(afe->dev, "NULL clk\n");
 }
 return 0;
}
EXPORT_SYMBOL_GPL(mt8188_afe_enable_clk);

void mt8188_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk)
{
 if (clk)
  clk_disable_unprepare(clk);
 else
  dev_dbg(afe->dev, "NULL clk\n");
}
EXPORT_SYMBOL_GPL(mt8188_afe_disable_clk);

int mt8188_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk,
       unsigned int rate)
{
 int ret;

 if (clk) {
  ret = clk_set_rate(clk, rate);
  if (ret) {
   dev_dbg(afe->dev, "%s(), failed to set clk rate\n",
    __func__);
   return ret;
  }
 }

 return 0;
}

int mt8188_afe_set_clk_parent(struct mtk_base_afe *afe, struct clk *clk,
         struct clk *parent)
{
 int ret;

 if (clk && parent) {
  ret = clk_set_parent(clk, parent);
  if (ret) {
   dev_dbg(afe->dev, "%s(), failed to set clk parent %d\n",
    __func__, ret);
   return ret;
  }
 }

 return 0;
}

static unsigned int get_top_cg_reg(unsigned int cg_type)
{
 switch (cg_type) {
 case MT8188_TOP_CG_A1SYS_TIMING:
 case MT8188_TOP_CG_A2SYS_TIMING:
 case MT8188_TOP_CG_26M_TIMING:
  return ASYS_TOP_CON;
 default:
  return 0;
 }
}

static unsigned int get_top_cg_mask(unsigned int cg_type)
{
 switch (cg_type) {
 case MT8188_TOP_CG_A1SYS_TIMING:
  return ASYS_TOP_CON_A1SYS_TIMING_ON;
 case MT8188_TOP_CG_A2SYS_TIMING:
  return ASYS_TOP_CON_A2SYS_TIMING_ON;
 case MT8188_TOP_CG_26M_TIMING:
  return ASYS_TOP_CON_26M_TIMING_ON;
 default:
  return 0;
 }
}

static unsigned int get_top_cg_on_val(unsigned int cg_type)
{
 switch (cg_type) {
 case MT8188_TOP_CG_A1SYS_TIMING:
 case MT8188_TOP_CG_A2SYS_TIMING:
 case MT8188_TOP_CG_26M_TIMING:
  return get_top_cg_mask(cg_type);
 default:
  return 0;
 }
}

static unsigned int get_top_cg_off_val(unsigned int cg_type)
{
 switch (cg_type) {
 case MT8188_TOP_CG_A1SYS_TIMING:
 case MT8188_TOP_CG_A2SYS_TIMING:
 case MT8188_TOP_CG_26M_TIMING:
  return 0;
 default:
  return get_top_cg_mask(cg_type);
 }
}

static int mt8188_afe_enable_top_cg(struct mtk_base_afe *afe, unsigned int cg_type)
{
 unsigned int reg = get_top_cg_reg(cg_type);
 unsigned int mask = get_top_cg_mask(cg_type);
 unsigned int val = get_top_cg_on_val(cg_type);

 regmap_update_bits(afe->regmap, reg, mask, val);

 return 0;
}

static int mt8188_afe_disable_top_cg(struct mtk_base_afe *afe, unsigned int cg_type)
{
 unsigned int reg = get_top_cg_reg(cg_type);
 unsigned int mask = get_top_cg_mask(cg_type);
 unsigned int val = get_top_cg_off_val(cg_type);

 regmap_update_bits(afe->regmap, reg, mask, val);

 return 0;
}

int mt8188_afe_enable_reg_rw_clk(struct mtk_base_afe *afe)
{
 struct mt8188_afe_private *afe_priv = afe->platform_priv;

 /* bus clock for AFE external access, like DRAM */
 mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_TOP_AUDIO_LOCAL_BUS_SEL]);

 /* bus clock for AFE internal access, like AFE SRAM */
 mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_TOP_AUD_INTBUS_SEL]);

 /* audio 26m clock source */
 mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_ADSP_AUDIO_26M]);

 /* AFE hw clock */
 mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE]);
 mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS_HP]);
 mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]);

 return 0;
}

int mt8188_afe_disable_reg_rw_clk(struct mtk_base_afe *afe)
{
 struct mt8188_afe_private *afe_priv = afe->platform_priv;

 mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]);
 mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS_HP]);
 mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE]);
 mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_ADSP_AUDIO_26M]);
 mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_TOP_AUD_INTBUS_SEL]);
 mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_TOP_AUDIO_LOCAL_BUS_SEL]);

 return 0;
}

static int mt8188_afe_enable_afe_on(struct mtk_base_afe *afe)
{
 regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x1);
 return 0;
}

static int mt8188_afe_disable_afe_on(struct mtk_base_afe *afe)
{
 regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x0);
 return 0;
}

static int mt8188_afe_enable_a1sys(struct mtk_base_afe *afe)
{
 struct mt8188_afe_private *afe_priv = afe->platform_priv;
 int ret;

 ret = mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]);
 if (ret)
  return ret;

 return mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_A1SYS_TIMING);
}

static int mt8188_afe_disable_a1sys(struct mtk_base_afe *afe)
{
 struct mt8188_afe_private *afe_priv = afe->platform_priv;

 mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_A1SYS_TIMING);
 mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]);
 return 0;
}

static int mt8188_afe_enable_a2sys(struct mtk_base_afe *afe)
{
 struct mt8188_afe_private *afe_priv = afe->platform_priv;
 int ret;

 ret = mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A2SYS]);
 if (ret)
  return ret;

 return mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_A2SYS_TIMING);
}

static int mt8188_afe_disable_a2sys(struct mtk_base_afe *afe)
{
 struct mt8188_afe_private *afe_priv = afe->platform_priv;

 mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_A2SYS_TIMING);
 mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A2SYS]);
 return 0;
}

int mt8188_apll1_enable(struct mtk_base_afe *afe)
{
 struct mt8188_afe_private *afe_priv = afe->platform_priv;
 int ret;

 ret = mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_TOP_APLL1_D4]);
 if (ret)
  return ret;

 ret = mt8188_afe_set_clk_parent(afe, afe_priv->clk[MT8188_CLK_TOP_A1SYS_HP_SEL],
     afe_priv->clk[MT8188_CLK_TOP_APLL1_D4]);
 if (ret)
  goto err_clk_parent;

 ret = mt8188_afe_enable_apll_tuner(afe, MT8188_AUD_PLL1);
 if (ret)
  goto err_apll_tuner;

 ret = mt8188_afe_enable_a1sys(afe);
 if (ret)
  goto err_a1sys;

 return 0;

err_a1sys:
 mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL1);
err_apll_tuner:
 mt8188_afe_set_clk_parent(afe, afe_priv->clk[MT8188_CLK_TOP_A1SYS_HP_SEL],
      afe_priv->clk[MT8188_CLK_XTAL_26M]);
err_clk_parent:
 mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_TOP_APLL1_D4]);

 return ret;
}

int mt8188_apll1_disable(struct mtk_base_afe *afe)
{
 struct mt8188_afe_private *afe_priv = afe->platform_priv;

 mt8188_afe_disable_a1sys(afe);
 mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL1);
 mt8188_afe_set_clk_parent(afe, afe_priv->clk[MT8188_CLK_TOP_A1SYS_HP_SEL],
      afe_priv->clk[MT8188_CLK_XTAL_26M]);
 mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_TOP_APLL1_D4]);

 return 0;
}

int mt8188_apll2_enable(struct mtk_base_afe *afe)
{
 int ret;

 ret = mt8188_afe_enable_apll_tuner(afe, MT8188_AUD_PLL2);
 if (ret)
  return ret;

 ret =  mt8188_afe_enable_a2sys(afe);
 if (ret)
  goto err_a2sys;

 return 0;
err_a2sys:
 mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL2);

 return ret;
}

int mt8188_apll2_disable(struct mtk_base_afe *afe)
{
 mt8188_afe_disable_a2sys(afe);
 mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL2);
 return 0;
}

int mt8188_afe_enable_main_clock(struct mtk_base_afe *afe)
{
 mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_26M_TIMING);
 mt8188_afe_enable_afe_on(afe);
 return 0;
}

int mt8188_afe_disable_main_clock(struct mtk_base_afe *afe)
{
 mt8188_afe_disable_afe_on(afe);
 mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_26M_TIMING);
 return 0;
}

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

¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© 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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge