brintos

brintos / linux-shallow public Read only

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