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