From 82bf7b59c8ba9dbaccd86a4300def62faa19793b Mon Sep 17 00:00:00 2001 From: Zhe Wang Date: Thu, 13 Jun 2019 16:48:09 +0800 Subject: [PATCH] audio: fixed cvbs audio pop noise on g12a/b [1/1] 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 --- sound/soc/amlogic/auge/card.c | 44 ++++++++--- sound/soc/codecs/amlogic/aml_codec_t9015.c | 114 ++++++++++++++++++++++++++--- 2 files changed, 134 insertions(+), 24 deletions(-) diff --git a/sound/soc/amlogic/auge/card.c b/sound/soc/amlogic/auge/card.c index 4002587..f0b32d3 100644 --- a/sound/soc/amlogic/auge/card.c +++ b/sound/soc/amlogic/auge/card.c @@ -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); diff --git a/sound/soc/codecs/amlogic/aml_codec_t9015.c b/sound/soc/codecs/amlogic/aml_codec_t9015.c index 2fbfe60..31cebb7 100644 --- a/sound/soc/codecs/amlogic/aml_codec_t9015.c +++ b/sound/soc/codecs/amlogic/aml_codec_t9015.c @@ -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; } -- 2.7.4