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