From 5e549a0c18fc0321c18e7b6842cb7afc90aab396 Mon Sep 17 00:00:00 2001 From: Petr Kulhavy Date: Mon, 3 Oct 2016 16:40:49 +0200 Subject: [PATCH 01/11] ASoC: tas571x: wait 50ms after oscillator trim Wait extra 50ms after writing the oscillator trim register in probe(), as recommended by the TAS5721 and TAS5711 datasheets. Signed-off-by: Petr Kulhavy Signed-off-by: Mark Brown --- sound/soc/codecs/tas571x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/tas571x.c b/sound/soc/codecs/tas571x.c index df5e5cb33baa..de65ecf534af 100644 --- a/sound/soc/codecs/tas571x.c +++ b/sound/soc/codecs/tas571x.c @@ -754,6 +754,7 @@ static int tas571x_i2c_probe(struct i2c_client *client, if (ret) return ret; + usleep_range(50000, 60000); memcpy(&priv->codec_driver, &tas571x_codec, sizeof(priv->codec_driver)); priv->codec_driver.component_driver.controls = priv->chip->controls; From 960695670502afa153c2294e15ca790dbe086f4d Mon Sep 17 00:00:00 2001 From: Petr Kulhavy Date: Mon, 3 Oct 2016 16:40:50 +0200 Subject: [PATCH 02/11] ASoC: tas571x: move mixer volume controls from TAS5711 to TAS5717 Channel 1 and 2 Mixer Volume controls (registers 0x72/0x73 and 0x76/0x77) were wrongly assigned to tas5711_controls in commit f252d2346022 ("ASoC: tas571x: add input channel mixer for TAS5717/19") Therefore move them to tas5717_controls. Signed-off-by: Petr Kulhavy Signed-off-by: Mark Brown --- sound/soc/codecs/tas571x.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/sound/soc/codecs/tas571x.c b/sound/soc/codecs/tas571x.c index de65ecf534af..34e4ce6f23d8 100644 --- a/sound/soc/codecs/tas571x.c +++ b/sound/soc/codecs/tas571x.c @@ -401,16 +401,6 @@ static const struct snd_kcontrol_new tas5711_controls[] = { TAS571X_SOFT_MUTE_REG, TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT, 1, 1), - - SOC_DOUBLE_R_RANGE("CH1 Mixer Volume", - TAS5717_CH1_LEFT_CH_MIX_REG, - TAS5717_CH1_RIGHT_CH_MIX_REG, - 16, 0, 0x80, 0), - - SOC_DOUBLE_R_RANGE("CH2 Mixer Volume", - TAS5717_CH2_LEFT_CH_MIX_REG, - TAS5717_CH2_RIGHT_CH_MIX_REG, - 16, 0, 0x80, 0), }; static const struct regmap_range tas571x_readonly_regs_range[] = { @@ -488,6 +478,16 @@ static const struct snd_kcontrol_new tas5717_controls[] = { TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT, 1, 1), + SOC_DOUBLE_R_RANGE("CH1 Mixer Volume", + TAS5717_CH1_LEFT_CH_MIX_REG, + TAS5717_CH1_RIGHT_CH_MIX_REG, + 16, 0, 0x80, 0), + + SOC_DOUBLE_R_RANGE("CH2 Mixer Volume", + TAS5717_CH2_LEFT_CH_MIX_REG, + TAS5717_CH2_RIGHT_CH_MIX_REG, + 16, 0, 0x80, 0), + /* * The biquads are named according to the register names. * Please note that TI's TAS57xx Graphical Development Environment From e54de7f555970915c3856e7709a7ff74d352f315 Mon Sep 17 00:00:00 2001 From: Petr Kulhavy Date: Mon, 3 Oct 2016 16:40:47 +0200 Subject: [PATCH 03/11] ASoC: tas571x: extend the t_i2c time to comply with TAS5721 TAS5721 datasheet recommends to wait at least 13.5ms after deasserting the RESET signal. For TAS5717 this time is only 12ms, which was the original value in the code. Extend the wait time after deasserting RESET from 12 to 13.5ms to comply with the TAS5721 specification. Signed-off-by: Petr Kulhavy Signed-off-by: Mark Brown --- sound/soc/codecs/tas571x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/tas571x.c b/sound/soc/codecs/tas571x.c index 34e4ce6f23d8..512b9e663e89 100644 --- a/sound/soc/codecs/tas571x.c +++ b/sound/soc/codecs/tas571x.c @@ -747,7 +747,7 @@ static int tas571x_i2c_probe(struct i2c_client *client, /* pulse the active low reset line for ~100us */ usleep_range(100, 200); gpiod_set_value(priv->reset_gpio, 0); - usleep_range(12000, 20000); + usleep_range(13500, 20000); } ret = regmap_write(priv->regmap, TAS571X_OSC_TRIM_REG, 0); From 8b0678dc914271e9ad4317fe82555ead92ce1cb9 Mon Sep 17 00:00:00 2001 From: Petr Kulhavy Date: Mon, 3 Oct 2016 16:40:48 +0200 Subject: [PATCH 04/11] ASoC: tas571x: remove improper PDN signal usage in set_bias_level The set_bias_level toggles the PDN signal when entering SND_SOC_BIAS_STANDBY and SND_SOC_BIAS_OFF. However this has no effect and actually breaks things down (tested with TAS5717) due to the following reasons: 1) holding down PDN does not save power but holding down RST does 2) now hard mute via register 0x5 is implemented and therefore it is no longer needed to toggle PDN to enter all channel shut down 3) in order to leave PDN it is required to toggle the RST signal (see TAS5721 datasheet), which was not implemented 4) toggling PDN as implemented actually mutes PWMs and there is no audio output (tested on TAS5717) For these reasons remove the PDN signal toggling and just initialize it to inactive in probe(). Signed-off-by: Petr Kulhavy Signed-off-by: Mark Brown --- sound/soc/codecs/tas571x.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/sound/soc/codecs/tas571x.c b/sound/soc/codecs/tas571x.c index 512b9e663e89..810369f687d7 100644 --- a/sound/soc/codecs/tas571x.c +++ b/sound/soc/codecs/tas571x.c @@ -341,20 +341,9 @@ static int tas571x_set_bias_level(struct snd_soc_codec *codec, return ret; } } - - gpiod_set_value(priv->pdn_gpio, 0); - usleep_range(5000, 6000); - - regcache_cache_only(priv->regmap, false); - ret = regcache_sync(priv->regmap); - if (ret) - return ret; } break; case SND_SOC_BIAS_OFF: - regcache_cache_only(priv->regmap, true); - gpiod_set_value(priv->pdn_gpio, 1); - if (!IS_ERR(priv->mclk)) clk_disable_unprepare(priv->mclk); break; @@ -771,9 +760,6 @@ static int tas571x_i2c_probe(struct i2c_client *client, return ret; } - regcache_cache_only(priv->regmap, true); - gpiod_set_value(priv->pdn_gpio, 1); - return snd_soc_register_codec(&client->dev, &priv->codec_driver, &tas571x_dai, 1); } From c975e39ccadf6dc047356c60773a043a2293b8cd Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 13 Oct 2016 11:47:13 +0300 Subject: [PATCH 05/11] ASoC: rt5663: fix a debug statement We increment "i" before printing the debug statement. That makes it the wrong sleep_time[] information and Smatch complains that the last increment could be beyond the end of the array. Signed-off-by: Dan Carpenter Acked-by: Bard Liao Signed-off-by: Mark Brown --- sound/soc/codecs/rt5663.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c index 01a18d88f1eb..00ff2788879e 100644 --- a/sound/soc/codecs/rt5663.c +++ b/sound/soc/codecs/rt5663.c @@ -1547,11 +1547,11 @@ static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert) msleep(sleep_time[i]); val = snd_soc_read(codec, RT5663_EM_JACK_TYPE_2) & 0x0003; + dev_dbg(codec->dev, "%s: MX-00e7 val=%x sleep %d\n", + __func__, val, sleep_time[i]); i++; if (val == 0x1 || val == 0x2 || val == 0x3) break; - dev_dbg(codec->dev, "%s: MX-00e7 val=%x sleep %d\n", - __func__, val, sleep_time[i]); } dev_dbg(codec->dev, "%s val = %d\n", __func__, val); switch (val) { From 1e6d304431958929b601b013687b73293ba27b88 Mon Sep 17 00:00:00 2001 From: Arnaud Pouliquen Date: Mon, 24 Oct 2016 16:42:52 +0200 Subject: [PATCH 06/11] ASoC: sti: fix channel status update after playback start If 'IEC958 Playback Default' control is updated during playback, Channel status needs to be set according to the runtime structure. Signed-off-by: Arnaud Pouliquen Signed-off-by: Mark Brown --- sound/soc/sti/uniperif_player.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sound/soc/sti/uniperif_player.c b/sound/soc/sti/uniperif_player.c index 1bc8ebc2528e..ad54d4cf58ad 100644 --- a/sound/soc/sti/uniperif_player.c +++ b/sound/soc/sti/uniperif_player.c @@ -614,7 +614,11 @@ static int uni_player_ctl_iec958_put(struct snd_kcontrol *kcontrol, iec958->status[3] = ucontrol->value.iec958.status[3]; mutex_unlock(&player->ctrl_lock); - uni_player_set_channel_status(player, NULL); + if (player->substream && player->substream->runtime) + uni_player_set_channel_status(player, + player->substream->runtime); + else + uni_player_set_channel_status(player, NULL); return 0; } From 7e235deb69dc7b1c4b5e1ac63a3157ef98ceeff3 Mon Sep 17 00:00:00 2001 From: Arnaud Pouliquen Date: Mon, 24 Oct 2016 16:42:57 +0200 Subject: [PATCH 07/11] ASoC: sti-sas: enable fast io for regmap Some registers accesses are done in atomic context. Enable fast io to use spinlock instead of mutex to protect access. Signed-off-by: Arnaud Pouliquen Signed-off-by: Mark Brown --- sound/soc/codecs/sti-sas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/sti-sas.c b/sound/soc/codecs/sti-sas.c index 7b31ee9b82bc..d6e00c77edcd 100644 --- a/sound/soc/codecs/sti-sas.c +++ b/sound/soc/codecs/sti-sas.c @@ -424,7 +424,7 @@ static const struct snd_soc_dai_ops stih407_dac_ops = { static const struct regmap_config stih407_sas_regmap = { .reg_bits = 32, .val_bits = 32, - + .fast_io = true, .max_register = STIH407_AUDIO_DAC_CTRL, .reg_defaults = stih407_sas_reg_defaults, .num_reg_defaults = ARRAY_SIZE(stih407_sas_reg_defaults), From 73f5dfc68316bef2ab7062ecdefd4b0ca941b4c1 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 27 Oct 2016 12:34:02 +0200 Subject: [PATCH 08/11] ASoC: samsung: get access to DMA engine early to defer probe properly ASoC Samsung sub-drivers tried to get access to their DMA engine controllers as a last step in driver probe. If a DMA engine was not available yet, samsung_asoc_dma_platform_register() function ended in -EPROBE_DEFER, but the driver already registered its component to ASoC core. This patch moves samsung_asoc_dma_platform_register() call before registering any components, to the common place, where driver was gathering all needed resources. In case of Samsung Exynos i2s driver the issue was even worse. The driver managed already to register its secondary DAI platform device before even getting the DMA engine access. That together with -EPROBE_DEFER error code from samsung_i2s_probe() immediately triggered another round of deferred probe retry and in turn endless loop of driver probing. This patch fixes broken boot on Odroid XU3 and other Exynos5422-based boards. Signed-off-by: Marek Szyprowski Reviewed-by: Javier Martinez Canillas Reviewed-by: Sylwester Nawrocki Signed-off-by: Mark Brown --- sound/soc/samsung/ac97.c | 10 +++++----- sound/soc/samsung/i2s.c | 19 ++++++++++--------- sound/soc/samsung/pcm.c | 21 +++++++++++---------- sound/soc/samsung/s3c2412-i2s.c | 18 +++++++++--------- sound/soc/samsung/s3c24xx-i2s.c | 16 ++++++++-------- sound/soc/samsung/spdif.c | 14 +++++++------- 6 files changed, 50 insertions(+), 48 deletions(-) diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c index 97d6700b1009..cbc0023c2bc8 100644 --- a/sound/soc/samsung/ac97.c +++ b/sound/soc/samsung/ac97.c @@ -383,11 +383,6 @@ static int s3c_ac97_probe(struct platform_device *pdev) goto err4; } - ret = devm_snd_soc_register_component(&pdev->dev, &s3c_ac97_component, - s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai)); - if (ret) - goto err5; - ret = samsung_asoc_dma_platform_register(&pdev->dev, ac97_pdata->dma_filter, NULL, NULL); @@ -396,6 +391,11 @@ static int s3c_ac97_probe(struct platform_device *pdev) goto err5; } + ret = devm_snd_soc_register_component(&pdev->dev, &s3c_ac97_component, + s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai)); + if (ret) + goto err5; + return 0; err5: free_irq(irq_res->start, NULL); diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 7e32cf4581f8..7825bff45ae3 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -1237,14 +1237,14 @@ static int samsung_i2s_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Unable to get drvdata\n"); return -EFAULT; } - ret = devm_snd_soc_register_component(&sec_dai->pdev->dev, - &samsung_i2s_component, - &sec_dai->i2s_dai_drv, 1); + ret = samsung_asoc_dma_platform_register(&pdev->dev, + sec_dai->filter, "tx-sec", NULL); if (ret != 0) return ret; - return samsung_asoc_dma_platform_register(&pdev->dev, - sec_dai->filter, "tx-sec", NULL); + return devm_snd_soc_register_component(&sec_dai->pdev->dev, + &samsung_i2s_component, + &sec_dai->i2s_dai_drv, 1); } pri_dai = i2s_alloc_dai(pdev, false); @@ -1314,6 +1314,11 @@ static int samsung_i2s_probe(struct platform_device *pdev) if (quirks & QUIRK_PRI_6CHAN) pri_dai->i2s_dai_drv.playback.channels_max = 6; + ret = samsung_asoc_dma_platform_register(&pdev->dev, pri_dai->filter, + NULL, NULL); + if (ret < 0) + goto err_disable_clk; + if (quirks & QUIRK_SEC_DAI) { sec_dai = i2s_alloc_dai(pdev, true); if (!sec_dai) { @@ -1353,10 +1358,6 @@ static int samsung_i2s_probe(struct platform_device *pdev) if (ret < 0) goto err_free_dai; - ret = samsung_asoc_dma_platform_register(&pdev->dev, pri_dai->filter, - NULL, NULL); - if (ret < 0) - goto err_free_dai; pm_runtime_enable(&pdev->dev); diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index 43e367a9acc3..c484985812ed 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c @@ -565,15 +565,6 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev) pcm->dma_capture = &s3c_pcm_stereo_in[pdev->id]; pcm->dma_playback = &s3c_pcm_stereo_out[pdev->id]; - pm_runtime_enable(&pdev->dev); - - ret = devm_snd_soc_register_component(&pdev->dev, &s3c_pcm_component, - &s3c_pcm_dai[pdev->id], 1); - if (ret != 0) { - dev_err(&pdev->dev, "failed to get register DAI: %d\n", ret); - goto err5; - } - ret = samsung_asoc_dma_platform_register(&pdev->dev, filter, NULL, NULL); if (ret) { @@ -581,8 +572,18 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev) goto err5; } - return 0; + pm_runtime_enable(&pdev->dev); + ret = devm_snd_soc_register_component(&pdev->dev, &s3c_pcm_component, + &s3c_pcm_dai[pdev->id], 1); + if (ret != 0) { + dev_err(&pdev->dev, "failed to get register DAI: %d\n", ret); + goto err6; + } + + return 0; +err6: + pm_runtime_disable(&pdev->dev); err5: clk_disable_unprepare(pcm->pclk); err4: diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c index 3e89fbc0c51d..0a4718207e6e 100644 --- a/sound/soc/samsung/s3c2412-i2s.c +++ b/sound/soc/samsung/s3c2412-i2s.c @@ -168,19 +168,19 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev) s3c2412_i2s_pcm_stereo_in.addr = res->start + S3C2412_IISRXD; s3c2412_i2s_pcm_stereo_in.filter_data = pdata->dma_capture; - ret = s3c_i2sv2_register_component(&pdev->dev, -1, - &s3c2412_i2s_component, - &s3c2412_i2s_dai); - if (ret) { - pr_err("failed to register the dai\n"); - return ret; - } - ret = samsung_asoc_dma_platform_register(&pdev->dev, pdata->dma_filter, NULL, NULL); - if (ret) + if (ret) { pr_err("failed to register the DMA: %d\n", ret); + return ret; + } + + ret = s3c_i2sv2_register_component(&pdev->dev, -1, + &s3c2412_i2s_component, + &s3c2412_i2s_dai); + if (ret) + pr_err("failed to register the dai\n"); return ret; } diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c index c78a936a3099..9052f6a7073e 100644 --- a/sound/soc/samsung/s3c24xx-i2s.c +++ b/sound/soc/samsung/s3c24xx-i2s.c @@ -474,18 +474,18 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev) s3c24xx_i2s_pcm_stereo_in.addr = res->start + S3C2410_IISFIFO; s3c24xx_i2s_pcm_stereo_in.filter_data = pdata->dma_capture; - ret = devm_snd_soc_register_component(&pdev->dev, - &s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1); - if (ret) { - pr_err("failed to register the dai\n"); - return ret; - } - ret = samsung_asoc_dma_platform_register(&pdev->dev, pdata->dma_filter, NULL, NULL); - if (ret) + if (ret) { pr_err("failed to register the dma: %d\n", ret); + return ret; + } + + ret = devm_snd_soc_register_component(&pdev->dev, + &s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1); + if (ret) + pr_err("failed to register the dai\n"); return ret; } diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c index 26c1fbed4d35..704b7b12bf8b 100644 --- a/sound/soc/samsung/spdif.c +++ b/sound/soc/samsung/spdif.c @@ -416,6 +416,13 @@ static int spdif_probe(struct platform_device *pdev) goto err3; } + ret = samsung_asoc_dma_platform_register(&pdev->dev, filter, + NULL, NULL); + if (ret) { + dev_err(&pdev->dev, "failed to register DMA: %d\n", ret); + goto err4; + } + dev_set_drvdata(&pdev->dev, spdif); ret = devm_snd_soc_register_component(&pdev->dev, @@ -435,13 +442,6 @@ static int spdif_probe(struct platform_device *pdev) spdif->dma_playback = &spdif_stereo_out; - ret = samsung_asoc_dma_platform_register(&pdev->dev, filter, - NULL, NULL); - if (ret) { - dev_err(&pdev->dev, "failed to register DMA: %d\n", ret); - goto err4; - } - return 0; err4: iounmap(spdif->regs); From 85915b63ad8b796848f431b66c9ba5e356e722e5 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Mon, 31 Oct 2016 14:42:09 +0800 Subject: [PATCH 09/11] ASoC: sun4i-codec: return error code instead of NULL when create_card fails When sun4i_codec_create_card fails, we do not assign a proper error code to the return value. The return value would be 0 from the previous function call, or we would have bailed out sooner. This would confuse the driver core into thinking the device probe succeeded, when in fact it didn't, leaving various devres based resources lingering. Make the create_card function pass back a meaningful error code, and assign it to the return value. Fixes: 45fb6b6f2aa3 ("ASoC: sunxi: add support for the on-chip codec on early Allwinner SoCs") Signed-off-by: Chen-Yu Tsai Signed-off-by: Mark Brown --- sound/soc/sunxi/sun4i-codec.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c index e047ec06d538..a60707761abf 100644 --- a/sound/soc/sunxi/sun4i-codec.c +++ b/sound/soc/sunxi/sun4i-codec.c @@ -765,11 +765,11 @@ static struct snd_soc_card *sun4i_codec_create_card(struct device *dev) card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); if (!card) - return NULL; + return ERR_PTR(-ENOMEM); card->dai_link = sun4i_codec_create_link(dev, &card->num_links); if (!card->dai_link) - return NULL; + return ERR_PTR(-ENOMEM); card->dev = dev; card->name = "sun4i-codec"; @@ -876,7 +876,8 @@ static int sun4i_codec_probe(struct platform_device *pdev) } card = sun4i_codec_create_card(&pdev->dev); - if (!card) { + if (IS_ERR(card)) { + ret = PTR_ERR(card); dev_err(&pdev->dev, "Failed to create our card\n"); goto err_unregister_codec; } From 3716a891d65cc04217da1af5f2bccb7eaf6092c2 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 1 Nov 2016 14:31:55 +0800 Subject: [PATCH 10/11] ASoC: sun4i-codec: Enable bus clock after getting GPIO In the current probe function the GPIO is acquired after the codec's bus clock is enabled. However if it fails to acquire the GPIO due to a deferred probe, it does not disable the bus clock before bailing out. This would result in the clock being enabled multiple times. Move the code that enables the bus clock after the part that gets the GPIO, maintaining a separation between resource acquisition and device enablement in the probe function. Signed-off-by: Chen-Yu Tsai Signed-off-by: Mark Brown --- sound/soc/sunxi/sun4i-codec.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c index a60707761abf..56ed9472e89f 100644 --- a/sound/soc/sunxi/sun4i-codec.c +++ b/sound/soc/sunxi/sun4i-codec.c @@ -829,12 +829,6 @@ static int sun4i_codec_probe(struct platform_device *pdev) return PTR_ERR(scodec->clk_module); } - /* Enable the bus clock */ - if (clk_prepare_enable(scodec->clk_apb)) { - dev_err(&pdev->dev, "Failed to enable the APB clock\n"); - return -EINVAL; - } - scodec->gpio_pa = devm_gpiod_get_optional(&pdev->dev, "allwinner,pa", GPIOD_OUT_LOW); if (IS_ERR(scodec->gpio_pa)) { @@ -844,6 +838,12 @@ static int sun4i_codec_probe(struct platform_device *pdev) return ret; } + /* Enable the bus clock */ + if (clk_prepare_enable(scodec->clk_apb)) { + dev_err(&pdev->dev, "Failed to enable the APB clock\n"); + return -EINVAL; + } + /* DMA configuration for TX FIFO */ scodec->playback_dma_data.addr = res->start + SUN4I_CODEC_DAC_TXDATA; scodec->playback_dma_data.maxburst = 4; From a4513320423a388ed55eb0754353f46b10d05a99 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 2 Nov 2016 12:03:03 +0100 Subject: [PATCH 11/11] ASoC: samsung: spdif: Fix DMA filter initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes issues introduced in commit 73f5dfc68316bef2ab7062ec "ASoC: samsung: get access to DMA engine early to defer probe properly" and indicated by a following compilation warning: CC [M] sound/soc/samsung/spdif.o sound/soc/samsung/spdif.c: In function ‘spdif_probe’: sound/soc/samsung/spdif.c:419:6: warning: ‘filter’ may be used uninitialized in this function [-Wuninitialized] Signed-off-by: Sylwester Nawrocki Signed-off-by: Mark Brown --- sound/soc/samsung/spdif.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c index 704b7b12bf8b..779504f54bc0 100644 --- a/sound/soc/samsung/spdif.c +++ b/sound/soc/samsung/spdif.c @@ -416,6 +416,15 @@ static int spdif_probe(struct platform_device *pdev) goto err3; } + spdif_stereo_out.addr_width = 2; + spdif_stereo_out.addr = mem_res->start + DATA_OUTBUF; + filter = NULL; + if (spdif_pdata) { + spdif_stereo_out.filter_data = spdif_pdata->dma_playback; + filter = spdif_pdata->dma_filter; + } + spdif->dma_playback = &spdif_stereo_out; + ret = samsung_asoc_dma_platform_register(&pdev->dev, filter, NULL, NULL); if (ret) { @@ -432,16 +441,6 @@ static int spdif_probe(struct platform_device *pdev) goto err4; } - spdif_stereo_out.addr_width = 2; - spdif_stereo_out.addr = mem_res->start + DATA_OUTBUF; - filter = NULL; - if (spdif_pdata) { - spdif_stereo_out.filter_data = spdif_pdata->dma_playback; - filter = spdif_pdata->dma_filter; - } - - spdif->dma_playback = &spdif_stereo_out; - return 0; err4: iounmap(spdif->regs);