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