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 28 struct rk_i2s_pins { 29 u32 reg_offset; 30 u32 shift; 31 }; 32 33 struct 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 56 static 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 65 static 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 79 static inline struct rk_i2s_dev *to_info(struct snd_soc_dai *dai) 80 { 81 return snd_soc_dai_get_drvdata(dai); 82 } 83 84 static 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 130 static 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 176 static 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 236 static 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 351 static 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 382 static 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 395 static 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 405 static 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 412 static 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 440 static const struct snd_soc_component_driver rockchip_i2s_component = { 441 .name = DRV_NAME, 442 }; 443 444 static 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 461 static 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 480 static 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 491 static bool rockchip_i2s_precious_reg(struct device *dev, unsigned int reg) 492 { 493 switch (reg) { 494 default: 495 return false; 496 } 497 } 498 499 static 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 507 static 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 521 static const struct rk_i2s_pins rk3399_i2s_pins = { 522 .reg_offset = 0xe220, 523 .shift = 11, 524 }; 525 526 static 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 534 static 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 643 err_suspend: 644 if (!pm_runtime_status_suspended(&pdev->dev)) 645 i2s_runtime_suspend(&pdev->dev); 646 err_pm_disable: 647 pm_runtime_disable(&pdev->dev); 648 649 return ret; 650 } 651 652 static 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 666 static const struct dev_pm_ops rockchip_i2s_pm_ops = { 667 SET_RUNTIME_PM_OPS(i2s_runtime_suspend, i2s_runtime_resume, 668 NULL) 669 }; 670 671 static 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 }; 680 module_platform_driver(rockchip_i2s_driver); 681 682 MODULE_DESCRIPTION("ROCKCHIP IIS ASoC Interface"); 683 MODULE_AUTHOR("jianqun <jay.xu@rock-chips.com>"); 684 MODULE_LICENSE("GPL v2"); 685 MODULE_ALIAS("platform:" DRV_NAME); 686 MODULE_DEVICE_TABLE(of, rockchip_i2s_match); 687