linux/sound/soc/rockchip/rockchip_i2s.c
<<
>>
Prefs
   1/* sound/soc/rockchip/rockchip_i2s.c
   2 *
   3 * ALSA SoC Audio Layer - Rockchip I2S Controller driver
   4 *
   5 * Copyright (c) 2014 Rockchip Electronics Co. Ltd.
   6 * Author: Jianqun <jay.xu@rock-chips.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 */
  12
  13#include <linux/module.h>
  14#include <linux/delay.h>
  15#include <linux/of_gpio.h>
  16#include <linux/clk.h>
  17#include <linux/pm_runtime.h>
  18#include <linux/regmap.h>
  19#include <sound/pcm_params.h>
  20#include <sound/dmaengine_pcm.h>
  21
  22#include "rockchip_i2s.h"
  23
  24#define DRV_NAME "rockchip-i2s"
  25
  26struct rk_i2s_dev {
  27        struct device *dev;
  28
  29        struct clk *hclk;
  30        struct clk *mclk;
  31
  32        struct snd_dmaengine_dai_dma_data capture_dma_data;
  33        struct snd_dmaengine_dai_dma_data playback_dma_data;
  34
  35        struct regmap *regmap;
  36
  37/*
  38 * Used to indicate the tx/rx status.
  39 * I2S controller hopes to start the tx and rx together,
  40 * also to stop them when they are both try to stop.
  41*/
  42        bool tx_start;
  43        bool rx_start;
  44        bool is_master_mode;
  45};
  46
  47static int i2s_runtime_suspend(struct device *dev)
  48{
  49        struct rk_i2s_dev *i2s = dev_get_drvdata(dev);
  50
  51        clk_disable_unprepare(i2s->mclk);
  52
  53        return 0;
  54}
  55
  56static int i2s_runtime_resume(struct device *dev)
  57{
  58        struct rk_i2s_dev *i2s = dev_get_drvdata(dev);
  59        int ret;
  60
  61        ret = clk_prepare_enable(i2s->mclk);
  62        if (ret) {
  63                dev_err(i2s->dev, "clock enable failed %d\n", ret);
  64                return ret;
  65        }
  66
  67        return 0;
  68}
  69
  70static inline struct rk_i2s_dev *to_info(struct snd_soc_dai *dai)
  71{
  72        return snd_soc_dai_get_drvdata(dai);
  73}
  74
  75static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)
  76{
  77        unsigned int val = 0;
  78        int retry = 10;
  79
  80        if (on) {
  81                regmap_update_bits(i2s->regmap, I2S_DMACR,
  82                                   I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE);
  83
  84                regmap_update_bits(i2s->regmap, I2S_XFER,
  85                                   I2S_XFER_TXS_START | I2S_XFER_RXS_START,
  86                                   I2S_XFER_TXS_START | I2S_XFER_RXS_START);
  87
  88                i2s->tx_start = true;
  89        } else {
  90                i2s->tx_start = false;
  91
  92                regmap_update_bits(i2s->regmap, I2S_DMACR,
  93                                   I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE);
  94
  95                if (!i2s->rx_start) {
  96                        regmap_update_bits(i2s->regmap, I2S_XFER,
  97                                           I2S_XFER_TXS_START |
  98                                           I2S_XFER_RXS_START,
  99                                           I2S_XFER_TXS_STOP |
 100                                           I2S_XFER_RXS_STOP);
 101
 102                        regmap_update_bits(i2s->regmap, I2S_CLR,
 103                                           I2S_CLR_TXC | I2S_CLR_RXC,
 104                                           I2S_CLR_TXC | I2S_CLR_RXC);
 105
 106                        regmap_read(i2s->regmap, I2S_CLR, &val);
 107
 108                        /* Should wait for clear operation to finish */
 109                        while (val) {
 110                                regmap_read(i2s->regmap, I2S_CLR, &val);
 111                                retry--;
 112                                if (!retry) {
 113                                        dev_warn(i2s->dev, "fail to clear\n");
 114                                        break;
 115                                }
 116                        }
 117                }
 118        }
 119}
 120
 121static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)
 122{
 123        unsigned int val = 0;
 124        int retry = 10;
 125
 126        if (on) {
 127                regmap_update_bits(i2s->regmap, I2S_DMACR,
 128                                   I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE);
 129
 130                regmap_update_bits(i2s->regmap, I2S_XFER,
 131                                   I2S_XFER_TXS_START | I2S_XFER_RXS_START,
 132                                   I2S_XFER_TXS_START | I2S_XFER_RXS_START);
 133
 134                i2s->rx_start = true;
 135        } else {
 136                i2s->rx_start = false;
 137
 138                regmap_update_bits(i2s->regmap, I2S_DMACR,
 139                                   I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_DISABLE);
 140
 141                if (!i2s->tx_start) {
 142                        regmap_update_bits(i2s->regmap, I2S_XFER,
 143                                           I2S_XFER_TXS_START |
 144                                           I2S_XFER_RXS_START,
 145                                           I2S_XFER_TXS_STOP |
 146                                           I2S_XFER_RXS_STOP);
 147
 148                        regmap_update_bits(i2s->regmap, I2S_CLR,
 149                                           I2S_CLR_TXC | I2S_CLR_RXC,
 150                                           I2S_CLR_TXC | I2S_CLR_RXC);
 151
 152                        regmap_read(i2s->regmap, I2S_CLR, &val);
 153
 154                        /* Should wait for clear operation to finish */
 155                        while (val) {
 156                                regmap_read(i2s->regmap, I2S_CLR, &val);
 157                                retry--;
 158                                if (!retry) {
 159                                        dev_warn(i2s->dev, "fail to clear\n");
 160                                        break;
 161                                }
 162                        }
 163                }
 164        }
 165}
 166
 167static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
 168                                unsigned int fmt)
 169{
 170        struct rk_i2s_dev *i2s = to_info(cpu_dai);
 171        unsigned int mask = 0, val = 0;
 172
 173        mask = I2S_CKR_MSS_MASK;
 174        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 175        case SND_SOC_DAIFMT_CBS_CFS:
 176                /* Set source clock in Master mode */
 177                val = I2S_CKR_MSS_MASTER;
 178                i2s->is_master_mode = true;
 179                break;
 180        case SND_SOC_DAIFMT_CBM_CFM:
 181                val = I2S_CKR_MSS_SLAVE;
 182                i2s->is_master_mode = false;
 183                break;
 184        default:
 185                return -EINVAL;
 186        }
 187
 188        regmap_update_bits(i2s->regmap, I2S_CKR, mask, val);
 189
 190        mask = I2S_TXCR_IBM_MASK;
 191        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 192        case SND_SOC_DAIFMT_RIGHT_J:
 193                val = I2S_TXCR_IBM_RSJM;
 194                break;
 195        case SND_SOC_DAIFMT_LEFT_J:
 196                val = I2S_TXCR_IBM_LSJM;
 197                break;
 198        case SND_SOC_DAIFMT_I2S:
 199                val = I2S_TXCR_IBM_NORMAL;
 200                break;
 201        default:
 202                return -EINVAL;
 203        }
 204
 205        regmap_update_bits(i2s->regmap, I2S_TXCR, mask, val);
 206
 207        mask = I2S_RXCR_IBM_MASK;
 208        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 209        case SND_SOC_DAIFMT_RIGHT_J:
 210                val = I2S_RXCR_IBM_RSJM;
 211                break;
 212        case SND_SOC_DAIFMT_LEFT_J:
 213                val = I2S_RXCR_IBM_LSJM;
 214                break;
 215        case SND_SOC_DAIFMT_I2S:
 216                val = I2S_RXCR_IBM_NORMAL;
 217                break;
 218        default:
 219                return -EINVAL;
 220        }
 221
 222        regmap_update_bits(i2s->regmap, I2S_RXCR, mask, val);
 223
 224        return 0;
 225}
 226
 227static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
 228                                  struct snd_pcm_hw_params *params,
 229                                  struct snd_soc_dai *dai)
 230{
 231        struct rk_i2s_dev *i2s = to_info(dai);
 232        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 233        unsigned int val = 0;
 234        unsigned int mclk_rate, bclk_rate, div_bclk, div_lrck;
 235
 236        if (i2s->is_master_mode) {
 237                mclk_rate = clk_get_rate(i2s->mclk);
 238                bclk_rate = 2 * 32 * params_rate(params);
 239                if (bclk_rate && mclk_rate % bclk_rate)
 240                        return -EINVAL;
 241
 242                div_bclk = mclk_rate / bclk_rate;
 243                div_lrck = bclk_rate / params_rate(params);
 244                regmap_update_bits(i2s->regmap, I2S_CKR,
 245                                   I2S_CKR_MDIV_MASK,
 246                                   I2S_CKR_MDIV(div_bclk));
 247
 248                regmap_update_bits(i2s->regmap, I2S_CKR,
 249                                   I2S_CKR_TSD_MASK |
 250                                   I2S_CKR_RSD_MASK,
 251                                   I2S_CKR_TSD(div_lrck) |
 252                                   I2S_CKR_RSD(div_lrck));
 253        }
 254
 255        switch (params_format(params)) {
 256        case SNDRV_PCM_FORMAT_S8:
 257                val |= I2S_TXCR_VDW(8);
 258                break;
 259        case SNDRV_PCM_FORMAT_S16_LE:
 260                val |= I2S_TXCR_VDW(16);
 261                break;
 262        case SNDRV_PCM_FORMAT_S20_3LE:
 263                val |= I2S_TXCR_VDW(20);
 264                break;
 265        case SNDRV_PCM_FORMAT_S24_LE:
 266                val |= I2S_TXCR_VDW(24);
 267                break;
 268        case SNDRV_PCM_FORMAT_S32_LE:
 269                val |= I2S_TXCR_VDW(32);
 270                break;
 271        default:
 272                return -EINVAL;
 273        }
 274
 275        switch (params_channels(params)) {
 276        case 8:
 277                val |= I2S_CHN_8;
 278                break;
 279        case 6:
 280                val |= I2S_CHN_6;
 281                break;
 282        case 4:
 283                val |= I2S_CHN_4;
 284                break;
 285        case 2:
 286                val |= I2S_CHN_2;
 287                break;
 288        default:
 289                dev_err(i2s->dev, "invalid channel: %d\n",
 290                        params_channels(params));
 291                return -EINVAL;
 292        }
 293
 294        if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
 295                regmap_update_bits(i2s->regmap, I2S_RXCR,
 296                                   I2S_RXCR_VDW_MASK | I2S_RXCR_CSR_MASK,
 297                                   val);
 298        else
 299                regmap_update_bits(i2s->regmap, I2S_TXCR,
 300                                   I2S_TXCR_VDW_MASK | I2S_TXCR_CSR_MASK,
 301                                   val);
 302
 303        regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK,
 304                           I2S_DMACR_TDL(16));
 305        regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK,
 306                           I2S_DMACR_RDL(16));
 307
 308        val = I2S_CKR_TRCM_TXRX;
 309        if (dai->driver->symmetric_rates || rtd->dai_link->symmetric_rates)
 310                val = I2S_CKR_TRCM_TXSHARE;
 311
 312        regmap_update_bits(i2s->regmap, I2S_CKR,
 313                           I2S_CKR_TRCM_MASK,
 314                           val);
 315        return 0;
 316}
 317
 318static int rockchip_i2s_trigger(struct snd_pcm_substream *substream,
 319                                int cmd, struct snd_soc_dai *dai)
 320{
 321        struct rk_i2s_dev *i2s = to_info(dai);
 322        int ret = 0;
 323
 324        switch (cmd) {
 325        case SNDRV_PCM_TRIGGER_START:
 326        case SNDRV_PCM_TRIGGER_RESUME:
 327        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 328                if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
 329                        rockchip_snd_rxctrl(i2s, 1);
 330                else
 331                        rockchip_snd_txctrl(i2s, 1);
 332                break;
 333        case SNDRV_PCM_TRIGGER_SUSPEND:
 334        case SNDRV_PCM_TRIGGER_STOP:
 335        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 336                if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
 337                        rockchip_snd_rxctrl(i2s, 0);
 338                else
 339                        rockchip_snd_txctrl(i2s, 0);
 340                break;
 341        default:
 342                ret = -EINVAL;
 343                break;
 344        }
 345
 346        return ret;
 347}
 348
 349static int rockchip_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id,
 350                                   unsigned int freq, int dir)
 351{
 352        struct rk_i2s_dev *i2s = to_info(cpu_dai);
 353        int ret;
 354
 355        ret = clk_set_rate(i2s->mclk, freq);
 356        if (ret)
 357                dev_err(i2s->dev, "Fail to set mclk %d\n", ret);
 358
 359        return ret;
 360}
 361
 362static int rockchip_i2s_dai_probe(struct snd_soc_dai *dai)
 363{
 364        struct rk_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai);
 365
 366        dai->capture_dma_data = &i2s->capture_dma_data;
 367        dai->playback_dma_data = &i2s->playback_dma_data;
 368
 369        return 0;
 370}
 371
 372static const struct snd_soc_dai_ops rockchip_i2s_dai_ops = {
 373        .hw_params = rockchip_i2s_hw_params,
 374        .set_sysclk = rockchip_i2s_set_sysclk,
 375        .set_fmt = rockchip_i2s_set_fmt,
 376        .trigger = rockchip_i2s_trigger,
 377};
 378
 379static struct snd_soc_dai_driver rockchip_i2s_dai = {
 380        .probe = rockchip_i2s_dai_probe,
 381        .playback = {
 382                .stream_name = "Playback",
 383                .channels_min = 2,
 384                .channels_max = 8,
 385                .rates = SNDRV_PCM_RATE_8000_192000,
 386                .formats = (SNDRV_PCM_FMTBIT_S8 |
 387                            SNDRV_PCM_FMTBIT_S16_LE |
 388                            SNDRV_PCM_FMTBIT_S20_3LE |
 389                            SNDRV_PCM_FMTBIT_S24_LE |
 390                            SNDRV_PCM_FMTBIT_S32_LE),
 391        },
 392        .capture = {
 393                .stream_name = "Capture",
 394                .channels_min = 2,
 395                .channels_max = 2,
 396                .rates = SNDRV_PCM_RATE_8000_192000,
 397                .formats = (SNDRV_PCM_FMTBIT_S8 |
 398                            SNDRV_PCM_FMTBIT_S16_LE |
 399                            SNDRV_PCM_FMTBIT_S20_3LE |
 400                            SNDRV_PCM_FMTBIT_S24_LE |
 401                            SNDRV_PCM_FMTBIT_S32_LE),
 402        },
 403        .ops = &rockchip_i2s_dai_ops,
 404        .symmetric_rates = 1,
 405};
 406
 407static const struct snd_soc_component_driver rockchip_i2s_component = {
 408        .name = DRV_NAME,
 409};
 410
 411static bool rockchip_i2s_wr_reg(struct device *dev, unsigned int reg)
 412{
 413        switch (reg) {
 414        case I2S_TXCR:
 415        case I2S_RXCR:
 416        case I2S_CKR:
 417        case I2S_DMACR:
 418        case I2S_INTCR:
 419        case I2S_XFER:
 420        case I2S_CLR:
 421        case I2S_TXDR:
 422                return true;
 423        default:
 424                return false;
 425        }
 426}
 427
 428static bool rockchip_i2s_rd_reg(struct device *dev, unsigned int reg)
 429{
 430        switch (reg) {
 431        case I2S_TXCR:
 432        case I2S_RXCR:
 433        case I2S_CKR:
 434        case I2S_DMACR:
 435        case I2S_INTCR:
 436        case I2S_XFER:
 437        case I2S_CLR:
 438        case I2S_RXDR:
 439        case I2S_FIFOLR:
 440        case I2S_INTSR:
 441                return true;
 442        default:
 443                return false;
 444        }
 445}
 446
 447static bool rockchip_i2s_volatile_reg(struct device *dev, unsigned int reg)
 448{
 449        switch (reg) {
 450        case I2S_INTSR:
 451        case I2S_CLR:
 452                return true;
 453        default:
 454                return false;
 455        }
 456}
 457
 458static bool rockchip_i2s_precious_reg(struct device *dev, unsigned int reg)
 459{
 460        switch (reg) {
 461        default:
 462                return false;
 463        }
 464}
 465
 466static const struct reg_default rockchip_i2s_reg_defaults[] = {
 467        {0x00, 0x0000000f},
 468        {0x04, 0x0000000f},
 469        {0x08, 0x00071f1f},
 470        {0x10, 0x001f0000},
 471        {0x14, 0x01f00000},
 472};
 473
 474static const struct regmap_config rockchip_i2s_regmap_config = {
 475        .reg_bits = 32,
 476        .reg_stride = 4,
 477        .val_bits = 32,
 478        .max_register = I2S_RXDR,
 479        .reg_defaults = rockchip_i2s_reg_defaults,
 480        .num_reg_defaults = ARRAY_SIZE(rockchip_i2s_reg_defaults),
 481        .writeable_reg = rockchip_i2s_wr_reg,
 482        .readable_reg = rockchip_i2s_rd_reg,
 483        .volatile_reg = rockchip_i2s_volatile_reg,
 484        .precious_reg = rockchip_i2s_precious_reg,
 485        .cache_type = REGCACHE_FLAT,
 486};
 487
 488static int rockchip_i2s_probe(struct platform_device *pdev)
 489{
 490        struct device_node *node = pdev->dev.of_node;
 491        struct rk_i2s_dev *i2s;
 492        struct snd_soc_dai_driver *soc_dai;
 493        struct resource *res;
 494        void __iomem *regs;
 495        int ret;
 496        int val;
 497
 498        i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
 499        if (!i2s) {
 500                dev_err(&pdev->dev, "Can't allocate rk_i2s_dev\n");
 501                return -ENOMEM;
 502        }
 503
 504        /* try to prepare related clocks */
 505        i2s->hclk = devm_clk_get(&pdev->dev, "i2s_hclk");
 506        if (IS_ERR(i2s->hclk)) {
 507                dev_err(&pdev->dev, "Can't retrieve i2s bus clock\n");
 508                return PTR_ERR(i2s->hclk);
 509        }
 510        ret = clk_prepare_enable(i2s->hclk);
 511        if (ret) {
 512                dev_err(i2s->dev, "hclock enable failed %d\n", ret);
 513                return ret;
 514        }
 515
 516        i2s->mclk = devm_clk_get(&pdev->dev, "i2s_clk");
 517        if (IS_ERR(i2s->mclk)) {
 518                dev_err(&pdev->dev, "Can't retrieve i2s master clock\n");
 519                return PTR_ERR(i2s->mclk);
 520        }
 521
 522        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 523        regs = devm_ioremap_resource(&pdev->dev, res);
 524        if (IS_ERR(regs))
 525                return PTR_ERR(regs);
 526
 527        i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
 528                                            &rockchip_i2s_regmap_config);
 529        if (IS_ERR(i2s->regmap)) {
 530                dev_err(&pdev->dev,
 531                        "Failed to initialise managed register map\n");
 532                return PTR_ERR(i2s->regmap);
 533        }
 534
 535        i2s->playback_dma_data.addr = res->start + I2S_TXDR;
 536        i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 537        i2s->playback_dma_data.maxburst = 4;
 538
 539        i2s->capture_dma_data.addr = res->start + I2S_RXDR;
 540        i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 541        i2s->capture_dma_data.maxburst = 4;
 542
 543        i2s->dev = &pdev->dev;
 544        dev_set_drvdata(&pdev->dev, i2s);
 545
 546        pm_runtime_enable(&pdev->dev);
 547        if (!pm_runtime_enabled(&pdev->dev)) {
 548                ret = i2s_runtime_resume(&pdev->dev);
 549                if (ret)
 550                        goto err_pm_disable;
 551        }
 552
 553        soc_dai = devm_kzalloc(&pdev->dev,
 554                               sizeof(*soc_dai), GFP_KERNEL);
 555        if (!soc_dai)
 556                return -ENOMEM;
 557
 558        memcpy(soc_dai, &rockchip_i2s_dai, sizeof(*soc_dai));
 559        if (!of_property_read_u32(node, "rockchip,playback-channels", &val)) {
 560                if (val >= 2 && val <= 8)
 561                        soc_dai->playback.channels_max = val;
 562        }
 563
 564        if (!of_property_read_u32(node, "rockchip,capture-channels", &val)) {
 565                if (val >= 2 && val <= 8)
 566                        soc_dai->capture.channels_max = val;
 567        }
 568
 569        ret = devm_snd_soc_register_component(&pdev->dev,
 570                                              &rockchip_i2s_component,
 571                                              soc_dai, 1);
 572
 573        if (ret) {
 574                dev_err(&pdev->dev, "Could not register DAI\n");
 575                goto err_suspend;
 576        }
 577
 578        ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
 579        if (ret) {
 580                dev_err(&pdev->dev, "Could not register PCM\n");
 581                return ret;
 582        }
 583
 584        return 0;
 585
 586err_suspend:
 587        if (!pm_runtime_status_suspended(&pdev->dev))
 588                i2s_runtime_suspend(&pdev->dev);
 589err_pm_disable:
 590        pm_runtime_disable(&pdev->dev);
 591
 592        return ret;
 593}
 594
 595static int rockchip_i2s_remove(struct platform_device *pdev)
 596{
 597        struct rk_i2s_dev *i2s = dev_get_drvdata(&pdev->dev);
 598
 599        pm_runtime_disable(&pdev->dev);
 600        if (!pm_runtime_status_suspended(&pdev->dev))
 601                i2s_runtime_suspend(&pdev->dev);
 602
 603        clk_disable_unprepare(i2s->mclk);
 604        clk_disable_unprepare(i2s->hclk);
 605
 606        return 0;
 607}
 608
 609static const struct of_device_id rockchip_i2s_match[] = {
 610        { .compatible = "rockchip,rk3066-i2s", },
 611        { .compatible = "rockchip,rk3188-i2s", },
 612        { .compatible = "rockchip,rk3288-i2s", },
 613        { .compatible = "rockchip,rk3399-i2s", },
 614        {},
 615};
 616
 617static const struct dev_pm_ops rockchip_i2s_pm_ops = {
 618        SET_RUNTIME_PM_OPS(i2s_runtime_suspend, i2s_runtime_resume,
 619                           NULL)
 620};
 621
 622static struct platform_driver rockchip_i2s_driver = {
 623        .probe = rockchip_i2s_probe,
 624        .remove = rockchip_i2s_remove,
 625        .driver = {
 626                .name = DRV_NAME,
 627                .of_match_table = of_match_ptr(rockchip_i2s_match),
 628                .pm = &rockchip_i2s_pm_ops,
 629        },
 630};
 631module_platform_driver(rockchip_i2s_driver);
 632
 633MODULE_DESCRIPTION("ROCKCHIP IIS ASoC Interface");
 634MODULE_AUTHOR("jianqun <jay.xu@rock-chips.com>");
 635MODULE_LICENSE("GPL v2");
 636MODULE_ALIAS("platform:" DRV_NAME);
 637MODULE_DEVICE_TABLE(of, rockchip_i2s_match);
 638