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 26 struct 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 }; 45 46 static int i2s_runtime_suspend(struct device *dev) 47 { 48 struct rk_i2s_dev *i2s = dev_get_drvdata(dev); 49 50 clk_disable_unprepare(i2s->mclk); 51 52 return 0; 53 } 54 55 static int i2s_runtime_resume(struct device *dev) 56 { 57 struct rk_i2s_dev *i2s = dev_get_drvdata(dev); 58 int ret; 59 60 ret = clk_prepare_enable(i2s->mclk); 61 if (ret) { 62 dev_err(i2s->dev, "clock enable failed %d\n", ret); 63 return ret; 64 } 65 66 return 0; 67 } 68 69 static inline struct rk_i2s_dev *to_info(struct snd_soc_dai *dai) 70 { 71 return snd_soc_dai_get_drvdata(dai); 72 } 73 74 static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on) 75 { 76 unsigned int val = 0; 77 int retry = 10; 78 79 if (on) { 80 regmap_update_bits(i2s->regmap, I2S_DMACR, 81 I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE); 82 83 regmap_update_bits(i2s->regmap, I2S_XFER, 84 I2S_XFER_TXS_START | I2S_XFER_RXS_START, 85 I2S_XFER_TXS_START | I2S_XFER_RXS_START); 86 87 i2s->tx_start = true; 88 } else { 89 i2s->tx_start = false; 90 91 regmap_update_bits(i2s->regmap, I2S_DMACR, 92 I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE); 93 94 if (!i2s->rx_start) { 95 regmap_update_bits(i2s->regmap, I2S_XFER, 96 I2S_XFER_TXS_START | 97 I2S_XFER_RXS_START, 98 I2S_XFER_TXS_STOP | 99 I2S_XFER_RXS_STOP); 100 101 regmap_update_bits(i2s->regmap, I2S_CLR, 102 I2S_CLR_TXC | I2S_CLR_RXC, 103 I2S_CLR_TXC | I2S_CLR_RXC); 104 105 regmap_read(i2s->regmap, I2S_CLR, &val); 106 107 /* Should wait for clear operation to finish */ 108 while (val) { 109 regmap_read(i2s->regmap, I2S_CLR, &val); 110 retry--; 111 if (!retry) 112 dev_warn(i2s->dev, "fail to clear\n"); 113 } 114 } 115 } 116 } 117 118 static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on) 119 { 120 unsigned int val = 0; 121 int retry = 10; 122 123 if (on) { 124 regmap_update_bits(i2s->regmap, I2S_DMACR, 125 I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE); 126 127 regmap_update_bits(i2s->regmap, I2S_XFER, 128 I2S_XFER_TXS_START | I2S_XFER_RXS_START, 129 I2S_XFER_TXS_START | I2S_XFER_RXS_START); 130 131 i2s->rx_start = true; 132 } else { 133 i2s->rx_start = false; 134 135 regmap_update_bits(i2s->regmap, I2S_DMACR, 136 I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_DISABLE); 137 138 if (!i2s->tx_start) { 139 regmap_update_bits(i2s->regmap, I2S_XFER, 140 I2S_XFER_TXS_START | 141 I2S_XFER_RXS_START, 142 I2S_XFER_TXS_STOP | 143 I2S_XFER_RXS_STOP); 144 145 regmap_update_bits(i2s->regmap, I2S_CLR, 146 I2S_CLR_TXC | I2S_CLR_RXC, 147 I2S_CLR_TXC | I2S_CLR_RXC); 148 149 regmap_read(i2s->regmap, I2S_CLR, &val); 150 151 /* Should wait for clear operation to finish */ 152 while (val) { 153 regmap_read(i2s->regmap, I2S_CLR, &val); 154 retry--; 155 if (!retry) 156 dev_warn(i2s->dev, "fail to clear\n"); 157 } 158 } 159 } 160 } 161 162 static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, 163 unsigned int fmt) 164 { 165 struct rk_i2s_dev *i2s = to_info(cpu_dai); 166 unsigned int mask = 0, val = 0; 167 168 mask = I2S_CKR_MSS_MASK; 169 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 170 case SND_SOC_DAIFMT_CBS_CFS: 171 /* Set source clock in Master mode */ 172 val = I2S_CKR_MSS_MASTER; 173 break; 174 case SND_SOC_DAIFMT_CBM_CFM: 175 val = I2S_CKR_MSS_SLAVE; 176 break; 177 default: 178 return -EINVAL; 179 } 180 181 regmap_update_bits(i2s->regmap, I2S_CKR, mask, val); 182 183 mask = I2S_TXCR_IBM_MASK; 184 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 185 case SND_SOC_DAIFMT_RIGHT_J: 186 val = I2S_TXCR_IBM_RSJM; 187 break; 188 case SND_SOC_DAIFMT_LEFT_J: 189 val = I2S_TXCR_IBM_LSJM; 190 break; 191 case SND_SOC_DAIFMT_I2S: 192 val = I2S_TXCR_IBM_NORMAL; 193 break; 194 default: 195 return -EINVAL; 196 } 197 198 regmap_update_bits(i2s->regmap, I2S_TXCR, mask, val); 199 200 mask = I2S_RXCR_IBM_MASK; 201 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 202 case SND_SOC_DAIFMT_RIGHT_J: 203 val = I2S_RXCR_IBM_RSJM; 204 break; 205 case SND_SOC_DAIFMT_LEFT_J: 206 val = I2S_RXCR_IBM_LSJM; 207 break; 208 case SND_SOC_DAIFMT_I2S: 209 val = I2S_RXCR_IBM_NORMAL; 210 break; 211 default: 212 return -EINVAL; 213 } 214 215 regmap_update_bits(i2s->regmap, I2S_RXCR, mask, val); 216 217 return 0; 218 } 219 220 static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, 221 struct snd_pcm_hw_params *params, 222 struct snd_soc_dai *dai) 223 { 224 struct rk_i2s_dev *i2s = to_info(dai); 225 unsigned int val = 0; 226 227 switch (params_format(params)) { 228 case SNDRV_PCM_FORMAT_S8: 229 val |= I2S_TXCR_VDW(8); 230 break; 231 case SNDRV_PCM_FORMAT_S16_LE: 232 val |= I2S_TXCR_VDW(16); 233 break; 234 case SNDRV_PCM_FORMAT_S20_3LE: 235 val |= I2S_TXCR_VDW(20); 236 break; 237 case SNDRV_PCM_FORMAT_S24_LE: 238 val |= I2S_TXCR_VDW(24); 239 break; 240 default: 241 return -EINVAL; 242 } 243 244 regmap_update_bits(i2s->regmap, I2S_TXCR, I2S_TXCR_VDW_MASK, val); 245 regmap_update_bits(i2s->regmap, I2S_RXCR, I2S_RXCR_VDW_MASK, val); 246 247 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 248 dai->playback_dma_data = &i2s->playback_dma_data; 249 regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK, 250 I2S_DMACR_TDL(1) | I2S_DMACR_TDE_ENABLE); 251 } else { 252 dai->capture_dma_data = &i2s->capture_dma_data; 253 regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK, 254 I2S_DMACR_RDL(1) | I2S_DMACR_RDE_ENABLE); 255 } 256 257 return 0; 258 } 259 260 static int rockchip_i2s_trigger(struct snd_pcm_substream *substream, 261 int cmd, struct snd_soc_dai *dai) 262 { 263 struct rk_i2s_dev *i2s = to_info(dai); 264 int ret = 0; 265 266 switch (cmd) { 267 case SNDRV_PCM_TRIGGER_START: 268 case SNDRV_PCM_TRIGGER_RESUME: 269 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 270 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 271 rockchip_snd_rxctrl(i2s, 1); 272 else 273 rockchip_snd_txctrl(i2s, 1); 274 break; 275 case SNDRV_PCM_TRIGGER_SUSPEND: 276 case SNDRV_PCM_TRIGGER_STOP: 277 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 278 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 279 rockchip_snd_rxctrl(i2s, 0); 280 else 281 rockchip_snd_txctrl(i2s, 0); 282 break; 283 default: 284 ret = -EINVAL; 285 break; 286 } 287 288 return ret; 289 } 290 291 static int rockchip_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, 292 unsigned int freq, int dir) 293 { 294 struct rk_i2s_dev *i2s = to_info(cpu_dai); 295 int ret; 296 297 ret = clk_set_rate(i2s->mclk, freq); 298 if (ret) 299 dev_err(i2s->dev, "Fail to set mclk %d\n", ret); 300 301 return ret; 302 } 303 304 static const struct snd_soc_dai_ops rockchip_i2s_dai_ops = { 305 .hw_params = rockchip_i2s_hw_params, 306 .set_sysclk = rockchip_i2s_set_sysclk, 307 .set_fmt = rockchip_i2s_set_fmt, 308 .trigger = rockchip_i2s_trigger, 309 }; 310 311 static struct snd_soc_dai_driver rockchip_i2s_dai = { 312 .playback = { 313 .channels_min = 2, 314 .channels_max = 8, 315 .rates = SNDRV_PCM_RATE_8000_192000, 316 .formats = (SNDRV_PCM_FMTBIT_S8 | 317 SNDRV_PCM_FMTBIT_S16_LE | 318 SNDRV_PCM_FMTBIT_S20_3LE | 319 SNDRV_PCM_FMTBIT_S24_LE), 320 }, 321 .capture = { 322 .channels_min = 2, 323 .channels_max = 2, 324 .rates = SNDRV_PCM_RATE_8000_192000, 325 .formats = (SNDRV_PCM_FMTBIT_S8 | 326 SNDRV_PCM_FMTBIT_S16_LE | 327 SNDRV_PCM_FMTBIT_S20_3LE | 328 SNDRV_PCM_FMTBIT_S24_LE), 329 }, 330 .ops = &rockchip_i2s_dai_ops, 331 }; 332 333 static const struct snd_soc_component_driver rockchip_i2s_component = { 334 .name = DRV_NAME, 335 }; 336 337 static bool rockchip_i2s_wr_reg(struct device *dev, unsigned int reg) 338 { 339 switch (reg) { 340 case I2S_TXCR: 341 case I2S_RXCR: 342 case I2S_CKR: 343 case I2S_DMACR: 344 case I2S_INTCR: 345 case I2S_XFER: 346 case I2S_CLR: 347 case I2S_TXDR: 348 return true; 349 default: 350 return false; 351 } 352 } 353 354 static bool rockchip_i2s_rd_reg(struct device *dev, unsigned int reg) 355 { 356 switch (reg) { 357 case I2S_TXCR: 358 case I2S_RXCR: 359 case I2S_CKR: 360 case I2S_DMACR: 361 case I2S_INTCR: 362 case I2S_XFER: 363 case I2S_CLR: 364 case I2S_RXDR: 365 case I2S_FIFOLR: 366 case I2S_INTSR: 367 return true; 368 default: 369 return false; 370 } 371 } 372 373 static bool rockchip_i2s_volatile_reg(struct device *dev, unsigned int reg) 374 { 375 switch (reg) { 376 case I2S_INTSR: 377 case I2S_CLR: 378 return true; 379 default: 380 return false; 381 } 382 } 383 384 static bool rockchip_i2s_precious_reg(struct device *dev, unsigned int reg) 385 { 386 switch (reg) { 387 default: 388 return false; 389 } 390 } 391 392 static const struct regmap_config rockchip_i2s_regmap_config = { 393 .reg_bits = 32, 394 .reg_stride = 4, 395 .val_bits = 32, 396 .max_register = I2S_RXDR, 397 .writeable_reg = rockchip_i2s_wr_reg, 398 .readable_reg = rockchip_i2s_rd_reg, 399 .volatile_reg = rockchip_i2s_volatile_reg, 400 .precious_reg = rockchip_i2s_precious_reg, 401 .cache_type = REGCACHE_FLAT, 402 }; 403 404 static int rockchip_i2s_probe(struct platform_device *pdev) 405 { 406 struct rk_i2s_dev *i2s; 407 struct resource *res; 408 void __iomem *regs; 409 int ret; 410 411 i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); 412 if (!i2s) { 413 dev_err(&pdev->dev, "Can't allocate rk_i2s_dev\n"); 414 return -ENOMEM; 415 } 416 417 /* try to prepare related clocks */ 418 i2s->hclk = devm_clk_get(&pdev->dev, "i2s_hclk"); 419 if (IS_ERR(i2s->hclk)) { 420 dev_err(&pdev->dev, "Can't retrieve i2s bus clock\n"); 421 return PTR_ERR(i2s->hclk); 422 } 423 424 i2s->mclk = devm_clk_get(&pdev->dev, "i2s_clk"); 425 if (IS_ERR(i2s->mclk)) { 426 dev_err(&pdev->dev, "Can't retrieve i2s master clock\n"); 427 return PTR_ERR(i2s->mclk); 428 } 429 430 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 431 regs = devm_ioremap_resource(&pdev->dev, res); 432 if (IS_ERR(regs)) 433 return PTR_ERR(regs); 434 435 i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs, 436 &rockchip_i2s_regmap_config); 437 if (IS_ERR(i2s->regmap)) { 438 dev_err(&pdev->dev, 439 "Failed to initialise managed register map\n"); 440 return PTR_ERR(i2s->regmap); 441 } 442 443 i2s->playback_dma_data.addr = res->start + I2S_TXDR; 444 i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 445 i2s->playback_dma_data.maxburst = 16; 446 447 i2s->capture_dma_data.addr = res->start + I2S_RXDR; 448 i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 449 i2s->capture_dma_data.maxburst = 16; 450 451 i2s->dev = &pdev->dev; 452 dev_set_drvdata(&pdev->dev, i2s); 453 454 pm_runtime_enable(&pdev->dev); 455 if (!pm_runtime_enabled(&pdev->dev)) { 456 ret = i2s_runtime_resume(&pdev->dev); 457 if (ret) 458 goto err_pm_disable; 459 } 460 461 ret = devm_snd_soc_register_component(&pdev->dev, 462 &rockchip_i2s_component, 463 &rockchip_i2s_dai, 1); 464 if (ret) { 465 dev_err(&pdev->dev, "Could not register DAI\n"); 466 goto err_suspend; 467 } 468 469 ret = snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); 470 if (ret) { 471 dev_err(&pdev->dev, "Could not register PCM\n"); 472 goto err_pcm_register; 473 } 474 475 return 0; 476 477 err_pcm_register: 478 snd_dmaengine_pcm_unregister(&pdev->dev); 479 err_suspend: 480 if (!pm_runtime_status_suspended(&pdev->dev)) 481 i2s_runtime_suspend(&pdev->dev); 482 err_pm_disable: 483 pm_runtime_disable(&pdev->dev); 484 485 return ret; 486 } 487 488 static int rockchip_i2s_remove(struct platform_device *pdev) 489 { 490 struct rk_i2s_dev *i2s = dev_get_drvdata(&pdev->dev); 491 492 pm_runtime_disable(&pdev->dev); 493 if (!pm_runtime_status_suspended(&pdev->dev)) 494 i2s_runtime_suspend(&pdev->dev); 495 496 clk_disable_unprepare(i2s->mclk); 497 clk_disable_unprepare(i2s->hclk); 498 snd_dmaengine_pcm_unregister(&pdev->dev); 499 snd_soc_unregister_component(&pdev->dev); 500 501 return 0; 502 } 503 504 static const struct of_device_id rockchip_i2s_match[] = { 505 { .compatible = "rockchip,rk3066-i2s", }, 506 {}, 507 }; 508 509 static const struct dev_pm_ops rockchip_i2s_pm_ops = { 510 SET_RUNTIME_PM_OPS(i2s_runtime_suspend, i2s_runtime_resume, 511 NULL) 512 }; 513 514 static struct platform_driver rockchip_i2s_driver = { 515 .probe = rockchip_i2s_probe, 516 .remove = rockchip_i2s_remove, 517 .driver = { 518 .name = DRV_NAME, 519 .owner = THIS_MODULE, 520 .of_match_table = of_match_ptr(rockchip_i2s_match), 521 .pm = &rockchip_i2s_pm_ops, 522 }, 523 }; 524 module_platform_driver(rockchip_i2s_driver); 525 526 MODULE_DESCRIPTION("ROCKCHIP IIS ASoC Interface"); 527 MODULE_AUTHOR("jianqun <jay.xu@rock-chips.com>"); 528 MODULE_LICENSE("GPL v2"); 529 MODULE_ALIAS("platform:" DRV_NAME); 530 MODULE_DEVICE_TABLE(of, rockchip_i2s_match); 531