audio: fixed cvbs audio pop noise on g12a/b [1/1]
authorZhe Wang <Zhe.Wang@amlogic.com>
Thu, 13 Jun 2019 08:48:09 +0000 (16:48 +0800)
committerNick Xie <nick@khadas.com>
Mon, 5 Aug 2019 06:45:45 +0000 (14:45 +0800)
PD#OTT-3760, PD#SWPL-8309

Problem:
startup ott, cvbs out with pop noise

Solution:
Set gpio init low

Verify:
verified by franklin

Change-Id: Ieb33e72473055fad69bc8e9a68ed0b0552e9f029
Signed-off-by: Zhe Wang <Zhe.Wang@amlogic.com>
sound/soc/amlogic/auge/card.c
sound/soc/codecs/amlogic/aml_codec_t9015.c

index 4002587..f0b32d3 100644 (file)
@@ -71,6 +71,7 @@ struct aml_card_data {
        struct gpio_desc *avout_mute_desc;
        struct timer_list timer;
        struct work_struct work;
+       struct work_struct init_work;
        bool hp_last_state;
        bool hp_cur_state;
        bool hp_det_status;
@@ -741,24 +742,41 @@ static int aml_card_parse_gpios(struct device_node *node,
                priv->spk_mute_active_low = active_low;
 
                ret = devm_gpio_request_one(dev, gpio, flags, "spk_mute");
-               if (ret < 0)
-                       return ret;
-
-               ret = snd_soc_add_card_controls(soc_card, card_controls,
+               if (ret >= 0) {
+                       snd_soc_add_card_controls(soc_card, card_controls,
                                        ARRAY_SIZE(card_controls));
+               }
        }
 
        priv->avout_mute_desc = gpiod_get(dev,
-                               "avout_mute",
-                               GPIOD_OUT_HIGH);
+                               "avout_mute", GPIOF_OUT_INIT_LOW);
+       if (!IS_ERR(priv->avout_mute_desc)) {
+               msleep(500);
+               gpiod_direction_output(priv->avout_mute_desc,
+                       GPIOF_OUT_INIT_HIGH);
+               pr_info("av out status: %s\n",
+                       gpiod_get_value(priv->avout_mute_desc) ?
+                       "high" : "low");
 
-       gpiod_direction_output(priv->avout_mute_desc,
-               GPIOF_OUT_INIT_HIGH);
-       pr_info("set av out GPIOF_OUT_INIT_HIGH!\n");
+       }
 
        return 0;
 }
 
+static void aml_init_work(struct work_struct *init_work)
+{
+       struct aml_card_data *priv = NULL;
+       struct device *dev = NULL;
+       struct device_node *np = NULL;
+
+       priv = container_of(init_work,
+                       struct aml_card_data, init_work);
+       dev = aml_priv_to_dev(priv);
+       np = dev->of_node;
+
+       aml_card_parse_gpios(np, priv);
+}
+
 static int aml_card_parse_of(struct device_node *node,
                                     struct aml_card_data *priv)
 {
@@ -963,9 +981,11 @@ static int aml_card_probe(struct platform_device *pdev)
                audio_jack_detect(priv);
                audio_extcon_register(priv, dev);
        }
-       ret = aml_card_parse_gpios(np, priv);
-       if (ret >= 0)
-               return ret;
+
+       INIT_WORK(&priv->init_work, aml_init_work);
+       schedule_work(&priv->init_work);
+
+       return 0;
 err:
        pr_err("%s error ret:%d\n", __func__, ret);
        aml_card_clean_reference(&priv->snd_card);
index 2fbfe60..31cebb7 100644 (file)
@@ -63,13 +63,29 @@ static const struct reg_default t9015_init_list[] = {
        {POWER_CONFIG, 0x00010000},
 };
 
+static const struct reg_default t9015_init_list_V2[] = {
+       {AUDIO_CONFIG_BLOCK_ENABLE, 0x0000B00F},
+       {ADC_VOL_CTR_PGA_IN_CONFIG, 0x00000000},
+       {DAC_VOL_CTR_DAC_SOFT_MUTE, 0xFBFB0000},
+       {LINE_OUT_CONFIG, 0x00001111},
+       {POWER_CONFIG, 0x00010000},
+};
+
 static int aml_T9015_audio_reg_init(struct snd_soc_codec *codec)
 {
        int i;
+       struct aml_T9015_audio_priv *T9015_audio =
+                               snd_soc_codec_get_drvdata(codec);
 
-       for (i = 0; i < ARRAY_SIZE(t9015_init_list); i++)
-               snd_soc_write(codec, t9015_init_list[i].reg,
-                               t9015_init_list[i].def);
+       if (T9015_audio && T9015_audio->is_auge_arch) {
+               for (i = 0; i < ARRAY_SIZE(t9015_init_list_V2); i++)
+                       snd_soc_write(codec, t9015_init_list_V2[i].reg,
+                                       t9015_init_list_V2[i].def);
+       } else {
+               for (i = 0; i < ARRAY_SIZE(t9015_init_list); i++)
+                       snd_soc_write(codec, t9015_init_list[i].reg,
+                                       t9015_init_list[i].def);
+       }
 
        return 0;
 }
@@ -229,6 +245,43 @@ static const struct snd_soc_dapm_widget T9015_audio_dapm_widgets[] = {
                         0, 0, &line_out_rn_mux),
 };
 
+static const struct snd_soc_dapm_widget T9015_audio_dapm_widgets_V2[] = {
+
+       /*Output */
+       SND_SOC_DAPM_OUTPUT("Lineout left N"),
+       SND_SOC_DAPM_OUTPUT("Lineout left P"),
+       SND_SOC_DAPM_OUTPUT("Lineout right N"),
+       SND_SOC_DAPM_OUTPUT("Lineout right P"),
+
+       /*DAC playback stream */
+       SND_SOC_DAPM_DAC("Left DAC", "HIFI Playback",
+                        AUDIO_CONFIG_BLOCK_ENABLE,
+                        DACL_EN, 0),
+       SND_SOC_DAPM_DAC("Right DAC", "HIFI Playback",
+                        AUDIO_CONFIG_BLOCK_ENABLE,
+                        DACR_EN, 0),
+
+       /*DRV output */
+       SND_SOC_DAPM_OUT_DRV("LOLP_OUT_EN", SND_SOC_NOPM,
+                            0, 0, NULL, 0),
+       SND_SOC_DAPM_OUT_DRV("LOLN_OUT_EN", SND_SOC_NOPM,
+                            0, 0, NULL, 0),
+       SND_SOC_DAPM_OUT_DRV("LORP_OUT_EN", SND_SOC_NOPM,
+                            0, 0, NULL, 0),
+       SND_SOC_DAPM_OUT_DRV("LORN_OUT_EN", SND_SOC_NOPM,
+                            0, 0, NULL, 0),
+
+       /*MUX output source select */
+       SND_SOC_DAPM_MUX("Lineout left P switch", SND_SOC_NOPM,
+                        0, 0, &line_out_lp_mux),
+       SND_SOC_DAPM_MUX("Lineout left N switch", SND_SOC_NOPM,
+                        0, 0, &line_out_ln_mux),
+       SND_SOC_DAPM_MUX("Lineout right P switch", SND_SOC_NOPM,
+                        0, 0, &line_out_rp_mux),
+       SND_SOC_DAPM_MUX("Lineout right N switch", SND_SOC_NOPM,
+                        0, 0, &line_out_rn_mux),
+};
+
 static const struct snd_soc_dapm_route T9015_audio_dapm_routes[] = {
     /*Output path*/
        {"Lineout left P switch", "LOLP_SEL_DACL", "Left DAC"},
@@ -496,6 +549,22 @@ static struct snd_soc_codec_driver soc_codec_dev_aml_T9015_audio = {
        }
 };
 
+static struct snd_soc_codec_driver soc_codec_dev_aml_T9015_audio_V2 = {
+       .probe = aml_T9015_audio_probe,
+       .remove = aml_T9015_audio_remove,
+       .suspend = aml_T9015_audio_suspend,
+       .resume = aml_T9015_audio_resume,
+       .set_bias_level = aml_T9015_audio_set_bias_level,
+       .component_driver = {
+               .controls = T9015_audio_snd_controls,
+               .num_controls = ARRAY_SIZE(T9015_audio_snd_controls),
+               .dapm_widgets = T9015_audio_dapm_widgets_V2,
+               .num_dapm_widgets = ARRAY_SIZE(T9015_audio_dapm_widgets_V2),
+               .dapm_routes = T9015_audio_dapm_routes,
+               .num_dapm_routes = ARRAY_SIZE(T9015_audio_dapm_routes),
+       }
+};
+
 static const struct regmap_config t9015_codec_regmap_config = {
        .reg_bits = 32,
        .reg_stride = 4,
@@ -506,6 +575,17 @@ static const struct regmap_config t9015_codec_regmap_config = {
        .cache_type = REGCACHE_RBTREE,
 };
 
+static const struct regmap_config t9015_codec_regmap_config_V2 = {
+       .reg_bits = 32,
+       .reg_stride = 4,
+       .val_bits = 32,
+       .max_register = 0x14,
+       .reg_defaults = t9015_init_list_V2,
+       .num_reg_defaults = ARRAY_SIZE(t9015_init_list_V2),
+       .cache_type = REGCACHE_RBTREE,
+};
+
+
 static int aml_T9015_audio_codec_probe(struct platform_device *pdev)
 {
        int ret = 0;
@@ -531,9 +611,6 @@ static int aml_T9015_audio_codec_probe(struct platform_device *pdev)
        if (IS_ERR(regs))
                return PTR_ERR(regs);
 
-       regmap = devm_regmap_init_mmio(&pdev->dev, regs,
-                                           &t9015_codec_regmap_config);
-
        T9015_audio->is_auge_arch = of_property_read_bool(
                        pdev->dev.of_node,
                        "is_auge_used");
@@ -561,12 +638,25 @@ static int aml_T9015_audio_codec_probe(struct platform_device *pdev)
                T9015_audio->is_auge_arch ? "auge" : "meson",
                T9015_audio->tdmout_index);
 
-       if (IS_ERR(regmap))
-               return PTR_ERR(regmap);
-
-       ret = snd_soc_register_codec(&pdev->dev,
-                                    &soc_codec_dev_aml_T9015_audio,
-                                    &aml_T9015_audio_dai[0], 1);
+       if (T9015_audio && T9015_audio->is_auge_arch) {
+               regmap = devm_regmap_init_mmio(&pdev->dev, regs,
+                                       &t9015_codec_regmap_config_V2);
+               if (IS_ERR(regmap))
+                       return PTR_ERR(regmap);
+
+               ret = snd_soc_register_codec(&pdev->dev,
+                                       &soc_codec_dev_aml_T9015_audio_V2,
+                                       &aml_T9015_audio_dai[0], 1);
+       } else {
+               regmap = devm_regmap_init_mmio(&pdev->dev, regs,
+                                       &t9015_codec_regmap_config);
+               if (IS_ERR(regmap))
+                       return PTR_ERR(regmap);
+
+               ret = snd_soc_register_codec(&pdev->dev,
+                                       &soc_codec_dev_aml_T9015_audio,
+                                       &aml_T9015_audio_dai[0], 1);
+       }
        return ret;
 }