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