diff options
Diffstat (limited to 'sound/soc/tegra/tegra20_spdif.c')
| -rw-r--r-- | sound/soc/tegra/tegra20_spdif.c | 78 |
1 files changed, 38 insertions, 40 deletions
diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c index f9b57418bd0..a0ce92400fa 100644 --- a/sound/soc/tegra/tegra20_spdif.c +++ b/sound/soc/tegra/tegra20_spdif.c @@ -32,29 +32,17 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> +#include <sound/dmaengine_pcm.h> #include "tegra20_spdif.h" #define DRV_NAME "tegra20-spdif" -static inline void tegra20_spdif_write(struct tegra20_spdif *spdif, u32 reg, - u32 val) -{ - regmap_write(spdif->regmap, reg, val); -} - -static inline u32 tegra20_spdif_read(struct tegra20_spdif *spdif, u32 reg) -{ - u32 val; - regmap_read(spdif->regmap, reg, &val); - return val; -} - static int tegra20_spdif_runtime_suspend(struct device *dev) { struct tegra20_spdif *spdif = dev_get_drvdata(dev); - clk_disable(spdif->clk_spdif_out); + clk_disable_unprepare(spdif->clk_spdif_out); return 0; } @@ -64,7 +52,7 @@ static int tegra20_spdif_runtime_resume(struct device *dev) struct tegra20_spdif *spdif = dev_get_drvdata(dev); int ret; - ret = clk_enable(spdif->clk_spdif_out); + ret = clk_prepare_enable(spdif->clk_spdif_out); if (ret) { dev_err(dev, "clk_enable failed: %d\n", ret); return ret; @@ -77,21 +65,24 @@ static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { - struct device *dev = substream->pcm->card->dev; + struct device *dev = dai->dev; struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai); + unsigned int mask = 0, val = 0; int ret, spdifclock; - spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_PACK; - spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_BIT_MODE_MASK; + mask |= TEGRA20_SPDIF_CTRL_PACK | + TEGRA20_SPDIF_CTRL_BIT_MODE_MASK; switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: - spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_PACK; - spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT; + val |= TEGRA20_SPDIF_CTRL_PACK | + TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT; break; default: return -EINVAL; } + regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL, mask, val); + switch (params_rate(params)) { case 32000: spdifclock = 4096000; @@ -129,14 +120,15 @@ static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream, static void tegra20_spdif_start_playback(struct tegra20_spdif *spdif) { - spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_TX_EN; - tegra20_spdif_write(spdif, TEGRA20_SPDIF_CTRL, spdif->reg_ctrl); + regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL, + TEGRA20_SPDIF_CTRL_TX_EN, + TEGRA20_SPDIF_CTRL_TX_EN); } static void tegra20_spdif_stop_playback(struct tegra20_spdif *spdif) { - spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_TX_EN; - tegra20_spdif_write(spdif, TEGRA20_SPDIF_CTRL, spdif->reg_ctrl); + regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL, + TEGRA20_SPDIF_CTRL_TX_EN, 0); } static int tegra20_spdif_trigger(struct snd_pcm_substream *substream, int cmd, @@ -181,6 +173,7 @@ static struct snd_soc_dai_driver tegra20_spdif_dai = { .name = DRV_NAME, .probe = tegra20_spdif_probe, .playback = { + .stream_name = "Playback", .channels_min = 2, .channels_max = 2, .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | @@ -190,6 +183,10 @@ static struct snd_soc_dai_driver tegra20_spdif_dai = { .ops = &tegra20_spdif_dai_ops, }; +static const struct snd_soc_component_driver tegra20_spdif_component = { + .name = DRV_NAME, +}; + static bool tegra20_spdif_wr_rd_reg(struct device *dev, unsigned int reg) { switch (reg) { @@ -216,7 +213,7 @@ static bool tegra20_spdif_wr_rd_reg(struct device *dev, unsigned int reg) return true; default: return false; - }; + } } static bool tegra20_spdif_volatile_reg(struct device *dev, unsigned int reg) @@ -237,7 +234,7 @@ static bool tegra20_spdif_volatile_reg(struct device *dev, unsigned int reg) return true; default: return false; - }; + } } static bool tegra20_spdif_precious_reg(struct device *dev, unsigned int reg) @@ -250,7 +247,7 @@ static bool tegra20_spdif_precious_reg(struct device *dev, unsigned int reg) return true; default: return false; - }; + } } static const struct regmap_config tegra20_spdif_regmap_config = { @@ -262,10 +259,10 @@ static const struct regmap_config tegra20_spdif_regmap_config = { .readable_reg = tegra20_spdif_wr_rd_reg, .volatile_reg = tegra20_spdif_volatile_reg, .precious_reg = tegra20_spdif_precious_reg, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_FLAT, }; -static __devinit int tegra20_spdif_platform_probe(struct platform_device *pdev) +static int tegra20_spdif_platform_probe(struct platform_device *pdev) { struct tegra20_spdif *spdif; struct resource *mem, *memregion, *dmareq; @@ -326,9 +323,9 @@ static __devinit int tegra20_spdif_platform_probe(struct platform_device *pdev) } spdif->playback_dma_data.addr = mem->start + TEGRA20_SPDIF_DATA_OUT; - spdif->playback_dma_data.wrap = 4; - spdif->playback_dma_data.width = 32; - spdif->playback_dma_data.req_sel = dmareq->start; + spdif->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + spdif->playback_dma_data.maxburst = 4; + spdif->playback_dma_data.slave_id = dmareq->start; pm_runtime_enable(&pdev->dev); if (!pm_runtime_enabled(&pdev->dev)) { @@ -337,7 +334,8 @@ static __devinit int tegra20_spdif_platform_probe(struct platform_device *pdev) goto err_pm_disable; } - ret = snd_soc_register_dai(&pdev->dev, &tegra20_spdif_dai); + ret = snd_soc_register_component(&pdev->dev, &tegra20_spdif_component, + &tegra20_spdif_dai, 1); if (ret) { dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); ret = -ENOMEM; @@ -347,13 +345,13 @@ static __devinit int tegra20_spdif_platform_probe(struct platform_device *pdev) ret = tegra_pcm_platform_register(&pdev->dev); if (ret) { dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); - goto err_unregister_dai; + goto err_unregister_component; } return 0; -err_unregister_dai: - snd_soc_unregister_dai(&pdev->dev); +err_unregister_component: + snd_soc_unregister_component(&pdev->dev); err_suspend: if (!pm_runtime_status_suspended(&pdev->dev)) tegra20_spdif_runtime_suspend(&pdev->dev); @@ -365,7 +363,7 @@ err: return ret; } -static int __devexit tegra20_spdif_platform_remove(struct platform_device *pdev) +static int tegra20_spdif_platform_remove(struct platform_device *pdev) { struct tegra20_spdif *spdif = dev_get_drvdata(&pdev->dev); @@ -374,14 +372,14 @@ static int __devexit tegra20_spdif_platform_remove(struct platform_device *pdev) tegra20_spdif_runtime_suspend(&pdev->dev); tegra_pcm_platform_unregister(&pdev->dev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); clk_put(spdif->clk_spdif_out); return 0; } -static const struct dev_pm_ops tegra20_spdif_pm_ops __devinitconst = { +static const struct dev_pm_ops tegra20_spdif_pm_ops = { SET_RUNTIME_PM_OPS(tegra20_spdif_runtime_suspend, tegra20_spdif_runtime_resume, NULL) }; @@ -393,7 +391,7 @@ static struct platform_driver tegra20_spdif_driver = { .pm = &tegra20_spdif_pm_ops, }, .probe = tegra20_spdif_platform_probe, - .remove = __devexit_p(tegra20_spdif_platform_remove), + .remove = tegra20_spdif_platform_remove, }; module_platform_driver(tegra20_spdif_driver); |
