File Index
Files and directories
Sign in
FILE

rockchip_i2s_tdm.c

File preview with syntax highlighting.

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