aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/tegra/tegra30_i2s.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/tegra/tegra30_i2s.c')
-rw-r--r--sound/soc/tegra/tegra30_i2s.c86
1 files changed, 30 insertions, 56 deletions
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c
index d59882ec48f1..10cd37096fb3 100644
--- a/sound/soc/tegra/tegra30_i2s.c
+++ b/sound/soc/tegra/tegra30_i2s.c
@@ -23,6 +23,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
+#include <linux/reset.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
@@ -35,7 +36,7 @@
#define DRV_NAME "tegra30-i2s"
-static int tegra30_i2s_runtime_suspend(struct device *dev)
+static __maybe_unused int tegra30_i2s_runtime_suspend(struct device *dev)
{
struct tegra30_i2s *i2s = dev_get_drvdata(dev);
@@ -46,7 +47,7 @@ static int tegra30_i2s_runtime_suspend(struct device *dev)
return 0;
}
-static int tegra30_i2s_runtime_resume(struct device *dev)
+static __maybe_unused int tegra30_i2s_runtime_resume(struct device *dev)
{
struct tegra30_i2s *i2s = dev_get_drvdata(dev);
int ret;
@@ -58,8 +59,18 @@ static int tegra30_i2s_runtime_resume(struct device *dev)
}
regcache_cache_only(i2s->regmap, false);
+ regcache_mark_dirty(i2s->regmap);
+
+ ret = regcache_sync(i2s->regmap);
+ if (ret)
+ goto disable_clocks;
return 0;
+
+disable_clocks:
+ clk_disable_unprepare(i2s->clk_i2s);
+
+ return ret;
}
static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
@@ -76,11 +87,11 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
}
mask |= TEGRA30_I2S_CTRL_MASTER_ENABLE;
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS:
+ switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
+ case SND_SOC_DAIFMT_BP_FP:
val |= TEGRA30_I2S_CTRL_MASTER_ENABLE;
break;
- case SND_SOC_DAIFMT_CBM_CFM:
+ case SND_SOC_DAIFMT_BC_FC:
break;
default:
return -EINVAL;
@@ -316,11 +327,12 @@ static const struct snd_soc_dai_driver tegra30_i2s_dai_template = {
.formats = SNDRV_PCM_FMTBIT_S16_LE,
},
.ops = &tegra30_i2s_dai_ops,
- .symmetric_rates = 1,
+ .symmetric_rate = 1,
};
static const struct snd_soc_component_driver tegra30_i2s_component = {
- .name = DRV_NAME,
+ .name = DRV_NAME,
+ .legacy_dai_naming = 1,
};
static bool tegra30_i2s_wr_rd_reg(struct device *dev, unsigned int reg)
@@ -395,7 +407,7 @@ static const struct of_device_id tegra30_i2s_of_match[] = {
static int tegra30_i2s_platform_probe(struct platform_device *pdev)
{
struct tegra30_i2s *i2s;
- const struct of_device_id *match;
+ const struct tegra30_i2s_soc_data *soc_data;
u32 cif_ids[2];
void __iomem *regs;
int ret;
@@ -407,13 +419,13 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
}
dev_set_drvdata(&pdev->dev, i2s);
- match = of_match_device(tegra30_i2s_of_match, &pdev->dev);
- if (!match) {
+ soc_data = of_device_get_match_data(&pdev->dev);
+ if (!soc_data) {
dev_err(&pdev->dev, "Error: No device match found\n");
ret = -ENODEV;
goto err;
}
- i2s->soc_data = (struct tegra30_i2s_soc_data *)match->data;
+ i2s->soc_data = soc_data;
i2s->dai = tegra30_i2s_dai_template;
i2s->dai.name = dev_name(&pdev->dev);
@@ -427,7 +439,7 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
i2s->playback_i2s_cif = cif_ids[0];
i2s->capture_i2s_cif = cif_ids[1];
- i2s->clk_i2s = clk_get(&pdev->dev, NULL);
+ i2s->clk_i2s = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(i2s->clk_i2s)) {
dev_err(&pdev->dev, "Can't retrieve i2s clock\n");
ret = PTR_ERR(i2s->clk_i2s);
@@ -437,7 +449,7 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(regs)) {
ret = PTR_ERR(regs);
- goto err_clk_put;
+ goto err;
}
i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
@@ -445,16 +457,11 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
if (IS_ERR(i2s->regmap)) {
dev_err(&pdev->dev, "regmap init failed\n");
ret = PTR_ERR(i2s->regmap);
- goto err_clk_put;
+ goto err;
}
regcache_cache_only(i2s->regmap, true);
pm_runtime_enable(&pdev->dev);
- if (!pm_runtime_enabled(&pdev->dev)) {
- ret = tegra30_i2s_runtime_resume(&pdev->dev);
- if (ret)
- goto err_pm_disable;
- }
i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
i2s->playback_dma_data.maxburst = 4;
@@ -464,7 +471,7 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
&i2s->playback_dma_data.addr);
if (ret) {
dev_err(&pdev->dev, "Could not alloc TX FIFO: %d\n", ret);
- goto err_suspend;
+ goto err_pm_disable;
}
ret = tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif,
i2s->playback_fifo_cif);
@@ -518,13 +525,8 @@ err_unroute_tx_fifo:
tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif);
err_free_tx_fifo:
tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif);
-err_suspend:
- if (!pm_runtime_status_suspended(&pdev->dev))
- tegra30_i2s_runtime_suspend(&pdev->dev);
err_pm_disable:
pm_runtime_disable(&pdev->dev);
-err_clk_put:
- clk_put(i2s->clk_i2s);
err:
return ret;
}
@@ -533,10 +535,6 @@ static int tegra30_i2s_platform_remove(struct platform_device *pdev)
{
struct tegra30_i2s *i2s = dev_get_drvdata(&pdev->dev);
- pm_runtime_disable(&pdev->dev);
- if (!pm_runtime_status_suspended(&pdev->dev))
- tegra30_i2s_runtime_suspend(&pdev->dev);
-
tegra_pcm_platform_unregister(&pdev->dev);
snd_soc_unregister_component(&pdev->dev);
@@ -546,40 +544,16 @@ static int tegra30_i2s_platform_remove(struct platform_device *pdev)
tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif);
tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif);
- clk_put(i2s->clk_i2s);
-
- return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int tegra30_i2s_suspend(struct device *dev)
-{
- struct tegra30_i2s *i2s = dev_get_drvdata(dev);
-
- regcache_mark_dirty(i2s->regmap);
+ pm_runtime_disable(&pdev->dev);
return 0;
}
-static int tegra30_i2s_resume(struct device *dev)
-{
- struct tegra30_i2s *i2s = dev_get_drvdata(dev);
- int ret;
-
- ret = pm_runtime_get_sync(dev);
- if (ret < 0)
- return ret;
- ret = regcache_sync(i2s->regmap);
- pm_runtime_put(dev);
-
- return ret;
-}
-#endif
-
static const struct dev_pm_ops tegra30_i2s_pm_ops = {
SET_RUNTIME_PM_OPS(tegra30_i2s_runtime_suspend,
tegra30_i2s_runtime_resume, NULL)
- SET_SYSTEM_SLEEP_PM_OPS(tegra30_i2s_suspend, tegra30_i2s_resume)
+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ pm_runtime_force_resume)
};
static struct platform_driver tegra30_i2s_driver = {