Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * tegra30_i2s.c - Tegra30 I2S driver
0004  *
0005  * Author: Stephen Warren <swarren@nvidia.com>
0006  * Copyright (c) 2010-2012, NVIDIA CORPORATION.  All rights reserved.
0007  *
0008  * Based on code copyright/by:
0009  *
0010  * Copyright (c) 2009-2010, NVIDIA Corporation.
0011  * Scott Peterson <speterson@nvidia.com>
0012  *
0013  * Copyright (C) 2010 Google, Inc.
0014  * Iliyan Malchev <malchev@google.com>
0015  */
0016 
0017 #include <linux/clk.h>
0018 #include <linux/device.h>
0019 #include <linux/io.h>
0020 #include <linux/module.h>
0021 #include <linux/of.h>
0022 #include <linux/of_device.h>
0023 #include <linux/platform_device.h>
0024 #include <linux/pm_runtime.h>
0025 #include <linux/regmap.h>
0026 #include <linux/reset.h>
0027 #include <linux/slab.h>
0028 #include <sound/core.h>
0029 #include <sound/pcm.h>
0030 #include <sound/pcm_params.h>
0031 #include <sound/soc.h>
0032 #include <sound/dmaengine_pcm.h>
0033 
0034 #include "tegra30_ahub.h"
0035 #include "tegra30_i2s.h"
0036 
0037 #define DRV_NAME "tegra30-i2s"
0038 
0039 static __maybe_unused int tegra30_i2s_runtime_suspend(struct device *dev)
0040 {
0041     struct tegra30_i2s *i2s = dev_get_drvdata(dev);
0042 
0043     regcache_cache_only(i2s->regmap, true);
0044 
0045     clk_disable_unprepare(i2s->clk_i2s);
0046 
0047     return 0;
0048 }
0049 
0050 static __maybe_unused int tegra30_i2s_runtime_resume(struct device *dev)
0051 {
0052     struct tegra30_i2s *i2s = dev_get_drvdata(dev);
0053     int ret;
0054 
0055     ret = clk_prepare_enable(i2s->clk_i2s);
0056     if (ret) {
0057         dev_err(dev, "clk_enable failed: %d\n", ret);
0058         return ret;
0059     }
0060 
0061     regcache_cache_only(i2s->regmap, false);
0062     regcache_mark_dirty(i2s->regmap);
0063 
0064     ret = regcache_sync(i2s->regmap);
0065     if (ret)
0066         goto disable_clocks;
0067 
0068     return 0;
0069 
0070 disable_clocks:
0071     clk_disable_unprepare(i2s->clk_i2s);
0072 
0073     return ret;
0074 }
0075 
0076 static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
0077                 unsigned int fmt)
0078 {
0079     struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
0080     unsigned int mask = 0, val = 0;
0081 
0082     switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0083     case SND_SOC_DAIFMT_NB_NF:
0084         break;
0085     default:
0086         return -EINVAL;
0087     }
0088 
0089     mask |= TEGRA30_I2S_CTRL_MASTER_ENABLE;
0090     switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0091     case SND_SOC_DAIFMT_BP_FP:
0092         val |= TEGRA30_I2S_CTRL_MASTER_ENABLE;
0093         break;
0094     case SND_SOC_DAIFMT_BC_FC:
0095         break;
0096     default:
0097         return -EINVAL;
0098     }
0099 
0100     mask |= TEGRA30_I2S_CTRL_FRAME_FORMAT_MASK |
0101         TEGRA30_I2S_CTRL_LRCK_MASK;
0102     switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0103     case SND_SOC_DAIFMT_DSP_A:
0104         val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC;
0105         val |= TEGRA30_I2S_CTRL_LRCK_L_LOW;
0106         break;
0107     case SND_SOC_DAIFMT_DSP_B:
0108         val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC;
0109         val |= TEGRA30_I2S_CTRL_LRCK_R_LOW;
0110         break;
0111     case SND_SOC_DAIFMT_I2S:
0112         val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK;
0113         val |= TEGRA30_I2S_CTRL_LRCK_L_LOW;
0114         break;
0115     case SND_SOC_DAIFMT_RIGHT_J:
0116         val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK;
0117         val |= TEGRA30_I2S_CTRL_LRCK_L_LOW;
0118         break;
0119     case SND_SOC_DAIFMT_LEFT_J:
0120         val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK;
0121         val |= TEGRA30_I2S_CTRL_LRCK_L_LOW;
0122         break;
0123     default:
0124         return -EINVAL;
0125     }
0126 
0127     pm_runtime_get_sync(dai->dev);
0128     regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, mask, val);
0129     pm_runtime_put(dai->dev);
0130 
0131     return 0;
0132 }
0133 
0134 static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
0135                  struct snd_pcm_hw_params *params,
0136                  struct snd_soc_dai *dai)
0137 {
0138     struct device *dev = dai->dev;
0139     struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
0140     unsigned int mask, val, reg;
0141     int ret, sample_size, srate, i2sclock, bitcnt;
0142     struct tegra30_ahub_cif_conf cif_conf;
0143 
0144     if (params_channels(params) != 2)
0145         return -EINVAL;
0146 
0147     mask = TEGRA30_I2S_CTRL_BIT_SIZE_MASK;
0148     switch (params_format(params)) {
0149     case SNDRV_PCM_FORMAT_S16_LE:
0150         val = TEGRA30_I2S_CTRL_BIT_SIZE_16;
0151         sample_size = 16;
0152         break;
0153     default:
0154         return -EINVAL;
0155     }
0156 
0157     regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, mask, val);
0158 
0159     srate = params_rate(params);
0160 
0161     /* Final "* 2" required by Tegra hardware */
0162     i2sclock = srate * params_channels(params) * sample_size * 2;
0163 
0164     bitcnt = (i2sclock / (2 * srate)) - 1;
0165     if (bitcnt < 0 || bitcnt > TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US)
0166         return -EINVAL;
0167 
0168     ret = clk_set_rate(i2s->clk_i2s, i2sclock);
0169     if (ret) {
0170         dev_err(dev, "Can't set I2S clock rate: %d\n", ret);
0171         return ret;
0172     }
0173 
0174     val = bitcnt << TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT;
0175 
0176     if (i2sclock % (2 * srate))
0177         val |= TEGRA30_I2S_TIMING_NON_SYM_ENABLE;
0178 
0179     regmap_write(i2s->regmap, TEGRA30_I2S_TIMING, val);
0180 
0181     cif_conf.threshold = 0;
0182     cif_conf.audio_channels = 2;
0183     cif_conf.client_channels = 2;
0184     cif_conf.audio_bits = TEGRA30_AUDIOCIF_BITS_16;
0185     cif_conf.client_bits = TEGRA30_AUDIOCIF_BITS_16;
0186     cif_conf.expand = 0;
0187     cif_conf.stereo_conv = 0;
0188     cif_conf.replicate = 0;
0189     cif_conf.truncate = 0;
0190     cif_conf.mono_conv = 0;
0191 
0192     if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
0193         cif_conf.direction = TEGRA30_AUDIOCIF_DIRECTION_RX;
0194         reg = TEGRA30_I2S_CIF_RX_CTRL;
0195     } else {
0196         cif_conf.direction = TEGRA30_AUDIOCIF_DIRECTION_TX;
0197         reg = TEGRA30_I2S_CIF_TX_CTRL;
0198     }
0199 
0200     i2s->soc_data->set_audio_cif(i2s->regmap, reg, &cif_conf);
0201 
0202     val = (1 << TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_SHIFT) |
0203           (1 << TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_SHIFT);
0204     regmap_write(i2s->regmap, TEGRA30_I2S_OFFSET, val);
0205 
0206     return 0;
0207 }
0208 
0209 static void tegra30_i2s_start_playback(struct tegra30_i2s *i2s)
0210 {
0211     tegra30_ahub_enable_tx_fifo(i2s->playback_fifo_cif);
0212     regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL,
0213                TEGRA30_I2S_CTRL_XFER_EN_TX,
0214                TEGRA30_I2S_CTRL_XFER_EN_TX);
0215 }
0216 
0217 static void tegra30_i2s_stop_playback(struct tegra30_i2s *i2s)
0218 {
0219     tegra30_ahub_disable_tx_fifo(i2s->playback_fifo_cif);
0220     regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL,
0221                TEGRA30_I2S_CTRL_XFER_EN_TX, 0);
0222 }
0223 
0224 static void tegra30_i2s_start_capture(struct tegra30_i2s *i2s)
0225 {
0226     tegra30_ahub_enable_rx_fifo(i2s->capture_fifo_cif);
0227     regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL,
0228                TEGRA30_I2S_CTRL_XFER_EN_RX,
0229                TEGRA30_I2S_CTRL_XFER_EN_RX);
0230 }
0231 
0232 static void tegra30_i2s_stop_capture(struct tegra30_i2s *i2s)
0233 {
0234     regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL,
0235                TEGRA30_I2S_CTRL_XFER_EN_RX, 0);
0236     tegra30_ahub_disable_rx_fifo(i2s->capture_fifo_cif);
0237 }
0238 
0239 static int tegra30_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
0240                 struct snd_soc_dai *dai)
0241 {
0242     struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
0243 
0244     switch (cmd) {
0245     case SNDRV_PCM_TRIGGER_START:
0246     case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
0247     case SNDRV_PCM_TRIGGER_RESUME:
0248         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
0249             tegra30_i2s_start_playback(i2s);
0250         else
0251             tegra30_i2s_start_capture(i2s);
0252         break;
0253     case SNDRV_PCM_TRIGGER_STOP:
0254     case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
0255     case SNDRV_PCM_TRIGGER_SUSPEND:
0256         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
0257             tegra30_i2s_stop_playback(i2s);
0258         else
0259             tegra30_i2s_stop_capture(i2s);
0260         break;
0261     default:
0262         return -EINVAL;
0263     }
0264 
0265     return 0;
0266 }
0267 
0268 static int tegra30_i2s_set_tdm(struct snd_soc_dai *dai,
0269                    unsigned int tx_mask, unsigned int rx_mask,
0270                    int slots, int slot_width)
0271 {
0272     struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
0273     unsigned int mask, val;
0274 
0275     dev_dbg(dai->dev, "%s: txmask=0x%08x rxmask=0x%08x slots=%d width=%d\n",
0276          __func__, tx_mask, rx_mask, slots, slot_width);
0277 
0278     mask = TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_MASK |
0279            TEGRA30_I2S_SLOT_CTRL_RX_SLOT_ENABLES_MASK |
0280            TEGRA30_I2S_SLOT_CTRL_TX_SLOT_ENABLES_MASK;
0281 
0282     val = (tx_mask << TEGRA30_I2S_SLOT_CTRL_TX_SLOT_ENABLES_SHIFT) |
0283           (rx_mask << TEGRA30_I2S_SLOT_CTRL_RX_SLOT_ENABLES_SHIFT) |
0284           ((slots - 1) << TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_SHIFT);
0285 
0286     pm_runtime_get_sync(dai->dev);
0287     regmap_update_bits(i2s->regmap, TEGRA30_I2S_SLOT_CTRL, mask, val);
0288     /* set the fsync width to minimum of 1 clock width */
0289     regmap_update_bits(i2s->regmap, TEGRA30_I2S_CH_CTRL,
0290                TEGRA30_I2S_CH_CTRL_FSYNC_WIDTH_MASK, 0x0);
0291     pm_runtime_put(dai->dev);
0292 
0293     return 0;
0294 }
0295 
0296 static int tegra30_i2s_probe(struct snd_soc_dai *dai)
0297 {
0298     struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
0299 
0300     dai->capture_dma_data = &i2s->capture_dma_data;
0301     dai->playback_dma_data = &i2s->playback_dma_data;
0302 
0303     return 0;
0304 }
0305 
0306 static const struct snd_soc_dai_ops tegra30_i2s_dai_ops = {
0307     .set_fmt    = tegra30_i2s_set_fmt,
0308     .hw_params  = tegra30_i2s_hw_params,
0309     .trigger    = tegra30_i2s_trigger,
0310     .set_tdm_slot   = tegra30_i2s_set_tdm,
0311 };
0312 
0313 static const struct snd_soc_dai_driver tegra30_i2s_dai_template = {
0314     .probe = tegra30_i2s_probe,
0315     .playback = {
0316         .stream_name = "Playback",
0317         .channels_min = 2,
0318         .channels_max = 2,
0319         .rates = SNDRV_PCM_RATE_8000_96000,
0320         .formats = SNDRV_PCM_FMTBIT_S16_LE,
0321     },
0322     .capture = {
0323         .stream_name = "Capture",
0324         .channels_min = 2,
0325         .channels_max = 2,
0326         .rates = SNDRV_PCM_RATE_8000_96000,
0327         .formats = SNDRV_PCM_FMTBIT_S16_LE,
0328     },
0329     .ops = &tegra30_i2s_dai_ops,
0330     .symmetric_rate = 1,
0331 };
0332 
0333 static const struct snd_soc_component_driver tegra30_i2s_component = {
0334     .name           = DRV_NAME,
0335     .legacy_dai_naming  = 1,
0336 };
0337 
0338 static bool tegra30_i2s_wr_rd_reg(struct device *dev, unsigned int reg)
0339 {
0340     switch (reg) {
0341     case TEGRA30_I2S_CTRL:
0342     case TEGRA30_I2S_TIMING:
0343     case TEGRA30_I2S_OFFSET:
0344     case TEGRA30_I2S_CH_CTRL:
0345     case TEGRA30_I2S_SLOT_CTRL:
0346     case TEGRA30_I2S_CIF_RX_CTRL:
0347     case TEGRA30_I2S_CIF_TX_CTRL:
0348     case TEGRA30_I2S_FLOWCTL:
0349     case TEGRA30_I2S_TX_STEP:
0350     case TEGRA30_I2S_FLOW_STATUS:
0351     case TEGRA30_I2S_FLOW_TOTAL:
0352     case TEGRA30_I2S_FLOW_OVER:
0353     case TEGRA30_I2S_FLOW_UNDER:
0354     case TEGRA30_I2S_LCOEF_1_4_0:
0355     case TEGRA30_I2S_LCOEF_1_4_1:
0356     case TEGRA30_I2S_LCOEF_1_4_2:
0357     case TEGRA30_I2S_LCOEF_1_4_3:
0358     case TEGRA30_I2S_LCOEF_1_4_4:
0359     case TEGRA30_I2S_LCOEF_1_4_5:
0360     case TEGRA30_I2S_LCOEF_2_4_0:
0361     case TEGRA30_I2S_LCOEF_2_4_1:
0362     case TEGRA30_I2S_LCOEF_2_4_2:
0363         return true;
0364     default:
0365         return false;
0366     }
0367 }
0368 
0369 static bool tegra30_i2s_volatile_reg(struct device *dev, unsigned int reg)
0370 {
0371     switch (reg) {
0372     case TEGRA30_I2S_FLOW_STATUS:
0373     case TEGRA30_I2S_FLOW_TOTAL:
0374     case TEGRA30_I2S_FLOW_OVER:
0375     case TEGRA30_I2S_FLOW_UNDER:
0376         return true;
0377     default:
0378         return false;
0379     }
0380 }
0381 
0382 static const struct regmap_config tegra30_i2s_regmap_config = {
0383     .reg_bits = 32,
0384     .reg_stride = 4,
0385     .val_bits = 32,
0386     .max_register = TEGRA30_I2S_LCOEF_2_4_2,
0387     .writeable_reg = tegra30_i2s_wr_rd_reg,
0388     .readable_reg = tegra30_i2s_wr_rd_reg,
0389     .volatile_reg = tegra30_i2s_volatile_reg,
0390     .cache_type = REGCACHE_FLAT,
0391 };
0392 
0393 static const struct tegra30_i2s_soc_data tegra30_i2s_config = {
0394     .set_audio_cif = tegra30_ahub_set_cif,
0395 };
0396 
0397 static const struct tegra30_i2s_soc_data tegra124_i2s_config = {
0398     .set_audio_cif = tegra124_ahub_set_cif,
0399 };
0400 
0401 static const struct of_device_id tegra30_i2s_of_match[] = {
0402     { .compatible = "nvidia,tegra124-i2s", .data = &tegra124_i2s_config },
0403     { .compatible = "nvidia,tegra30-i2s", .data = &tegra30_i2s_config },
0404     {},
0405 };
0406 
0407 static int tegra30_i2s_platform_probe(struct platform_device *pdev)
0408 {
0409     struct tegra30_i2s *i2s;
0410     const struct tegra30_i2s_soc_data *soc_data;
0411     u32 cif_ids[2];
0412     void __iomem *regs;
0413     int ret;
0414 
0415     i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_i2s), GFP_KERNEL);
0416     if (!i2s) {
0417         ret = -ENOMEM;
0418         goto err;
0419     }
0420     dev_set_drvdata(&pdev->dev, i2s);
0421 
0422     soc_data = of_device_get_match_data(&pdev->dev);
0423     if (!soc_data) {
0424         dev_err(&pdev->dev, "Error: No device match found\n");
0425         ret = -ENODEV;
0426         goto err;
0427     }
0428     i2s->soc_data = soc_data;
0429 
0430     i2s->dai = tegra30_i2s_dai_template;
0431     i2s->dai.name = dev_name(&pdev->dev);
0432 
0433     ret = of_property_read_u32_array(pdev->dev.of_node,
0434                      "nvidia,ahub-cif-ids", cif_ids,
0435                      ARRAY_SIZE(cif_ids));
0436     if (ret < 0)
0437         goto err;
0438 
0439     i2s->playback_i2s_cif = cif_ids[0];
0440     i2s->capture_i2s_cif = cif_ids[1];
0441 
0442     i2s->clk_i2s = devm_clk_get(&pdev->dev, NULL);
0443     if (IS_ERR(i2s->clk_i2s)) {
0444         dev_err(&pdev->dev, "Can't retrieve i2s clock\n");
0445         ret = PTR_ERR(i2s->clk_i2s);
0446         goto err;
0447     }
0448 
0449     regs = devm_platform_ioremap_resource(pdev, 0);
0450     if (IS_ERR(regs)) {
0451         ret = PTR_ERR(regs);
0452         goto err;
0453     }
0454 
0455     i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
0456                         &tegra30_i2s_regmap_config);
0457     if (IS_ERR(i2s->regmap)) {
0458         dev_err(&pdev->dev, "regmap init failed\n");
0459         ret = PTR_ERR(i2s->regmap);
0460         goto err;
0461     }
0462     regcache_cache_only(i2s->regmap, true);
0463 
0464     pm_runtime_enable(&pdev->dev);
0465 
0466     i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
0467     i2s->playback_dma_data.maxburst = 4;
0468     ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif,
0469                         i2s->playback_dma_chan,
0470                         sizeof(i2s->playback_dma_chan),
0471                         &i2s->playback_dma_data.addr);
0472     if (ret) {
0473         dev_err(&pdev->dev, "Could not alloc TX FIFO: %d\n", ret);
0474         goto err_pm_disable;
0475     }
0476     ret = tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif,
0477                          i2s->playback_fifo_cif);
0478     if (ret) {
0479         dev_err(&pdev->dev, "Could not route TX FIFO: %d\n", ret);
0480         goto err_free_tx_fifo;
0481     }
0482 
0483     i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
0484     i2s->capture_dma_data.maxburst = 4;
0485     ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif,
0486                         i2s->capture_dma_chan,
0487                         sizeof(i2s->capture_dma_chan),
0488                         &i2s->capture_dma_data.addr);
0489     if (ret) {
0490         dev_err(&pdev->dev, "Could not alloc RX FIFO: %d\n", ret);
0491         goto err_unroute_tx_fifo;
0492     }
0493     ret = tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif,
0494                          i2s->capture_i2s_cif);
0495     if (ret) {
0496         dev_err(&pdev->dev, "Could not route TX FIFO: %d\n", ret);
0497         goto err_free_rx_fifo;
0498     }
0499 
0500     ret = snd_soc_register_component(&pdev->dev, &tegra30_i2s_component,
0501                    &i2s->dai, 1);
0502     if (ret) {
0503         dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
0504         ret = -ENOMEM;
0505         goto err_unroute_rx_fifo;
0506     }
0507 
0508     ret = tegra_pcm_platform_register_with_chan_names(&pdev->dev,
0509                 &i2s->dma_config, i2s->playback_dma_chan,
0510                 i2s->capture_dma_chan);
0511     if (ret) {
0512         dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
0513         goto err_unregister_component;
0514     }
0515 
0516     return 0;
0517 
0518 err_unregister_component:
0519     snd_soc_unregister_component(&pdev->dev);
0520 err_unroute_rx_fifo:
0521     tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif);
0522 err_free_rx_fifo:
0523     tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif);
0524 err_unroute_tx_fifo:
0525     tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif);
0526 err_free_tx_fifo:
0527     tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif);
0528 err_pm_disable:
0529     pm_runtime_disable(&pdev->dev);
0530 err:
0531     return ret;
0532 }
0533 
0534 static int tegra30_i2s_platform_remove(struct platform_device *pdev)
0535 {
0536     struct tegra30_i2s *i2s = dev_get_drvdata(&pdev->dev);
0537 
0538     tegra_pcm_platform_unregister(&pdev->dev);
0539     snd_soc_unregister_component(&pdev->dev);
0540 
0541     tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif);
0542     tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif);
0543 
0544     tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif);
0545     tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif);
0546 
0547     pm_runtime_disable(&pdev->dev);
0548 
0549     return 0;
0550 }
0551 
0552 static const struct dev_pm_ops tegra30_i2s_pm_ops = {
0553     SET_RUNTIME_PM_OPS(tegra30_i2s_runtime_suspend,
0554                tegra30_i2s_runtime_resume, NULL)
0555     SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
0556                 pm_runtime_force_resume)
0557 };
0558 
0559 static struct platform_driver tegra30_i2s_driver = {
0560     .driver = {
0561         .name = DRV_NAME,
0562         .of_match_table = tegra30_i2s_of_match,
0563         .pm = &tegra30_i2s_pm_ops,
0564     },
0565     .probe = tegra30_i2s_platform_probe,
0566     .remove = tegra30_i2s_platform_remove,
0567 };
0568 module_platform_driver(tegra30_i2s_driver);
0569 
0570 MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
0571 MODULE_DESCRIPTION("Tegra30 I2S ASoC driver");
0572 MODULE_LICENSE("GPL");
0573 MODULE_ALIAS("platform:" DRV_NAME);
0574 MODULE_DEVICE_TABLE(of, tegra30_i2s_of_match);