883 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* sound/soc/rockchip/rockchip_i2s.c3 *4 * ALSA SoC Audio Layer - Rockchip I2S Controller driver5 *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.h>14#include <linux/clk.h>15#include <linux/pinctrl/consumer.h>16#include <linux/pm_runtime.h>17#include <linux/regmap.h>18#include <linux/spinlock.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_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 bool has_capture;44 bool has_playback;45 46/*47 * Used to indicate the tx/rx status.48 * I2S controller hopes to start the tx and rx together,49 * also to stop them when they are both try to stop.50*/51 bool tx_start;52 bool rx_start;53 bool is_master_mode;54 const struct rk_i2s_pins *pins;55 unsigned int bclk_ratio;56 spinlock_t lock; /* tx/rx lock */57 struct pinctrl *pinctrl;58 struct pinctrl_state *bclk_on;59 struct pinctrl_state *bclk_off;60};61 62static int i2s_pinctrl_select_bclk_on(struct rk_i2s_dev *i2s)63{64 int ret = 0;65 66 if (!IS_ERR(i2s->pinctrl) && !IS_ERR_OR_NULL(i2s->bclk_on))67 ret = pinctrl_select_state(i2s->pinctrl, i2s->bclk_on);68 69 if (ret)70 dev_err(i2s->dev, "bclk enable failed %d\n", ret);71 72 return ret;73}74 75static int i2s_pinctrl_select_bclk_off(struct rk_i2s_dev *i2s)76{77 78 int ret = 0;79 80 if (!IS_ERR(i2s->pinctrl) && !IS_ERR_OR_NULL(i2s->bclk_off))81 ret = pinctrl_select_state(i2s->pinctrl, i2s->bclk_off);82 83 if (ret)84 dev_err(i2s->dev, "bclk disable failed %d\n", ret);85 86 return ret;87}88 89static int i2s_runtime_suspend(struct device *dev)90{91 struct rk_i2s_dev *i2s = dev_get_drvdata(dev);92 93 regcache_cache_only(i2s->regmap, true);94 clk_disable_unprepare(i2s->mclk);95 96 return 0;97}98 99static int i2s_runtime_resume(struct device *dev)100{101 struct rk_i2s_dev *i2s = dev_get_drvdata(dev);102 int ret;103 104 ret = clk_prepare_enable(i2s->mclk);105 if (ret) {106 dev_err(i2s->dev, "clock enable failed %d\n", ret);107 return ret;108 }109 110 regcache_cache_only(i2s->regmap, false);111 regcache_mark_dirty(i2s->regmap);112 113 ret = regcache_sync(i2s->regmap);114 if (ret)115 clk_disable_unprepare(i2s->mclk);116 117 return ret;118}119 120static inline struct rk_i2s_dev *to_info(struct snd_soc_dai *dai)121{122 return snd_soc_dai_get_drvdata(dai);123}124 125static int rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)126{127 unsigned int val = 0;128 int ret = 0;129 130 spin_lock(&i2s->lock);131 if (on) {132 ret = regmap_update_bits(i2s->regmap, I2S_DMACR,133 I2S_DMACR_TDE_ENABLE,134 I2S_DMACR_TDE_ENABLE);135 if (ret < 0)136 goto end;137 ret = regmap_update_bits(i2s->regmap, I2S_XFER,138 I2S_XFER_TXS_START | I2S_XFER_RXS_START,139 I2S_XFER_TXS_START | I2S_XFER_RXS_START);140 if (ret < 0)141 goto end;142 i2s->tx_start = true;143 } else {144 i2s->tx_start = false;145 146 ret = regmap_update_bits(i2s->regmap, I2S_DMACR,147 I2S_DMACR_TDE_ENABLE,148 I2S_DMACR_TDE_DISABLE);149 if (ret < 0)150 goto end;151 152 if (!i2s->rx_start) {153 ret = regmap_update_bits(i2s->regmap, I2S_XFER,154 I2S_XFER_TXS_START | I2S_XFER_RXS_START,155 I2S_XFER_TXS_STOP | I2S_XFER_RXS_STOP);156 if (ret < 0)157 goto end;158 udelay(150);159 ret = regmap_update_bits(i2s->regmap, I2S_CLR,160 I2S_CLR_TXC | I2S_CLR_RXC,161 I2S_CLR_TXC | I2S_CLR_RXC);162 if (ret < 0)163 goto end;164 ret = regmap_read_poll_timeout_atomic(i2s->regmap,165 I2S_CLR,166 val,167 val == 0,168 20,169 200);170 if (ret < 0)171 dev_warn(i2s->dev, "fail to clear: %d\n", ret);172 }173 }174end:175 spin_unlock(&i2s->lock);176 if (ret < 0)177 dev_err(i2s->dev, "lrclk update failed\n");178 179 return ret;180}181 182static int rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)183{184 unsigned int val = 0;185 int ret = 0;186 187 spin_lock(&i2s->lock);188 if (on) {189 ret = regmap_update_bits(i2s->regmap, I2S_DMACR,190 I2S_DMACR_RDE_ENABLE,191 I2S_DMACR_RDE_ENABLE);192 if (ret < 0)193 goto end;194 195 ret = regmap_update_bits(i2s->regmap, I2S_XFER,196 I2S_XFER_TXS_START | I2S_XFER_RXS_START,197 I2S_XFER_TXS_START | I2S_XFER_RXS_START);198 if (ret < 0)199 goto end;200 i2s->rx_start = true;201 } else {202 i2s->rx_start = false;203 204 ret = regmap_update_bits(i2s->regmap, I2S_DMACR,205 I2S_DMACR_RDE_ENABLE,206 I2S_DMACR_RDE_DISABLE);207 if (ret < 0)208 goto end;209 210 if (!i2s->tx_start) {211 ret = regmap_update_bits(i2s->regmap, I2S_XFER,212 I2S_XFER_TXS_START | I2S_XFER_RXS_START,213 I2S_XFER_TXS_STOP | I2S_XFER_RXS_STOP);214 if (ret < 0)215 goto end;216 udelay(150);217 ret = regmap_update_bits(i2s->regmap, I2S_CLR,218 I2S_CLR_TXC | I2S_CLR_RXC,219 I2S_CLR_TXC | I2S_CLR_RXC);220 if (ret < 0)221 goto end;222 ret = regmap_read_poll_timeout_atomic(i2s->regmap,223 I2S_CLR,224 val,225 val == 0,226 20,227 200);228 if (ret < 0)229 dev_warn(i2s->dev, "fail to clear: %d\n", ret);230 }231 }232end:233 spin_unlock(&i2s->lock);234 if (ret < 0)235 dev_err(i2s->dev, "lrclk update failed\n");236 237 return ret;238}239 240static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,241 unsigned int fmt)242{243 struct rk_i2s_dev *i2s = to_info(cpu_dai);244 unsigned int mask = 0, val = 0;245 int ret = 0;246 247 pm_runtime_get_sync(cpu_dai->dev);248 mask = I2S_CKR_MSS_MASK;249 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {250 case SND_SOC_DAIFMT_BP_FP:251 /* Set source clock in Master mode */252 val = I2S_CKR_MSS_MASTER;253 i2s->is_master_mode = true;254 break;255 case SND_SOC_DAIFMT_BC_FC:256 val = I2S_CKR_MSS_SLAVE;257 i2s->is_master_mode = false;258 break;259 default:260 ret = -EINVAL;261 goto err_pm_put;262 }263 264 regmap_update_bits(i2s->regmap, I2S_CKR, mask, val);265 266 mask = I2S_CKR_CKP_MASK | I2S_CKR_TLP_MASK | I2S_CKR_RLP_MASK;267 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {268 case SND_SOC_DAIFMT_NB_NF:269 val = I2S_CKR_CKP_NORMAL |270 I2S_CKR_TLP_NORMAL |271 I2S_CKR_RLP_NORMAL;272 break;273 case SND_SOC_DAIFMT_NB_IF:274 val = I2S_CKR_CKP_NORMAL |275 I2S_CKR_TLP_INVERTED |276 I2S_CKR_RLP_INVERTED;277 break;278 case SND_SOC_DAIFMT_IB_NF:279 val = I2S_CKR_CKP_INVERTED |280 I2S_CKR_TLP_NORMAL |281 I2S_CKR_RLP_NORMAL;282 break;283 case SND_SOC_DAIFMT_IB_IF:284 val = I2S_CKR_CKP_INVERTED |285 I2S_CKR_TLP_INVERTED |286 I2S_CKR_RLP_INVERTED;287 break;288 default:289 ret = -EINVAL;290 goto err_pm_put;291 }292 293 regmap_update_bits(i2s->regmap, I2S_CKR, mask, val);294 295 mask = I2S_TXCR_IBM_MASK | I2S_TXCR_TFS_MASK | I2S_TXCR_PBM_MASK;296 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {297 case SND_SOC_DAIFMT_RIGHT_J:298 val = I2S_TXCR_IBM_RSJM;299 break;300 case SND_SOC_DAIFMT_LEFT_J:301 val = I2S_TXCR_IBM_LSJM;302 break;303 case SND_SOC_DAIFMT_I2S:304 val = I2S_TXCR_IBM_NORMAL;305 break;306 case SND_SOC_DAIFMT_DSP_A: /* PCM delay 1 bit mode */307 val = I2S_TXCR_TFS_PCM | I2S_TXCR_PBM_MODE(1);308 break;309 case SND_SOC_DAIFMT_DSP_B: /* PCM no delay mode */310 val = I2S_TXCR_TFS_PCM;311 break;312 default:313 ret = -EINVAL;314 goto err_pm_put;315 }316 317 regmap_update_bits(i2s->regmap, I2S_TXCR, mask, val);318 319 mask = I2S_RXCR_IBM_MASK | I2S_RXCR_TFS_MASK | I2S_RXCR_PBM_MASK;320 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {321 case SND_SOC_DAIFMT_RIGHT_J:322 val = I2S_RXCR_IBM_RSJM;323 break;324 case SND_SOC_DAIFMT_LEFT_J:325 val = I2S_RXCR_IBM_LSJM;326 break;327 case SND_SOC_DAIFMT_I2S:328 val = I2S_RXCR_IBM_NORMAL;329 break;330 case SND_SOC_DAIFMT_DSP_A: /* PCM delay 1 bit mode */331 val = I2S_RXCR_TFS_PCM | I2S_RXCR_PBM_MODE(1);332 break;333 case SND_SOC_DAIFMT_DSP_B: /* PCM no delay mode */334 val = I2S_RXCR_TFS_PCM;335 break;336 default:337 ret = -EINVAL;338 goto err_pm_put;339 }340 341 regmap_update_bits(i2s->regmap, I2S_RXCR, mask, val);342 343err_pm_put:344 pm_runtime_put(cpu_dai->dev);345 346 return ret;347}348 349static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,350 struct snd_pcm_hw_params *params,351 struct snd_soc_dai *dai)352{353 struct rk_i2s_dev *i2s = to_info(dai);354 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);355 unsigned int val = 0;356 unsigned int mclk_rate, bclk_rate, div_bclk, div_lrck;357 358 if (i2s->is_master_mode) {359 mclk_rate = clk_get_rate(i2s->mclk);360 bclk_rate = i2s->bclk_ratio * params_rate(params);361 if (!bclk_rate)362 return -EINVAL;363 364 div_bclk = DIV_ROUND_CLOSEST(mclk_rate, bclk_rate);365 div_lrck = bclk_rate / params_rate(params);366 regmap_update_bits(i2s->regmap, I2S_CKR,367 I2S_CKR_MDIV_MASK,368 I2S_CKR_MDIV(div_bclk));369 370 regmap_update_bits(i2s->regmap, I2S_CKR,371 I2S_CKR_TSD_MASK |372 I2S_CKR_RSD_MASK,373 I2S_CKR_TSD(div_lrck) |374 I2S_CKR_RSD(div_lrck));375 }376 377 switch (params_format(params)) {378 case SNDRV_PCM_FORMAT_S8:379 val |= I2S_TXCR_VDW(8);380 break;381 case SNDRV_PCM_FORMAT_S16_LE:382 val |= I2S_TXCR_VDW(16);383 break;384 case SNDRV_PCM_FORMAT_S20_3LE:385 val |= I2S_TXCR_VDW(20);386 break;387 case SNDRV_PCM_FORMAT_S24_LE:388 val |= I2S_TXCR_VDW(24);389 break;390 case SNDRV_PCM_FORMAT_S32_LE:391 val |= I2S_TXCR_VDW(32);392 break;393 default:394 return -EINVAL;395 }396 397 switch (params_channels(params)) {398 case 8:399 val |= I2S_CHN_8;400 break;401 case 6:402 val |= I2S_CHN_6;403 break;404 case 4:405 val |= I2S_CHN_4;406 break;407 case 2:408 val |= I2S_CHN_2;409 break;410 default:411 dev_err(i2s->dev, "invalid channel: %d\n",412 params_channels(params));413 return -EINVAL;414 }415 416 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)417 regmap_update_bits(i2s->regmap, I2S_RXCR,418 I2S_RXCR_VDW_MASK | I2S_RXCR_CSR_MASK,419 val);420 else421 regmap_update_bits(i2s->regmap, I2S_TXCR,422 I2S_TXCR_VDW_MASK | I2S_TXCR_CSR_MASK,423 val);424 425 if (!IS_ERR(i2s->grf) && i2s->pins) {426 regmap_read(i2s->regmap, I2S_TXCR, &val);427 val &= I2S_TXCR_CSR_MASK;428 429 switch (val) {430 case I2S_CHN_4:431 val = I2S_IO_4CH_OUT_6CH_IN;432 break;433 case I2S_CHN_6:434 val = I2S_IO_6CH_OUT_4CH_IN;435 break;436 case I2S_CHN_8:437 val = I2S_IO_8CH_OUT_2CH_IN;438 break;439 default:440 val = I2S_IO_2CH_OUT_8CH_IN;441 break;442 }443 444 val <<= i2s->pins->shift;445 val |= (I2S_IO_DIRECTION_MASK << i2s->pins->shift) << 16;446 regmap_write(i2s->grf, i2s->pins->reg_offset, val);447 }448 449 regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK,450 I2S_DMACR_TDL(16));451 regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK,452 I2S_DMACR_RDL(16));453 454 val = I2S_CKR_TRCM_TXRX;455 if (dai->driver->symmetric_rate && rtd->dai_link->symmetric_rate)456 val = I2S_CKR_TRCM_TXONLY;457 458 regmap_update_bits(i2s->regmap, I2S_CKR,459 I2S_CKR_TRCM_MASK,460 val);461 return 0;462}463 464static int rockchip_i2s_trigger(struct snd_pcm_substream *substream,465 int cmd, struct snd_soc_dai *dai)466{467 struct rk_i2s_dev *i2s = to_info(dai);468 int ret = 0;469 470 switch (cmd) {471 case SNDRV_PCM_TRIGGER_START:472 case SNDRV_PCM_TRIGGER_RESUME:473 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:474 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)475 ret = rockchip_snd_rxctrl(i2s, 1);476 else477 ret = rockchip_snd_txctrl(i2s, 1);478 if (ret < 0)479 return ret;480 i2s_pinctrl_select_bclk_on(i2s);481 break;482 case SNDRV_PCM_TRIGGER_SUSPEND:483 case SNDRV_PCM_TRIGGER_STOP:484 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:485 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {486 if (!i2s->tx_start)487 i2s_pinctrl_select_bclk_off(i2s);488 ret = rockchip_snd_rxctrl(i2s, 0);489 } else {490 if (!i2s->rx_start)491 i2s_pinctrl_select_bclk_off(i2s);492 ret = rockchip_snd_txctrl(i2s, 0);493 }494 break;495 default:496 ret = -EINVAL;497 break;498 }499 500 return ret;501}502 503static int rockchip_i2s_set_bclk_ratio(struct snd_soc_dai *dai,504 unsigned int ratio)505{506 struct rk_i2s_dev *i2s = to_info(dai);507 508 i2s->bclk_ratio = ratio;509 510 return 0;511}512 513static int rockchip_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id,514 unsigned int freq, int dir)515{516 struct rk_i2s_dev *i2s = to_info(cpu_dai);517 int ret;518 519 if (freq == 0)520 return 0;521 522 ret = clk_set_rate(i2s->mclk, freq);523 if (ret)524 dev_err(i2s->dev, "Fail to set mclk %d\n", ret);525 526 return ret;527}528 529static int rockchip_i2s_dai_probe(struct snd_soc_dai *dai)530{531 struct rk_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai);532 533 snd_soc_dai_init_dma_data(dai,534 i2s->has_playback ? &i2s->playback_dma_data : NULL,535 i2s->has_capture ? &i2s->capture_dma_data : NULL);536 537 return 0;538}539 540static const struct snd_soc_dai_ops rockchip_i2s_dai_ops = {541 .probe = rockchip_i2s_dai_probe,542 .hw_params = rockchip_i2s_hw_params,543 .set_bclk_ratio = rockchip_i2s_set_bclk_ratio,544 .set_sysclk = rockchip_i2s_set_sysclk,545 .set_fmt = rockchip_i2s_set_fmt,546 .trigger = rockchip_i2s_trigger,547};548 549static struct snd_soc_dai_driver rockchip_i2s_dai = {550 .ops = &rockchip_i2s_dai_ops,551 .symmetric_rate = 1,552};553 554static const struct snd_soc_component_driver rockchip_i2s_component = {555 .name = DRV_NAME,556 .legacy_dai_naming = 1,557};558 559static bool rockchip_i2s_wr_reg(struct device *dev, unsigned int reg)560{561 switch (reg) {562 case I2S_TXCR:563 case I2S_RXCR:564 case I2S_CKR:565 case I2S_DMACR:566 case I2S_INTCR:567 case I2S_XFER:568 case I2S_CLR:569 case I2S_TXDR:570 return true;571 default:572 return false;573 }574}575 576static bool rockchip_i2s_rd_reg(struct device *dev, unsigned int reg)577{578 switch (reg) {579 case I2S_TXCR:580 case I2S_RXCR:581 case I2S_CKR:582 case I2S_DMACR:583 case I2S_INTCR:584 case I2S_XFER:585 case I2S_CLR:586 case I2S_TXDR:587 case I2S_RXDR:588 case I2S_FIFOLR:589 case I2S_INTSR:590 return true;591 default:592 return false;593 }594}595 596static bool rockchip_i2s_volatile_reg(struct device *dev, unsigned int reg)597{598 switch (reg) {599 case I2S_INTSR:600 case I2S_CLR:601 case I2S_FIFOLR:602 case I2S_TXDR:603 case I2S_RXDR:604 return true;605 default:606 return false;607 }608}609 610static bool rockchip_i2s_precious_reg(struct device *dev, unsigned int reg)611{612 switch (reg) {613 case I2S_RXDR:614 return true;615 default:616 return false;617 }618}619 620static const struct reg_default rockchip_i2s_reg_defaults[] = {621 {0x00, 0x0000000f},622 {0x04, 0x0000000f},623 {0x08, 0x00071f1f},624 {0x10, 0x001f0000},625 {0x14, 0x01f00000},626};627 628static const struct regmap_config rockchip_i2s_regmap_config = {629 .reg_bits = 32,630 .reg_stride = 4,631 .val_bits = 32,632 .max_register = I2S_RXDR,633 .reg_defaults = rockchip_i2s_reg_defaults,634 .num_reg_defaults = ARRAY_SIZE(rockchip_i2s_reg_defaults),635 .writeable_reg = rockchip_i2s_wr_reg,636 .readable_reg = rockchip_i2s_rd_reg,637 .volatile_reg = rockchip_i2s_volatile_reg,638 .precious_reg = rockchip_i2s_precious_reg,639 .cache_type = REGCACHE_FLAT,640};641 642static const struct rk_i2s_pins rk3399_i2s_pins = {643 .reg_offset = 0xe220,644 .shift = 11,645};646 647static const struct of_device_id rockchip_i2s_match[] __maybe_unused = {648 { .compatible = "rockchip,px30-i2s", },649 { .compatible = "rockchip,rk1808-i2s", },650 { .compatible = "rockchip,rk3036-i2s", },651 { .compatible = "rockchip,rk3066-i2s", },652 { .compatible = "rockchip,rk3128-i2s", },653 { .compatible = "rockchip,rk3188-i2s", },654 { .compatible = "rockchip,rk3228-i2s", },655 { .compatible = "rockchip,rk3288-i2s", },656 { .compatible = "rockchip,rk3308-i2s", },657 { .compatible = "rockchip,rk3328-i2s", },658 { .compatible = "rockchip,rk3366-i2s", },659 { .compatible = "rockchip,rk3368-i2s", },660 { .compatible = "rockchip,rk3399-i2s", .data = &rk3399_i2s_pins },661 { .compatible = "rockchip,rk3588-i2s", },662 { .compatible = "rockchip,rv1126-i2s", },663 {},664};665 666static int rockchip_i2s_init_dai(struct rk_i2s_dev *i2s, struct resource *res,667 struct snd_soc_dai_driver **dp)668{669 struct device_node *node = i2s->dev->of_node;670 struct snd_soc_dai_driver *dai;671 struct property *dma_names;672 const char *dma_name;673 unsigned int val;674 675 of_property_for_each_string(node, "dma-names", dma_names, dma_name) {676 if (!strcmp(dma_name, "tx"))677 i2s->has_playback = true;678 if (!strcmp(dma_name, "rx"))679 i2s->has_capture = true;680 }681 682 dai = devm_kmemdup(i2s->dev, &rockchip_i2s_dai,683 sizeof(*dai), GFP_KERNEL);684 if (!dai)685 return -ENOMEM;686 687 if (i2s->has_playback) {688 dai->playback.stream_name = "Playback";689 dai->playback.channels_min = 2;690 dai->playback.channels_max = 8;691 dai->playback.rates = SNDRV_PCM_RATE_8000_192000;692 dai->playback.formats = SNDRV_PCM_FMTBIT_S8 |693 SNDRV_PCM_FMTBIT_S16_LE |694 SNDRV_PCM_FMTBIT_S20_3LE |695 SNDRV_PCM_FMTBIT_S24_LE |696 SNDRV_PCM_FMTBIT_S32_LE;697 698 i2s->playback_dma_data.addr = res->start + I2S_TXDR;699 i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;700 i2s->playback_dma_data.maxburst = 8;701 702 if (!of_property_read_u32(node, "rockchip,playback-channels", &val)) {703 if (val >= 2 && val <= 8)704 dai->playback.channels_max = val;705 }706 }707 708 if (i2s->has_capture) {709 dai->capture.stream_name = "Capture";710 dai->capture.channels_min = 2;711 dai->capture.channels_max = 8;712 dai->capture.rates = SNDRV_PCM_RATE_8000_192000;713 dai->capture.formats = SNDRV_PCM_FMTBIT_S8 |714 SNDRV_PCM_FMTBIT_S16_LE |715 SNDRV_PCM_FMTBIT_S20_3LE |716 SNDRV_PCM_FMTBIT_S24_LE |717 SNDRV_PCM_FMTBIT_S32_LE;718 719 i2s->capture_dma_data.addr = res->start + I2S_RXDR;720 i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;721 i2s->capture_dma_data.maxburst = 8;722 723 if (!of_property_read_u32(node, "rockchip,capture-channels", &val)) {724 if (val >= 2 && val <= 8)725 dai->capture.channels_max = val;726 }727 }728 729 if (dp)730 *dp = dai;731 732 return 0;733}734 735static int rockchip_i2s_probe(struct platform_device *pdev)736{737 struct device_node *node = pdev->dev.of_node;738 struct rk_i2s_dev *i2s;739 struct snd_soc_dai_driver *dai;740 struct resource *res;741 void __iomem *regs;742 int ret;743 744 i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);745 if (!i2s)746 return -ENOMEM;747 748 spin_lock_init(&i2s->lock);749 i2s->dev = &pdev->dev;750 751 i2s->grf = syscon_regmap_lookup_by_phandle(node, "rockchip,grf");752 if (!IS_ERR(i2s->grf)) {753 i2s->pins = device_get_match_data(&pdev->dev);754 if (!i2s->pins)755 return -EINVAL;756 757 }758 759 /* try to prepare related clocks */760 i2s->hclk = devm_clk_get(&pdev->dev, "i2s_hclk");761 if (IS_ERR(i2s->hclk)) {762 dev_err(&pdev->dev, "Can't retrieve i2s bus clock\n");763 return PTR_ERR(i2s->hclk);764 }765 ret = clk_prepare_enable(i2s->hclk);766 if (ret) {767 dev_err(i2s->dev, "hclock enable failed %d\n", ret);768 return ret;769 }770 771 i2s->mclk = devm_clk_get(&pdev->dev, "i2s_clk");772 if (IS_ERR(i2s->mclk)) {773 dev_err(&pdev->dev, "Can't retrieve i2s master clock\n");774 ret = PTR_ERR(i2s->mclk);775 goto err_clk;776 }777 778 regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);779 if (IS_ERR(regs)) {780 ret = PTR_ERR(regs);781 goto err_clk;782 }783 784 i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,785 &rockchip_i2s_regmap_config);786 if (IS_ERR(i2s->regmap)) {787 dev_err(&pdev->dev,788 "Failed to initialise managed register map\n");789 ret = PTR_ERR(i2s->regmap);790 goto err_clk;791 }792 793 i2s->bclk_ratio = 64;794 i2s->pinctrl = devm_pinctrl_get(&pdev->dev);795 if (!IS_ERR(i2s->pinctrl)) {796 i2s->bclk_on = pinctrl_lookup_state(i2s->pinctrl, "bclk_on");797 if (!IS_ERR_OR_NULL(i2s->bclk_on)) {798 i2s->bclk_off = pinctrl_lookup_state(i2s->pinctrl, "bclk_off");799 if (IS_ERR_OR_NULL(i2s->bclk_off)) {800 dev_err(&pdev->dev, "failed to find i2s bclk_off\n");801 ret = -EINVAL;802 goto err_clk;803 }804 }805 } else {806 dev_dbg(&pdev->dev, "failed to find i2s pinctrl\n");807 }808 809 i2s_pinctrl_select_bclk_off(i2s);810 811 dev_set_drvdata(&pdev->dev, i2s);812 813 pm_runtime_enable(&pdev->dev);814 if (!pm_runtime_enabled(&pdev->dev)) {815 ret = i2s_runtime_resume(&pdev->dev);816 if (ret)817 goto err_pm_disable;818 }819 820 ret = rockchip_i2s_init_dai(i2s, res, &dai);821 if (ret)822 goto err_pm_disable;823 824 ret = devm_snd_soc_register_component(&pdev->dev,825 &rockchip_i2s_component,826 dai, 1);827 828 if (ret) {829 dev_err(&pdev->dev, "Could not register DAI\n");830 goto err_suspend;831 }832 833 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);834 if (ret) {835 dev_err(&pdev->dev, "Could not register PCM\n");836 goto err_suspend;837 }838 839 return 0;840 841err_suspend:842 if (!pm_runtime_status_suspended(&pdev->dev))843 i2s_runtime_suspend(&pdev->dev);844err_pm_disable:845 pm_runtime_disable(&pdev->dev);846err_clk:847 clk_disable_unprepare(i2s->hclk);848 return ret;849}850 851static void rockchip_i2s_remove(struct platform_device *pdev)852{853 struct rk_i2s_dev *i2s = dev_get_drvdata(&pdev->dev);854 855 pm_runtime_disable(&pdev->dev);856 if (!pm_runtime_status_suspended(&pdev->dev))857 i2s_runtime_suspend(&pdev->dev);858 859 clk_disable_unprepare(i2s->hclk);860}861 862static const struct dev_pm_ops rockchip_i2s_pm_ops = {863 SET_RUNTIME_PM_OPS(i2s_runtime_suspend, i2s_runtime_resume,864 NULL)865};866 867static struct platform_driver rockchip_i2s_driver = {868 .probe = rockchip_i2s_probe,869 .remove = rockchip_i2s_remove,870 .driver = {871 .name = DRV_NAME,872 .of_match_table = of_match_ptr(rockchip_i2s_match),873 .pm = &rockchip_i2s_pm_ops,874 },875};876module_platform_driver(rockchip_i2s_driver);877 878MODULE_DESCRIPTION("ROCKCHIP IIS ASoC Interface");879MODULE_AUTHOR("jianqun <jay.xu@rock-chips.com>");880MODULE_LICENSE("GPL v2");881MODULE_ALIAS("platform:" DRV_NAME);882MODULE_DEVICE_TABLE(of, rockchip_i2s_match);883