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