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