xref: /linux/sound/soc/tegra/tegra210_admaif.c (revision 0fc8f6200d2313278fbf4539bbab74677c685531)
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 		dev_err(dai->dev, "invalid stream direction: %d\n", direction);
412 		return -EINVAL;
413 	}
414 
415 	regmap_update_bits(admaif->regmap, reg, mask, val);
416 
417 	return 0;
418 }
419 
420 static int tegra_admaif_stop(struct snd_soc_dai *dai, int direction)
421 {
422 	struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai);
423 	unsigned int enable_reg, status_reg, reset_reg, mask, val;
424 	char *dir_name;
425 	int err, enable;
426 
427 	switch (direction) {
428 	case SNDRV_PCM_STREAM_PLAYBACK:
429 		mask = TX_ENABLE_MASK;
430 		enable = TX_ENABLE;
431 		dir_name = "TX";
432 		enable_reg = CH_TX_REG(TEGRA_ADMAIF_TX_ENABLE, dai->id);
433 		status_reg = CH_TX_REG(TEGRA_ADMAIF_TX_STATUS, dai->id);
434 		reset_reg = CH_TX_REG(TEGRA_ADMAIF_TX_SOFT_RESET, dai->id);
435 		break;
436 	case SNDRV_PCM_STREAM_CAPTURE:
437 		mask = RX_ENABLE_MASK;
438 		enable = RX_ENABLE;
439 		dir_name = "RX";
440 		enable_reg = CH_RX_REG(TEGRA_ADMAIF_RX_ENABLE, dai->id);
441 		status_reg = CH_RX_REG(TEGRA_ADMAIF_RX_STATUS, dai->id);
442 		reset_reg = CH_RX_REG(TEGRA_ADMAIF_RX_SOFT_RESET, dai->id);
443 		break;
444 	default:
445 		dev_err(dai->dev, "invalid stream direction: %d\n", direction);
446 		return -EINVAL;
447 	}
448 
449 	/* Disable TX/RX channel */
450 	regmap_update_bits(admaif->regmap, enable_reg, mask, ~enable);
451 
452 	/* Wait until ADMAIF TX/RX status is disabled */
453 	err = regmap_read_poll_timeout_atomic(admaif->regmap, status_reg, val,
454 					      !(val & enable), 10, 10000);
455 	if (err < 0)
456 		dev_warn(dai->dev, "timeout: failed to disable ADMAIF%d_%s\n",
457 			 dai->id + 1, dir_name);
458 
459 	/* SW reset */
460 	regmap_update_bits(admaif->regmap, reset_reg, SW_RESET_MASK, SW_RESET);
461 
462 	/* Wait till SW reset is complete */
463 	err = regmap_read_poll_timeout_atomic(admaif->regmap, reset_reg, val,
464 					      !(val & SW_RESET_MASK & SW_RESET),
465 					      10, 10000);
466 	if (err) {
467 		dev_err(dai->dev, "timeout: SW reset failed for ADMAIF%d_%s\n",
468 			dai->id + 1, dir_name);
469 		return err;
470 	}
471 
472 	return 0;
473 }
474 
475 static int tegra_admaif_trigger(struct snd_pcm_substream *substream, int cmd,
476 				struct snd_soc_dai *dai)
477 {
478 	int err;
479 
480 	err = snd_dmaengine_pcm_trigger(substream, cmd);
481 	if (err)
482 		return err;
483 
484 	switch (cmd) {
485 	case SNDRV_PCM_TRIGGER_START:
486 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
487 	case SNDRV_PCM_TRIGGER_RESUME:
488 		return tegra_admaif_start(dai, substream->stream);
489 	case SNDRV_PCM_TRIGGER_STOP:
490 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
491 	case SNDRV_PCM_TRIGGER_SUSPEND:
492 		return tegra_admaif_stop(dai, substream->stream);
493 	default:
494 		dev_err(dai->dev, "invalid trigger command: %d\n", cmd);
495 		return -EINVAL;
496 	}
497 }
498 
499 static int tegra210_admaif_pget_mono_to_stereo(struct snd_kcontrol *kcontrol,
500 	struct snd_ctl_elem_value *ucontrol)
501 {
502 	struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
503 	struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
504 	struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
505 
506 	ucontrol->value.enumerated.item[0] =
507 		admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg];
508 
509 	return 0;
510 }
511 
512 static int tegra210_admaif_pput_mono_to_stereo(struct snd_kcontrol *kcontrol,
513 	struct snd_ctl_elem_value *ucontrol)
514 {
515 	struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
516 	struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
517 	struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
518 	unsigned int value = ucontrol->value.enumerated.item[0];
519 
520 	if (value == admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg])
521 		return 0;
522 
523 	admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value;
524 
525 	return 1;
526 }
527 
528 static int tegra210_admaif_cget_mono_to_stereo(struct snd_kcontrol *kcontrol,
529 	struct snd_ctl_elem_value *ucontrol)
530 {
531 	struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
532 	struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
533 	struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
534 
535 	ucontrol->value.enumerated.item[0] =
536 		admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg];
537 
538 	return 0;
539 }
540 
541 static int tegra210_admaif_cput_mono_to_stereo(struct snd_kcontrol *kcontrol,
542 	struct snd_ctl_elem_value *ucontrol)
543 {
544 	struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
545 	struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
546 	struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
547 	unsigned int value = ucontrol->value.enumerated.item[0];
548 
549 	if (value == admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg])
550 		return 0;
551 
552 	admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] = value;
553 
554 	return 1;
555 }
556 
557 static int tegra210_admaif_pget_stereo_to_mono(struct snd_kcontrol *kcontrol,
558 	struct snd_ctl_elem_value *ucontrol)
559 {
560 	struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
561 	struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
562 	struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
563 
564 	ucontrol->value.enumerated.item[0] =
565 		admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg];
566 
567 	return 0;
568 }
569 
570 static int tegra210_admaif_pput_stereo_to_mono(struct snd_kcontrol *kcontrol,
571 	struct snd_ctl_elem_value *ucontrol)
572 {
573 	struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
574 	struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
575 	struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
576 	unsigned int value = ucontrol->value.enumerated.item[0];
577 
578 	if (value == admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg])
579 		return 0;
580 
581 	admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] = value;
582 
583 	return 1;
584 }
585 
586 static int tegra210_admaif_cget_stereo_to_mono(struct snd_kcontrol *kcontrol,
587 	struct snd_ctl_elem_value *ucontrol)
588 {
589 	struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
590 	struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
591 	struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
592 
593 	ucontrol->value.enumerated.item[0] =
594 		admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg];
595 
596 	return 0;
597 }
598 
599 static int tegra210_admaif_cput_stereo_to_mono(struct snd_kcontrol *kcontrol,
600 	struct snd_ctl_elem_value *ucontrol)
601 {
602 	struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
603 	struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
604 	struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
605 	unsigned int value = ucontrol->value.enumerated.item[0];
606 
607 	if (value == admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg])
608 		return 0;
609 
610 	admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] = value;
611 
612 	return 1;
613 }
614 
615 static int tegra_admaif_dai_probe(struct snd_soc_dai *dai)
616 {
617 	struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai);
618 
619 	snd_soc_dai_init_dma_data(dai,	&admaif->playback_dma_data[dai->id],
620 					&admaif->capture_dma_data[dai->id]);
621 
622 	return 0;
623 }
624 
625 static const struct snd_soc_dai_ops tegra_admaif_dai_ops = {
626 	.probe		= tegra_admaif_dai_probe,
627 	.hw_params	= tegra_admaif_hw_params,
628 	.trigger	= tegra_admaif_trigger,
629 	.shutdown	= tegra_admaif_shutdown,
630 	.prepare	= tegra_admaif_prepare,
631 };
632 
633 #define DAI(dai_name, channel)					\
634 	{							\
635 		.name = dai_name,				\
636 		.playback = {					\
637 			.stream_name = dai_name " Playback",	\
638 			.channels_min = 1,			\
639 			.channels_max = channel,		\
640 			.rates = SNDRV_PCM_RATE_8000_192000,	\
641 			.formats = SNDRV_PCM_FMTBIT_S8 |	\
642 				SNDRV_PCM_FMTBIT_S16_LE |	\
643 				SNDRV_PCM_FMTBIT_S24_LE |	\
644 				SNDRV_PCM_FMTBIT_S32_LE,	\
645 		},						\
646 		.capture = {					\
647 			.stream_name = dai_name " Capture",	\
648 			.channels_min = 1,			\
649 			.channels_max = channel,		\
650 			.rates = SNDRV_PCM_RATE_8000_192000,	\
651 			.formats = SNDRV_PCM_FMTBIT_S8 |	\
652 				SNDRV_PCM_FMTBIT_S16_LE |	\
653 				SNDRV_PCM_FMTBIT_S24_LE |	\
654 				SNDRV_PCM_FMTBIT_S32_LE,	\
655 		},						\
656 		.ops = &tegra_admaif_dai_ops,			\
657 	}
658 
659 static struct snd_soc_dai_driver tegra210_admaif_cmpnt_dais[] = {
660 	DAI("ADMAIF1", TEGRA210_ADMAIF_MAX_CHANNEL),
661 	DAI("ADMAIF2", TEGRA210_ADMAIF_MAX_CHANNEL),
662 	DAI("ADMAIF3", TEGRA210_ADMAIF_MAX_CHANNEL),
663 	DAI("ADMAIF4", TEGRA210_ADMAIF_MAX_CHANNEL),
664 	DAI("ADMAIF5", TEGRA210_ADMAIF_MAX_CHANNEL),
665 	DAI("ADMAIF6", TEGRA210_ADMAIF_MAX_CHANNEL),
666 	DAI("ADMAIF7", TEGRA210_ADMAIF_MAX_CHANNEL),
667 	DAI("ADMAIF8", TEGRA210_ADMAIF_MAX_CHANNEL),
668 	DAI("ADMAIF9", TEGRA210_ADMAIF_MAX_CHANNEL),
669 	DAI("ADMAIF10", TEGRA210_ADMAIF_MAX_CHANNEL),
670 };
671 
672 static struct snd_soc_dai_driver tegra186_admaif_cmpnt_dais[] = {
673 	DAI("ADMAIF1", TEGRA186_ADMAIF_MAX_CHANNEL),
674 	DAI("ADMAIF2", TEGRA186_ADMAIF_MAX_CHANNEL),
675 	DAI("ADMAIF3", TEGRA186_ADMAIF_MAX_CHANNEL),
676 	DAI("ADMAIF4", TEGRA186_ADMAIF_MAX_CHANNEL),
677 	DAI("ADMAIF5", TEGRA186_ADMAIF_MAX_CHANNEL),
678 	DAI("ADMAIF6", TEGRA186_ADMAIF_MAX_CHANNEL),
679 	DAI("ADMAIF7", TEGRA186_ADMAIF_MAX_CHANNEL),
680 	DAI("ADMAIF8", TEGRA186_ADMAIF_MAX_CHANNEL),
681 	DAI("ADMAIF9", TEGRA186_ADMAIF_MAX_CHANNEL),
682 	DAI("ADMAIF10", TEGRA186_ADMAIF_MAX_CHANNEL),
683 	DAI("ADMAIF11", TEGRA186_ADMAIF_MAX_CHANNEL),
684 	DAI("ADMAIF12", TEGRA186_ADMAIF_MAX_CHANNEL),
685 	DAI("ADMAIF13", TEGRA186_ADMAIF_MAX_CHANNEL),
686 	DAI("ADMAIF14", TEGRA186_ADMAIF_MAX_CHANNEL),
687 	DAI("ADMAIF15", TEGRA186_ADMAIF_MAX_CHANNEL),
688 	DAI("ADMAIF16", TEGRA186_ADMAIF_MAX_CHANNEL),
689 	DAI("ADMAIF17", TEGRA186_ADMAIF_MAX_CHANNEL),
690 	DAI("ADMAIF18", TEGRA186_ADMAIF_MAX_CHANNEL),
691 	DAI("ADMAIF19", TEGRA186_ADMAIF_MAX_CHANNEL),
692 	DAI("ADMAIF20", TEGRA186_ADMAIF_MAX_CHANNEL),
693 };
694 
695 static struct snd_soc_dai_driver tegra264_admaif_cmpnt_dais[] = {
696 	DAI("ADMAIF1", TEGRA264_ADMAIF_MAX_CHANNEL),
697 	DAI("ADMAIF2", TEGRA264_ADMAIF_MAX_CHANNEL),
698 	DAI("ADMAIF3", TEGRA264_ADMAIF_MAX_CHANNEL),
699 	DAI("ADMAIF4", TEGRA264_ADMAIF_MAX_CHANNEL),
700 	DAI("ADMAIF5", TEGRA264_ADMAIF_MAX_CHANNEL),
701 	DAI("ADMAIF6", TEGRA264_ADMAIF_MAX_CHANNEL),
702 	DAI("ADMAIF7", TEGRA264_ADMAIF_MAX_CHANNEL),
703 	DAI("ADMAIF8", TEGRA264_ADMAIF_MAX_CHANNEL),
704 	DAI("ADMAIF9", TEGRA264_ADMAIF_MAX_CHANNEL),
705 	DAI("ADMAIF10", TEGRA264_ADMAIF_MAX_CHANNEL),
706 	DAI("ADMAIF11", TEGRA264_ADMAIF_MAX_CHANNEL),
707 	DAI("ADMAIF12", TEGRA264_ADMAIF_MAX_CHANNEL),
708 	DAI("ADMAIF13", TEGRA264_ADMAIF_MAX_CHANNEL),
709 	DAI("ADMAIF14", TEGRA264_ADMAIF_MAX_CHANNEL),
710 	DAI("ADMAIF15", TEGRA264_ADMAIF_MAX_CHANNEL),
711 	DAI("ADMAIF16", TEGRA264_ADMAIF_MAX_CHANNEL),
712 	DAI("ADMAIF17", TEGRA264_ADMAIF_MAX_CHANNEL),
713 	DAI("ADMAIF18", TEGRA264_ADMAIF_MAX_CHANNEL),
714 	DAI("ADMAIF19", TEGRA264_ADMAIF_MAX_CHANNEL),
715 	DAI("ADMAIF20", TEGRA264_ADMAIF_MAX_CHANNEL),
716 	DAI("ADMAIF21", TEGRA264_ADMAIF_MAX_CHANNEL),
717 	DAI("ADMAIF22", TEGRA264_ADMAIF_MAX_CHANNEL),
718 	DAI("ADMAIF23", TEGRA264_ADMAIF_MAX_CHANNEL),
719 	DAI("ADMAIF24", TEGRA264_ADMAIF_MAX_CHANNEL),
720 	DAI("ADMAIF25", TEGRA264_ADMAIF_MAX_CHANNEL),
721 	DAI("ADMAIF26", TEGRA264_ADMAIF_MAX_CHANNEL),
722 	DAI("ADMAIF27", TEGRA264_ADMAIF_MAX_CHANNEL),
723 	DAI("ADMAIF28", TEGRA264_ADMAIF_MAX_CHANNEL),
724 	DAI("ADMAIF29", TEGRA264_ADMAIF_MAX_CHANNEL),
725 	DAI("ADMAIF30", TEGRA264_ADMAIF_MAX_CHANNEL),
726 	DAI("ADMAIF31", TEGRA264_ADMAIF_MAX_CHANNEL),
727 	DAI("ADMAIF32", TEGRA264_ADMAIF_MAX_CHANNEL),
728 };
729 
730 static const char * const tegra_admaif_stereo_conv_text[] = {
731 	"CH0", "CH1", "AVG",
732 };
733 
734 static const char * const tegra_admaif_mono_conv_text[] = {
735 	"Zero", "Copy",
736 };
737 
738 /*
739  * Below macro is added to avoid looping over all ADMAIFx controls related
740  * to mono/stereo conversions in get()/put() callbacks.
741  */
742 #define NV_SOC_ENUM_EXT(xname, xreg, xhandler_get, xhandler_put, xenum_text)   \
743 {									       \
744 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,				       \
745 	.info = snd_soc_info_enum_double,				       \
746 	.name = xname,							       \
747 	.get = xhandler_get,						       \
748 	.put = xhandler_put,						       \
749 	.private_value = (unsigned long)&(struct soc_enum)		       \
750 		SOC_ENUM_SINGLE(xreg, 0, ARRAY_SIZE(xenum_text), xenum_text)   \
751 }
752 
753 #define TEGRA_ADMAIF_CIF_CTRL(reg)					       \
754 	NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Mono To Stereo", reg - 1,     \
755 			tegra210_admaif_pget_mono_to_stereo,		       \
756 			tegra210_admaif_pput_mono_to_stereo,		       \
757 			tegra_admaif_mono_conv_text),			       \
758 	NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Stereo To Mono", reg - 1,     \
759 			tegra210_admaif_pget_stereo_to_mono,		       \
760 			tegra210_admaif_pput_stereo_to_mono,		       \
761 			tegra_admaif_stereo_conv_text),			       \
762 	NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Mono To Stereo", reg - 1,      \
763 			tegra210_admaif_cget_mono_to_stereo,		       \
764 			tegra210_admaif_cput_mono_to_stereo,		       \
765 			tegra_admaif_mono_conv_text),			       \
766 	NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Stereo To Mono", reg - 1,      \
767 			tegra210_admaif_cget_stereo_to_mono,		       \
768 			tegra210_admaif_cput_stereo_to_mono,		       \
769 			tegra_admaif_stereo_conv_text)
770 
771 static struct snd_kcontrol_new tegra210_admaif_controls[] = {
772 	TEGRA_ADMAIF_CIF_CTRL(1),
773 	TEGRA_ADMAIF_CIF_CTRL(2),
774 	TEGRA_ADMAIF_CIF_CTRL(3),
775 	TEGRA_ADMAIF_CIF_CTRL(4),
776 	TEGRA_ADMAIF_CIF_CTRL(5),
777 	TEGRA_ADMAIF_CIF_CTRL(6),
778 	TEGRA_ADMAIF_CIF_CTRL(7),
779 	TEGRA_ADMAIF_CIF_CTRL(8),
780 	TEGRA_ADMAIF_CIF_CTRL(9),
781 	TEGRA_ADMAIF_CIF_CTRL(10),
782 };
783 
784 static struct snd_kcontrol_new tegra186_admaif_controls[] = {
785 	TEGRA_ADMAIF_CIF_CTRL(1),
786 	TEGRA_ADMAIF_CIF_CTRL(2),
787 	TEGRA_ADMAIF_CIF_CTRL(3),
788 	TEGRA_ADMAIF_CIF_CTRL(4),
789 	TEGRA_ADMAIF_CIF_CTRL(5),
790 	TEGRA_ADMAIF_CIF_CTRL(6),
791 	TEGRA_ADMAIF_CIF_CTRL(7),
792 	TEGRA_ADMAIF_CIF_CTRL(8),
793 	TEGRA_ADMAIF_CIF_CTRL(9),
794 	TEGRA_ADMAIF_CIF_CTRL(10),
795 	TEGRA_ADMAIF_CIF_CTRL(11),
796 	TEGRA_ADMAIF_CIF_CTRL(12),
797 	TEGRA_ADMAIF_CIF_CTRL(13),
798 	TEGRA_ADMAIF_CIF_CTRL(14),
799 	TEGRA_ADMAIF_CIF_CTRL(15),
800 	TEGRA_ADMAIF_CIF_CTRL(16),
801 	TEGRA_ADMAIF_CIF_CTRL(17),
802 	TEGRA_ADMAIF_CIF_CTRL(18),
803 	TEGRA_ADMAIF_CIF_CTRL(19),
804 	TEGRA_ADMAIF_CIF_CTRL(20),
805 };
806 
807 static struct snd_kcontrol_new tegra264_admaif_controls[] = {
808 	TEGRA_ADMAIF_CIF_CTRL(1),
809 	TEGRA_ADMAIF_CIF_CTRL(2),
810 	TEGRA_ADMAIF_CIF_CTRL(3),
811 	TEGRA_ADMAIF_CIF_CTRL(4),
812 	TEGRA_ADMAIF_CIF_CTRL(5),
813 	TEGRA_ADMAIF_CIF_CTRL(6),
814 	TEGRA_ADMAIF_CIF_CTRL(7),
815 	TEGRA_ADMAIF_CIF_CTRL(8),
816 	TEGRA_ADMAIF_CIF_CTRL(9),
817 	TEGRA_ADMAIF_CIF_CTRL(10),
818 	TEGRA_ADMAIF_CIF_CTRL(11),
819 	TEGRA_ADMAIF_CIF_CTRL(12),
820 	TEGRA_ADMAIF_CIF_CTRL(13),
821 	TEGRA_ADMAIF_CIF_CTRL(14),
822 	TEGRA_ADMAIF_CIF_CTRL(15),
823 	TEGRA_ADMAIF_CIF_CTRL(16),
824 	TEGRA_ADMAIF_CIF_CTRL(17),
825 	TEGRA_ADMAIF_CIF_CTRL(18),
826 	TEGRA_ADMAIF_CIF_CTRL(19),
827 	TEGRA_ADMAIF_CIF_CTRL(20),
828 	TEGRA_ADMAIF_CIF_CTRL(21),
829 	TEGRA_ADMAIF_CIF_CTRL(22),
830 	TEGRA_ADMAIF_CIF_CTRL(23),
831 	TEGRA_ADMAIF_CIF_CTRL(24),
832 	TEGRA_ADMAIF_CIF_CTRL(25),
833 	TEGRA_ADMAIF_CIF_CTRL(26),
834 	TEGRA_ADMAIF_CIF_CTRL(27),
835 	TEGRA_ADMAIF_CIF_CTRL(28),
836 	TEGRA_ADMAIF_CIF_CTRL(29),
837 	TEGRA_ADMAIF_CIF_CTRL(30),
838 	TEGRA_ADMAIF_CIF_CTRL(31),
839 	TEGRA_ADMAIF_CIF_CTRL(32),
840 };
841 
842 static const struct snd_soc_component_driver tegra210_admaif_cmpnt = {
843 	.controls		= tegra210_admaif_controls,
844 	.num_controls		= ARRAY_SIZE(tegra210_admaif_controls),
845 	.pcm_new		= tegra_pcm_new,
846 	.open			= tegra_pcm_open,
847 	.close			= tegra_pcm_close,
848 	.hw_params		= tegra_pcm_hw_params,
849 	.pointer		= tegra_pcm_pointer,
850 };
851 
852 static const struct snd_soc_component_driver tegra186_admaif_cmpnt = {
853 	.controls		= tegra186_admaif_controls,
854 	.num_controls		= ARRAY_SIZE(tegra186_admaif_controls),
855 	.pcm_new		= tegra_pcm_new,
856 	.open			= tegra_pcm_open,
857 	.close			= tegra_pcm_close,
858 	.hw_params		= tegra_pcm_hw_params,
859 	.pointer		= tegra_pcm_pointer,
860 };
861 
862 static const struct snd_soc_component_driver tegra264_admaif_cmpnt = {
863 	.controls		= tegra264_admaif_controls,
864 	.num_controls		= ARRAY_SIZE(tegra264_admaif_controls),
865 	.pcm_new		= tegra_pcm_new,
866 	.open			= tegra_pcm_open,
867 	.close			= tegra_pcm_close,
868 	.hw_params		= tegra_pcm_hw_params,
869 	.pointer		= tegra_pcm_pointer,
870 };
871 
872 static const struct tegra_admaif_soc_data soc_data_tegra210 = {
873 	.num_ch		= TEGRA210_ADMAIF_CHANNEL_COUNT,
874 	.max_stream_ch	= TEGRA210_ADMAIF_MAX_CHANNEL,
875 	.cmpnt		= &tegra210_admaif_cmpnt,
876 	.dais		= tegra210_admaif_cmpnt_dais,
877 	.regmap_conf	= &tegra210_admaif_regmap_config,
878 	.global_base	= TEGRA210_ADMAIF_GLOBAL_BASE,
879 	.tx_base	= TEGRA210_ADMAIF_TX_BASE,
880 	.rx_base	= TEGRA210_ADMAIF_RX_BASE,
881 };
882 
883 static const struct tegra_admaif_soc_data soc_data_tegra186 = {
884 	.num_ch		= TEGRA186_ADMAIF_CHANNEL_COUNT,
885 	.max_stream_ch	= TEGRA186_ADMAIF_MAX_CHANNEL,
886 	.cmpnt		= &tegra186_admaif_cmpnt,
887 	.dais		= tegra186_admaif_cmpnt_dais,
888 	.regmap_conf	= &tegra186_admaif_regmap_config,
889 	.global_base	= TEGRA186_ADMAIF_GLOBAL_BASE,
890 	.tx_base	= TEGRA186_ADMAIF_TX_BASE,
891 	.rx_base	= TEGRA186_ADMAIF_RX_BASE,
892 };
893 
894 static const struct tegra_admaif_soc_data soc_data_tegra264 = {
895 	.num_ch		= TEGRA264_ADMAIF_CHANNEL_COUNT,
896 	.max_stream_ch	= TEGRA264_ADMAIF_MAX_CHANNEL,
897 	.cmpnt		= &tegra264_admaif_cmpnt,
898 	.dais		= tegra264_admaif_cmpnt_dais,
899 	.regmap_conf	= &tegra264_admaif_regmap_config,
900 	.global_base	= TEGRA264_ADMAIF_GLOBAL_BASE,
901 	.tx_base	= TEGRA264_ADMAIF_TX_BASE,
902 	.rx_base	= TEGRA264_ADMAIF_RX_BASE,
903 };
904 
905 static const struct of_device_id tegra_admaif_of_match[] = {
906 	{ .compatible = "nvidia,tegra210-admaif", .data = &soc_data_tegra210 },
907 	{ .compatible = "nvidia,tegra186-admaif", .data = &soc_data_tegra186 },
908 	{ .compatible = "nvidia,tegra264-admaif", .data = &soc_data_tegra264 },
909 	{},
910 };
911 MODULE_DEVICE_TABLE(of, tegra_admaif_of_match);
912 
913 static int tegra_admaif_probe(struct platform_device *pdev)
914 {
915 	struct tegra_admaif *admaif;
916 	void __iomem *regs;
917 	struct resource *res;
918 	int err, i;
919 
920 	admaif = devm_kzalloc(&pdev->dev, sizeof(*admaif), GFP_KERNEL);
921 	if (!admaif)
922 		return -ENOMEM;
923 
924 	admaif->soc_data = of_device_get_match_data(&pdev->dev);
925 
926 	dev_set_drvdata(&pdev->dev, admaif);
927 
928 	admaif->capture_dma_data =
929 		devm_kcalloc(&pdev->dev,
930 			     admaif->soc_data->num_ch,
931 			     sizeof(struct snd_dmaengine_dai_dma_data),
932 			     GFP_KERNEL);
933 	if (!admaif->capture_dma_data)
934 		return -ENOMEM;
935 
936 	admaif->playback_dma_data =
937 		devm_kcalloc(&pdev->dev,
938 			     admaif->soc_data->num_ch,
939 			     sizeof(struct snd_dmaengine_dai_dma_data),
940 			     GFP_KERNEL);
941 	if (!admaif->playback_dma_data)
942 		return -ENOMEM;
943 
944 	for (i = 0; i < ADMAIF_PATHS; i++) {
945 		admaif->mono_to_stereo[i] =
946 			devm_kcalloc(&pdev->dev, admaif->soc_data->num_ch,
947 				     sizeof(unsigned int), GFP_KERNEL);
948 		if (!admaif->mono_to_stereo[i])
949 			return -ENOMEM;
950 
951 		admaif->stereo_to_mono[i] =
952 			devm_kcalloc(&pdev->dev, admaif->soc_data->num_ch,
953 				     sizeof(unsigned int), GFP_KERNEL);
954 		if (!admaif->stereo_to_mono[i])
955 			return -ENOMEM;
956 	}
957 
958 	regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
959 	if (IS_ERR(regs))
960 		return PTR_ERR(regs);
961 
962 	admaif->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
963 					       admaif->soc_data->regmap_conf);
964 	if (IS_ERR(admaif->regmap))
965 		return dev_err_probe(&pdev->dev, PTR_ERR(admaif->regmap),
966 				     "regmap init failed\n");
967 
968 	regcache_cache_only(admaif->regmap, true);
969 
970 	err = tegra_isomgr_adma_register(&pdev->dev);
971 	if (err)
972 		return err;
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 		return dev_err_probe(&pdev->dev, err,
1014 				     "can't register ADMAIF component\n");
1015 
1016 	pm_runtime_enable(&pdev->dev);
1017 
1018 	return 0;
1019 }
1020 
1021 static void tegra_admaif_remove(struct platform_device *pdev)
1022 {
1023 	tegra_isomgr_adma_unregister(&pdev->dev);
1024 	pm_runtime_disable(&pdev->dev);
1025 }
1026 
1027 static const struct dev_pm_ops tegra_admaif_pm_ops = {
1028 	RUNTIME_PM_OPS(tegra_admaif_runtime_suspend,
1029 		       tegra_admaif_runtime_resume, NULL)
1030 	SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
1031 };
1032 
1033 static struct platform_driver tegra_admaif_driver = {
1034 	.probe = tegra_admaif_probe,
1035 	.remove = tegra_admaif_remove,
1036 	.driver = {
1037 		.name = "tegra210-admaif",
1038 		.of_match_table = tegra_admaif_of_match,
1039 		.pm = pm_ptr(&tegra_admaif_pm_ops),
1040 	},
1041 };
1042 module_platform_driver(tegra_admaif_driver);
1043 
1044 MODULE_AUTHOR("Songhee Baek <sbaek@nvidia.com>");
1045 MODULE_DESCRIPTION("Tegra210 ASoC ADMAIF driver");
1046 MODULE_LICENSE("GPL v2");
1047