1 // SPDX-License-Identifier: GPL-2.0-only 2 // ALSA SoC Audio Layer - Rockchip I2S/TDM Controller driver 3 4 // Copyright (c) 2018 Rockchip Electronics Co. Ltd. 5 // Author: Sugar Zhang <sugar.zhang@rock-chips.com> 6 // Author: Nicolas Frattaroli <frattaroli.nicolas@gmail.com> 7 8 #include <linux/clk.h> 9 #include <linux/clk-provider.h> 10 #include <linux/delay.h> 11 #include <linux/mfd/syscon.h> 12 #include <linux/module.h> 13 #include <linux/of_address.h> 14 #include <linux/of_device.h> 15 #include <linux/of_gpio.h> 16 #include <linux/pm_runtime.h> 17 #include <linux/regmap.h> 18 #include <linux/reset.h> 19 #include <linux/spinlock.h> 20 #include <sound/dmaengine_pcm.h> 21 #include <sound/pcm_params.h> 22 23 #include "rockchip_i2s_tdm.h" 24 25 #define DRV_NAME "rockchip-i2s-tdm" 26 27 #define DEFAULT_MCLK_FS 256 28 #define CH_GRP_MAX 4 /* The max channel 8 / 2 */ 29 #define MULTIPLEX_CH_MAX 10 30 #define CLK_PPM_MIN -1000 31 #define CLK_PPM_MAX 1000 32 33 #define TRCM_TXRX 0 34 #define TRCM_TX 1 35 #define TRCM_RX 2 36 37 struct txrx_config { 38 u32 addr; 39 u32 reg; 40 u32 txonly; 41 u32 rxonly; 42 }; 43 44 struct rk_i2s_soc_data { 45 u32 softrst_offset; 46 u32 grf_reg_offset; 47 u32 grf_shift; 48 int config_count; 49 const struct txrx_config *configs; 50 int (*init)(struct device *dev, u32 addr); 51 }; 52 53 struct rk_i2s_tdm_dev { 54 struct device *dev; 55 struct clk *hclk; 56 struct clk *mclk_tx; 57 struct clk *mclk_rx; 58 /* The mclk_tx_src is parent of mclk_tx */ 59 struct clk *mclk_tx_src; 60 /* The mclk_rx_src is parent of mclk_rx */ 61 struct clk *mclk_rx_src; 62 /* 63 * The mclk_root0 and mclk_root1 are root parent and supplies for 64 * the different FS. 65 * 66 * e.g: 67 * mclk_root0 is VPLL0, used for FS=48000Hz 68 * mclk_root1 is VPLL1, used for FS=44100Hz 69 */ 70 struct clk *mclk_root0; 71 struct clk *mclk_root1; 72 struct regmap *regmap; 73 struct regmap *grf; 74 struct snd_dmaengine_dai_dma_data capture_dma_data; 75 struct snd_dmaengine_dai_dma_data playback_dma_data; 76 struct reset_control *tx_reset; 77 struct reset_control *rx_reset; 78 struct rk_i2s_soc_data *soc_data; 79 bool is_master_mode; 80 bool io_multiplex; 81 bool mclk_calibrate; 82 bool tdm_mode; 83 unsigned int mclk_rx_freq; 84 unsigned int mclk_tx_freq; 85 unsigned int mclk_root0_freq; 86 unsigned int mclk_root1_freq; 87 unsigned int mclk_root0_initial_freq; 88 unsigned int mclk_root1_initial_freq; 89 unsigned int frame_width; 90 unsigned int clk_trcm; 91 unsigned int i2s_sdis[CH_GRP_MAX]; 92 unsigned int i2s_sdos[CH_GRP_MAX]; 93 int clk_ppm; 94 int refcount; 95 spinlock_t lock; /* xfer lock */ 96 bool has_playback; 97 bool has_capture; 98 }; 99 100 static int to_ch_num(unsigned int val) 101 { 102 switch (val) { 103 case I2S_CHN_4: 104 return 4; 105 case I2S_CHN_6: 106 return 6; 107 case I2S_CHN_8: 108 return 8; 109 default: 110 return 2; 111 } 112 } 113 114 static void i2s_tdm_disable_unprepare_mclk(struct rk_i2s_tdm_dev *i2s_tdm) 115 { 116 clk_disable_unprepare(i2s_tdm->mclk_tx); 117 clk_disable_unprepare(i2s_tdm->mclk_rx); 118 if (i2s_tdm->mclk_calibrate) { 119 clk_disable_unprepare(i2s_tdm->mclk_tx_src); 120 clk_disable_unprepare(i2s_tdm->mclk_rx_src); 121 clk_disable_unprepare(i2s_tdm->mclk_root0); 122 clk_disable_unprepare(i2s_tdm->mclk_root1); 123 } 124 } 125 126 /** 127 * i2s_tdm_prepare_enable_mclk - prepare to enable all mclks, disable them on 128 * failure. 129 * @i2s_tdm: rk_i2s_tdm_dev struct 130 * 131 * This function attempts to enable all mclk clocks, but cleans up after 132 * itself on failure. Guarantees to balance its calls. 133 * 134 * Returns success (0) or negative errno. 135 */ 136 static int i2s_tdm_prepare_enable_mclk(struct rk_i2s_tdm_dev *i2s_tdm) 137 { 138 int ret = 0; 139 140 ret = clk_prepare_enable(i2s_tdm->mclk_tx); 141 if (ret) 142 goto err_mclk_tx; 143 ret = clk_prepare_enable(i2s_tdm->mclk_rx); 144 if (ret) 145 goto err_mclk_rx; 146 if (i2s_tdm->mclk_calibrate) { 147 ret = clk_prepare_enable(i2s_tdm->mclk_tx_src); 148 if (ret) 149 goto err_mclk_rx; 150 ret = clk_prepare_enable(i2s_tdm->mclk_rx_src); 151 if (ret) 152 goto err_mclk_rx_src; 153 ret = clk_prepare_enable(i2s_tdm->mclk_root0); 154 if (ret) 155 goto err_mclk_root0; 156 ret = clk_prepare_enable(i2s_tdm->mclk_root1); 157 if (ret) 158 goto err_mclk_root1; 159 } 160 161 return 0; 162 163 err_mclk_root1: 164 clk_disable_unprepare(i2s_tdm->mclk_root0); 165 err_mclk_root0: 166 clk_disable_unprepare(i2s_tdm->mclk_rx_src); 167 err_mclk_rx_src: 168 clk_disable_unprepare(i2s_tdm->mclk_tx_src); 169 err_mclk_rx: 170 clk_disable_unprepare(i2s_tdm->mclk_tx); 171 err_mclk_tx: 172 return ret; 173 } 174 175 static int __maybe_unused i2s_tdm_runtime_suspend(struct device *dev) 176 { 177 struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev); 178 179 regcache_cache_only(i2s_tdm->regmap, true); 180 i2s_tdm_disable_unprepare_mclk(i2s_tdm); 181 182 clk_disable_unprepare(i2s_tdm->hclk); 183 184 return 0; 185 } 186 187 static int __maybe_unused i2s_tdm_runtime_resume(struct device *dev) 188 { 189 struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev); 190 int ret; 191 192 ret = clk_prepare_enable(i2s_tdm->hclk); 193 if (ret) 194 goto err_hclk; 195 196 ret = i2s_tdm_prepare_enable_mclk(i2s_tdm); 197 if (ret) 198 goto err_mclk; 199 200 regcache_cache_only(i2s_tdm->regmap, false); 201 regcache_mark_dirty(i2s_tdm->regmap); 202 203 ret = regcache_sync(i2s_tdm->regmap); 204 if (ret) 205 goto err_regcache; 206 207 return 0; 208 209 err_regcache: 210 i2s_tdm_disable_unprepare_mclk(i2s_tdm); 211 err_mclk: 212 clk_disable_unprepare(i2s_tdm->hclk); 213 err_hclk: 214 return ret; 215 } 216 217 static inline struct rk_i2s_tdm_dev *to_info(struct snd_soc_dai *dai) 218 { 219 return snd_soc_dai_get_drvdata(dai); 220 } 221 222 /* 223 * Makes sure that both tx and rx are reset at the same time to sync lrck 224 * when clk_trcm > 0. 225 */ 226 static void rockchip_snd_xfer_sync_reset(struct rk_i2s_tdm_dev *i2s_tdm) 227 { 228 /* This is technically race-y. 229 * 230 * In an ideal world, we could atomically assert both resets at the 231 * same time, through an atomic bulk reset API. This API however does 232 * not exist, so what the downstream vendor code used to do was 233 * implement half a reset controller here and require the CRU to be 234 * passed to the driver as a device tree node. Violating abstractions 235 * like that is bad, especially when it influences something like the 236 * bindings which are supposed to describe the hardware, not whatever 237 * workarounds the driver needs, so it was dropped. 238 * 239 * In practice, asserting the resets one by one appears to work just 240 * fine for playback. During duplex (playback + capture) operation, 241 * this might become an issue, but that should be solved by the 242 * implementation of the aforementioned API, not by shoving a reset 243 * controller into an audio driver. 244 */ 245 246 reset_control_assert(i2s_tdm->tx_reset); 247 reset_control_assert(i2s_tdm->rx_reset); 248 udelay(10); 249 reset_control_deassert(i2s_tdm->tx_reset); 250 reset_control_deassert(i2s_tdm->rx_reset); 251 udelay(10); 252 } 253 254 static void rockchip_snd_reset(struct reset_control *rc) 255 { 256 reset_control_assert(rc); 257 udelay(10); 258 reset_control_deassert(rc); 259 udelay(10); 260 } 261 262 static void rockchip_snd_xfer_clear(struct rk_i2s_tdm_dev *i2s_tdm, 263 unsigned int clr) 264 { 265 unsigned int xfer_mask = 0; 266 unsigned int xfer_val = 0; 267 unsigned int val; 268 int retry = 10; 269 bool tx = clr & I2S_CLR_TXC; 270 bool rx = clr & I2S_CLR_RXC; 271 272 if (!(rx || tx)) 273 return; 274 275 if (tx) { 276 xfer_mask = I2S_XFER_TXS_START; 277 xfer_val = I2S_XFER_TXS_STOP; 278 } 279 if (rx) { 280 xfer_mask |= I2S_XFER_RXS_START; 281 xfer_val |= I2S_XFER_RXS_STOP; 282 } 283 284 regmap_update_bits(i2s_tdm->regmap, I2S_XFER, xfer_mask, xfer_val); 285 udelay(150); 286 regmap_update_bits(i2s_tdm->regmap, I2S_CLR, clr, clr); 287 288 regmap_read(i2s_tdm->regmap, I2S_CLR, &val); 289 /* Wait on the clear operation to finish */ 290 while (val) { 291 udelay(15); 292 regmap_read(i2s_tdm->regmap, I2S_CLR, &val); 293 retry--; 294 if (!retry) { 295 dev_warn(i2s_tdm->dev, "clear failed, reset %s%s\n", 296 tx ? "tx" : "", rx ? "rx" : ""); 297 if (rx && tx) 298 rockchip_snd_xfer_sync_reset(i2s_tdm); 299 else if (tx) 300 rockchip_snd_reset(i2s_tdm->tx_reset); 301 else if (rx) 302 rockchip_snd_reset(i2s_tdm->rx_reset); 303 break; 304 } 305 } 306 } 307 308 static inline void rockchip_enable_tde(struct regmap *regmap) 309 { 310 regmap_update_bits(regmap, I2S_DMACR, I2S_DMACR_TDE_ENABLE, 311 I2S_DMACR_TDE_ENABLE); 312 } 313 314 static inline void rockchip_disable_tde(struct regmap *regmap) 315 { 316 regmap_update_bits(regmap, I2S_DMACR, I2S_DMACR_TDE_ENABLE, 317 I2S_DMACR_TDE_DISABLE); 318 } 319 320 static inline void rockchip_enable_rde(struct regmap *regmap) 321 { 322 regmap_update_bits(regmap, I2S_DMACR, I2S_DMACR_RDE_ENABLE, 323 I2S_DMACR_RDE_ENABLE); 324 } 325 326 static inline void rockchip_disable_rde(struct regmap *regmap) 327 { 328 regmap_update_bits(regmap, I2S_DMACR, I2S_DMACR_RDE_ENABLE, 329 I2S_DMACR_RDE_DISABLE); 330 } 331 332 /* only used when clk_trcm > 0 */ 333 static void rockchip_snd_txrxctrl(struct snd_pcm_substream *substream, 334 struct snd_soc_dai *dai, int on) 335 { 336 struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai); 337 unsigned long flags; 338 339 spin_lock_irqsave(&i2s_tdm->lock, flags); 340 if (on) { 341 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 342 rockchip_enable_tde(i2s_tdm->regmap); 343 else 344 rockchip_enable_rde(i2s_tdm->regmap); 345 346 if (++i2s_tdm->refcount == 1) { 347 rockchip_snd_xfer_sync_reset(i2s_tdm); 348 regmap_update_bits(i2s_tdm->regmap, I2S_XFER, 349 I2S_XFER_TXS_START | 350 I2S_XFER_RXS_START, 351 I2S_XFER_TXS_START | 352 I2S_XFER_RXS_START); 353 } 354 } else { 355 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 356 rockchip_disable_tde(i2s_tdm->regmap); 357 else 358 rockchip_disable_rde(i2s_tdm->regmap); 359 360 if (--i2s_tdm->refcount == 0) { 361 rockchip_snd_xfer_clear(i2s_tdm, 362 I2S_CLR_TXC | I2S_CLR_RXC); 363 } 364 } 365 spin_unlock_irqrestore(&i2s_tdm->lock, flags); 366 } 367 368 static void rockchip_snd_txctrl(struct rk_i2s_tdm_dev *i2s_tdm, int on) 369 { 370 if (on) { 371 rockchip_enable_tde(i2s_tdm->regmap); 372 373 regmap_update_bits(i2s_tdm->regmap, I2S_XFER, 374 I2S_XFER_TXS_START, 375 I2S_XFER_TXS_START); 376 } else { 377 rockchip_disable_tde(i2s_tdm->regmap); 378 379 rockchip_snd_xfer_clear(i2s_tdm, I2S_CLR_TXC); 380 } 381 } 382 383 static void rockchip_snd_rxctrl(struct rk_i2s_tdm_dev *i2s_tdm, int on) 384 { 385 if (on) { 386 rockchip_enable_rde(i2s_tdm->regmap); 387 388 regmap_update_bits(i2s_tdm->regmap, I2S_XFER, 389 I2S_XFER_RXS_START, 390 I2S_XFER_RXS_START); 391 } else { 392 rockchip_disable_rde(i2s_tdm->regmap); 393 394 rockchip_snd_xfer_clear(i2s_tdm, I2S_CLR_RXC); 395 } 396 } 397 398 static int rockchip_i2s_tdm_set_fmt(struct snd_soc_dai *cpu_dai, 399 unsigned int fmt) 400 { 401 struct rk_i2s_tdm_dev *i2s_tdm = to_info(cpu_dai); 402 unsigned int mask, val, tdm_val, txcr_val, rxcr_val; 403 int ret; 404 bool is_tdm = i2s_tdm->tdm_mode; 405 406 ret = pm_runtime_get_sync(cpu_dai->dev); 407 if (ret < 0 && ret != -EACCES) { 408 pm_runtime_put_noidle(cpu_dai->dev); 409 return ret; 410 } 411 412 mask = I2S_CKR_MSS_MASK; 413 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 414 case SND_SOC_DAIFMT_CBC_CFC: 415 val = I2S_CKR_MSS_MASTER; 416 i2s_tdm->is_master_mode = true; 417 break; 418 case SND_SOC_DAIFMT_CBP_CFP: 419 val = I2S_CKR_MSS_SLAVE; 420 i2s_tdm->is_master_mode = false; 421 break; 422 default: 423 ret = -EINVAL; 424 goto err_pm_put; 425 } 426 427 regmap_update_bits(i2s_tdm->regmap, I2S_CKR, mask, val); 428 429 mask = I2S_CKR_CKP_MASK | I2S_CKR_TLP_MASK | I2S_CKR_RLP_MASK; 430 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 431 case SND_SOC_DAIFMT_NB_NF: 432 val = I2S_CKR_CKP_NORMAL | 433 I2S_CKR_TLP_NORMAL | 434 I2S_CKR_RLP_NORMAL; 435 break; 436 case SND_SOC_DAIFMT_NB_IF: 437 val = I2S_CKR_CKP_NORMAL | 438 I2S_CKR_TLP_INVERTED | 439 I2S_CKR_RLP_INVERTED; 440 break; 441 case SND_SOC_DAIFMT_IB_NF: 442 val = I2S_CKR_CKP_INVERTED | 443 I2S_CKR_TLP_NORMAL | 444 I2S_CKR_RLP_NORMAL; 445 break; 446 case SND_SOC_DAIFMT_IB_IF: 447 val = I2S_CKR_CKP_INVERTED | 448 I2S_CKR_TLP_INVERTED | 449 I2S_CKR_RLP_INVERTED; 450 break; 451 default: 452 ret = -EINVAL; 453 goto err_pm_put; 454 } 455 456 regmap_update_bits(i2s_tdm->regmap, I2S_CKR, mask, val); 457 458 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 459 case SND_SOC_DAIFMT_RIGHT_J: 460 txcr_val = I2S_TXCR_IBM_RSJM; 461 rxcr_val = I2S_RXCR_IBM_RSJM; 462 break; 463 case SND_SOC_DAIFMT_LEFT_J: 464 txcr_val = I2S_TXCR_IBM_LSJM; 465 rxcr_val = I2S_RXCR_IBM_LSJM; 466 break; 467 case SND_SOC_DAIFMT_I2S: 468 txcr_val = I2S_TXCR_IBM_NORMAL; 469 rxcr_val = I2S_RXCR_IBM_NORMAL; 470 break; 471 case SND_SOC_DAIFMT_DSP_A: /* PCM no delay mode */ 472 txcr_val = I2S_TXCR_TFS_PCM; 473 rxcr_val = I2S_RXCR_TFS_PCM; 474 break; 475 case SND_SOC_DAIFMT_DSP_B: /* PCM delay 1 mode */ 476 txcr_val = I2S_TXCR_TFS_PCM | I2S_TXCR_PBM_MODE(1); 477 rxcr_val = I2S_RXCR_TFS_PCM | I2S_RXCR_PBM_MODE(1); 478 break; 479 default: 480 ret = -EINVAL; 481 goto err_pm_put; 482 } 483 484 mask = I2S_TXCR_IBM_MASK | I2S_TXCR_TFS_MASK | I2S_TXCR_PBM_MASK; 485 regmap_update_bits(i2s_tdm->regmap, I2S_TXCR, mask, txcr_val); 486 487 mask = I2S_RXCR_IBM_MASK | I2S_RXCR_TFS_MASK | I2S_RXCR_PBM_MASK; 488 regmap_update_bits(i2s_tdm->regmap, I2S_RXCR, mask, rxcr_val); 489 490 if (is_tdm) { 491 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 492 case SND_SOC_DAIFMT_RIGHT_J: 493 val = I2S_TXCR_TFS_TDM_I2S; 494 tdm_val = TDM_SHIFT_CTRL(2); 495 break; 496 case SND_SOC_DAIFMT_LEFT_J: 497 val = I2S_TXCR_TFS_TDM_I2S; 498 tdm_val = TDM_SHIFT_CTRL(1); 499 break; 500 case SND_SOC_DAIFMT_I2S: 501 val = I2S_TXCR_TFS_TDM_I2S; 502 tdm_val = TDM_SHIFT_CTRL(0); 503 break; 504 case SND_SOC_DAIFMT_DSP_A: 505 val = I2S_TXCR_TFS_TDM_PCM; 506 tdm_val = TDM_SHIFT_CTRL(0); 507 break; 508 case SND_SOC_DAIFMT_DSP_B: 509 val = I2S_TXCR_TFS_TDM_PCM; 510 tdm_val = TDM_SHIFT_CTRL(2); 511 break; 512 default: 513 ret = -EINVAL; 514 goto err_pm_put; 515 } 516 517 tdm_val |= TDM_FSYNC_WIDTH_SEL1(1); 518 tdm_val |= TDM_FSYNC_WIDTH_HALF_FRAME; 519 520 mask = I2S_TXCR_TFS_MASK; 521 regmap_update_bits(i2s_tdm->regmap, I2S_TXCR, mask, val); 522 regmap_update_bits(i2s_tdm->regmap, I2S_RXCR, mask, val); 523 524 mask = TDM_FSYNC_WIDTH_SEL1_MSK | TDM_FSYNC_WIDTH_SEL0_MSK | 525 TDM_SHIFT_CTRL_MSK; 526 regmap_update_bits(i2s_tdm->regmap, I2S_TDM_TXCR, 527 mask, tdm_val); 528 regmap_update_bits(i2s_tdm->regmap, I2S_TDM_RXCR, 529 mask, tdm_val); 530 } 531 532 err_pm_put: 533 pm_runtime_put(cpu_dai->dev); 534 535 return ret; 536 } 537 538 static void rockchip_i2s_tdm_xfer_pause(struct snd_pcm_substream *substream, 539 struct rk_i2s_tdm_dev *i2s_tdm) 540 { 541 int stream; 542 543 stream = SNDRV_PCM_STREAM_LAST - substream->stream; 544 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 545 rockchip_disable_tde(i2s_tdm->regmap); 546 else 547 rockchip_disable_rde(i2s_tdm->regmap); 548 549 rockchip_snd_xfer_clear(i2s_tdm, I2S_CLR_TXC | I2S_CLR_RXC); 550 } 551 552 static void rockchip_i2s_tdm_xfer_resume(struct snd_pcm_substream *substream, 553 struct rk_i2s_tdm_dev *i2s_tdm) 554 { 555 int stream; 556 557 stream = SNDRV_PCM_STREAM_LAST - substream->stream; 558 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 559 rockchip_enable_tde(i2s_tdm->regmap); 560 else 561 rockchip_enable_rde(i2s_tdm->regmap); 562 563 regmap_update_bits(i2s_tdm->regmap, I2S_XFER, 564 I2S_XFER_TXS_START | 565 I2S_XFER_RXS_START, 566 I2S_XFER_TXS_START | 567 I2S_XFER_RXS_START); 568 } 569 570 static int rockchip_i2s_tdm_clk_set_rate(struct rk_i2s_tdm_dev *i2s_tdm, 571 struct clk *clk, unsigned long rate, 572 int ppm) 573 { 574 unsigned long rate_target; 575 int delta, ret; 576 577 if (ppm == i2s_tdm->clk_ppm) 578 return 0; 579 580 if (ppm < 0) 581 delta = -1; 582 else 583 delta = 1; 584 585 delta *= (int)div64_u64((u64)rate * (u64)abs(ppm) + 500000, 586 1000000); 587 588 rate_target = rate + delta; 589 590 if (!rate_target) 591 return -EINVAL; 592 593 ret = clk_set_rate(clk, rate_target); 594 if (ret) 595 return ret; 596 597 i2s_tdm->clk_ppm = ppm; 598 599 return 0; 600 } 601 602 static int rockchip_i2s_tdm_calibrate_mclk(struct rk_i2s_tdm_dev *i2s_tdm, 603 struct snd_pcm_substream *substream, 604 unsigned int lrck_freq) 605 { 606 struct clk *mclk_root; 607 struct clk *mclk_parent; 608 unsigned int mclk_root_freq; 609 unsigned int mclk_root_initial_freq; 610 unsigned int mclk_parent_freq; 611 unsigned int div, delta; 612 u64 ppm; 613 int ret; 614 615 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 616 mclk_parent = i2s_tdm->mclk_tx_src; 617 else 618 mclk_parent = i2s_tdm->mclk_rx_src; 619 620 switch (lrck_freq) { 621 case 8000: 622 case 16000: 623 case 24000: 624 case 32000: 625 case 48000: 626 case 64000: 627 case 96000: 628 case 192000: 629 mclk_root = i2s_tdm->mclk_root0; 630 mclk_root_freq = i2s_tdm->mclk_root0_freq; 631 mclk_root_initial_freq = i2s_tdm->mclk_root0_initial_freq; 632 mclk_parent_freq = DEFAULT_MCLK_FS * 192000; 633 break; 634 case 11025: 635 case 22050: 636 case 44100: 637 case 88200: 638 case 176400: 639 mclk_root = i2s_tdm->mclk_root1; 640 mclk_root_freq = i2s_tdm->mclk_root1_freq; 641 mclk_root_initial_freq = i2s_tdm->mclk_root1_initial_freq; 642 mclk_parent_freq = DEFAULT_MCLK_FS * 176400; 643 break; 644 default: 645 dev_err(i2s_tdm->dev, "Invalid LRCK frequency: %u Hz\n", 646 lrck_freq); 647 return -EINVAL; 648 } 649 650 ret = clk_set_parent(mclk_parent, mclk_root); 651 if (ret) 652 return ret; 653 654 ret = rockchip_i2s_tdm_clk_set_rate(i2s_tdm, mclk_root, 655 mclk_root_freq, 0); 656 if (ret) 657 return ret; 658 659 delta = abs(mclk_root_freq % mclk_parent_freq - mclk_parent_freq); 660 ppm = div64_u64((uint64_t)delta * 1000000, (uint64_t)mclk_root_freq); 661 662 if (ppm) { 663 div = DIV_ROUND_CLOSEST(mclk_root_initial_freq, mclk_parent_freq); 664 if (!div) 665 return -EINVAL; 666 667 mclk_root_freq = mclk_parent_freq * round_up(div, 2); 668 669 ret = clk_set_rate(mclk_root, mclk_root_freq); 670 if (ret) 671 return ret; 672 673 i2s_tdm->mclk_root0_freq = clk_get_rate(i2s_tdm->mclk_root0); 674 i2s_tdm->mclk_root1_freq = clk_get_rate(i2s_tdm->mclk_root1); 675 } 676 677 return clk_set_rate(mclk_parent, mclk_parent_freq); 678 } 679 680 static int rockchip_i2s_tdm_set_mclk(struct rk_i2s_tdm_dev *i2s_tdm, 681 struct snd_pcm_substream *substream, 682 struct clk **mclk) 683 { 684 unsigned int mclk_freq; 685 int ret; 686 687 if (i2s_tdm->clk_trcm) { 688 if (i2s_tdm->mclk_tx_freq != i2s_tdm->mclk_rx_freq) { 689 dev_err(i2s_tdm->dev, 690 "clk_trcm, tx: %d and rx: %d should be the same\n", 691 i2s_tdm->mclk_tx_freq, 692 i2s_tdm->mclk_rx_freq); 693 return -EINVAL; 694 } 695 696 ret = clk_set_rate(i2s_tdm->mclk_tx, i2s_tdm->mclk_tx_freq); 697 if (ret) 698 return ret; 699 700 ret = clk_set_rate(i2s_tdm->mclk_rx, i2s_tdm->mclk_rx_freq); 701 if (ret) 702 return ret; 703 704 /* mclk_rx is also ok. */ 705 *mclk = i2s_tdm->mclk_tx; 706 } else { 707 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 708 *mclk = i2s_tdm->mclk_tx; 709 mclk_freq = i2s_tdm->mclk_tx_freq; 710 } else { 711 *mclk = i2s_tdm->mclk_rx; 712 mclk_freq = i2s_tdm->mclk_rx_freq; 713 } 714 715 ret = clk_set_rate(*mclk, mclk_freq); 716 if (ret) 717 return ret; 718 } 719 720 return 0; 721 } 722 723 static int rockchip_i2s_ch_to_io(unsigned int ch, bool substream_capture) 724 { 725 if (substream_capture) { 726 switch (ch) { 727 case I2S_CHN_4: 728 return I2S_IO_6CH_OUT_4CH_IN; 729 case I2S_CHN_6: 730 return I2S_IO_4CH_OUT_6CH_IN; 731 case I2S_CHN_8: 732 return I2S_IO_2CH_OUT_8CH_IN; 733 default: 734 return I2S_IO_8CH_OUT_2CH_IN; 735 } 736 } else { 737 switch (ch) { 738 case I2S_CHN_4: 739 return I2S_IO_4CH_OUT_6CH_IN; 740 case I2S_CHN_6: 741 return I2S_IO_6CH_OUT_4CH_IN; 742 case I2S_CHN_8: 743 return I2S_IO_8CH_OUT_2CH_IN; 744 default: 745 return I2S_IO_2CH_OUT_8CH_IN; 746 } 747 } 748 } 749 750 static int rockchip_i2s_io_multiplex(struct snd_pcm_substream *substream, 751 struct snd_soc_dai *dai) 752 { 753 struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai); 754 int usable_chs = MULTIPLEX_CH_MAX; 755 unsigned int val = 0; 756 757 if (!i2s_tdm->io_multiplex) 758 return 0; 759 760 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 761 struct snd_pcm_str *playback_str = 762 &substream->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK]; 763 764 if (playback_str->substream_opened) { 765 regmap_read(i2s_tdm->regmap, I2S_TXCR, &val); 766 val &= I2S_TXCR_CSR_MASK; 767 usable_chs = MULTIPLEX_CH_MAX - to_ch_num(val); 768 } 769 770 regmap_read(i2s_tdm->regmap, I2S_RXCR, &val); 771 val &= I2S_RXCR_CSR_MASK; 772 773 if (to_ch_num(val) > usable_chs) { 774 dev_err(i2s_tdm->dev, 775 "Capture channels (%d) > usable channels (%d)\n", 776 to_ch_num(val), usable_chs); 777 return -EINVAL; 778 } 779 780 rockchip_i2s_ch_to_io(val, true); 781 } else { 782 struct snd_pcm_str *capture_str = 783 &substream->pcm->streams[SNDRV_PCM_STREAM_CAPTURE]; 784 785 if (capture_str->substream_opened) { 786 regmap_read(i2s_tdm->regmap, I2S_RXCR, &val); 787 val &= I2S_RXCR_CSR_MASK; 788 usable_chs = MULTIPLEX_CH_MAX - to_ch_num(val); 789 } 790 791 regmap_read(i2s_tdm->regmap, I2S_TXCR, &val); 792 val &= I2S_TXCR_CSR_MASK; 793 794 if (to_ch_num(val) > usable_chs) { 795 dev_err(i2s_tdm->dev, 796 "Playback channels (%d) > usable channels (%d)\n", 797 to_ch_num(val), usable_chs); 798 return -EINVAL; 799 } 800 } 801 802 val <<= i2s_tdm->soc_data->grf_shift; 803 val |= (I2S_IO_DIRECTION_MASK << i2s_tdm->soc_data->grf_shift) << 16; 804 regmap_write(i2s_tdm->grf, i2s_tdm->soc_data->grf_reg_offset, val); 805 806 return 0; 807 } 808 809 static int rockchip_i2s_trcm_mode(struct snd_pcm_substream *substream, 810 struct snd_soc_dai *dai, 811 unsigned int div_bclk, 812 unsigned int div_lrck, 813 unsigned int fmt) 814 { 815 struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai); 816 unsigned long flags; 817 818 if (!i2s_tdm->clk_trcm) 819 return 0; 820 821 spin_lock_irqsave(&i2s_tdm->lock, flags); 822 if (i2s_tdm->refcount) 823 rockchip_i2s_tdm_xfer_pause(substream, i2s_tdm); 824 825 regmap_update_bits(i2s_tdm->regmap, I2S_CLKDIV, 826 I2S_CLKDIV_TXM_MASK | I2S_CLKDIV_RXM_MASK, 827 I2S_CLKDIV_TXM(div_bclk) | I2S_CLKDIV_RXM(div_bclk)); 828 regmap_update_bits(i2s_tdm->regmap, I2S_CKR, 829 I2S_CKR_TSD_MASK | I2S_CKR_RSD_MASK, 830 I2S_CKR_TSD(div_lrck) | I2S_CKR_RSD(div_lrck)); 831 832 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 833 regmap_update_bits(i2s_tdm->regmap, I2S_TXCR, 834 I2S_TXCR_VDW_MASK | I2S_TXCR_CSR_MASK, 835 fmt); 836 else 837 regmap_update_bits(i2s_tdm->regmap, I2S_RXCR, 838 I2S_RXCR_VDW_MASK | I2S_RXCR_CSR_MASK, 839 fmt); 840 841 if (i2s_tdm->refcount) 842 rockchip_i2s_tdm_xfer_resume(substream, i2s_tdm); 843 spin_unlock_irqrestore(&i2s_tdm->lock, flags); 844 845 return 0; 846 } 847 848 static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream, 849 struct snd_pcm_hw_params *params, 850 struct snd_soc_dai *dai) 851 { 852 struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai); 853 struct clk *mclk; 854 int ret = 0; 855 unsigned int val = 0; 856 unsigned int mclk_rate, bclk_rate, div_bclk = 4, div_lrck = 64; 857 858 if (i2s_tdm->is_master_mode) { 859 if (i2s_tdm->mclk_calibrate) 860 rockchip_i2s_tdm_calibrate_mclk(i2s_tdm, substream, 861 params_rate(params)); 862 863 ret = rockchip_i2s_tdm_set_mclk(i2s_tdm, substream, &mclk); 864 if (ret) 865 return ret; 866 867 mclk_rate = clk_get_rate(mclk); 868 bclk_rate = i2s_tdm->frame_width * params_rate(params); 869 if (!bclk_rate) 870 return -EINVAL; 871 872 div_bclk = DIV_ROUND_CLOSEST(mclk_rate, bclk_rate); 873 div_lrck = bclk_rate / params_rate(params); 874 } 875 876 switch (params_format(params)) { 877 case SNDRV_PCM_FORMAT_S8: 878 val |= I2S_TXCR_VDW(8); 879 break; 880 case SNDRV_PCM_FORMAT_S16_LE: 881 val |= I2S_TXCR_VDW(16); 882 break; 883 case SNDRV_PCM_FORMAT_S20_3LE: 884 val |= I2S_TXCR_VDW(20); 885 break; 886 case SNDRV_PCM_FORMAT_S24_LE: 887 val |= I2S_TXCR_VDW(24); 888 break; 889 case SNDRV_PCM_FORMAT_S32_LE: 890 val |= I2S_TXCR_VDW(32); 891 break; 892 default: 893 return -EINVAL; 894 } 895 896 switch (params_channels(params)) { 897 case 8: 898 val |= I2S_CHN_8; 899 break; 900 case 6: 901 val |= I2S_CHN_6; 902 break; 903 case 4: 904 val |= I2S_CHN_4; 905 break; 906 case 2: 907 val |= I2S_CHN_2; 908 break; 909 default: 910 return -EINVAL; 911 } 912 913 if (i2s_tdm->clk_trcm) { 914 rockchip_i2s_trcm_mode(substream, dai, div_bclk, div_lrck, val); 915 } else if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 916 regmap_update_bits(i2s_tdm->regmap, I2S_CLKDIV, 917 I2S_CLKDIV_TXM_MASK, 918 I2S_CLKDIV_TXM(div_bclk)); 919 regmap_update_bits(i2s_tdm->regmap, I2S_CKR, 920 I2S_CKR_TSD_MASK, 921 I2S_CKR_TSD(div_lrck)); 922 regmap_update_bits(i2s_tdm->regmap, I2S_TXCR, 923 I2S_TXCR_VDW_MASK | I2S_TXCR_CSR_MASK, 924 val); 925 } else { 926 regmap_update_bits(i2s_tdm->regmap, I2S_CLKDIV, 927 I2S_CLKDIV_RXM_MASK, 928 I2S_CLKDIV_RXM(div_bclk)); 929 regmap_update_bits(i2s_tdm->regmap, I2S_CKR, 930 I2S_CKR_RSD_MASK, 931 I2S_CKR_RSD(div_lrck)); 932 regmap_update_bits(i2s_tdm->regmap, I2S_RXCR, 933 I2S_RXCR_VDW_MASK | I2S_RXCR_CSR_MASK, 934 val); 935 } 936 937 return rockchip_i2s_io_multiplex(substream, dai); 938 } 939 940 static int rockchip_i2s_tdm_trigger(struct snd_pcm_substream *substream, 941 int cmd, struct snd_soc_dai *dai) 942 { 943 struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai); 944 945 switch (cmd) { 946 case SNDRV_PCM_TRIGGER_START: 947 case SNDRV_PCM_TRIGGER_RESUME: 948 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 949 if (i2s_tdm->clk_trcm) 950 rockchip_snd_txrxctrl(substream, dai, 1); 951 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 952 rockchip_snd_rxctrl(i2s_tdm, 1); 953 else 954 rockchip_snd_txctrl(i2s_tdm, 1); 955 break; 956 case SNDRV_PCM_TRIGGER_SUSPEND: 957 case SNDRV_PCM_TRIGGER_STOP: 958 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 959 if (i2s_tdm->clk_trcm) 960 rockchip_snd_txrxctrl(substream, dai, 0); 961 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 962 rockchip_snd_rxctrl(i2s_tdm, 0); 963 else 964 rockchip_snd_txctrl(i2s_tdm, 0); 965 break; 966 default: 967 return -EINVAL; 968 } 969 970 return 0; 971 } 972 973 static int rockchip_i2s_tdm_set_sysclk(struct snd_soc_dai *cpu_dai, int stream, 974 unsigned int freq, int dir) 975 { 976 struct rk_i2s_tdm_dev *i2s_tdm = to_info(cpu_dai); 977 978 /* Put set mclk rate into rockchip_i2s_tdm_set_mclk() */ 979 if (i2s_tdm->clk_trcm) { 980 i2s_tdm->mclk_tx_freq = freq; 981 i2s_tdm->mclk_rx_freq = freq; 982 } else { 983 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 984 i2s_tdm->mclk_tx_freq = freq; 985 else 986 i2s_tdm->mclk_rx_freq = freq; 987 } 988 989 dev_dbg(i2s_tdm->dev, "The target mclk_%s freq is: %d\n", 990 stream ? "rx" : "tx", freq); 991 992 return 0; 993 } 994 995 static int rockchip_i2s_tdm_clk_compensation_info(struct snd_kcontrol *kcontrol, 996 struct snd_ctl_elem_info *uinfo) 997 { 998 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 999 uinfo->count = 1; 1000 uinfo->value.integer.min = CLK_PPM_MIN; 1001 uinfo->value.integer.max = CLK_PPM_MAX; 1002 uinfo->value.integer.step = 1; 1003 1004 return 0; 1005 } 1006 1007 static int rockchip_i2s_tdm_clk_compensation_get(struct snd_kcontrol *kcontrol, 1008 struct snd_ctl_elem_value *ucontrol) 1009 { 1010 struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol); 1011 struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai); 1012 1013 ucontrol->value.integer.value[0] = i2s_tdm->clk_ppm; 1014 1015 return 0; 1016 } 1017 1018 static int rockchip_i2s_tdm_clk_compensation_put(struct snd_kcontrol *kcontrol, 1019 struct snd_ctl_elem_value *ucontrol) 1020 { 1021 struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol); 1022 struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai); 1023 int ret = 0, ppm = 0; 1024 int changed = 0; 1025 unsigned long old_rate; 1026 1027 if (ucontrol->value.integer.value[0] < CLK_PPM_MIN || 1028 ucontrol->value.integer.value[0] > CLK_PPM_MAX) 1029 return -EINVAL; 1030 1031 ppm = ucontrol->value.integer.value[0]; 1032 1033 old_rate = clk_get_rate(i2s_tdm->mclk_root0); 1034 ret = rockchip_i2s_tdm_clk_set_rate(i2s_tdm, i2s_tdm->mclk_root0, 1035 i2s_tdm->mclk_root0_freq, ppm); 1036 if (ret) 1037 return ret; 1038 if (old_rate != clk_get_rate(i2s_tdm->mclk_root0)) 1039 changed = 1; 1040 1041 if (clk_is_match(i2s_tdm->mclk_root0, i2s_tdm->mclk_root1)) 1042 return changed; 1043 1044 old_rate = clk_get_rate(i2s_tdm->mclk_root1); 1045 ret = rockchip_i2s_tdm_clk_set_rate(i2s_tdm, i2s_tdm->mclk_root1, 1046 i2s_tdm->mclk_root1_freq, ppm); 1047 if (ret) 1048 return ret; 1049 if (old_rate != clk_get_rate(i2s_tdm->mclk_root1)) 1050 changed = 1; 1051 1052 return changed; 1053 } 1054 1055 static struct snd_kcontrol_new rockchip_i2s_tdm_compensation_control = { 1056 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1057 .name = "PCM Clock Compensation in PPM", 1058 .info = rockchip_i2s_tdm_clk_compensation_info, 1059 .get = rockchip_i2s_tdm_clk_compensation_get, 1060 .put = rockchip_i2s_tdm_clk_compensation_put, 1061 }; 1062 1063 static int rockchip_i2s_tdm_dai_probe(struct snd_soc_dai *dai) 1064 { 1065 struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai); 1066 1067 if (i2s_tdm->has_capture) 1068 dai->capture_dma_data = &i2s_tdm->capture_dma_data; 1069 if (i2s_tdm->has_playback) 1070 dai->playback_dma_data = &i2s_tdm->playback_dma_data; 1071 1072 if (i2s_tdm->mclk_calibrate) 1073 snd_soc_add_dai_controls(dai, &rockchip_i2s_tdm_compensation_control, 1); 1074 1075 return 0; 1076 } 1077 1078 static int rockchip_dai_tdm_slot(struct snd_soc_dai *dai, 1079 unsigned int tx_mask, unsigned int rx_mask, 1080 int slots, int slot_width) 1081 { 1082 struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai); 1083 unsigned int mask, val; 1084 1085 i2s_tdm->tdm_mode = true; 1086 i2s_tdm->frame_width = slots * slot_width; 1087 mask = TDM_SLOT_BIT_WIDTH_MSK | TDM_FRAME_WIDTH_MSK; 1088 val = TDM_SLOT_BIT_WIDTH(slot_width) | 1089 TDM_FRAME_WIDTH(slots * slot_width); 1090 regmap_update_bits(i2s_tdm->regmap, I2S_TDM_TXCR, 1091 mask, val); 1092 regmap_update_bits(i2s_tdm->regmap, I2S_TDM_RXCR, 1093 mask, val); 1094 1095 return 0; 1096 } 1097 1098 static int rockchip_i2s_tdm_set_bclk_ratio(struct snd_soc_dai *dai, 1099 unsigned int ratio) 1100 { 1101 struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai); 1102 1103 if (ratio < 32 || ratio > 512 || ratio % 2 == 1) 1104 return -EINVAL; 1105 1106 i2s_tdm->frame_width = ratio; 1107 1108 return 0; 1109 } 1110 1111 static const struct snd_soc_dai_ops rockchip_i2s_tdm_dai_ops = { 1112 .hw_params = rockchip_i2s_tdm_hw_params, 1113 .set_bclk_ratio = rockchip_i2s_tdm_set_bclk_ratio, 1114 .set_sysclk = rockchip_i2s_tdm_set_sysclk, 1115 .set_fmt = rockchip_i2s_tdm_set_fmt, 1116 .set_tdm_slot = rockchip_dai_tdm_slot, 1117 .trigger = rockchip_i2s_tdm_trigger, 1118 }; 1119 1120 static const struct snd_soc_component_driver rockchip_i2s_tdm_component = { 1121 .name = DRV_NAME, 1122 }; 1123 1124 static bool rockchip_i2s_tdm_wr_reg(struct device *dev, unsigned int reg) 1125 { 1126 switch (reg) { 1127 case I2S_TXCR: 1128 case I2S_RXCR: 1129 case I2S_CKR: 1130 case I2S_DMACR: 1131 case I2S_INTCR: 1132 case I2S_XFER: 1133 case I2S_CLR: 1134 case I2S_TXDR: 1135 case I2S_TDM_TXCR: 1136 case I2S_TDM_RXCR: 1137 case I2S_CLKDIV: 1138 return true; 1139 default: 1140 return false; 1141 } 1142 } 1143 1144 static bool rockchip_i2s_tdm_rd_reg(struct device *dev, unsigned int reg) 1145 { 1146 switch (reg) { 1147 case I2S_TXCR: 1148 case I2S_RXCR: 1149 case I2S_CKR: 1150 case I2S_DMACR: 1151 case I2S_INTCR: 1152 case I2S_XFER: 1153 case I2S_CLR: 1154 case I2S_TXDR: 1155 case I2S_RXDR: 1156 case I2S_TXFIFOLR: 1157 case I2S_INTSR: 1158 case I2S_RXFIFOLR: 1159 case I2S_TDM_TXCR: 1160 case I2S_TDM_RXCR: 1161 case I2S_CLKDIV: 1162 return true; 1163 default: 1164 return false; 1165 } 1166 } 1167 1168 static bool rockchip_i2s_tdm_volatile_reg(struct device *dev, unsigned int reg) 1169 { 1170 switch (reg) { 1171 case I2S_TXFIFOLR: 1172 case I2S_INTSR: 1173 case I2S_CLR: 1174 case I2S_TXDR: 1175 case I2S_RXDR: 1176 case I2S_RXFIFOLR: 1177 return true; 1178 default: 1179 return false; 1180 } 1181 } 1182 1183 static bool rockchip_i2s_tdm_precious_reg(struct device *dev, unsigned int reg) 1184 { 1185 if (reg == I2S_RXDR) 1186 return true; 1187 return false; 1188 } 1189 1190 static const struct reg_default rockchip_i2s_tdm_reg_defaults[] = { 1191 {0x00, 0x7200000f}, 1192 {0x04, 0x01c8000f}, 1193 {0x08, 0x00001f1f}, 1194 {0x10, 0x001f0000}, 1195 {0x14, 0x01f00000}, 1196 {0x30, 0x00003eff}, 1197 {0x34, 0x00003eff}, 1198 {0x38, 0x00000707}, 1199 }; 1200 1201 static const struct regmap_config rockchip_i2s_tdm_regmap_config = { 1202 .reg_bits = 32, 1203 .reg_stride = 4, 1204 .val_bits = 32, 1205 .max_register = I2S_CLKDIV, 1206 .reg_defaults = rockchip_i2s_tdm_reg_defaults, 1207 .num_reg_defaults = ARRAY_SIZE(rockchip_i2s_tdm_reg_defaults), 1208 .writeable_reg = rockchip_i2s_tdm_wr_reg, 1209 .readable_reg = rockchip_i2s_tdm_rd_reg, 1210 .volatile_reg = rockchip_i2s_tdm_volatile_reg, 1211 .precious_reg = rockchip_i2s_tdm_precious_reg, 1212 .cache_type = REGCACHE_FLAT, 1213 }; 1214 1215 static int common_soc_init(struct device *dev, u32 addr) 1216 { 1217 struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev); 1218 const struct txrx_config *configs = i2s_tdm->soc_data->configs; 1219 u32 reg = 0, val = 0, trcm = i2s_tdm->clk_trcm; 1220 int i; 1221 1222 if (trcm == TRCM_TXRX) 1223 return 0; 1224 1225 for (i = 0; i < i2s_tdm->soc_data->config_count; i++) { 1226 if (addr != configs[i].addr) 1227 continue; 1228 reg = configs[i].reg; 1229 if (trcm == TRCM_TX) 1230 val = configs[i].txonly; 1231 else 1232 val = configs[i].rxonly; 1233 1234 if (reg) 1235 regmap_write(i2s_tdm->grf, reg, val); 1236 } 1237 1238 return 0; 1239 } 1240 1241 static const struct txrx_config px30_txrx_config[] = { 1242 { 0xff060000, 0x184, PX30_I2S0_CLK_TXONLY, PX30_I2S0_CLK_RXONLY }, 1243 }; 1244 1245 static const struct txrx_config rk1808_txrx_config[] = { 1246 { 0xff7e0000, 0x190, RK1808_I2S0_CLK_TXONLY, RK1808_I2S0_CLK_RXONLY }, 1247 }; 1248 1249 static const struct txrx_config rk3308_txrx_config[] = { 1250 { 0xff300000, 0x308, RK3308_I2S0_CLK_TXONLY, RK3308_I2S0_CLK_RXONLY }, 1251 { 0xff310000, 0x308, RK3308_I2S1_CLK_TXONLY, RK3308_I2S1_CLK_RXONLY }, 1252 }; 1253 1254 static const struct txrx_config rk3568_txrx_config[] = { 1255 { 0xfe410000, 0x504, RK3568_I2S1_CLK_TXONLY, RK3568_I2S1_CLK_RXONLY }, 1256 { 0xfe410000, 0x508, RK3568_I2S1_MCLK_TX_OE, RK3568_I2S1_MCLK_RX_OE }, 1257 { 0xfe420000, 0x508, RK3568_I2S2_MCLK_OE, RK3568_I2S2_MCLK_OE }, 1258 { 0xfe430000, 0x504, RK3568_I2S3_CLK_TXONLY, RK3568_I2S3_CLK_RXONLY }, 1259 { 0xfe430000, 0x508, RK3568_I2S3_MCLK_TXONLY, RK3568_I2S3_MCLK_RXONLY }, 1260 { 0xfe430000, 0x508, RK3568_I2S3_MCLK_OE, RK3568_I2S3_MCLK_OE }, 1261 }; 1262 1263 static const struct txrx_config rv1126_txrx_config[] = { 1264 { 0xff800000, 0x10260, RV1126_I2S0_CLK_TXONLY, RV1126_I2S0_CLK_RXONLY }, 1265 }; 1266 1267 static struct rk_i2s_soc_data px30_i2s_soc_data = { 1268 .softrst_offset = 0x0300, 1269 .configs = px30_txrx_config, 1270 .config_count = ARRAY_SIZE(px30_txrx_config), 1271 .init = common_soc_init, 1272 }; 1273 1274 static struct rk_i2s_soc_data rk1808_i2s_soc_data = { 1275 .softrst_offset = 0x0300, 1276 .configs = rk1808_txrx_config, 1277 .config_count = ARRAY_SIZE(rk1808_txrx_config), 1278 .init = common_soc_init, 1279 }; 1280 1281 static struct rk_i2s_soc_data rk3308_i2s_soc_data = { 1282 .softrst_offset = 0x0400, 1283 .grf_reg_offset = 0x0308, 1284 .grf_shift = 5, 1285 .configs = rk3308_txrx_config, 1286 .config_count = ARRAY_SIZE(rk3308_txrx_config), 1287 .init = common_soc_init, 1288 }; 1289 1290 static struct rk_i2s_soc_data rk3568_i2s_soc_data = { 1291 .softrst_offset = 0x0400, 1292 .configs = rk3568_txrx_config, 1293 .config_count = ARRAY_SIZE(rk3568_txrx_config), 1294 .init = common_soc_init, 1295 }; 1296 1297 static struct rk_i2s_soc_data rv1126_i2s_soc_data = { 1298 .softrst_offset = 0x0300, 1299 .configs = rv1126_txrx_config, 1300 .config_count = ARRAY_SIZE(rv1126_txrx_config), 1301 .init = common_soc_init, 1302 }; 1303 1304 static const struct of_device_id rockchip_i2s_tdm_match[] = { 1305 { .compatible = "rockchip,px30-i2s-tdm", .data = &px30_i2s_soc_data }, 1306 { .compatible = "rockchip,rk1808-i2s-tdm", .data = &rk1808_i2s_soc_data }, 1307 { .compatible = "rockchip,rk3308-i2s-tdm", .data = &rk3308_i2s_soc_data }, 1308 { .compatible = "rockchip,rk3568-i2s-tdm", .data = &rk3568_i2s_soc_data }, 1309 { .compatible = "rockchip,rv1126-i2s-tdm", .data = &rv1126_i2s_soc_data }, 1310 {}, 1311 }; 1312 1313 static struct snd_soc_dai_driver i2s_tdm_dai = { 1314 .probe = rockchip_i2s_tdm_dai_probe, 1315 .playback = { 1316 .stream_name = "Playback", 1317 }, 1318 .capture = { 1319 .stream_name = "Capture", 1320 }, 1321 .ops = &rockchip_i2s_tdm_dai_ops, 1322 }; 1323 1324 static void rockchip_i2s_tdm_init_dai(struct rk_i2s_tdm_dev *i2s_tdm) 1325 { 1326 struct property *dma_names; 1327 const char *dma_name; 1328 u64 formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | 1329 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE | 1330 SNDRV_PCM_FMTBIT_S32_LE); 1331 struct device_node *node = i2s_tdm->dev->of_node; 1332 1333 of_property_for_each_string(node, "dma-names", dma_names, dma_name) { 1334 if (!strcmp(dma_name, "tx")) 1335 i2s_tdm->has_playback = true; 1336 if (!strcmp(dma_name, "rx")) 1337 i2s_tdm->has_capture = true; 1338 } 1339 1340 if (i2s_tdm->has_playback) { 1341 i2s_tdm_dai.playback.channels_min = 2; 1342 i2s_tdm_dai.playback.channels_max = 8; 1343 i2s_tdm_dai.playback.rates = SNDRV_PCM_RATE_8000_192000; 1344 i2s_tdm_dai.playback.formats = formats; 1345 } 1346 1347 if (i2s_tdm->has_capture) { 1348 i2s_tdm_dai.capture.channels_min = 2; 1349 i2s_tdm_dai.capture.channels_max = 8; 1350 i2s_tdm_dai.capture.rates = SNDRV_PCM_RATE_8000_192000; 1351 i2s_tdm_dai.capture.formats = formats; 1352 } 1353 } 1354 1355 static int rockchip_i2s_tdm_path_check(struct rk_i2s_tdm_dev *i2s_tdm, 1356 int num, 1357 bool is_rx_path) 1358 { 1359 unsigned int *i2s_data; 1360 int i, j; 1361 1362 if (is_rx_path) 1363 i2s_data = i2s_tdm->i2s_sdis; 1364 else 1365 i2s_data = i2s_tdm->i2s_sdos; 1366 1367 for (i = 0; i < num; i++) { 1368 if (i2s_data[i] > CH_GRP_MAX - 1) { 1369 dev_err(i2s_tdm->dev, 1370 "%s path i2s_data[%d]: %d is too high, max is: %d\n", 1371 is_rx_path ? "RX" : "TX", 1372 i, i2s_data[i], CH_GRP_MAX); 1373 return -EINVAL; 1374 } 1375 1376 for (j = 0; j < num; j++) { 1377 if (i == j) 1378 continue; 1379 1380 if (i2s_data[i] == i2s_data[j]) { 1381 dev_err(i2s_tdm->dev, 1382 "%s path invalid routed i2s_data: [%d]%d == [%d]%d\n", 1383 is_rx_path ? "RX" : "TX", 1384 i, i2s_data[i], 1385 j, i2s_data[j]); 1386 return -EINVAL; 1387 } 1388 } 1389 } 1390 1391 return 0; 1392 } 1393 1394 static void rockchip_i2s_tdm_tx_path_config(struct rk_i2s_tdm_dev *i2s_tdm, 1395 int num) 1396 { 1397 int idx; 1398 1399 for (idx = 0; idx < num; idx++) { 1400 regmap_update_bits(i2s_tdm->regmap, I2S_TXCR, 1401 I2S_TXCR_PATH_MASK(idx), 1402 I2S_TXCR_PATH(idx, i2s_tdm->i2s_sdos[idx])); 1403 } 1404 } 1405 1406 static void rockchip_i2s_tdm_rx_path_config(struct rk_i2s_tdm_dev *i2s_tdm, 1407 int num) 1408 { 1409 int idx; 1410 1411 for (idx = 0; idx < num; idx++) { 1412 regmap_update_bits(i2s_tdm->regmap, I2S_RXCR, 1413 I2S_RXCR_PATH_MASK(idx), 1414 I2S_RXCR_PATH(idx, i2s_tdm->i2s_sdis[idx])); 1415 } 1416 } 1417 1418 static void rockchip_i2s_tdm_path_config(struct rk_i2s_tdm_dev *i2s_tdm, 1419 int num, bool is_rx_path) 1420 { 1421 if (is_rx_path) 1422 rockchip_i2s_tdm_rx_path_config(i2s_tdm, num); 1423 else 1424 rockchip_i2s_tdm_tx_path_config(i2s_tdm, num); 1425 } 1426 1427 static int rockchip_i2s_tdm_get_calibrate_mclks(struct rk_i2s_tdm_dev *i2s_tdm) 1428 { 1429 int num_mclks = 0; 1430 1431 i2s_tdm->mclk_tx_src = devm_clk_get(i2s_tdm->dev, "mclk_tx_src"); 1432 if (!IS_ERR(i2s_tdm->mclk_tx_src)) 1433 num_mclks++; 1434 1435 i2s_tdm->mclk_rx_src = devm_clk_get(i2s_tdm->dev, "mclk_rx_src"); 1436 if (!IS_ERR(i2s_tdm->mclk_rx_src)) 1437 num_mclks++; 1438 1439 i2s_tdm->mclk_root0 = devm_clk_get(i2s_tdm->dev, "mclk_root0"); 1440 if (!IS_ERR(i2s_tdm->mclk_root0)) 1441 num_mclks++; 1442 1443 i2s_tdm->mclk_root1 = devm_clk_get(i2s_tdm->dev, "mclk_root1"); 1444 if (!IS_ERR(i2s_tdm->mclk_root1)) 1445 num_mclks++; 1446 1447 if (num_mclks < 4 && num_mclks != 0) 1448 return -ENOENT; 1449 1450 if (num_mclks == 4) 1451 i2s_tdm->mclk_calibrate = 1; 1452 1453 return 0; 1454 } 1455 1456 static int rockchip_i2s_tdm_path_prepare(struct rk_i2s_tdm_dev *i2s_tdm, 1457 struct device_node *np, 1458 bool is_rx_path) 1459 { 1460 char *i2s_tx_path_prop = "rockchip,i2s-tx-route"; 1461 char *i2s_rx_path_prop = "rockchip,i2s-rx-route"; 1462 char *i2s_path_prop; 1463 unsigned int *i2s_data; 1464 int num, ret = 0; 1465 1466 if (is_rx_path) { 1467 i2s_path_prop = i2s_rx_path_prop; 1468 i2s_data = i2s_tdm->i2s_sdis; 1469 } else { 1470 i2s_path_prop = i2s_tx_path_prop; 1471 i2s_data = i2s_tdm->i2s_sdos; 1472 } 1473 1474 num = of_count_phandle_with_args(np, i2s_path_prop, NULL); 1475 if (num < 0) { 1476 if (num != -ENOENT) { 1477 dev_err(i2s_tdm->dev, 1478 "Failed to read '%s' num: %d\n", 1479 i2s_path_prop, num); 1480 ret = num; 1481 } 1482 return ret; 1483 } else if (num != CH_GRP_MAX) { 1484 dev_err(i2s_tdm->dev, 1485 "The num: %d should be: %d\n", num, CH_GRP_MAX); 1486 return -EINVAL; 1487 } 1488 1489 ret = of_property_read_u32_array(np, i2s_path_prop, 1490 i2s_data, num); 1491 if (ret < 0) { 1492 dev_err(i2s_tdm->dev, 1493 "Failed to read '%s': %d\n", 1494 i2s_path_prop, ret); 1495 return ret; 1496 } 1497 1498 ret = rockchip_i2s_tdm_path_check(i2s_tdm, num, is_rx_path); 1499 if (ret < 0) { 1500 dev_err(i2s_tdm->dev, 1501 "Failed to check i2s data bus: %d\n", ret); 1502 return ret; 1503 } 1504 1505 rockchip_i2s_tdm_path_config(i2s_tdm, num, is_rx_path); 1506 1507 return 0; 1508 } 1509 1510 static int rockchip_i2s_tdm_tx_path_prepare(struct rk_i2s_tdm_dev *i2s_tdm, 1511 struct device_node *np) 1512 { 1513 return rockchip_i2s_tdm_path_prepare(i2s_tdm, np, 0); 1514 } 1515 1516 static int rockchip_i2s_tdm_rx_path_prepare(struct rk_i2s_tdm_dev *i2s_tdm, 1517 struct device_node *np) 1518 { 1519 return rockchip_i2s_tdm_path_prepare(i2s_tdm, np, 1); 1520 } 1521 1522 static int rockchip_i2s_tdm_probe(struct platform_device *pdev) 1523 { 1524 struct device_node *node = pdev->dev.of_node; 1525 const struct of_device_id *of_id; 1526 struct rk_i2s_tdm_dev *i2s_tdm; 1527 struct resource *res; 1528 void __iomem *regs; 1529 int ret; 1530 1531 i2s_tdm = devm_kzalloc(&pdev->dev, sizeof(*i2s_tdm), GFP_KERNEL); 1532 if (!i2s_tdm) 1533 return -ENOMEM; 1534 1535 i2s_tdm->dev = &pdev->dev; 1536 1537 of_id = of_match_device(rockchip_i2s_tdm_match, &pdev->dev); 1538 if (!of_id || !of_id->data) 1539 return -EINVAL; 1540 1541 spin_lock_init(&i2s_tdm->lock); 1542 i2s_tdm->soc_data = (struct rk_i2s_soc_data *)of_id->data; 1543 1544 rockchip_i2s_tdm_init_dai(i2s_tdm); 1545 1546 i2s_tdm->frame_width = 64; 1547 1548 i2s_tdm->clk_trcm = TRCM_TXRX; 1549 if (of_property_read_bool(node, "rockchip,trcm-sync-tx-only")) 1550 i2s_tdm->clk_trcm = TRCM_TX; 1551 if (of_property_read_bool(node, "rockchip,trcm-sync-rx-only")) { 1552 if (i2s_tdm->clk_trcm) { 1553 dev_err(i2s_tdm->dev, "invalid trcm-sync configuration\n"); 1554 return -EINVAL; 1555 } 1556 i2s_tdm->clk_trcm = TRCM_RX; 1557 } 1558 if (i2s_tdm->clk_trcm != TRCM_TXRX) 1559 i2s_tdm_dai.symmetric_rate = 1; 1560 1561 i2s_tdm->grf = syscon_regmap_lookup_by_phandle(node, "rockchip,grf"); 1562 if (IS_ERR(i2s_tdm->grf)) 1563 return dev_err_probe(i2s_tdm->dev, PTR_ERR(i2s_tdm->grf), 1564 "Error in rockchip,grf\n"); 1565 1566 i2s_tdm->tx_reset = devm_reset_control_get_optional_exclusive(&pdev->dev, 1567 "tx-m"); 1568 if (IS_ERR(i2s_tdm->tx_reset)) { 1569 ret = PTR_ERR(i2s_tdm->tx_reset); 1570 return dev_err_probe(i2s_tdm->dev, ret, 1571 "Error in tx-m reset control\n"); 1572 } 1573 1574 i2s_tdm->rx_reset = devm_reset_control_get_optional_exclusive(&pdev->dev, 1575 "rx-m"); 1576 if (IS_ERR(i2s_tdm->rx_reset)) { 1577 ret = PTR_ERR(i2s_tdm->rx_reset); 1578 return dev_err_probe(i2s_tdm->dev, ret, 1579 "Error in rx-m reset control\n"); 1580 } 1581 1582 i2s_tdm->hclk = devm_clk_get(&pdev->dev, "hclk"); 1583 if (IS_ERR(i2s_tdm->hclk)) { 1584 return dev_err_probe(i2s_tdm->dev, PTR_ERR(i2s_tdm->hclk), 1585 "Failed to get clock hclk\n"); 1586 } 1587 1588 i2s_tdm->mclk_tx = devm_clk_get(&pdev->dev, "mclk_tx"); 1589 if (IS_ERR(i2s_tdm->mclk_tx)) { 1590 return dev_err_probe(i2s_tdm->dev, PTR_ERR(i2s_tdm->mclk_tx), 1591 "Failed to get clock mclk_tx\n"); 1592 } 1593 1594 i2s_tdm->mclk_rx = devm_clk_get(&pdev->dev, "mclk_rx"); 1595 if (IS_ERR(i2s_tdm->mclk_rx)) { 1596 return dev_err_probe(i2s_tdm->dev, PTR_ERR(i2s_tdm->mclk_rx), 1597 "Failed to get clock mclk_rx\n"); 1598 } 1599 1600 i2s_tdm->io_multiplex = 1601 of_property_read_bool(node, "rockchip,io-multiplex"); 1602 1603 ret = rockchip_i2s_tdm_get_calibrate_mclks(i2s_tdm); 1604 if (ret) 1605 return dev_err_probe(i2s_tdm->dev, ret, 1606 "mclk-calibrate clocks missing"); 1607 1608 regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 1609 if (IS_ERR(regs)) { 1610 return dev_err_probe(i2s_tdm->dev, PTR_ERR(regs), 1611 "Failed to get resource IORESOURCE_MEM\n"); 1612 } 1613 1614 i2s_tdm->regmap = devm_regmap_init_mmio(&pdev->dev, regs, 1615 &rockchip_i2s_tdm_regmap_config); 1616 if (IS_ERR(i2s_tdm->regmap)) { 1617 return dev_err_probe(i2s_tdm->dev, PTR_ERR(i2s_tdm->regmap), 1618 "Failed to initialise regmap\n"); 1619 } 1620 1621 if (i2s_tdm->has_playback) { 1622 i2s_tdm->playback_dma_data.addr = res->start + I2S_TXDR; 1623 i2s_tdm->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 1624 i2s_tdm->playback_dma_data.maxburst = 8; 1625 } 1626 1627 if (i2s_tdm->has_capture) { 1628 i2s_tdm->capture_dma_data.addr = res->start + I2S_RXDR; 1629 i2s_tdm->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 1630 i2s_tdm->capture_dma_data.maxburst = 8; 1631 } 1632 1633 ret = rockchip_i2s_tdm_tx_path_prepare(i2s_tdm, node); 1634 if (ret < 0) { 1635 dev_err(&pdev->dev, "I2S TX path prepare failed: %d\n", ret); 1636 return ret; 1637 } 1638 1639 ret = rockchip_i2s_tdm_rx_path_prepare(i2s_tdm, node); 1640 if (ret < 0) { 1641 dev_err(&pdev->dev, "I2S RX path prepare failed: %d\n", ret); 1642 return ret; 1643 } 1644 1645 dev_set_drvdata(&pdev->dev, i2s_tdm); 1646 1647 ret = clk_prepare_enable(i2s_tdm->hclk); 1648 if (ret) { 1649 return dev_err_probe(i2s_tdm->dev, ret, 1650 "Failed to enable clock hclk\n"); 1651 } 1652 1653 ret = i2s_tdm_prepare_enable_mclk(i2s_tdm); 1654 if (ret) { 1655 ret = dev_err_probe(i2s_tdm->dev, ret, 1656 "Failed to enable one or more mclks\n"); 1657 goto err_disable_hclk; 1658 } 1659 1660 if (i2s_tdm->mclk_calibrate) { 1661 i2s_tdm->mclk_root0_initial_freq = clk_get_rate(i2s_tdm->mclk_root0); 1662 i2s_tdm->mclk_root1_initial_freq = clk_get_rate(i2s_tdm->mclk_root1); 1663 i2s_tdm->mclk_root0_freq = i2s_tdm->mclk_root0_initial_freq; 1664 i2s_tdm->mclk_root1_freq = i2s_tdm->mclk_root1_initial_freq; 1665 } 1666 1667 pm_runtime_enable(&pdev->dev); 1668 1669 regmap_update_bits(i2s_tdm->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK, 1670 I2S_DMACR_TDL(16)); 1671 regmap_update_bits(i2s_tdm->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK, 1672 I2S_DMACR_RDL(16)); 1673 regmap_update_bits(i2s_tdm->regmap, I2S_CKR, I2S_CKR_TRCM_MASK, 1674 i2s_tdm->clk_trcm << I2S_CKR_TRCM_SHIFT); 1675 1676 if (i2s_tdm->soc_data && i2s_tdm->soc_data->init) 1677 i2s_tdm->soc_data->init(&pdev->dev, res->start); 1678 1679 ret = devm_snd_soc_register_component(&pdev->dev, 1680 &rockchip_i2s_tdm_component, 1681 &i2s_tdm_dai, 1); 1682 1683 if (ret) { 1684 dev_err(&pdev->dev, "Could not register DAI\n"); 1685 goto err_suspend; 1686 } 1687 1688 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); 1689 if (ret) { 1690 dev_err(&pdev->dev, "Could not register PCM\n"); 1691 goto err_suspend; 1692 } 1693 1694 return 0; 1695 1696 err_suspend: 1697 if (!pm_runtime_status_suspended(&pdev->dev)) 1698 i2s_tdm_runtime_suspend(&pdev->dev); 1699 pm_runtime_disable(&pdev->dev); 1700 1701 err_disable_hclk: 1702 clk_disable_unprepare(i2s_tdm->hclk); 1703 1704 return ret; 1705 } 1706 1707 static int rockchip_i2s_tdm_remove(struct platform_device *pdev) 1708 { 1709 if (!pm_runtime_status_suspended(&pdev->dev)) 1710 i2s_tdm_runtime_suspend(&pdev->dev); 1711 1712 pm_runtime_disable(&pdev->dev); 1713 1714 return 0; 1715 } 1716 1717 static int __maybe_unused rockchip_i2s_tdm_suspend(struct device *dev) 1718 { 1719 struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev); 1720 1721 regcache_mark_dirty(i2s_tdm->regmap); 1722 1723 return 0; 1724 } 1725 1726 static int __maybe_unused rockchip_i2s_tdm_resume(struct device *dev) 1727 { 1728 struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev); 1729 int ret; 1730 1731 ret = pm_runtime_get_sync(dev); 1732 if (ret < 0) 1733 return ret; 1734 ret = regcache_sync(i2s_tdm->regmap); 1735 pm_runtime_put(dev); 1736 1737 return ret; 1738 } 1739 1740 static const struct dev_pm_ops rockchip_i2s_tdm_pm_ops = { 1741 SET_RUNTIME_PM_OPS(i2s_tdm_runtime_suspend, i2s_tdm_runtime_resume, 1742 NULL) 1743 SET_SYSTEM_SLEEP_PM_OPS(rockchip_i2s_tdm_suspend, 1744 rockchip_i2s_tdm_resume) 1745 }; 1746 1747 static struct platform_driver rockchip_i2s_tdm_driver = { 1748 .probe = rockchip_i2s_tdm_probe, 1749 .remove = rockchip_i2s_tdm_remove, 1750 .driver = { 1751 .name = DRV_NAME, 1752 .of_match_table = of_match_ptr(rockchip_i2s_tdm_match), 1753 .pm = &rockchip_i2s_tdm_pm_ops, 1754 }, 1755 }; 1756 module_platform_driver(rockchip_i2s_tdm_driver); 1757 1758 MODULE_DESCRIPTION("ROCKCHIP I2S/TDM ASoC Interface"); 1759 MODULE_AUTHOR("Sugar Zhang <sugar.zhang@rock-chips.com>"); 1760 MODULE_LICENSE("GPL v2"); 1761 MODULE_ALIAS("platform:" DRV_NAME); 1762 MODULE_DEVICE_TABLE(of, rockchip_i2s_tdm_match); 1763