xref: /linux/sound/soc/tegra/tegra210_admaif.c (revision c17ee635fd3a482b2ad2bf5e269755c2eae5f25e)
1 // SPDX-License-Identifier: GPL-2.0-only
2 // SPDX-FileCopyrightText: Copyright (c) 2020-2025 NVIDIA CORPORATION & AFFILIATES.
3 // All rights reserved.
4 //
5 // tegra210_admaif.c - Tegra ADMAIF driver
6 
7 #include <linux/clk.h>
8 #include <linux/device.h>
9 #include <linux/module.h>
10 #include <linux/of_platform.h>
11 #include <linux/platform_device.h>
12 #include <linux/pm_runtime.h>
13 #include <linux/regmap.h>
14 #include <sound/pcm_params.h>
15 #include <sound/soc.h>
16 #include "tegra_isomgr_bw.h"
17 #include "tegra210_admaif.h"
18 #include "tegra_cif.h"
19 #include "tegra_pcm.h"
20 
21 #define CH_REG(offset, reg, id)						       \
22 	((offset) + (reg) + (TEGRA_ADMAIF_CHANNEL_REG_STRIDE * (id)))
23 
24 #define CH_TX_REG(reg, id) CH_REG(admaif->soc_data->tx_base, reg, id)
25 
26 #define CH_RX_REG(reg, id) CH_REG(admaif->soc_data->rx_base, reg, id)
27 
28 #define REG_DEFAULTS(id, rx_ctrl, tx_ctrl, tx_base, rx_base, cif_ctrl)	       \
29 	{ CH_REG(rx_base, TEGRA_ADMAIF_RX_INT_MASK, id), 0x00000001 },	       \
30 	{ CH_REG(rx_base, TEGRA_ADMAIF_CH_ACIF_RX_CTRL, id), cif_ctrl },     \
31 	{ CH_REG(rx_base, TEGRA_ADMAIF_RX_FIFO_CTRL, id), rx_ctrl },	       \
32 	{ CH_REG(tx_base, TEGRA_ADMAIF_TX_INT_MASK, id), 0x00000001 },	       \
33 	{ CH_REG(tx_base, TEGRA_ADMAIF_CH_ACIF_TX_CTRL, id), cif_ctrl },     \
34 	{ CH_REG(tx_base, TEGRA_ADMAIF_TX_FIFO_CTRL, id), tx_ctrl }
35 
36 #define ADMAIF_REG_DEFAULTS(id, chip)					       \
37 	REG_DEFAULTS((id) - 1,						       \
38 		chip ## _ADMAIF_RX ## id ## _FIFO_CTRL_REG_DEFAULT,	       \
39 		chip ## _ADMAIF_TX ## id ## _FIFO_CTRL_REG_DEFAULT,	       \
40 		chip ## _ADMAIF_TX_BASE,				       \
41 		chip ## _ADMAIF_RX_BASE,				       \
42 		chip ## _ADMAIF_CIF_REG_DEFAULT)
43 
44 static const struct reg_default tegra186_admaif_reg_defaults[] = {
45 	{(TEGRA_ADMAIF_GLOBAL_CG_0 + TEGRA186_ADMAIF_GLOBAL_BASE), 0x00000003},
46 	ADMAIF_REG_DEFAULTS(1, TEGRA186),
47 	ADMAIF_REG_DEFAULTS(2, TEGRA186),
48 	ADMAIF_REG_DEFAULTS(3, TEGRA186),
49 	ADMAIF_REG_DEFAULTS(4, TEGRA186),
50 	ADMAIF_REG_DEFAULTS(5, TEGRA186),
51 	ADMAIF_REG_DEFAULTS(6, TEGRA186),
52 	ADMAIF_REG_DEFAULTS(7, TEGRA186),
53 	ADMAIF_REG_DEFAULTS(8, TEGRA186),
54 	ADMAIF_REG_DEFAULTS(9, TEGRA186),
55 	ADMAIF_REG_DEFAULTS(10, TEGRA186),
56 	ADMAIF_REG_DEFAULTS(11, TEGRA186),
57 	ADMAIF_REG_DEFAULTS(12, TEGRA186),
58 	ADMAIF_REG_DEFAULTS(13, TEGRA186),
59 	ADMAIF_REG_DEFAULTS(14, TEGRA186),
60 	ADMAIF_REG_DEFAULTS(15, TEGRA186),
61 	ADMAIF_REG_DEFAULTS(16, TEGRA186),
62 	ADMAIF_REG_DEFAULTS(17, TEGRA186),
63 	ADMAIF_REG_DEFAULTS(18, TEGRA186),
64 	ADMAIF_REG_DEFAULTS(19, TEGRA186),
65 	ADMAIF_REG_DEFAULTS(20, TEGRA186)
66 };
67 
68 static const struct reg_default tegra210_admaif_reg_defaults[] = {
69 	{(TEGRA_ADMAIF_GLOBAL_CG_0 + TEGRA210_ADMAIF_GLOBAL_BASE), 0x00000003},
70 	ADMAIF_REG_DEFAULTS(1, TEGRA210),
71 	ADMAIF_REG_DEFAULTS(2, TEGRA210),
72 	ADMAIF_REG_DEFAULTS(3, TEGRA210),
73 	ADMAIF_REG_DEFAULTS(4, TEGRA210),
74 	ADMAIF_REG_DEFAULTS(5, TEGRA210),
75 	ADMAIF_REG_DEFAULTS(6, TEGRA210),
76 	ADMAIF_REG_DEFAULTS(7, TEGRA210),
77 	ADMAIF_REG_DEFAULTS(8, TEGRA210),
78 	ADMAIF_REG_DEFAULTS(9, TEGRA210),
79 	ADMAIF_REG_DEFAULTS(10, TEGRA210)
80 };
81 
82 static const struct reg_default tegra264_admaif_reg_defaults[] = {
83 	{(TEGRA_ADMAIF_GLOBAL_CG_0 + TEGRA264_ADMAIF_GLOBAL_BASE), 0x00000003},
84 	ADMAIF_REG_DEFAULTS(1, TEGRA264),
85 	ADMAIF_REG_DEFAULTS(2, TEGRA264),
86 	ADMAIF_REG_DEFAULTS(3, TEGRA264),
87 	ADMAIF_REG_DEFAULTS(4, TEGRA264),
88 	ADMAIF_REG_DEFAULTS(5, TEGRA264),
89 	ADMAIF_REG_DEFAULTS(6, TEGRA264),
90 	ADMAIF_REG_DEFAULTS(7, TEGRA264),
91 	ADMAIF_REG_DEFAULTS(8, TEGRA264),
92 	ADMAIF_REG_DEFAULTS(9, TEGRA264),
93 	ADMAIF_REG_DEFAULTS(10, TEGRA264),
94 	ADMAIF_REG_DEFAULTS(11, TEGRA264),
95 	ADMAIF_REG_DEFAULTS(12, TEGRA264),
96 	ADMAIF_REG_DEFAULTS(13, TEGRA264),
97 	ADMAIF_REG_DEFAULTS(14, TEGRA264),
98 	ADMAIF_REG_DEFAULTS(15, TEGRA264),
99 	ADMAIF_REG_DEFAULTS(16, TEGRA264),
100 	ADMAIF_REG_DEFAULTS(17, TEGRA264),
101 	ADMAIF_REG_DEFAULTS(18, TEGRA264),
102 	ADMAIF_REG_DEFAULTS(19, TEGRA264),
103 	ADMAIF_REG_DEFAULTS(20, TEGRA264),
104 	ADMAIF_REG_DEFAULTS(21, TEGRA264),
105 	ADMAIF_REG_DEFAULTS(22, TEGRA264),
106 	ADMAIF_REG_DEFAULTS(23, TEGRA264),
107 	ADMAIF_REG_DEFAULTS(24, TEGRA264),
108 	ADMAIF_REG_DEFAULTS(25, TEGRA264),
109 	ADMAIF_REG_DEFAULTS(26, TEGRA264),
110 	ADMAIF_REG_DEFAULTS(27, TEGRA264),
111 	ADMAIF_REG_DEFAULTS(28, TEGRA264),
112 	ADMAIF_REG_DEFAULTS(29, TEGRA264),
113 	ADMAIF_REG_DEFAULTS(30, TEGRA264),
114 	ADMAIF_REG_DEFAULTS(31, TEGRA264),
115 	ADMAIF_REG_DEFAULTS(32, TEGRA264)
116 };
117 
118 static bool tegra_admaif_wr_reg(struct device *dev, unsigned int reg)
119 {
120 	struct tegra_admaif *admaif = dev_get_drvdata(dev);
121 	unsigned int ch_stride = TEGRA_ADMAIF_CHANNEL_REG_STRIDE;
122 	unsigned int num_ch = admaif->soc_data->num_ch;
123 	unsigned int rx_base = admaif->soc_data->rx_base;
124 	unsigned int tx_base = admaif->soc_data->tx_base;
125 	unsigned int global_base = admaif->soc_data->global_base;
126 	unsigned int reg_max = admaif->soc_data->regmap_conf->max_register;
127 	unsigned int rx_max = rx_base + (num_ch * ch_stride);
128 	unsigned int tx_max = tx_base + (num_ch * ch_stride);
129 
130 	if ((reg >= rx_base) && (reg < rx_max)) {
131 		reg = (reg - rx_base) % ch_stride;
132 		if ((reg == TEGRA_ADMAIF_RX_ENABLE) ||
133 		    (reg == TEGRA_ADMAIF_RX_FIFO_CTRL) ||
134 		    (reg == TEGRA_ADMAIF_RX_SOFT_RESET) ||
135 		    (reg == TEGRA_ADMAIF_CH_ACIF_RX_CTRL))
136 			return true;
137 	} else if ((reg >= tx_base) && (reg < tx_max)) {
138 		reg = (reg - tx_base) % ch_stride;
139 		if ((reg == TEGRA_ADMAIF_TX_ENABLE) ||
140 		    (reg == TEGRA_ADMAIF_TX_FIFO_CTRL) ||
141 		    (reg == TEGRA_ADMAIF_TX_SOFT_RESET) ||
142 		    (reg == TEGRA_ADMAIF_CH_ACIF_TX_CTRL))
143 			return true;
144 	} else if ((reg >= global_base) && (reg < reg_max)) {
145 		if (reg == (global_base + TEGRA_ADMAIF_GLOBAL_ENABLE))
146 			return true;
147 	}
148 
149 	return false;
150 }
151 
152 static bool tegra_admaif_rd_reg(struct device *dev, unsigned int reg)
153 {
154 	struct tegra_admaif *admaif = dev_get_drvdata(dev);
155 	unsigned int ch_stride = TEGRA_ADMAIF_CHANNEL_REG_STRIDE;
156 	unsigned int num_ch = admaif->soc_data->num_ch;
157 	unsigned int rx_base = admaif->soc_data->rx_base;
158 	unsigned int tx_base = admaif->soc_data->tx_base;
159 	unsigned int global_base = admaif->soc_data->global_base;
160 	unsigned int reg_max = admaif->soc_data->regmap_conf->max_register;
161 	unsigned int rx_max = rx_base + (num_ch * ch_stride);
162 	unsigned int tx_max = tx_base + (num_ch * ch_stride);
163 
164 	if ((reg >= rx_base) && (reg < rx_max)) {
165 		reg = (reg - rx_base) % ch_stride;
166 		if ((reg == TEGRA_ADMAIF_RX_ENABLE) ||
167 		    (reg == TEGRA_ADMAIF_RX_STATUS) ||
168 		    (reg == TEGRA_ADMAIF_RX_INT_STATUS) ||
169 		    (reg == TEGRA_ADMAIF_RX_FIFO_CTRL) ||
170 		    (reg == TEGRA_ADMAIF_RX_SOFT_RESET) ||
171 		    (reg == TEGRA_ADMAIF_CH_ACIF_RX_CTRL))
172 			return true;
173 	} else if ((reg >= tx_base) && (reg < tx_max)) {
174 		reg = (reg - tx_base) % ch_stride;
175 		if ((reg == TEGRA_ADMAIF_TX_ENABLE) ||
176 		    (reg == TEGRA_ADMAIF_TX_STATUS) ||
177 		    (reg == TEGRA_ADMAIF_TX_INT_STATUS) ||
178 		    (reg == TEGRA_ADMAIF_TX_FIFO_CTRL) ||
179 		    (reg == TEGRA_ADMAIF_TX_SOFT_RESET) ||
180 		    (reg == TEGRA_ADMAIF_CH_ACIF_TX_CTRL))
181 			return true;
182 	} else if ((reg >= global_base) && (reg < reg_max)) {
183 		if ((reg == (global_base + TEGRA_ADMAIF_GLOBAL_ENABLE)) ||
184 		    (reg == (global_base + TEGRA_ADMAIF_GLOBAL_CG_0)) ||
185 		    (reg == (global_base + TEGRA_ADMAIF_GLOBAL_STATUS)) ||
186 		    (reg == (global_base +
187 				TEGRA_ADMAIF_GLOBAL_RX_ENABLE_STATUS)) ||
188 		    (reg == (global_base +
189 				TEGRA_ADMAIF_GLOBAL_TX_ENABLE_STATUS)))
190 			return true;
191 	}
192 
193 	return false;
194 }
195 
196 static bool tegra_admaif_volatile_reg(struct device *dev, unsigned int reg)
197 {
198 	struct tegra_admaif *admaif = dev_get_drvdata(dev);
199 	unsigned int ch_stride = TEGRA_ADMAIF_CHANNEL_REG_STRIDE;
200 	unsigned int num_ch = admaif->soc_data->num_ch;
201 	unsigned int rx_base = admaif->soc_data->rx_base;
202 	unsigned int tx_base = admaif->soc_data->tx_base;
203 	unsigned int global_base = admaif->soc_data->global_base;
204 	unsigned int reg_max = admaif->soc_data->regmap_conf->max_register;
205 	unsigned int rx_max = rx_base + (num_ch * ch_stride);
206 	unsigned int tx_max = tx_base + (num_ch * ch_stride);
207 
208 	if ((reg >= rx_base) && (reg < rx_max)) {
209 		reg = (reg - rx_base) % ch_stride;
210 		if ((reg == TEGRA_ADMAIF_RX_ENABLE) ||
211 		    (reg == TEGRA_ADMAIF_RX_STATUS) ||
212 		    (reg == TEGRA_ADMAIF_RX_INT_STATUS) ||
213 		    (reg == TEGRA_ADMAIF_RX_SOFT_RESET))
214 			return true;
215 	} else if ((reg >= tx_base) && (reg < tx_max)) {
216 		reg = (reg - tx_base) % ch_stride;
217 		if ((reg == TEGRA_ADMAIF_TX_ENABLE) ||
218 		    (reg == TEGRA_ADMAIF_TX_STATUS) ||
219 		    (reg == TEGRA_ADMAIF_TX_INT_STATUS) ||
220 		    (reg == TEGRA_ADMAIF_TX_SOFT_RESET))
221 			return true;
222 	} else if ((reg >= global_base) && (reg < reg_max)) {
223 		if ((reg == (global_base + TEGRA_ADMAIF_GLOBAL_STATUS)) ||
224 		    (reg == (global_base +
225 				TEGRA_ADMAIF_GLOBAL_RX_ENABLE_STATUS)) ||
226 		    (reg == (global_base +
227 				TEGRA_ADMAIF_GLOBAL_TX_ENABLE_STATUS)))
228 			return true;
229 	}
230 
231 	return false;
232 }
233 
234 static const struct regmap_config tegra210_admaif_regmap_config = {
235 	.reg_bits		= 32,
236 	.reg_stride		= 4,
237 	.val_bits		= 32,
238 	.max_register		= TEGRA210_ADMAIF_LAST_REG,
239 	.writeable_reg		= tegra_admaif_wr_reg,
240 	.readable_reg		= tegra_admaif_rd_reg,
241 	.volatile_reg		= tegra_admaif_volatile_reg,
242 	.reg_defaults		= tegra210_admaif_reg_defaults,
243 	.num_reg_defaults	= TEGRA210_ADMAIF_CHANNEL_COUNT * 6 + 1,
244 	.reg_default_cb		= regmap_default_zero_cb,
245 	.cache_type		= REGCACHE_FLAT,
246 };
247 
248 static const struct regmap_config tegra186_admaif_regmap_config = {
249 	.reg_bits		= 32,
250 	.reg_stride		= 4,
251 	.val_bits		= 32,
252 	.max_register		= TEGRA186_ADMAIF_LAST_REG,
253 	.writeable_reg		= tegra_admaif_wr_reg,
254 	.readable_reg		= tegra_admaif_rd_reg,
255 	.volatile_reg		= tegra_admaif_volatile_reg,
256 	.reg_defaults		= tegra186_admaif_reg_defaults,
257 	.num_reg_defaults	= TEGRA186_ADMAIF_CHANNEL_COUNT * 6 + 1,
258 	.reg_default_cb		= regmap_default_zero_cb,
259 	.cache_type		= REGCACHE_FLAT,
260 };
261 
262 static const struct regmap_config tegra264_admaif_regmap_config = {
263 	.reg_bits		= 32,
264 	.reg_stride		= 4,
265 	.val_bits		= 32,
266 	.max_register		= TEGRA264_ADMAIF_LAST_REG,
267 	.writeable_reg		= tegra_admaif_wr_reg,
268 	.readable_reg		= tegra_admaif_rd_reg,
269 	.volatile_reg		= tegra_admaif_volatile_reg,
270 	.reg_defaults		= tegra264_admaif_reg_defaults,
271 	.num_reg_defaults	= TEGRA264_ADMAIF_CHANNEL_COUNT * 6 + 1,
272 	.reg_default_cb		= regmap_default_zero_cb,
273 	.cache_type		= REGCACHE_FLAT,
274 };
275 
276 static int tegra_admaif_runtime_suspend(struct device *dev)
277 {
278 	struct tegra_admaif *admaif = dev_get_drvdata(dev);
279 
280 	regcache_cache_only(admaif->regmap, true);
281 	regcache_mark_dirty(admaif->regmap);
282 
283 	return 0;
284 }
285 
286 static int tegra_admaif_runtime_resume(struct device *dev)
287 {
288 	struct tegra_admaif *admaif = dev_get_drvdata(dev);
289 
290 	regcache_cache_only(admaif->regmap, false);
291 	regcache_sync(admaif->regmap);
292 
293 	return 0;
294 }
295 
296 static int tegra_admaif_set_pack_mode(struct regmap *map, unsigned int reg,
297 				      int valid_bit)
298 {
299 	switch (valid_bit) {
300 	case DATA_8BIT:
301 		regmap_update_bits(map, reg, PACK8_EN_MASK, PACK8_EN);
302 		regmap_update_bits(map, reg, PACK16_EN_MASK, 0);
303 		break;
304 	case DATA_16BIT:
305 		regmap_update_bits(map, reg, PACK16_EN_MASK, PACK16_EN);
306 		regmap_update_bits(map, reg, PACK8_EN_MASK, 0);
307 		break;
308 	case DATA_32BIT:
309 		regmap_update_bits(map, reg, PACK16_EN_MASK, 0);
310 		regmap_update_bits(map, reg, PACK8_EN_MASK, 0);
311 		break;
312 	default:
313 		return -EINVAL;
314 	}
315 
316 	return 0;
317 }
318 
319 static int tegra_admaif_prepare(struct snd_pcm_substream *substream,
320 				struct snd_soc_dai *dai)
321 {
322 	return tegra_isomgr_adma_setbw(substream, dai, true);
323 }
324 
325 static void tegra_admaif_shutdown(struct snd_pcm_substream *substream,
326 				  struct snd_soc_dai *dai)
327 {
328 	tegra_isomgr_adma_setbw(substream, dai, false);
329 }
330 
331 static int tegra_admaif_hw_params(struct snd_pcm_substream *substream,
332 				  struct snd_pcm_hw_params *params,
333 				  struct snd_soc_dai *dai)
334 {
335 	struct device *dev = dai->dev;
336 	struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai);
337 	struct tegra_cif_conf cif_conf;
338 	unsigned int reg, path;
339 	int valid_bit, channels;
340 
341 	memset(&cif_conf, 0, sizeof(struct tegra_cif_conf));
342 
343 	switch (params_format(params)) {
344 	case SNDRV_PCM_FORMAT_S8:
345 		cif_conf.audio_bits = TEGRA_ACIF_BITS_8;
346 		cif_conf.client_bits = TEGRA_ACIF_BITS_8;
347 		valid_bit = DATA_8BIT;
348 		break;
349 	case SNDRV_PCM_FORMAT_S16_LE:
350 		cif_conf.audio_bits = TEGRA_ACIF_BITS_16;
351 		cif_conf.client_bits = TEGRA_ACIF_BITS_16;
352 		valid_bit = DATA_16BIT;
353 		break;
354 	case SNDRV_PCM_FORMAT_S24_LE:
355 		cif_conf.audio_bits = TEGRA_ACIF_BITS_32;
356 		cif_conf.client_bits = TEGRA_ACIF_BITS_24;
357 		valid_bit = DATA_32BIT;
358 		break;
359 	case SNDRV_PCM_FORMAT_S32_LE:
360 		cif_conf.audio_bits = TEGRA_ACIF_BITS_32;
361 		cif_conf.client_bits = TEGRA_ACIF_BITS_32;
362 		valid_bit  = DATA_32BIT;
363 		break;
364 	default:
365 		dev_err(dev, "unsupported format!\n");
366 		return -EOPNOTSUPP;
367 	}
368 
369 	channels = params_channels(params);
370 	cif_conf.client_ch = channels;
371 	cif_conf.audio_ch = channels;
372 
373 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
374 		path = ADMAIF_TX_PATH;
375 		reg = CH_TX_REG(TEGRA_ADMAIF_CH_ACIF_TX_CTRL, dai->id);
376 	} else {
377 		path = ADMAIF_RX_PATH;
378 		reg = CH_RX_REG(TEGRA_ADMAIF_CH_ACIF_RX_CTRL, dai->id);
379 	}
380 
381 	cif_conf.mono_conv = admaif->mono_to_stereo[path][dai->id];
382 	cif_conf.stereo_conv = admaif->stereo_to_mono[path][dai->id];
383 
384 	tegra_admaif_set_pack_mode(admaif->regmap, reg, valid_bit);
385 
386 	if (admaif->soc_data->max_stream_ch == TEGRA264_ADMAIF_MAX_CHANNEL)
387 		tegra264_set_cif(admaif->regmap, reg, &cif_conf);
388 	else
389 		tegra_set_cif(admaif->regmap, reg, &cif_conf);
390 
391 	return 0;
392 }
393 
394 static int tegra_admaif_start(struct snd_soc_dai *dai, int direction)
395 {
396 	struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai);
397 	unsigned int reg, mask, val;
398 
399 	switch (direction) {
400 	case SNDRV_PCM_STREAM_PLAYBACK:
401 		mask = TX_ENABLE_MASK;
402 		val = TX_ENABLE;
403 		reg = CH_TX_REG(TEGRA_ADMAIF_TX_ENABLE, dai->id);
404 		break;
405 	case SNDRV_PCM_STREAM_CAPTURE:
406 		mask = RX_ENABLE_MASK;
407 		val = RX_ENABLE;
408 		reg = CH_RX_REG(TEGRA_ADMAIF_RX_ENABLE, dai->id);
409 		break;
410 	default:
411 		return -EINVAL;
412 	}
413 
414 	regmap_update_bits(admaif->regmap, reg, mask, val);
415 
416 	return 0;
417 }
418 
419 static int tegra_admaif_stop(struct snd_soc_dai *dai, int direction)
420 {
421 	struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai);
422 	unsigned int enable_reg, status_reg, reset_reg, mask, val;
423 	char *dir_name;
424 	int err, enable;
425 
426 	switch (direction) {
427 	case SNDRV_PCM_STREAM_PLAYBACK:
428 		mask = TX_ENABLE_MASK;
429 		enable = TX_ENABLE;
430 		dir_name = "TX";
431 		enable_reg = CH_TX_REG(TEGRA_ADMAIF_TX_ENABLE, dai->id);
432 		status_reg = CH_TX_REG(TEGRA_ADMAIF_TX_STATUS, dai->id);
433 		reset_reg = CH_TX_REG(TEGRA_ADMAIF_TX_SOFT_RESET, dai->id);
434 		break;
435 	case SNDRV_PCM_STREAM_CAPTURE:
436 		mask = RX_ENABLE_MASK;
437 		enable = RX_ENABLE;
438 		dir_name = "RX";
439 		enable_reg = CH_RX_REG(TEGRA_ADMAIF_RX_ENABLE, dai->id);
440 		status_reg = CH_RX_REG(TEGRA_ADMAIF_RX_STATUS, dai->id);
441 		reset_reg = CH_RX_REG(TEGRA_ADMAIF_RX_SOFT_RESET, dai->id);
442 		break;
443 	default:
444 		return -EINVAL;
445 	}
446 
447 	/* Disable TX/RX channel */
448 	regmap_update_bits(admaif->regmap, enable_reg, mask, ~enable);
449 
450 	/* Wait until ADMAIF TX/RX status is disabled */
451 	err = regmap_read_poll_timeout_atomic(admaif->regmap, status_reg, val,
452 					      !(val & enable), 10, 10000);
453 	if (err < 0)
454 		dev_warn(dai->dev, "timeout: failed to disable ADMAIF%d_%s\n",
455 			 dai->id + 1, dir_name);
456 
457 	/* SW reset */
458 	regmap_update_bits(admaif->regmap, reset_reg, SW_RESET_MASK, SW_RESET);
459 
460 	/* Wait till SW reset is complete */
461 	err = regmap_read_poll_timeout_atomic(admaif->regmap, reset_reg, val,
462 					      !(val & SW_RESET_MASK & SW_RESET),
463 					      10, 10000);
464 	if (err) {
465 		dev_err(dai->dev, "timeout: SW reset failed for ADMAIF%d_%s\n",
466 			dai->id + 1, dir_name);
467 		return err;
468 	}
469 
470 	return 0;
471 }
472 
473 static int tegra_admaif_trigger(struct snd_pcm_substream *substream, int cmd,
474 				struct snd_soc_dai *dai)
475 {
476 	int err;
477 
478 	err = snd_dmaengine_pcm_trigger(substream, cmd);
479 	if (err)
480 		return err;
481 
482 	switch (cmd) {
483 	case SNDRV_PCM_TRIGGER_START:
484 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
485 	case SNDRV_PCM_TRIGGER_RESUME:
486 		return tegra_admaif_start(dai, substream->stream);
487 	case SNDRV_PCM_TRIGGER_STOP:
488 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
489 	case SNDRV_PCM_TRIGGER_SUSPEND:
490 		return tegra_admaif_stop(dai, substream->stream);
491 	default:
492 		return -EINVAL;
493 	}
494 }
495 
496 static int tegra210_admaif_pget_mono_to_stereo(struct snd_kcontrol *kcontrol,
497 	struct snd_ctl_elem_value *ucontrol)
498 {
499 	struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
500 	struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
501 	struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
502 
503 	ucontrol->value.enumerated.item[0] =
504 		admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg];
505 
506 	return 0;
507 }
508 
509 static int tegra210_admaif_pput_mono_to_stereo(struct snd_kcontrol *kcontrol,
510 	struct snd_ctl_elem_value *ucontrol)
511 {
512 	struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
513 	struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
514 	struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
515 	unsigned int value = ucontrol->value.enumerated.item[0];
516 
517 	if (value == admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg])
518 		return 0;
519 
520 	admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value;
521 
522 	return 1;
523 }
524 
525 static int tegra210_admaif_cget_mono_to_stereo(struct snd_kcontrol *kcontrol,
526 	struct snd_ctl_elem_value *ucontrol)
527 {
528 	struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
529 	struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
530 	struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
531 
532 	ucontrol->value.enumerated.item[0] =
533 		admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg];
534 
535 	return 0;
536 }
537 
538 static int tegra210_admaif_cput_mono_to_stereo(struct snd_kcontrol *kcontrol,
539 	struct snd_ctl_elem_value *ucontrol)
540 {
541 	struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
542 	struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
543 	struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
544 	unsigned int value = ucontrol->value.enumerated.item[0];
545 
546 	if (value == admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg])
547 		return 0;
548 
549 	admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] = value;
550 
551 	return 1;
552 }
553 
554 static int tegra210_admaif_pget_stereo_to_mono(struct snd_kcontrol *kcontrol,
555 	struct snd_ctl_elem_value *ucontrol)
556 {
557 	struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
558 	struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
559 	struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
560 
561 	ucontrol->value.enumerated.item[0] =
562 		admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg];
563 
564 	return 0;
565 }
566 
567 static int tegra210_admaif_pput_stereo_to_mono(struct snd_kcontrol *kcontrol,
568 	struct snd_ctl_elem_value *ucontrol)
569 {
570 	struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
571 	struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
572 	struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
573 	unsigned int value = ucontrol->value.enumerated.item[0];
574 
575 	if (value == admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg])
576 		return 0;
577 
578 	admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] = value;
579 
580 	return 1;
581 }
582 
583 static int tegra210_admaif_cget_stereo_to_mono(struct snd_kcontrol *kcontrol,
584 	struct snd_ctl_elem_value *ucontrol)
585 {
586 	struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
587 	struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
588 	struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
589 
590 	ucontrol->value.enumerated.item[0] =
591 		admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg];
592 
593 	return 0;
594 }
595 
596 static int tegra210_admaif_cput_stereo_to_mono(struct snd_kcontrol *kcontrol,
597 	struct snd_ctl_elem_value *ucontrol)
598 {
599 	struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
600 	struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
601 	struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
602 	unsigned int value = ucontrol->value.enumerated.item[0];
603 
604 	if (value == admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg])
605 		return 0;
606 
607 	admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] = value;
608 
609 	return 1;
610 }
611 
612 static int tegra_admaif_dai_probe(struct snd_soc_dai *dai)
613 {
614 	struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai);
615 
616 	snd_soc_dai_init_dma_data(dai,	&admaif->playback_dma_data[dai->id],
617 					&admaif->capture_dma_data[dai->id]);
618 
619 	return 0;
620 }
621 
622 static const struct snd_soc_dai_ops tegra_admaif_dai_ops = {
623 	.probe		= tegra_admaif_dai_probe,
624 	.hw_params	= tegra_admaif_hw_params,
625 	.trigger	= tegra_admaif_trigger,
626 	.shutdown	= tegra_admaif_shutdown,
627 	.prepare	= tegra_admaif_prepare,
628 };
629 
630 #define DAI(dai_name, channel)					\
631 	{							\
632 		.name = dai_name,				\
633 		.playback = {					\
634 			.stream_name = dai_name " Playback",	\
635 			.channels_min = 1,			\
636 			.channels_max = channel,		\
637 			.rates = SNDRV_PCM_RATE_8000_192000,	\
638 			.formats = SNDRV_PCM_FMTBIT_S8 |	\
639 				SNDRV_PCM_FMTBIT_S16_LE |	\
640 				SNDRV_PCM_FMTBIT_S24_LE |	\
641 				SNDRV_PCM_FMTBIT_S32_LE,	\
642 		},						\
643 		.capture = {					\
644 			.stream_name = dai_name " Capture",	\
645 			.channels_min = 1,			\
646 			.channels_max = channel,		\
647 			.rates = SNDRV_PCM_RATE_8000_192000,	\
648 			.formats = SNDRV_PCM_FMTBIT_S8 |	\
649 				SNDRV_PCM_FMTBIT_S16_LE |	\
650 				SNDRV_PCM_FMTBIT_S24_LE |	\
651 				SNDRV_PCM_FMTBIT_S32_LE,	\
652 		},						\
653 		.ops = &tegra_admaif_dai_ops,			\
654 	}
655 
656 static struct snd_soc_dai_driver tegra210_admaif_cmpnt_dais[] = {
657 	DAI("ADMAIF1", TEGRA210_ADMAIF_MAX_CHANNEL),
658 	DAI("ADMAIF2", TEGRA210_ADMAIF_MAX_CHANNEL),
659 	DAI("ADMAIF3", TEGRA210_ADMAIF_MAX_CHANNEL),
660 	DAI("ADMAIF4", TEGRA210_ADMAIF_MAX_CHANNEL),
661 	DAI("ADMAIF5", TEGRA210_ADMAIF_MAX_CHANNEL),
662 	DAI("ADMAIF6", TEGRA210_ADMAIF_MAX_CHANNEL),
663 	DAI("ADMAIF7", TEGRA210_ADMAIF_MAX_CHANNEL),
664 	DAI("ADMAIF8", TEGRA210_ADMAIF_MAX_CHANNEL),
665 	DAI("ADMAIF9", TEGRA210_ADMAIF_MAX_CHANNEL),
666 	DAI("ADMAIF10", TEGRA210_ADMAIF_MAX_CHANNEL),
667 };
668 
669 static struct snd_soc_dai_driver tegra186_admaif_cmpnt_dais[] = {
670 	DAI("ADMAIF1", TEGRA186_ADMAIF_MAX_CHANNEL),
671 	DAI("ADMAIF2", TEGRA186_ADMAIF_MAX_CHANNEL),
672 	DAI("ADMAIF3", TEGRA186_ADMAIF_MAX_CHANNEL),
673 	DAI("ADMAIF4", TEGRA186_ADMAIF_MAX_CHANNEL),
674 	DAI("ADMAIF5", TEGRA186_ADMAIF_MAX_CHANNEL),
675 	DAI("ADMAIF6", TEGRA186_ADMAIF_MAX_CHANNEL),
676 	DAI("ADMAIF7", TEGRA186_ADMAIF_MAX_CHANNEL),
677 	DAI("ADMAIF8", TEGRA186_ADMAIF_MAX_CHANNEL),
678 	DAI("ADMAIF9", TEGRA186_ADMAIF_MAX_CHANNEL),
679 	DAI("ADMAIF10", TEGRA186_ADMAIF_MAX_CHANNEL),
680 	DAI("ADMAIF11", TEGRA186_ADMAIF_MAX_CHANNEL),
681 	DAI("ADMAIF12", TEGRA186_ADMAIF_MAX_CHANNEL),
682 	DAI("ADMAIF13", TEGRA186_ADMAIF_MAX_CHANNEL),
683 	DAI("ADMAIF14", TEGRA186_ADMAIF_MAX_CHANNEL),
684 	DAI("ADMAIF15", TEGRA186_ADMAIF_MAX_CHANNEL),
685 	DAI("ADMAIF16", TEGRA186_ADMAIF_MAX_CHANNEL),
686 	DAI("ADMAIF17", TEGRA186_ADMAIF_MAX_CHANNEL),
687 	DAI("ADMAIF18", TEGRA186_ADMAIF_MAX_CHANNEL),
688 	DAI("ADMAIF19", TEGRA186_ADMAIF_MAX_CHANNEL),
689 	DAI("ADMAIF20", TEGRA186_ADMAIF_MAX_CHANNEL),
690 };
691 
692 static struct snd_soc_dai_driver tegra264_admaif_cmpnt_dais[] = {
693 	DAI("ADMAIF1", TEGRA264_ADMAIF_MAX_CHANNEL),
694 	DAI("ADMAIF2", TEGRA264_ADMAIF_MAX_CHANNEL),
695 	DAI("ADMAIF3", TEGRA264_ADMAIF_MAX_CHANNEL),
696 	DAI("ADMAIF4", TEGRA264_ADMAIF_MAX_CHANNEL),
697 	DAI("ADMAIF5", TEGRA264_ADMAIF_MAX_CHANNEL),
698 	DAI("ADMAIF6", TEGRA264_ADMAIF_MAX_CHANNEL),
699 	DAI("ADMAIF7", TEGRA264_ADMAIF_MAX_CHANNEL),
700 	DAI("ADMAIF8", TEGRA264_ADMAIF_MAX_CHANNEL),
701 	DAI("ADMAIF9", TEGRA264_ADMAIF_MAX_CHANNEL),
702 	DAI("ADMAIF10", TEGRA264_ADMAIF_MAX_CHANNEL),
703 	DAI("ADMAIF11", TEGRA264_ADMAIF_MAX_CHANNEL),
704 	DAI("ADMAIF12", TEGRA264_ADMAIF_MAX_CHANNEL),
705 	DAI("ADMAIF13", TEGRA264_ADMAIF_MAX_CHANNEL),
706 	DAI("ADMAIF14", TEGRA264_ADMAIF_MAX_CHANNEL),
707 	DAI("ADMAIF15", TEGRA264_ADMAIF_MAX_CHANNEL),
708 	DAI("ADMAIF16", TEGRA264_ADMAIF_MAX_CHANNEL),
709 	DAI("ADMAIF17", TEGRA264_ADMAIF_MAX_CHANNEL),
710 	DAI("ADMAIF18", TEGRA264_ADMAIF_MAX_CHANNEL),
711 	DAI("ADMAIF19", TEGRA264_ADMAIF_MAX_CHANNEL),
712 	DAI("ADMAIF20", TEGRA264_ADMAIF_MAX_CHANNEL),
713 	DAI("ADMAIF21", TEGRA264_ADMAIF_MAX_CHANNEL),
714 	DAI("ADMAIF22", TEGRA264_ADMAIF_MAX_CHANNEL),
715 	DAI("ADMAIF23", TEGRA264_ADMAIF_MAX_CHANNEL),
716 	DAI("ADMAIF24", TEGRA264_ADMAIF_MAX_CHANNEL),
717 	DAI("ADMAIF25", TEGRA264_ADMAIF_MAX_CHANNEL),
718 	DAI("ADMAIF26", TEGRA264_ADMAIF_MAX_CHANNEL),
719 	DAI("ADMAIF27", TEGRA264_ADMAIF_MAX_CHANNEL),
720 	DAI("ADMAIF28", TEGRA264_ADMAIF_MAX_CHANNEL),
721 	DAI("ADMAIF29", TEGRA264_ADMAIF_MAX_CHANNEL),
722 	DAI("ADMAIF30", TEGRA264_ADMAIF_MAX_CHANNEL),
723 	DAI("ADMAIF31", TEGRA264_ADMAIF_MAX_CHANNEL),
724 	DAI("ADMAIF32", TEGRA264_ADMAIF_MAX_CHANNEL),
725 };
726 
727 static const char * const tegra_admaif_stereo_conv_text[] = {
728 	"CH0", "CH1", "AVG",
729 };
730 
731 static const char * const tegra_admaif_mono_conv_text[] = {
732 	"Zero", "Copy",
733 };
734 
735 /*
736  * Below macro is added to avoid looping over all ADMAIFx controls related
737  * to mono/stereo conversions in get()/put() callbacks.
738  */
739 #define NV_SOC_ENUM_EXT(xname, xreg, xhandler_get, xhandler_put, xenum_text)   \
740 {									       \
741 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,				       \
742 	.info = snd_soc_info_enum_double,				       \
743 	.name = xname,							       \
744 	.get = xhandler_get,						       \
745 	.put = xhandler_put,						       \
746 	.private_value = (unsigned long)&(struct soc_enum)		       \
747 		SOC_ENUM_SINGLE(xreg, 0, ARRAY_SIZE(xenum_text), xenum_text)   \
748 }
749 
750 #define TEGRA_ADMAIF_CIF_CTRL(reg)					       \
751 	NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Mono To Stereo", reg - 1,     \
752 			tegra210_admaif_pget_mono_to_stereo,		       \
753 			tegra210_admaif_pput_mono_to_stereo,		       \
754 			tegra_admaif_mono_conv_text),			       \
755 	NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Stereo To Mono", reg - 1,     \
756 			tegra210_admaif_pget_stereo_to_mono,		       \
757 			tegra210_admaif_pput_stereo_to_mono,		       \
758 			tegra_admaif_stereo_conv_text),			       \
759 	NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Mono To Stereo", reg - 1,      \
760 			tegra210_admaif_cget_mono_to_stereo,		       \
761 			tegra210_admaif_cput_mono_to_stereo,		       \
762 			tegra_admaif_mono_conv_text),			       \
763 	NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Stereo To Mono", reg - 1,      \
764 			tegra210_admaif_cget_stereo_to_mono,		       \
765 			tegra210_admaif_cput_stereo_to_mono,		       \
766 			tegra_admaif_stereo_conv_text)
767 
768 static struct snd_kcontrol_new tegra210_admaif_controls[] = {
769 	TEGRA_ADMAIF_CIF_CTRL(1),
770 	TEGRA_ADMAIF_CIF_CTRL(2),
771 	TEGRA_ADMAIF_CIF_CTRL(3),
772 	TEGRA_ADMAIF_CIF_CTRL(4),
773 	TEGRA_ADMAIF_CIF_CTRL(5),
774 	TEGRA_ADMAIF_CIF_CTRL(6),
775 	TEGRA_ADMAIF_CIF_CTRL(7),
776 	TEGRA_ADMAIF_CIF_CTRL(8),
777 	TEGRA_ADMAIF_CIF_CTRL(9),
778 	TEGRA_ADMAIF_CIF_CTRL(10),
779 };
780 
781 static struct snd_kcontrol_new tegra186_admaif_controls[] = {
782 	TEGRA_ADMAIF_CIF_CTRL(1),
783 	TEGRA_ADMAIF_CIF_CTRL(2),
784 	TEGRA_ADMAIF_CIF_CTRL(3),
785 	TEGRA_ADMAIF_CIF_CTRL(4),
786 	TEGRA_ADMAIF_CIF_CTRL(5),
787 	TEGRA_ADMAIF_CIF_CTRL(6),
788 	TEGRA_ADMAIF_CIF_CTRL(7),
789 	TEGRA_ADMAIF_CIF_CTRL(8),
790 	TEGRA_ADMAIF_CIF_CTRL(9),
791 	TEGRA_ADMAIF_CIF_CTRL(10),
792 	TEGRA_ADMAIF_CIF_CTRL(11),
793 	TEGRA_ADMAIF_CIF_CTRL(12),
794 	TEGRA_ADMAIF_CIF_CTRL(13),
795 	TEGRA_ADMAIF_CIF_CTRL(14),
796 	TEGRA_ADMAIF_CIF_CTRL(15),
797 	TEGRA_ADMAIF_CIF_CTRL(16),
798 	TEGRA_ADMAIF_CIF_CTRL(17),
799 	TEGRA_ADMAIF_CIF_CTRL(18),
800 	TEGRA_ADMAIF_CIF_CTRL(19),
801 	TEGRA_ADMAIF_CIF_CTRL(20),
802 };
803 
804 static struct snd_kcontrol_new tegra264_admaif_controls[] = {
805 	TEGRA_ADMAIF_CIF_CTRL(1),
806 	TEGRA_ADMAIF_CIF_CTRL(2),
807 	TEGRA_ADMAIF_CIF_CTRL(3),
808 	TEGRA_ADMAIF_CIF_CTRL(4),
809 	TEGRA_ADMAIF_CIF_CTRL(5),
810 	TEGRA_ADMAIF_CIF_CTRL(6),
811 	TEGRA_ADMAIF_CIF_CTRL(7),
812 	TEGRA_ADMAIF_CIF_CTRL(8),
813 	TEGRA_ADMAIF_CIF_CTRL(9),
814 	TEGRA_ADMAIF_CIF_CTRL(10),
815 	TEGRA_ADMAIF_CIF_CTRL(11),
816 	TEGRA_ADMAIF_CIF_CTRL(12),
817 	TEGRA_ADMAIF_CIF_CTRL(13),
818 	TEGRA_ADMAIF_CIF_CTRL(14),
819 	TEGRA_ADMAIF_CIF_CTRL(15),
820 	TEGRA_ADMAIF_CIF_CTRL(16),
821 	TEGRA_ADMAIF_CIF_CTRL(17),
822 	TEGRA_ADMAIF_CIF_CTRL(18),
823 	TEGRA_ADMAIF_CIF_CTRL(19),
824 	TEGRA_ADMAIF_CIF_CTRL(20),
825 	TEGRA_ADMAIF_CIF_CTRL(21),
826 	TEGRA_ADMAIF_CIF_CTRL(22),
827 	TEGRA_ADMAIF_CIF_CTRL(23),
828 	TEGRA_ADMAIF_CIF_CTRL(24),
829 	TEGRA_ADMAIF_CIF_CTRL(25),
830 	TEGRA_ADMAIF_CIF_CTRL(26),
831 	TEGRA_ADMAIF_CIF_CTRL(27),
832 	TEGRA_ADMAIF_CIF_CTRL(28),
833 	TEGRA_ADMAIF_CIF_CTRL(29),
834 	TEGRA_ADMAIF_CIF_CTRL(30),
835 	TEGRA_ADMAIF_CIF_CTRL(31),
836 	TEGRA_ADMAIF_CIF_CTRL(32),
837 };
838 
839 static const struct snd_soc_component_driver tegra210_admaif_cmpnt = {
840 	.controls		= tegra210_admaif_controls,
841 	.num_controls		= ARRAY_SIZE(tegra210_admaif_controls),
842 	.pcm_construct		= tegra_pcm_construct,
843 	.open			= tegra_pcm_open,
844 	.close			= tegra_pcm_close,
845 	.hw_params		= tegra_pcm_hw_params,
846 	.pointer		= tegra_pcm_pointer,
847 };
848 
849 static const struct snd_soc_component_driver tegra186_admaif_cmpnt = {
850 	.controls		= tegra186_admaif_controls,
851 	.num_controls		= ARRAY_SIZE(tegra186_admaif_controls),
852 	.pcm_construct		= tegra_pcm_construct,
853 	.open			= tegra_pcm_open,
854 	.close			= tegra_pcm_close,
855 	.hw_params		= tegra_pcm_hw_params,
856 	.pointer		= tegra_pcm_pointer,
857 };
858 
859 static const struct snd_soc_component_driver tegra264_admaif_cmpnt = {
860 	.controls		= tegra264_admaif_controls,
861 	.num_controls		= ARRAY_SIZE(tegra264_admaif_controls),
862 	.pcm_construct		= tegra_pcm_construct,
863 	.open			= tegra_pcm_open,
864 	.close			= tegra_pcm_close,
865 	.hw_params		= tegra_pcm_hw_params,
866 	.pointer		= tegra_pcm_pointer,
867 };
868 
869 static const struct tegra_admaif_soc_data soc_data_tegra210 = {
870 	.num_ch		= TEGRA210_ADMAIF_CHANNEL_COUNT,
871 	.max_stream_ch	= TEGRA210_ADMAIF_MAX_CHANNEL,
872 	.cmpnt		= &tegra210_admaif_cmpnt,
873 	.dais		= tegra210_admaif_cmpnt_dais,
874 	.regmap_conf	= &tegra210_admaif_regmap_config,
875 	.global_base	= TEGRA210_ADMAIF_GLOBAL_BASE,
876 	.tx_base	= TEGRA210_ADMAIF_TX_BASE,
877 	.rx_base	= TEGRA210_ADMAIF_RX_BASE,
878 };
879 
880 static const struct tegra_admaif_soc_data soc_data_tegra186 = {
881 	.num_ch		= TEGRA186_ADMAIF_CHANNEL_COUNT,
882 	.max_stream_ch	= TEGRA186_ADMAIF_MAX_CHANNEL,
883 	.cmpnt		= &tegra186_admaif_cmpnt,
884 	.dais		= tegra186_admaif_cmpnt_dais,
885 	.regmap_conf	= &tegra186_admaif_regmap_config,
886 	.global_base	= TEGRA186_ADMAIF_GLOBAL_BASE,
887 	.tx_base	= TEGRA186_ADMAIF_TX_BASE,
888 	.rx_base	= TEGRA186_ADMAIF_RX_BASE,
889 };
890 
891 static const struct tegra_admaif_soc_data soc_data_tegra264 = {
892 	.num_ch		= TEGRA264_ADMAIF_CHANNEL_COUNT,
893 	.max_stream_ch	= TEGRA264_ADMAIF_MAX_CHANNEL,
894 	.cmpnt		= &tegra264_admaif_cmpnt,
895 	.dais		= tegra264_admaif_cmpnt_dais,
896 	.regmap_conf	= &tegra264_admaif_regmap_config,
897 	.global_base	= TEGRA264_ADMAIF_GLOBAL_BASE,
898 	.tx_base	= TEGRA264_ADMAIF_TX_BASE,
899 	.rx_base	= TEGRA264_ADMAIF_RX_BASE,
900 };
901 
902 static const struct of_device_id tegra_admaif_of_match[] = {
903 	{ .compatible = "nvidia,tegra210-admaif", .data = &soc_data_tegra210 },
904 	{ .compatible = "nvidia,tegra186-admaif", .data = &soc_data_tegra186 },
905 	{ .compatible = "nvidia,tegra264-admaif", .data = &soc_data_tegra264 },
906 	{},
907 };
908 MODULE_DEVICE_TABLE(of, tegra_admaif_of_match);
909 
910 static int tegra_admaif_probe(struct platform_device *pdev)
911 {
912 	struct tegra_admaif *admaif;
913 	void __iomem *regs;
914 	struct resource *res;
915 	int err, i;
916 
917 	admaif = devm_kzalloc(&pdev->dev, sizeof(*admaif), GFP_KERNEL);
918 	if (!admaif)
919 		return -ENOMEM;
920 
921 	admaif->soc_data = of_device_get_match_data(&pdev->dev);
922 
923 	dev_set_drvdata(&pdev->dev, admaif);
924 
925 	admaif->capture_dma_data =
926 		devm_kcalloc(&pdev->dev,
927 			     admaif->soc_data->num_ch,
928 			     sizeof(struct snd_dmaengine_dai_dma_data),
929 			     GFP_KERNEL);
930 	if (!admaif->capture_dma_data)
931 		return -ENOMEM;
932 
933 	admaif->playback_dma_data =
934 		devm_kcalloc(&pdev->dev,
935 			     admaif->soc_data->num_ch,
936 			     sizeof(struct snd_dmaengine_dai_dma_data),
937 			     GFP_KERNEL);
938 	if (!admaif->playback_dma_data)
939 		return -ENOMEM;
940 
941 	for (i = 0; i < ADMAIF_PATHS; i++) {
942 		admaif->mono_to_stereo[i] =
943 			devm_kcalloc(&pdev->dev, admaif->soc_data->num_ch,
944 				     sizeof(unsigned int), GFP_KERNEL);
945 		if (!admaif->mono_to_stereo[i])
946 			return -ENOMEM;
947 
948 		admaif->stereo_to_mono[i] =
949 			devm_kcalloc(&pdev->dev, admaif->soc_data->num_ch,
950 				     sizeof(unsigned int), GFP_KERNEL);
951 		if (!admaif->stereo_to_mono[i])
952 			return -ENOMEM;
953 	}
954 
955 	regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
956 	if (IS_ERR(regs))
957 		return PTR_ERR(regs);
958 
959 	admaif->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
960 					       admaif->soc_data->regmap_conf);
961 	if (IS_ERR(admaif->regmap)) {
962 		dev_err(&pdev->dev, "regmap init failed\n");
963 		return PTR_ERR(admaif->regmap);
964 	}
965 
966 	regcache_cache_only(admaif->regmap, true);
967 
968 	err = tegra_isomgr_adma_register(&pdev->dev);
969 	if (err) {
970 		dev_err(&pdev->dev, "Failed to add interconnect path\n");
971 		return err;
972 	}
973 
974 	regmap_update_bits(admaif->regmap, admaif->soc_data->global_base +
975 			   TEGRA_ADMAIF_GLOBAL_ENABLE, 1, 1);
976 
977 	for (i = 0; i < admaif->soc_data->num_ch; i++) {
978 		admaif->playback_dma_data[i].addr = res->start +
979 			CH_TX_REG(TEGRA_ADMAIF_TX_FIFO_WRITE, i);
980 
981 		admaif->capture_dma_data[i].addr = res->start +
982 			CH_RX_REG(TEGRA_ADMAIF_RX_FIFO_READ, i);
983 
984 		admaif->playback_dma_data[i].addr_width = 32;
985 
986 		if (of_property_read_string_index(pdev->dev.of_node,
987 				"dma-names", (i * 2) + 1,
988 				&admaif->playback_dma_data[i].chan_name) < 0) {
989 			dev_err(&pdev->dev,
990 				"missing property nvidia,dma-names\n");
991 
992 			return -ENODEV;
993 		}
994 
995 		admaif->capture_dma_data[i].addr_width = 32;
996 
997 		if (of_property_read_string_index(pdev->dev.of_node,
998 				"dma-names",
999 				(i * 2),
1000 				&admaif->capture_dma_data[i].chan_name) < 0) {
1001 			dev_err(&pdev->dev,
1002 				"missing property nvidia,dma-names\n");
1003 
1004 			return -ENODEV;
1005 		}
1006 	}
1007 
1008 	err = devm_snd_soc_register_component(&pdev->dev,
1009 					      admaif->soc_data->cmpnt,
1010 					      admaif->soc_data->dais,
1011 					      admaif->soc_data->num_ch);
1012 	if (err) {
1013 		dev_err(&pdev->dev,
1014 			"can't register ADMAIF component, err: %d\n", err);
1015 		return err;
1016 	}
1017 
1018 	pm_runtime_enable(&pdev->dev);
1019 
1020 	return 0;
1021 }
1022 
1023 static void tegra_admaif_remove(struct platform_device *pdev)
1024 {
1025 	tegra_isomgr_adma_unregister(&pdev->dev);
1026 	pm_runtime_disable(&pdev->dev);
1027 }
1028 
1029 static const struct dev_pm_ops tegra_admaif_pm_ops = {
1030 	RUNTIME_PM_OPS(tegra_admaif_runtime_suspend,
1031 		       tegra_admaif_runtime_resume, NULL)
1032 	SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
1033 };
1034 
1035 static struct platform_driver tegra_admaif_driver = {
1036 	.probe = tegra_admaif_probe,
1037 	.remove = tegra_admaif_remove,
1038 	.driver = {
1039 		.name = "tegra210-admaif",
1040 		.of_match_table = tegra_admaif_of_match,
1041 		.pm = pm_ptr(&tegra_admaif_pm_ops),
1042 	},
1043 };
1044 module_platform_driver(tegra_admaif_driver);
1045 
1046 MODULE_AUTHOR("Songhee Baek <sbaek@nvidia.com>");
1047 MODULE_DESCRIPTION("Tegra210 ASoC ADMAIF driver");
1048 MODULE_LICENSE("GPL v2");
1049